summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgeno <gabriele.genovese2@studio.unibo.it>2024-06-26 14:53:05 +0200
committergeno <gabriele.genovese2@studio.unibo.it>2024-06-26 14:53:05 +0200
commit06671f5aed68753435a762bc3be43e83094156d1 (patch)
tree56f251596cf57f6f13a7921e7dad6e795989329d
parente09358f3648445bbf9747f40497af6221d933a99 (diff)
exercise 1 completed
1.b now works 1.c implened error for "function takes N positional arguments but M were given"
-rw-r--r--progs/test2.py9
-rw-r--r--src/Main.java2
-rw-r--r--src/ast/nodes/ArglistNode.java12
-rw-r--r--src/ast/nodes/AssignmentNode.java4
-rw-r--r--src/ast/nodes/AtomNode.java6
-rw-r--r--src/ast/nodes/CompNode.java2
-rw-r--r--src/ast/nodes/CompoundNode.java4
-rw-r--r--src/ast/nodes/ExprNode.java45
-rw-r--r--src/ast/nodes/FuncdefNode.java10
-rw-r--r--src/ast/nodes/IfNode.java3
-rw-r--r--src/ast/nodes/ParamdefNode.java18
-rw-r--r--src/ast/nodes/ParamlistNode.java5
-rw-r--r--src/ast/nodes/SimpleStmtNode.java3
-rw-r--r--src/ast/nodes/SimpleStmtsNode.java3
-rw-r--r--src/ast/nodes/TrailerNode.java5
-rw-r--r--src/ast/types/FunctionType.java27
16 files changed, 116 insertions, 42 deletions
diff --git a/progs/test2.py b/progs/test2.py
index c62d44a..9c1318d 100644
--- a/progs/test2.py
+++ b/progs/test2.py
@@ -1,3 +1,6 @@
-x = 1
-if y == 1:
- print("a")
+x = 2 ; y = 3
+
+def f(x, y):
+ return x+y
+
+print(f(5,3,1)+ x + y)
diff --git a/src/Main.java b/src/Main.java
index bfc21e3..121d3d1 100644
--- a/src/Main.java
+++ b/src/Main.java
@@ -20,7 +20,7 @@ public class Main {
try {
// String fileStr = file.getPath();
// FIXME: use the fileStr above
- String fileStr = "./progs/test.py";
+ String fileStr = "./progs/test2.py";
System.out.println(fileStr);
System.out.println(readFile(fileStr));
CharStream cs = CharStreams.fromFileName(fileStr);
diff --git a/src/ast/nodes/ArglistNode.java b/src/ast/nodes/ArglistNode.java
index 71bcdce..cd1a403 100644
--- a/src/ast/nodes/ArglistNode.java
+++ b/src/ast/nodes/ArglistNode.java
@@ -1,15 +1,15 @@
package ast.nodes;
+import ast.types.*;
import java.util.ArrayList;
-
import semanticanalysis.SemanticError;
import semanticanalysis.SymbolTable;
-import ast.types.*;
/**
* Node for the `arglist` statement of the grammar.
*/
public class ArglistNode implements Node {
+
protected ArrayList<Node> arguments;
public ArglistNode(ArrayList<Node> arguments) {
@@ -19,14 +19,14 @@ public class ArglistNode implements Node {
@Override
public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting) {
ArrayList<SemanticError> errors = new ArrayList<SemanticError>();
-
+
for (var arg : arguments) {
ExprNode argExpr = (ExprNode) arg;
String argName = argExpr.getId();
// TODO: check fucking IntType for params
// TODO: remove fucking comments
- if (!ST.top_lookup(argName) && argExpr.typeCheck() instanceof AtomType){
+ if (argName != null && !ST.top_lookup(argName) && argExpr.typeCheck() instanceof AtomType) {
// System.out.println(!(this.typeCheck() instanceof IntType) + " " + !ST.top_lookup(this.getId()));
errors.add(new SemanticError("'" + argName + "' is not defined."));
} else {
@@ -37,6 +37,10 @@ public class ArglistNode implements Node {
return errors;
}
+ public int getArgumentNumber() {
+ return arguments.size();
+ }
+
@Override
public Type typeCheck() {
return new VoidType();
diff --git a/src/ast/nodes/AssignmentNode.java b/src/ast/nodes/AssignmentNode.java
index b0310b5..3d597ef 100644
--- a/src/ast/nodes/AssignmentNode.java
+++ b/src/ast/nodes/AssignmentNode.java
@@ -1,15 +1,15 @@
package ast.nodes;
+import ast.types.*;
import java.util.ArrayList;
-
import semanticanalysis.SemanticError;
import semanticanalysis.SymbolTable;
-import ast.types.*;
/**
* Node for the `assignment` statement of the grammar.
*/
public class AssignmentNode implements Node {
+
private ExprNode lhr;
private Node assign;
private ExprNode rhr;
diff --git a/src/ast/nodes/AtomNode.java b/src/ast/nodes/AtomNode.java
index 0704bc4..96132d8 100644
--- a/src/ast/nodes/AtomNode.java
+++ b/src/ast/nodes/AtomNode.java
@@ -25,11 +25,11 @@ public class AtomNode implements Node {
@Override
public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting) {
var errors = new ArrayList<SemanticError>();
-
+
// Print the symbol table
- System.out.println(ST);
+ // System.out.println(ST);
- if ((this.typeCheck() instanceof AtomType) && !ST.top_lookup(this.getId())/*ST.nslookup(this.getId()) < 0*/) {
+ if ((this.typeCheck() instanceof AtomType) && ST.nslookup(this.getId()) < 0) {
// System.out.println(!(this.typeCheck() instanceof IntType) + " " + !ST.top_lookup(this.getId()));
errors.add(new SemanticError("'" + this.getId() + "' is not defined."));
}
diff --git a/src/ast/nodes/CompNode.java b/src/ast/nodes/CompNode.java
index 33976bf..f167bf9 100644
--- a/src/ast/nodes/CompNode.java
+++ b/src/ast/nodes/CompNode.java
@@ -11,6 +11,7 @@ import org.antlr.v4.runtime.tree.TerminalNode;
* Node for the `comp_op` statement of the grammar.
*/
public class CompNode implements Node {
+
private TerminalNode op;
public CompNode(TerminalNode op) {
@@ -19,6 +20,7 @@ public class CompNode implements Node {
@Override
public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting) {
+ System.out.println("Comp node");
return new ArrayList<SemanticError>();
}
diff --git a/src/ast/nodes/CompoundNode.java b/src/ast/nodes/CompoundNode.java
index e64be9e..d21c2c7 100644
--- a/src/ast/nodes/CompoundNode.java
+++ b/src/ast/nodes/CompoundNode.java
@@ -1,15 +1,15 @@
package ast.nodes;
+import ast.types.*;
import java.util.ArrayList;
-
import semanticanalysis.SemanticError;
import semanticanalysis.SymbolTable;
-import ast.types.*;
/**
* Node for the `compound_node` statement of the grammar.
*/
public class CompoundNode implements Node {
+
private Node ifNode;
private Node funcDef;
private Node forStmt;
diff --git a/src/ast/nodes/ExprNode.java b/src/ast/nodes/ExprNode.java
index 4bb67f7..eea69f8 100644
--- a/src/ast/nodes/ExprNode.java
+++ b/src/ast/nodes/ExprNode.java
@@ -3,6 +3,7 @@ package ast.nodes;
import ast.types.*;
import java.util.ArrayList;
import java.util.Arrays;
+import semanticanalysis.STentry;
import semanticanalysis.SemanticError;
import semanticanalysis.SymbolTable;
@@ -100,29 +101,47 @@ public class ExprNode implements Node {
}
public String getId() {
- return ((AtomNode) this.atom).getId();
+ if (atom != null) {
+ return ((AtomNode) this.atom).getId();
+ } else {
+ return null;
+ }
}
@Override
public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting) {
ArrayList<SemanticError> errors = new ArrayList<SemanticError>();
-
- if (atom != null && !Arrays.asList(bif).contains(atom.getId())) {
- errors.addAll(atom.checkSemantics(ST, _nesting));
-
- for (var trailer : trailers) {
- errors.addAll(trailer.checkSemantics(ST, _nesting));
- }
+
+ if (atom != null && !trailers.isEmpty()) {
+ // function call
+ if (!Arrays.asList(bif).contains(atom.getId())) {
+ errors.addAll(atom.checkSemantics(ST, _nesting));
+ Node trailer = trailers.get(0);
+ String funName = atom.getId();
+ STentry s = ST.lookup(funName);
+ if (s != null) {
+ FunctionType ft = (FunctionType) s.getType();
+ int paramNumber = ft.getParamNumber();
+ int argNumber = ((TrailerNode) trailer).getArgumentNumber();
+ if (paramNumber != argNumber) {
+ errors.add(new SemanticError(funName + "() takes " + String.valueOf(paramNumber) + " positional arguments but " + String.valueOf(argNumber) + " were given"));
+ }
+ }
+ } else {
+ for (var trailer : trailers) {
+ errors.addAll(trailer.checkSemantics(ST, _nesting));
+ }
+ }
}
-
+
if (compOp != null) {
errors.addAll(compOp.checkSemantics(ST, _nesting));
}
for (var expr : exprs) {
errors.addAll(expr.checkSemantics(ST, _nesting));
- }
-
+ }
+
return errors;
}
@@ -157,11 +176,11 @@ public class ExprNode implements Node {
for (var expr : exprs) {
str += expr.toPrint(prefix);
- }
+ }
for (var trailer : trailers) {
str += trailer.toPrint(prefix);
- }
+ }
if (op != null) {
str += prefix + "Op(" + op + ")\n";
diff --git a/src/ast/nodes/FuncdefNode.java b/src/ast/nodes/FuncdefNode.java
index 4c8f92f..8985e08 100644
--- a/src/ast/nodes/FuncdefNode.java
+++ b/src/ast/nodes/FuncdefNode.java
@@ -13,6 +13,7 @@ import org.antlr.v4.runtime.tree.TerminalNode;
* Node for the `funcdef` statement of the grammar.
*/
public class FuncdefNode implements Node {
+
private TerminalNode name;
private Node paramlist;
private Node block;
@@ -26,14 +27,17 @@ public class FuncdefNode implements Node {
@Override
public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting) {
ArrayList<SemanticError> errors = new ArrayList<SemanticError>();
-
- ST.insert(this.name.toString(), this.block.typeCheck(), _nesting, "");
+ int paramNumber = ((ParamlistNode) paramlist).getParamNumber();
+ Type returnType = this.block.typeCheck();
+ FunctionType ft = new FunctionType(paramNumber, returnType);
+
+ ST.insert(this.name.toString(), ft, _nesting, "");
HashMap<String, STentry> HM = new HashMap<String, STentry>();
ST.add(HM);
- ST.insert(this.name.toString(), this.block.typeCheck(), _nesting + 1, "");
+ ST.insert(this.name.toString(), ft, _nesting + 1, "");
if (paramlist != null) {
errors.addAll(paramlist.checkSemantics(ST, _nesting + 1));
diff --git a/src/ast/nodes/IfNode.java b/src/ast/nodes/IfNode.java
index 50dde4a..772041b 100644
--- a/src/ast/nodes/IfNode.java
+++ b/src/ast/nodes/IfNode.java
@@ -1,10 +1,9 @@
package ast.nodes;
+import ast.types.*;
import java.util.ArrayList;
-
import semanticanalysis.SemanticError;
import semanticanalysis.SymbolTable;
-import ast.types.*;
/**
* Node for the `if` statement of the grammar.
diff --git a/src/ast/nodes/ParamdefNode.java b/src/ast/nodes/ParamdefNode.java
index 265b6b6..5164537 100644
--- a/src/ast/nodes/ParamdefNode.java
+++ b/src/ast/nodes/ParamdefNode.java
@@ -1,24 +1,32 @@
package ast.nodes;
-import java.util.ArrayList;
-
import ast.types.*;
-import semanticanalysis.*;
+import java.util.ArrayList;
+import semanticanalysis.SemanticError;
+import semanticanalysis.SymbolTable;
/**
* Node for the `paramdef` statement of the grammar. Extends the `AtomNode`
* class.
*/
public class ParamdefNode extends AtomNode {
+
public ParamdefNode(String val) {
super(val);
}
@Override
public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting) {
- ST.insert(this.getId(), this.typeCheck(), _nesting, "");
+ var errors = new ArrayList<SemanticError>();
+ String paramName = this.getId();
+
+ if (!ST.top_lookup(paramName)) {
+ ST.insert(paramName, this.typeCheck(), _nesting, "");
+ } else {
+ errors.add(new SemanticError("Duplicate argument '" + paramName + "' in function definition."));
+ }
- return new ArrayList<SemanticError>();
+ return errors;
}
// FIXME: it should returns the param' type
diff --git a/src/ast/nodes/ParamlistNode.java b/src/ast/nodes/ParamlistNode.java
index 144eb13..0a9696f 100644
--- a/src/ast/nodes/ParamlistNode.java
+++ b/src/ast/nodes/ParamlistNode.java
@@ -10,6 +10,7 @@ import ast.types.*;
* Node for the `param_list` statement of the grammar.
*/
public class ParamlistNode implements Node {
+
private ArrayList<Node> params;
public ParamlistNode(ArrayList<Node> _params) {
@@ -27,6 +28,10 @@ public class ParamlistNode implements Node {
return errors;
}
+ public int getParamNumber() {
+ return params.size();
+ }
+
@Override
public Type typeCheck() {
return new VoidType();
diff --git a/src/ast/nodes/SimpleStmtNode.java b/src/ast/nodes/SimpleStmtNode.java
index 5f844cb..b7e5455 100644
--- a/src/ast/nodes/SimpleStmtNode.java
+++ b/src/ast/nodes/SimpleStmtNode.java
@@ -1,10 +1,9 @@
package ast.nodes;
+import ast.types.*;
import java.util.ArrayList;
-
import semanticanalysis.SemanticError;
import semanticanalysis.SymbolTable;
-import ast.types.*;
/**
* Node for the `simple_stmt` statement of the grammar.
diff --git a/src/ast/nodes/SimpleStmtsNode.java b/src/ast/nodes/SimpleStmtsNode.java
index 66c8e2c..97bffff 100644
--- a/src/ast/nodes/SimpleStmtsNode.java
+++ b/src/ast/nodes/SimpleStmtsNode.java
@@ -1,10 +1,9 @@
package ast.nodes;
+import ast.types.*;
import java.util.ArrayList;
-
import semanticanalysis.SemanticError;
import semanticanalysis.SymbolTable;
-import ast.types.*;
/**
* Node for the `simple_stmts` statement of the grammar.
diff --git a/src/ast/nodes/TrailerNode.java b/src/ast/nodes/TrailerNode.java
index b0a0ee7..850b8e8 100644
--- a/src/ast/nodes/TrailerNode.java
+++ b/src/ast/nodes/TrailerNode.java
@@ -11,6 +11,7 @@ import org.antlr.v4.runtime.tree.TerminalNode;
* Node for the `trailer` statement of the grammar.
*/
public class TrailerNode implements Node {
+
private Node arglist;
private ArrayList<Node> exprs;
private TerminalNode methodCall;
@@ -39,6 +40,10 @@ public class TrailerNode implements Node {
return errors;
}
+ public int getArgumentNumber() {
+ return ((ArglistNode) arglist).getArgumentNumber();
+ }
+
@Override
public Type typeCheck() {
return new VoidType();
diff --git a/src/ast/types/FunctionType.java b/src/ast/types/FunctionType.java
new file mode 100644
index 0000000..464bb9c
--- /dev/null
+++ b/src/ast/types/FunctionType.java
@@ -0,0 +1,27 @@
+package ast.types;
+
+/**
+ * An tom type. TODO: do I need to use this one?
+ */
+public class FunctionType extends Type {
+
+ private final int paramNumber;
+ private final Type returnType;
+
+ public FunctionType(int paramNumber, Type returnType) {
+ this.paramNumber = paramNumber;
+ this.returnType = returnType;
+ }
+
+ public int getParamNumber() {
+ return paramNumber;
+ }
+
+ public Type getReturnType() {
+ return returnType;
+ }
+
+ public String toPrint(String prefix) {
+ return prefix + "Atom\n";
+ }
+}