diff --git a/src/pp/s1184725/boppi/BoppiBasicGenerator.java b/src/pp/s1184725/boppi/BoppiBasicGenerator.java deleted file mode 100644 index fe53ffb..0000000 --- a/src/pp/s1184725/boppi/BoppiBasicGenerator.java +++ /dev/null @@ -1,397 +0,0 @@ -package pp.s1184725.boppi; - -import java.util.*; - -import org.antlr.v4.runtime.ParserRuleContext; -import org.antlr.v4.runtime.RuleContext; -import org.antlr.v4.runtime.tree.*; - -import pp.iloc.model.*; -import pp.s1184725.boppi.BasicParser.*; - -public class BoppiBasicGenerator extends BasicBaseVisitor { - private static final int ARBASESIZE = 8; - public Program prog; - private Annotations an; - private int regNum; - private final Reg tempArp = new Reg("ART"), arp = new Reg("ARP"), resultReg = new Reg("RES"); - - /** - * Maps operator tokens to ILOC opcodes. - */ - private static Map ops = new HashMap() { - private static final long serialVersionUID = 8979722313842633807L; - - { - put(BasicLexer.AND, OpCode.and); - put(BasicLexer.DIVIDE, OpCode.div); - put(BasicLexer.EQ, OpCode.cmp_EQ); - put(BasicLexer.GT, OpCode.cmp_GT); - put(BasicLexer.GTE, OpCode.cmp_GE); - put(BasicLexer.LEQ, OpCode.cmp_LE); - put(BasicLexer.LT, OpCode.cmp_LT); - put(BasicLexer.MINUS, OpCode.sub); - put(BasicLexer.MULTIPLY, OpCode.mult); - put(BasicLexer.NEQ, OpCode.cmp_NE); - put(BasicLexer.PLUS, OpCode.add); - put(BasicLexer.OR, OpCode.or); - } - }; - - /** - * Creates a new generator with the given variable annotations. - * - * @param annotations - * the annotation object to use during generation - */ - public BoppiBasicGenerator(Annotations annotations) { - an = annotations; - prog = new Program(); - regNum = 0; - } - - /** - * Retrieves a register for a given tree node. - * - * @param parseTree - * the tree node - * @return a register for the tree node - */ - private Reg getReg(ParseTree parseTree) { - Reg reg = an.registers.get(parseTree); - if (reg == null) { - reg = new Reg("r_" + (regNum++)); - an.registers.put(parseTree, reg); - } - return reg; - } - - /** - * Attaches the register used in the {@code source} tree node to the - * {@link destination} node. - * - * @param source - * the node to retrieve the register from - * @param destination - * the node to copy the register to - * @return the register that was copied - */ - private Reg copyReg(ParseTree source, ParseTree destination) { - Reg reg = an.registers.get(source); - an.registers.put(destination, reg); - return reg; - } - - private Reg getVar(ParserRuleContext node, Variable var) { - int difference = an.function.get(node).getDepth() + 1 - var.getDepth(); - if (difference > 0) { - emit(node, OpCode.i2i, arp, tempArp); - while (difference-- > 0) - emit(node, OpCode.loadAI, tempArp, new Num(-4), tempArp); - - return tempArp; - } else - return arp; - } - - /** - * Constructs an operation from the parameters and adds it to the program - * under construction. - */ - private Op emit(ParserRuleContext ctx, Label label, OpCode opCode, Operand... args) { - Op result = new Op(label, opCode, args); - result.setComment(ctx.getText()); - this.prog.addInstr(result); - return result; - } - - /** - * Constructs an operation from the parameters and adds it to the program - * under construction. - */ - private Op emit(ParserRuleContext ctx, OpCode opCode, Operand... args) { - return emit(ctx, (Label) null, opCode, args); - } - - @Override - public Void visitChildren(RuleNode tree) { - super.visitChildren(tree); - if (an.registers.get(tree) == null) - for (int i = tree.getChildCount() - 1; i >= 0; i--) - if (tree.getChild(i) instanceof RuleContext) { - copyReg(tree.getChild(i), tree); - break; - } - - return null; - } - - @Override - public Void visitProgram(ProgramContext ctx) { - emit(ctx, OpCode.loadI, new Num(0), tempArp); - emit(ctx, OpCode.loadI, new Num(0), arp); - - return visitChildren(ctx); - } - - @Override - public Void visitAssign(AssignContext ctx) { - visit(ctx.singleExpr()); - copyReg(ctx.singleExpr(), ctx); - - if (SimpleType.CHAR.equals(an.types.get(ctx))) - emit(ctx, OpCode.cstoreAI, getReg(ctx), getVar(ctx.variable(), an.variables.get(ctx.variable())), - new Num(an.variables.get(ctx.variable()).getOffset())); - else - emit(ctx, OpCode.storeAI, getReg(ctx), getVar(ctx.variable(), an.variables.get(ctx.variable())), - new Num(an.variables.get(ctx.variable()).getOffset())); - - return null; - } - - @Override - public Void visitCall(CallContext ctx) { - Variable function = an.variables.get(ctx.variable()); - FunctionType parameters = ((FunctionType) function.getType()); - Reg temp = new Reg("r__"); - visit(ctx.variable()); - emit(ctx.variable(), OpCode.loadAI, getVar(ctx.variable(), an.variables.get(ctx.variable())), - new Num(an.variables.get(ctx.variable()).getOffset()), temp); - emit(ctx.variable(), OpCode.push, temp); - - for (int i = 0; i < ctx.expr().size(); i++) { - visit(ctx.expr(i)); - - if (SimpleType.CHAR.equals(parameters.getParameters().get(i))) - emit(ctx.expr(i), OpCode.cpush, getReg(ctx.expr(i))); - else - emit(ctx.expr(i), OpCode.push, getReg(ctx.expr(i))); - } - emit(ctx.variable(), OpCode.addI, arp, - new Num(((FunctionType) an.function.get(ctx).getType()).getLocalDataSize() + ARBASESIZE), tempArp); - for (int i = ctx.expr().size() - 1; i >= 0; i--) { - if (SimpleType.CHAR.equals(parameters.getParameters().get(i))) { - emit(ctx.expr(i), OpCode.cpop, temp); - emit(ctx.expr(i), OpCode.cstoreAI, temp, tempArp, new Num(parameters.getOffsets().get(i))); - } else { - emit(ctx.expr(i), OpCode.pop, temp); - emit(ctx.expr(i), OpCode.storeAI, temp, tempArp, new Num(parameters.getOffsets().get(i))); - } - } - emit(ctx.variable(), OpCode.storeAI, arp, tempArp, new Num(-4)); - Label label = new Label("ret" + ctx.hashCode()); - emit(ctx.variable(), OpCode.loadI, new Num(label), temp); - emit(ctx.variable(), OpCode.storeAI, temp, tempArp, new Num(-8)); - emit(ctx, OpCode.i2i, tempArp, arp); - emit(ctx.variable(), OpCode.pop, temp); - emit(ctx, OpCode.jump, temp); - emit(ctx, label, OpCode.loadAI, arp, new Num(-4), arp); - - an.registers.put(ctx, resultReg); - return null; - } - - @Override - public Void visitFuncDeclare(FuncDeclareContext ctx) { - Reg temp = new Reg("r__"); - Label skip = new Label("s" + ctx.hashCode()); - emit(ctx, OpCode.jumpI, skip); - int targetAddress = emit(ctx, OpCode.nop).getLine(); - visit(ctx.body); - copyReg(ctx.body, ctx); - if (SimpleType.CHAR.equals(an.types.get(ctx.body))) - emit(ctx, OpCode.c2c, getReg(ctx), resultReg); - else - emit(ctx, OpCode.i2i, getReg(ctx), resultReg); - emit(ctx, OpCode.loadAI, arp, new Num(-8), temp); - emit(ctx, OpCode.jump, temp); - emit(ctx, skip, OpCode.loadI, new Num(targetAddress), temp); - emit(ctx, OpCode.storeAI, temp, getVar(ctx, an.variables.get(ctx)), new Num(an.variables.get(ctx).getOffset())); - return null; - } - - @Override - public Void visitBool(BoolContext ctx) { - emit(ctx, OpCode.loadI, new Num(ctx.TRUE() != null ? 1 : 0), getReg(ctx)); - return null; - } - - @Override - public Void visitNumber(NumberContext ctx) { - emit(ctx, OpCode.loadI, new Num(Integer.parseInt(ctx.LITERAL10().getText())), getReg(ctx)); - return null; - } - - @Override - public Void visitInfix1(Infix1Context ctx) { - visitChildren(ctx); - emit(ctx, ops.get(ctx.op.getType()), getReg(ctx.lhs), getReg(ctx.rhs), getReg(ctx)); - return null; - } - - @Override - public Void visitInfix2(Infix2Context ctx) { - visitChildren(ctx); - emit(ctx, ops.get(ctx.op.getType()), getReg(ctx.lhs), getReg(ctx.rhs), getReg(ctx)); - return null; - } - - @Override - public Void visitInfix3(Infix3Context ctx) { - visitChildren(ctx); - emit(ctx, ops.get(ctx.op.getType()), getReg(ctx.lhs), getReg(ctx.rhs), getReg(ctx)); - return null; - } - - @Override - public Void visitInfix4(Infix4Context ctx) { - visitChildren(ctx); - emit(ctx, OpCode.and, getReg(ctx.lhs), getReg(ctx.rhs), getReg(ctx)); - return null; - } - - @Override - public Void visitInfix5(Infix5Context ctx) { - visitChildren(ctx); - emit(ctx, OpCode.or, getReg(ctx.lhs), getReg(ctx.rhs), getReg(ctx)); - return null; - } - - @Override - public Void visitPrefix1(Prefix1Context ctx) { - visitChildren(ctx); - - switch (ctx.op.getType()) { - case BasicLexer.MINUS: - emit(ctx, OpCode.rsubI, getReg(ctx.singleExpr()), new Num(0), getReg(ctx)); - } - return null; - } - - @Override - public Void visitVar(VarContext ctx) { - if (SimpleType.CHAR.equals(an.types.get(ctx))) - emit(ctx, OpCode.cloadAI, getVar(ctx.variable(), an.variables.get(ctx.variable())), - new Num(an.variables.get(ctx.variable()).getOffset()), getReg(ctx)); - else - emit(ctx, OpCode.loadAI, getVar(ctx.variable(), an.variables.get(ctx.variable())), - new Num(an.variables.get(ctx.variable()).getOffset()), getReg(ctx)); - - return null; - } - - @Override - public Void visitChar(CharContext ctx) { - emit(ctx, OpCode.loadI, new Num(ctx.CHAR().getText().codePointAt(1)), getReg(ctx)); - emit(ctx, OpCode.i2c, getReg(ctx), getReg(ctx)); - return null; - } - - @Override - public Void visitRead(ReadContext ctx) { - for (VariableContext expr : ctx.variable()) { - visit(expr); - if (SimpleType.BOOL.equals(an.types.get(expr)) || SimpleType.INT.equals(an.types.get(expr))) { - emit(ctx, OpCode.in, new Str(""), getReg(ctx)); - emit(ctx, OpCode.storeAI, getReg(ctx), getVar(expr, an.variables.get(expr)), - new Num(an.variables.get(expr).getOffset())); - } else if (SimpleType.CHAR.equals(an.types.get(expr))) { - // Get input until at least 1 character - Label getTarget = new Label("lcin_l" + ctx.hashCode()); - Label continueTarget = new Label("lcin_e" + ctx.hashCode()); - Reg countReg = new Reg("tempReg"); - emit(ctx, getTarget, OpCode.cin, new Str("")); - emit(ctx, OpCode.pop, countReg); - emit(ctx, OpCode.cbr, countReg, continueTarget, getTarget); - - // Get character - emit(ctx, continueTarget, OpCode.cpop, getReg(ctx)); - emit(ctx, OpCode.cstoreAI, getReg(ctx), getVar(expr, an.variables.get(expr)), - new Num(an.variables.get(expr).getOffset())); - - // Pop all remaining characters - Label loopTarget = new Label("lcpop_l" + ctx.hashCode()); - Label iterTarget = new Label("lcpop_c" + ctx.hashCode()); - Label stopTarget = new Label("lcpop_e" + ctx.hashCode()); - Reg tempReg2 = new Reg("tempReg2"); - emit(ctx, loopTarget, OpCode.subI, countReg, new Num(1), countReg); - emit(ctx, OpCode.cbr, countReg, iterTarget, stopTarget); - emit(ctx, iterTarget, OpCode.cpop, tempReg2); - emit(ctx, OpCode.jumpI, loopTarget); - emit(ctx, stopTarget, OpCode.nop); - } else { - emit(ctx, OpCode.out, new Str("Unknown type: "), an.registers.get(expr)); - } - } - return null; - } - - @Override - public Void visitIf(IfContext ctx) { - Label toTrue = new Label("if_t" + ctx.hashCode()); - Label toFalse = new Label("if_f" + ctx.hashCode()); - Label toEnd = new Label("if_e" + ctx.hashCode()); - - visit(ctx.cond); - if (ctx.onFalse == null) { - emit(ctx, OpCode.cbr, getReg(ctx.cond), toTrue, toEnd); - - emit(ctx, toTrue, OpCode.nop); - visit(ctx.onTrue); - } else { - emit(ctx, OpCode.cbr, getReg(ctx.cond), toTrue, toFalse); - - emit(ctx, toTrue, OpCode.nop); - visit(ctx.onTrue); - if (an.types.get(ctx) != SimpleType.VOID) - emit(ctx, OpCode.i2i, getReg(ctx.onTrue), getReg(ctx)); - emit(ctx, OpCode.jumpI, toEnd); - - emit(ctx, toFalse, OpCode.nop); - visit(ctx.onFalse); - if (an.types.get(ctx) != SimpleType.VOID) - emit(ctx, OpCode.i2i, getReg(ctx.onFalse), getReg(ctx)); - - } - emit(ctx, toEnd, OpCode.nop); - - return null; - } - - @Override - public Void visitWhile(WhileContext ctx) { - Label toLoop = new Label("while_t" + ctx.hashCode()); - Label toCond = new Label("while_f" + ctx.hashCode()); - Label toEnd = new Label("while_e" + ctx.hashCode()); - - emit(ctx, OpCode.jumpI, toCond); - emit(ctx, toLoop, OpCode.nop); - visit(ctx.onTrue); - emit(ctx, toCond, OpCode.nop); - visit(ctx.cond); - emit(ctx, OpCode.cbr, getReg(ctx.cond), toLoop, toEnd); - emit(ctx, toEnd, OpCode.nop); - - return null; - } - - @Override - public Void visitWrite(WriteContext ctx) { - for (ExprContext expr : ctx.expr()) { - visit(expr); - if (SimpleType.BOOL.equals(an.types.get(expr)) || SimpleType.INT.equals(an.types.get(expr))) { - emit(ctx, OpCode.out, new Str(""), getReg(expr)); - } else if (SimpleType.CHAR.equals(an.types.get(expr))) { - Reg tempReg = new Reg("tempReg"); - emit(ctx, OpCode.cpush, getReg(expr)); - emit(ctx, OpCode.loadI, new Num(1), tempReg); - emit(ctx, OpCode.push, tempReg); - emit(ctx, OpCode.cout, new Str("")); - } else { - emit(ctx, OpCode.out, new Str("Unknown type: "), getReg(expr)); - } - } - copyReg(ctx.expr(0), ctx); - return null; - } -} diff --git a/src/pp/s1184725/boppi/BoppiBasicChecker.java b/src/pp/s1184725/boppi/BoppiChecker.java similarity index 91% rename from src/pp/s1184725/boppi/BoppiBasicChecker.java rename to src/pp/s1184725/boppi/BoppiChecker.java index 5bf7110..c4ae809 100644 --- a/src/pp/s1184725/boppi/BoppiBasicChecker.java +++ b/src/pp/s1184725/boppi/BoppiChecker.java @@ -1,38 +1,45 @@ package pp.s1184725.boppi; -import java.util.ArrayList; -import java.util.EmptyStackException; -import java.util.List; +import java.util.*; import java.util.logging.Logger; import java.util.stream.Collectors; import org.antlr.v4.runtime.ParserRuleContext; import org.antlr.v4.runtime.tree.ParseTree; -import pp.s1184725.boppi.BasicParser.*; +import pp.s1184725.boppi.antlr.BoppiBaseVisitor; +import pp.s1184725.boppi.antlr.BoppiLexer; +import pp.s1184725.boppi.antlr.BoppiParser.*; /** * This class performs type checking and variable assignment on a bare parse * tree. * */ -public class BoppiBasicChecker extends BasicBaseVisitor { +public class BoppiChecker extends BoppiBaseVisitor { private CachingSymbolTable symbols; private Annotations an; private Logger log; /** - * Creates a new checker with a logger and an object to link types and - * variables to parse tree nodes. + * Checks and annotates a program. Problems are reported to the given + * logger. * + * @param ast + * the program's AST * @param logger * the logger object to write warnings and errors to - * @param annotations - * the annotations object + * @return the generated annotations */ - public BoppiBasicChecker(Logger logger, Annotations annotations) { + public static Annotations checkProgram(ParseTree ast, Logger logger) { + BoppiChecker checker = new BoppiChecker(logger); + checker.visit(ast); + return checker.an; + } + + protected BoppiChecker(Logger logger) { symbols = new CachingSymbolTable<>(); - an = annotations; + an = new Annotations(); log = logger; } @@ -116,7 +123,7 @@ public class BoppiBasicChecker extends BasicBaseVisitor { public Type visitFuncDeclare(FuncDeclareContext ctx) { try { List parameterTypes = ctx.type().stream().skip(1).map(this::visit).collect(Collectors.toList()); - FunctionType type = new FunctionType(visit(ctx.result), parameterTypes, symbols.functionDepth); + FunctionType type = new FunctionType(visit(ctx.result), parameterTypes); Variable func = symbols.put(ctx.name.getText(), type); an.variables.put(ctx, func); an.currentFunction.push(func); @@ -179,10 +186,10 @@ public class BoppiBasicChecker extends BasicBaseVisitor { checkConstraint(lht, rht, ctx); switch (ctx.op.getType()) { - case BasicLexer.LT: - case BasicLexer.LEQ: - case BasicLexer.GTE: - case BasicLexer.GT: + case BoppiLexer.LT: + case BoppiLexer.LEQ: + case BoppiLexer.GTE: + case BoppiLexer.GT: checkConstraint(lht, SimpleType.INT, ctx); } @@ -220,12 +227,12 @@ public class BoppiBasicChecker extends BasicBaseVisitor { Type type = visit(ctx.singleExpr()); switch (ctx.op.getType()) { - case BasicLexer.NOT: + case BoppiLexer.NOT: checkConstraint(type, SimpleType.BOOL, ctx.singleExpr()); break; - case BasicLexer.PLUS: - case BasicLexer.MINUS: + case BoppiLexer.PLUS: + case BoppiLexer.MINUS: checkConstraint(type, SimpleType.INT, ctx.singleExpr()); break; } @@ -235,7 +242,7 @@ public class BoppiBasicChecker extends BasicBaseVisitor { @Override public Type visitProgram(ProgramContext ctx) { - FunctionType main = new FunctionType(SimpleType.VOID, new ArrayList<>(), symbols.functionDepth); + FunctionType main = new FunctionType(SimpleType.VOID, new ArrayList<>()); an.currentFunction.push(new Variable(main, 0, 0)); main.setLocalDataSize(symbols.withFunctionScope(() -> super.visitProgram(ctx))); return null; diff --git a/src/pp/s1184725/boppi/BoppiGenerator.java b/src/pp/s1184725/boppi/BoppiGenerator.java new file mode 100644 index 0000000..4248bc1 --- /dev/null +++ b/src/pp/s1184725/boppi/BoppiGenerator.java @@ -0,0 +1,605 @@ +package pp.s1184725.boppi; + +import java.util.*; +import java.util.logging.Logger; +import java.util.stream.Collectors; + +import org.antlr.v4.runtime.ParserRuleContext; +import org.antlr.v4.runtime.tree.*; +import org.apache.commons.lang3.StringUtils; + +import pp.iloc.eval.Machine; +import pp.iloc.model.*; +import pp.s1184725.boppi.antlr.BoppiBaseVisitor; +import pp.s1184725.boppi.antlr.BoppiLexer; +import pp.s1184725.boppi.antlr.BoppiParser.*; + +public class BoppiGenerator extends BoppiBaseVisitor { + private static final int ARBASESIZE = 16; + private static final Operand ZERO = new Num(0); + private static final Operand OFFSET_ARP = new Num(-4), OFFSET_RETURN_ADDR = new Num(-8), + OFFSET_RETURN_VAL = new Num(-12), OFFSET_AL = new Num(-16); + + /** + * Recommended number of registers to use before throwing a warning. + */ + public static int RECOMMENDED_REGISTER_COUNT = 10; + private Program prog; + private Annotations an; + private int regNum; + private final Reg tempArp = new Reg("ART"), arp = Machine.ARP_REG; + private List regFree, regInUse; + private Logger logger; + + /** + * Maps operator tokens to ILOC opcodes. + */ + private static Map ops = new HashMap() { + private static final long serialVersionUID = 8979722313842633807L; + + { + put(BoppiLexer.AND, OpCode.and); + put(BoppiLexer.DIVIDE, OpCode.div); + put(BoppiLexer.EQ, OpCode.cmp_EQ); + put(BoppiLexer.GT, OpCode.cmp_GT); + put(BoppiLexer.GTE, OpCode.cmp_GE); + put(BoppiLexer.LEQ, OpCode.cmp_LE); + put(BoppiLexer.LT, OpCode.cmp_LT); + put(BoppiLexer.MINUS, OpCode.sub); + put(BoppiLexer.MULTIPLY, OpCode.mult); + put(BoppiLexer.NEQ, OpCode.cmp_NE); + put(BoppiLexer.PLUS, OpCode.add); + put(BoppiLexer.OR, OpCode.or); + } + }; + + /** + * Creates a new generator with the given variable annotations and attaches + * the given logger. + * + * @param ast + * the program's AST + * @param annotations + * the annotation object to use during generation + * @param logger + * the logger to report errors to + * @return an ILOC program generated from the AST + */ + public static Program generateProgram(ParseTree ast, Annotations annotations, Logger logger) { + BoppiGenerator generator = new BoppiGenerator(annotations, logger); + generator.visit(ast); + return generator.prog; + } + + protected BoppiGenerator(Annotations annotations, Logger logger) { + an = annotations; + prog = new Program(); + regNum = 0; + regFree = new ArrayList<>(); + regInUse = new ArrayList<>(); + } + + private Reg makeReg(ParserRuleContext ctx) { + Reg reg; + if (regFree.isEmpty()) { + reg = new Reg("__" + (regInUse.size() + 1)); + regInUse.add(reg); + + if (regInUse.size() > 10) + logger.warning( + String.format("Using more than 10 registers at %d:%d. Consider rebalancing your expressions.", + ctx.start.getLine(), ctx.start.getCharPositionInLine())); + } else { + if (regFree.remove(an.registers.get(ctx))) + reg = an.registers.get(ctx); + else + reg = regFree.remove(0); + regInUse.add(reg); + } + an.registers.put(ctx, reg); + return reg; + } + + private void freeReg(ParserRuleContext ctx) { + Reg reg = an.registers.get(ctx); + if (reg == null) + return; + if (!regInUse.contains(reg)) { + logger.severe(getError(ctx, "INTERNAL: cannot free register %s since it is not in use.", reg.getName())); + } else { + regInUse.remove(reg); + regFree.add(reg); + } + } + + /** + * Retrieves a register for a given tree node. + * + * @param parseTree + * the tree node + * @return a register for the tree node + */ + private Reg getReg(ParseTree parseTree) { + Reg reg = an.registers.get(parseTree); + if (reg == null) { + if (Math.max(3, 4) > 2) + throw new RuntimeException("???" + parseTree.getText()); + reg = new Reg("r_" + (regNum++)); + an.registers.put(parseTree, reg); + } + return reg; + } + + /** + * Attaches the register used in the {@code source} tree node to the + * {@link destination} node. + * + * @param source + * the node to retrieve the register from + * @param destination + * the node to copy the register to + * @return the register that was copied + */ + private Reg copyReg(ParseTree source, ParseTree destination) { + Reg reg = an.registers.get(source); + an.registers.put(destination, reg); + return reg; + } + + private Reg getVar(ParserRuleContext node) { + Variable var = an.variables.get(node); + + if (var.getDepth() <= an.function.get(node).getDepth()) { + emit("travelling ALs", OpCode.i2i, arp, tempArp); + for (int i = var.getDepth(); i <= an.function.get(node).getDepth(); i++) + emit(StringUtils.repeat(' ', i) + "\\", OpCode.loadAI, tempArp, OFFSET_AL, tempArp); + + return tempArp; + } else + return arp; + } + + /** + * Constructs an operation from the parameters and adds it to the program + * under construction. + */ + private Op emit(String comment, Label label, OpCode opCode, Operand... args) { + Op result = new Op(label, opCode, args); + result.setComment(String.format("%-40s | %20s : %s", comment, + regInUse.stream().map((reg) -> reg.getName().substring(2)).collect(Collectors.joining(" ")), + regFree.stream().map((reg) -> reg.getName().substring(2)).collect(Collectors.joining(" ")))); + this.prog.addInstr(result); + return result; + } + + /** + * Constructs an operation from the parameters and adds it to the program + * under construction. + */ + private Op emit(String comment, OpCode opCode, Operand... args) { + return emit(comment, (Label) null, opCode, args); + } + + @Override + public Void visitBlock(BlockContext ctx) { + super.visitBlock(ctx); + copyReg(ctx.expr(), ctx); + return null; + } + + @Override + public Void visitDeclare(DeclareContext ctx) { + return null; + } + + @Override + public Void visitParens(ParensContext ctx) { + super.visitParens(ctx); + copyReg(ctx.expr(), ctx); + return null; + } + + @Override + public Void visitProgram(ProgramContext ctx) { + emit("initialise temp ARP", OpCode.loadI, ZERO, tempArp); + + return visitChildren(ctx); + } + + @Override + public Void visitExpr(ExprContext ctx) { + for (int i = 0; i < ctx.singleExpr().size() - 1; i++) { + visit(ctx.singleExpr(i)); + freeReg(ctx.singleExpr(i)); + } + ParserRuleContext last = ctx.singleExpr(ctx.singleExpr().size() - 1); + visit(last); + copyReg(last, ctx); + return null; + } + + @Override + public Void visitAssign(AssignContext ctx) { + visit(ctx.singleExpr()); + copyReg(ctx.singleExpr(), ctx); + + if (SimpleType.CHAR.equals(an.types.get(ctx))) + emit("to " + ctx.variable().getText(), OpCode.cstoreAI, getReg(ctx), getVar(ctx.variable()), + new Num(an.variables.get(ctx.variable()).getOffset())); + else + emit("to " + ctx.variable().getText(), OpCode.storeAI, getReg(ctx), getVar(ctx.variable()), + new Num(an.variables.get(ctx.variable()).getOffset())); + + return null; + } + + @Override + public Void visitCall(CallContext ctx) { + String base = "call " + ctx.variable().getText() + " - "; + Variable function = an.variables.get(ctx.variable()); + FunctionType parameters = ((FunctionType) function.getType()); + visit(ctx.variable()); + freeReg(ctx.variable()); + emit(base + "target address", OpCode.loadAI, getVar(ctx.variable()), + new Num(an.variables.get(ctx.variable()).getOffset()), makeReg(ctx)); + emit(base + "target address", OpCode.push, getReg(ctx)); + freeReg(ctx); + + for (int i = 0; i < ctx.expr().size(); i++) { + visit(ctx.expr(i)); + + if (SimpleType.CHAR.equals(parameters.getParameters().get(i))) + emit(base + "param " + i, OpCode.cpush, getReg(ctx.expr(i))); + else + emit(base + "param " + i, OpCode.push, getReg(ctx.expr(i))); + freeReg(ctx.expr(i)); + } + + emit(base + "set new ARP", OpCode.addI, arp, + new Num(((FunctionType) an.function.get(ctx).getType()).getLocalDataSize() + ARBASESIZE), tempArp); + + makeReg(ctx); + for (int i = ctx.expr().size() - 1; i >= 0; i--) { + if (SimpleType.CHAR.equals(parameters.getParameters().get(i))) { + emit(base + "param " + i, OpCode.cpop, getReg(ctx)); + emit(base + "param " + i, OpCode.cstoreAI, getReg(ctx), tempArp, + new Num(parameters.getOffsets().get(i))); + } else { + emit(base + "param " + i, OpCode.pop, getReg(ctx)); + emit(base + "param " + i, OpCode.storeAI, getReg(ctx), tempArp, + new Num(parameters.getOffsets().get(i))); + } + } + + emit(base + "link caller ARP", OpCode.storeAI, arp, tempArp, OFFSET_ARP); + + emit(base + "travelling ALs", OpCode.i2i, arp, getReg(ctx)); + for (int i = an.variables.get(ctx.variable()).getDepth(); i <= an.function.get(ctx).getDepth(); i++) + emit(base + StringUtils.repeat(' ', i) + "\\", OpCode.loadAI, getReg(ctx), OFFSET_AL, getReg(ctx)); + emit(base + "link caller AL", OpCode.storeAI, getReg(ctx), tempArp, OFFSET_AL); + + Label label = new Label("ret" + ctx.hashCode()); + emit(base + "load return address", OpCode.loadI, new Num(label), getReg(ctx)); + emit(base + "set return address", OpCode.storeAI, getReg(ctx), tempArp, OFFSET_RETURN_ADDR); + emit(base + "move ARP", OpCode.i2i, tempArp, arp); + emit(base + "target address", OpCode.pop, getReg(ctx)); + freeReg(ctx); + + Stack inUse = new Stack<>(); + for (Reg reg : regInUse) { + inUse.push(reg); + emit(base + "register save " + reg.getName(), OpCode.push, reg); + } + + emit(base + "execute", OpCode.jump, getReg(ctx)); + + emit(base + "load result", label, OpCode.loadAI, arp, OFFSET_RETURN_VAL, makeReg(ctx)); + while (!inUse.isEmpty()) { + Reg reg = inUse.pop(); + emit(base + "restoring register save " + reg.getName(), OpCode.pop, reg); + } + emit(base + "reset ARP", OpCode.loadAI, arp, OFFSET_ARP, arp); + + return null; + } + + @Override + public Void visitFuncDeclare(FuncDeclareContext ctx) { + String base = "define " + ctx.IDENTIFIER(0).getText() + " - "; + Label skip = new Label("s" + ctx.hashCode()); + emit(base + "jump over body", OpCode.jumpI, skip); + int targetAddress = emit(base + "entry point", OpCode.nop).getLine(); + visit(ctx.body); + emit(base + "move result", OpCode.storeAI, getReg(ctx.body), arp, OFFSET_RETURN_VAL); + freeReg(ctx.body); + emit(base + "load return address", OpCode.loadAI, arp, OFFSET_RETURN_ADDR, makeReg(ctx)); + emit(base + "go to return address", OpCode.jump, getReg(ctx)); + emit(base + "load target address", skip, OpCode.loadI, new Num(targetAddress), getReg(ctx)); + emit(base + "set target address", OpCode.storeAI, getReg(ctx), getVar(ctx), + new Num(an.variables.get(ctx).getOffset())); + freeReg(ctx); + an.registers.removeFrom(ctx); + return null; + } + + @Override + public Void visitBool(BoolContext ctx) { + emit(ctx.getText(), OpCode.loadI, new Num(ctx.TRUE() != null ? 1 : 0), makeReg(ctx)); + return null; + } + + @Override + public Void visitNumber(NumberContext ctx) { + emit(ctx.getText(), OpCode.loadI, new Num(Integer.parseInt(ctx.LITERAL10().getText())), makeReg(ctx)); + return null; + } + + @Override + public Void visitInfix1(Infix1Context ctx) { + visitChildren(ctx); + emit(ctx.getChild(1).getText(), ops.get(ctx.op.getType()), getReg(ctx.lhs), getReg(ctx.rhs), + copyReg(ctx.lhs, ctx)); + freeReg(ctx.rhs); + return null; + } + + @Override + public Void visitInfix2(Infix2Context ctx) { + visitChildren(ctx); + emit(ctx.getChild(1).getText(), ops.get(ctx.op.getType()), getReg(ctx.lhs), getReg(ctx.rhs), + copyReg(ctx.lhs, ctx)); + freeReg(ctx.rhs); + return null; + } + + @Override + public Void visitInfix3(Infix3Context ctx) { + visitChildren(ctx); + emit(ctx.getChild(1).getText(), ops.get(ctx.op.getType()), getReg(ctx.lhs), getReg(ctx.rhs), + copyReg(ctx.lhs, ctx)); + freeReg(ctx.rhs); + return null; + } + + @Override + public Void visitInfix4(Infix4Context ctx) { + visitChildren(ctx); + emit(ctx.getChild(1).getText(), ops.get(ctx.AND().getSymbol().getType()), getReg(ctx.lhs), getReg(ctx.rhs), + copyReg(ctx.lhs, ctx)); + freeReg(ctx.rhs); + return null; + } + + @Override + public Void visitInfix5(Infix5Context ctx) { + visitChildren(ctx); + emit(ctx.getChild(1).getText(), ops.get(ctx.OR().getSymbol().getType()), getReg(ctx.lhs), getReg(ctx.rhs), + copyReg(ctx.lhs, ctx)); + freeReg(ctx.rhs); + return null; + } + + @Override + public Void visitPrefix1(Prefix1Context ctx) { + visitChildren(ctx); + copyReg(ctx.singleExpr(), ctx); + + switch (ctx.op.getType()) { + case BoppiLexer.MINUS: + emit("unary -", OpCode.rsubI, getReg(ctx), ZERO, getReg(ctx)); + } + return null; + } + + @Override + public Void visitVar(VarContext ctx) { + if (SimpleType.CHAR.equals(an.types.get(ctx))) + emit("var " + ctx.variable().getText(), OpCode.cloadAI, getVar(ctx.variable()), + new Num(an.variables.get(ctx.variable()).getOffset()), makeReg(ctx)); + else + emit("var " + ctx.variable().getText(), OpCode.loadAI, getVar(ctx.variable()), + new Num(an.variables.get(ctx.variable()).getOffset()), makeReg(ctx)); + + return null; + } + + @Override + public Void visitChar(CharContext ctx) { + emit(ctx.getText(), OpCode.loadI, new Num(ctx.CHAR().getText().codePointAt(1)), makeReg(ctx)); + emit(ctx.getText(), OpCode.i2c, getReg(ctx), getReg(ctx)); + return null; + } + + @Override + public Void visitRead(ReadContext ctx) { + if (ctx.variable().size() > 1) { + for (VariableContext expr : ctx.variable()) { + visit(expr); + if (SimpleType.BOOL.equals(an.types.get(expr)) || SimpleType.INT.equals(an.types.get(expr))) { + emit("", OpCode.in, new Str(""), makeReg(ctx)); + emit("var " + expr.getText(), OpCode.storeAI, getReg(ctx), getVar(expr), + new Num(an.variables.get(expr).getOffset())); + } else if (SimpleType.CHAR.equals(an.types.get(expr))) { + // Get input until at least 1 character + Label getTarget = new Label("lcin_l" + ctx.hashCode()); + Label continueTarget = new Label("lcin_e" + ctx.hashCode()); + + Reg countReg = makeReg(ctx); + makeReg(ctx); + + emit("", getTarget, OpCode.cin, new Str("")); + emit("str length", OpCode.pop, countReg); + emit("repeat if 0 length", OpCode.cbr, countReg, continueTarget, getTarget); + + // Get character + emit("pop whole string", continueTarget, OpCode.cpop, getReg(ctx)); + emit("var " + expr.getText(), OpCode.cstoreAI, getReg(ctx), getVar(expr), + new Num(an.variables.get(expr).getOffset())); + + // Pop all remaining characters + Label loopTarget = new Label("lcpop_l" + ctx.hashCode()); + Label iterTarget = new Label("lcpop_c" + ctx.hashCode()); + Label stopTarget = new Label("lcpop_e" + ctx.hashCode()); + emit("pop remaining", loopTarget, OpCode.subI, countReg, new Num(1), countReg); + emit("pop remaining", OpCode.cbr, countReg, iterTarget, stopTarget); + emit("pop remaining", iterTarget, OpCode.cpop, getReg(ctx)); + emit("pop remaining", OpCode.jumpI, loopTarget); + emit("pop remaining", stopTarget, OpCode.nop); + } else { + emit("????????", OpCode.out, new Str("Unknown type: "), copyReg(expr, ctx)); + } + freeReg(ctx); + } + } else { + VariableContext expr = ctx.variable(0); + visit(expr); + if (SimpleType.BOOL.equals(an.types.get(expr)) || SimpleType.INT.equals(an.types.get(expr))) { + emit("", OpCode.in, new Str(""), makeReg(ctx)); + emit("var " + expr.getText(), OpCode.storeAI, getReg(ctx), getVar(expr), + new Num(an.variables.get(expr).getOffset())); + } else if (SimpleType.CHAR.equals(an.types.get(expr))) { + // Get input until at least 1 character + Label getTarget = new Label("lcin_l" + ctx.hashCode()); + Label continueTarget = new Label("lcin_e" + ctx.hashCode()); + + Reg countReg = makeReg(ctx); + makeReg(ctx); + + emit("", getTarget, OpCode.cin, new Str("")); + emit("str length", OpCode.pop, countReg); + emit("repeat if 0 length", OpCode.cbr, countReg, continueTarget, getTarget); + + // Get character + emit("pop whole string", continueTarget, OpCode.cpop, getReg(ctx)); + emit("var " + expr.getText(), OpCode.cstoreAI, getReg(ctx), getVar(expr), + new Num(an.variables.get(expr).getOffset())); + + // Pop all remaining characters + Label loopTarget = new Label("lcpop_l" + ctx.hashCode()); + Label iterTarget = new Label("lcpop_c" + ctx.hashCode()); + Label stopTarget = new Label("lcpop_e" + ctx.hashCode()); + emit("pop remaining", loopTarget, OpCode.subI, countReg, new Num(1), countReg); + emit("pop remaining", OpCode.cbr, countReg, iterTarget, stopTarget); + emit("pop remaining", iterTarget, OpCode.cpop, getReg(ctx)); + emit("pop remaining", OpCode.jumpI, loopTarget); + emit("pop remaining", stopTarget, OpCode.nop); + // Reload value + emit("var " + expr.getText(), OpCode.cloadAI, getVar(expr), new Num(an.variables.get(expr).getOffset()), + getReg(ctx)); + } + } + return null; + } + + @Override + public Void visitIf(IfContext ctx) { + Label toTrue = new Label("if_t" + ctx.hashCode()); + Label toFalse = new Label("if_f" + ctx.hashCode()); + Label toEnd = new Label("if_e" + ctx.hashCode()); + + visit(ctx.cond); + if (ctx.onFalse == null) { + emit("", OpCode.cbr, getReg(ctx.cond), toTrue, toEnd); + freeReg(ctx.cond); + + emit("", toTrue, OpCode.nop); + visit(ctx.onTrue); + freeReg(ctx.onTrue); + } else { + emit("", OpCode.cbr, getReg(ctx.cond), toTrue, toFalse); + freeReg(ctx.cond); + + emit("", toTrue, OpCode.nop); + visit(ctx.onTrue); + freeReg(ctx.onTrue); + if (an.types.get(ctx) != SimpleType.VOID) + emit("result", OpCode.i2i, getReg(ctx.onTrue), makeReg(ctx)); + emit("", OpCode.jumpI, toEnd); + freeReg(ctx); + + emit("", toFalse, OpCode.nop); + visit(ctx.onFalse); + freeReg(ctx.onFalse); + if (an.types.get(ctx) != SimpleType.VOID) + emit("result", OpCode.i2i, getReg(ctx.onFalse), makeReg(ctx)); + + } + emit("end target", toEnd, OpCode.nop); + + return null; + } + + @Override + public Void visitWhile(WhileContext ctx) { + Label toLoop = new Label("while_t" + ctx.hashCode()); + Label toCond = new Label("while_f" + ctx.hashCode()); + Label toEnd = new Label("while_e" + ctx.hashCode()); + + emit("to condition", OpCode.jumpI, toCond); + emit("loop target", toLoop, OpCode.nop); + visit(ctx.onTrue); + freeReg(ctx.onTrue); + emit("condition target", toCond, OpCode.nop); + visit(ctx.cond); + freeReg(ctx.cond); + emit("", OpCode.cbr, getReg(ctx.cond), toLoop, toEnd); + emit("end target", toEnd, OpCode.nop); + + return null; + } + + @Override + public Void visitWrite(WriteContext ctx) { + if (ctx.expr().size() > 1) { + for (ExprContext expr : ctx.expr()) { + visit(expr); + if (SimpleType.BOOL.equals(an.types.get(expr)) || SimpleType.INT.equals(an.types.get(expr))) { + emit("", OpCode.out, new Str(""), getReg(expr)); + } else if (SimpleType.CHAR.equals(an.types.get(expr))) { + makeReg(ctx); + emit("push character", OpCode.cpush, getReg(expr)); + emit("load 1", OpCode.loadI, new Num(1), getReg(ctx)); + emit("push 1", OpCode.push, getReg(ctx)); + emit("print character", OpCode.cout, new Str("")); + freeReg(ctx); + } else { + emit("??????????????", OpCode.out, new Str("Unknown type: "), getReg(expr)); + } + freeReg(expr); + } + an.registers.removeFrom(ctx); + } else { + ExprContext expr = ctx.expr(0); + visit(expr); + if (SimpleType.BOOL.equals(an.types.get(expr)) || SimpleType.INT.equals(an.types.get(expr))) { + emit("", OpCode.out, new Str(""), getReg(expr)); + } else if (SimpleType.CHAR.equals(an.types.get(expr))) { + makeReg(ctx); + emit("push character", OpCode.cpush, getReg(expr)); + emit("load 1", OpCode.loadI, new Num(1), getReg(ctx)); + emit("push 1", OpCode.push, getReg(ctx)); + emit("print character", OpCode.cout, new Str("")); + freeReg(ctx); + } + + copyReg(expr, ctx); + } + return null; + } + + /** + * Returns an error message for a given parse tree node. + * + * @param ctx + * the parse tree node at which the error occurred + * @param message + * the error message + * @param args + * arguments for the message, see {@link String#format} + */ + private String getError(ParserRuleContext node, String message, Object... args) { + int line = node.getStart().getLine(); + int column = node.getStart().getCharPositionInLine(); + return String.format("Line %d:%d - %s", line, column, String.format(message, args)); + } +} diff --git a/src/pp/s1184725/boppi/DebugCachingSymbolTable.java b/src/pp/s1184725/boppi/DebugCachingSymbolTable.java index f133816..57e4917 100644 --- a/src/pp/s1184725/boppi/DebugCachingSymbolTable.java +++ b/src/pp/s1184725/boppi/DebugCachingSymbolTable.java @@ -11,8 +11,8 @@ public class DebugCachingSymbolTable extends CachingSymbolTable< @Override public void openFunctionScope() { - System.out.println(this.getClass().getName() + ": entering scope depth " + functionDepth); super.openFunctionScope(); + System.out.println(this.getClass().getName() + ": entering scope depth " + functionDepth); } @Override @@ -28,7 +28,7 @@ public class DebugCachingSymbolTable extends CachingSymbolTable< @Override public Variable put(String id, T type) throws Exception, EmptyStackException { - System.out.println(this.getClass().getName() + ": declaring '" + id + "' at scope " + functionDepth); + System.out.println(this.getClass().getName() + ": declaring '" + id + "' ("+type.toString()+") at scope " + functionDepth); return super.put(id, type); } diff --git a/src/pp/s1184725/boppi/FunctionType.java b/src/pp/s1184725/boppi/FunctionType.java index f7454c4..b3c70d8 100644 --- a/src/pp/s1184725/boppi/FunctionType.java +++ b/src/pp/s1184725/boppi/FunctionType.java @@ -10,13 +10,11 @@ public class FunctionType implements Type { private List offsets; private Type result; private int localDataSize; - private int depth; - public FunctionType(Type returnType, List parameterTypes, int depth) { + public FunctionType(Type returnType, List parameterTypes) { result = returnType; parameters = new ArrayList<>(parameterTypes); offsets = new ArrayList<>(); - this.depth = depth; } @Override @@ -83,12 +81,4 @@ public class FunctionType implements Type { public List getOffsets() { return offsets; } - - public int getDepth() { - return depth; - } - - public void setDepth(int newDepth) { - depth = newDepth; - } } diff --git a/src/pp/s1184725/boppi/SimpleType.java b/src/pp/s1184725/boppi/SimpleType.java index ccfa52e..f8a4f8f 100644 --- a/src/pp/s1184725/boppi/SimpleType.java +++ b/src/pp/s1184725/boppi/SimpleType.java @@ -1,8 +1,9 @@ package pp.s1184725.boppi; -import static pp.s1184725.boppi.BasicLexer.*; +import static pp.s1184725.boppi.antlr.BoppiLexer.*; import pp.iloc.eval.Machine; +import pp.s1184725.boppi.antlr.BoppiLexer; /** * This class provides 4 basic data types: @@ -28,7 +29,7 @@ public enum SimpleType implements Type { } /** - * Maps a token lexed by {@link BasicLexer} to a data type. + * Maps a token lexed by {@link BoppiLexer} to a data type. * * @param token * the token to parse diff --git a/src/pp/s1184725/boppi/ToolChain.java b/src/pp/s1184725/boppi/ToolChain.java index 941c08b..341ab8d 100644 --- a/src/pp/s1184725/boppi/ToolChain.java +++ b/src/pp/s1184725/boppi/ToolChain.java @@ -12,6 +12,8 @@ import org.apache.commons.lang3.tuple.Pair; import pp.iloc.Simulator; import pp.iloc.model.Program; +import pp.s1184725.boppi.antlr.BoppiLexer; +import pp.s1184725.boppi.antlr.BoppiParser; /** * This class provides methods for all steps in the Boppi tool chain. @@ -56,8 +58,8 @@ public class ToolChain { * the logger to attach * @return the initialised lexer */ - public static BasicLexer getLexer(CharStream stream, Logger logger) { - BasicLexer lexer = new BasicLexer(stream); + public static BoppiLexer getLexer(CharStream stream, Logger logger) { + BoppiLexer lexer = new BoppiLexer(stream); lexer.removeErrorListeners(); lexer.addErrorListener(new BaseErrorListener() { @Override @@ -79,8 +81,8 @@ public class ToolChain { * the logger to attach * @return the initialised parser */ - public static BasicParser getParser(BasicLexer lexer, Logger logger) { - BasicParser parser = new BasicParser(new CommonTokenStream(lexer)); + public static BoppiParser getParser(BoppiLexer lexer, Logger logger) { + BoppiParser parser = new BoppiParser(new CommonTokenStream(lexer)); parser.removeErrorListeners(); parser.addErrorListener(new BaseErrorListener() { @Override @@ -93,7 +95,7 @@ public class ToolChain { } /** - * Checks a (sub)program with the {@link BoppiBasicChecker} and returns the + * Checks a (sub)program with the {@link BoppiChecker} and returns the * annotations. * * @param program @@ -103,9 +105,7 @@ public class ToolChain { * @return the annotations made by the checker */ public static Annotations getAnnotations(ParseTree program, Logger logger) { - Annotations annotations = new Annotations(); - new BoppiBasicChecker(logger, annotations).visit(program); - return annotations; + return BoppiChecker.checkProgram(program, logger); } /** @@ -115,12 +115,12 @@ public class ToolChain { * the parse tree to convert to ILOC * @param annotations * the annotations object provided by the checking phase + * @param logger + * the logger to write checker messages to * @return an ILOC program */ - public static Program getILOC(ParseTree program, Annotations annotations) { - BoppiBasicGenerator generator = new BoppiBasicGenerator(annotations); - generator.visit(program); - return generator.prog; + public static Program getILOC(ParseTree program, Logger logger, Annotations annotations) { + return BoppiGenerator.generateProgram(program, annotations, logger); } /** @@ -170,7 +170,7 @@ public class ToolChain { List logs = makeListLog(logger); ParseTree ast = getParser(getLexer(stream, logger), logger).program(); - return Pair.of(getILOC(ast, getAnnotations(ast, logger)), logs); + return Pair.of(getILOC(ast, logger, getAnnotations(ast, logger)), logs); } /** @@ -185,7 +185,7 @@ public class ToolChain { */ public static Program compile(CharStream stream, Logger logger) { ParseTree ast = getParser(getLexer(stream, logger), logger).program(); - return getILOC(ast, getAnnotations(ast, logger)); + return getILOC(ast, logger, getAnnotations(ast, logger)); } /** diff --git a/src/pp/s1184725/boppi/Variable.java b/src/pp/s1184725/boppi/Variable.java index 0f7f47e..5d91ade 100644 --- a/src/pp/s1184725/boppi/Variable.java +++ b/src/pp/s1184725/boppi/Variable.java @@ -17,6 +17,8 @@ public class Variable { * * @param type * the type of the variable + * @param depth + * the lexical depth of this variable * @param offset * the memory offset for this variable */ diff --git a/src/pp/s1184725/boppi/Basic.g4 b/src/pp/s1184725/boppi/antlr/Boppi.g4 similarity index 89% rename from src/pp/s1184725/boppi/Basic.g4 rename to src/pp/s1184725/boppi/antlr/Boppi.g4 index b4d0e51..cb148d2 100644 --- a/src/pp/s1184725/boppi/Basic.g4 +++ b/src/pp/s1184725/boppi/antlr/Boppi.g4 @@ -1,4 +1,4 @@ -grammar Basic; +grammar Boppi; program: expr EOF; @@ -11,7 +11,7 @@ singleExpr | BRAOPEN expr BRACLOSE #block | IN PAROPEN variable (LISTDELIM variable)* PARCLOSE #read | OUT PAROPEN expr (LISTDELIM expr)* PARCLOSE #write - | variable PAROPEN expr (LISTDELIM expr)* PARCLOSE #call + | variable PAROPEN (expr (LISTDELIM expr)*)? PARCLOSE #call | IFOPEN cond=expr IFTRUE onTrue=expr (IFFALSE onFalse=expr)? IFCLOSE #if | WHILEOPEN cond=expr WHILETRUE onTrue=expr WHILECLOSE #while | op=(PLUS|MINUS|NOT) singleExpr #prefix1 @@ -21,7 +21,7 @@ singleExpr | lhs=singleExpr AND rhs=singleExpr #infix4 | lhs=singleExpr OR rhs=singleExpr #infix5 | DECLARE type IDENTIFIER #declare - | FUNCTION result=type name=IDENTIFIER PAROPEN type IDENTIFIER (LISTDELIM type IDENTIFIER)* PARCLOSE body=singleExpr #funcDeclare + | FUNCTION result=type name=IDENTIFIER PAROPEN (type IDENTIFIER (LISTDELIM type IDENTIFIER)*)? PARCLOSE body=singleExpr #funcDeclare | variable ASSIGN singleExpr #assign | variable #var | LITERAL10 #number diff --git a/src/pp/s1184725/boppi/Basic.tokens b/src/pp/s1184725/boppi/antlr/Boppi.tokens similarity index 100% rename from src/pp/s1184725/boppi/Basic.tokens rename to src/pp/s1184725/boppi/antlr/Boppi.tokens diff --git a/src/pp/s1184725/boppi/BasicBaseVisitor.java b/src/pp/s1184725/boppi/antlr/BoppiBaseVisitor.java similarity index 71% rename from src/pp/s1184725/boppi/BasicBaseVisitor.java rename to src/pp/s1184725/boppi/antlr/BoppiBaseVisitor.java index c827739..e3d021b 100644 --- a/src/pp/s1184725/boppi/BasicBaseVisitor.java +++ b/src/pp/s1184725/boppi/antlr/BoppiBaseVisitor.java @@ -1,182 +1,182 @@ -// Generated from Basic.g4 by ANTLR 4.7 -package pp.s1184725.boppi; +// Generated from Boppi.g4 by ANTLR 4.7 +package pp.s1184725.boppi.antlr; import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor; /** - * This class provides an empty implementation of {@link BasicVisitor}, + * This class provides an empty implementation of {@link BoppiVisitor}, * which can be extended to create a visitor which only needs to handle a subset * of the available methods. * * @param The return type of the visit operation. Use {@link Void} for * operations with no return type. */ -public class BasicBaseVisitor extends AbstractParseTreeVisitor implements BasicVisitor { +public class BoppiBaseVisitor extends AbstractParseTreeVisitor implements BoppiVisitor { /** * {@inheritDoc} * *

The default implementation returns the result of calling * {@link #visitChildren} on {@code ctx}.

*/ - @Override public T visitProgram(BasicParser.ProgramContext ctx) { return visitChildren(ctx); } + @Override public T visitProgram(BoppiParser.ProgramContext ctx) { return visitChildren(ctx); } /** * {@inheritDoc} * *

The default implementation returns the result of calling * {@link #visitChildren} on {@code ctx}.

*/ - @Override public T visitExpr(BasicParser.ExprContext ctx) { return visitChildren(ctx); } + @Override public T visitExpr(BoppiParser.ExprContext ctx) { return visitChildren(ctx); } /** * {@inheritDoc} * *

The default implementation returns the result of calling * {@link #visitChildren} on {@code ctx}.

*/ - @Override public T visitParens(BasicParser.ParensContext ctx) { return visitChildren(ctx); } + @Override public T visitParens(BoppiParser.ParensContext ctx) { return visitChildren(ctx); } /** * {@inheritDoc} * *

The default implementation returns the result of calling * {@link #visitChildren} on {@code ctx}.

*/ - @Override public T visitRead(BasicParser.ReadContext ctx) { return visitChildren(ctx); } + @Override public T visitRead(BoppiParser.ReadContext ctx) { return visitChildren(ctx); } /** * {@inheritDoc} * *

The default implementation returns the result of calling * {@link #visitChildren} on {@code ctx}.

*/ - @Override public T visitDeclare(BasicParser.DeclareContext ctx) { return visitChildren(ctx); } + @Override public T visitDeclare(BoppiParser.DeclareContext ctx) { return visitChildren(ctx); } /** * {@inheritDoc} * *

The default implementation returns the result of calling * {@link #visitChildren} on {@code ctx}.

*/ - @Override public T visitBool(BasicParser.BoolContext ctx) { return visitChildren(ctx); } + @Override public T visitBool(BoppiParser.BoolContext ctx) { return visitChildren(ctx); } /** * {@inheritDoc} * *

The default implementation returns the result of calling * {@link #visitChildren} on {@code ctx}.

*/ - @Override public T visitVar(BasicParser.VarContext ctx) { return visitChildren(ctx); } + @Override public T visitVar(BoppiParser.VarContext ctx) { return visitChildren(ctx); } /** * {@inheritDoc} * *

The default implementation returns the result of calling * {@link #visitChildren} on {@code ctx}.

*/ - @Override public T visitInfix2(BasicParser.Infix2Context ctx) { return visitChildren(ctx); } + @Override public T visitInfix2(BoppiParser.Infix2Context ctx) { return visitChildren(ctx); } /** * {@inheritDoc} * *

The default implementation returns the result of calling * {@link #visitChildren} on {@code ctx}.

*/ - @Override public T visitInfix3(BasicParser.Infix3Context ctx) { return visitChildren(ctx); } + @Override public T visitInfix3(BoppiParser.Infix3Context ctx) { return visitChildren(ctx); } /** * {@inheritDoc} * *

The default implementation returns the result of calling * {@link #visitChildren} on {@code ctx}.

*/ - @Override public T visitInfix1(BasicParser.Infix1Context ctx) { return visitChildren(ctx); } + @Override public T visitInfix1(BoppiParser.Infix1Context ctx) { return visitChildren(ctx); } /** * {@inheritDoc} * *

The default implementation returns the result of calling * {@link #visitChildren} on {@code ctx}.

*/ - @Override public T visitWhile(BasicParser.WhileContext ctx) { return visitChildren(ctx); } + @Override public T visitWhile(BoppiParser.WhileContext ctx) { return visitChildren(ctx); } /** * {@inheritDoc} * *

The default implementation returns the result of calling * {@link #visitChildren} on {@code ctx}.

*/ - @Override public T visitInfix4(BasicParser.Infix4Context ctx) { return visitChildren(ctx); } + @Override public T visitInfix4(BoppiParser.Infix4Context ctx) { return visitChildren(ctx); } /** * {@inheritDoc} * *

The default implementation returns the result of calling * {@link #visitChildren} on {@code ctx}.

*/ - @Override public T visitInfix5(BasicParser.Infix5Context ctx) { return visitChildren(ctx); } + @Override public T visitInfix5(BoppiParser.Infix5Context ctx) { return visitChildren(ctx); } /** * {@inheritDoc} * *

The default implementation returns the result of calling * {@link #visitChildren} on {@code ctx}.

*/ - @Override public T visitCall(BasicParser.CallContext ctx) { return visitChildren(ctx); } + @Override public T visitCall(BoppiParser.CallContext ctx) { return visitChildren(ctx); } /** * {@inheritDoc} * *

The default implementation returns the result of calling * {@link #visitChildren} on {@code ctx}.

*/ - @Override public T visitNumber(BasicParser.NumberContext ctx) { return visitChildren(ctx); } + @Override public T visitNumber(BoppiParser.NumberContext ctx) { return visitChildren(ctx); } /** * {@inheritDoc} * *

The default implementation returns the result of calling * {@link #visitChildren} on {@code ctx}.

*/ - @Override public T visitFuncDeclare(BasicParser.FuncDeclareContext ctx) { return visitChildren(ctx); } + @Override public T visitFuncDeclare(BoppiParser.FuncDeclareContext ctx) { return visitChildren(ctx); } /** * {@inheritDoc} * *

The default implementation returns the result of calling * {@link #visitChildren} on {@code ctx}.

*/ - @Override public T visitChar(BasicParser.CharContext ctx) { return visitChildren(ctx); } + @Override public T visitChar(BoppiParser.CharContext ctx) { return visitChildren(ctx); } /** * {@inheritDoc} * *

The default implementation returns the result of calling * {@link #visitChildren} on {@code ctx}.

*/ - @Override public T visitBlock(BasicParser.BlockContext ctx) { return visitChildren(ctx); } + @Override public T visitBlock(BoppiParser.BlockContext ctx) { return visitChildren(ctx); } /** * {@inheritDoc} * *

The default implementation returns the result of calling * {@link #visitChildren} on {@code ctx}.

*/ - @Override public T visitWrite(BasicParser.WriteContext ctx) { return visitChildren(ctx); } + @Override public T visitWrite(BoppiParser.WriteContext ctx) { return visitChildren(ctx); } /** * {@inheritDoc} * *

The default implementation returns the result of calling * {@link #visitChildren} on {@code ctx}.

*/ - @Override public T visitIf(BasicParser.IfContext ctx) { return visitChildren(ctx); } + @Override public T visitIf(BoppiParser.IfContext ctx) { return visitChildren(ctx); } /** * {@inheritDoc} * *

The default implementation returns the result of calling * {@link #visitChildren} on {@code ctx}.

*/ - @Override public T visitPrefix1(BasicParser.Prefix1Context ctx) { return visitChildren(ctx); } + @Override public T visitPrefix1(BoppiParser.Prefix1Context ctx) { return visitChildren(ctx); } /** * {@inheritDoc} * *

The default implementation returns the result of calling * {@link #visitChildren} on {@code ctx}.

*/ - @Override public T visitAssign(BasicParser.AssignContext ctx) { return visitChildren(ctx); } + @Override public T visitAssign(BoppiParser.AssignContext ctx) { return visitChildren(ctx); } /** * {@inheritDoc} * *

The default implementation returns the result of calling * {@link #visitChildren} on {@code ctx}.

*/ - @Override public T visitType(BasicParser.TypeContext ctx) { return visitChildren(ctx); } + @Override public T visitType(BoppiParser.TypeContext ctx) { return visitChildren(ctx); } /** * {@inheritDoc} * *

The default implementation returns the result of calling * {@link #visitChildren} on {@code ctx}.

*/ - @Override public T visitVariable(BasicParser.VariableContext ctx) { return visitChildren(ctx); } + @Override public T visitVariable(BoppiParser.VariableContext ctx) { return visitChildren(ctx); } } \ No newline at end of file diff --git a/src/pp/s1184725/boppi/BasicLexer.java b/src/pp/s1184725/boppi/antlr/BoppiLexer.java similarity index 97% rename from src/pp/s1184725/boppi/BasicLexer.java rename to src/pp/s1184725/boppi/antlr/BoppiLexer.java index 9ebc2fa..ce9647a 100644 --- a/src/pp/s1184725/boppi/BasicLexer.java +++ b/src/pp/s1184725/boppi/antlr/BoppiLexer.java @@ -1,5 +1,5 @@ -// Generated from Basic.g4 by ANTLR 4.7 -package pp.s1184725.boppi; +// Generated from Boppi.g4 by ANTLR 4.7 +package pp.s1184725.boppi.antlr; import org.antlr.v4.runtime.Lexer; import org.antlr.v4.runtime.CharStream; import org.antlr.v4.runtime.Token; @@ -10,7 +10,7 @@ import org.antlr.v4.runtime.dfa.DFA; import org.antlr.v4.runtime.misc.*; @SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"}) -public class BasicLexer extends Lexer { +public class BoppiLexer extends Lexer { static { RuntimeMetaData.checkVersion("4.7", RuntimeMetaData.VERSION); } protected static final DFA[] _decisionToDFA; @@ -90,13 +90,13 @@ public class BasicLexer extends Lexer { } - public BasicLexer(CharStream input) { + public BoppiLexer(CharStream input) { super(input); _interp = new LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache); } @Override - public String getGrammarFileName() { return "Basic.g4"; } + public String getGrammarFileName() { return "Boppi.g4"; } @Override public String[] getRuleNames() { return ruleNames; } diff --git a/src/pp/s1184725/boppi/BasicLexer.tokens b/src/pp/s1184725/boppi/antlr/BoppiLexer.tokens similarity index 100% rename from src/pp/s1184725/boppi/BasicLexer.tokens rename to src/pp/s1184725/boppi/antlr/BoppiLexer.tokens diff --git a/src/pp/s1184725/boppi/BasicParser.java b/src/pp/s1184725/boppi/antlr/BoppiParser.java similarity index 74% rename from src/pp/s1184725/boppi/BasicParser.java rename to src/pp/s1184725/boppi/antlr/BoppiParser.java index 06b13ef..b097e5a 100644 --- a/src/pp/s1184725/boppi/BasicParser.java +++ b/src/pp/s1184725/boppi/antlr/BoppiParser.java @@ -1,5 +1,5 @@ -// Generated from Basic.g4 by ANTLR 4.7 -package pp.s1184725.boppi; +// Generated from Boppi.g4 by ANTLR 4.7 +package pp.s1184725.boppi.antlr; import org.antlr.v4.runtime.atn.*; import org.antlr.v4.runtime.dfa.DFA; import org.antlr.v4.runtime.*; @@ -10,7 +10,7 @@ import java.util.Iterator; import java.util.ArrayList; @SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"}) -public class BasicParser extends Parser { +public class BoppiParser extends Parser { static { RuntimeMetaData.checkVersion("4.7", RuntimeMetaData.VERSION); } protected static final DFA[] _decisionToDFA; @@ -79,7 +79,7 @@ public class BasicParser extends Parser { } @Override - public String getGrammarFileName() { return "Basic.g4"; } + public String getGrammarFileName() { return "Boppi.g4"; } @Override public String[] getRuleNames() { return ruleNames; } @@ -90,7 +90,7 @@ public class BasicParser extends Parser { @Override public ATN getATN() { return _ATN; } - public BasicParser(TokenStream input) { + public BoppiParser(TokenStream input) { super(input); _interp = new ParserATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache); } @@ -98,14 +98,14 @@ public class BasicParser extends Parser { public ExprContext expr() { return getRuleContext(ExprContext.class,0); } - public TerminalNode EOF() { return getToken(BasicParser.EOF, 0); } + public TerminalNode EOF() { return getToken(BoppiParser.EOF, 0); } public ProgramContext(ParserRuleContext parent, int invokingState) { super(parent, invokingState); } @Override public int getRuleIndex() { return RULE_program; } @Override public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof BasicVisitor ) return ((BasicVisitor)visitor).visitProgram(this); + if ( visitor instanceof BoppiVisitor ) return ((BoppiVisitor)visitor).visitProgram(this); else return visitor.visitChildren(this); } } @@ -140,9 +140,9 @@ public class BasicParser extends Parser { public SingleExprContext singleExpr(int i) { return getRuleContext(SingleExprContext.class,i); } - public List COMPOUND() { return getTokens(BasicParser.COMPOUND); } + public List COMPOUND() { return getTokens(BoppiParser.COMPOUND); } public TerminalNode COMPOUND(int i) { - return getToken(BasicParser.COMPOUND, i); + return getToken(BoppiParser.COMPOUND, i); } public ExprContext(ParserRuleContext parent, int invokingState) { super(parent, invokingState); @@ -150,7 +150,7 @@ public class BasicParser extends Parser { @Override public int getRuleIndex() { return RULE_expr; } @Override public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof BasicVisitor ) return ((BasicVisitor)visitor).visitExpr(this); + if ( visitor instanceof BoppiVisitor ) return ((BoppiVisitor)visitor).visitExpr(this); else return visitor.visitChildren(this); } } @@ -213,59 +213,59 @@ public class BasicParser extends Parser { } } public static class ParensContext extends SingleExprContext { - public TerminalNode PAROPEN() { return getToken(BasicParser.PAROPEN, 0); } + public TerminalNode PAROPEN() { return getToken(BoppiParser.PAROPEN, 0); } public ExprContext expr() { return getRuleContext(ExprContext.class,0); } - public TerminalNode PARCLOSE() { return getToken(BasicParser.PARCLOSE, 0); } + public TerminalNode PARCLOSE() { return getToken(BoppiParser.PARCLOSE, 0); } public ParensContext(SingleExprContext ctx) { copyFrom(ctx); } @Override public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof BasicVisitor ) return ((BasicVisitor)visitor).visitParens(this); + if ( visitor instanceof BoppiVisitor ) return ((BoppiVisitor)visitor).visitParens(this); else return visitor.visitChildren(this); } } public static class ReadContext extends SingleExprContext { - public TerminalNode IN() { return getToken(BasicParser.IN, 0); } - public TerminalNode PAROPEN() { return getToken(BasicParser.PAROPEN, 0); } + public TerminalNode IN() { return getToken(BoppiParser.IN, 0); } + public TerminalNode PAROPEN() { return getToken(BoppiParser.PAROPEN, 0); } public List variable() { return getRuleContexts(VariableContext.class); } public VariableContext variable(int i) { return getRuleContext(VariableContext.class,i); } - public TerminalNode PARCLOSE() { return getToken(BasicParser.PARCLOSE, 0); } - public List LISTDELIM() { return getTokens(BasicParser.LISTDELIM); } + public TerminalNode PARCLOSE() { return getToken(BoppiParser.PARCLOSE, 0); } + public List LISTDELIM() { return getTokens(BoppiParser.LISTDELIM); } public TerminalNode LISTDELIM(int i) { - return getToken(BasicParser.LISTDELIM, i); + return getToken(BoppiParser.LISTDELIM, i); } public ReadContext(SingleExprContext ctx) { copyFrom(ctx); } @Override public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof BasicVisitor ) return ((BasicVisitor)visitor).visitRead(this); + if ( visitor instanceof BoppiVisitor ) return ((BoppiVisitor)visitor).visitRead(this); else return visitor.visitChildren(this); } } public static class DeclareContext extends SingleExprContext { - public TerminalNode DECLARE() { return getToken(BasicParser.DECLARE, 0); } + public TerminalNode DECLARE() { return getToken(BoppiParser.DECLARE, 0); } public TypeContext type() { return getRuleContext(TypeContext.class,0); } - public TerminalNode IDENTIFIER() { return getToken(BasicParser.IDENTIFIER, 0); } + public TerminalNode IDENTIFIER() { return getToken(BoppiParser.IDENTIFIER, 0); } public DeclareContext(SingleExprContext ctx) { copyFrom(ctx); } @Override public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof BasicVisitor ) return ((BasicVisitor)visitor).visitDeclare(this); + if ( visitor instanceof BoppiVisitor ) return ((BoppiVisitor)visitor).visitDeclare(this); else return visitor.visitChildren(this); } } public static class BoolContext extends SingleExprContext { - public TerminalNode TRUE() { return getToken(BasicParser.TRUE, 0); } - public TerminalNode FALSE() { return getToken(BasicParser.FALSE, 0); } + public TerminalNode TRUE() { return getToken(BoppiParser.TRUE, 0); } + public TerminalNode FALSE() { return getToken(BoppiParser.FALSE, 0); } public BoolContext(SingleExprContext ctx) { copyFrom(ctx); } @Override public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof BasicVisitor ) return ((BasicVisitor)visitor).visitBool(this); + if ( visitor instanceof BoppiVisitor ) return ((BoppiVisitor)visitor).visitBool(this); else return visitor.visitChildren(this); } } @@ -276,7 +276,7 @@ public class BasicParser extends Parser { public VarContext(SingleExprContext ctx) { copyFrom(ctx); } @Override public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof BasicVisitor ) return ((BasicVisitor)visitor).visitVar(this); + if ( visitor instanceof BoppiVisitor ) return ((BoppiVisitor)visitor).visitVar(this); else return visitor.visitChildren(this); } } @@ -290,12 +290,12 @@ public class BasicParser extends Parser { public SingleExprContext singleExpr(int i) { return getRuleContext(SingleExprContext.class,i); } - public TerminalNode PLUS() { return getToken(BasicParser.PLUS, 0); } - public TerminalNode MINUS() { return getToken(BasicParser.MINUS, 0); } + public TerminalNode PLUS() { return getToken(BoppiParser.PLUS, 0); } + public TerminalNode MINUS() { return getToken(BoppiParser.MINUS, 0); } public Infix2Context(SingleExprContext ctx) { copyFrom(ctx); } @Override public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof BasicVisitor ) return ((BasicVisitor)visitor).visitInfix2(this); + if ( visitor instanceof BoppiVisitor ) return ((BoppiVisitor)visitor).visitInfix2(this); else return visitor.visitChildren(this); } } @@ -309,16 +309,16 @@ public class BasicParser extends Parser { public SingleExprContext singleExpr(int i) { return getRuleContext(SingleExprContext.class,i); } - public TerminalNode LT() { return getToken(BasicParser.LT, 0); } - public TerminalNode LEQ() { return getToken(BasicParser.LEQ, 0); } - public TerminalNode GTE() { return getToken(BasicParser.GTE, 0); } - public TerminalNode GT() { return getToken(BasicParser.GT, 0); } - public TerminalNode EQ() { return getToken(BasicParser.EQ, 0); } - public TerminalNode NEQ() { return getToken(BasicParser.NEQ, 0); } + public TerminalNode LT() { return getToken(BoppiParser.LT, 0); } + public TerminalNode LEQ() { return getToken(BoppiParser.LEQ, 0); } + public TerminalNode GTE() { return getToken(BoppiParser.GTE, 0); } + public TerminalNode GT() { return getToken(BoppiParser.GT, 0); } + public TerminalNode EQ() { return getToken(BoppiParser.EQ, 0); } + public TerminalNode NEQ() { return getToken(BoppiParser.NEQ, 0); } public Infix3Context(SingleExprContext ctx) { copyFrom(ctx); } @Override public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof BasicVisitor ) return ((BasicVisitor)visitor).visitInfix3(this); + if ( visitor instanceof BoppiVisitor ) return ((BoppiVisitor)visitor).visitInfix3(this); else return visitor.visitChildren(this); } } @@ -332,22 +332,22 @@ public class BasicParser extends Parser { public SingleExprContext singleExpr(int i) { return getRuleContext(SingleExprContext.class,i); } - public TerminalNode MULTIPLY() { return getToken(BasicParser.MULTIPLY, 0); } - public TerminalNode DIVIDE() { return getToken(BasicParser.DIVIDE, 0); } - public TerminalNode MODULO() { return getToken(BasicParser.MODULO, 0); } + public TerminalNode MULTIPLY() { return getToken(BoppiParser.MULTIPLY, 0); } + public TerminalNode DIVIDE() { return getToken(BoppiParser.DIVIDE, 0); } + public TerminalNode MODULO() { return getToken(BoppiParser.MODULO, 0); } public Infix1Context(SingleExprContext ctx) { copyFrom(ctx); } @Override public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof BasicVisitor ) return ((BasicVisitor)visitor).visitInfix1(this); + if ( visitor instanceof BoppiVisitor ) return ((BoppiVisitor)visitor).visitInfix1(this); else return visitor.visitChildren(this); } } public static class WhileContext extends SingleExprContext { public ExprContext cond; public ExprContext onTrue; - public TerminalNode WHILEOPEN() { return getToken(BasicParser.WHILEOPEN, 0); } - public TerminalNode WHILETRUE() { return getToken(BasicParser.WHILETRUE, 0); } - public TerminalNode WHILECLOSE() { return getToken(BasicParser.WHILECLOSE, 0); } + public TerminalNode WHILEOPEN() { return getToken(BoppiParser.WHILEOPEN, 0); } + public TerminalNode WHILETRUE() { return getToken(BoppiParser.WHILETRUE, 0); } + public TerminalNode WHILECLOSE() { return getToken(BoppiParser.WHILECLOSE, 0); } public List expr() { return getRuleContexts(ExprContext.class); } @@ -357,14 +357,14 @@ public class BasicParser extends Parser { public WhileContext(SingleExprContext ctx) { copyFrom(ctx); } @Override public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof BasicVisitor ) return ((BasicVisitor)visitor).visitWhile(this); + if ( visitor instanceof BoppiVisitor ) return ((BoppiVisitor)visitor).visitWhile(this); else return visitor.visitChildren(this); } } public static class Infix4Context extends SingleExprContext { public SingleExprContext lhs; public SingleExprContext rhs; - public TerminalNode AND() { return getToken(BasicParser.AND, 0); } + public TerminalNode AND() { return getToken(BoppiParser.AND, 0); } public List singleExpr() { return getRuleContexts(SingleExprContext.class); } @@ -374,14 +374,14 @@ public class BasicParser extends Parser { public Infix4Context(SingleExprContext ctx) { copyFrom(ctx); } @Override public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof BasicVisitor ) return ((BasicVisitor)visitor).visitInfix4(this); + if ( visitor instanceof BoppiVisitor ) return ((BoppiVisitor)visitor).visitInfix4(this); else return visitor.visitChildren(this); } } public static class Infix5Context extends SingleExprContext { public SingleExprContext lhs; public SingleExprContext rhs; - public TerminalNode OR() { return getToken(BasicParser.OR, 0); } + public TerminalNode OR() { return getToken(BoppiParser.OR, 0); } public List singleExpr() { return getRuleContexts(SingleExprContext.class); } @@ -391,7 +391,7 @@ public class BasicParser extends Parser { public Infix5Context(SingleExprContext ctx) { copyFrom(ctx); } @Override public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof BasicVisitor ) return ((BasicVisitor)visitor).visitInfix5(this); + if ( visitor instanceof BoppiVisitor ) return ((BoppiVisitor)visitor).visitInfix5(this); else return visitor.visitChildren(this); } } @@ -399,31 +399,31 @@ public class BasicParser extends Parser { public VariableContext variable() { return getRuleContext(VariableContext.class,0); } - public TerminalNode PAROPEN() { return getToken(BasicParser.PAROPEN, 0); } + public TerminalNode PAROPEN() { return getToken(BoppiParser.PAROPEN, 0); } + public TerminalNode PARCLOSE() { return getToken(BoppiParser.PARCLOSE, 0); } public List expr() { return getRuleContexts(ExprContext.class); } public ExprContext expr(int i) { return getRuleContext(ExprContext.class,i); } - public TerminalNode PARCLOSE() { return getToken(BasicParser.PARCLOSE, 0); } - public List LISTDELIM() { return getTokens(BasicParser.LISTDELIM); } + public List LISTDELIM() { return getTokens(BoppiParser.LISTDELIM); } public TerminalNode LISTDELIM(int i) { - return getToken(BasicParser.LISTDELIM, i); + return getToken(BoppiParser.LISTDELIM, i); } public CallContext(SingleExprContext ctx) { copyFrom(ctx); } @Override public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof BasicVisitor ) return ((BasicVisitor)visitor).visitCall(this); + if ( visitor instanceof BoppiVisitor ) return ((BoppiVisitor)visitor).visitCall(this); else return visitor.visitChildren(this); } } public static class NumberContext extends SingleExprContext { - public TerminalNode LITERAL10() { return getToken(BasicParser.LITERAL10, 0); } + public TerminalNode LITERAL10() { return getToken(BoppiParser.LITERAL10, 0); } public NumberContext(SingleExprContext ctx) { copyFrom(ctx); } @Override public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof BasicVisitor ) return ((BasicVisitor)visitor).visitNumber(this); + if ( visitor instanceof BoppiVisitor ) return ((BoppiVisitor)visitor).visitNumber(this); else return visitor.visitChildren(this); } } @@ -431,73 +431,73 @@ public class BasicParser extends Parser { public TypeContext result; public Token name; public SingleExprContext body; - public TerminalNode FUNCTION() { return getToken(BasicParser.FUNCTION, 0); } - public TerminalNode PAROPEN() { return getToken(BasicParser.PAROPEN, 0); } + public TerminalNode FUNCTION() { return getToken(BoppiParser.FUNCTION, 0); } + public TerminalNode PAROPEN() { return getToken(BoppiParser.PAROPEN, 0); } + public TerminalNode PARCLOSE() { return getToken(BoppiParser.PARCLOSE, 0); } public List type() { return getRuleContexts(TypeContext.class); } public TypeContext type(int i) { return getRuleContext(TypeContext.class,i); } - public List IDENTIFIER() { return getTokens(BasicParser.IDENTIFIER); } + public List IDENTIFIER() { return getTokens(BoppiParser.IDENTIFIER); } public TerminalNode IDENTIFIER(int i) { - return getToken(BasicParser.IDENTIFIER, i); + return getToken(BoppiParser.IDENTIFIER, i); } - public TerminalNode PARCLOSE() { return getToken(BasicParser.PARCLOSE, 0); } public SingleExprContext singleExpr() { return getRuleContext(SingleExprContext.class,0); } - public List LISTDELIM() { return getTokens(BasicParser.LISTDELIM); } + public List LISTDELIM() { return getTokens(BoppiParser.LISTDELIM); } public TerminalNode LISTDELIM(int i) { - return getToken(BasicParser.LISTDELIM, i); + return getToken(BoppiParser.LISTDELIM, i); } public FuncDeclareContext(SingleExprContext ctx) { copyFrom(ctx); } @Override public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof BasicVisitor ) return ((BasicVisitor)visitor).visitFuncDeclare(this); + if ( visitor instanceof BoppiVisitor ) return ((BoppiVisitor)visitor).visitFuncDeclare(this); else return visitor.visitChildren(this); } } public static class CharContext extends SingleExprContext { - public TerminalNode CHAR() { return getToken(BasicParser.CHAR, 0); } + public TerminalNode CHAR() { return getToken(BoppiParser.CHAR, 0); } public CharContext(SingleExprContext ctx) { copyFrom(ctx); } @Override public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof BasicVisitor ) return ((BasicVisitor)visitor).visitChar(this); + if ( visitor instanceof BoppiVisitor ) return ((BoppiVisitor)visitor).visitChar(this); else return visitor.visitChildren(this); } } public static class BlockContext extends SingleExprContext { - public TerminalNode BRAOPEN() { return getToken(BasicParser.BRAOPEN, 0); } + public TerminalNode BRAOPEN() { return getToken(BoppiParser.BRAOPEN, 0); } public ExprContext expr() { return getRuleContext(ExprContext.class,0); } - public TerminalNode BRACLOSE() { return getToken(BasicParser.BRACLOSE, 0); } + public TerminalNode BRACLOSE() { return getToken(BoppiParser.BRACLOSE, 0); } public BlockContext(SingleExprContext ctx) { copyFrom(ctx); } @Override public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof BasicVisitor ) return ((BasicVisitor)visitor).visitBlock(this); + if ( visitor instanceof BoppiVisitor ) return ((BoppiVisitor)visitor).visitBlock(this); else return visitor.visitChildren(this); } } public static class WriteContext extends SingleExprContext { - public TerminalNode OUT() { return getToken(BasicParser.OUT, 0); } - public TerminalNode PAROPEN() { return getToken(BasicParser.PAROPEN, 0); } + public TerminalNode OUT() { return getToken(BoppiParser.OUT, 0); } + public TerminalNode PAROPEN() { return getToken(BoppiParser.PAROPEN, 0); } public List expr() { return getRuleContexts(ExprContext.class); } public ExprContext expr(int i) { return getRuleContext(ExprContext.class,i); } - public TerminalNode PARCLOSE() { return getToken(BasicParser.PARCLOSE, 0); } - public List LISTDELIM() { return getTokens(BasicParser.LISTDELIM); } + public TerminalNode PARCLOSE() { return getToken(BoppiParser.PARCLOSE, 0); } + public List LISTDELIM() { return getTokens(BoppiParser.LISTDELIM); } public TerminalNode LISTDELIM(int i) { - return getToken(BasicParser.LISTDELIM, i); + return getToken(BoppiParser.LISTDELIM, i); } public WriteContext(SingleExprContext ctx) { copyFrom(ctx); } @Override public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof BasicVisitor ) return ((BasicVisitor)visitor).visitWrite(this); + if ( visitor instanceof BoppiVisitor ) return ((BoppiVisitor)visitor).visitWrite(this); else return visitor.visitChildren(this); } } @@ -505,20 +505,20 @@ public class BasicParser extends Parser { public ExprContext cond; public ExprContext onTrue; public ExprContext onFalse; - public TerminalNode IFOPEN() { return getToken(BasicParser.IFOPEN, 0); } - public TerminalNode IFTRUE() { return getToken(BasicParser.IFTRUE, 0); } - public TerminalNode IFCLOSE() { return getToken(BasicParser.IFCLOSE, 0); } + public TerminalNode IFOPEN() { return getToken(BoppiParser.IFOPEN, 0); } + public TerminalNode IFTRUE() { return getToken(BoppiParser.IFTRUE, 0); } + public TerminalNode IFCLOSE() { return getToken(BoppiParser.IFCLOSE, 0); } public List expr() { return getRuleContexts(ExprContext.class); } public ExprContext expr(int i) { return getRuleContext(ExprContext.class,i); } - public TerminalNode IFFALSE() { return getToken(BasicParser.IFFALSE, 0); } + public TerminalNode IFFALSE() { return getToken(BoppiParser.IFFALSE, 0); } public IfContext(SingleExprContext ctx) { copyFrom(ctx); } @Override public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof BasicVisitor ) return ((BasicVisitor)visitor).visitIf(this); + if ( visitor instanceof BoppiVisitor ) return ((BoppiVisitor)visitor).visitIf(this); else return visitor.visitChildren(this); } } @@ -527,13 +527,13 @@ public class BasicParser extends Parser { public SingleExprContext singleExpr() { return getRuleContext(SingleExprContext.class,0); } - public TerminalNode PLUS() { return getToken(BasicParser.PLUS, 0); } - public TerminalNode MINUS() { return getToken(BasicParser.MINUS, 0); } - public TerminalNode NOT() { return getToken(BasicParser.NOT, 0); } + public TerminalNode PLUS() { return getToken(BoppiParser.PLUS, 0); } + public TerminalNode MINUS() { return getToken(BoppiParser.MINUS, 0); } + public TerminalNode NOT() { return getToken(BoppiParser.NOT, 0); } public Prefix1Context(SingleExprContext ctx) { copyFrom(ctx); } @Override public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof BasicVisitor ) return ((BasicVisitor)visitor).visitPrefix1(this); + if ( visitor instanceof BoppiVisitor ) return ((BoppiVisitor)visitor).visitPrefix1(this); else return visitor.visitChildren(this); } } @@ -541,14 +541,14 @@ public class BasicParser extends Parser { public VariableContext variable() { return getRuleContext(VariableContext.class,0); } - public TerminalNode ASSIGN() { return getToken(BasicParser.ASSIGN, 0); } + public TerminalNode ASSIGN() { return getToken(BoppiParser.ASSIGN, 0); } public SingleExprContext singleExpr() { return getRuleContext(SingleExprContext.class,0); } public AssignContext(SingleExprContext ctx) { copyFrom(ctx); } @Override public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof BasicVisitor ) return ((BasicVisitor)visitor).visitAssign(this); + if ( visitor instanceof BoppiVisitor ) return ((BoppiVisitor)visitor).visitAssign(this); else return visitor.visitChildren(this); } } @@ -569,9 +569,9 @@ public class BasicParser extends Parser { int _alt; enterOuterAlt(_localctx, 1); { - setState(116); + setState(120); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,7,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,9,_ctx) ) { case 1: { _localctx = new ParensContext(_localctx); @@ -670,25 +670,33 @@ public class BasicParser extends Parser { variable(); setState(57); match(PAROPEN); - setState(58); - expr(); - setState(63); + setState(66); _errHandler.sync(this); _la = _input.LA(1); - while (_la==LISTDELIM) { + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << PAROPEN) | (1L << BRAOPEN) | (1L << IN) | (1L << OUT) | (1L << IFOPEN) | (1L << WHILEOPEN) | (1L << PLUS) | (1L << MINUS) | (1L << NOT) | (1L << DECLARE) | (1L << FUNCTION) | (1L << CHAR) | (1L << TRUE) | (1L << FALSE) | (1L << IDENTIFIER) | (1L << LITERAL10))) != 0)) { { - { - setState(59); - match(LISTDELIM); - setState(60); + setState(58); expr(); - } - } - setState(65); + setState(63); _errHandler.sync(this); _la = _input.LA(1); + while (_la==LISTDELIM) { + { + { + setState(59); + match(LISTDELIM); + setState(60); + expr(); + } + } + setState(65); + _errHandler.sync(this); + _la = _input.LA(1); + } + } } - setState(66); + + setState(68); match(PARCLOSE); } break; @@ -697,27 +705,27 @@ public class BasicParser extends Parser { _localctx = new IfContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(68); - match(IFOPEN); - setState(69); - ((IfContext)_localctx).cond = expr(); setState(70); - match(IFTRUE); + match(IFOPEN); setState(71); + ((IfContext)_localctx).cond = expr(); + setState(72); + match(IFTRUE); + setState(73); ((IfContext)_localctx).onTrue = expr(); - setState(74); + setState(76); _errHandler.sync(this); _la = _input.LA(1); if (_la==IFFALSE) { { - setState(72); + setState(74); match(IFFALSE); - setState(73); + setState(75); ((IfContext)_localctx).onFalse = expr(); } } - setState(76); + setState(78); match(IFCLOSE); } break; @@ -726,15 +734,15 @@ public class BasicParser extends Parser { _localctx = new WhileContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(78); - match(WHILEOPEN); - setState(79); - ((WhileContext)_localctx).cond = expr(); setState(80); - match(WHILETRUE); + match(WHILEOPEN); setState(81); - ((WhileContext)_localctx).onTrue = expr(); + ((WhileContext)_localctx).cond = expr(); setState(82); + match(WHILETRUE); + setState(83); + ((WhileContext)_localctx).onTrue = expr(); + setState(84); match(WHILECLOSE); } break; @@ -743,7 +751,7 @@ public class BasicParser extends Parser { _localctx = new Prefix1Context(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(84); + setState(86); ((Prefix1Context)_localctx).op = _input.LT(1); _la = _input.LA(1); if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << PLUS) | (1L << MINUS) | (1L << NOT))) != 0)) ) { @@ -754,7 +762,7 @@ public class BasicParser extends Parser { _errHandler.reportMatch(this); consume(); } - setState(85); + setState(87); singleExpr(13); } break; @@ -763,11 +771,11 @@ public class BasicParser extends Parser { _localctx = new DeclareContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(86); - match(DECLARE); - setState(87); - type(); setState(88); + match(DECLARE); + setState(89); + type(); + setState(90); match(IDENTIFIER); } break; @@ -776,39 +784,47 @@ public class BasicParser extends Parser { _localctx = new FuncDeclareContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(90); - match(FUNCTION); - setState(91); - ((FuncDeclareContext)_localctx).result = type(); setState(92); - ((FuncDeclareContext)_localctx).name = match(IDENTIFIER); + match(FUNCTION); setState(93); - match(PAROPEN); + ((FuncDeclareContext)_localctx).result = type(); setState(94); - type(); + ((FuncDeclareContext)_localctx).name = match(IDENTIFIER); setState(95); - match(IDENTIFIER); - setState(102); + match(PAROPEN); + setState(107); _errHandler.sync(this); _la = _input.LA(1); - while (_la==LISTDELIM) { - { + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << INTTYPE) | (1L << BOOLTYPE) | (1L << CHARTYPE) | (1L << IDENTIFIER))) != 0)) { { setState(96); - match(LISTDELIM); - setState(97); type(); - setState(98); + setState(97); match(IDENTIFIER); - } - } setState(104); _errHandler.sync(this); _la = _input.LA(1); + while (_la==LISTDELIM) { + { + { + setState(98); + match(LISTDELIM); + setState(99); + type(); + setState(100); + match(IDENTIFIER); + } + } + setState(106); + _errHandler.sync(this); + _la = _input.LA(1); + } + } } - setState(105); + + setState(109); match(PARCLOSE); - setState(106); + setState(110); ((FuncDeclareContext)_localctx).body = singleExpr(6); } break; @@ -817,11 +833,11 @@ public class BasicParser extends Parser { _localctx = new AssignContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(108); + setState(112); variable(); - setState(109); + setState(113); match(ASSIGN); - setState(110); + setState(114); singleExpr(5); } break; @@ -830,7 +846,7 @@ public class BasicParser extends Parser { _localctx = new VarContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(112); + setState(116); variable(); } break; @@ -839,7 +855,7 @@ public class BasicParser extends Parser { _localctx = new NumberContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(113); + setState(117); match(LITERAL10); } break; @@ -848,7 +864,7 @@ public class BasicParser extends Parser { _localctx = new CharContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(114); + setState(118); match(CHAR); } break; @@ -857,7 +873,7 @@ public class BasicParser extends Parser { _localctx = new BoolContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(115); + setState(119); _la = _input.LA(1); if ( !(_la==TRUE || _la==FALSE) ) { _errHandler.recoverInline(this); @@ -871,25 +887,25 @@ public class BasicParser extends Parser { break; } _ctx.stop = _input.LT(-1); - setState(135); + setState(139); _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,9,_ctx); + _alt = getInterpreter().adaptivePredict(_input,11,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { if ( _parseListeners!=null ) triggerExitRuleEvent(); _prevctx = _localctx; { - setState(133); + setState(137); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,8,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,10,_ctx) ) { case 1: { _localctx = new Infix1Context(new SingleExprContext(_parentctx, _parentState)); ((Infix1Context)_localctx).lhs = _prevctx; pushNewRecursionContext(_localctx, _startState, RULE_singleExpr); - setState(118); + setState(122); if (!(precpred(_ctx, 12))) throw new FailedPredicateException(this, "precpred(_ctx, 12)"); - setState(119); + setState(123); ((Infix1Context)_localctx).op = _input.LT(1); _la = _input.LA(1); if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << MULTIPLY) | (1L << DIVIDE) | (1L << MODULO))) != 0)) ) { @@ -900,7 +916,7 @@ public class BasicParser extends Parser { _errHandler.reportMatch(this); consume(); } - setState(120); + setState(124); ((Infix1Context)_localctx).rhs = singleExpr(13); } break; @@ -909,9 +925,9 @@ public class BasicParser extends Parser { _localctx = new Infix2Context(new SingleExprContext(_parentctx, _parentState)); ((Infix2Context)_localctx).lhs = _prevctx; pushNewRecursionContext(_localctx, _startState, RULE_singleExpr); - setState(121); + setState(125); if (!(precpred(_ctx, 11))) throw new FailedPredicateException(this, "precpred(_ctx, 11)"); - setState(122); + setState(126); ((Infix2Context)_localctx).op = _input.LT(1); _la = _input.LA(1); if ( !(_la==PLUS || _la==MINUS) ) { @@ -922,7 +938,7 @@ public class BasicParser extends Parser { _errHandler.reportMatch(this); consume(); } - setState(123); + setState(127); ((Infix2Context)_localctx).rhs = singleExpr(12); } break; @@ -931,9 +947,9 @@ public class BasicParser extends Parser { _localctx = new Infix3Context(new SingleExprContext(_parentctx, _parentState)); ((Infix3Context)_localctx).lhs = _prevctx; pushNewRecursionContext(_localctx, _startState, RULE_singleExpr); - setState(124); + setState(128); if (!(precpred(_ctx, 10))) throw new FailedPredicateException(this, "precpred(_ctx, 10)"); - setState(125); + setState(129); ((Infix3Context)_localctx).op = _input.LT(1); _la = _input.LA(1); if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << LEQ) | (1L << GTE) | (1L << NEQ) | (1L << EQ) | (1L << LT) | (1L << GT))) != 0)) ) { @@ -944,7 +960,7 @@ public class BasicParser extends Parser { _errHandler.reportMatch(this); consume(); } - setState(126); + setState(130); ((Infix3Context)_localctx).rhs = singleExpr(11); } break; @@ -953,11 +969,11 @@ public class BasicParser extends Parser { _localctx = new Infix4Context(new SingleExprContext(_parentctx, _parentState)); ((Infix4Context)_localctx).lhs = _prevctx; pushNewRecursionContext(_localctx, _startState, RULE_singleExpr); - setState(127); + setState(131); if (!(precpred(_ctx, 9))) throw new FailedPredicateException(this, "precpred(_ctx, 9)"); - setState(128); + setState(132); match(AND); - setState(129); + setState(133); ((Infix4Context)_localctx).rhs = singleExpr(10); } break; @@ -966,20 +982,20 @@ public class BasicParser extends Parser { _localctx = new Infix5Context(new SingleExprContext(_parentctx, _parentState)); ((Infix5Context)_localctx).lhs = _prevctx; pushNewRecursionContext(_localctx, _startState, RULE_singleExpr); - setState(130); + setState(134); if (!(precpred(_ctx, 8))) throw new FailedPredicateException(this, "precpred(_ctx, 8)"); - setState(131); + setState(135); match(OR); - setState(132); + setState(136); ((Infix5Context)_localctx).rhs = singleExpr(9); } break; } } } - setState(137); + setState(141); _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,9,_ctx); + _alt = getInterpreter().adaptivePredict(_input,11,_ctx); } } } @@ -996,9 +1012,9 @@ public class BasicParser extends Parser { public static class TypeContext extends ParserRuleContext { public Token staticType; - public TerminalNode INTTYPE() { return getToken(BasicParser.INTTYPE, 0); } - public TerminalNode BOOLTYPE() { return getToken(BasicParser.BOOLTYPE, 0); } - public TerminalNode CHARTYPE() { return getToken(BasicParser.CHARTYPE, 0); } + public TerminalNode INTTYPE() { return getToken(BoppiParser.INTTYPE, 0); } + public TerminalNode BOOLTYPE() { return getToken(BoppiParser.BOOLTYPE, 0); } + public TerminalNode CHARTYPE() { return getToken(BoppiParser.CHARTYPE, 0); } public VariableContext variable() { return getRuleContext(VariableContext.class,0); } @@ -1008,7 +1024,7 @@ public class BasicParser extends Parser { @Override public int getRuleIndex() { return RULE_type; } @Override public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof BasicVisitor ) return ((BasicVisitor)visitor).visitType(this); + if ( visitor instanceof BoppiVisitor ) return ((BoppiVisitor)visitor).visitType(this); else return visitor.visitChildren(this); } } @@ -1018,7 +1034,7 @@ public class BasicParser extends Parser { enterRule(_localctx, 6, RULE_type); int _la; try { - setState(140); + setState(144); _errHandler.sync(this); switch (_input.LA(1)) { case INTTYPE: @@ -1026,7 +1042,7 @@ public class BasicParser extends Parser { case CHARTYPE: enterOuterAlt(_localctx, 1); { - setState(138); + setState(142); ((TypeContext)_localctx).staticType = _input.LT(1); _la = _input.LA(1); if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << INTTYPE) | (1L << BOOLTYPE) | (1L << CHARTYPE))) != 0)) ) { @@ -1042,7 +1058,7 @@ public class BasicParser extends Parser { case IDENTIFIER: enterOuterAlt(_localctx, 2); { - setState(139); + setState(143); variable(); } break; @@ -1062,14 +1078,14 @@ public class BasicParser extends Parser { } public static class VariableContext extends ParserRuleContext { - public TerminalNode IDENTIFIER() { return getToken(BasicParser.IDENTIFIER, 0); } + public TerminalNode IDENTIFIER() { return getToken(BoppiParser.IDENTIFIER, 0); } public VariableContext(ParserRuleContext parent, int invokingState) { super(parent, invokingState); } @Override public int getRuleIndex() { return RULE_variable; } @Override public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof BasicVisitor ) return ((BasicVisitor)visitor).visitVariable(this); + if ( visitor instanceof BoppiVisitor ) return ((BoppiVisitor)visitor).visitVariable(this); else return visitor.visitChildren(this); } } @@ -1080,7 +1096,7 @@ public class BasicParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(142); + setState(146); match(IDENTIFIER); } } @@ -1119,47 +1135,49 @@ public class BasicParser extends Parser { } public static final String _serializedATN = - "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3-\u0093\4\2\t\2\4"+ + "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3-\u0097\4\2\t\2\4"+ "\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\3\2\3\2\3\2\3\3\3\3\3\3\5\3\23\n\3\7\3"+ "\25\n\3\f\3\16\3\30\13\3\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3"+ "\4\3\4\3\4\7\4(\n\4\f\4\16\4+\13\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\7\4\64"+ "\n\4\f\4\16\4\67\13\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\7\4@\n\4\f\4\16\4C\13"+ - "\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\5\4M\n\4\3\4\3\4\3\4\3\4\3\4\3\4\3"+ + "\4\5\4E\n\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\5\4O\n\4\3\4\3\4\3\4\3\4\3"+ "\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4"+ - "\7\4g\n\4\f\4\16\4j\13\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\5"+ - "\4w\n\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\7"+ - "\4\u0088\n\4\f\4\16\4\u008b\13\4\3\5\3\5\5\5\u008f\n\5\3\6\3\6\3\6\2\3"+ - "\6\7\2\4\6\b\n\2\b\3\2\20\22\3\2\'(\3\2\23\25\3\2\20\21\3\2\26\33\3\2"+ - " \"\2\u00a8\2\f\3\2\2\2\4\17\3\2\2\2\6v\3\2\2\2\b\u008e\3\2\2\2\n\u0090"+ - "\3\2\2\2\f\r\5\4\3\2\r\16\7\2\2\3\16\3\3\2\2\2\17\26\5\6\4\2\20\22\7$"+ - "\2\2\21\23\5\6\4\2\22\21\3\2\2\2\22\23\3\2\2\2\23\25\3\2\2\2\24\20\3\2"+ - "\2\2\25\30\3\2\2\2\26\24\3\2\2\2\26\27\3\2\2\2\27\5\3\2\2\2\30\26\3\2"+ - "\2\2\31\32\b\4\1\2\32\33\7\3\2\2\33\34\5\4\3\2\34\35\7\4\2\2\35w\3\2\2"+ - "\2\36\37\7\5\2\2\37 \5\4\3\2 !\7\6\2\2!w\3\2\2\2\"#\7\7\2\2#$\7\3\2\2"+ - "$)\5\n\6\2%&\7%\2\2&(\5\n\6\2\'%\3\2\2\2(+\3\2\2\2)\'\3\2\2\2)*\3\2\2"+ - "\2*,\3\2\2\2+)\3\2\2\2,-\7\4\2\2-w\3\2\2\2./\7\b\2\2/\60\7\3\2\2\60\65"+ - "\5\4\3\2\61\62\7%\2\2\62\64\5\4\3\2\63\61\3\2\2\2\64\67\3\2\2\2\65\63"+ - "\3\2\2\2\65\66\3\2\2\2\668\3\2\2\2\67\65\3\2\2\289\7\4\2\29w\3\2\2\2:"+ - ";\5\n\6\2;<\7\3\2\2\7%\2\2>@\5\4\3\2?=\3\2\2\2@C\3\2\2\2A"+ - "?\3\2\2\2AB\3\2\2\2BD\3\2\2\2CA\3\2\2\2DE\7\4\2\2Ew\3\2\2\2FG\7\t\2\2"+ - "GH\5\4\3\2HI\7\n\2\2IL\5\4\3\2JK\7\13\2\2KM\5\4\3\2LJ\3\2\2\2LM\3\2\2"+ - "\2MN\3\2\2\2NO\7\f\2\2Ow\3\2\2\2PQ\7\r\2\2QR\5\4\3\2RS\7\16\2\2ST\5\4"+ - "\3\2TU\7\17\2\2Uw\3\2\2\2VW\t\2\2\2Ww\5\6\4\17XY\7\36\2\2YZ\5\b\5\2Z["+ - "\7)\2\2[w\3\2\2\2\\]\7\37\2\2]^\5\b\5\2^_\7)\2\2_`\7\3\2\2`a\5\b\5\2a"+ - "h\7)\2\2bc\7%\2\2cd\5\b\5\2de\7)\2\2eg\3\2\2\2fb\3\2\2\2gj\3\2\2\2hf\3"+ - "\2\2\2hi\3\2\2\2ik\3\2\2\2jh\3\2\2\2kl\7\4\2\2lm\5\6\4\bmw\3\2\2\2no\5"+ - "\n\6\2op\7#\2\2pq\5\6\4\7qw\3\2\2\2rw\5\n\6\2sw\7*\2\2tw\7&\2\2uw\t\3"+ - "\2\2v\31\3\2\2\2v\36\3\2\2\2v\"\3\2\2\2v.\3\2\2\2v:\3\2\2\2vF\3\2\2\2"+ - "vP\3\2\2\2vV\3\2\2\2vX\3\2\2\2v\\\3\2\2\2vn\3\2\2\2vr\3\2\2\2vs\3\2\2"+ - "\2vt\3\2\2\2vu\3\2\2\2w\u0089\3\2\2\2xy\f\16\2\2yz\t\4\2\2z\u0088\5\6"+ - "\4\17{|\f\r\2\2|}\t\5\2\2}\u0088\5\6\4\16~\177\f\f\2\2\177\u0080\t\6\2"+ - "\2\u0080\u0088\5\6\4\r\u0081\u0082\f\13\2\2\u0082\u0083\7\34\2\2\u0083"+ - "\u0088\5\6\4\f\u0084\u0085\f\n\2\2\u0085\u0086\7\35\2\2\u0086\u0088\5"+ - "\6\4\13\u0087x\3\2\2\2\u0087{\3\2\2\2\u0087~\3\2\2\2\u0087\u0081\3\2\2"+ - "\2\u0087\u0084\3\2\2\2\u0088\u008b\3\2\2\2\u0089\u0087\3\2\2\2\u0089\u008a"+ - "\3\2\2\2\u008a\7\3\2\2\2\u008b\u0089\3\2\2\2\u008c\u008f\t\7\2\2\u008d"+ - "\u008f\5\n\6\2\u008e\u008c\3\2\2\2\u008e\u008d\3\2\2\2\u008f\t\3\2\2\2"+ - "\u0090\u0091\7)\2\2\u0091\13\3\2\2\2\r\22\26)\65ALhv\u0087\u0089\u008e"; + "\3\4\3\4\7\4i\n\4\f\4\16\4l\13\4\5\4n\n\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4"+ + "\3\4\3\4\3\4\3\4\5\4{\n\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4"+ + "\3\4\3\4\3\4\3\4\7\4\u008c\n\4\f\4\16\4\u008f\13\4\3\5\3\5\5\5\u0093\n"+ + "\5\3\6\3\6\3\6\2\3\6\7\2\4\6\b\n\2\b\3\2\20\22\3\2\'(\3\2\23\25\3\2\20"+ + "\21\3\2\26\33\3\2 \"\2\u00ae\2\f\3\2\2\2\4\17\3\2\2\2\6z\3\2\2\2\b\u0092"+ + "\3\2\2\2\n\u0094\3\2\2\2\f\r\5\4\3\2\r\16\7\2\2\3\16\3\3\2\2\2\17\26\5"+ + "\6\4\2\20\22\7$\2\2\21\23\5\6\4\2\22\21\3\2\2\2\22\23\3\2\2\2\23\25\3"+ + "\2\2\2\24\20\3\2\2\2\25\30\3\2\2\2\26\24\3\2\2\2\26\27\3\2\2\2\27\5\3"+ + "\2\2\2\30\26\3\2\2\2\31\32\b\4\1\2\32\33\7\3\2\2\33\34\5\4\3\2\34\35\7"+ + "\4\2\2\35{\3\2\2\2\36\37\7\5\2\2\37 \5\4\3\2 !\7\6\2\2!{\3\2\2\2\"#\7"+ + "\7\2\2#$\7\3\2\2$)\5\n\6\2%&\7%\2\2&(\5\n\6\2\'%\3\2\2\2(+\3\2\2\2)\'"+ + "\3\2\2\2)*\3\2\2\2*,\3\2\2\2+)\3\2\2\2,-\7\4\2\2-{\3\2\2\2./\7\b\2\2/"+ + "\60\7\3\2\2\60\65\5\4\3\2\61\62\7%\2\2\62\64\5\4\3\2\63\61\3\2\2\2\64"+ + "\67\3\2\2\2\65\63\3\2\2\2\65\66\3\2\2\2\668\3\2\2\2\67\65\3\2\2\289\7"+ + "\4\2\29{\3\2\2\2:;\5\n\6\2;D\7\3\2\2\7%\2\2>@\5\4\3\2?=\3"+ + "\2\2\2@C\3\2\2\2A?\3\2\2\2AB\3\2\2\2BE\3\2\2\2CA\3\2\2\2D<\3\2\2\2DE\3"+ + "\2\2\2EF\3\2\2\2FG\7\4\2\2G{\3\2\2\2HI\7\t\2\2IJ\5\4\3\2JK\7\n\2\2KN\5"+ + "\4\3\2LM\7\13\2\2MO\5\4\3\2NL\3\2\2\2NO\3\2\2\2OP\3\2\2\2PQ\7\f\2\2Q{"+ + "\3\2\2\2RS\7\r\2\2ST\5\4\3\2TU\7\16\2\2UV\5\4\3\2VW\7\17\2\2W{\3\2\2\2"+ + "XY\t\2\2\2Y{\5\6\4\17Z[\7\36\2\2[\\\5\b\5\2\\]\7)\2\2]{\3\2\2\2^_\7\37"+ + "\2\2_`\5\b\5\2`a\7)\2\2am\7\3\2\2bc\5\b\5\2cj\7)\2\2de\7%\2\2ef\5\b\5"+ + "\2fg\7)\2\2gi\3\2\2\2hd\3\2\2\2il\3\2\2\2jh\3\2\2\2jk\3\2\2\2kn\3\2\2"+ + "\2lj\3\2\2\2mb\3\2\2\2mn\3\2\2\2no\3\2\2\2op\7\4\2\2pq\5\6\4\bq{\3\2\2"+ + "\2rs\5\n\6\2st\7#\2\2tu\5\6\4\7u{\3\2\2\2v{\5\n\6\2w{\7*\2\2x{\7&\2\2"+ + "y{\t\3\2\2z\31\3\2\2\2z\36\3\2\2\2z\"\3\2\2\2z.\3\2\2\2z:\3\2\2\2zH\3"+ + "\2\2\2zR\3\2\2\2zX\3\2\2\2zZ\3\2\2\2z^\3\2\2\2zr\3\2\2\2zv\3\2\2\2zw\3"+ + "\2\2\2zx\3\2\2\2zy\3\2\2\2{\u008d\3\2\2\2|}\f\16\2\2}~\t\4\2\2~\u008c"+ + "\5\6\4\17\177\u0080\f\r\2\2\u0080\u0081\t\5\2\2\u0081\u008c\5\6\4\16\u0082"+ + "\u0083\f\f\2\2\u0083\u0084\t\6\2\2\u0084\u008c\5\6\4\r\u0085\u0086\f\13"+ + "\2\2\u0086\u0087\7\34\2\2\u0087\u008c\5\6\4\f\u0088\u0089\f\n\2\2\u0089"+ + "\u008a\7\35\2\2\u008a\u008c\5\6\4\13\u008b|\3\2\2\2\u008b\177\3\2\2\2"+ + "\u008b\u0082\3\2\2\2\u008b\u0085\3\2\2\2\u008b\u0088\3\2\2\2\u008c\u008f"+ + "\3\2\2\2\u008d\u008b\3\2\2\2\u008d\u008e\3\2\2\2\u008e\7\3\2\2\2\u008f"+ + "\u008d\3\2\2\2\u0090\u0093\t\7\2\2\u0091\u0093\5\n\6\2\u0092\u0090\3\2"+ + "\2\2\u0092\u0091\3\2\2\2\u0093\t\3\2\2\2\u0094\u0095\7)\2\2\u0095\13\3"+ + "\2\2\2\17\22\26)\65ADNjmz\u008b\u008d\u0092"; public static final ATN _ATN = new ATNDeserializer().deserialize(_serializedATN.toCharArray()); static { diff --git a/src/pp/s1184725/boppi/BasicVisitor.java b/src/pp/s1184725/boppi/antlr/BoppiVisitor.java similarity index 52% rename from src/pp/s1184725/boppi/BasicVisitor.java rename to src/pp/s1184725/boppi/antlr/BoppiVisitor.java index 3863b4b..4ec59d8 100644 --- a/src/pp/s1184725/boppi/BasicVisitor.java +++ b/src/pp/s1184725/boppi/antlr/BoppiVisitor.java @@ -1,177 +1,177 @@ -// Generated from Basic.g4 by ANTLR 4.7 -package pp.s1184725.boppi; +// Generated from Boppi.g4 by ANTLR 4.7 +package pp.s1184725.boppi.antlr; import org.antlr.v4.runtime.tree.ParseTreeVisitor; /** * This interface defines a complete generic visitor for a parse tree produced - * by {@link BasicParser}. + * by {@link BoppiParser}. * * @param The return type of the visit operation. Use {@link Void} for * operations with no return type. */ -public interface BasicVisitor extends ParseTreeVisitor { +public interface BoppiVisitor extends ParseTreeVisitor { /** - * Visit a parse tree produced by {@link BasicParser#program}. + * Visit a parse tree produced by {@link BoppiParser#program}. * @param ctx the parse tree * @return the visitor result */ - T visitProgram(BasicParser.ProgramContext ctx); + T visitProgram(BoppiParser.ProgramContext ctx); /** - * Visit a parse tree produced by {@link BasicParser#expr}. + * Visit a parse tree produced by {@link BoppiParser#expr}. * @param ctx the parse tree * @return the visitor result */ - T visitExpr(BasicParser.ExprContext ctx); + T visitExpr(BoppiParser.ExprContext ctx); /** * Visit a parse tree produced by the {@code parens} - * labeled alternative in {@link BasicParser#singleExpr}. + * labeled alternative in {@link BoppiParser#singleExpr}. * @param ctx the parse tree * @return the visitor result */ - T visitParens(BasicParser.ParensContext ctx); + T visitParens(BoppiParser.ParensContext ctx); /** * Visit a parse tree produced by the {@code read} - * labeled alternative in {@link BasicParser#singleExpr}. + * labeled alternative in {@link BoppiParser#singleExpr}. * @param ctx the parse tree * @return the visitor result */ - T visitRead(BasicParser.ReadContext ctx); + T visitRead(BoppiParser.ReadContext ctx); /** * Visit a parse tree produced by the {@code declare} - * labeled alternative in {@link BasicParser#singleExpr}. + * labeled alternative in {@link BoppiParser#singleExpr}. * @param ctx the parse tree * @return the visitor result */ - T visitDeclare(BasicParser.DeclareContext ctx); + T visitDeclare(BoppiParser.DeclareContext ctx); /** * Visit a parse tree produced by the {@code bool} - * labeled alternative in {@link BasicParser#singleExpr}. + * labeled alternative in {@link BoppiParser#singleExpr}. * @param ctx the parse tree * @return the visitor result */ - T visitBool(BasicParser.BoolContext ctx); + T visitBool(BoppiParser.BoolContext ctx); /** * Visit a parse tree produced by the {@code var} - * labeled alternative in {@link BasicParser#singleExpr}. + * labeled alternative in {@link BoppiParser#singleExpr}. * @param ctx the parse tree * @return the visitor result */ - T visitVar(BasicParser.VarContext ctx); + T visitVar(BoppiParser.VarContext ctx); /** * Visit a parse tree produced by the {@code infix2} - * labeled alternative in {@link BasicParser#singleExpr}. + * labeled alternative in {@link BoppiParser#singleExpr}. * @param ctx the parse tree * @return the visitor result */ - T visitInfix2(BasicParser.Infix2Context ctx); + T visitInfix2(BoppiParser.Infix2Context ctx); /** * Visit a parse tree produced by the {@code infix3} - * labeled alternative in {@link BasicParser#singleExpr}. + * labeled alternative in {@link BoppiParser#singleExpr}. * @param ctx the parse tree * @return the visitor result */ - T visitInfix3(BasicParser.Infix3Context ctx); + T visitInfix3(BoppiParser.Infix3Context ctx); /** * Visit a parse tree produced by the {@code infix1} - * labeled alternative in {@link BasicParser#singleExpr}. + * labeled alternative in {@link BoppiParser#singleExpr}. * @param ctx the parse tree * @return the visitor result */ - T visitInfix1(BasicParser.Infix1Context ctx); + T visitInfix1(BoppiParser.Infix1Context ctx); /** * Visit a parse tree produced by the {@code while} - * labeled alternative in {@link BasicParser#singleExpr}. + * labeled alternative in {@link BoppiParser#singleExpr}. * @param ctx the parse tree * @return the visitor result */ - T visitWhile(BasicParser.WhileContext ctx); + T visitWhile(BoppiParser.WhileContext ctx); /** * Visit a parse tree produced by the {@code infix4} - * labeled alternative in {@link BasicParser#singleExpr}. + * labeled alternative in {@link BoppiParser#singleExpr}. * @param ctx the parse tree * @return the visitor result */ - T visitInfix4(BasicParser.Infix4Context ctx); + T visitInfix4(BoppiParser.Infix4Context ctx); /** * Visit a parse tree produced by the {@code infix5} - * labeled alternative in {@link BasicParser#singleExpr}. + * labeled alternative in {@link BoppiParser#singleExpr}. * @param ctx the parse tree * @return the visitor result */ - T visitInfix5(BasicParser.Infix5Context ctx); + T visitInfix5(BoppiParser.Infix5Context ctx); /** * Visit a parse tree produced by the {@code call} - * labeled alternative in {@link BasicParser#singleExpr}. + * labeled alternative in {@link BoppiParser#singleExpr}. * @param ctx the parse tree * @return the visitor result */ - T visitCall(BasicParser.CallContext ctx); + T visitCall(BoppiParser.CallContext ctx); /** * Visit a parse tree produced by the {@code number} - * labeled alternative in {@link BasicParser#singleExpr}. + * labeled alternative in {@link BoppiParser#singleExpr}. * @param ctx the parse tree * @return the visitor result */ - T visitNumber(BasicParser.NumberContext ctx); + T visitNumber(BoppiParser.NumberContext ctx); /** * Visit a parse tree produced by the {@code funcDeclare} - * labeled alternative in {@link BasicParser#singleExpr}. + * labeled alternative in {@link BoppiParser#singleExpr}. * @param ctx the parse tree * @return the visitor result */ - T visitFuncDeclare(BasicParser.FuncDeclareContext ctx); + T visitFuncDeclare(BoppiParser.FuncDeclareContext ctx); /** * Visit a parse tree produced by the {@code char} - * labeled alternative in {@link BasicParser#singleExpr}. + * labeled alternative in {@link BoppiParser#singleExpr}. * @param ctx the parse tree * @return the visitor result */ - T visitChar(BasicParser.CharContext ctx); + T visitChar(BoppiParser.CharContext ctx); /** * Visit a parse tree produced by the {@code block} - * labeled alternative in {@link BasicParser#singleExpr}. + * labeled alternative in {@link BoppiParser#singleExpr}. * @param ctx the parse tree * @return the visitor result */ - T visitBlock(BasicParser.BlockContext ctx); + T visitBlock(BoppiParser.BlockContext ctx); /** * Visit a parse tree produced by the {@code write} - * labeled alternative in {@link BasicParser#singleExpr}. + * labeled alternative in {@link BoppiParser#singleExpr}. * @param ctx the parse tree * @return the visitor result */ - T visitWrite(BasicParser.WriteContext ctx); + T visitWrite(BoppiParser.WriteContext ctx); /** * Visit a parse tree produced by the {@code if} - * labeled alternative in {@link BasicParser#singleExpr}. + * labeled alternative in {@link BoppiParser#singleExpr}. * @param ctx the parse tree * @return the visitor result */ - T visitIf(BasicParser.IfContext ctx); + T visitIf(BoppiParser.IfContext ctx); /** * Visit a parse tree produced by the {@code prefix1} - * labeled alternative in {@link BasicParser#singleExpr}. + * labeled alternative in {@link BoppiParser#singleExpr}. * @param ctx the parse tree * @return the visitor result */ - T visitPrefix1(BasicParser.Prefix1Context ctx); + T visitPrefix1(BoppiParser.Prefix1Context ctx); /** * Visit a parse tree produced by the {@code assign} - * labeled alternative in {@link BasicParser#singleExpr}. + * labeled alternative in {@link BoppiParser#singleExpr}. * @param ctx the parse tree * @return the visitor result */ - T visitAssign(BasicParser.AssignContext ctx); + T visitAssign(BoppiParser.AssignContext ctx); /** - * Visit a parse tree produced by {@link BasicParser#type}. + * Visit a parse tree produced by {@link BoppiParser#type}. * @param ctx the parse tree * @return the visitor result */ - T visitType(BasicParser.TypeContext ctx); + T visitType(BoppiParser.TypeContext ctx); /** - * Visit a parse tree produced by {@link BasicParser#variable}. + * Visit a parse tree produced by {@link BoppiParser#variable}. * @param ctx the parse tree * @return the visitor result */ - T visitVariable(BasicParser.VariableContext ctx); + T visitVariable(BoppiParser.VariableContext ctx); } \ No newline at end of file diff --git a/src/pp/s1184725/boppi/test/AllTests.java b/src/pp/s1184725/boppi/test/AllTests.java index 7ddcce4..471c586 100644 --- a/src/pp/s1184725/boppi/test/AllTests.java +++ b/src/pp/s1184725/boppi/test/AllTests.java @@ -9,6 +9,6 @@ import org.junit.runners.Suite.SuiteClasses; @RunWith(Suite.class) @SuiteClasses({ CheckerTest.class, GeneratorTest.class, ParserTest.class }) public class AllTests { - static final Path directory = Paths.get("src/pp/s1184725/boppi/test/parsing/"); + static final Path directory = Paths.get("src/pp/s1184725/boppi/test/programs/"); } diff --git a/src/pp/s1184725/boppi/test/GeneratorTest.java b/src/pp/s1184725/boppi/test/GeneratorTest.java index ca31b64..932fae9 100644 --- a/src/pp/s1184725/boppi/test/GeneratorTest.java +++ b/src/pp/s1184725/boppi/test/GeneratorTest.java @@ -8,6 +8,7 @@ import java.util.logging.*; import org.antlr.v4.runtime.CharStream; import org.antlr.v4.runtime.tree.ParseTree; +import org.apache.commons.lang3.StringUtils; import org.junit.Test; import pp.iloc.Simulator; @@ -17,6 +18,7 @@ import pp.s1184725.boppi.*; public class GeneratorTest { private List log; private String[] out; + private Level logLevel = Level.SEVERE; private void compileAndRunString(String code, String... input) { compileAndRun(ToolChain.getCharStream(code), String.join("\n", input) + "\n"); @@ -29,10 +31,11 @@ public class GeneratorTest { private void compileAndRun(CharStream stream, String input) { Logger logger = Logger.getAnonymousLogger(); log = ToolChain.makeListLog(logger); + logger.setLevel(logLevel); ParseTree ast = ToolChain.getParser(ToolChain.getLexer(stream, logger), logger).program(); Annotations annotations = ToolChain.getAnnotations(ast, logger); - Program program = ToolChain.getILOC(ast, annotations); + Program program = ToolChain.getILOC(ast, logger, annotations); if (Simulator.DEBUG) System.out.println(program.prettyPrint()); @@ -40,10 +43,33 @@ public class GeneratorTest { out = ToolChain.execute(program, logger, input).split("\n"); } + @SuppressWarnings("unused") + private void debugRun(CharStream stream, String... input) { + Simulator.DEBUG = true; + String in = String.join("\n", input) + "\n"; + Logger logger = Logger.getAnonymousLogger(); + log = ToolChain.makeListLog(logger); + logger.setLevel(Level.FINEST); + + ParseTree ast = ToolChain.getParser(ToolChain.getLexer(stream, logger), logger).program(); + Annotations annotations = ToolChain.getAnnotations(ast, logger); + Program program = ToolChain.getILOC(ast, logger, annotations); + + System.out.println(program.prettyPrint()); + + out = ToolChain.execute(program, logger, in).split("\n"); + + log.forEach((entry) -> System.out.println(entry.getMessage())); + Simulator.DEBUG = false; + } + @Test public void correctExpressionTest() { compileAndRunFile("simpleExpression.boppi"); assertThat(log, is(empty())); + + compileAndRunString(StringUtils.repeat("1+(", 8) + "1" + StringUtils.repeat(")", 8)); + assertThat(log, is(empty())); } @Test @@ -87,7 +113,7 @@ public class GeneratorTest { } @Test - public void correctFunctionTest() { + public void correctSimpleFunctionTest() { compileAndRunString("function int id(int a) a; 1"); assertThat(log, is(empty())); @@ -108,7 +134,10 @@ public class GeneratorTest { compileAndRunString("function char const(char a, char b) a; print(const('A', 'T'))"); assertThat(log, is(empty())); assertThat(out, is(arrayContaining("A"))); + } + @Test + public void correctComplexFunctionTest() { compileAndRunString("function int factorial(int n) {if (n > 1) then n*factorial(n-1) else 1 fi}"); assertThat(log, is(empty())); @@ -117,6 +146,9 @@ public class GeneratorTest { "5"); assertThat(log, is(empty())); assertThat(out, is(arrayContaining("120"))); - } + compileAndRunFile("simpleFunctionPassing.boppi"); + assertThat(log, is(empty())); + assertThat(out, is(arrayContaining("40", "104", "1", "2", "8"))); + } } diff --git a/src/pp/s1184725/boppi/test/parsing/basicProgram1.boppi b/src/pp/s1184725/boppi/test/programs/basicProgram1.boppi similarity index 100% rename from src/pp/s1184725/boppi/test/parsing/basicProgram1.boppi rename to src/pp/s1184725/boppi/test/programs/basicProgram1.boppi diff --git a/src/pp/s1184725/boppi/test/parsing/fibonacciIterative.boppi b/src/pp/s1184725/boppi/test/programs/fibonacciIterative.boppi similarity index 100% rename from src/pp/s1184725/boppi/test/parsing/fibonacciIterative.boppi rename to src/pp/s1184725/boppi/test/programs/fibonacciIterative.boppi diff --git a/src/pp/s1184725/boppi/test/parsing/if.boppi b/src/pp/s1184725/boppi/test/programs/if.boppi similarity index 100% rename from src/pp/s1184725/boppi/test/parsing/if.boppi rename to src/pp/s1184725/boppi/test/programs/if.boppi diff --git a/src/pp/s1184725/boppi/test/parsing/simpleExpression.boppi b/src/pp/s1184725/boppi/test/programs/simpleExpression.boppi similarity index 100% rename from src/pp/s1184725/boppi/test/parsing/simpleExpression.boppi rename to src/pp/s1184725/boppi/test/programs/simpleExpression.boppi diff --git a/src/pp/s1184725/boppi/test/programs/simpleFunctionPassing.boppi b/src/pp/s1184725/boppi/test/programs/simpleFunctionPassing.boppi new file mode 100644 index 0000000..28d9c5d --- /dev/null +++ b/src/pp/s1184725/boppi/test/programs/simpleFunctionPassing.boppi @@ -0,0 +1,38 @@ +var int undefined; +function int intDiadic(int a, int b) undefined; + +function intDiadic getMultiply() { + function int multiply(int a, int b) + a*b; + multiply +}; + +function int biasedMultiply(int a, int b) a*b+4; + +var intDiadic myMultiply; +myMultiply := getMultiply(); +print(myMultiply(5, 8)); + +myMultiply := biasedMultiply; +print(myMultiply(10, 10)); + +function int fibonacci(int n) { + var int start0; start0 := 1; + var int start1; start1 := 1; + + function int doFibonacci(int n) + if n == 0 then + start0 + else + if n == 1 then + start1 + else + doFibonacci(n-1)+doFibonacci(n-2) + fi + fi + ; + + doFibonacci(n) +}; + +print(fibonacci(1), fibonacci(2), fibonacci(5)); diff --git a/src/pp/s1184725/boppi/test/parsing/simpleScope.boppi b/src/pp/s1184725/boppi/test/programs/simpleScope.boppi similarity index 100% rename from src/pp/s1184725/boppi/test/parsing/simpleScope.boppi rename to src/pp/s1184725/boppi/test/programs/simpleScope.boppi diff --git a/src/pp/s1184725/boppi/test/parsing/simpleVariable.boppi b/src/pp/s1184725/boppi/test/programs/simpleVariable.boppi similarity index 100% rename from src/pp/s1184725/boppi/test/parsing/simpleVariable.boppi rename to src/pp/s1184725/boppi/test/programs/simpleVariable.boppi diff --git a/src/pp/s1184725/boppi/test/parsing/while.boppi b/src/pp/s1184725/boppi/test/programs/while.boppi similarity index 100% rename from src/pp/s1184725/boppi/test/parsing/while.boppi rename to src/pp/s1184725/boppi/test/programs/while.boppi