summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgeno <gabriele.genovese2@studio.unibo.it>2024-06-27 20:49:56 +0200
committergeno <gabriele.genovese2@studio.unibo.it>2024-06-27 20:49:56 +0200
commitfd85e9980c0305c6dfb91aaeb199430a89163c3e (patch)
tree724d7184c11ad3acb8a8b0d2e15f1922f5b36059
parent4898724edf343650ffb80792caf9e242e5843059 (diff)
fixed comp_for and added reseved word type
-rw-r--r--src/ast/Python3VisitorImpl.java44
-rw-r--r--src/ast/nodes/ArglistNode.java38
-rw-r--r--src/ast/nodes/AtomNode.java13
-rw-r--r--src/ast/nodes/CompForNode.java59
-rw-r--r--src/ast/nodes/CompIterNode.java50
-rw-r--r--src/ast/nodes/TestlistCompNode.java19
-rw-r--r--src/ast/types/NoneType.java16
-rw-r--r--src/ast/types/ReservedWordsType.java (renamed from src/ast/types/ContinueBreakType.java)4
8 files changed, 213 insertions, 30 deletions
diff --git a/src/ast/Python3VisitorImpl.java b/src/ast/Python3VisitorImpl.java
index 5b812ea..c5f1bfa 100644
--- a/src/ast/Python3VisitorImpl.java
+++ b/src/ast/Python3VisitorImpl.java
@@ -434,6 +434,8 @@ public class Python3VisitorImpl extends Python3ParserBaseVisitor<Node> {
Testlist_compContext tlc = ctx.testlist_comp();
if (ctx.NUMBER() != null) {
return new AtomNode(ctx.NUMBER().toString(), null);
+ } else if (ctx.NONE() != null) {
+ return new AtomNode(ctx.NONE().toString(), null);
} else if (ctx.TRUE() != null) {
return new AtomNode(ctx.TRUE().toString(), null);
} else if (ctx.FALSE() != null) {
@@ -453,7 +455,7 @@ public class Python3VisitorImpl extends Python3ParserBaseVisitor<Node> {
} else if (ctx.OPEN_PAREN() != null && ctx.CLOSE_PAREN() != null) {
return manageTlc(tlc);
}
- return new AtomNode(ctx.NONE().toString(), null);
+ return new AtomNode(null, null);
}
public AtomNode manageTlc(Testlist_compContext tlc) {
@@ -533,7 +535,45 @@ public class Python3VisitorImpl extends Python3ParserBaseVisitor<Node> {
for (ExprContext c : ctx.expr()) {
exprlist.add(visit(c));
}
+ Comp_forContext cfc = ctx.comp_for();
+ if (cfc != null) {
+ Node comp = visit(ctx.comp_for());
+ return new TestlistCompNode(exprlist, comp);
+ }
+ return new TestlistCompNode(exprlist, null);
+ }
+
+ /**
+ * Returns a `CompForNode`.
+ *
+ * ``` comp_for : 'for' exprlist 'in' expr comp_iter? ;```
+ */
+ public Node visitComp_for(Comp_forContext ctx) {
+ Node exprlist = visit(ctx.exprlist());
+ Node expr = visit(ctx.expr());
+ Comp_iterContext cic = ctx.comp_iter();
- return new TestlistCompNode(exprlist);
+ if (cic != null) {
+ Node comp = visit(ctx.comp_iter());
+ return new CompForNode(exprlist, expr, comp);
+ }
+ return new CompForNode(exprlist, expr, null);
+ }
+
+ /**
+ * Returns a `CompIterNode`.
+ *
+ * ``` comp_iter : comp_for | comp_if ; ;```
+ */
+ public Node visitComp_iter(Comp_iterContext ctx) {
+ // TODO: Implement comp_if
+ // Node iter = visit(ctx.comp_if());
+ Comp_forContext cfc = ctx.comp_for();
+ if (cfc != null) {
+ Node forNode = visit(ctx.comp_for());
+ return new CompIterNode(forNode);
+
+ }
+ return new CompIterNode(null);
}
}
diff --git a/src/ast/nodes/ArglistNode.java b/src/ast/nodes/ArglistNode.java
index 983d150..c29a4e0 100644
--- a/src/ast/nodes/ArglistNode.java
+++ b/src/ast/nodes/ArglistNode.java
@@ -22,25 +22,27 @@ public class ArglistNode implements Node {
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 (argName != null) {
- if (Arrays.asList(bif).contains(argName)) {
- continue;
+ if (arg instanceof ExprNode) {
+ ExprNode argExpr = (ExprNode) arg;
+ String argName = argExpr.getId();
+
+ // TODO: check fucking IntType for params
+ // TODO: remove fucking comments
+ if (argName != null) {
+ if (Arrays.asList(bif).contains(argName)) {
+ continue;
+ }
+
+ if (ST.lookup(argName) != null && ST.lookup(argName).getType() instanceof ImportType) {
+ continue;
+ }
+
+ if (ST.nslookup(argName) < 0 && argExpr.typeCheck() instanceof AtomType) {
+ errors.add(new SemanticError("name '" + argName + "' is not defined."));
+ }
+ } else {
+ errors.addAll(arg.checkSemantics(ST, _nesting));
}
-
- if (ST.lookup(argName) != null && ST.lookup(argName).getType() instanceof ImportType) {
- continue;
- }
-
- if (ST.nslookup(argName) < 0 && argExpr.typeCheck() instanceof AtomType) {
- errors.add(new SemanticError("name '" + argName + "' is not defined."));
- }
- } else {
- errors.addAll(arg.checkSemantics(ST, _nesting));
}
}
diff --git a/src/ast/nodes/AtomNode.java b/src/ast/nodes/AtomNode.java
index 592aac4..16281d6 100644
--- a/src/ast/nodes/AtomNode.java
+++ b/src/ast/nodes/AtomNode.java
@@ -50,23 +50,28 @@ public class AtomNode implements Node {
return new VoidType();
}
+ Pattern noneVariable = Pattern.compile("^(None)$");
Pattern booleanVariable = Pattern.compile("^(True|False)$");
- Pattern continueBreakVariable = Pattern.compile("^(continue|break)$");
+ Pattern reservedWords = Pattern.compile("^(continue|break|int|float)$");
// this regex should match every possible atom name written in this format: CHAR (CHAR | DIGIT)*
Pattern simpleVariable = Pattern.compile("^[a-zA-Z][a-zA-Z0-9]*$", Pattern.CASE_INSENSITIVE);
+ Matcher noneVariableMatcher = noneVariable.matcher(this.val);
Matcher booleanVariableMatcher = booleanVariable.matcher(this.val);
- Matcher continueBreakVariableMatcher = continueBreakVariable.matcher(this.val);
+ Matcher reservedWordsMatcher = reservedWords.matcher(this.val);
Matcher simpleVariableMatcher = simpleVariable.matcher(this.val);
+ boolean matchFoundNone = noneVariableMatcher.find();
boolean matchFoundBoolean = booleanVariableMatcher.find();
- boolean matchFoundContinueBreak = continueBreakVariableMatcher.find();
+ boolean matchFoundContinueBreak = reservedWordsMatcher.find();
boolean matchFoundSimpleVariable = simpleVariableMatcher.find();
if (matchFoundBoolean) {
return new BoolType();
} else if (matchFoundContinueBreak) {
- return new ContinueBreakType();
+ return new ReservedWordsType();
+ } else if (matchFoundNone) {
+ return new NoneType();
} else if (matchFoundSimpleVariable) {
return new AtomType(); // could be a variable or a fuction
} else {
diff --git a/src/ast/nodes/CompForNode.java b/src/ast/nodes/CompForNode.java
new file mode 100644
index 0000000..d5c50d6
--- /dev/null
+++ b/src/ast/nodes/CompForNode.java
@@ -0,0 +1,59 @@
+package ast.nodes;
+
+import ast.types.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import semanticanalysis.SemanticError;
+import semanticanalysis.SymbolTable;
+
+/**
+ * Node for the `comp_for` statement of the grammar. 'for' exprlist 'in' expr
+ * comp_iter?
+ */
+public class CompForNode implements Node {
+
+ protected ExprListNode exprlist;
+ protected ExprNode single_expr;
+ protected CompIterNode comp_iter;
+
+ public CompForNode(Node exprlist, Node single_expr, Node comp_iter) {
+ this.exprlist = (ExprListNode) exprlist;
+ this.single_expr = (ExprNode) single_expr;
+ this.comp_iter = (CompIterNode) comp_iter;
+ }
+
+ @Override
+ public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting) {
+ ArrayList<SemanticError> errors = new ArrayList<SemanticError>();
+
+ errors.addAll(exprlist.checkSemantics(ST, _nesting));
+ errors.addAll(single_expr.checkSemantics(ST, _nesting));
+ if (comp_iter != null) {
+ errors.addAll(comp_iter.checkSemantics(ST, _nesting));
+ }
+ return errors;
+ }
+
+ @Override
+ public Type typeCheck() {
+ return new VoidType();
+ }
+
+ // TODO: add code generation for arglist node
+ @Override
+ public String codeGeneration() {
+ return "";
+ }
+
+ @Override
+ public String toPrint(String prefix) {
+ String str = prefix + "CompForNode\n";
+
+ prefix += " ";
+ str += exprlist.toPrint(prefix);
+ str += single_expr.toPrint(prefix);
+ str += comp_iter.toPrint(prefix);
+ return str;
+ }
+
+}
diff --git a/src/ast/nodes/CompIterNode.java b/src/ast/nodes/CompIterNode.java
new file mode 100644
index 0000000..6704bd7
--- /dev/null
+++ b/src/ast/nodes/CompIterNode.java
@@ -0,0 +1,50 @@
+package ast.nodes;
+
+import ast.types.*;
+import java.util.ArrayList;
+import semanticanalysis.SemanticError;
+import semanticanalysis.SymbolTable;
+
+/**
+ * Node for the `comp_iter` statement of the grammar.
+ */
+public class CompIterNode implements Node {
+
+ protected CompForNode comp_for;
+ // protected CompIfNode compIfNode;
+
+ public CompIterNode(Node comp_for) {
+ this.comp_for = (CompForNode) comp_for;
+ }
+
+ @Override
+ public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting) {
+ ArrayList<SemanticError> errors = new ArrayList<SemanticError>();
+
+ if (comp_for != null) {
+ errors.addAll(comp_for.checkSemantics(ST, _nesting));
+ }
+ return errors;
+ }
+
+ @Override
+ public Type typeCheck() {
+ return new VoidType();
+ }
+
+ // TODO: add code generation for arglist node
+ @Override
+ public String codeGeneration() {
+ return "";
+ }
+
+ @Override
+ public String toPrint(String prefix) {
+ String str = prefix + "CompIterNode\n";
+
+ prefix += " ";
+ str += comp_for.toPrint(prefix);
+ return str;
+ }
+
+}
diff --git a/src/ast/nodes/TestlistCompNode.java b/src/ast/nodes/TestlistCompNode.java
index 070b1a1..bcaca83 100644
--- a/src/ast/nodes/TestlistCompNode.java
+++ b/src/ast/nodes/TestlistCompNode.java
@@ -11,17 +11,28 @@ import semanticanalysis.SymbolTable;
public class TestlistCompNode implements Node {
private final ArrayList<Node> exprs;
+ private final CompForNode comp;
- public TestlistCompNode(ArrayList<Node> _exprs) {
- this.exprs = _exprs;
+ public TestlistCompNode(ArrayList<Node> exprs, Node comp) {
+ this.exprs = exprs;
+ this.comp = (CompForNode) comp;
}
@Override
public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting) {
ArrayList<SemanticError> errors = new ArrayList();
- for (var param : exprs) {
- errors.addAll(param.checkSemantics(ST, _nesting));
+ if (comp != null) {
+ // if comp is set, then we save the atom in the ST (we assume the first expr is an atom)
+ String id = ((ExprNode) exprs.get(0)).getId();
+ Type t = ((ExprNode) exprs.get(0)).typeCheck();
+ ST.insert(id, t, _nesting, "");
+ // errors.addAll(comp.checkSemantics(ST, _nesting));
+ } else {
+ // if comp is not set, then exprs is a list of 1 or more element
+ for (var param : exprs) {
+ errors.addAll(param.checkSemantics(ST, _nesting));
+ }
}
return errors;
diff --git a/src/ast/types/NoneType.java b/src/ast/types/NoneType.java
new file mode 100644
index 0000000..42f7fd7
--- /dev/null
+++ b/src/ast/types/NoneType.java
@@ -0,0 +1,16 @@
+package ast.types;
+
+/**
+ * A none type. None return unit.
+ */
+public class NoneType extends Type {
+
+ public String toPrint(String prefix) {
+ return prefix + "None\n";
+ }
+
+ @Override
+ public String toString() {
+ return "None";
+ }
+}
diff --git a/src/ast/types/ContinueBreakType.java b/src/ast/types/ReservedWordsType.java
index dfcf1f2..f5f7ac5 100644
--- a/src/ast/types/ContinueBreakType.java
+++ b/src/ast/types/ReservedWordsType.java
@@ -3,8 +3,8 @@ package ast.types;
/**
* A type for the continue and break statements.
*/
-public class ContinueBreakType extends Type {
+public class ReservedWordsType extends Type {
public String toPrint(String prefix) {
- return prefix + "ContinueBreak\n";
+ return prefix + "ReservedWords\n";
}
}