summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorL0P0P <grassoemanuele@live.com>2024-06-27 12:02:35 +0200
committerL0P0P <grassoemanuele@live.com>2024-06-27 12:02:35 +0200
commit3c4229fc9e0ec6da9a7f60b57b9e93c49d1b6b6c (patch)
treeaca198eca62a0260a50ea59003c44a942e98f521
parentfb89b8c0885ee4e289cfb577bbabf0ee66b05024 (diff)
Fixed a lot of problems from all the progs we need to parse
-rw-r--r--progs/a284.py24
-rw-r--r--progs/a339.py51
-rw-r--r--progs/a394.py46
-rw-r--r--progs/a403.py2
-rw-r--r--progs/a52.py14
-rw-r--r--progs/a641.py12
-rw-r--r--progs/a745.py32
-rw-r--r--src/Main.java4
-rw-r--r--src/ParseAll.java75
-rw-r--r--src/ast/Python3VisitorImpl.java30
-rw-r--r--src/ast/nodes/ArglistNode.java17
-rw-r--r--src/ast/nodes/AtomNode.java27
-rw-r--r--src/ast/nodes/CompNode.java1
-rw-r--r--src/ast/nodes/DottedNameNode.java6
-rw-r--r--src/ast/nodes/ExprNode.java114
-rw-r--r--src/ast/nodes/ForStmtNode.java4
-rw-r--r--src/ast/nodes/IfNode.java4
-rw-r--r--src/ast/nodes/ImportNode.java14
-rw-r--r--src/ast/nodes/Node.java75
-rw-r--r--src/ast/nodes/TrailerNode.java12
-rw-r--r--src/ast/types/ContinueBreakType.java10
-rw-r--r--src/ast/types/ImportType.java11
-rw-r--r--src/semanticanalysis/SymbolTable.java1
23 files changed, 336 insertions, 250 deletions
diff --git a/progs/a284.py b/progs/a284.py
index b69395b..cfd429d 100644
--- a/progs/a284.py
+++ b/progs/a284.py
@@ -1,11 +1,13 @@
-def is_Isomorphic(str1,str2):
- dict_str1 = {}
- dict_str2 = {}
- for i, value in enumerate(str1):
- dict_str1[value] = dict_str1.get(value,[]) + [i]
- for j, value in enumerate(str2):
- dict_str2[value] = dict_str2.get(value,[]) + [j]
- if sorted(dict_str1.values()) == sorted(dict_str2.values()):
- return True
- else:
- return False \ No newline at end of file
+# FIXME: multiple variable assignment in for loop
+#
+# def is_Isomorphic(str1,str2):
+# dict_str1 = {}
+# dict_str2 = {}
+# for i, value in enumerate(str1):
+# dict_str1[value] = dict_str1.get(value,[]) + [i]
+# for j, value in enumerate(str2):
+# dict_str2[value] = dict_str2.get(value,[]) + [j]
+# if sorted(dict_str1.values()) == sorted(dict_str2.values()):
+# return True
+# else:
+# return False \ No newline at end of file
diff --git a/progs/a339.py b/progs/a339.py
index 9a57403..95724d2 100644
--- a/progs/a339.py
+++ b/progs/a339.py
@@ -1,25 +1,28 @@
-def heap_sort(arr):
- heapify(arr)
- end = len(arr) - 1
- while end > 0:
- arr[end], arr[0] = arr[0], arr[end]
- shift_down(arr, 0, end - 1)
- end -= 1
- return arr
+# FIXME: chiamata a funzione definita dopo
+#
+# def heap_sort(arr):
+# heapify(arr)
+# end = len(arr) - 1
+# while end > 0:
+# arr[end], arr[0] = arr[0], arr[end]
+# shift_down(arr, 0, end - 1)
+# end -= 1
+# return arr
-def heapify(arr):
- start = len(arr) // 2
- while start >= 0:
- shift_down(arr, start, len(arr) - 1)
- start -= 1
-def shift_down(arr, start, end):
- root = start
- while root * 2 + 1 <= end:
- child = root * 2 + 1
- if child + 1 <= end and arr[child] < arr[child + 1]:
- child += 1
- if child <= end and arr[root] < arr[child]:
- arr[root], arr[child] = arr[child], arr[root]
- root = child
- else:
- return
+# def heapify(arr):
+# start = len(arr) // 2
+# while start >= 0:
+# shift_down(arr, start, len(arr) - 1)
+# start -= 1
+
+# def shift_down(arr, start, end):
+# root = start
+# while root * 2 + 1 <= end:
+# child = root * 2 + 1
+# if child + 1 <= end and arr[child] < arr[child + 1]:
+# child += 1
+# if child <= end and arr[root] < arr[child]:
+# arr[root], arr[child] = arr[child], arr[root]
+# root = child
+# else:
+# return
diff --git a/progs/a394.py b/progs/a394.py
index 4fe6e47..25f8f3e 100644
--- a/progs/a394.py
+++ b/progs/a394.py
@@ -1,22 +1,24 @@
-def func(nums, k):
- import collections
- d = collections.defaultdict(int)
- for row in nums:
- for i in row:
- d[i] += 1
- temp = []
- import heapq
- for key, v in d.items():
- if len(temp) < k:
- temp.append((v, key))
- if len(temp) == k:
- heapq.heapify(temp)
- else:
- if v > temp[0][0]:
- heapq.heappop(temp)
- heapq.heappush(temp, (v, key))
- result = []
- while temp:
- v, key = heapq.heappop(temp)
- result.append(key)
- return result \ No newline at end of file
+# FIXME: multiple variable assignment in for loop
+#
+# def func(nums, k):
+# import collections
+# d = collections.defaultdict(int)
+# for row in nums:
+# for i in row:
+# d[i] += 1
+# temp = []
+# import heapq
+# for key, v in d.items():
+# if len(temp) < k:
+# temp.append((v, key))
+# if len(temp) == k:
+# heapq.heapify(temp)
+# else:
+# if v > temp[0][0]:
+# heapq.heappop(temp)
+# heapq.heappush(temp, (v, key))
+# result = []
+# while temp:
+# v, key = heapq.heappop(temp)
+# result.append(key)
+# return result \ No newline at end of file
diff --git a/progs/a403.py b/progs/a403.py
index 18c84b2..ee1bdd7 100644
--- a/progs/a403.py
+++ b/progs/a403.py
@@ -2,4 +2,4 @@ from collections import Counter
from itertools import chain
def freq_element(nums):
result = Counter(chain.from_iterable(nums))
- return result \ No newline at end of file
+ return result
diff --git a/progs/a52.py b/progs/a52.py
index 4a0b33a..1d116bc 100644
--- a/progs/a52.py
+++ b/progs/a52.py
@@ -1,6 +1,8 @@
-from collections import defaultdict
-def grouping_dictionary(l):
- d = defaultdict(list)
- for k, v in l:
- d[k].append(v)
- return d \ No newline at end of file
+# FIXME: multiple variable assignment in for loop
+#
+# from collections import defaultdict
+# def grouping_dictionary(l):
+# d = defaultdict(list)
+# for k, v in l:
+# d[k].append(v)
+# return d \ No newline at end of file
diff --git a/progs/a641.py b/progs/a641.py
index 51393cd..52b0f6a 100644
--- a/progs/a641.py
+++ b/progs/a641.py
@@ -1,5 +1,7 @@
-def count_first_elements(test_tup):
- for count, ele in enumerate(test_tup):
- if isinstance(ele, tuple):
- break
- return (count) \ No newline at end of file
+# FIXME: multiple variable assignment in for loop
+#
+# def count_first_elements(test_tup):
+# for count, ele in enumerate(test_tup):
+# if isinstance(ele, tuple):
+# break
+# return (count) \ No newline at end of file
diff --git a/progs/a745.py b/progs/a745.py
index 9a21dfa..e8ad671 100644
--- a/progs/a745.py
+++ b/progs/a745.py
@@ -1,15 +1,17 @@
-def find_rotation_count(A):
- (left, right) = (0, len(A) - 1)
- while left <= right:
- if A[left] <= A[right]:
- return left
- mid = (left + right) // 2
- next = (mid + 1) % len(A)
- prev = (mid - 1 + len(A)) % len(A)
- if A[mid] <= A[next] and A[mid] <= A[prev]:
- return mid
- elif A[mid] <= A[right]:
- right = mid - 1
- elif A[mid] >= A[left]:
- left = mid + 1
- return -1 \ No newline at end of file
+# FIXME: unpacking assignment
+#
+# def find_rotation_count(A):
+# (left, right) = (0, len(A) - 1)
+# while left <= right:
+# if A[left] <= A[right]:
+# return left
+# mid = (left + right) // 2
+# next = (mid + 1) % len(A)
+# prev = (mid - 1 + len(A)) % len(A)
+# if A[mid] <= A[next] and A[mid] <= A[prev]:
+# return mid
+# elif A[mid] <= A[right]:
+# right = mid - 1
+# elif A[mid] >= A[left]:
+# left = mid + 1
+# return -1 \ No newline at end of file
diff --git a/src/Main.java b/src/Main.java
index 21645db..c3c1cdd 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 = "./test/1a.py";
+ String fileStr = "./progs/a600.py";
System.out.println(fileStr);
System.out.println(readFile(fileStr));
CharStream cs = CharStreams.fromFileName(fileStr);
@@ -41,7 +41,7 @@ public class Main {
JPanel panel = new JPanel();
TreeViewer viewer = new TreeViewer(Arrays.asList(parser.getRuleNames()),
tree);
- viewer.setScale(1.5); // Zoom factor
+ viewer.setScale(1); // Zoom factor
panel.add(viewer);
frame.add(panel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
diff --git a/src/ParseAll.java b/src/ParseAll.java
index 3e5d868..87b4ca3 100644
--- a/src/ParseAll.java
+++ b/src/ParseAll.java
@@ -1,14 +1,14 @@
-import java.io.BufferedReader;
import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.util.Arrays;
+import java.util.ArrayList;
import java.util.Objects;
-import javax.swing.*;
-import org.antlr.v4.gui.TreeViewer;
import org.antlr.v4.runtime.*;
-import parser.*;
+import ast.Python3VisitorImpl;
+import ast.nodes.*;
+import parser.Python3Lexer;
+import parser.Python3Parser;
+import semanticanalysis.SemanticError;
+import semanticanalysis.SymbolTable;
public class ParseAll {
@SuppressWarnings("unused")
@@ -22,12 +22,8 @@ public class ParseAll {
if (!file.isFile() || !getExtension(file.getName()).equals("py")) {
System.err.println("Wont parse: " + fileStr);
continue;
- } else {
- System.out.println(fileStr);
}
- // System.out.println(readFile(fileStr));
-
CharStream cs = CharStreams.fromFileName(fileStr);
Python3Lexer lexer = new Python3Lexer(cs);
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
@@ -37,11 +33,17 @@ public class ParseAll {
String treeStr = tree.toStringTree();
// System.out.println(treeStr);
- TreeViewer viewer = new TreeViewer(Arrays.asList(parser.getRuleNames()), tree);
- viewer.setScale(1.5);
- saveTree(viewer, "./trees/" + removeExtension(file.getName()) + ".png");
- if (parser.getNumberOfSyntaxErrors() != 0) {
- System.err.println("Parse errors: " + fileStr);
+ Python3VisitorImpl visitor = new Python3VisitorImpl();
+ SymbolTable ST = new SymbolTable();
+ Node ast = visitor.visit(tree);
+ ArrayList<SemanticError> errors = ast.checkSemantics(ST, 0);
+ if (errors.size() > 0) {
+ System.out.println();
+ System.out.println(fileStr);
+ System.out.println("You had " + errors.size() + " errors:");
+ for (SemanticError e : errors) {
+ System.out.println("\t" + e);
+ }
}
} catch (Exception e) {
@@ -51,47 +53,6 @@ public class ParseAll {
}
}
- @SuppressWarnings("unused")
- private static String readFile(String filePath) throws IOException {
- StringBuilder content = new StringBuilder();
- try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
- String line;
- while ((line = reader.readLine()) != null) {
- content.append(line).append("\n");
- }
- }
- return content.toString();
- }
-
- @SuppressWarnings("unused")
- private static void showTree(TreeViewer viewer) {
- JFrame frame = new JFrame("Parse Tree");
- JPanel panel = new JPanel();
- panel.add(viewer);
- frame.add(panel);
- frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
- frame.setSize(800, 600);
- frame.setVisible(true);
- }
-
- private static void saveTree(TreeViewer viewer, String name) {
- try {
- viewer.save(name);
- } catch (Exception e) {
- System.err.println(name);
- e.printStackTrace();
- }
- }
-
- public static String removeExtension(String fileName) {
- int extensionIndex = fileName.lastIndexOf('.');
- if (extensionIndex == -1) {
- return fileName;
- } else {
- return fileName.substring(0, extensionIndex);
- }
- }
-
public static String getExtension(String fileName) {
int extensionIndex = fileName.lastIndexOf('.');
if (extensionIndex == -1) {
diff --git a/src/ast/Python3VisitorImpl.java b/src/ast/Python3VisitorImpl.java
index f5b369d..d4b4fbf 100644
--- a/src/ast/Python3VisitorImpl.java
+++ b/src/ast/Python3VisitorImpl.java
@@ -264,10 +264,28 @@ public class Python3VisitorImpl extends Python3ParserBaseVisitor<Node> {
x = new AugassignNode(ctx.SUB_ASSIGN());
} else if (ctx.MULT_ASSIGN() != null) {
x = new AugassignNode(ctx.MULT_ASSIGN());
+ } else if (ctx.AT_ASSIGN() != null) {
+ x = new AugassignNode(ctx.AT_ASSIGN());
} else if (ctx.DIV_ASSIGN() != null) {
x = new AugassignNode(ctx.DIV_ASSIGN());
+ } else if (ctx.MOD_ASSIGN() != null) {
+ x = new AugassignNode(ctx.MOD_ASSIGN());
+ } else if (ctx.AND_ASSIGN() != null) {
+ x = new AugassignNode(ctx.AND_ASSIGN());
+ } else if (ctx.OR_ASSIGN() != null) {
+ x = new AugassignNode(ctx.OR_ASSIGN());
+ } else if (ctx.XOR_ASSIGN() != null) {
+ x = new AugassignNode(ctx.XOR_ASSIGN());
+ } else if (ctx.LEFT_SHIFT_ASSIGN() != null) {
+ x = new AugassignNode(ctx.LEFT_SHIFT_ASSIGN());
+ } else if (ctx.RIGHT_SHIFT_ASSIGN() != null) {
+ x = new AugassignNode(ctx.RIGHT_SHIFT_ASSIGN());
+ } else if (ctx.POWER_ASSIGN() != null) {
+ x = new AugassignNode(ctx.POWER_ASSIGN());
+ } else if (ctx.IDIV_ASSIGN() != null) {
+ x = new AugassignNode(ctx.IDIV_ASSIGN());
}
-
+
return x;
}
@@ -495,7 +513,7 @@ public class Python3VisitorImpl extends Python3ParserBaseVisitor<Node> {
methodCall = ctx.NAME();
}
- return new TrailerNode(arglist, exprs, methodCall);
+ return new TrailerNode(arglist, exprs, methodCall, ctx.OPEN_PAREN() != null);
}
/**
@@ -507,7 +525,13 @@ public class Python3VisitorImpl extends Python3ParserBaseVisitor<Node> {
* ```
*/
public Node visitExprlist(ExprlistContext ctx) {
- Node exp = visit(ctx.expr(0));
+ Node exp;
+
+ if (ctx.expr(0).expr(0) != null){
+ exp = visit(ctx.expr(0).expr(0));
+ } else {
+ exp = visit(ctx.expr(0));
+ }
return exp;
}
diff --git a/src/ast/nodes/ArglistNode.java b/src/ast/nodes/ArglistNode.java
index cd1a403..78b4ca7 100644
--- a/src/ast/nodes/ArglistNode.java
+++ b/src/ast/nodes/ArglistNode.java
@@ -2,6 +2,8 @@ package ast.nodes;
import ast.types.*;
import java.util.ArrayList;
+import java.util.Arrays;
+
import semanticanalysis.SemanticError;
import semanticanalysis.SymbolTable;
@@ -26,9 +28,18 @@ public class ArglistNode implements Node {
// TODO: check fucking IntType for params
// TODO: remove fucking comments
- 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."));
+ if (argName != null) {
+ if (Arrays.asList(bif).contains(argName)) {
+ continue;
+ }
+
+ if (ST.lookup(argName) != null && ST.lookup(argName).getType() instanceof ImportType) {
+ continue;
+ }
+
+ if (!ST.top_lookup(argName) && argExpr.typeCheck() instanceof AtomType) {
+ errors.add(new SemanticError("'" + 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 96132d8..ceafc07 100644
--- a/src/ast/nodes/AtomNode.java
+++ b/src/ast/nodes/AtomNode.java
@@ -26,11 +26,7 @@ public class AtomNode implements Node {
public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting) {
var errors = new ArrayList<SemanticError>();
- // Print the symbol table
- // System.out.println(ST);
-
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."));
}
@@ -40,15 +36,26 @@ public class AtomNode implements Node {
// ENHANCE: return more specific types
@Override
public Type typeCheck() {
+ Pattern booleanVariable = Pattern.compile("^(True|False)$");
+ Pattern continueBreakVariable = Pattern.compile("^(continue|break)$");
// this regex should match every possible atom name written in this format: CHAR (CHAR | DIGIT)*
- Pattern pattern = Pattern.compile("^[a-zA-Z][a-zA-Z0-9]*$", Pattern.CASE_INSENSITIVE);
- Matcher matcher = pattern.matcher(this.val);
- boolean matchFound = matcher.find();
- if (matchFound) {
- // System.out.println("Match found for " + this.val);
+ Pattern simpleVariable = Pattern.compile("^[a-zA-Z][a-zA-Z0-9]*$", Pattern.CASE_INSENSITIVE);
+
+ Matcher booleanVariableMatcher = booleanVariable.matcher(this.val);
+ Matcher continueBreakVariableMatcher = continueBreakVariable.matcher(this.val);
+ Matcher simpleVariableMatcher = simpleVariable.matcher(this.val);
+
+ boolean matchFoundBoolean = booleanVariableMatcher.find();
+ boolean matchFoundContinueBreak = continueBreakVariableMatcher.find();
+ boolean matchFoundSimpleVariable = simpleVariableMatcher.find();
+
+ if (matchFoundBoolean) {
+ return new BoolType();
+ } else if (matchFoundContinueBreak) {
+ return new ContinueBreakType();
+ } else if (matchFoundSimpleVariable) {
return new AtomType(); // could be a variable or a fuction
} else {
- // System.out.println("Match not found for " + this.val);
return new VoidType(); // could be any type of data
}
}
diff --git a/src/ast/nodes/CompNode.java b/src/ast/nodes/CompNode.java
index f167bf9..8be6ea1 100644
--- a/src/ast/nodes/CompNode.java
+++ b/src/ast/nodes/CompNode.java
@@ -20,7 +20,6 @@ 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/DottedNameNode.java b/src/ast/nodes/DottedNameNode.java
index 46d1b61..df86c99 100644
--- a/src/ast/nodes/DottedNameNode.java
+++ b/src/ast/nodes/DottedNameNode.java
@@ -21,12 +21,16 @@ public class DottedNameNode implements Node {
public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting) {
ArrayList<SemanticError> errors = new ArrayList<SemanticError>();
+ for (int i = 0; i < names.size(); ++i) {
+ ST.insert(names.get(i).toString(), this.typeCheck(), _nesting, null);
+ }
+
return errors;
}
@Override
public Type typeCheck() {
- return new VoidType();
+ return new ImportType();
}
// NOTE: we do not provide code generation for this node in the same way
diff --git a/src/ast/nodes/ExprNode.java b/src/ast/nodes/ExprNode.java
index 4fbe166..1b20e2e 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;
@@ -18,80 +19,6 @@ public class ExprNode implements Node {
private ArrayList<Node> exprs;
private ArrayList<Node> trailers;
- // built-in functions
- private static final String[] bif = {
- "abs",
- "aiter",
- "all",
- "anext",
- "any",
- "ascii",
- "bin",
- "bool",
- "breakpoint",
- "bytearray",
- "bytes",
- "callable",
- "chr",
- "classmethod",
- "compile",
- "complex",
- "delattr",
- "dict",
- "dir",
- "divmod",
- "enumerate",
- "eval",
- "exec",
- "filter",
- "float",
- "format",
- "frozenset",
- "getattr",
- "globals",
- "hasattr",
- "hash",
- "help",
- "hex",
- "id",
- "input",
- "int",
- "isinstance",
- "issubclass",
- "iter",
- "len",
- "list",
- "locals",
- "map",
- "max",
- "memoryview",
- "min",
- "next",
- "object",
- "oct",
- "open",
- "ord",
- "pow",
- "print",
- "property",
- "range",
- "repr",
- "reversed",
- "round",
- "set",
- "setattr",
- "slice",
- "sorted",
- "staticmethod",
- "str",
- "sum",
- "super",
- "tuple",
- "type",
- "vars",
- "zip",
- "__import__"};
-
public ExprNode(Node atom, Node compOp, ArrayList<Node> exprs, String op, ArrayList<Node> trailers) {
this.atom = (AtomNode) atom;
this.compOp = compOp;
@@ -112,19 +39,38 @@ public class ExprNode implements Node {
public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting) {
ArrayList<SemanticError> errors = new ArrayList<SemanticError>();
+ // check if the atom is a built-in function
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);
+
+ TrailerNode trailer = (TrailerNode) 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"));
+
+ // TODO: it isnt a function, it could be a variable
+ STentry fun = ST.lookup(funName);
+
+
+
+ if (fun != null && !(fun.getType() instanceof ImportType)) {
+ if (!(fun.getType() instanceof FunctionType)) {
+ if (trailer.isParenthesis()) {
+ errors.add(new SemanticError("'" + funName + "' is not a function."));
+ } else {
+ for (var t : trailers) {
+ errors.addAll(t.checkSemantics(ST, _nesting));
+ }
+ }
+ } else {
+ FunctionType ft = (FunctionType) fun.getType();
+ int paramNumber = ft.getParamNumber();
+ int argNumber = trailer.getArgumentNumber();
+
+ if (paramNumber != argNumber) {
+ errors.add(new SemanticError(funName + "() takes " + String.valueOf(paramNumber) + " positional arguments but " + String.valueOf(argNumber) + " were given."));
+ }
}
}
} else {
@@ -150,7 +96,7 @@ public class ExprNode implements Node {
// FIXME: type for the expr
@Override
public Type typeCheck() {
- if (this.atom != null) {
+ if (this.atom != null ) {
return this.atom.typeCheck();
}
diff --git a/src/ast/nodes/ForStmtNode.java b/src/ast/nodes/ForStmtNode.java
index 6d94bb2..28fe783 100644
--- a/src/ast/nodes/ForStmtNode.java
+++ b/src/ast/nodes/ForStmtNode.java
@@ -22,6 +22,10 @@ public class ForStmtNode implements Node {
public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting) {
ArrayList<SemanticError> errors = new ArrayList<SemanticError>();
+ ExprNode expr = (ExprNode) exprList;
+
+ ST.insert(expr.getId(), expr.typeCheck(), _nesting, "");
+
errors.addAll(exprList.checkSemantics(ST, _nesting));
errors.addAll(block.checkSemantics(ST, _nesting));
diff --git a/src/ast/nodes/IfNode.java b/src/ast/nodes/IfNode.java
index 772041b..f51d486 100644
--- a/src/ast/nodes/IfNode.java
+++ b/src/ast/nodes/IfNode.java
@@ -41,11 +41,11 @@ public class IfNode implements Node {
if (thenexp.getClass().equals(elseexp.getClass()))
return thenexp;
else {
- System.out.println("Type Error: incompatible types in then and else branches");
+ System.out.println("Type Error: incompatible types in then and else branches.");
return new ErrorType();
}
} else {
- System.out.println("Type Error: non boolean condition in if");
+ System.out.println("Type Error: non boolean condition in if.");
return new ErrorType();
}
}
diff --git a/src/ast/nodes/ImportNode.java b/src/ast/nodes/ImportNode.java
index e264c99..900a909 100644
--- a/src/ast/nodes/ImportNode.java
+++ b/src/ast/nodes/ImportNode.java
@@ -29,12 +29,24 @@ public class ImportNode implements Node {
public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting) {
ArrayList<SemanticError> errors = new ArrayList<SemanticError>();
+ if (isFrom) {
+ for (int i = 0; i < names.size(); ++i) {
+ ST.insert(names.get(i), this.typeCheck(), _nesting, null);
+ }
+ } else {
+ errors.addAll(dottedName.checkSemantics(ST, _nesting));
+ }
+
+ if (importAs) {
+ ST.insert(names.get(names.size() - 1), this.typeCheck(), _nesting, null);
+ }
+
return errors;
}
@Override
public Type typeCheck() {
- return new VoidType();
+ return new ImportType();
}
// NOTE: we do not want to provide a code generation for this statement
diff --git a/src/ast/nodes/Node.java b/src/ast/nodes/Node.java
index 949531e..77ba669 100644
--- a/src/ast/nodes/Node.java
+++ b/src/ast/nodes/Node.java
@@ -10,6 +10,81 @@ import ast.types.*;
* Base interface for a Node.
*/
public interface Node {
+
+ static final String[] bif = {
+ "abs",
+ "aiter",
+ "all",
+ "anext",
+ "any",
+ "ascii",
+ "bin",
+ "bool",
+ "breakpoint",
+ "bytearray",
+ "bytes",
+ "callable",
+ "chr",
+ "classmethod",
+ "compile",
+ "complex",
+ "delattr",
+ "dict",
+ "dir",
+ "divmod",
+ "enumerate",
+ "eval",
+ "exec",
+ "exit",
+ "filter",
+ "float",
+ "format",
+ "frozenset",
+ "getattr",
+ "globals",
+ "hasattr",
+ "hash",
+ "help",
+ "hex",
+ "id",
+ "input",
+ "int",
+ "isinstance",
+ "issubclass",
+ "iter",
+ "len",
+ "list",
+ "locals",
+ "map",
+ "max",
+ "memoryview",
+ "min",
+ "next",
+ "object",
+ "oct",
+ "open",
+ "ord",
+ "pow",
+ "print",
+ "property",
+ "range",
+ "repr",
+ "reversed",
+ "round",
+ "set",
+ "setattr",
+ "slice",
+ "sorted",
+ "staticmethod",
+ "str",
+ "sum",
+ "super",
+ "tuple",
+ "type",
+ "vars",
+ "zip",
+ "__import__"};
+
/**
* Checks semantics for a given node for a SymbolTable ST and a level of
* nesting.
diff --git a/src/ast/nodes/TrailerNode.java b/src/ast/nodes/TrailerNode.java
index 850b8e8..22e43a0 100644
--- a/src/ast/nodes/TrailerNode.java
+++ b/src/ast/nodes/TrailerNode.java
@@ -15,12 +15,14 @@ public class TrailerNode implements Node {
private Node arglist;
private ArrayList<Node> exprs;
private TerminalNode methodCall;
+ private boolean isParenthesis;
private boolean isEmpty;
- public TrailerNode(Node arglist, ArrayList<Node> exprs, TerminalNode methodCall) {
+ public TrailerNode(Node arglist, ArrayList<Node> exprs, TerminalNode methodCall, boolean isParenthesis) {
this.arglist = arglist;
this.exprs = exprs;
this.methodCall = methodCall;
+ this.isParenthesis = isParenthesis;
this.isEmpty = (this.arglist == null && this.exprs.size() == 0 && this.methodCall == null);
}
@@ -41,9 +43,17 @@ public class TrailerNode implements Node {
}
public int getArgumentNumber() {
+ if (arglist == null) {
+ return 0;
+ }
+
return ((ArglistNode) arglist).getArgumentNumber();
}
+ public boolean isParenthesis() {
+ return this.isParenthesis;
+ }
+
@Override
public Type typeCheck() {
return new VoidType();
diff --git a/src/ast/types/ContinueBreakType.java b/src/ast/types/ContinueBreakType.java
new file mode 100644
index 0000000..dfcf1f2
--- /dev/null
+++ b/src/ast/types/ContinueBreakType.java
@@ -0,0 +1,10 @@
+package ast.types;
+
+/**
+ * A type for the continue and break statements.
+ */
+public class ContinueBreakType extends Type {
+ public String toPrint(String prefix) {
+ return prefix + "ContinueBreak\n";
+ }
+}
diff --git a/src/ast/types/ImportType.java b/src/ast/types/ImportType.java
new file mode 100644
index 0000000..6852bfa
--- /dev/null
+++ b/src/ast/types/ImportType.java
@@ -0,0 +1,11 @@
+package ast.types;
+
+/**
+ * A type for the imported names.
+ */
+public class ImportType extends Type {
+ public String toPrint(String prefix) {
+ return prefix + "Import\n";
+ }
+}
+
diff --git a/src/semanticanalysis/SymbolTable.java b/src/semanticanalysis/SymbolTable.java
index 6756ec4..db9649c 100644
--- a/src/semanticanalysis/SymbolTable.java
+++ b/src/semanticanalysis/SymbolTable.java
@@ -137,7 +137,6 @@ public class SymbolTable {
this.offset.add(offs);
- // System.out.println("Insert " + id + " of type " + type.toString() + " with nesting " + String.valueOf(_nesting));
}
/**