diff options
author | Geno <48206120+gabrielegenovese@users.noreply.github.com> | 2024-07-11 12:57:56 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-07-11 12:57:56 +0200 |
commit | b50c7e99603e9f85d82d700d62c16c4fcef88715 (patch) | |
tree | 5052206f06e0426a43599cb236652614db04d22e | |
parent | f0692ff5f9e39cbd1c203e9d5abebf55a3d0f6fc (diff) |
Code generation (#20)
Co-authored-by: geno <gabrigeno@gmail>
Co-authored-by: Santo Cariotti <santo@dcariotti.me>
52 files changed, 2716 insertions, 197 deletions
@@ -2,4 +2,5 @@ out/ trees/ .project .vscode/ -src/parser/.antlr/
\ No newline at end of file +src/parser/.antlr/ +code.asm
\ No newline at end of file diff --git a/src/Main.java b/src/Main.java index f53b410..15d472d 100644 --- a/src/Main.java +++ b/src/Main.java @@ -5,11 +5,16 @@ import javax.swing.*; import org.antlr.v4.gui.TreeViewer; import org.antlr.v4.runtime.*; +import java.nio.file.StandardOpenOption; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import ast.*; import ast.nodes.*; -import parser.*; +import parser.Python3Lexer; +import parser.Python3Parser; import semanticanalysis.*; -import semanticanalysis.Share; +import svm.*; public class Main { @@ -52,7 +57,7 @@ public class Main { Python3VisitorImpl visitor = new Python3VisitorImpl(); SymbolTable ST = new SymbolTable(); Node ast = visitor.visit(tree); - ArrayList<SemanticError> errorsWithDup = ast.checkSemantics(ST, 0); + ArrayList<SemanticError> errorsWithDup = ast.checkSemantics(ST, 0, null); ArrayList<SemanticError> errors = Share.removeDuplicates(errorsWithDup); if (!errors.isEmpty()) { System.out.println("You had " + errors.size() + " errors:"); @@ -62,6 +67,32 @@ public class Main { } else { System.out.println("Visualizing AST..."); System.out.println(ast.toPrint("")); + System.out.println("Creating VM code..."); + String prog = ast.codeGeneration(); + String asmFile = "code.asm"; + Path file = Paths.get(asmFile); + if (!Files.exists(file)) { + Files.createFile(file); + } + Files.write(file, prog.getBytes(), StandardOpenOption.TRUNCATE_EXISTING); + System.out.println("Done!"); + + CharStream inputASM = CharStreams.fromFileName(asmFile); + SVMLexer lexerASM = new SVMLexer(inputASM); + CommonTokenStream tokensASM = new CommonTokenStream(lexerASM); + SVMParser parserASM = new SVMParser(tokensASM); + + SVMVisitorImpl visitorSVM = new SVMVisitorImpl(); + visitorSVM.visit(parserASM.assembly()); + + System.out.println("You had: " + lexerASM.lexicalErrors + " lexical errors and " + + parserASM.getNumberOfSyntaxErrors() + " syntax errors."); + if (lexerASM.lexicalErrors > 0 || parserASM.getNumberOfSyntaxErrors() > 0) + System.exit(1); + + System.out.println("Starting Virtual Machine..."); + ExecuteVM vm = new ExecuteVM(visitorSVM.code); + vm.cpu(); } } catch (Exception e) { e.printStackTrace(); diff --git a/src/ParseAll.java b/src/ParseAll.java index 7def6f4..06b99ad 100644 --- a/src/ParseAll.java +++ b/src/ParseAll.java @@ -34,12 +34,11 @@ public class ParseAll { Python3Parser.RootContext tree = parser.root(); String treeStr = tree.toStringTree(); - // System.out.println(treeStr); Python3VisitorImpl visitor = new Python3VisitorImpl(); SymbolTable ST = new SymbolTable(); Node ast = visitor.visit(tree); - ArrayList<SemanticError> errorsWithDup = ast.checkSemantics(ST, 0); + ArrayList<SemanticError> errorsWithDup = ast.checkSemantics(ST, 0, null); ArrayList<SemanticError> errors = Share.removeDuplicates(errorsWithDup); if (!errors.isEmpty()) { System.out.println(); diff --git a/src/ast/Python3VisitorImpl.java b/src/ast/Python3VisitorImpl.java index 1cf15b7..98ede6d 100644 --- a/src/ast/Python3VisitorImpl.java +++ b/src/ast/Python3VisitorImpl.java @@ -336,7 +336,7 @@ public class Python3VisitorImpl extends Python3ParserBaseVisitor<Node> { } /** - * Returns a `CompNode`. It should never be null. + * Returns a `CompOpNode`. It should never be null. * * ``` comp_op : '<' | '>' | '==' | '>=' | '<=' | '<>' | '!=' | 'in' | 'not' * 'in' | 'is' | 'is' 'not' ; ``` @@ -344,24 +344,24 @@ public class Python3VisitorImpl extends Python3ParserBaseVisitor<Node> { public Node visitComp_op(Comp_opContext ctx) { Node comp = null; if (ctx.LESS_THAN() != null) { - comp = new CompNode(ctx.LESS_THAN()); + comp = new CompOpNode(ctx.LESS_THAN()); } else if (ctx.GREATER_THAN() != null) { - comp = new CompNode(ctx.GREATER_THAN()); + comp = new CompOpNode(ctx.GREATER_THAN()); } else if (ctx.EQUALS() != null) { - comp = new CompNode(ctx.EQUALS()); + comp = new CompOpNode(ctx.EQUALS()); } else if (ctx.GT_EQ() != null) { - comp = new CompNode(ctx.GT_EQ()); + comp = new CompOpNode(ctx.GT_EQ()); } else if (ctx.LT_EQ() != null) { - comp = new CompNode(ctx.LT_EQ()); + comp = new CompOpNode(ctx.LT_EQ()); } else if (ctx.NOT_EQ_2() != null) { // We're ignoring NOT_EQ_1() because no one uses `<>` - comp = new CompNode(ctx.NOT_EQ_2()); + comp = new CompOpNode(ctx.NOT_EQ_2()); } else if (ctx.IN() != null) { - comp = new CompNode(ctx.IN()); + comp = new CompOpNode(ctx.IN()); } else if (ctx.NOT() != null) { - comp = new CompNode(ctx.NOT()); + comp = new CompOpNode(ctx.NOT()); } else if (ctx.IS() != null) { - comp = new CompNode(ctx.IS()); + comp = new CompOpNode(ctx.IS()); } return comp; @@ -396,6 +396,14 @@ public class Python3VisitorImpl extends Python3ParserBaseVisitor<Node> { op = ctx.NOT().toString(); } + if (ctx.AND() != null) { + op = ctx.AND().toString(); + } + + if (ctx.OR() != null) { + op = ctx.OR().toString(); + } + if (ctx.STAR() != null) { op = ctx.STAR().toString(); } @@ -404,6 +412,10 @@ public class Python3VisitorImpl extends Python3ParserBaseVisitor<Node> { op = ctx.DIV().toString(); } + if (ctx.MOD() != null) { + op = ctx.MOD().toString(); + } + if (ctx.atom() != null) { atom = visit(ctx.atom()); } diff --git a/src/ast/nodes/ArglistNode.java b/src/ast/nodes/ArglistNode.java index a0ea25b..5da7e2c 100644 --- a/src/ast/nodes/ArglistNode.java +++ b/src/ast/nodes/ArglistNode.java @@ -18,16 +18,16 @@ public class ArglistNode implements Node { } @Override - public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting) { + public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting, FunctionType ft) { ArrayList<SemanticError> errors = new ArrayList<>(); for (var arg : arguments) { if (arg instanceof ExprNode) { ExprNode argExpr = (ExprNode) arg; String argName = argExpr.getId(); + errors.addAll(arg.checkSemantics(ST, _nesting, ft)); - // TODO: check fucking IntType for params - // TODO: remove fucking comments + // TODO: check IntType for params if (argName != null) { if (Arrays.asList(bif).contains(argName)) { continue; @@ -40,8 +40,6 @@ public class ArglistNode implements Node { 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)); } } } @@ -58,10 +56,13 @@ public class ArglistNode implements Node { return new VoidType(); } - // TODO: add code generation for arglist node @Override public String codeGeneration() { - return ""; + String str = ""; + for (Node arg : arguments) { + str += arg.codeGeneration() + "pushr A0\n"; + } + return str; } @Override diff --git a/src/ast/nodes/AssignmentNode.java b/src/ast/nodes/AssignmentNode.java index c4a44dc..358d497 100644 --- a/src/ast/nodes/AssignmentNode.java +++ b/src/ast/nodes/AssignmentNode.java @@ -2,6 +2,8 @@ package ast.nodes; import ast.types.*; import java.util.ArrayList; + +import semanticanalysis.STentry; import semanticanalysis.SemanticError; import semanticanalysis.SymbolTable; @@ -14,35 +16,45 @@ public class AssignmentNode implements Node { private final Node assign; private final ExprListNode rhr; + // Useful for code gen + private int offset; + private boolean alreadyDef; + public AssignmentNode(Node lhr, Node assign, Node rhr) { this.lhr = (ExprListNode) lhr; this.assign = assign; this.rhr = (ExprListNode) rhr; + this.alreadyDef = false; } @Override - public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting) { + public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting, FunctionType ft) { ArrayList<SemanticError> errors = new ArrayList<>(); - // errors.addAll(lhr.checkSemantics(ST, _nesting)); - errors.addAll(assign.checkSemantics(ST, _nesting)); - errors.addAll(rhr.checkSemantics(ST, _nesting)); + // DO NOT CHECK lhr + errors.addAll(assign.checkSemantics(ST, _nesting, ft)); + errors.addAll(rhr.checkSemantics(ST, _nesting, ft)); int lsize = lhr.getSize(); - // FIXME: unused variable - // int rsize = rhr.getSize(); - // if (lsize == rsize) { for (int i = 0; i < lsize; i++) { - ExprNode latom = (ExprNode) lhr.getElem(i); - ST.insert(latom.getId(), new AtomType(), _nesting, ""); - // ExprNode ratom = (ExprNode) rhr.getElem(i); - } - // } else { - // FIX: sgravata da piĆ¹ problemi che altro - // errors.add(new SemanticError("ValueError: different size of left or right side assignment")); - // } + ExprNode leftAtom = (ExprNode) lhr.getElem(i); + STentry e = ST.lookup(leftAtom.getId()); + if (ft != null) { + ft.addLocalVar(); + } + if (e == null) { + ST.insert(leftAtom.getId(), new AtomType(), _nesting, ""); + e = ST.lookup(leftAtom.getId()); + } else { + int ns = e.getNesting(); + if (_nesting == ns) { + this.alreadyDef = true; + } + } + offset = e.getOffset(); + } return errors; } @@ -52,10 +64,29 @@ public class AssignmentNode implements Node { return rhr.typeCheck(); } - // TODO: add code generation for assignment @Override public String codeGeneration() { - return ""; + String rhrString = rhr.codeGeneration(); + + String lhrString = ""; + ExprNode leftAtom = (ExprNode) lhr.getElem(0); + + // The code generation for the left atom returns a `store A0 0(T1)` at + // the end but we do not want that command. + // So, we'll have a string with the substring + the offset. + String leftAtomCode = leftAtom.codeGeneration(); + lhrString += leftAtomCode.substring(0, leftAtomCode.length() - 17) + offset; + + // If the variable name is previously defined it'll load the variable + // from the `0(T1)`, otherwise it'll push the `A0` register at the top + // of the stack. + if (!this.alreadyDef) { + lhrString += "\npushr A0\n"; + } else { + lhrString += "\nload A0 0(T1)\n"; + } + + return rhrString + lhrString; } @Override diff --git a/src/ast/nodes/AtomNode.java b/src/ast/nodes/AtomNode.java index 37d4d79..ea99808 100644 --- a/src/ast/nodes/AtomNode.java +++ b/src/ast/nodes/AtomNode.java @@ -2,6 +2,7 @@ package ast.nodes; import ast.types.*; import java.util.ArrayList; +import java.util.Arrays; import java.util.regex.Matcher; import java.util.regex.Pattern; import semanticanalysis.SemanticError; @@ -15,6 +16,10 @@ public class AtomNode implements Node { protected String val; protected TestlistCompNode exprlist; + // very scatchy + protected int ns; + protected int offset; + public AtomNode(String val, Node exprlist) { this.val = val; this.exprlist = (TestlistCompNode) exprlist; @@ -25,23 +30,29 @@ public class AtomNode implements Node { * returns `null`. */ public String getId() { - return this.val; + return val; } @Override - public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting) { + public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting, FunctionType ft) { ArrayList<SemanticError> errors = new ArrayList<>(); if (val != null) { - if ((this.typeCheck() instanceof AtomType) && ST.nslookup(this.getId()) < 0) { - errors.add(new SemanticError("name '" + this.getId() + "' is not defined.")); - } else { - // System.out.println("exist " + this.typeCheck()); + if (!Arrays.asList(bif).contains(getId())) { + if ((typeCheck() instanceof AtomType) && ST.nslookup(getId()) < 0) { + errors.add(new SemanticError("name '" + getId() + "' is not defined.")); + } else { + if ((typeCheck() instanceof AtomType)) { + int varNs = ST.lookup(getId()).getNesting(); + this.ns = _nesting - varNs; + offset = ST.lookup(getId()).getOffset(); + } + } } } if (exprlist != null) { - errors.addAll(exprlist.checkSemantics(ST, _nesting)); + errors.addAll(exprlist.checkSemantics(ST, _nesting, ft)); } return errors; @@ -50,29 +61,34 @@ public class AtomNode implements Node { // ENHANCE: return more specific types @Override public Type typeCheck() { - if (this.val == null) { + if (val == null) { return new VoidType(); } Pattern noneVariable = Pattern.compile("^(None)$"); Pattern booleanVariable = Pattern.compile("^(True|False)$"); + Pattern integerVariable = Pattern.compile("^[0-9]+$"); 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 reservedWordsMatcher = reservedWords.matcher(this.val); - Matcher simpleVariableMatcher = simpleVariable.matcher(this.val); + Matcher noneVariableMatcher = noneVariable.matcher(val); + Matcher booleanVariableMatcher = booleanVariable.matcher(val); + Matcher integerVariableMatcher = integerVariable.matcher(val); + Matcher reservedWordsMatcher = reservedWords.matcher(val); + Matcher simpleVariableMatcher = simpleVariable.matcher(val); boolean matchFoundNone = noneVariableMatcher.find(); boolean matchFoundBoolean = booleanVariableMatcher.find(); + boolean matchFoundInteger = integerVariableMatcher.find(); boolean matchFoundContinueBreak = reservedWordsMatcher.find(); boolean matchFoundSimpleVariable = simpleVariableMatcher.find(); if (matchFoundBoolean) { return new BoolType(); + } else if (matchFoundInteger) { + return new IntType(); } else if (matchFoundContinueBreak) { return new ReservedWordsType(); } else if (matchFoundNone) { @@ -84,10 +100,37 @@ public class AtomNode implements Node { } } - // TODO: add code generation for atom node @Override public String codeGeneration() { - return ""; + if (exprlist != null) { + return exprlist.codeGeneration(); + } + + if (typeCheck() instanceof IntType) { + return "storei A0 " + getId() + "\n"; + } + + if (typeCheck() instanceof BoolType) { + return "storei A0 " + boolValue(getId()) + "\n"; + } + + if (typeCheck() instanceof AtomType) { + // We need to ascend the access-link chain to the top (or bottom, + // who knows). + String str = "move AL T1\n"; + for (int i = 0; i < this.ns; i++) { + str += "store T1 0(T1)\n"; + } + + str += "subi T1 " + offset + "\nstore A0 0(T1)\n"; + return str; + } + + return "Error: could not parse an atom\n"; + } + + public static String boolValue(String id) { + return id.equals("True") ? "1" : "0"; } @Override diff --git a/src/ast/nodes/AugassignNode.java b/src/ast/nodes/AugassignNode.java index aef60cc..906dcd7 100644 --- a/src/ast/nodes/AugassignNode.java +++ b/src/ast/nodes/AugassignNode.java @@ -20,19 +20,18 @@ public class AugassignNode implements Node { } @Override - public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting) { + public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting, FunctionType ft) { return new ArrayList<>(); } - // FIXME: use the right type @Override public Type typeCheck() { return new VoidType(); } - // TODO: add code generation for augassign node @Override public String codeGeneration() { + // We're just considering the `=` operation for this language. return ""; } diff --git a/src/ast/nodes/BlockNode.java b/src/ast/nodes/BlockNode.java index 732e89b..2ea0a47 100644 --- a/src/ast/nodes/BlockNode.java +++ b/src/ast/nodes/BlockNode.java @@ -15,12 +15,12 @@ public class BlockNode extends RootNode { } @Override - public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting) { + public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting, FunctionType ft) { ArrayList<SemanticError> errors = new ArrayList<>(); // Check semantics for each child for (Node child : childs) { - errors.addAll(child.checkSemantics(ST, _nesting)); + errors.addAll(child.checkSemantics(ST, _nesting, ft)); } return errors; @@ -32,6 +32,17 @@ public class BlockNode extends RootNode { } @Override + public String codeGeneration() { + String str = ""; + + for (Node child : childs) { + str += child.codeGeneration(); + } + + return str; + } + + @Override public String toPrint(String prefix) { String str = prefix + "Block\n"; diff --git a/src/ast/nodes/CompForNode.java b/src/ast/nodes/CompForNode.java index 405a400..1f51af5 100644 --- a/src/ast/nodes/CompForNode.java +++ b/src/ast/nodes/CompForNode.java @@ -22,13 +22,13 @@ public class CompForNode implements Node { } @Override - public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting) { + public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting, FunctionType ft) { ArrayList<SemanticError> errors = new ArrayList<>(); - errors.addAll(exprlist.checkSemantics(ST, _nesting)); - errors.addAll(single_expr.checkSemantics(ST, _nesting)); + errors.addAll(exprlist.checkSemantics(ST, _nesting, ft)); + errors.addAll(single_expr.checkSemantics(ST, _nesting, ft)); if (comp_iter != null) { - errors.addAll(comp_iter.checkSemantics(ST, _nesting)); + errors.addAll(comp_iter.checkSemantics(ST, _nesting, ft)); } return errors; } @@ -38,7 +38,9 @@ public class CompForNode implements Node { return new VoidType(); } - // TODO: add code generation for arglist node + /** + * We do not want to provide the code generation for the for list comprehension. + */ @Override public String codeGeneration() { return ""; diff --git a/src/ast/nodes/CompIterNode.java b/src/ast/nodes/CompIterNode.java index 1cc8a9b..de443fa 100644 --- a/src/ast/nodes/CompIterNode.java +++ b/src/ast/nodes/CompIterNode.java @@ -11,18 +11,17 @@ import semanticanalysis.SymbolTable; 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) { + public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting, FunctionType ft) { ArrayList<SemanticError> errors = new ArrayList<>(); if (comp_for != null) { - errors.addAll(comp_for.checkSemantics(ST, _nesting)); + errors.addAll(comp_for.checkSemantics(ST, _nesting, ft)); } return errors; } @@ -32,7 +31,9 @@ public class CompIterNode implements Node { return new VoidType(); } - // TODO: add code generation for arglist node + /** + * We do not want to provide the code generation for this stuff. + */ @Override public String codeGeneration() { return ""; diff --git a/src/ast/nodes/CompNode.java b/src/ast/nodes/CompOpNode.java index b6e0191..7997052 100644 --- a/src/ast/nodes/CompNode.java +++ b/src/ast/nodes/CompOpNode.java @@ -10,16 +10,20 @@ import org.antlr.v4.runtime.tree.TerminalNode; /** * Node for the `comp_op` statement of the grammar. */ -public class CompNode implements Node { +public class CompOpNode implements Node { private final TerminalNode op; - public CompNode(TerminalNode op) { + public CompOpNode(TerminalNode op) { this.op = op; } + public String getOp() { + return op.toString(); + } + @Override - public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting) { + public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting, FunctionType ft) { return new ArrayList<>(); } @@ -29,7 +33,9 @@ public class CompNode implements Node { return new VoidType(); } - // TODO: add code generation for CompNode + /** + * The code generation for this operation is in `ExprNode`. + */ @Override public String codeGeneration() { return ""; @@ -37,6 +43,6 @@ public class CompNode implements Node { @Override public String toPrint(String prefix) { - return prefix + "CompNode(" + op + ")\n"; + return prefix + "CompOpNode(" + op + ")\n"; } } diff --git a/src/ast/nodes/CompoundNode.java b/src/ast/nodes/CompoundNode.java index 2655f35..f0f63f2 100644 --- a/src/ast/nodes/CompoundNode.java +++ b/src/ast/nodes/CompoundNode.java @@ -23,23 +23,23 @@ public class CompoundNode implements Node { } @Override - public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting) { + public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting, FunctionType ft) { ArrayList<SemanticError> errors = new ArrayList<>(); if (ifNode != null) { - errors.addAll(ifNode.checkSemantics(ST, _nesting)); + errors.addAll(ifNode.checkSemantics(ST, _nesting, ft)); } if (funcDef != null) { - errors.addAll(funcDef.checkSemantics(ST, _nesting)); + errors.addAll(funcDef.checkSemantics(ST, _nesting, ft)); } if (forStmt != null) { - errors.addAll(forStmt.checkSemantics(ST, _nesting)); + errors.addAll(forStmt.checkSemantics(ST, _nesting, ft)); } if (whileStmt != null) { - errors.addAll(whileStmt.checkSemantics(ST, _nesting)); + errors.addAll(whileStmt.checkSemantics(ST, _nesting, ft)); } return errors; @@ -50,10 +50,25 @@ public class CompoundNode implements Node { return new VoidType(); } - // TODO: add code generation for CompoundNode @Override public String codeGeneration() { - return ""; + if (ifNode != null) { + return ifNode.codeGeneration(); + } + + if (funcDef != null) { + return funcDef.codeGeneration(); + } + + if (forStmt != null) { + return forStmt.codeGeneration(); + } + + if (whileStmt != null) { + return whileStmt.codeGeneration(); + } + + return "Error: everything is null in Compound node\n"; } @Override diff --git a/src/ast/nodes/DottedNameNode.java b/src/ast/nodes/DottedNameNode.java index 2698b1c..827945a 100644 --- a/src/ast/nodes/DottedNameNode.java +++ b/src/ast/nodes/DottedNameNode.java @@ -19,7 +19,7 @@ public class DottedNameNode implements Node { } @Override - public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting) { + public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting, FunctionType ft) { ArrayList<SemanticError> errors = new ArrayList<>(); for (int i = 0; i < names.size(); ++i) { @@ -34,8 +34,10 @@ public class DottedNameNode implements Node { return new ImportType(); } - // NOTE: we do not provide code generation for this node in the same way - // we do not want to do this for the import stm. + /** + * We do not provide code generation for this node in the same way + * we do not want to do this for the import stm. + */ @Override public String codeGeneration() { return ""; diff --git a/src/ast/nodes/ExprListNode.java b/src/ast/nodes/ExprListNode.java index 4760db8..a3ac237 100644 --- a/src/ast/nodes/ExprListNode.java +++ b/src/ast/nodes/ExprListNode.java @@ -17,11 +17,11 @@ public class ExprListNode implements Node { } @Override - public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting) { + public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting, FunctionType ft) { ArrayList<SemanticError> errors = new ArrayList<>(); for (var expr : exprs) { - errors.addAll(expr.checkSemantics(ST, _nesting)); + errors.addAll(expr.checkSemantics(ST, _nesting, ft)); } return errors; @@ -47,10 +47,15 @@ public class ExprListNode implements Node { return new VoidType(); } - // TODO: code generation for expr list @Override public String codeGeneration() { - return ""; + String str = ""; + + for (var exp : exprs) { + str += exp.codeGeneration(); + } + + return str; } @Override diff --git a/src/ast/nodes/ExprNode.java b/src/ast/nodes/ExprNode.java index 693176a..dec0b54 100644 --- a/src/ast/nodes/ExprNode.java +++ b/src/ast/nodes/ExprNode.java @@ -3,9 +3,11 @@ package ast.nodes; import ast.types.*; import java.util.ArrayList; import java.util.Arrays; + import semanticanalysis.STentry; import semanticanalysis.SemanticError; import semanticanalysis.SymbolTable; +import codegen.Label; /** * Node for the `expr` statement of the grammar. @@ -18,6 +20,10 @@ public class ExprNode implements Node { private final ArrayList<Node> exprs; private final ArrayList<Node> trailers; + // VERY scatchy + private int paramNumber; + private String funL; + public ExprNode(Node atom, Node compOp, ArrayList<Node> exprs, String op, ArrayList<Node> trailers) { this.atom = (AtomNode) atom; this.compOp = compOp; @@ -51,16 +57,15 @@ public class ExprNode implements Node { } @Override - public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting) { + public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting, FunctionType ft) { ArrayList<SemanticError> errors = new ArrayList<>(); + // Check if the atom is a function + if (isFunctionCall()) { - // check if the atom is a function - if (atom != null && !trailers.isEmpty()) { - - // check if the atom is not a built-in function + // Check if the atom is not a built-in function if (!Arrays.asList(bif).contains(atom.getId())) { - errors.addAll(atom.checkSemantics(ST, _nesting)); + errors.addAll(atom.checkSemantics(ST, _nesting, ft)); TrailerNode trailer = (TrailerNode) trailers.get(0); String funName = atom.getId(); @@ -69,14 +74,10 @@ public class ExprNode implements Node { STentry fun = ST.lookup(funName); if (fun != null && !(fun.getType() instanceof ImportType)) { - if (!(fun.getType() instanceof FunctionType)) { - for (var t : trailers) { - errors.addAll(t.checkSemantics(ST, _nesting)); - } - - } else { - FunctionType ft = (FunctionType) fun.getType(); - int paramNumber = ft.getParamNumber(); + if ((fun.getType() instanceof FunctionType)) { + FunctionType atomFt = (FunctionType) fun.getType(); + paramNumber = atomFt.getParamNumber(); + funL = atomFt.getLabel(); int argNumber = trailer.getArgumentNumber(); if (paramNumber != argNumber) { @@ -84,23 +85,25 @@ public class ExprNode implements Node { + " positional arguments but " + String.valueOf(argNumber) + " were given.")); } } + for (var t : trailers) { + errors.addAll(t.checkSemantics(ST, _nesting, ft)); + } } } else { for (var trailer : trailers) { - errors.addAll(trailer.checkSemantics(ST, _nesting)); + errors.addAll(trailer.checkSemantics(ST, _nesting, ft)); } - } } else if (atom != null) { - errors.addAll(atom.checkSemantics(ST, _nesting)); + errors.addAll(atom.checkSemantics(ST, _nesting, ft)); } if (compOp != null) { - errors.addAll(compOp.checkSemantics(ST, _nesting)); + errors.addAll(compOp.checkSemantics(ST, _nesting, ft)); } for (var expr : exprs) { - errors.addAll(expr.checkSemantics(ST, _nesting)); + errors.addAll(expr.checkSemantics(ST, _nesting, ft)); } return errors; @@ -116,10 +119,95 @@ public class ExprNode implements Node { return new VoidType(); } - // TODO: add code generation for expr + public boolean isFunctionCall() { + return atom != null && !trailers.isEmpty(); + } + @Override public String codeGeneration() { - return ""; + + // A function call + if (isFunctionCall()) { + TrailerNode trailer = (TrailerNode) trailers.get(0); + String trailerS = trailer.codeGeneration(); + + // If the atom is a built-in function. return the trailer's content + if (Arrays.asList(bif).contains(atom.getId())) { + return trailerS; + } + + // We're not considering nested functions, so despite of slide 62 + // we do not have a forloop for nesting_level - + // loopkup(..).nesting_level here. + return "pushr FP\n" + + "move SP FP\n" + + "addi FP 1\n" + + "move AL T1\n" + + "pushr T1\n" + + trailerS + + "move FP AL\n" + + "subi AL 1\n" + + "jsub " + funL + "\n"; + } + + // Check operation + if (op != null) { + switch (op) { + case "+": + case "-": + case "*": + // In real Python `/` is a float division but we'll consider the + // int division here below. + case "/": + return intOpCodeGen(exprs.get(0), exprs.get(1), op); + case "%": + return modCodeGen(exprs.get(0), exprs.get(1)); + case "and": + return andCodeGen(exprs.get(0), exprs.get(1)); + case "or": + return orCodeGen(exprs.get(0), exprs.get(1)); + case "not": + return notCodeGen(exprs.get(0)); + default: + return "Error: operation " + op + " not supported\n"; + } + } + + // Check comp operation + if (compOp != null) { + CompOpNode cmpOp = (CompOpNode) compOp; + String op = cmpOp.getOp(); + switch (op) { + case "==": + return eqCodeGen(exprs.get(0), exprs.get(1)); + case "!=": + return neqCodeGen(exprs.get(0), exprs.get(1)); + case "<": + return lsCodeGen(exprs.get(0), exprs.get(1)); + case "<=": + return leqCodeGen(exprs.get(0), exprs.get(1)); + case ">": + return gtCodeGen(exprs.get(0), exprs.get(1)); + case ">=": + return gteCodeGen(exprs.get(0), exprs.get(1)); + default: + return "Error: operation " + op + " not supported\n"; + } + } + + if (atom != null) { + return atom.codeGeneration(); + } + + if (!exprs.isEmpty()) { + String str = ""; + for (var expr : exprs) { + str += expr.codeGeneration(); + } + return str; + } + + return "Error: cannot recognize the expression\n"; } @Override @@ -133,19 +221,19 @@ public class ExprNode implements Node { if (compOp != null) { str += compOp.toPrint(prefix); } - + if (exprs != null) { for (var expr : exprs) { str += expr.toPrint(prefix); } } - + if (trailers != null) { for (var trailer : trailers) { str += trailer.toPrint(prefix); } - } - + } + if (op != null) { str += prefix + "Op(" + op + ")\n"; } @@ -153,4 +241,220 @@ public class ExprNode implements Node { return str; } + private String intOpCodeGen(Node leftE, Node rightE, String op) { + String ls = leftE.codeGeneration(); + String rs = rightE.codeGeneration(); + String ops; + + switch (op) { + case "+": + ops = "add"; + break; + case "-": + ops = "sub"; + break; + case "*": + ops = "mul"; + break; + case "/": + ops = "div"; + break; + default: + ops = "Error: cannot manage op " + op; + } + + return ls + + "pushr A0\n" + + rs + + "popr T1\n" + + ops + " T1 A0\n" + + "popr A0\n"; + } + + private String modCodeGen(Node leftE, Node rightE) { + String ls = leftE.codeGeneration(); + String rs = rightE.codeGeneration(); + + // Push the register twice because, for instance, + // 7 % 2 = + // 7 / 2 = 3 + // 3 * 2 = 6 + // 7 - 6 = 1 <--- result + return ls + + "pushr A0\n" + + "pushr A0\n" + + rs + + "popr T1\n" + + // Divide the two numbers + "div T1 A0\n" + + "popr T1\n" + + // Multiply the division result for the number at the left + "mul T1 A0\n" + + "popr A0\n" + + // Get the previous number at the left from the stack + "popr T1\n" + + // Subtracting the two numbers we have the module value + "sub T1 A0\n" + + "popr A0\n"; + } + + /** + * NOTE: for the boolean operation we assume that False = 0, True = 1 + * NOTE: we should optimize ignoring the the right value if the left value + * is false. + */ + private String andCodeGen(Node leftE, Node rightE) { + String endl = Label.newBasic("endAnd"); + String ls = leftE.codeGeneration(); + String rs = rightE.codeGeneration(); + return ls + + "storei T1 0\n" + + "beq A0 T1 " + endl + "\n" + + rs + + endl + ":\n"; + } + + /** + * NOTE: we should optimize ignoring the right value if the left value is + * true. + */ + private String orCodeGen(Node leftE, Node rightE) { + String endl = Label.newBasic("endOr"); + String ls = leftE.codeGeneration(); + String rs = rightE.codeGeneration(); + return ls + + "storei T1 1\n" + + "beq A0 T1 " + endl + "\n" + + rs + + endl + ":\n"; + } + + private String notCodeGen(Node expr) { + String exprs = expr.codeGeneration(); + // We use the `sub` because: + // not True = 1 - 1 = 0 = False + // not False = 1 - 0 = 1 = True + return exprs + + "storei T1 1\n" + + "sub T1 A0\n" + + "popr A0\n"; + } + + private String eqCodeGen(Node leftE, Node rightE) { + String truel = Label.newBasic("true"); + String endl = Label.newBasic("end"); + String ls = leftE.codeGeneration(); + String rs = rightE.codeGeneration(); + return ls + + "pushr A0\n" + + rs + + "popr T1\n" + + "beq T1 A0 " + truel + "\n" + + "storei A0 0\n" + + "b " + endl + "\n" + + truel + ":\n" + + "storei A0 1\n" + + endl + ":\n"; + } + + private String neqCodeGen(Node leftE, Node rightE) { + String truel = Label.newBasic("true"); + String endl = Label.newBasic("end"); + String ls = leftE.codeGeneration(); + String rs = rightE.codeGeneration(); + return ls + + "pushr A0\n" + + rs + + "popr T1\n" + + "beq T1 A0 " + truel + "\n" + + "storei A0 1\n" + + // storei A0 1 instead of storei A0 0 + "b " + endl + "\n" + + truel + ":\n" + + // storei A0 0 instead of storei A0 1 + "storei A0 0\n" + + endl + ":\n"; + } + + private String lsCodeGen(Node leftE, Node rightE) { + String truel = Label.newBasic("true"); + String truel2 = Label.newBasic("true"); + String endl = Label.newBasic("end"); + String ls = leftE.codeGeneration(); + String rs = rightE.codeGeneration(); + return ls + + "pushr A0\n" + + rs + + "popr T1\n" + + "bleq T1 A0 " + truel + "\n" + + "storei A0 0\n" + + "b " + endl + "\n" + + truel + ":\n" + + "beq T1 A0 " + truel2 + "\n" + + "storei A0 1\n" + + "b " + endl + "\n" + + truel2 + ":\n" + + "storei A0 0\n" + + "b " + endl + "\n" + + endl + ":\n"; + } + + private String leqCodeGen(Node leftE, Node rightE) { + String truel = Label.newBasic("true"); + String endl = Label.newBasic("end"); + String ls = leftE.codeGeneration(); + String rs = rightE.codeGeneration(); + return ls + + "pushr A0\n" + + rs + + "popr T1\n" + + "bleq T1 A0 " + truel + "\n" + + "storei A0 0\n" + + "b " + endl + "\n" + + truel + ":\n" + + "storei A0 1\n" + + endl + ":\n"; + } + + private String gtCodeGen(Node leftE, Node rightE) { + String truel = Label.newBasic("true"); + String endl = Label.newBasic("end"); + String ls = leftE.codeGeneration(); + String rs = rightE.codeGeneration(); + return ls + + "pushr A0\n" + + rs + + "popr T1\n" + + // Invert A0 and T1 (different than leq) + "bleq A0 T1 " + truel + "\n" + + "storei A0 0\n" + + "b " + endl + "\n" + + truel + ":\n" + + "storei A0 1\n" + + endl + ":\n"; + } + + private String gteCodeGen(Node leftE, Node rightE) { + String truel = Label.newBasic("true"); + String truel2 = Label.newBasic("true"); + String endl = Label.newBasic("end"); + String ls = leftE.codeGeneration(); + String rs = rightE.codeGeneration(); + return ls + + "pushr A0\n" + + rs + + "popr T1\n" + + "bleq T1 A0 " + truel + "\n" + + "storei A0 1\n" + + "b " + endl + "\n" + + truel + ":\n" + + "beq T1 A0 " + truel2 + "\n" + + "storei A0 0\n" + + "b " + endl + "\n" + + truel2 + ":\n" + + "storei A0 1\n" + + "b " + endl + "\n" + + endl + ":\n"; + } + } diff --git a/src/ast/nodes/ForStmtNode.java b/src/ast/nodes/ForStmtNode.java index 50574f0..507d314 100644 --- a/src/ast/nodes/ForStmtNode.java +++ b/src/ast/nodes/ForStmtNode.java @@ -33,7 +33,7 @@ public class ForStmtNode implements Node { * an atom. */ @Override - public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting) { + public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting, FunctionType ft) { ArrayList<SemanticError> errors = new ArrayList<>(); // Save every atom in the expression's list, except the last one @@ -52,8 +52,8 @@ public class ForStmtNode implements Node { // ENHANCE: check that the comp_op is the `in` keyword ST.insert(atomLeft.getId(), atomLeft.typeCheck(), _nesting, ""); - errors.addAll(exprList.checkSemantics(ST, _nesting)); - errors.addAll(block.checkSemantics(ST, _nesting)); + errors.addAll(exprList.checkSemantics(ST, _nesting, ft)); + errors.addAll(block.checkSemantics(ST, _nesting, ft)); return errors; } @@ -63,7 +63,10 @@ public class ForStmtNode implements Node { return new VoidType(); } - // TODO: add code generation for while + /** + * We do not provide the cgen for the `for_stm` because we do not have the + * iterators idea that the real Python has. + */ @Override public String codeGeneration() { return ""; diff --git a/src/ast/nodes/FuncdefNode.java b/src/ast/nodes/FuncdefNode.java index 91231cc..c2671b2 100644 --- a/src/ast/nodes/FuncdefNode.java +++ b/src/ast/nodes/FuncdefNode.java @@ -8,6 +8,7 @@ import semanticanalysis.SemanticError; import semanticanalysis.SymbolTable; import ast.types.*; import org.antlr.v4.runtime.tree.TerminalNode; +import codegen.Label; /** * Node for the `funcdef` statement of the grammar. @@ -17,38 +18,45 @@ public class FuncdefNode implements Node { private final TerminalNode name; private final Node paramlist; private final Node block; + private final String funLabel; public FuncdefNode(TerminalNode name, Node paramlist, Node block) { this.name = name; this.paramlist = paramlist; this.block = block; + this.funLabel = Label.newFun("FUN"); } @Override - public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting) { + public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting, FunctionType ft) { ArrayList<SemanticError> errors = new ArrayList<>(); - int paramNumber = ((ParamlistNode) paramlist).getParamNumber(); + int paramNumber = 0; + if (paramlist != null) { + paramNumber = ((ParamlistNode) paramlist).getParamNumber(); + } Type returnType = this.block.typeCheck(); - FunctionType ft = new FunctionType(paramNumber, returnType); + FunctionType newFt = new FunctionType(paramNumber, returnType, funLabel); - ST.insert(this.name.toString(), ft, _nesting, ""); + String funName = this.name.toString(); + ST.insert(funName, newFt, _nesting, ""); HashMap<String, STentry> HM = new HashMap<>(); ST.add(HM); - ST.insert(this.name.toString(), ft, _nesting + 1, ""); + ST.insert(funName, newFt, _nesting + 1, ""); + ST.decreaseOffset(); if (paramlist != null) { - errors.addAll(paramlist.checkSemantics(ST, _nesting + 1)); + errors.addAll(paramlist.checkSemantics(ST, _nesting + 1, newFt)); } - // TODO: think to the fucking offset // Offset is increased for the possible return value - ST.increaseoffset(); + ST.increaseOffset(); - errors.addAll(block.checkSemantics(ST, _nesting + 1)); + errors.addAll(block.checkSemantics(ST, _nesting + 1, newFt)); + // return to the outer block ST.remove(); return errors; @@ -60,9 +68,18 @@ public class FuncdefNode implements Node { return new VoidType(); } - // TODO: code generation for funcdef + /** + * Taken from slide 56 of CodeGeneration.pdf + */ @Override public String codeGeneration() { + String blockS = block.codeGeneration(); + // The "return" which fix the RA is inside the block + String funS = funLabel + ":\n" + + "pushr RA\n" + + blockS; + + Label.addFunDef(funS); return ""; } diff --git a/src/ast/nodes/IfNode.java b/src/ast/nodes/IfNode.java index 223dffb..ca42b7a 100644 --- a/src/ast/nodes/IfNode.java +++ b/src/ast/nodes/IfNode.java @@ -4,6 +4,7 @@ import ast.types.*; import java.util.ArrayList; import semanticanalysis.SemanticError; import semanticanalysis.SymbolTable; +import codegen.Label; /** * Node for the `if` statement of the grammar. @@ -11,23 +12,23 @@ import semanticanalysis.SymbolTable; public class IfNode implements Node { private final Node guard; - private final Node thenbranch; - private final Node elsebranch; + private final Node thenBranch; + private final Node elseBranch; - public IfNode(Node guard, Node thenbranch, Node elsebranch) { + public IfNode(Node guard, Node thenBranch, Node elseBranch) { this.guard = guard; - this.thenbranch = thenbranch; - this.elsebranch = elsebranch; + this.thenBranch = thenBranch; + this.elseBranch = elseBranch; } @Override - public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting) { + public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting, FunctionType ft) { ArrayList<SemanticError> errors = new ArrayList<>(); - errors.addAll(guard.checkSemantics(ST, _nesting)); - errors.addAll(thenbranch.checkSemantics(ST, _nesting)); - if (elsebranch != null) { - errors.addAll(elsebranch.checkSemantics(ST, _nesting)); + errors.addAll(guard.checkSemantics(ST, _nesting, ft)); + errors.addAll(thenBranch.checkSemantics(ST, _nesting, ft)); + if (elseBranch != null) { + errors.addAll(elseBranch.checkSemantics(ST, _nesting, ft)); } return errors; @@ -37,11 +38,11 @@ public class IfNode implements Node { @Override public Type typeCheck() { if (guard.typeCheck() instanceof BoolType) { - Type thenexp = thenbranch.typeCheck(); - Type elseexp = elsebranch.typeCheck(); + Type thenexp = thenBranch.typeCheck(); + Type elseexp = elseBranch.typeCheck(); if (thenexp.getClass().equals(elseexp.getClass())) { - return thenexp; - }else { + return thenexp; + } else { System.out.println("Type Error: incompatible types in then and else branches."); return new ErrorType(); } @@ -51,18 +52,37 @@ public class IfNode implements Node { } } - // TODO: add code generation for if @Override public String codeGeneration() { - return ""; + String thenLabel = Label.newBasic("then"); + String endLabel = Label.newBasic("end"); + + String guardS = guard.codeGeneration(); + String thenS = thenBranch.codeGeneration(); + String elseS = ""; + if (elseBranch != null) { + elseS = elseBranch.codeGeneration(); + } + + // We're assuming that the guard is boolean or an operation which puts a + // true (1) or false (0) into A0. + return guardS + + "storei T1 1\n" + + // Check if A0 = true + "beq A0 T1 " + thenLabel + "\n" + + elseS + + "b " + endLabel + "\n" + + thenLabel + ":\n" + + thenS + + endLabel + ":\n"; } @Override public String toPrint(String prefix) { - String str = prefix + "If\n" + guard.toPrint(prefix + " ") + thenbranch.toPrint(prefix + " "); + String str = prefix + "If\n" + guard.toPrint(prefix + " ") + thenBranch.toPrint(prefix + " "); - if (elsebranch != null) { - str += elsebranch.toPrint(prefix + " "); + if (elseBranch != null) { + str += elseBranch.toPrint(prefix + " "); } return str; diff --git a/src/ast/nodes/ImportNode.java b/src/ast/nodes/ImportNode.java index f26c0d0..97e3404 100644 --- a/src/ast/nodes/ImportNode.java +++ b/src/ast/nodes/ImportNode.java @@ -26,7 +26,7 @@ public class ImportNode implements Node { } @Override - public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting) { + public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting, FunctionType ft) { ArrayList<SemanticError> errors = new ArrayList<>(); if (isFrom) { @@ -34,7 +34,7 @@ public class ImportNode implements Node { ST.insert(names.get(i), this.typeCheck(), _nesting, null); } } else { - errors.addAll(dottedName.checkSemantics(ST, _nesting)); + errors.addAll(dottedName.checkSemantics(ST, _nesting, ft)); } if (importAs) { @@ -49,7 +49,9 @@ public class ImportNode implements Node { return new ImportType(); } - // NOTE: we do not want to provide a code generation for this statement + /** + * NOTE: we do not want to provide a code generation for this statement + */ @Override public String codeGeneration() { return ""; diff --git a/src/ast/nodes/Node.java b/src/ast/nodes/Node.java index 9fb58b8..0e58093 100644 --- a/src/ast/nodes/Node.java +++ b/src/ast/nodes/Node.java @@ -88,7 +88,7 @@ public interface Node { * Checks semantics for a given node for a SymbolTable ST and a level of * nesting. Returns a list of `SemanticError`. */ - ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting); + ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting, FunctionType ft); /** * Checks the type for a given node. If there's any error, returns an diff --git a/src/ast/nodes/ParamdefNode.java b/src/ast/nodes/ParamdefNode.java index e5694fa..4bba772 100644 --- a/src/ast/nodes/ParamdefNode.java +++ b/src/ast/nodes/ParamdefNode.java @@ -16,7 +16,7 @@ public class ParamdefNode extends AtomNode { } @Override - public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting) { + public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting, FunctionType ft) { ArrayList<SemanticError> errors = new ArrayList<>(); String paramName = this.getId(); diff --git a/src/ast/nodes/ParamlistNode.java b/src/ast/nodes/ParamlistNode.java index e8c9a42..9e8d75c 100644 --- a/src/ast/nodes/ParamlistNode.java +++ b/src/ast/nodes/ParamlistNode.java @@ -12,16 +12,16 @@ public class ParamlistNode implements Node { private final ArrayList<Node> params; - public ParamlistNode(ArrayList<Node> _params) { - params = _params; + public ParamlistNode(ArrayList<Node> params) { + this.params = params; } @Override - public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting) { + public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting, FunctionType ft) { ArrayList<SemanticError> errors = new ArrayList<>(); for (var param : params) { - errors.addAll(param.checkSemantics(ST, _nesting)); + errors.addAll(param.checkSemantics(ST, _nesting, ft)); } return errors; @@ -36,7 +36,6 @@ public class ParamlistNode implements Node { return new VoidType(); } - // TODO: code generation for param list @Override public String codeGeneration() { return ""; diff --git a/src/ast/nodes/ReturnStmtNode.java b/src/ast/nodes/ReturnStmtNode.java index bb49ded..15c8d69 100644 --- a/src/ast/nodes/ReturnStmtNode.java +++ b/src/ast/nodes/ReturnStmtNode.java @@ -1,7 +1,9 @@ package ast.nodes; import ast.types.*; + import java.util.ArrayList; + import semanticanalysis.SemanticError; import semanticanalysis.SymbolTable; @@ -12,16 +14,23 @@ public class ReturnStmtNode implements Node { private final Node exprList; + // VERY scatchy + private int localvar; + private int paramNumber; + public ReturnStmtNode(Node exprList) { this.exprList = exprList; } @Override - public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting) { + public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting, FunctionType ft) { ArrayList<SemanticError> errors = new ArrayList<>(); + // If I am in a "return", `ft` will be null. + this.localvar = ft.getLocalvarNum(); + this.paramNumber = ft.getParamNumber(); if (this.exprList != null) { - errors.addAll(this.exprList.checkSemantics(ST, _nesting)); + errors.addAll(this.exprList.checkSemantics(ST, _nesting, ft)); } return errors; @@ -36,10 +45,21 @@ public class ReturnStmtNode implements Node { return new VoidType(); } - // TODO: add code generation for return stmt @Override public String codeGeneration() { - return ""; + String expS = exprList.codeGeneration(); + for (int i = 0; i < localvar; i++) { + expS += "pop\n"; + } + return expS + + "popr RA\n" + + "addi SP " + paramNumber + "\n" + + "pop\n" + + "store FP 0(FP)\n" + + "move FP AL\n" + + "subi AL 1\n" + + "pop\n" + + "rsub RA\n"; } @Override diff --git a/src/ast/nodes/RootNode.java b/src/ast/nodes/RootNode.java index 26778f4..9cad871 100644 --- a/src/ast/nodes/RootNode.java +++ b/src/ast/nodes/RootNode.java @@ -1,6 +1,8 @@ package ast.nodes; import ast.types.*; +import codegen.Label; + import java.util.ArrayList; import java.util.HashMap; import semanticanalysis.*; @@ -19,7 +21,7 @@ public class RootNode implements Node { } @Override - public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting) { + public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting, FunctionType ft) { ArrayList<SemanticError> errors = new ArrayList<>(); // Create a new HashMap for the current scope @@ -30,7 +32,7 @@ public class RootNode implements Node { // Check semantics for each child for (Node child : childs) { - errors.addAll(child.checkSemantics(ST, _nesting)); + errors.addAll(child.checkSemantics(ST, _nesting, ft)); } // Remove the HashMap from the SymbolTable @@ -44,10 +46,16 @@ public class RootNode implements Node { return new VoidType(); } - // TODO: Code generation for RootNode @Override public String codeGeneration() { - return ""; + // Workaround per SP = MEM - 1 + String str = "pushr FP\npushr AL\n"; + + for (Node child : childs) { + str += child.codeGeneration(); + } + + return str + "halt\n" + Label.getFunDef(); } @Override diff --git a/src/ast/nodes/SimpleStmtNode.java b/src/ast/nodes/SimpleStmtNode.java index fbeeb1b..31a935f 100644 --- a/src/ast/nodes/SimpleStmtNode.java +++ b/src/ast/nodes/SimpleStmtNode.java @@ -23,23 +23,23 @@ public class SimpleStmtNode implements Node { } @Override - public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting) { + public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting, FunctionType ft) { ArrayList<SemanticError> errors = new ArrayList<>(); if (assignment != null) { - errors.addAll(assignment.checkSemantics(ST, _nesting)); + errors.addAll(assignment.checkSemantics(ST, _nesting, ft)); } if (expr != null) { - errors.addAll(expr.checkSemantics(ST, _nesting)); + errors.addAll(expr.checkSemantics(ST, _nesting, ft)); } if (returnStmt != null) { - errors.addAll(returnStmt.checkSemantics(ST, _nesting)); + errors.addAll(returnStmt.checkSemantics(ST, _nesting, ft)); } if (importStmt != null) { - errors.addAll(importStmt.checkSemantics(ST, _nesting)); + errors.addAll(importStmt.checkSemantics(ST, _nesting, ft)); } return errors; @@ -50,10 +50,26 @@ public class SimpleStmtNode implements Node { return new VoidType(); } - // TODO: add code generation for SimpleStmtNode @Override public String codeGeneration() { - return ""; + if (assignment != null) { + return assignment.codeGeneration(); + } + + if (expr != null) { + return expr.codeGeneration(); + } + + if (returnStmt != null) { + return returnStmt.codeGeneration(); + } + + // Not supported + // if (importStmt != null) { + // return importStmt.codeGeneration(); + // } + + return "Error: everything is null in Compound node"; } @Override diff --git a/src/ast/nodes/SimpleStmtsNode.java b/src/ast/nodes/SimpleStmtsNode.java index 5377c5d..8e5c924 100644 --- a/src/ast/nodes/SimpleStmtsNode.java +++ b/src/ast/nodes/SimpleStmtsNode.java @@ -17,11 +17,11 @@ public class SimpleStmtsNode implements Node { } @Override - public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting) { + public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting, FunctionType ft) { ArrayList<SemanticError> errors = new ArrayList<>(); for (Node stmt : stmts) { - errors.addAll(stmt.checkSemantics(ST, _nesting)); + errors.addAll(stmt.checkSemantics(ST, _nesting, ft)); } return errors; @@ -32,10 +32,15 @@ public class SimpleStmtsNode implements Node { return new VoidType(); } - // TODO: Code generation for SimpleStmtsNode @Override public String codeGeneration() { - return ""; + String str = ""; + + for (Node stmt : stmts) { + str += stmt.codeGeneration(); + } + + return str; } @Override diff --git a/src/ast/nodes/TestlistCompNode.java b/src/ast/nodes/TestlistCompNode.java index 32049f5..e55f854 100644 --- a/src/ast/nodes/TestlistCompNode.java +++ b/src/ast/nodes/TestlistCompNode.java @@ -19,22 +19,23 @@ public class TestlistCompNode implements Node { } @Override - public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting) { + public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting, FunctionType ft) { ArrayList<SemanticError> errors = new ArrayList<>(); if (comp != null) { - // if comp is set, then we save the atom in the ST (we assume the first expr is - // an atom) + // If comp is set, then we save the atom in the ST (we assume the first expr is + // an atom). We ignore the `comp.checkSemantics()`. 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 + // If comp is not set, then exprs is a list of 1 or more element for (var param : exprs) { var exp = (ExprNode) param; - ST.insert(exp.getId(), exp.typeCheck(), _nesting, ""); - errors.addAll(param.checkSemantics(ST, _nesting)); + if (exp.getId() != null && !exp.isFunctionCall()) { + ST.insert(exp.getId(), exp.typeCheck(), _nesting, ""); + } + errors.addAll(param.checkSemantics(ST, _nesting, ft)); } } @@ -61,10 +62,13 @@ public class TestlistCompNode implements Node { return new VoidType(); } - // TODO: code generation for expr list @Override public String codeGeneration() { - return ""; + String str = ""; + for (var param : exprs) { + str += param.codeGeneration(); + } + return str; } @Override diff --git a/src/ast/nodes/TrailerNode.java b/src/ast/nodes/TrailerNode.java index d8301b8..d70e962 100644 --- a/src/ast/nodes/TrailerNode.java +++ b/src/ast/nodes/TrailerNode.java @@ -28,15 +28,15 @@ public class TrailerNode implements Node { } @Override - public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting) { + public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting, FunctionType ft) { ArrayList<SemanticError> errors = new ArrayList<>(); if (arglist != null) { - errors.addAll(arglist.checkSemantics(ST, _nesting)); + errors.addAll(arglist.checkSemantics(ST, _nesting, ft)); } for (var expr : exprs) { - errors.addAll(expr.checkSemantics(ST, _nesting)); + errors.addAll(expr.checkSemantics(ST, _nesting, ft)); } return errors; @@ -59,9 +59,11 @@ public class TrailerNode implements Node { return new VoidType(); } - // TODO: add code generation for trailer node @Override public String codeGeneration() { + if (arglist != null) { + return arglist.codeGeneration(); + } return ""; } diff --git a/src/ast/nodes/WhileStmtNode.java b/src/ast/nodes/WhileStmtNode.java index 352cbc0..d371046 100644 --- a/src/ast/nodes/WhileStmtNode.java +++ b/src/ast/nodes/WhileStmtNode.java @@ -19,11 +19,11 @@ public class WhileStmtNode implements Node { } @Override - public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting) { + public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting, FunctionType ft) { ArrayList<SemanticError> errors = new ArrayList<>(); - errors.addAll(expr.checkSemantics(ST, _nesting)); - errors.addAll(block.checkSemantics(ST, _nesting)); + errors.addAll(expr.checkSemantics(ST, _nesting, ft)); + errors.addAll(block.checkSemantics(ST, _nesting, ft)); return errors; } @@ -33,7 +33,7 @@ public class WhileStmtNode implements Node { return new VoidType(); } - // TODO: add code generation for while + // TODO: add cgen per while (but it's not requested from the exercise) @Override public String codeGeneration() { return ""; diff --git a/src/ast/types/FunctionType.java b/src/ast/types/FunctionType.java index 5e6adaa..1a04bb6 100644 --- a/src/ast/types/FunctionType.java +++ b/src/ast/types/FunctionType.java @@ -7,13 +7,25 @@ public class FunctionType extends Type { private final int paramNumber; private final Type returnType; + private final String label; + private int localvarNum; - public FunctionType(int paramNumber, Type returnType) { + public FunctionType(int paramNumber, Type returnType, String label) { this.paramNumber = paramNumber; this.returnType = returnType; + this.label = label; + this.localvarNum = 0; } - // Return the length of the parameters + public void addLocalVar() { + localvarNum++; + } + + public int getLocalvarNum() { + return localvarNum; + } + + // Return the number of the parameters public int getParamNumber() { return paramNumber; } @@ -22,8 +34,17 @@ public class FunctionType extends Type { return returnType; } + public String getLabel() { + return label; + } + @Override public String toPrint(String prefix) { return prefix + "Function\n"; } + + @Override + public String toString() { + return "NP: " + paramNumber + " RT: " + returnType + " L: " + label; + } } diff --git a/src/ast/types/Type.java b/src/ast/types/Type.java index 6190106..c5b8312 100644 --- a/src/ast/types/Type.java +++ b/src/ast/types/Type.java @@ -20,7 +20,7 @@ public class Type implements Node { } @Override - public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting) { + public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting, FunctionType ft) { // It is never invoked return null; } diff --git a/src/codegen/Label.java b/src/codegen/Label.java new file mode 100644 index 0000000..52977c7 --- /dev/null +++ b/src/codegen/Label.java @@ -0,0 +1,32 @@ +package codegen; + +public class Label { + + private static String funDef = ""; + private static int labelCounter = 0; + private static int functionLabelCounter = 0; + + public static void addFunDef(String s) { + funDef += s; + } + + public static String getFunDef() { + return funDef; + } + + /** + * Create a new basic label. Use this method to define labels for if, while and + * for statemests. + */ + public static String newBasic(String base) { + return base + (labelCounter++); + } + + /** + * Create a new label for a function definition. + */ + public static String newFun(String base) { + return base + (functionLabelCounter++); + } + +} diff --git a/src/semanticanalysis/SymbolTable.java b/src/semanticanalysis/SymbolTable.java index 50309a5..5a28b66 100644 --- a/src/semanticanalysis/SymbolTable.java +++ b/src/semanticanalysis/SymbolTable.java @@ -128,13 +128,12 @@ public class SymbolTable { offs = offs + 1; this.offset.add(offs); - } /** * Increase the offset level. */ - public void increaseoffset() { + public void increaseOffset() { int n = this.offset.size() - 1; int offs = this.offset.get(n); this.offset.remove(n); @@ -144,10 +143,23 @@ public class SymbolTable { this.offset.add(offs); } + /** + * Decrease the offset level. + */ + public void decreaseOffset() { + int n = this.offset.size() - 1; + int offs = this.offset.get(n); + this.offset.remove(n); + + offs = offs - 1; + + this.offset.add(offs); + } + @Override public String toString() { // Print the symbol table - String str = ""; + String str = "ST "; for (int i = 0; i < this.symbolTable.size(); i++) { str += "Level " + i + "\n"; HashMap<String, STentry> H = this.symbolTable.get(i); @@ -159,4 +171,10 @@ public class SymbolTable { return str; } + + @Override + public SymbolTable clone() throws CloneNotSupportedException { + Object obj = super.clone(); + return (SymbolTable) obj; + } } diff --git a/src/svm/AssemblyClass.java b/src/svm/AssemblyClass.java new file mode 100644 index 0000000..219c748 --- /dev/null +++ b/src/svm/AssemblyClass.java @@ -0,0 +1,74 @@ +package svm ; + +public class AssemblyClass { + private int code; + private String arg1; + private String arg2; + private String arg3; + + public AssemblyClass(int _code, String _arg1, String _arg2, String _arg3) { + code = _code; + arg1 = _arg1; + arg2 = _arg2; + arg3 = _arg3; + } + + public int getCode() { + return code; + } + + public void setCode(int _code) { + code = _code; + } + /* + AssemblyClass assemblyClass(String o) { + this.operation = o; + return this; + } + + AssemblyClass assemblyClass(String o, String a1) { + this.operation = o; + this.arg1 = a1; + return this; + } + + AssemblyClass assemblyClass(String o, String a1, String a2) { + this.operation = o; + this.arg1 = a1; + this.arg2 = a2; + return this; + } + + AssemblyClass AssemblyClass(String o, String a1, String a2, String a3) { + this.operation = o; + this.arg1 = a1; + this.arg2 = a2; + this.arg3 = a3; + return this; + } +*/ + +// public String getOperation() { +// return operation; +// } + + public String getArg1() { + return arg1; + } + + public void setArg1(String _arg1) { + arg1 = _arg1; + } + + public String getArg2() { + return arg2; + } + + public String getArg3() { + return arg3; + } + + public void setArg3(String _arg3) { + arg3 = _arg3; + } +}
\ No newline at end of file diff --git a/src/svm/ExecuteVM.java b/src/svm/ExecuteVM.java new file mode 100755 index 0000000..d3dec33 --- /dev/null +++ b/src/svm/ExecuteVM.java @@ -0,0 +1,234 @@ +package svm; + +import java.util.concurrent.TimeUnit; + +public class ExecuteVM { + + public static final int CODESIZE = 1000 ; + public static final int MEMSIZE = 1000 ; //10000; + + private AssemblyClass[] code; + private int[] memory = new int[MEMSIZE]; + + private int ip = 0; // instruction pointer + private int sp = MEMSIZE-1 ; // stack pointer + private int al = MEMSIZE-2 ; // access link + private int fp = MEMSIZE-1 ; // frame pointer + private int ra; // return address + private int a0; // the register for values of expressions + private int t1; // temporary register + private int t2; // additional temporary register, just in case + + public ExecuteVM(AssemblyClass[] _code) { + code = _code ; + } + + + public void StampaMem(int _j){ + System.out.print(_j + ": " + code[ip].getCode()) ; + for (int i = MEMSIZE-1; i > sp ; i--){ + System.out.print("\t" + memory[i]) ; + } + System.out.println(" ----- " + "SP = " + sp + ", FP = " + fp + ", AL = " + al + ", RA = " + ra + ", A0 = " + a0 + ", T1 = " + t1 ) ; + } + + public int read(String _strg) { + int tmp ; + switch (_strg) { + case "IP": + tmp = ip ; + break ; + case "SP": + tmp = sp ; + break ; + case "AL": + tmp = al ; + break ; + case "FP": + tmp = fp ; + break ; + case "RA": + tmp = ra ; + break ; + case "A0": + tmp = a0 ; + break ; + case "T1": + tmp = t1 ; + break ; + case "T2": + tmp = t2 ; + break ; + default : + tmp = -99999 ; // error value + break ; + } + return tmp ; + } + + public void update(String _strg, int _val) { + switch (_strg) { + case "IP": + ip = _val ; + break ; + case "SP": + sp = _val ; + break ; + case "AL": + al = _val ; + break ; + case "FP": + fp = _val ; + break ; + case "RA": + ra = _val ; + break ; + case "A0": + a0 = _val; + break ; + case "T1": + t1 = _val ; + break ; + case "T2": + t2 = _val ; + break ; + default : + // error value + break ; + } + } + + public void cpu() { + int j = 0 ; + + while ( true ) { + // try { + // TimeUnit.SECONDS.sleep(1); + // } catch (InterruptedException e) { + // // TODO Auto-generated catch block + // e.printStackTrace(); + // } + StampaMem(j) ; j=j+1 ; + AssemblyClass bytecode = code[ip] ; // fetch + int tmp ; + int address; + switch ( bytecode.getCode() ) { + case SVMParser.PUSH: + push(Integer.parseInt(bytecode.getArg1())) ; + ip = ip+1 ; + break; + case SVMParser.PUSHR: + push(read(bytecode.getArg1())); + ip = ip+1 ; + break ; + case SVMParser.POP: + pop(); + ip = ip+1 ; + break; + case SVMParser.LOAD: + tmp = read(bytecode.getArg3()) + Integer.parseInt(bytecode.getArg2()) ; + if ((tmp < 0) || (tmp >= MEMSIZE)) { + System.out.println("\nError: Null pointer exception1"); + return; + } else { + memory[tmp] = read(bytecode.getArg1()) ; + ip = ip+1 ; + break; + } + case SVMParser.STOREI: + update(bytecode.getArg1(), Integer.parseInt(bytecode.getArg2())) ; + ip = ip+1 ; + break; + case SVMParser.STORE: + tmp = read(bytecode.getArg3()) + Integer.parseInt(bytecode.getArg2()); + if ((tmp < 0) || (tmp >= MEMSIZE)) { + System.out.println("\nError: Null pointer exception2"); + return; + } else { + update(bytecode.getArg1(), memory[tmp]); + ip = ip+1 ; + break; + } + case SVMParser.MOVE: + update(bytecode.getArg2(), read(bytecode.getArg1())) ; + ip = ip+1 ; + break; + case SVMParser.ADD: + push(read(bytecode.getArg1()) + read(bytecode.getArg2())) ; + ip = ip+1 ; + break; + case SVMParser.ADDI: + update(bytecode.getArg1(), read(bytecode.getArg1()) + Integer.parseInt(bytecode.getArg2()) ); + ip = ip+1 ; + break; + case SVMParser.SUB: + push(read(bytecode.getArg1()) - read(bytecode.getArg2())); + ip = ip+1 ; + break; + case SVMParser.SUBI: + update(bytecode.getArg1(), read(bytecode.getArg1()) - Integer.parseInt(bytecode.getArg2()) ); + ip = ip+1 ; + break; + case SVMParser.MUL: + push(read(bytecode.getArg1()) * read(bytecode.getArg2())); + ip = ip+1 ; + break; + case SVMParser.MULI: + update(bytecode.getArg1(), read(bytecode.getArg1()) * Integer.parseInt(bytecode.getArg2()) ) ; + ip = ip+1 ; + break; + case SVMParser.DIV: + push(read(bytecode.getArg1()) / read(bytecode.getArg2())); + ip = ip+1 ; + break; + case SVMParser.DIVI: + update(bytecode.getArg1(), read(bytecode.getArg1()) / Integer.parseInt(bytecode.getArg2()) ); + ip = ip+1 ; + break; + case SVMParser.POPR : // + update(bytecode.getArg1(), memory[sp+1]); + pop() ; + ip = ip+1 ; + break; + case SVMParser.BRANCH: + address = ip + 1; + ip = code[address].getCode() ; + break; + case SVMParser.BRANCHEQ : // + if (read(bytecode.getArg1()) == read(bytecode.getArg2())){ + address = ip+1; + ip = code[address].getCode() ; + } else ip = ip+2 ; + break; + case SVMParser.BRANCHLESSEQ : + if (read(bytecode.getArg1()) <= read(bytecode.getArg2())){ + address = ip+1; + ip = code[address].getCode() ; + } else ip = ip+2 ; + break; + case SVMParser.JUMPSUB : + ra = ip+1 ; + address = ip ; + ip = Integer.parseInt(code[address].getArg1()) ; + break; + case SVMParser.RETURNSUB: + ip = read(bytecode.getArg1()) ; + break; + case SVMParser.HALT : //to print the result + System.out.println("\nResult: " + a0 + "\n"); + return; + } + } + } + + private int pop() { + sp = sp+1 ; + return memory[sp] ; + } + + private void push(int v) { + memory[sp] = v; + sp = sp-1 ; + } + +}
\ No newline at end of file diff --git a/src/svm/SVM.g4 b/src/svm/SVM.g4 new file mode 100755 index 0000000..c913b87 --- /dev/null +++ b/src/svm/SVM.g4 @@ -0,0 +1,79 @@ +grammar SVM; + +@header { +import java.util.HashMap; +} + +@lexer::members { +public int lexicalErrors=0; +} + +/*------------------------------------------------------------------ + * PARSER RULES + *------------------------------------------------------------------*/ + +assembly: (instruction)* ; + +instruction: + ( LOAD REG NUMBER '(' REG ')' // = memory[NUMBER + REGright] <- REGleft ## NEVER USED! WHY? + | STORE REG NUMBER '(' REG ')' // = REGleft <- memory[NUMBER + REGright] + | STOREI REG NUMBER // = REG <- NUMBER + | MOVE REG REG // = REGleft <- REGright + | ADD REG REG // = top <- REGleft + REGright + | ADDI REG NUMBER // = top <- REGleft + NUMBER + | SUB REG REG // = top <- REGleft - REGright + | SUBI REG NUMBER // = top <- REGleft - NUMBER + | MUL REG REG // = top <- REGleft * REGright + | MULI REG NUMBER // = top <- REGleft * NUMBER + | DIV REG REG // = top <- REGleft / REGright + | DIVI REG NUMBER // = top <- REGleft / NUMBER + | PUSH (n=NUMBER | l=LABEL) // = memory[sp] = number|label , sp = sp-1 + | PUSHR REG // = memory[sp] = REG , sp = sp-1 + | POP // = sp = sp+1 + | POPR REG // = REG <- memory[sp+1] == STORE REG 0($sp) + | BRANCH LABEL // = ip = LABEL + | BRANCHEQ REG REG LABEL // = if REGleft == REGright => ip = LABEL + | BRANCHLESSEQ REG REG LABEL // = if REGleft <= REGright => ip = LABEL + | JUMPSUB LABEL + | RETURNSUB REG + | l=LABEL ':' + | HALT + ) ; + +/*------------------------------------------------------------------ + * LEXER RULES + *------------------------------------------------------------------*/ + +LOAD : 'load' ; +STORE : 'store' ; +STOREI : 'storei' ; +MOVE : 'move' ; +ADD : 'add' ; +ADDI : 'addi' ; +SUB : 'sub' ; +SUBI : 'subi' ; +MUL : 'mul' ; +MULI : 'muli' ; +DIV : 'div' ; +DIVI : 'divi' ; +PUSH : 'push' ; +PUSHR : 'pushr' ; +POP : 'pop' ; +POPR : 'popr' ; +BRANCH : 'b' ; +BRANCHEQ :'beq' ; +BRANCHLESSEQ:'bleq' ; +JUMPSUB : 'jsub' ; +RETURNSUB: 'rsub' ; +HALT : 'halt' ; + +REG : 'A0' | 'RA' | 'FP' | 'SP' | 'AL' | 'T1' | 'T2' ; +LABEL : ('a'..'z'|'A'..'Z')('a'..'z' | 'A'..'Z' | '0'..'9')* ; +NUMBER : '0' | ('-')?(('1'..'9')('0'..'9')*) ; + + +WHITESP : ( '\t' | ' ' | '\r' | '\n' )+ -> channel(HIDDEN); +LINECOMENTS : '//' (~('\n'|'\r'))* -> skip; + +ERR : . { System.err.println("Invalid char: "+ getText()); lexicalErrors++; } -> channel(HIDDEN); + diff --git a/src/svm/SVM.interp b/src/svm/SVM.interp new file mode 100644 index 0000000..7cb714d --- /dev/null +++ b/src/svm/SVM.interp @@ -0,0 +1,75 @@ +token literal names: +null +'(' +')' +':' +'load' +'store' +'storei' +'move' +'add' +'addi' +'sub' +'subi' +'mul' +'muli' +'div' +'divi' +'push' +'pushr' +'pop' +'popr' +'b' +'beq' +'bleq' +'jsub' +'rsub' +'halt' +null +null +null +null +null +null + +token symbolic names: +null +null +null +null +LOAD +STORE +STOREI +MOVE +ADD +ADDI +SUB +SUBI +MUL +MULI +DIV +DIVI +PUSH +PUSHR +POP +POPR +BRANCH +BRANCHEQ +BRANCHLESSEQ +JUMPSUB +RETURNSUB +HALT +REG +LABEL +NUMBER +WHITESP +LINECOMENTS +ERR + +rule names: +assembly +instruction + + +atn: +[4, 1, 31, 82, 2, 0, 7, 0, 2, 1, 7, 1, 1, 0, 5, 0, 6, 8, 0, 10, 0, 12, 0, 9, 9, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 56, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 80, 8, 1, 1, 1, 0, 0, 2, 0, 2, 0, 0, 103, 0, 7, 1, 0, 0, 0, 2, 79, 1, 0, 0, 0, 4, 6, 3, 2, 1, 0, 5, 4, 1, 0, 0, 0, 6, 9, 1, 0, 0, 0, 7, 5, 1, 0, 0, 0, 7, 8, 1, 0, 0, 0, 8, 1, 1, 0, 0, 0, 9, 7, 1, 0, 0, 0, 10, 11, 5, 4, 0, 0, 11, 12, 5, 26, 0, 0, 12, 13, 5, 28, 0, 0, 13, 14, 5, 1, 0, 0, 14, 15, 5, 26, 0, 0, 15, 80, 5, 2, 0, 0, 16, 17, 5, 5, 0, 0, 17, 18, 5, 26, 0, 0, 18, 19, 5, 28, 0, 0, 19, 20, 5, 1, 0, 0, 20, 21, 5, 26, 0, 0, 21, 80, 5, 2, 0, 0, 22, 23, 5, 6, 0, 0, 23, 24, 5, 26, 0, 0, 24, 80, 5, 28, 0, 0, 25, 26, 5, 7, 0, 0, 26, 27, 5, 26, 0, 0, 27, 80, 5, 26, 0, 0, 28, 29, 5, 8, 0, 0, 29, 30, 5, 26, 0, 0, 30, 80, 5, 26, 0, 0, 31, 32, 5, 9, 0, 0, 32, 33, 5, 26, 0, 0, 33, 80, 5, 28, 0, 0, 34, 35, 5, 10, 0, 0, 35, 36, 5, 26, 0, 0, 36, 80, 5, 26, 0, 0, 37, 38, 5, 11, 0, 0, 38, 39, 5, 26, 0, 0, 39, 80, 5, 28, 0, 0, 40, 41, 5, 12, 0, 0, 41, 42, 5, 26, 0, 0, 42, 80, 5, 26, 0, 0, 43, 44, 5, 13, 0, 0, 44, 45, 5, 26, 0, 0, 45, 80, 5, 28, 0, 0, 46, 47, 5, 14, 0, 0, 47, 48, 5, 26, 0, 0, 48, 80, 5, 26, 0, 0, 49, 50, 5, 15, 0, 0, 50, 51, 5, 26, 0, 0, 51, 80, 5, 28, 0, 0, 52, 55, 5, 16, 0, 0, 53, 56, 5, 28, 0, 0, 54, 56, 5, 27, 0, 0, 55, 53, 1, 0, 0, 0, 55, 54, 1, 0, 0, 0, 56, 80, 1, 0, 0, 0, 57, 58, 5, 17, 0, 0, 58, 80, 5, 26, 0, 0, 59, 80, 5, 18, 0, 0, 60, 61, 5, 19, 0, 0, 61, 80, 5, 26, 0, 0, 62, 63, 5, 20, 0, 0, 63, 80, 5, 27, 0, 0, 64, 65, 5, 21, 0, 0, 65, 66, 5, 26, 0, 0, 66, 67, 5, 26, 0, 0, 67, 80, 5, 27, 0, 0, 68, 69, 5, 22, 0, 0, 69, 70, 5, 26, 0, 0, 70, 71, 5, 26, 0, 0, 71, 80, 5, 27, 0, 0, 72, 73, 5, 23, 0, 0, 73, 80, 5, 27, 0, 0, 74, 75, 5, 24, 0, 0, 75, 80, 5, 26, 0, 0, 76, 77, 5, 27, 0, 0, 77, 80, 5, 3, 0, 0, 78, 80, 5, 25, 0, 0, 79, 10, 1, 0, 0, 0, 79, 16, 1, 0, 0, 0, 79, 22, 1, 0, 0, 0, 79, 25, 1, 0, 0, 0, 79, 28, 1, 0, 0, 0, 79, 31, 1, 0, 0, 0, 79, 34, 1, 0, 0, 0, 79, 37, 1, 0, 0, 0, 79, 40, 1, 0, 0, 0, 79, 43, 1, 0, 0, 0, 79, 46, 1, 0, 0, 0, 79, 49, 1, 0, 0, 0, 79, 52, 1, 0, 0, 0, 79, 57, 1, 0, 0, 0, 79, 59, 1, 0, 0, 0, 79, 60, 1, 0, 0, 0, 79, 62, 1, 0, 0, 0, 79, 64, 1, 0, 0, 0, 79, 68, 1, 0, 0, 0, 79, 72, 1, 0, 0, 0, 79, 74, 1, 0, 0, 0, 79, 76, 1, 0, 0, 0, 79, 78, 1, 0, 0, 0, 80, 3, 1, 0, 0, 0, 3, 7, 55, 79]
\ No newline at end of file diff --git a/src/svm/SVM.tokens b/src/svm/SVM.tokens new file mode 100644 index 0000000..e76ba15 --- /dev/null +++ b/src/svm/SVM.tokens @@ -0,0 +1,56 @@ +T__0=1 +T__1=2 +T__2=3 +LOAD=4 +STORE=5 +STOREI=6 +MOVE=7 +ADD=8 +ADDI=9 +SUB=10 +SUBI=11 +MUL=12 +MULI=13 +DIV=14 +DIVI=15 +PUSH=16 +PUSHR=17 +POP=18 +POPR=19 +BRANCH=20 +BRANCHEQ=21 +BRANCHLESSEQ=22 +JUMPSUB=23 +RETURNSUB=24 +HALT=25 +REG=26 +LABEL=27 +NUMBER=28 +WHITESP=29 +LINECOMENTS=30 +ERR=31 +'('=1 +')'=2 +':'=3 +'load'=4 +'store'=5 +'storei'=6 +'move'=7 +'add'=8 +'addi'=9 +'sub'=10 +'subi'=11 +'mul'=12 +'muli'=13 +'div'=14 +'divi'=15 +'push'=16 +'pushr'=17 +'pop'=18 +'popr'=19 +'b'=20 +'beq'=21 +'bleq'=22 +'jsub'=23 +'rsub'=24 +'halt'=25 diff --git a/src/svm/SVMBaseListener.java b/src/svm/SVMBaseListener.java new file mode 100644 index 0000000..19d7c60 --- /dev/null +++ b/src/svm/SVMBaseListener.java @@ -0,0 +1,67 @@ +// Generated from /home/gabri/Desktop/clp_project/src/svm/SVM.g4 by ANTLR 4.13.1 +package svm; + +import java.util.HashMap; + + +import org.antlr.v4.runtime.ParserRuleContext; +import org.antlr.v4.runtime.tree.ErrorNode; +import org.antlr.v4.runtime.tree.TerminalNode; + +/** + * This class provides an empty implementation of {@link SVMListener}, + * which can be extended to create a listener which only needs to handle a subset + * of the available methods. + */ +@SuppressWarnings("CheckReturnValue") +public class SVMBaseListener implements SVMListener { + /** + * {@inheritDoc} + * + * <p>The default implementation does nothing.</p> + */ + @Override public void enterAssembly(SVMParser.AssemblyContext ctx) { } + /** + * {@inheritDoc} + * + * <p>The default implementation does nothing.</p> + */ + @Override public void exitAssembly(SVMParser.AssemblyContext ctx) { } + /** + * {@inheritDoc} + * + * <p>The default implementation does nothing.</p> + */ + @Override public void enterInstruction(SVMParser.InstructionContext ctx) { } + /** + * {@inheritDoc} + * + * <p>The default implementation does nothing.</p> + */ + @Override public void exitInstruction(SVMParser.InstructionContext ctx) { } + + /** + * {@inheritDoc} + * + * <p>The default implementation does nothing.</p> + */ + @Override public void enterEveryRule(ParserRuleContext ctx) { } + /** + * {@inheritDoc} + * + * <p>The default implementation does nothing.</p> + */ + @Override public void exitEveryRule(ParserRuleContext ctx) { } + /** + * {@inheritDoc} + * + * <p>The default implementation does nothing.</p> + */ + @Override public void visitTerminal(TerminalNode node) { } + /** + * {@inheritDoc} + * + * <p>The default implementation does nothing.</p> + */ + @Override public void visitErrorNode(ErrorNode node) { } +}
\ No newline at end of file diff --git a/src/svm/SVMBaseVisitor.java b/src/svm/SVMBaseVisitor.java new file mode 100644 index 0000000..ba371ce --- /dev/null +++ b/src/svm/SVMBaseVisitor.java @@ -0,0 +1,32 @@ +// Generated from /home/gabri/Desktop/clp_project/src/svm/SVM.g4 by ANTLR 4.13.1 +package svm; + +import java.util.HashMap; + +import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor; + +/** + * This class provides an empty implementation of {@link SVMVisitor}, + * which can be extended to create a visitor which only needs to handle a subset + * of the available methods. + * + * @param <T> The return type of the visit operation. Use {@link Void} for + * operations with no return type. + */ +@SuppressWarnings("CheckReturnValue") +public class SVMBaseVisitor<T> extends AbstractParseTreeVisitor<T> implements SVMVisitor<T> { + /** + * {@inheritDoc} + * + * <p>The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.</p> + */ + @Override public T visitAssembly(SVMParser.AssemblyContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + * <p>The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.</p> + */ + @Override public T visitInstruction(SVMParser.InstructionContext ctx) { return visitChildren(ctx); } +}
\ No newline at end of file diff --git a/src/svm/SVMLexer.interp b/src/svm/SVMLexer.interp new file mode 100644 index 0000000..7c6ed9f --- /dev/null +++ b/src/svm/SVMLexer.interp @@ -0,0 +1,110 @@ +token literal names: +null +'(' +')' +':' +'load' +'store' +'storei' +'move' +'add' +'addi' +'sub' +'subi' +'mul' +'muli' +'div' +'divi' +'push' +'pushr' +'pop' +'popr' +'b' +'beq' +'bleq' +'jsub' +'rsub' +'halt' +null +null +null +null +null +null + +token symbolic names: +null +null +null +null +LOAD +STORE +STOREI +MOVE +ADD +ADDI +SUB +SUBI +MUL +MULI +DIV +DIVI +PUSH +PUSHR +POP +POPR +BRANCH +BRANCHEQ +BRANCHLESSEQ +JUMPSUB +RETURNSUB +HALT +REG +LABEL +NUMBER +WHITESP +LINECOMENTS +ERR + +rule names: +T__0 +T__1 +T__2 +LOAD +STORE +STOREI +MOVE +ADD +ADDI +SUB +SUBI +MUL +MULI +DIV +DIVI +PUSH +PUSHR +POP +POPR +BRANCH +BRANCHEQ +BRANCHLESSEQ +JUMPSUB +RETURNSUB +HALT +REG +LABEL +NUMBER +WHITESP +LINECOMENTS +ERR + +channel names: +DEFAULT_TOKEN_CHANNEL +HIDDEN + +mode names: +DEFAULT_MODE + +atn: +[4, 0, 31, 233, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 1, 0, 1, 0, 1, 1, 1, 1, 1, 2, 1, 2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 7, 1, 7, 1, 7, 1, 7, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 9, 1, 9, 1, 9, 1, 9, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 11, 1, 11, 1, 11, 1, 11, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 13, 1, 13, 1, 13, 1, 13, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 17, 1, 17, 1, 17, 1, 17, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 19, 1, 19, 1, 20, 1, 20, 1, 20, 1, 20, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 3, 25, 189, 8, 25, 1, 26, 1, 26, 5, 26, 193, 8, 26, 10, 26, 12, 26, 196, 9, 26, 1, 27, 1, 27, 3, 27, 200, 8, 27, 1, 27, 1, 27, 5, 27, 204, 8, 27, 10, 27, 12, 27, 207, 9, 27, 3, 27, 209, 8, 27, 1, 28, 4, 28, 212, 8, 28, 11, 28, 12, 28, 213, 1, 28, 1, 28, 1, 29, 1, 29, 1, 29, 1, 29, 5, 29, 222, 8, 29, 10, 29, 12, 29, 225, 9, 29, 1, 29, 1, 29, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 0, 0, 31, 1, 1, 3, 2, 5, 3, 7, 4, 9, 5, 11, 6, 13, 7, 15, 8, 17, 9, 19, 10, 21, 11, 23, 12, 25, 13, 27, 14, 29, 15, 31, 16, 33, 17, 35, 18, 37, 19, 39, 20, 41, 21, 43, 22, 45, 23, 47, 24, 49, 25, 51, 26, 53, 27, 55, 28, 57, 29, 59, 30, 61, 31, 1, 0, 4, 2, 0, 65, 90, 97, 122, 3, 0, 48, 57, 65, 90, 97, 122, 3, 0, 9, 10, 13, 13, 32, 32, 2, 0, 10, 10, 13, 13, 244, 0, 1, 1, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 5, 1, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, 9, 1, 0, 0, 0, 0, 11, 1, 0, 0, 0, 0, 13, 1, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 17, 1, 0, 0, 0, 0, 19, 1, 0, 0, 0, 0, 21, 1, 0, 0, 0, 0, 23, 1, 0, 0, 0, 0, 25, 1, 0, 0, 0, 0, 27, 1, 0, 0, 0, 0, 29, 1, 0, 0, 0, 0, 31, 1, 0, 0, 0, 0, 33, 1, 0, 0, 0, 0, 35, 1, 0, 0, 0, 0, 37, 1, 0, 0, 0, 0, 39, 1, 0, 0, 0, 0, 41, 1, 0, 0, 0, 0, 43, 1, 0, 0, 0, 0, 45, 1, 0, 0, 0, 0, 47, 1, 0, 0, 0, 0, 49, 1, 0, 0, 0, 0, 51, 1, 0, 0, 0, 0, 53, 1, 0, 0, 0, 0, 55, 1, 0, 0, 0, 0, 57, 1, 0, 0, 0, 0, 59, 1, 0, 0, 0, 0, 61, 1, 0, 0, 0, 1, 63, 1, 0, 0, 0, 3, 65, 1, 0, 0, 0, 5, 67, 1, 0, 0, 0, 7, 69, 1, 0, 0, 0, 9, 74, 1, 0, 0, 0, 11, 80, 1, 0, 0, 0, 13, 87, 1, 0, 0, 0, 15, 92, 1, 0, 0, 0, 17, 96, 1, 0, 0, 0, 19, 101, 1, 0, 0, 0, 21, 105, 1, 0, 0, 0, 23, 110, 1, 0, 0, 0, 25, 114, 1, 0, 0, 0, 27, 119, 1, 0, 0, 0, 29, 123, 1, 0, 0, 0, 31, 128, 1, 0, 0, 0, 33, 133, 1, 0, 0, 0, 35, 139, 1, 0, 0, 0, 37, 143, 1, 0, 0, 0, 39, 148, 1, 0, 0, 0, 41, 150, 1, 0, 0, 0, 43, 154, 1, 0, 0, 0, 45, 159, 1, 0, 0, 0, 47, 164, 1, 0, 0, 0, 49, 169, 1, 0, 0, 0, 51, 188, 1, 0, 0, 0, 53, 190, 1, 0, 0, 0, 55, 208, 1, 0, 0, 0, 57, 211, 1, 0, 0, 0, 59, 217, 1, 0, 0, 0, 61, 228, 1, 0, 0, 0, 63, 64, 5, 40, 0, 0, 64, 2, 1, 0, 0, 0, 65, 66, 5, 41, 0, 0, 66, 4, 1, 0, 0, 0, 67, 68, 5, 58, 0, 0, 68, 6, 1, 0, 0, 0, 69, 70, 5, 108, 0, 0, 70, 71, 5, 111, 0, 0, 71, 72, 5, 97, 0, 0, 72, 73, 5, 100, 0, 0, 73, 8, 1, 0, 0, 0, 74, 75, 5, 115, 0, 0, 75, 76, 5, 116, 0, 0, 76, 77, 5, 111, 0, 0, 77, 78, 5, 114, 0, 0, 78, 79, 5, 101, 0, 0, 79, 10, 1, 0, 0, 0, 80, 81, 5, 115, 0, 0, 81, 82, 5, 116, 0, 0, 82, 83, 5, 111, 0, 0, 83, 84, 5, 114, 0, 0, 84, 85, 5, 101, 0, 0, 85, 86, 5, 105, 0, 0, 86, 12, 1, 0, 0, 0, 87, 88, 5, 109, 0, 0, 88, 89, 5, 111, 0, 0, 89, 90, 5, 118, 0, 0, 90, 91, 5, 101, 0, 0, 91, 14, 1, 0, 0, 0, 92, 93, 5, 97, 0, 0, 93, 94, 5, 100, 0, 0, 94, 95, 5, 100, 0, 0, 95, 16, 1, 0, 0, 0, 96, 97, 5, 97, 0, 0, 97, 98, 5, 100, 0, 0, 98, 99, 5, 100, 0, 0, 99, 100, 5, 105, 0, 0, 100, 18, 1, 0, 0, 0, 101, 102, 5, 115, 0, 0, 102, 103, 5, 117, 0, 0, 103, 104, 5, 98, 0, 0, 104, 20, 1, 0, 0, 0, 105, 106, 5, 115, 0, 0, 106, 107, 5, 117, 0, 0, 107, 108, 5, 98, 0, 0, 108, 109, 5, 105, 0, 0, 109, 22, 1, 0, 0, 0, 110, 111, 5, 109, 0, 0, 111, 112, 5, 117, 0, 0, 112, 113, 5, 108, 0, 0, 113, 24, 1, 0, 0, 0, 114, 115, 5, 109, 0, 0, 115, 116, 5, 117, 0, 0, 116, 117, 5, 108, 0, 0, 117, 118, 5, 105, 0, 0, 118, 26, 1, 0, 0, 0, 119, 120, 5, 100, 0, 0, 120, 121, 5, 105, 0, 0, 121, 122, 5, 118, 0, 0, 122, 28, 1, 0, 0, 0, 123, 124, 5, 100, 0, 0, 124, 125, 5, 105, 0, 0, 125, 126, 5, 118, 0, 0, 126, 127, 5, 105, 0, 0, 127, 30, 1, 0, 0, 0, 128, 129, 5, 112, 0, 0, 129, 130, 5, 117, 0, 0, 130, 131, 5, 115, 0, 0, 131, 132, 5, 104, 0, 0, 132, 32, 1, 0, 0, 0, 133, 134, 5, 112, 0, 0, 134, 135, 5, 117, 0, 0, 135, 136, 5, 115, 0, 0, 136, 137, 5, 104, 0, 0, 137, 138, 5, 114, 0, 0, 138, 34, 1, 0, 0, 0, 139, 140, 5, 112, 0, 0, 140, 141, 5, 111, 0, 0, 141, 142, 5, 112, 0, 0, 142, 36, 1, 0, 0, 0, 143, 144, 5, 112, 0, 0, 144, 145, 5, 111, 0, 0, 145, 146, 5, 112, 0, 0, 146, 147, 5, 114, 0, 0, 147, 38, 1, 0, 0, 0, 148, 149, 5, 98, 0, 0, 149, 40, 1, 0, 0, 0, 150, 151, 5, 98, 0, 0, 151, 152, 5, 101, 0, 0, 152, 153, 5, 113, 0, 0, 153, 42, 1, 0, 0, 0, 154, 155, 5, 98, 0, 0, 155, 156, 5, 108, 0, 0, 156, 157, 5, 101, 0, 0, 157, 158, 5, 113, 0, 0, 158, 44, 1, 0, 0, 0, 159, 160, 5, 106, 0, 0, 160, 161, 5, 115, 0, 0, 161, 162, 5, 117, 0, 0, 162, 163, 5, 98, 0, 0, 163, 46, 1, 0, 0, 0, 164, 165, 5, 114, 0, 0, 165, 166, 5, 115, 0, 0, 166, 167, 5, 117, 0, 0, 167, 168, 5, 98, 0, 0, 168, 48, 1, 0, 0, 0, 169, 170, 5, 104, 0, 0, 170, 171, 5, 97, 0, 0, 171, 172, 5, 108, 0, 0, 172, 173, 5, 116, 0, 0, 173, 50, 1, 0, 0, 0, 174, 175, 5, 65, 0, 0, 175, 189, 5, 48, 0, 0, 176, 177, 5, 82, 0, 0, 177, 189, 5, 65, 0, 0, 178, 179, 5, 70, 0, 0, 179, 189, 5, 80, 0, 0, 180, 181, 5, 83, 0, 0, 181, 189, 5, 80, 0, 0, 182, 183, 5, 65, 0, 0, 183, 189, 5, 76, 0, 0, 184, 185, 5, 84, 0, 0, 185, 189, 5, 49, 0, 0, 186, 187, 5, 84, 0, 0, 187, 189, 5, 50, 0, 0, 188, 174, 1, 0, 0, 0, 188, 176, 1, 0, 0, 0, 188, 178, 1, 0, 0, 0, 188, 180, 1, 0, 0, 0, 188, 182, 1, 0, 0, 0, 188, 184, 1, 0, 0, 0, 188, 186, 1, 0, 0, 0, 189, 52, 1, 0, 0, 0, 190, 194, 7, 0, 0, 0, 191, 193, 7, 1, 0, 0, 192, 191, 1, 0, 0, 0, 193, 196, 1, 0, 0, 0, 194, 192, 1, 0, 0, 0, 194, 195, 1, 0, 0, 0, 195, 54, 1, 0, 0, 0, 196, 194, 1, 0, 0, 0, 197, 209, 5, 48, 0, 0, 198, 200, 5, 45, 0, 0, 199, 198, 1, 0, 0, 0, 199, 200, 1, 0, 0, 0, 200, 201, 1, 0, 0, 0, 201, 205, 2, 49, 57, 0, 202, 204, 2, 48, 57, 0, 203, 202, 1, 0, 0, 0, 204, 207, 1, 0, 0, 0, 205, 203, 1, 0, 0, 0, 205, 206, 1, 0, 0, 0, 206, 209, 1, 0, 0, 0, 207, 205, 1, 0, 0, 0, 208, 197, 1, 0, 0, 0, 208, 199, 1, 0, 0, 0, 209, 56, 1, 0, 0, 0, 210, 212, 7, 2, 0, 0, 211, 210, 1, 0, 0, 0, 212, 213, 1, 0, 0, 0, 213, 211, 1, 0, 0, 0, 213, 214, 1, 0, 0, 0, 214, 215, 1, 0, 0, 0, 215, 216, 6, 28, 0, 0, 216, 58, 1, 0, 0, 0, 217, 218, 5, 47, 0, 0, 218, 219, 5, 47, 0, 0, 219, 223, 1, 0, 0, 0, 220, 222, 8, 3, 0, 0, 221, 220, 1, 0, 0, 0, 222, 225, 1, 0, 0, 0, 223, 221, 1, 0, 0, 0, 223, 224, 1, 0, 0, 0, 224, 226, 1, 0, 0, 0, 225, 223, 1, 0, 0, 0, 226, 227, 6, 29, 1, 0, 227, 60, 1, 0, 0, 0, 228, 229, 9, 0, 0, 0, 229, 230, 6, 30, 2, 0, 230, 231, 1, 0, 0, 0, 231, 232, 6, 30, 0, 0, 232, 62, 1, 0, 0, 0, 8, 0, 188, 194, 199, 205, 208, 213, 223, 3, 0, 1, 0, 6, 0, 0, 1, 30, 0]
\ No newline at end of file diff --git a/src/svm/SVMLexer.java b/src/svm/SVMLexer.java new file mode 100644 index 0000000..c21bb1b --- /dev/null +++ b/src/svm/SVMLexer.java @@ -0,0 +1,296 @@ +// Generated from /home/gabri/Desktop/clp_project/src/svm/SVM.g4 by ANTLR 4.13.1 +package svm; + +import java.util.HashMap; + +import org.antlr.v4.runtime.Lexer; +import org.antlr.v4.runtime.CharStream; +import org.antlr.v4.runtime.Token; +import org.antlr.v4.runtime.TokenStream; +import org.antlr.v4.runtime.*; +import org.antlr.v4.runtime.atn.*; +import org.antlr.v4.runtime.dfa.DFA; +import org.antlr.v4.runtime.misc.*; + +@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast", "CheckReturnValue", "this-escape"}) +public class SVMLexer extends Lexer { + static { RuntimeMetaData.checkVersion("4.13.1", RuntimeMetaData.VERSION); } + + protected static final DFA[] _decisionToDFA; + protected static final PredictionContextCache _sharedContextCache = + new PredictionContextCache(); + public static final int + T__0=1, T__1=2, T__2=3, LOAD=4, STORE=5, STOREI=6, MOVE=7, ADD=8, ADDI=9, + SUB=10, SUBI=11, MUL=12, MULI=13, DIV=14, DIVI=15, PUSH=16, PUSHR=17, + POP=18, POPR=19, BRANCH=20, BRANCHEQ=21, BRANCHLESSEQ=22, JUMPSUB=23, + RETURNSUB=24, HALT=25, REG=26, LABEL=27, NUMBER=28, WHITESP=29, LINECOMENTS=30, + ERR=31; + public static String[] channelNames = { + "DEFAULT_TOKEN_CHANNEL", "HIDDEN" + }; + + public static String[] modeNames = { + "DEFAULT_MODE" + }; + + private static String[] makeRuleNames() { + return new String[] { + "T__0", "T__1", "T__2", "LOAD", "STORE", "STOREI", "MOVE", "ADD", "ADDI", + "SUB", "SUBI", "MUL", "MULI", "DIV", "DIVI", "PUSH", "PUSHR", "POP", + "POPR", "BRANCH", "BRANCHEQ", "BRANCHLESSEQ", "JUMPSUB", "RETURNSUB", + "HALT", "REG", "LABEL", "NUMBER", "WHITESP", "LINECOMENTS", "ERR" + }; + } + public static final String[] ruleNames = makeRuleNames(); + + private static String[] makeLiteralNames() { + return new String[] { + null, "'('", "')'", "':'", "'load'", "'store'", "'storei'", "'move'", + "'add'", "'addi'", "'sub'", "'subi'", "'mul'", "'muli'", "'div'", "'divi'", + "'push'", "'pushr'", "'pop'", "'popr'", "'b'", "'beq'", "'bleq'", "'jsub'", + "'rsub'", "'halt'" + }; + } + private static final String[] _LITERAL_NAMES = makeLiteralNames(); + private static String[] makeSymbolicNames() { + return new String[] { + null, null, null, null, "LOAD", "STORE", "STOREI", "MOVE", "ADD", "ADDI", + "SUB", "SUBI", "MUL", "MULI", "DIV", "DIVI", "PUSH", "PUSHR", "POP", + "POPR", "BRANCH", "BRANCHEQ", "BRANCHLESSEQ", "JUMPSUB", "RETURNSUB", + "HALT", "REG", "LABEL", "NUMBER", "WHITESP", "LINECOMENTS", "ERR" + }; + } + private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames(); + public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); + + /** + * @deprecated Use {@link #VOCABULARY} instead. + */ + @Deprecated + public static final String[] tokenNames; + static { + tokenNames = new String[_SYMBOLIC_NAMES.length]; + for (int i = 0; i < tokenNames.length; i++) { + tokenNames[i] = VOCABULARY.getLiteralName(i); + if (tokenNames[i] == null) { + tokenNames[i] = VOCABULARY.getSymbolicName(i); + } + + if (tokenNames[i] == null) { + tokenNames[i] = "<INVALID>"; + } + } + } + + @Override + @Deprecated + public String[] getTokenNames() { + return tokenNames; + } + + @Override + + public Vocabulary getVocabulary() { + return VOCABULARY; + } + + + public int lexicalErrors=0; + + + public SVMLexer(CharStream input) { + super(input); + _interp = new LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache); + } + + @Override + public String getGrammarFileName() { return "SVM.g4"; } + + @Override + public String[] getRuleNames() { return ruleNames; } + + @Override + public String getSerializedATN() { return _serializedATN; } + + @Override + public String[] getChannelNames() { return channelNames; } + + @Override + public String[] getModeNames() { return modeNames; } + + @Override + public ATN getATN() { return _ATN; } + + @Override + public void action(RuleContext _localctx, int ruleIndex, int actionIndex) { + switch (ruleIndex) { + case 30: + ERR_action((RuleContext)_localctx, actionIndex); + break; + } + } + private void ERR_action(RuleContext _localctx, int actionIndex) { + switch (actionIndex) { + case 0: + System.err.println("Invalid char: "+ getText()); lexicalErrors++; + break; + } + } + + public static final String _serializedATN = + "\u0004\u0000\u001f\u00e9\u0006\uffff\uffff\u0002\u0000\u0007\u0000\u0002"+ + "\u0001\u0007\u0001\u0002\u0002\u0007\u0002\u0002\u0003\u0007\u0003\u0002"+ + "\u0004\u0007\u0004\u0002\u0005\u0007\u0005\u0002\u0006\u0007\u0006\u0002"+ + "\u0007\u0007\u0007\u0002\b\u0007\b\u0002\t\u0007\t\u0002\n\u0007\n\u0002"+ + "\u000b\u0007\u000b\u0002\f\u0007\f\u0002\r\u0007\r\u0002\u000e\u0007\u000e"+ + "\u0002\u000f\u0007\u000f\u0002\u0010\u0007\u0010\u0002\u0011\u0007\u0011"+ + "\u0002\u0012\u0007\u0012\u0002\u0013\u0007\u0013\u0002\u0014\u0007\u0014"+ + "\u0002\u0015\u0007\u0015\u0002\u0016\u0007\u0016\u0002\u0017\u0007\u0017"+ + "\u0002\u0018\u0007\u0018\u0002\u0019\u0007\u0019\u0002\u001a\u0007\u001a"+ + "\u0002\u001b\u0007\u001b\u0002\u001c\u0007\u001c\u0002\u001d\u0007\u001d"+ + "\u0002\u001e\u0007\u001e\u0001\u0000\u0001\u0000\u0001\u0001\u0001\u0001"+ + "\u0001\u0002\u0001\u0002\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003"+ + "\u0001\u0003\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004"+ + "\u0001\u0004\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005"+ + "\u0001\u0005\u0001\u0005\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0006"+ + "\u0001\u0006\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007\u0001\b\u0001"+ + "\b\u0001\b\u0001\b\u0001\b\u0001\t\u0001\t\u0001\t\u0001\t\u0001\n\u0001"+ + "\n\u0001\n\u0001\n\u0001\n\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b"+ + "\u0001\f\u0001\f\u0001\f\u0001\f\u0001\f\u0001\r\u0001\r\u0001\r\u0001"+ + "\r\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000f"+ + "\u0001\u000f\u0001\u000f\u0001\u000f\u0001\u000f\u0001\u0010\u0001\u0010"+ + "\u0001\u0010\u0001\u0010\u0001\u0010\u0001\u0010\u0001\u0011\u0001\u0011"+ + "\u0001\u0011\u0001\u0011\u0001\u0012\u0001\u0012\u0001\u0012\u0001\u0012"+ + "\u0001\u0012\u0001\u0013\u0001\u0013\u0001\u0014\u0001\u0014\u0001\u0014"+ + "\u0001\u0014\u0001\u0015\u0001\u0015\u0001\u0015\u0001\u0015\u0001\u0015"+ + "\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0017"+ + "\u0001\u0017\u0001\u0017\u0001\u0017\u0001\u0017\u0001\u0018\u0001\u0018"+ + "\u0001\u0018\u0001\u0018\u0001\u0018\u0001\u0019\u0001\u0019\u0001\u0019"+ + "\u0001\u0019\u0001\u0019\u0001\u0019\u0001\u0019\u0001\u0019\u0001\u0019"+ + "\u0001\u0019\u0001\u0019\u0001\u0019\u0001\u0019\u0001\u0019\u0003\u0019"+ + "\u00bd\b\u0019\u0001\u001a\u0001\u001a\u0005\u001a\u00c1\b\u001a\n\u001a"+ + "\f\u001a\u00c4\t\u001a\u0001\u001b\u0001\u001b\u0003\u001b\u00c8\b\u001b"+ + "\u0001\u001b\u0001\u001b\u0005\u001b\u00cc\b\u001b\n\u001b\f\u001b\u00cf"+ + "\t\u001b\u0003\u001b\u00d1\b\u001b\u0001\u001c\u0004\u001c\u00d4\b\u001c"+ + "\u000b\u001c\f\u001c\u00d5\u0001\u001c\u0001\u001c\u0001\u001d\u0001\u001d"+ + "\u0001\u001d\u0001\u001d\u0005\u001d\u00de\b\u001d\n\u001d\f\u001d\u00e1"+ + "\t\u001d\u0001\u001d\u0001\u001d\u0001\u001e\u0001\u001e\u0001\u001e\u0001"+ + "\u001e\u0001\u001e\u0000\u0000\u001f\u0001\u0001\u0003\u0002\u0005\u0003"+ + "\u0007\u0004\t\u0005\u000b\u0006\r\u0007\u000f\b\u0011\t\u0013\n\u0015"+ + "\u000b\u0017\f\u0019\r\u001b\u000e\u001d\u000f\u001f\u0010!\u0011#\u0012"+ + "%\u0013\'\u0014)\u0015+\u0016-\u0017/\u00181\u00193\u001a5\u001b7\u001c"+ + "9\u001d;\u001e=\u001f\u0001\u0000\u0004\u0002\u0000AZaz\u0003\u000009"+ + "AZaz\u0003\u0000\t\n\r\r \u0002\u0000\n\n\r\r\u00f4\u0000\u0001\u0001"+ + "\u0000\u0000\u0000\u0000\u0003\u0001\u0000\u0000\u0000\u0000\u0005\u0001"+ + "\u0000\u0000\u0000\u0000\u0007\u0001\u0000\u0000\u0000\u0000\t\u0001\u0000"+ + "\u0000\u0000\u0000\u000b\u0001\u0000\u0000\u0000\u0000\r\u0001\u0000\u0000"+ + "\u0000\u0000\u000f\u0001\u0000\u0000\u0000\u0000\u0011\u0001\u0000\u0000"+ + "\u0000\u0000\u0013\u0001\u0000\u0000\u0000\u0000\u0015\u0001\u0000\u0000"+ + "\u0000\u0000\u0017\u0001\u0000\u0000\u0000\u0000\u0019\u0001\u0000\u0000"+ + "\u0000\u0000\u001b\u0001\u0000\u0000\u0000\u0000\u001d\u0001\u0000\u0000"+ + "\u0000\u0000\u001f\u0001\u0000\u0000\u0000\u0000!\u0001\u0000\u0000\u0000"+ + "\u0000#\u0001\u0000\u0000\u0000\u0000%\u0001\u0000\u0000\u0000\u0000\'"+ + "\u0001\u0000\u0000\u0000\u0000)\u0001\u0000\u0000\u0000\u0000+\u0001\u0000"+ + "\u0000\u0000\u0000-\u0001\u0000\u0000\u0000\u0000/\u0001\u0000\u0000\u0000"+ + "\u00001\u0001\u0000\u0000\u0000\u00003\u0001\u0000\u0000\u0000\u00005"+ + "\u0001\u0000\u0000\u0000\u00007\u0001\u0000\u0000\u0000\u00009\u0001\u0000"+ + "\u0000\u0000\u0000;\u0001\u0000\u0000\u0000\u0000=\u0001\u0000\u0000\u0000"+ + "\u0001?\u0001\u0000\u0000\u0000\u0003A\u0001\u0000\u0000\u0000\u0005C"+ + "\u0001\u0000\u0000\u0000\u0007E\u0001\u0000\u0000\u0000\tJ\u0001\u0000"+ + "\u0000\u0000\u000bP\u0001\u0000\u0000\u0000\rW\u0001\u0000\u0000\u0000"+ + "\u000f\\\u0001\u0000\u0000\u0000\u0011`\u0001\u0000\u0000\u0000\u0013"+ + "e\u0001\u0000\u0000\u0000\u0015i\u0001\u0000\u0000\u0000\u0017n\u0001"+ + "\u0000\u0000\u0000\u0019r\u0001\u0000\u0000\u0000\u001bw\u0001\u0000\u0000"+ + "\u0000\u001d{\u0001\u0000\u0000\u0000\u001f\u0080\u0001\u0000\u0000\u0000"+ + "!\u0085\u0001\u0000\u0000\u0000#\u008b\u0001\u0000\u0000\u0000%\u008f"+ + "\u0001\u0000\u0000\u0000\'\u0094\u0001\u0000\u0000\u0000)\u0096\u0001"+ + "\u0000\u0000\u0000+\u009a\u0001\u0000\u0000\u0000-\u009f\u0001\u0000\u0000"+ + "\u0000/\u00a4\u0001\u0000\u0000\u00001\u00a9\u0001\u0000\u0000\u00003"+ + "\u00bc\u0001\u0000\u0000\u00005\u00be\u0001\u0000\u0000\u00007\u00d0\u0001"+ + "\u0000\u0000\u00009\u00d3\u0001\u0000\u0000\u0000;\u00d9\u0001\u0000\u0000"+ + "\u0000=\u00e4\u0001\u0000\u0000\u0000?@\u0005(\u0000\u0000@\u0002\u0001"+ + "\u0000\u0000\u0000AB\u0005)\u0000\u0000B\u0004\u0001\u0000\u0000\u0000"+ + "CD\u0005:\u0000\u0000D\u0006\u0001\u0000\u0000\u0000EF\u0005l\u0000\u0000"+ + "FG\u0005o\u0000\u0000GH\u0005a\u0000\u0000HI\u0005d\u0000\u0000I\b\u0001"+ + "\u0000\u0000\u0000JK\u0005s\u0000\u0000KL\u0005t\u0000\u0000LM\u0005o"+ + "\u0000\u0000MN\u0005r\u0000\u0000NO\u0005e\u0000\u0000O\n\u0001\u0000"+ + "\u0000\u0000PQ\u0005s\u0000\u0000QR\u0005t\u0000\u0000RS\u0005o\u0000"+ + "\u0000ST\u0005r\u0000\u0000TU\u0005e\u0000\u0000UV\u0005i\u0000\u0000"+ + "V\f\u0001\u0000\u0000\u0000WX\u0005m\u0000\u0000XY\u0005o\u0000\u0000"+ + "YZ\u0005v\u0000\u0000Z[\u0005e\u0000\u0000[\u000e\u0001\u0000\u0000\u0000"+ + "\\]\u0005a\u0000\u0000]^\u0005d\u0000\u0000^_\u0005d\u0000\u0000_\u0010"+ + "\u0001\u0000\u0000\u0000`a\u0005a\u0000\u0000ab\u0005d\u0000\u0000bc\u0005"+ + "d\u0000\u0000cd\u0005i\u0000\u0000d\u0012\u0001\u0000\u0000\u0000ef\u0005"+ + "s\u0000\u0000fg\u0005u\u0000\u0000gh\u0005b\u0000\u0000h\u0014\u0001\u0000"+ + "\u0000\u0000ij\u0005s\u0000\u0000jk\u0005u\u0000\u0000kl\u0005b\u0000"+ + "\u0000lm\u0005i\u0000\u0000m\u0016\u0001\u0000\u0000\u0000no\u0005m\u0000"+ + "\u0000op\u0005u\u0000\u0000pq\u0005l\u0000\u0000q\u0018\u0001\u0000\u0000"+ + "\u0000rs\u0005m\u0000\u0000st\u0005u\u0000\u0000tu\u0005l\u0000\u0000"+ + "uv\u0005i\u0000\u0000v\u001a\u0001\u0000\u0000\u0000wx\u0005d\u0000\u0000"+ + "xy\u0005i\u0000\u0000yz\u0005v\u0000\u0000z\u001c\u0001\u0000\u0000\u0000"+ + "{|\u0005d\u0000\u0000|}\u0005i\u0000\u0000}~\u0005v\u0000\u0000~\u007f"+ + "\u0005i\u0000\u0000\u007f\u001e\u0001\u0000\u0000\u0000\u0080\u0081\u0005"+ + "p\u0000\u0000\u0081\u0082\u0005u\u0000\u0000\u0082\u0083\u0005s\u0000"+ + "\u0000\u0083\u0084\u0005h\u0000\u0000\u0084 \u0001\u0000\u0000\u0000\u0085"+ + "\u0086\u0005p\u0000\u0000\u0086\u0087\u0005u\u0000\u0000\u0087\u0088\u0005"+ + "s\u0000\u0000\u0088\u0089\u0005h\u0000\u0000\u0089\u008a\u0005r\u0000"+ + "\u0000\u008a\"\u0001\u0000\u0000\u0000\u008b\u008c\u0005p\u0000\u0000"+ + "\u008c\u008d\u0005o\u0000\u0000\u008d\u008e\u0005p\u0000\u0000\u008e$"+ + "\u0001\u0000\u0000\u0000\u008f\u0090\u0005p\u0000\u0000\u0090\u0091\u0005"+ + "o\u0000\u0000\u0091\u0092\u0005p\u0000\u0000\u0092\u0093\u0005r\u0000"+ + "\u0000\u0093&\u0001\u0000\u0000\u0000\u0094\u0095\u0005b\u0000\u0000\u0095"+ + "(\u0001\u0000\u0000\u0000\u0096\u0097\u0005b\u0000\u0000\u0097\u0098\u0005"+ + "e\u0000\u0000\u0098\u0099\u0005q\u0000\u0000\u0099*\u0001\u0000\u0000"+ + "\u0000\u009a\u009b\u0005b\u0000\u0000\u009b\u009c\u0005l\u0000\u0000\u009c"+ + "\u009d\u0005e\u0000\u0000\u009d\u009e\u0005q\u0000\u0000\u009e,\u0001"+ + "\u0000\u0000\u0000\u009f\u00a0\u0005j\u0000\u0000\u00a0\u00a1\u0005s\u0000"+ + "\u0000\u00a1\u00a2\u0005u\u0000\u0000\u00a2\u00a3\u0005b\u0000\u0000\u00a3"+ + ".\u0001\u0000\u0000\u0000\u00a4\u00a5\u0005r\u0000\u0000\u00a5\u00a6\u0005"+ + "s\u0000\u0000\u00a6\u00a7\u0005u\u0000\u0000\u00a7\u00a8\u0005b\u0000"+ + "\u0000\u00a80\u0001\u0000\u0000\u0000\u00a9\u00aa\u0005h\u0000\u0000\u00aa"+ + "\u00ab\u0005a\u0000\u0000\u00ab\u00ac\u0005l\u0000\u0000\u00ac\u00ad\u0005"+ + "t\u0000\u0000\u00ad2\u0001\u0000\u0000\u0000\u00ae\u00af\u0005A\u0000"+ + "\u0000\u00af\u00bd\u00050\u0000\u0000\u00b0\u00b1\u0005R\u0000\u0000\u00b1"+ + "\u00bd\u0005A\u0000\u0000\u00b2\u00b3\u0005F\u0000\u0000\u00b3\u00bd\u0005"+ + "P\u0000\u0000\u00b4\u00b5\u0005S\u0000\u0000\u00b5\u00bd\u0005P\u0000"+ + "\u0000\u00b6\u00b7\u0005A\u0000\u0000\u00b7\u00bd\u0005L\u0000\u0000\u00b8"+ + "\u00b9\u0005T\u0000\u0000\u00b9\u00bd\u00051\u0000\u0000\u00ba\u00bb\u0005"+ + "T\u0000\u0000\u00bb\u00bd\u00052\u0000\u0000\u00bc\u00ae\u0001\u0000\u0000"+ + "\u0000\u00bc\u00b0\u0001\u0000\u0000\u0000\u00bc\u00b2\u0001\u0000\u0000"+ + "\u0000\u00bc\u00b4\u0001\u0000\u0000\u0000\u00bc\u00b6\u0001\u0000\u0000"+ + "\u0000\u00bc\u00b8\u0001\u0000\u0000\u0000\u00bc\u00ba\u0001\u0000\u0000"+ + "\u0000\u00bd4\u0001\u0000\u0000\u0000\u00be\u00c2\u0007\u0000\u0000\u0000"+ + "\u00bf\u00c1\u0007\u0001\u0000\u0000\u00c0\u00bf\u0001\u0000\u0000\u0000"+ + "\u00c1\u00c4\u0001\u0000\u0000\u0000\u00c2\u00c0\u0001\u0000\u0000\u0000"+ + "\u00c2\u00c3\u0001\u0000\u0000\u0000\u00c36\u0001\u0000\u0000\u0000\u00c4"+ + "\u00c2\u0001\u0000\u0000\u0000\u00c5\u00d1\u00050\u0000\u0000\u00c6\u00c8"+ + "\u0005-\u0000\u0000\u00c7\u00c6\u0001\u0000\u0000\u0000\u00c7\u00c8\u0001"+ + "\u0000\u0000\u0000\u00c8\u00c9\u0001\u0000\u0000\u0000\u00c9\u00cd\u0002"+ + "19\u0000\u00ca\u00cc\u000209\u0000\u00cb\u00ca\u0001\u0000\u0000\u0000"+ + "\u00cc\u00cf\u0001\u0000\u0000\u0000\u00cd\u00cb\u0001\u0000\u0000\u0000"+ + "\u00cd\u00ce\u0001\u0000\u0000\u0000\u00ce\u00d1\u0001\u0000\u0000\u0000"+ + "\u00cf\u00cd\u0001\u0000\u0000\u0000\u00d0\u00c5\u0001\u0000\u0000\u0000"+ + "\u00d0\u00c7\u0001\u0000\u0000\u0000\u00d18\u0001\u0000\u0000\u0000\u00d2"+ + "\u00d4\u0007\u0002\u0000\u0000\u00d3\u00d2\u0001\u0000\u0000\u0000\u00d4"+ + "\u00d5\u0001\u0000\u0000\u0000\u00d5\u00d3\u0001\u0000\u0000\u0000\u00d5"+ + "\u00d6\u0001\u0000\u0000\u0000\u00d6\u00d7\u0001\u0000\u0000\u0000\u00d7"+ + "\u00d8\u0006\u001c\u0000\u0000\u00d8:\u0001\u0000\u0000\u0000\u00d9\u00da"+ + "\u0005/\u0000\u0000\u00da\u00db\u0005/\u0000\u0000\u00db\u00df\u0001\u0000"+ + "\u0000\u0000\u00dc\u00de\b\u0003\u0000\u0000\u00dd\u00dc\u0001\u0000\u0000"+ + "\u0000\u00de\u00e1\u0001\u0000\u0000\u0000\u00df\u00dd\u0001\u0000\u0000"+ + "\u0000\u00df\u00e0\u0001\u0000\u0000\u0000\u00e0\u00e2\u0001\u0000\u0000"+ + "\u0000\u00e1\u00df\u0001\u0000\u0000\u0000\u00e2\u00e3\u0006\u001d\u0001"+ + "\u0000\u00e3<\u0001\u0000\u0000\u0000\u00e4\u00e5\t\u0000\u0000\u0000"+ + "\u00e5\u00e6\u0006\u001e\u0002\u0000\u00e6\u00e7\u0001\u0000\u0000\u0000"+ + "\u00e7\u00e8\u0006\u001e\u0000\u0000\u00e8>\u0001\u0000\u0000\u0000\b"+ + "\u0000\u00bc\u00c2\u00c7\u00cd\u00d0\u00d5\u00df\u0003\u0000\u0001\u0000"+ + "\u0006\u0000\u0000\u0001\u001e\u0000"; + public static final ATN _ATN = + new ATNDeserializer().deserialize(_serializedATN.toCharArray()); + static { + _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()]; + for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) { + _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i); + } + } +}
\ No newline at end of file diff --git a/src/svm/SVMLexer.tokens b/src/svm/SVMLexer.tokens new file mode 100644 index 0000000..e76ba15 --- /dev/null +++ b/src/svm/SVMLexer.tokens @@ -0,0 +1,56 @@ +T__0=1 +T__1=2 +T__2=3 +LOAD=4 +STORE=5 +STOREI=6 +MOVE=7 +ADD=8 +ADDI=9 +SUB=10 +SUBI=11 +MUL=12 +MULI=13 +DIV=14 +DIVI=15 +PUSH=16 +PUSHR=17 +POP=18 +POPR=19 +BRANCH=20 +BRANCHEQ=21 +BRANCHLESSEQ=22 +JUMPSUB=23 +RETURNSUB=24 +HALT=25 +REG=26 +LABEL=27 +NUMBER=28 +WHITESP=29 +LINECOMENTS=30 +ERR=31 +'('=1 +')'=2 +':'=3 +'load'=4 +'store'=5 +'storei'=6 +'move'=7 +'add'=8 +'addi'=9 +'sub'=10 +'subi'=11 +'mul'=12 +'muli'=13 +'div'=14 +'divi'=15 +'push'=16 +'pushr'=17 +'pop'=18 +'popr'=19 +'b'=20 +'beq'=21 +'bleq'=22 +'jsub'=23 +'rsub'=24 +'halt'=25 diff --git a/src/svm/SVMListener.java b/src/svm/SVMListener.java new file mode 100644 index 0000000..770e56e --- /dev/null +++ b/src/svm/SVMListener.java @@ -0,0 +1,33 @@ +// Generated from /home/gabri/Desktop/clp_project/src/svm/SVM.g4 by ANTLR 4.13.1 +package svm; + +import java.util.HashMap; + +import org.antlr.v4.runtime.tree.ParseTreeListener; + +/** + * This interface defines a complete listener for a parse tree produced by + * {@link SVMParser}. + */ +public interface SVMListener extends ParseTreeListener { + /** + * Enter a parse tree produced by {@link SVMParser#assembly}. + * @param ctx the parse tree + */ + void enterAssembly(SVMParser.AssemblyContext ctx); + /** + * Exit a parse tree produced by {@link SVMParser#assembly}. + * @param ctx the parse tree + */ + void exitAssembly(SVMParser.AssemblyContext ctx); + /** + * Enter a parse tree produced by {@link SVMParser#instruction}. + * @param ctx the parse tree + */ + void enterInstruction(SVMParser.InstructionContext ctx); + /** + * Exit a parse tree produced by {@link SVMParser#instruction}. + * @param ctx the parse tree + */ + void exitInstruction(SVMParser.InstructionContext ctx); +}
\ No newline at end of file diff --git a/src/svm/SVMParser.java b/src/svm/SVMParser.java new file mode 100644 index 0000000..8687116 --- /dev/null +++ b/src/svm/SVMParser.java @@ -0,0 +1,547 @@ +// Generated from /home/gabri/Desktop/clp_project/src/svm/SVM.g4 by ANTLR 4.13.1 +package svm; + +import java.util.HashMap; + +import org.antlr.v4.runtime.atn.*; +import org.antlr.v4.runtime.dfa.DFA; +import org.antlr.v4.runtime.*; +import org.antlr.v4.runtime.misc.*; +import org.antlr.v4.runtime.tree.*; +import java.util.List; +import java.util.Iterator; +import java.util.ArrayList; + +@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast", "CheckReturnValue"}) +public class SVMParser extends Parser { + static { RuntimeMetaData.checkVersion("4.13.1", RuntimeMetaData.VERSION); } + + protected static final DFA[] _decisionToDFA; + protected static final PredictionContextCache _sharedContextCache = + new PredictionContextCache(); + public static final int + T__0=1, T__1=2, T__2=3, LOAD=4, STORE=5, STOREI=6, MOVE=7, ADD=8, ADDI=9, + SUB=10, SUBI=11, MUL=12, MULI=13, DIV=14, DIVI=15, PUSH=16, PUSHR=17, + POP=18, POPR=19, BRANCH=20, BRANCHEQ=21, BRANCHLESSEQ=22, JUMPSUB=23, + RETURNSUB=24, HALT=25, REG=26, LABEL=27, NUMBER=28, WHITESP=29, LINECOMENTS=30, + ERR=31; + public static final int + RULE_assembly = 0, RULE_instruction = 1; + private static String[] makeRuleNames() { + return new String[] { + "assembly", "instruction" + }; + } + public static final String[] ruleNames = makeRuleNames(); + + private static String[] makeLiteralNames() { + return new String[] { + null, "'('", "')'", "':'", "'load'", "'store'", "'storei'", "'move'", + "'add'", "'addi'", "'sub'", "'subi'", "'mul'", "'muli'", "'div'", "'divi'", + "'push'", "'pushr'", "'pop'", "'popr'", "'b'", "'beq'", "'bleq'", "'jsub'", + "'rsub'", "'halt'" + }; + } + private static final String[] _LITERAL_NAMES = makeLiteralNames(); + private static String[] makeSymbolicNames() { + return new String[] { + null, null, null, null, "LOAD", "STORE", "STOREI", "MOVE", "ADD", "ADDI", + "SUB", "SUBI", "MUL", "MULI", "DIV", "DIVI", "PUSH", "PUSHR", "POP", + "POPR", "BRANCH", "BRANCHEQ", "BRANCHLESSEQ", "JUMPSUB", "RETURNSUB", + "HALT", "REG", "LABEL", "NUMBER", "WHITESP", "LINECOMENTS", "ERR" + }; + } + private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames(); + public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); + + /** + * @deprecated Use {@link #VOCABULARY} instead. + */ + @Deprecated + public static final String[] tokenNames; + static { + tokenNames = new String[_SYMBOLIC_NAMES.length]; + for (int i = 0; i < tokenNames.length; i++) { + tokenNames[i] = VOCABULARY.getLiteralName(i); + if (tokenNames[i] == null) { + tokenNames[i] = VOCABULARY.getSymbolicName(i); + } + + if (tokenNames[i] == null) { + tokenNames[i] = "<INVALID>"; + } + } + } + + @Override + @Deprecated + public String[] getTokenNames() { + return tokenNames; + } + + @Override + + public Vocabulary getVocabulary() { + return VOCABULARY; + } + + @Override + public String getGrammarFileName() { return "SVM.g4"; } + + @Override + public String[] getRuleNames() { return ruleNames; } + + @Override + public String getSerializedATN() { return _serializedATN; } + + @Override + public ATN getATN() { return _ATN; } + + public SVMParser(TokenStream input) { + super(input); + _interp = new ParserATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache); + } + + @SuppressWarnings("CheckReturnValue") + public static class AssemblyContext extends ParserRuleContext { + public List<InstructionContext> instruction() { + return getRuleContexts(InstructionContext.class); + } + public InstructionContext instruction(int i) { + return getRuleContext(InstructionContext.class,i); + } + public AssemblyContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_assembly; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof SVMListener ) ((SVMListener)listener).enterAssembly(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof SVMListener ) ((SVMListener)listener).exitAssembly(this); + } + @Override + public <T> T accept(ParseTreeVisitor<? extends T> visitor) { + if ( visitor instanceof SVMVisitor ) return ((SVMVisitor<? extends T>)visitor).visitAssembly(this); + else return visitor.visitChildren(this); + } + } + + public final AssemblyContext assembly() throws RecognitionException { + AssemblyContext _localctx = new AssemblyContext(_ctx, getState()); + enterRule(_localctx, 0, RULE_assembly); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(7); + _errHandler.sync(this); + _la = _input.LA(1); + while ((((_la) & ~0x3f) == 0 && ((1L << _la) & 201326576L) != 0)) { + { + { + setState(4); + instruction(); + } + } + setState(9); + _errHandler.sync(this); + _la = _input.LA(1); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class InstructionContext extends ParserRuleContext { + public Token n; + public Token l; + public TerminalNode LOAD() { return getToken(SVMParser.LOAD, 0); } + public List<TerminalNode> REG() { return getTokens(SVMParser.REG); } + public TerminalNode REG(int i) { + return getToken(SVMParser.REG, i); + } + public TerminalNode NUMBER() { return getToken(SVMParser.NUMBER, 0); } + public TerminalNode STORE() { return getToken(SVMParser.STORE, 0); } + public TerminalNode STOREI() { return getToken(SVMParser.STOREI, 0); } + public TerminalNode MOVE() { return getToken(SVMParser.MOVE, 0); } + public TerminalNode ADD() { return getToken(SVMParser.ADD, 0); } + public TerminalNode ADDI() { return getToken(SVMParser.ADDI, 0); } + public TerminalNode SUB() { return getToken(SVMParser.SUB, 0); } + public TerminalNode SUBI() { return getToken(SVMParser.SUBI, 0); } + public TerminalNode MUL() { return getToken(SVMParser.MUL, 0); } + public TerminalNode MULI() { return getToken(SVMParser.MULI, 0); } + public TerminalNode DIV() { return getToken(SVMParser.DIV, 0); } + public TerminalNode DIVI() { return getToken(SVMParser.DIVI, 0); } + public TerminalNode PUSH() { return getToken(SVMParser.PUSH, 0); } + public TerminalNode PUSHR() { return getToken(SVMParser.PUSHR, 0); } + public TerminalNode POP() { return getToken(SVMParser.POP, 0); } + public TerminalNode POPR() { return getToken(SVMParser.POPR, 0); } + public TerminalNode BRANCH() { return getToken(SVMParser.BRANCH, 0); } + public TerminalNode LABEL() { return getToken(SVMParser.LABEL, 0); } + public TerminalNode BRANCHEQ() { return getToken(SVMParser.BRANCHEQ, 0); } + public TerminalNode BRANCHLESSEQ() { return getToken(SVMParser.BRANCHLESSEQ, 0); } + public TerminalNode JUMPSUB() { return getToken(SVMParser.JUMPSUB, 0); } + public TerminalNode RETURNSUB() { return getToken(SVMParser.RETURNSUB, 0); } + public TerminalNode HALT() { return getToken(SVMParser.HALT, 0); } + public InstructionContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_instruction; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof SVMListener ) ((SVMListener)listener).enterInstruction(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof SVMListener ) ((SVMListener)listener).exitInstruction(this); + } + @Override + public <T> T accept(ParseTreeVisitor<? extends T> visitor) { + if ( visitor instanceof SVMVisitor ) return ((SVMVisitor<? extends T>)visitor).visitInstruction(this); + else return visitor.visitChildren(this); + } + } + + public final InstructionContext instruction() throws RecognitionException { + InstructionContext _localctx = new InstructionContext(_ctx, getState()); + enterRule(_localctx, 2, RULE_instruction); + try { + enterOuterAlt(_localctx, 1); + { + setState(79); + _errHandler.sync(this); + switch (_input.LA(1)) { + case LOAD: + { + setState(10); + match(LOAD); + setState(11); + match(REG); + setState(12); + match(NUMBER); + setState(13); + match(T__0); + setState(14); + match(REG); + setState(15); + match(T__1); + } + break; + case STORE: + { + setState(16); + match(STORE); + setState(17); + match(REG); + setState(18); + match(NUMBER); + setState(19); + match(T__0); + setState(20); + match(REG); + setState(21); + match(T__1); + } + break; + case STOREI: + { + setState(22); + match(STOREI); + setState(23); + match(REG); + setState(24); + match(NUMBER); + } + break; + case MOVE: + { + setState(25); + match(MOVE); + setState(26); + match(REG); + setState(27); + match(REG); + } + break; + case ADD: + { + setState(28); + match(ADD); + setState(29); + match(REG); + setState(30); + match(REG); + } + break; + case ADDI: + { + setState(31); + match(ADDI); + setState(32); + match(REG); + setState(33); + match(NUMBER); + } + break; + case SUB: + { + setState(34); + match(SUB); + setState(35); + match(REG); + setState(36); + match(REG); + } + break; + case SUBI: + { + setState(37); + match(SUBI); + setState(38); + match(REG); + setState(39); + match(NUMBER); + } + break; + case MUL: + { + setState(40); + match(MUL); + setState(41); + match(REG); + setState(42); + match(REG); + } + break; + case MULI: + { + setState(43); + match(MULI); + setState(44); + match(REG); + setState(45); + match(NUMBER); + } + break; + case DIV: + { + setState(46); + match(DIV); + setState(47); + match(REG); + setState(48); + match(REG); + } + break; + case DIVI: + { + setState(49); + match(DIVI); + setState(50); + match(REG); + setState(51); + match(NUMBER); + } + break; + case PUSH: + { + setState(52); + match(PUSH); + setState(55); + _errHandler.sync(this); + switch (_input.LA(1)) { + case NUMBER: + { + setState(53); + ((InstructionContext)_localctx).n = match(NUMBER); + } + break; + case LABEL: + { + setState(54); + ((InstructionContext)_localctx).l = match(LABEL); + } + break; + default: + throw new NoViableAltException(this); + } + } + break; + case PUSHR: + { + setState(57); + match(PUSHR); + setState(58); + match(REG); + } + break; + case POP: + { + setState(59); + match(POP); + } + break; + case POPR: + { + setState(60); + match(POPR); + setState(61); + match(REG); + } + break; + case BRANCH: + { + setState(62); + match(BRANCH); + setState(63); + match(LABEL); + } + break; + case BRANCHEQ: + { + setState(64); + match(BRANCHEQ); + setState(65); + match(REG); + setState(66); + match(REG); + setState(67); + match(LABEL); + } + break; + case BRANCHLESSEQ: + { + setState(68); + match(BRANCHLESSEQ); + setState(69); + match(REG); + setState(70); + match(REG); + setState(71); + match(LABEL); + } + break; + case JUMPSUB: + { + setState(72); + match(JUMPSUB); + setState(73); + match(LABEL); + } + break; + case RETURNSUB: + { + setState(74); + match(RETURNSUB); + setState(75); + match(REG); + } + break; + case LABEL: + { + setState(76); + ((InstructionContext)_localctx).l = match(LABEL); + setState(77); + match(T__2); + } + break; + case HALT: + { + setState(78); + match(HALT); + } + break; + default: + throw new NoViableAltException(this); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static final String _serializedATN = + "\u0004\u0001\u001fR\u0002\u0000\u0007\u0000\u0002\u0001\u0007\u0001\u0001"+ + "\u0000\u0005\u0000\u0006\b\u0000\n\u0000\f\u0000\t\t\u0000\u0001\u0001"+ + "\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001"+ + "\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001"+ + "\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001"+ + "\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001"+ + "\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001"+ + "\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001"+ + "\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001"+ + "\u0001\u0001\u0001\u0001\u0003\u00018\b\u0001\u0001\u0001\u0001\u0001"+ + "\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001"+ + "\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001"+ + "\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001"+ + "\u0001\u0001\u0001\u0001\u0003\u0001P\b\u0001\u0001\u0001\u0000\u0000"+ + "\u0002\u0000\u0002\u0000\u0000g\u0000\u0007\u0001\u0000\u0000\u0000\u0002"+ + "O\u0001\u0000\u0000\u0000\u0004\u0006\u0003\u0002\u0001\u0000\u0005\u0004"+ + "\u0001\u0000\u0000\u0000\u0006\t\u0001\u0000\u0000\u0000\u0007\u0005\u0001"+ + "\u0000\u0000\u0000\u0007\b\u0001\u0000\u0000\u0000\b\u0001\u0001\u0000"+ + "\u0000\u0000\t\u0007\u0001\u0000\u0000\u0000\n\u000b\u0005\u0004\u0000"+ + "\u0000\u000b\f\u0005\u001a\u0000\u0000\f\r\u0005\u001c\u0000\u0000\r\u000e"+ + "\u0005\u0001\u0000\u0000\u000e\u000f\u0005\u001a\u0000\u0000\u000fP\u0005"+ + "\u0002\u0000\u0000\u0010\u0011\u0005\u0005\u0000\u0000\u0011\u0012\u0005"+ + "\u001a\u0000\u0000\u0012\u0013\u0005\u001c\u0000\u0000\u0013\u0014\u0005"+ + "\u0001\u0000\u0000\u0014\u0015\u0005\u001a\u0000\u0000\u0015P\u0005\u0002"+ + "\u0000\u0000\u0016\u0017\u0005\u0006\u0000\u0000\u0017\u0018\u0005\u001a"+ + "\u0000\u0000\u0018P\u0005\u001c\u0000\u0000\u0019\u001a\u0005\u0007\u0000"+ + "\u0000\u001a\u001b\u0005\u001a\u0000\u0000\u001bP\u0005\u001a\u0000\u0000"+ + "\u001c\u001d\u0005\b\u0000\u0000\u001d\u001e\u0005\u001a\u0000\u0000\u001e"+ + "P\u0005\u001a\u0000\u0000\u001f \u0005\t\u0000\u0000 !\u0005\u001a\u0000"+ + "\u0000!P\u0005\u001c\u0000\u0000\"#\u0005\n\u0000\u0000#$\u0005\u001a"+ + "\u0000\u0000$P\u0005\u001a\u0000\u0000%&\u0005\u000b\u0000\u0000&\'\u0005"+ + "\u001a\u0000\u0000\'P\u0005\u001c\u0000\u0000()\u0005\f\u0000\u0000)*"+ + "\u0005\u001a\u0000\u0000*P\u0005\u001a\u0000\u0000+,\u0005\r\u0000\u0000"+ + ",-\u0005\u001a\u0000\u0000-P\u0005\u001c\u0000\u0000./\u0005\u000e\u0000"+ + "\u0000/0\u0005\u001a\u0000\u00000P\u0005\u001a\u0000\u000012\u0005\u000f"+ + "\u0000\u000023\u0005\u001a\u0000\u00003P\u0005\u001c\u0000\u000047\u0005"+ + "\u0010\u0000\u000058\u0005\u001c\u0000\u000068\u0005\u001b\u0000\u0000"+ + "75\u0001\u0000\u0000\u000076\u0001\u0000\u0000\u00008P\u0001\u0000\u0000"+ + "\u00009:\u0005\u0011\u0000\u0000:P\u0005\u001a\u0000\u0000;P\u0005\u0012"+ + "\u0000\u0000<=\u0005\u0013\u0000\u0000=P\u0005\u001a\u0000\u0000>?\u0005"+ + "\u0014\u0000\u0000?P\u0005\u001b\u0000\u0000@A\u0005\u0015\u0000\u0000"+ + "AB\u0005\u001a\u0000\u0000BC\u0005\u001a\u0000\u0000CP\u0005\u001b\u0000"+ + "\u0000DE\u0005\u0016\u0000\u0000EF\u0005\u001a\u0000\u0000FG\u0005\u001a"+ + "\u0000\u0000GP\u0005\u001b\u0000\u0000HI\u0005\u0017\u0000\u0000IP\u0005"+ + "\u001b\u0000\u0000JK\u0005\u0018\u0000\u0000KP\u0005\u001a\u0000\u0000"+ + "LM\u0005\u001b\u0000\u0000MP\u0005\u0003\u0000\u0000NP\u0005\u0019\u0000"+ + "\u0000O\n\u0001\u0000\u0000\u0000O\u0010\u0001\u0000\u0000\u0000O\u0016"+ + "\u0001\u0000\u0000\u0000O\u0019\u0001\u0000\u0000\u0000O\u001c\u0001\u0000"+ + "\u0000\u0000O\u001f\u0001\u0000\u0000\u0000O\"\u0001\u0000\u0000\u0000"+ + "O%\u0001\u0000\u0000\u0000O(\u0001\u0000\u0000\u0000O+\u0001\u0000\u0000"+ + "\u0000O.\u0001\u0000\u0000\u0000O1\u0001\u0000\u0000\u0000O4\u0001\u0000"+ + "\u0000\u0000O9\u0001\u0000\u0000\u0000O;\u0001\u0000\u0000\u0000O<\u0001"+ + "\u0000\u0000\u0000O>\u0001\u0000\u0000\u0000O@\u0001\u0000\u0000\u0000"+ + "OD\u0001\u0000\u0000\u0000OH\u0001\u0000\u0000\u0000OJ\u0001\u0000\u0000"+ + "\u0000OL\u0001\u0000\u0000\u0000ON\u0001\u0000\u0000\u0000P\u0003\u0001"+ + "\u0000\u0000\u0000\u0003\u00077O"; + public static final ATN _ATN = + new ATNDeserializer().deserialize(_serializedATN.toCharArray()); + static { + _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()]; + for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) { + _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i); + } + } +}
\ No newline at end of file diff --git a/src/svm/SVMVisitor.java b/src/svm/SVMVisitor.java new file mode 100644 index 0000000..d4e132d --- /dev/null +++ b/src/svm/SVMVisitor.java @@ -0,0 +1,28 @@ +// Generated from /home/gabri/Desktop/clp_project/src/svm/SVM.g4 by ANTLR 4.13.1 +package svm; + +import java.util.HashMap; + +import org.antlr.v4.runtime.tree.ParseTreeVisitor; + +/** + * This interface defines a complete generic visitor for a parse tree produced + * by {@link SVMParser}. + * + * @param <T> The return type of the visit operation. Use {@link Void} for + * operations with no return type. + */ +public interface SVMVisitor<T> extends ParseTreeVisitor<T> { + /** + * Visit a parse tree produced by {@link SVMParser#assembly}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitAssembly(SVMParser.AssemblyContext ctx); + /** + * Visit a parse tree produced by {@link SVMParser#instruction}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitInstruction(SVMParser.InstructionContext ctx); +}
\ No newline at end of file diff --git a/src/svm/SVMVisitorImpl.java b/src/svm/SVMVisitorImpl.java new file mode 100644 index 0000000..391b986 --- /dev/null +++ b/src/svm/SVMVisitorImpl.java @@ -0,0 +1,156 @@ +package svm; + +import java.util.HashMap; + +public class SVMVisitorImpl extends SVMBaseVisitor<Void> { + + public AssemblyClass[] code = new AssemblyClass[ExecuteVM.CODESIZE]; + private int i = 0; + private HashMap<String,Integer> labelAdd = new HashMap<String,Integer>(); + // definisce a quale linea di codice corrisponde una etichetta + private HashMap<Integer,String> labelRef = new HashMap<Integer,String>(); + // definisce l'insieme di linee di codice che contengono una certa etichetta + + public Void visitAssembly(SVMParser.AssemblyContext ctx) { + visitChildren(ctx); + + //printlabeladd() ; // checks + //printlabelref() ; // checks + + for (Integer refAdd : labelRef.keySet()) { + int tmp = refAdd ; + String s = labelRef.get(refAdd) ; + if (code[tmp] == null) { + code[tmp] = new AssemblyClass(labelAdd.get(s), null, null, null); + } else { + code[tmp].setArg1(labelAdd.get(s).toString()); + } + } + + return null; + } + + public void printlabeladd() { + for (String m : labelAdd.keySet()) { + System.out.println("chiave: " + m + " valore: " + labelAdd.get(m)) ; + } + } + + public void printlabelref() { + for (Integer m : labelRef.keySet()) { + System.out.println("indirizzo: " + m + " etichetta: " + labelRef.get(m)) ; + } + } + + public Void visitInstruction(SVMParser.InstructionContext ctx) { + switch (ctx.getStart().getType()) { + case SVMLexer.LOAD: + code[i] = new AssemblyClass(SVMParser.LOAD, ctx.REG(0).toString(), ctx.NUMBER().toString(),ctx.REG(1).toString()); + i = i+1 ; + break; + case SVMLexer.STORE: + code[i] = new AssemblyClass(SVMParser.STORE, ctx.REG(0).toString(), ctx.NUMBER().toString(),ctx.REG(1).toString()); + i = i+1 ; + break; + case SVMLexer.STOREI: + code[i] = new AssemblyClass(SVMParser.STOREI, ctx.REG(0).toString(), ctx.NUMBER().toString(), null); + i = i+1 ; + break; + case SVMLexer.MOVE: + code[i] = new AssemblyClass(SVMParser.MOVE, ctx.REG(0).toString(), ctx.REG(1).toString(), null); + i = i+1 ; + break; + case SVMLexer.ADD: + code[i] = new AssemblyClass(SVMParser.ADD, ctx.REG(0).toString(), ctx.REG(1).toString(), null); + i = i+1 ; + break; + case SVMLexer.ADDI: + code[i] = new AssemblyClass(SVMParser.ADDI, ctx.REG(0).toString(), ctx.NUMBER().toString(), null); + i = i+1 ; + break; + case SVMLexer.SUB: + code[i] = new AssemblyClass(SVMParser.SUB, ctx.REG(0).toString(), ctx.REG(1).toString(), null); + i = i+1 ; + break; + case SVMLexer.SUBI: + code[i] = new AssemblyClass(SVMParser.SUBI, ctx.REG(0).toString(), ctx.NUMBER().toString(), null); + i = i+1 ; + break; + case SVMLexer.MUL: + code[i] = new AssemblyClass(SVMParser.MUL, ctx.REG(0).toString(), ctx.REG(1).toString(), null); + i = i+1 ; + break; + case SVMLexer.MULI: + code[i] = new AssemblyClass(SVMParser.MULI, ctx.REG(0).toString(), ctx.NUMBER().toString(), null); + i = i+1 ; + break; + case SVMLexer.DIV: + code[i] = new AssemblyClass(SVMParser.DIV, ctx.REG(0).toString(), ctx.REG(1).toString(), null); + i = i+1 ; + break; + case SVMLexer.DIVI: + code[i] = new AssemblyClass(SVMParser.DIVI, ctx.REG(0).toString(), ctx.NUMBER().toString(), null); + i = i+1 ; + break; + case SVMLexer.PUSH: + if (ctx.n != null) { + code[i] = new AssemblyClass(SVMParser.PUSH, ctx.n.getText(), null, null); + } else { + code[i] = new AssemblyClass(SVMParser.PUSH, ctx.l.getText(), null, null); + labelRef.put(i, ctx.l.getText()); + } + i = i+1 ; + break; + case SVMLexer.PUSHR: + code[i] = new AssemblyClass(SVMParser.PUSHR, ctx.REG(0).toString(), null, null); + i = i+1 ; + break; + case SVMLexer.POP: + code[i] = new AssemblyClass(SVMParser.POP, null, null, null); + i = i+1 ; + break; + case SVMLexer.POPR: + code[i] = new AssemblyClass(SVMParser.POPR, ctx.REG(0).toString(), null, null); + i = i+1 ; + break; + case SVMLexer.LABEL: + labelAdd.put(ctx.l.getText(),i); + break; + case SVMLexer.BRANCH: + code[i] = new AssemblyClass(SVMParser.BRANCH, ctx.LABEL().toString(), null, null); + i = i+1 ; + labelRef.put(i, (ctx.LABEL() != null ? ctx.LABEL().toString() : null)); + i = i+1 ; + break; + case SVMLexer.BRANCHEQ: + code[i] = new AssemblyClass(SVMParser.BRANCHEQ, ctx.REG(0).toString(), ctx.REG(1).toString(), ctx.LABEL().toString()); + i = i+1 ; + labelRef.put(i, (ctx.LABEL() != null ? ctx.LABEL().toString() : null)); + i = i+1 ; + break; + case SVMLexer.BRANCHLESSEQ: + code[i] = new AssemblyClass(SVMParser.BRANCHLESSEQ, ctx.REG(0).toString(), ctx.REG(1).toString(), ctx.LABEL().toString()); + i = i+1 ; + labelRef.put(i, (ctx.LABEL() != null ? ctx.LABEL().toString() : null)); + i = i+1 ; + break; + case SVMLexer.JUMPSUB: + code[i] = new AssemblyClass(SVMParser.JUMPSUB, ctx.LABEL().toString(), null, null); + labelRef.put(i, ctx.LABEL().toString() ); + i = i+1 ; + break; + case SVMLexer.RETURNSUB: + code[i] = new AssemblyClass(SVMParser.RETURNSUB, ctx.REG(0).toString(), null, null); + i = i+1 ; + break; + case SVMLexer.HALT: + code[i] = new AssemblyClass(SVMParser.HALT, null, null, null); + i = i+1 ; + break; + default: + break; // Invalid instruction + } + return null; + } + +} diff --git a/test/3-1.py b/test/3-1.py new file mode 100644 index 0000000..95d2fbe --- /dev/null +++ b/test/3-1.py @@ -0,0 +1,14 @@ + +def prime_num(num, div): + if (num >=1): + if (div*div <= num/2): + if (num % div) == 0: + return False + else: + return prime_num(num,div+1) + else: + return True + else: + return False + +print(prime_num(29,2)) diff --git a/test/3-2.py b/test/3-2.py new file mode 100644 index 0000000..417fbde --- /dev/null +++ b/test/3-2.py @@ -0,0 +1,16 @@ + +num = 29 + +def prime_numBIS(div): + if (num >=1): + if (div*div <= num/2): + if (num % div) == 0: + return False + else: + return prime_numBIS(div+1) + else: + return True + else: + return False + +print(prime_numBIS(2)) diff --git a/test/3-3.py b/test/3-3.py new file mode 100644 index 0000000..af57e46 --- /dev/null +++ b/test/3-3.py @@ -0,0 +1,8 @@ + +def fibonacci(n): + if ((n == 0) or (n == 1)): + return 1 + else: + return (fibonacci(n-1) + fibonacci(n-2)) + +print(fibonacci(6)) diff --git a/test/3-4.py b/test/3-4.py new file mode 100644 index 0000000..79bf77a --- /dev/null +++ b/test/3-4.py @@ -0,0 +1,8 @@ + +def fibonacciIT(n,a,b): + if ((n == 0) or (n == 1)): + return a + else: + return (fibonacciIT(n-1, a+b, a)) + +print(fibonacciIT(6,1,1)) |