diff options
author | geno <gabriele.genovese2@studio.unibo.it> | 2024-06-26 14:53:05 +0200 |
---|---|---|
committer | geno <gabriele.genovese2@studio.unibo.it> | 2024-06-26 14:53:05 +0200 |
commit | 06671f5aed68753435a762bc3be43e83094156d1 (patch) | |
tree | 56f251596cf57f6f13a7921e7dad6e795989329d | |
parent | e09358f3648445bbf9747f40497af6221d933a99 (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.py | 9 | ||||
-rw-r--r-- | src/Main.java | 2 | ||||
-rw-r--r-- | src/ast/nodes/ArglistNode.java | 12 | ||||
-rw-r--r-- | src/ast/nodes/AssignmentNode.java | 4 | ||||
-rw-r--r-- | src/ast/nodes/AtomNode.java | 6 | ||||
-rw-r--r-- | src/ast/nodes/CompNode.java | 2 | ||||
-rw-r--r-- | src/ast/nodes/CompoundNode.java | 4 | ||||
-rw-r--r-- | src/ast/nodes/ExprNode.java | 45 | ||||
-rw-r--r-- | src/ast/nodes/FuncdefNode.java | 10 | ||||
-rw-r--r-- | src/ast/nodes/IfNode.java | 3 | ||||
-rw-r--r-- | src/ast/nodes/ParamdefNode.java | 18 | ||||
-rw-r--r-- | src/ast/nodes/ParamlistNode.java | 5 | ||||
-rw-r--r-- | src/ast/nodes/SimpleStmtNode.java | 3 | ||||
-rw-r--r-- | src/ast/nodes/SimpleStmtsNode.java | 3 | ||||
-rw-r--r-- | src/ast/nodes/TrailerNode.java | 5 | ||||
-rw-r--r-- | src/ast/types/FunctionType.java | 27 |
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"; + } +} |