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 /src | |
| parent | f0692ff5f9e39cbd1c203e9d5abebf55a3d0f6fc (diff) | |
Code generation (#20)
Co-authored-by: geno <gabrigeno@gmail>
Co-authored-by: Santo Cariotti <santo@dcariotti.me>
Diffstat (limited to 'src')
47 files changed, 2668 insertions, 196 deletions
| 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; +    } + +} | 
