19 Commits
Author SHA1 Message Date
simonkellet 54d9f06a9e merge 2022-10-10 13:56:38 +01:00
simonkellet d1a97c0d8f added this file 2022-10-10 13:48:49 +01:00
simonkellet 693d933c19 repeatuntil works 2022-10-10 13:39:00 +01:00
simonkellet c9ca3c5bba bardemo works 2022-10-10 13:34:03 +01:00
Sandy BrownleeandGitHub ce307a11a6 Update ConstantFolder.java 2022-10-06 17:20:59 +01:00
Sandy Brownlee 55fdd944fa Changes for constant folding 2022-09-30 00:10:27 +01:00
Sandy Brownlee 7a8fb2564c Added NOP to opcodes so ordinals match the book 2022-09-28 10:44:30 +01:00
Sandy Brownlee 6a30c4db8b Updated examples 2022-09-27 21:41:24 +01:00
simonkellet e1268aae42 end of practical3 (no bonus) 2022-09-27 10:23:16 +01:00
Sandy Brownlee 461749e44a Added timing to interpreter 2022-09-23 17:21:03 +01:00
simonkellet 4341d02572 end of practical 2 2022-09-23 16:59:48 +01:00
simonkellet 32bd99d78b new lines to check if it is still working 2022-09-23 15:33:28 +01:00
simonkellet fab24be627 added success test for multi-line 2022-09-23 15:32:59 +01:00
simonkellet 6b7fdd3bb0 added multi-line comment support 2022-09-23 15:32:37 +01:00
simonkellet f69942533f works with error code 2022-09-23 14:14:35 +01:00
Sandy Brownlee 0c1b2530fa Amended comments in Encoder 2022-09-22 17:37:52 +01:00
Sandy Brownlee f5951671b9 Added increment demo program 2022-09-21 16:49:53 +01:00
Sandy Brownlee 1da8cabdf7 minor fix to repeatuntil 2022-09-21 13:35:56 +01:00
simonkellet a647259dc2 added readme 2022-09-20 18:28:06 +01:00
39 changed files with 853 additions and 46 deletions
+2
View File
@@ -0,0 +1,2 @@
# A5 Triangle Compiler
@@ -21,6 +21,8 @@ import java.io.IOException;
public class Interpreter { public class Interpreter {
static long startTimeNanos = 0;
static String objectName; static String objectName;
// DATA STORE // DATA STORE
@@ -183,6 +185,7 @@ public class Interpreter {
break; break;
case halted: case halted:
System.out.println("Program has halted normally."); System.out.println("Program has halted normally.");
System.out.println("Total execution time (ns): " + (System.nanoTime() - startTimeNanos));
break; break;
case failedDataStoreFull: case failedDataStoreFull:
System.out.println("Program has failed due to exhaustion of Data Store."); System.out.println("Program has failed due to exhaustion of Data Store.");
@@ -634,6 +637,7 @@ public class Interpreter {
loadObjectProgram(objectName); loadObjectProgram(objectName);
if (CT != CB) { if (CT != CB) {
startTimeNanos = System.nanoTime();
interpretProgram(); interpretProgram();
showStatus(); showStatus();
} }
@@ -1,5 +1,5 @@
package triangle.abstractMachine; package triangle.abstractMachine;
public enum OpCode { public enum OpCode {
LOAD, LOADA, LOADI, LOADL, STORE, STOREI, CALL, CALLI, RETURN, PUSH, POP, JUMP, JUMPI, JUMPIF, HALT LOAD, LOADA, LOADI, LOADL, STORE, STOREI, CALL, CALLI, RETURN, NOP, PUSH, POP, JUMP, JUMPI, JUMPIF, HALT
} }
@@ -18,6 +18,7 @@ import triangle.abstractSyntaxTrees.Program;
import triangle.codeGenerator.Emitter; import triangle.codeGenerator.Emitter;
import triangle.codeGenerator.Encoder; import triangle.codeGenerator.Encoder;
import triangle.contextualAnalyzer.Checker; import triangle.contextualAnalyzer.Checker;
import triangle.optimiser.ConstantFolder;
import triangle.syntacticAnalyzer.Parser; import triangle.syntacticAnalyzer.Parser;
import triangle.syntacticAnalyzer.Scanner; import triangle.syntacticAnalyzer.Scanner;
import triangle.syntacticAnalyzer.SourceFile; import triangle.syntacticAnalyzer.SourceFile;
@@ -35,6 +36,7 @@ public class Compiler {
static String objectName = "obj.tam"; static String objectName = "obj.tam";
static boolean showTree = false; static boolean showTree = false;
static boolean folding = false;
private static Scanner scanner; private static Scanner scanner;
private static Parser parser; private static Parser parser;
@@ -91,6 +93,10 @@ public class Compiler {
if (showingAST) { if (showingAST) {
drawer.draw(theAST); drawer.draw(theAST);
} }
if (folding) {
theAST.visit(new ConstantFolder());
}
if (reporter.getNumErrors() == 0) { if (reporter.getNumErrors() == 0) {
System.out.println("Code Generation ..."); System.out.println("Code Generation ...");
encoder.encodeRun(theAST, showingTable); // 3rd pass encoder.encodeRun(theAST, showingTable); // 3rd pass
@@ -116,7 +122,7 @@ public class Compiler {
public static void main(String[] args) { public static void main(String[] args) {
if (args.length < 1) { if (args.length < 1) {
System.out.println("Usage: tc filename [-o=outputfilename] [tree]"); System.out.println("Usage: tc filename [-o=outputfilename] [tree] [folding]");
System.exit(1); System.exit(1);
} }
@@ -138,6 +144,8 @@ public class Compiler {
showTree = true; showTree = true;
} else if (sl.startsWith("-o=")) { } else if (sl.startsWith("-o=")) {
objectName = s.substring(3); objectName = s.substring(3);
} else if (sl.equals("folding")) {
folding = true;
} }
} }
} }
@@ -43,4 +43,7 @@ public final class StdEnvironment {
public static FuncDeclaration chrDecl, ordDecl, eolDecl, eofDecl; public static FuncDeclaration chrDecl, ordDecl, eolDecl, eofDecl;
//keep the bar separate for practical 3 (week 3) work!
public static UnaryOperatorDeclaration barDecl;
} }
@@ -29,5 +29,5 @@ public class ConstActualParameter extends ActualParameter {
return v.visitConstActualParameter(this, arg); return v.visitConstActualParameter(this, arg);
} }
public final Expression E; public Expression E;
} }
@@ -30,6 +30,6 @@ public class MultipleArrayAggregate extends ArrayAggregate {
return v.visitMultipleArrayAggregate(this, arg); return v.visitMultipleArrayAggregate(this, arg);
} }
public final Expression E; public Expression E;
public final ArrayAggregate AA; public final ArrayAggregate AA;
} }
@@ -33,6 +33,6 @@ public class MultipleRecordAggregate extends RecordAggregate {
} }
public final Identifier I; public final Identifier I;
public final Expression E; public Expression E;
public final RecordAggregate RA; public final RecordAggregate RA;
} }
@@ -29,5 +29,5 @@ public class SingleArrayAggregate extends ArrayAggregate {
return v.visitSingleArrayAggregate(this, arg); return v.visitSingleArrayAggregate(this, arg);
} }
public final Expression E; public Expression E;
} }
@@ -32,5 +32,5 @@ public class SingleRecordAggregate extends RecordAggregate {
} }
public final Identifier I; public final Identifier I;
public final Expression E; public Expression E;
} }
@@ -32,5 +32,5 @@ public class AssignCommand extends Command {
} }
public final Vname V; public final Vname V;
public final Expression E; public Expression E;
} }
@@ -31,6 +31,6 @@ public class IfCommand extends Command {
return v.visitIfCommand(this, arg); return v.visitIfCommand(this, arg);
} }
public final Expression E; public Expression E;
public final Command C1, C2; public final Command C1, C2;
} }
@@ -0,0 +1,22 @@
package triangle.abstractSyntaxTrees.commands;
import triangle.abstractSyntaxTrees.expressions.Expression;
import triangle.abstractSyntaxTrees.visitors.CommandVisitor;
import triangle.syntacticAnalyzer.SourcePosition;
public class RepeatCommand extends Command {
public RepeatCommand(Expression eAST, Command cAST, SourcePosition position) {
super(position);
E = eAST;
C = cAST;
}
public <TArg, TResult> TResult visit(CommandVisitor<TArg, TResult> v, TArg arg) {
return v.visitRepeatCommand(this, arg);
}
//public final Expression E;
public Expression E;
public final Command C;
}
@@ -30,6 +30,6 @@ public class WhileCommand extends Command {
return v.visitWhileCommand(this, arg); return v.visitWhileCommand(this, arg);
} }
public final Expression E; public Expression E;
public final Command C; public final Command C;
} }
@@ -38,5 +38,5 @@ public class ConstDeclaration extends Declaration implements ConstantDeclaration
} }
public final Identifier I; public final Identifier I;
public final Expression E; public Expression E;
} }
@@ -49,5 +49,5 @@ public class FuncDeclaration extends Declaration implements FunctionDeclaration
public final Identifier I; public final Identifier I;
public final FormalParameterSequence FPS; public final FormalParameterSequence FPS;
public TypeDenoter T; public TypeDenoter T;
public final Expression E; public Expression E;
} }
@@ -31,6 +31,7 @@ public class BinaryExpression extends Expression {
return v.visitBinaryExpression(this, arg); return v.visitBinaryExpression(this, arg);
} }
public final Expression E1, E2; public Expression E1;
public Expression E2;
public final Operator O; public final Operator O;
} }
@@ -30,5 +30,7 @@ public class IfExpression extends Expression {
return v.visitIfExpression(this, arg); return v.visitIfExpression(this, arg);
} }
public final Expression E1, E2, E3; public Expression E1;
public Expression E2;
public Expression E3;
} }
@@ -31,5 +31,5 @@ public class LetExpression extends Expression {
} }
public final Declaration D; public final Declaration D;
public final Expression E; public Expression E;
} }
@@ -30,6 +30,6 @@ public class UnaryExpression extends Expression {
return v.visitUnaryExpression(this, arg); return v.visitUnaryExpression(this, arg);
} }
public final Expression E; public Expression E;
public final Operator O; public final Operator O;
} }
@@ -5,11 +5,11 @@ import triangle.abstractSyntaxTrees.commands.CallCommand;
import triangle.abstractSyntaxTrees.commands.EmptyCommand; import triangle.abstractSyntaxTrees.commands.EmptyCommand;
import triangle.abstractSyntaxTrees.commands.IfCommand; import triangle.abstractSyntaxTrees.commands.IfCommand;
import triangle.abstractSyntaxTrees.commands.LetCommand; import triangle.abstractSyntaxTrees.commands.LetCommand;
import triangle.abstractSyntaxTrees.commands.RepeatCommand;
import triangle.abstractSyntaxTrees.commands.SequentialCommand; import triangle.abstractSyntaxTrees.commands.SequentialCommand;
import triangle.abstractSyntaxTrees.commands.WhileCommand; import triangle.abstractSyntaxTrees.commands.WhileCommand;
public interface CommandVisitor<TArg, TResult> { public interface CommandVisitor<TArg, TResult> {
TResult visitAssignCommand(AssignCommand ast, TArg arg); TResult visitAssignCommand(AssignCommand ast, TArg arg);
TResult visitCallCommand(CallCommand ast, TArg arg); TResult visitCallCommand(CallCommand ast, TArg arg);
@@ -24,4 +24,6 @@ public interface CommandVisitor<TArg, TResult> {
TResult visitWhileCommand(WhileCommand ast, TArg arg); TResult visitWhileCommand(WhileCommand ast, TArg arg);
TResult visitRepeatCommand(RepeatCommand ast, TArg arg);
} }
@@ -30,6 +30,6 @@ public class SubscriptVname extends Vname {
return v.visitSubscriptVname(this, arg); return v.visitSubscriptVname(this, arg);
} }
public final Expression E; public Expression E;
public final Vname V; public final Vname V;
} }
@@ -38,6 +38,7 @@ import triangle.abstractSyntaxTrees.commands.CallCommand;
import triangle.abstractSyntaxTrees.commands.EmptyCommand; import triangle.abstractSyntaxTrees.commands.EmptyCommand;
import triangle.abstractSyntaxTrees.commands.IfCommand; import triangle.abstractSyntaxTrees.commands.IfCommand;
import triangle.abstractSyntaxTrees.commands.LetCommand; import triangle.abstractSyntaxTrees.commands.LetCommand;
import triangle.abstractSyntaxTrees.commands.RepeatCommand;
import triangle.abstractSyntaxTrees.commands.SequentialCommand; import triangle.abstractSyntaxTrees.commands.SequentialCommand;
import triangle.abstractSyntaxTrees.commands.WhileCommand; import triangle.abstractSyntaxTrees.commands.WhileCommand;
import triangle.abstractSyntaxTrees.declarations.BinaryOperatorDeclaration; import triangle.abstractSyntaxTrees.declarations.BinaryOperatorDeclaration;
@@ -100,6 +101,7 @@ import triangle.abstractSyntaxTrees.vnames.SimpleVname;
import triangle.abstractSyntaxTrees.vnames.SubscriptVname; import triangle.abstractSyntaxTrees.vnames.SubscriptVname;
import triangle.abstractSyntaxTrees.vnames.Vname; import triangle.abstractSyntaxTrees.vnames.Vname;
import triangle.codeGenerator.entities.AddressableEntity; import triangle.codeGenerator.entities.AddressableEntity;
import triangle.codeGenerator.entities.BarPrimitiveRoutine;
import triangle.codeGenerator.entities.EqualityRoutine; import triangle.codeGenerator.entities.EqualityRoutine;
import triangle.codeGenerator.entities.FetchableEntity; import triangle.codeGenerator.entities.FetchableEntity;
import triangle.codeGenerator.entities.Field; import triangle.codeGenerator.entities.Field;
@@ -181,6 +183,15 @@ public final class Encoder implements ActualParameterVisitor<Frame, Integer>,
return null; return null;
} }
@Override
public Void visitRepeatCommand(RepeatCommand ast, Frame frame) {
var loopAddr = emitter.getNextInstrAddr();
ast.E.visit(this, frame);
ast.C.visit(this, frame);
emitter.emit(OpCode.JUMPIF, Machine.trueRep, Register.CB, loopAddr);
return null;
}
// Expressions // Expressions
@Override @Override
public Integer visitArrayExpression(ArrayExpression ast, Frame frame) { public Integer visitArrayExpression(ArrayExpression ast, Frame frame) {
@@ -734,6 +745,9 @@ public final class Encoder implements ActualParameterVisitor<Frame, Integer>,
elaborateStdPrimRoutine(StdEnvironment.puteolDecl, Primitive.PUTEOL); elaborateStdPrimRoutine(StdEnvironment.puteolDecl, Primitive.PUTEOL);
elaborateStdEqRoutine(StdEnvironment.equalDecl, Primitive.EQ); elaborateStdEqRoutine(StdEnvironment.equalDecl, Primitive.EQ);
elaborateStdEqRoutine(StdEnvironment.unequalDecl, Primitive.NE); elaborateStdEqRoutine(StdEnvironment.unequalDecl, Primitive.NE);
StdEnvironment.barDecl.entity = new BarPrimitiveRoutine();
} }
boolean tableDetailsReqd; boolean tableDetailsReqd;
@@ -741,10 +755,9 @@ public final class Encoder implements ActualParameterVisitor<Frame, Integer>,
public static void writeTableDetails(AbstractSyntaxTree ast) { public static void writeTableDetails(AbstractSyntaxTree ast) {
} }
// Generates code to fetch the value of a named constant or variable // Generates code to pop the top off the stack
// and push it on to the stack. // and store the value in a named constant or variable
// currentLevel is the routine level where the vname occurs. // frame the local stack frame when
// frameSize is the anticipated size of the local stack frame when
// the constant or variable is fetched at run-time. // the constant or variable is fetched at run-time.
// valSize is the size of the constant or variable's value. // valSize is the size of the constant or variable's value.
@@ -0,0 +1,27 @@
package triangle.codeGenerator.entities;
import triangle.abstractMachine.Machine;
import triangle.abstractMachine.OpCode;
import triangle.abstractMachine.Primitive;
import triangle.abstractMachine.Register;
import triangle.codeGenerator.Emitter;
import triangle.codeGenerator.Frame;
public class BarPrimitiveRoutine extends RuntimeEntity implements RoutineEntity {
public BarPrimitiveRoutine() {
super(Machine.closureSize);
}
public void encodeCall(Emitter emitter, Frame frame) {
//push the literal value of 100 onto the stack
emitter.emit(OpCode.LOADL, 0, 100);
emitter.emit(OpCode.CALL, Register.PB, Primitive.MULT);
}
public void encodeFetch(Emitter emitter, Frame frame) {
emitter.emit(OpCode.LOADA, 0, Register.SB, 0);
emitter.emit(OpCode.LOADA, Register.PB, Primitive.MULT);
}
}
@@ -34,6 +34,7 @@ import triangle.abstractSyntaxTrees.commands.CallCommand;
import triangle.abstractSyntaxTrees.commands.EmptyCommand; import triangle.abstractSyntaxTrees.commands.EmptyCommand;
import triangle.abstractSyntaxTrees.commands.IfCommand; import triangle.abstractSyntaxTrees.commands.IfCommand;
import triangle.abstractSyntaxTrees.commands.LetCommand; import triangle.abstractSyntaxTrees.commands.LetCommand;
import triangle.abstractSyntaxTrees.commands.RepeatCommand;
import triangle.abstractSyntaxTrees.commands.SequentialCommand; import triangle.abstractSyntaxTrees.commands.SequentialCommand;
import triangle.abstractSyntaxTrees.commands.WhileCommand; import triangle.abstractSyntaxTrees.commands.WhileCommand;
import triangle.abstractSyntaxTrees.declarations.BinaryOperatorDeclaration; import triangle.abstractSyntaxTrees.declarations.BinaryOperatorDeclaration;
@@ -185,6 +186,15 @@ public final class Checker implements ActualParameterVisitor<FormalParameter, Vo
return null; return null;
} }
@Override
public Void visitRepeatCommand(RepeatCommand ast, Void arg) {
var eType = ast.E.visit(this);
checkAndReportError(eType.equals(StdEnvironment.booleanType), "Boolean expression expected here", ast.E);
ast.C.visit(this);
return null;
}
// Expressions // Expressions
// Returns the TypeDenoter denoting the type of the expression. Does // Returns the TypeDenoter denoting the type of the expression. Does
@@ -948,6 +958,10 @@ public final class Checker implements ActualParameterVisitor<FormalParameter, Vo
StdEnvironment.notlessDecl = declareStdBinaryOp(">=", StdEnvironment.integerType, StdEnvironment.integerType, StdEnvironment.notlessDecl = declareStdBinaryOp(">=", StdEnvironment.integerType, StdEnvironment.integerType,
StdEnvironment.booleanType); StdEnvironment.booleanType);
//add the new bar operator!
StdEnvironment.barDecl = declareStdUnaryOp("|", StdEnvironment.integerType, StdEnvironment.integerType);
StdEnvironment.charDecl = declareStdType("Char", StdEnvironment.charType); StdEnvironment.charDecl = declareStdType("Char", StdEnvironment.charType);
StdEnvironment.chrDecl = declareStdFunc("chr", StdEnvironment.chrDecl = declareStdFunc("chr",
new SingleFormalParameterSequence( new SingleFormalParameterSequence(
@@ -0,0 +1,601 @@
package triangle.optimiser;
import triangle.StdEnvironment;
import triangle.abstractSyntaxTrees.AbstractSyntaxTree;
import triangle.abstractSyntaxTrees.Program;
import triangle.abstractSyntaxTrees.actuals.ConstActualParameter;
import triangle.abstractSyntaxTrees.actuals.EmptyActualParameterSequence;
import triangle.abstractSyntaxTrees.actuals.FuncActualParameter;
import triangle.abstractSyntaxTrees.actuals.MultipleActualParameterSequence;
import triangle.abstractSyntaxTrees.actuals.ProcActualParameter;
import triangle.abstractSyntaxTrees.actuals.SingleActualParameterSequence;
import triangle.abstractSyntaxTrees.actuals.VarActualParameter;
import triangle.abstractSyntaxTrees.aggregates.MultipleArrayAggregate;
import triangle.abstractSyntaxTrees.aggregates.MultipleRecordAggregate;
import triangle.abstractSyntaxTrees.aggregates.SingleArrayAggregate;
import triangle.abstractSyntaxTrees.aggregates.SingleRecordAggregate;
import triangle.abstractSyntaxTrees.commands.AssignCommand;
import triangle.abstractSyntaxTrees.commands.CallCommand;
import triangle.abstractSyntaxTrees.commands.EmptyCommand;
import triangle.abstractSyntaxTrees.commands.IfCommand;
import triangle.abstractSyntaxTrees.commands.LetCommand;
import triangle.abstractSyntaxTrees.commands.RepeatCommand;
import triangle.abstractSyntaxTrees.commands.SequentialCommand;
import triangle.abstractSyntaxTrees.commands.WhileCommand;
import triangle.abstractSyntaxTrees.declarations.BinaryOperatorDeclaration;
import triangle.abstractSyntaxTrees.declarations.ConstDeclaration;
import triangle.abstractSyntaxTrees.declarations.FuncDeclaration;
import triangle.abstractSyntaxTrees.declarations.ProcDeclaration;
import triangle.abstractSyntaxTrees.declarations.SequentialDeclaration;
import triangle.abstractSyntaxTrees.declarations.UnaryOperatorDeclaration;
import triangle.abstractSyntaxTrees.declarations.VarDeclaration;
import triangle.abstractSyntaxTrees.expressions.ArrayExpression;
import triangle.abstractSyntaxTrees.expressions.BinaryExpression;
import triangle.abstractSyntaxTrees.expressions.CallExpression;
import triangle.abstractSyntaxTrees.expressions.CharacterExpression;
import triangle.abstractSyntaxTrees.expressions.EmptyExpression;
import triangle.abstractSyntaxTrees.expressions.Expression;
import triangle.abstractSyntaxTrees.expressions.IfExpression;
import triangle.abstractSyntaxTrees.expressions.IntegerExpression;
import triangle.abstractSyntaxTrees.expressions.LetExpression;
import triangle.abstractSyntaxTrees.expressions.RecordExpression;
import triangle.abstractSyntaxTrees.expressions.UnaryExpression;
import triangle.abstractSyntaxTrees.expressions.VnameExpression;
import triangle.abstractSyntaxTrees.formals.ConstFormalParameter;
import triangle.abstractSyntaxTrees.formals.EmptyFormalParameterSequence;
import triangle.abstractSyntaxTrees.formals.FuncFormalParameter;
import triangle.abstractSyntaxTrees.formals.MultipleFormalParameterSequence;
import triangle.abstractSyntaxTrees.formals.ProcFormalParameter;
import triangle.abstractSyntaxTrees.formals.SingleFormalParameterSequence;
import triangle.abstractSyntaxTrees.formals.VarFormalParameter;
import triangle.abstractSyntaxTrees.terminals.CharacterLiteral;
import triangle.abstractSyntaxTrees.terminals.Identifier;
import triangle.abstractSyntaxTrees.terminals.IntegerLiteral;
import triangle.abstractSyntaxTrees.terminals.Operator;
import triangle.abstractSyntaxTrees.types.AnyTypeDenoter;
import triangle.abstractSyntaxTrees.types.ArrayTypeDenoter;
import triangle.abstractSyntaxTrees.types.BoolTypeDenoter;
import triangle.abstractSyntaxTrees.types.CharTypeDenoter;
import triangle.abstractSyntaxTrees.types.ErrorTypeDenoter;
import triangle.abstractSyntaxTrees.types.IntTypeDenoter;
import triangle.abstractSyntaxTrees.types.MultipleFieldTypeDenoter;
import triangle.abstractSyntaxTrees.types.RecordTypeDenoter;
import triangle.abstractSyntaxTrees.types.SimpleTypeDenoter;
import triangle.abstractSyntaxTrees.types.SingleFieldTypeDenoter;
import triangle.abstractSyntaxTrees.types.TypeDeclaration;
import triangle.abstractSyntaxTrees.visitors.ActualParameterSequenceVisitor;
import triangle.abstractSyntaxTrees.visitors.ActualParameterVisitor;
import triangle.abstractSyntaxTrees.visitors.ArrayAggregateVisitor;
import triangle.abstractSyntaxTrees.visitors.CommandVisitor;
import triangle.abstractSyntaxTrees.visitors.DeclarationVisitor;
import triangle.abstractSyntaxTrees.visitors.ExpressionVisitor;
import triangle.abstractSyntaxTrees.visitors.FormalParameterSequenceVisitor;
import triangle.abstractSyntaxTrees.visitors.IdentifierVisitor;
import triangle.abstractSyntaxTrees.visitors.LiteralVisitor;
import triangle.abstractSyntaxTrees.visitors.OperatorVisitor;
import triangle.abstractSyntaxTrees.visitors.ProgramVisitor;
import triangle.abstractSyntaxTrees.visitors.RecordAggregateVisitor;
import triangle.abstractSyntaxTrees.visitors.TypeDenoterVisitor;
import triangle.abstractSyntaxTrees.visitors.VnameVisitor;
import triangle.abstractSyntaxTrees.vnames.DotVname;
import triangle.abstractSyntaxTrees.vnames.SimpleVname;
import triangle.abstractSyntaxTrees.vnames.SubscriptVname;
import triangle.codeGenerator.entities.RuntimeEntity;
public class ConstantFolder implements ActualParameterVisitor<Void, AbstractSyntaxTree>,
ActualParameterSequenceVisitor<Void, AbstractSyntaxTree>, ArrayAggregateVisitor<Void, AbstractSyntaxTree>,
CommandVisitor<Void, AbstractSyntaxTree>, DeclarationVisitor<Void, AbstractSyntaxTree>,
ExpressionVisitor<Void, AbstractSyntaxTree>, FormalParameterSequenceVisitor<Void, AbstractSyntaxTree>,
IdentifierVisitor<Void, AbstractSyntaxTree>, LiteralVisitor<Void, AbstractSyntaxTree>,
OperatorVisitor<Void, AbstractSyntaxTree>, ProgramVisitor<Void, AbstractSyntaxTree>,
RecordAggregateVisitor<Void, AbstractSyntaxTree>, TypeDenoterVisitor<Void, AbstractSyntaxTree>,
VnameVisitor<Void, RuntimeEntity> {
{
}
@Override
public AbstractSyntaxTree visitConstFormalParameter(ConstFormalParameter ast, Void arg) {
ast.I.visit(this);
ast.T.visit(this);
return null;
}
@Override
public AbstractSyntaxTree visitFuncFormalParameter(FuncFormalParameter ast, Void arg) {
ast.I.visit(this);
ast.T.visit(this);
return null;
}
@Override
public AbstractSyntaxTree visitProcFormalParameter(ProcFormalParameter ast, Void arg) {
ast.I.visit(this);
ast.FPS.visit(this);
return null;
}
@Override
public AbstractSyntaxTree visitVarFormalParameter(VarFormalParameter ast, Void arg) {
ast.I.visit(this);
ast.T.visit(this);
return null;
}
@Override
public AbstractSyntaxTree visitMultipleFieldTypeDenoter(MultipleFieldTypeDenoter ast, Void arg) {
ast.FT.visit(this);
ast.I.visit(this);
ast.T.visit(this);
return null;
}
@Override
public AbstractSyntaxTree visitSingleFieldTypeDenoter(SingleFieldTypeDenoter ast, Void arg) {
ast.I.visit(this);
ast.T.visit(this);
return null;
}
@Override
public RuntimeEntity visitDotVname(DotVname ast, Void arg) {
ast.I.visit(this);
ast.V.visit(this);
return null;
}
@Override
public RuntimeEntity visitSimpleVname(SimpleVname ast, Void arg) {
ast.I.visit(this);
return null;
}
@Override
public RuntimeEntity visitSubscriptVname(SubscriptVname ast, Void arg) {
AbstractSyntaxTree replacement = ast.E.visit(this);
if (replacement != null) {
ast.E = (Expression) replacement;
}
ast.V.visit(this);
return null;
}
@Override
public AbstractSyntaxTree visitAnyTypeDenoter(AnyTypeDenoter ast, Void arg) {
return null;
}
@Override
public AbstractSyntaxTree visitArrayTypeDenoter(ArrayTypeDenoter ast, Void arg) {
ast.IL.visit(this);
ast.T.visit(this);
return null;
}
@Override
public AbstractSyntaxTree visitBoolTypeDenoter(BoolTypeDenoter ast, Void arg) {
return null;
}
@Override
public AbstractSyntaxTree visitCharTypeDenoter(CharTypeDenoter ast, Void arg) {
return null;
}
@Override
public AbstractSyntaxTree visitErrorTypeDenoter(ErrorTypeDenoter ast, Void arg) {
return null;
}
@Override
public AbstractSyntaxTree visitSimpleTypeDenoter(SimpleTypeDenoter ast, Void arg) {
ast.I.visit(this);
return null;
}
@Override
public AbstractSyntaxTree visitIntTypeDenoter(IntTypeDenoter ast, Void arg) {
return null;
}
@Override
public AbstractSyntaxTree visitRecordTypeDenoter(RecordTypeDenoter ast, Void arg) {
ast.FT.visit(this);
return null;
}
@Override
public AbstractSyntaxTree visitMultipleRecordAggregate(MultipleRecordAggregate ast, Void arg) {
AbstractSyntaxTree replacement = ast.E.visit(this);
if (replacement != null) {
ast.E = (Expression) replacement;
}
ast.I.visit(this);
ast.RA.visit(this);
return null;
}
@Override
public AbstractSyntaxTree visitSingleRecordAggregate(SingleRecordAggregate ast, Void arg) {
AbstractSyntaxTree replacement = ast.E.visit(this);
if (replacement != null) {
ast.E = (Expression) replacement;
}
ast.I.visit(this);
return null;
}
@Override
public AbstractSyntaxTree visitProgram(Program ast, Void arg) {
ast.C.visit(this);
return null;
}
@Override
public AbstractSyntaxTree visitOperator(Operator ast, Void arg) {
return null;
}
@Override
public AbstractSyntaxTree visitCharacterLiteral(CharacterLiteral ast, Void arg) {
return null;
}
@Override
public AbstractSyntaxTree visitIntegerLiteral(IntegerLiteral ast, Void arg) {
return ast;
}
@Override
public AbstractSyntaxTree visitIdentifier(Identifier ast, Void arg) {
return null;
}
@Override
public AbstractSyntaxTree visitEmptyFormalParameterSequence(EmptyFormalParameterSequence ast, Void arg) {
return null;
}
@Override
public AbstractSyntaxTree visitMultipleFormalParameterSequence(MultipleFormalParameterSequence ast, Void arg) {
ast.FP.visit(this);
ast.FPS.visit(this);
return null;
}
@Override
public AbstractSyntaxTree visitSingleFormalParameterSequence(SingleFormalParameterSequence ast, Void arg) {
ast.FP.visit(this);
return null;
}
@Override
public AbstractSyntaxTree visitArrayExpression(ArrayExpression ast, Void arg) {
ast.AA.visit(this);
return null;
}
@Override
public AbstractSyntaxTree visitBinaryExpression(BinaryExpression ast, Void arg) {
AbstractSyntaxTree replacement1 = ast.E1.visit(this);
AbstractSyntaxTree replacement2 = ast.E2.visit(this);
ast.O.visit(this);
// if visiting a child node returns something, it's either the original constant
// (IntegerLiteral) or a folded version replacing the expression at that child
// node
// If both child nodes are not null; return a folded version of this
// BinaryExpression
// Otherwise, at least one child node isn't constant (foldable) so just replace
// the
// foldable child nodes with their folded equivalent and return null
if (replacement1 != null && replacement2 != null) {
return foldBinaryExpression(replacement1, replacement2, ast.O);
} else if (replacement1 != null) {
ast.E1 = (Expression) replacement1;
} else if (replacement2 != null) {
ast.E2 = (Expression) replacement2;
}
// if we get here, we can't fold any higher than this level
return null;
}
@Override
public AbstractSyntaxTree visitCallExpression(CallExpression ast, Void arg) {
ast.APS.visit(this);
ast.I.visit(this);
return null;
}
@Override
public AbstractSyntaxTree visitCharacterExpression(CharacterExpression ast, Void arg) {
ast.CL.visit(this);
return null;
}
@Override
public AbstractSyntaxTree visitEmptyExpression(EmptyExpression ast, Void arg) {
return null;
}
@Override
public AbstractSyntaxTree visitIfExpression(IfExpression ast, Void arg) {
AbstractSyntaxTree replacement1 = ast.E1.visit(this);
if (replacement1 != null) {
ast.E1 = (Expression) replacement1;
}
AbstractSyntaxTree replacement2 = ast.E2.visit(this);
if (replacement2 != null) {
ast.E2 = (Expression) replacement2;
}
AbstractSyntaxTree replacement3 = ast.E3.visit(this);
if (replacement3 != null) {
ast.E3 = (Expression) replacement3;
}
return null;
}
@Override
public AbstractSyntaxTree visitIntegerExpression(IntegerExpression ast, Void arg) {
return ast;
}
@Override
public AbstractSyntaxTree visitLetExpression(LetExpression ast, Void arg) {
ast.D.visit(this);
AbstractSyntaxTree replacement = ast.E.visit(this);
if (replacement != null) {
ast.E = (Expression) replacement;
}
return null;
}
@Override
public AbstractSyntaxTree visitRecordExpression(RecordExpression ast, Void arg) {
ast.RA.visit(this);
return null;
}
@Override
public AbstractSyntaxTree visitUnaryExpression(UnaryExpression ast, Void arg) {
AbstractSyntaxTree replacement = ast.E.visit(this);
if (replacement != null) {
ast.E = (Expression) replacement;
}
ast.O.visit(this);
return null;
}
@Override
public AbstractSyntaxTree visitVnameExpression(VnameExpression ast, Void arg) {
ast.V.visit(this);
return null;
}
@Override
public AbstractSyntaxTree visitBinaryOperatorDeclaration(BinaryOperatorDeclaration ast, Void arg) {
ast.ARG1.visit(this);
ast.ARG2.visit(this);
ast.O.visit(this);
ast.RES.visit(this);
return null;
}
@Override
public AbstractSyntaxTree visitConstDeclaration(ConstDeclaration ast, Void arg) {
AbstractSyntaxTree replacement = ast.E.visit(this);
if (replacement != null) {
ast.E = (Expression) replacement;
}
ast.I.visit(this);
return null;
}
@Override
public AbstractSyntaxTree visitFuncDeclaration(FuncDeclaration ast, Void arg) {
AbstractSyntaxTree replacement = ast.E.visit(this);
if (replacement != null) {
ast.E = (Expression) replacement;
}
ast.FPS.visit(this);
ast.I.visit(this);
ast.T.visit(this);
return null;
}
@Override
public AbstractSyntaxTree visitProcDeclaration(ProcDeclaration ast, Void arg) {
ast.C.visit(this);
ast.FPS.visit(this);
ast.I.visit(this);
return null;
}
@Override
public AbstractSyntaxTree visitSequentialDeclaration(SequentialDeclaration ast, Void arg) {
ast.D1.visit(this);
ast.D2.visit(this);
return null;
}
@Override
public AbstractSyntaxTree visitTypeDeclaration(TypeDeclaration ast, Void arg) {
ast.I.visit(this);
ast.T.visit(this);
return null;
}
@Override
public AbstractSyntaxTree visitUnaryOperatorDeclaration(UnaryOperatorDeclaration ast, Void arg) {
ast.ARG.visit(this);
ast.O.visit(this);
ast.RES.visit(this);
return null;
}
@Override
public AbstractSyntaxTree visitVarDeclaration(VarDeclaration ast, Void arg) {
ast.I.visit(this);
ast.T.visit(this);
return null;
}
@Override
public AbstractSyntaxTree visitAssignCommand(AssignCommand ast, Void arg) {
AbstractSyntaxTree replacement = ast.E.visit(this);
if (replacement != null) {
ast.E = (Expression) replacement;
}
ast.V.visit(this);
return null;
}
@Override
public AbstractSyntaxTree visitCallCommand(CallCommand ast, Void arg) {
return null;
}
@Override
public AbstractSyntaxTree visitEmptyCommand(EmptyCommand ast, Void arg) {
return null;
}
@Override
public AbstractSyntaxTree visitIfCommand(IfCommand ast, Void arg) {
ast.C1.visit(this);
ast.C2.visit(this);
AbstractSyntaxTree replacement = ast.E.visit(this);
if (replacement != null) {
ast.E = (Expression) replacement;
}
return null;
}
@Override
public AbstractSyntaxTree visitLetCommand(LetCommand ast, Void arg) {
ast.C.visit(this);
ast.D.visit(this);
return null;
}
@Override
public AbstractSyntaxTree visitSequentialCommand(SequentialCommand ast, Void arg) {
ast.C1.visit(this);
ast.C2.visit(this);
return null;
}
@Override
public AbstractSyntaxTree visitWhileCommand(WhileCommand ast, Void arg) {
ast.C.visit(this);
AbstractSyntaxTree replacement = ast.E.visit(this);
if (replacement != null) {
ast.E = (Expression) replacement;
}
return null;
}
// TODO uncomment if you've implemented the repeat command
// @Override
// public AbstractSyntaxTree visitRepeatCommand(RepeatCommand ast, Void arg) {
// ast.C.visit(this);
// AbstractSyntaxTree replacement = ast.E.visit(this);
// if (replacement != null) {
// ast.E = (Expression) replacement;
// }
// return null;
// }
@Override
public AbstractSyntaxTree visitMultipleArrayAggregate(MultipleArrayAggregate ast, Void arg) {
ast.AA.visit(this);
AbstractSyntaxTree replacement = ast.E.visit(this);
if (replacement != null) {
ast.E = (Expression) replacement;
}
return null;
}
@Override
public AbstractSyntaxTree visitSingleArrayAggregate(SingleArrayAggregate ast, Void arg) {
AbstractSyntaxTree replacement = ast.E.visit(this);
if (replacement != null) {
ast.E = (Expression) replacement;
}
return null;
}
@Override
public AbstractSyntaxTree visitEmptyActualParameterSequence(EmptyActualParameterSequence ast, Void arg) {
return null;
}
@Override
public AbstractSyntaxTree visitMultipleActualParameterSequence(MultipleActualParameterSequence ast, Void arg) {
ast.AP.visit(this);
ast.APS.visit(this);
return null;
}
@Override
public AbstractSyntaxTree visitSingleActualParameterSequence(SingleActualParameterSequence ast, Void arg) {
ast.AP.visit(this);
return null;
}
@Override
public AbstractSyntaxTree visitConstActualParameter(ConstActualParameter ast, Void arg) {
AbstractSyntaxTree replacement = ast.E.visit(this);
if (replacement != null) {
ast.E = (Expression) replacement;
}
return null;
}
@Override
public AbstractSyntaxTree visitFuncActualParameter(FuncActualParameter ast, Void arg) {
ast.I.visit(this);
return null;
}
@Override
public AbstractSyntaxTree visitProcActualParameter(ProcActualParameter ast, Void arg) {
ast.I.visit(this);
return null;
}
@Override
public AbstractSyntaxTree visitVarActualParameter(VarActualParameter ast, Void arg) {
ast.V.visit(this);
return null;
}
public AbstractSyntaxTree foldBinaryExpression(AbstractSyntaxTree node1, AbstractSyntaxTree node2, Operator o) {
// the only case we know how to deal with for now is two IntegerExpressions
if ((node1 instanceof IntegerExpression) && (node2 instanceof IntegerExpression)) {
int int1 = (Integer.parseInt(((IntegerExpression) node1).IL.spelling));
int int2 = (Integer.parseInt(((IntegerExpression) node2).IL.spelling));
Object foldedValue = null;
if (o.decl == StdEnvironment.addDecl) {
foldedValue = int1 + int2;
}
if (foldedValue instanceof Integer) {
IntegerLiteral il = new IntegerLiteral(foldedValue.toString(), node1.getPosition());
IntegerExpression ie = new IntegerExpression(il, node1.getPosition());
ie.type = StdEnvironment.integerType;
return ie;
} else if (foldedValue instanceof Boolean) {
/* currently not handled! */
}
}
// any unhandled situation (i.e., not foldable) is ignored
return null;
}
}
@@ -37,6 +37,7 @@ import triangle.abstractSyntaxTrees.commands.Command;
import triangle.abstractSyntaxTrees.commands.EmptyCommand; import triangle.abstractSyntaxTrees.commands.EmptyCommand;
import triangle.abstractSyntaxTrees.commands.IfCommand; import triangle.abstractSyntaxTrees.commands.IfCommand;
import triangle.abstractSyntaxTrees.commands.LetCommand; import triangle.abstractSyntaxTrees.commands.LetCommand;
import triangle.abstractSyntaxTrees.commands.RepeatCommand;
import triangle.abstractSyntaxTrees.commands.SequentialCommand; import triangle.abstractSyntaxTrees.commands.SequentialCommand;
import triangle.abstractSyntaxTrees.commands.WhileCommand; import triangle.abstractSyntaxTrees.commands.WhileCommand;
import triangle.abstractSyntaxTrees.declarations.ConstDeclaration; import triangle.abstractSyntaxTrees.declarations.ConstDeclaration;
@@ -320,7 +321,7 @@ public class Parser {
} }
break; break;
case Token.WHILE: { case Token.WHILE: { //while expr. do command
acceptIt(); acceptIt();
Expression eAST = parseExpression(); Expression eAST = parseExpression();
accept(Token.DO); accept(Token.DO);
@@ -330,6 +331,16 @@ public class Parser {
} }
break; break;
case Token.REPEAT: { //repeat command until expr.
acceptIt();
Command cAST = parseSingleCommand();
accept(Token.UNTIL); //check that there is a "until"
Expression eAST = parseExpression();
finish(commandPos);
commandAST = new RepeatCommand(eAST, cAST, commandPos);
}
break;
case Token.SEMICOLON: case Token.SEMICOLON:
case Token.END: case Token.END:
case Token.ELSE: case Token.ELSE:
@@ -918,3 +929,4 @@ public class Parser {
return fieldAST; return fieldAST;
} }
} }
@@ -35,7 +35,7 @@ public final class Scanner {
private boolean isOperator(char c) { private boolean isOperator(char c) {
return (c == '+' || c == '-' || c == '*' || c == '/' || c == '=' || c == '<' || c == '>' || c == '\\' return (c == '+' || c == '-' || c == '*' || c == '/' || c == '=' || c == '<' || c == '>' || c == '\\'
|| c == '&' || c == '@' || c == '%' || c == '^' || c == '?'); || c == '&' || c == '@' || c == '%' || c == '^' || c == '?' || c == '|');
} }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@@ -64,7 +64,7 @@ public final class Scanner {
private void scanSeparator() { private void scanSeparator() {
switch (currentChar) { switch (currentChar) {
// comment // ! comment
case '!': { case '!': {
takeIt(); takeIt();
while ((currentChar != SourceFile.EOL) && (currentChar != SourceFile.EOT)) while ((currentChar != SourceFile.EOL) && (currentChar != SourceFile.EOT))
@@ -84,6 +84,18 @@ public final class Scanner {
} }
break; break;
// new type of comment, the multi-line $ comment
case '$':{
takeIt();
//check if it is not the comment char or EOT, skipping new lines (no EOL)
while((currentChar != '$') && (currentChar != SourceFile.EOT))
takeIt();
//if we reach another $, takeIt and move on, we've reached the end of the multi-line comment
if(currentChar == '$')
takeIt();
}
break;
// whitespace // whitespace
case ' ': case ' ':
case '\n': case '\n':
@@ -188,6 +200,13 @@ public final class Scanner {
takeIt(); takeIt();
return Token.OPERATOR; return Token.OPERATOR;
// TODO: Bar operator, week 3
case '|':
takeIt();
while(isOperator(currentChar))
takeIt();
return Token.OPERATOR;
case '\'': case '\'':
takeIt(); takeIt();
takeIt(); // the quoted character takeIt(); // the quoted character
@@ -262,7 +281,7 @@ public final class Scanner {
currentlyScanningToken = false; currentlyScanningToken = false;
// skip any whitespace or comments // skip any whitespace or comments
while (currentChar == '!' || currentChar == ' ' || currentChar == '\n' || currentChar == '\r' while (currentChar == '!' || currentChar == ' ' || currentChar == '\n' || currentChar == '\r'
|| currentChar == '\t' || currentChar == '#') || currentChar == '\t' || currentChar == '#' || currentChar == '$')
scanSeparator(); scanSeparator();
currentlyScanningToken = true; currentlyScanningToken = true;
@@ -64,20 +64,20 @@ final class Token extends Object {
// reserved words - must be in alphabetical order... // reserved words - must be in alphabetical order...
ARRAY = 4, BEGIN = 5, CONST = 6, DO = 7, ELSE = 8, END = 9, FUNC = 10, IF = 11, IN = 12, LET = 13, OF = 14, ARRAY = 4, BEGIN = 5, CONST = 6, DO = 7, ELSE = 8, END = 9, FUNC = 10, IF = 11, IN = 12, LET = 13, OF = 14,
PROC = 15, RECORD = 16, THEN = 17, TYPE = 18, VAR = 19, WHILE = 20, PROC = 15, RECORD = 16, REPEAT = 17, THEN = 18, TYPE = 19, UNTIL = 20, VAR = 21, WHILE = 22,
// punctuation... // punctuation...
DOT = 21, COLON = 22, SEMICOLON = 23, COMMA = 24, BECOMES = 25, IS = 26, DOT = 23, COLON = 24, SEMICOLON = 25, COMMA = 26, BECOMES = 27, IS = 28,
// brackets... // brackets...
LPAREN = 27, RPAREN = 28, LBRACKET = 29, RBRACKET = 30, LCURLY = 31, RCURLY = 32, LPAREN = 29, RPAREN = 30, LBRACKET = 31, RBRACKET = 32, LCURLY = 33, RCURLY = 34,
// special tokens... // special tokens...
EOT = 33, ERROR = 34; EOT = 35, ERROR = 36;
private static String[] tokenTable = new String[] { "<int>", "<char>", "<identifier>", "<operator>", "array", private static String[] tokenTable = new String[] { "<int>", "<char>", "<identifier>", "<operator>", "array",
"begin", "const", "do", "else", "end", "func", "if", "in", "let", "of", "proc", "record", "then", "type", "begin", "const", "do", "else", "end", "func", "if", "in", "let", "of", "proc", "record", "repeat", "then", "type",
"var", "while", ".", ":", ";", ",", ":=", "~", "(", ")", "[", "]", "{", "}", "", "<error>" }; "until", "var", "while", ".", ":", ";", ",", ":=", "~", "(", ")", "[", "]", "{", "}", "", "<error>" };
private final static int firstReservedWord = Token.ARRAY, lastReservedWord = Token.WHILE; private final static int firstReservedWord = Token.ARRAY, lastReservedWord = Token.WHILE;
@@ -33,6 +33,7 @@ import triangle.abstractSyntaxTrees.commands.CallCommand;
import triangle.abstractSyntaxTrees.commands.EmptyCommand; import triangle.abstractSyntaxTrees.commands.EmptyCommand;
import triangle.abstractSyntaxTrees.commands.IfCommand; import triangle.abstractSyntaxTrees.commands.IfCommand;
import triangle.abstractSyntaxTrees.commands.LetCommand; import triangle.abstractSyntaxTrees.commands.LetCommand;
import triangle.abstractSyntaxTrees.commands.RepeatCommand;
import triangle.abstractSyntaxTrees.commands.SequentialCommand; import triangle.abstractSyntaxTrees.commands.SequentialCommand;
import triangle.abstractSyntaxTrees.commands.WhileCommand; import triangle.abstractSyntaxTrees.commands.WhileCommand;
import triangle.abstractSyntaxTrees.declarations.BinaryOperatorDeclaration; import triangle.abstractSyntaxTrees.declarations.BinaryOperatorDeclaration;
@@ -159,6 +160,14 @@ public class LayoutVisitor implements ActualParameterVisitor<Void, DrawingTree>,
return layoutBinary("WhileCom.", d1, d2); return layoutBinary("WhileCom.", d1, d2);
} }
@Override
public DrawingTree visitRepeatCommand(RepeatCommand ast, Void obj) {
//very similar to the while cmd, just reverse!
var d1 = ast.C.visit(this);
var d2 = ast.E.visit(this);
return layoutBinary("Repeat.Com.", d1, d2);
}
// Expressions // Expressions
@Override @Override
public DrawingTree visitArrayExpression(ArrayExpression ast, Void obj) { public DrawingTree visitArrayExpression(ArrayExpression ast, Void obj) {
@@ -28,19 +28,19 @@ public class TestScanner {
@Test @Test
public void testHiNewComment2() { public void testHiNewComment2() {
compileExpectFailure("/hi-newcomment2.tri"); compileExpectSuccess("/hi-newcomment2.tri");
} }
@Test @Test
public void testBarDemo() { public void testBarDemo() {
compileExpectFailure("/bardemo.tri"); compileExpectSuccess("/bardemo.tri"); //TODO: Change this to failure
} }
@Test @Test
public void testRepeatUntil() { public void testRepeatUntil() {
compileExpectFailure("/repeatuntil.tri"); compileExpectSuccess("/repeatuntil.tri");
} }
@Test @Test
Binary file not shown.
+12
View File
@@ -0,0 +1,12 @@
let
var a: Integer
in
begin
a := 10 + 20 * 2 / 3;
putint(a);
puteol();
a := 5 + 8;
putint(a)
end
+13 -1
View File
@@ -9,7 +9,19 @@ in
b := 2; b := 2;
putint(a); putint(a);
<<<<<<< HEAD
puteol();
=======
puteol();
>>>>>>> ce307a11a6c71de9c69bd0a4c91205bb6437f6e9
putint(b); putint(b);
puteol();
putint(|a); putint(|a);
putint(|b) puteol();
putint(|b);
puteol()
<<<<<<< HEAD
=======
>>>>>>> ce307a11a6c71de9c69bd0a4c91205bb6437f6e9
end end
+3
View File
@@ -4,6 +4,9 @@
$ $
another new comment another new comment
another new comment
another new comment
another new comment
$ $
begin begin
+14
View File
@@ -0,0 +1,14 @@
! this won't compile without implementing the bonus material in Practical 3
let
var a: Integer
in
begin
getint(var a);
a++;
putint(a);
puteol();
a++;
putint(a);
puteol();
end
+1 -1
View File
@@ -10,5 +10,5 @@ begin
put('a'); put('a');
a := a + 1; a := a + 1;
end end
until a < 5 until a >= 5
end end
+22
View File
@@ -0,0 +1,22 @@
let
var a : Integer;
var b : Integer;
var c : Integer
in
begin
put('1');
puteol();
a := 0;
while a < 5000 do
begin
b := 0;
while b < 3000 do
begin
c := c + a;
c := c / (1 + b);
b := b + 1;
end;
a := a + 1;
end;
putint(c);
end
+12 -7
View File
@@ -14,11 +14,16 @@ if [ -z "$1" ]
file=$1 file=$1
fi fi
printf "${GRN}Compiling file: $1.tri to $1.tam ...${NC}\n" printf "${GRN}[INFO] Compiling file: $1.tri to $1.tam ...${NC}\n"
# Compile to tam
#java -cp build/libs/Triangle-Tools.jar triangle.Compiler programs/$1.tri -o=$1.tam &> /dev/null #Quiet output, not handy!
java -cp build/libs/Triangle-Tools.jar triangle.Compiler programs/$1.tri -o=$1.tam
printf "${GRN}Running file: $1.tam ...${NC}\n" # Compile to tam
# Run the Program if java -cp build/libs/Triangle-Tools.jar triangle.Compiler programs/$1.tri -o=$1.tam &> /dev/null #quiet
java -cp build/libs/Triangle-Tools.jar triangle.abstractMachine.Interpreter $1.tam then
printf "${GRN}[INFO] Running file: $1.tam ...${NC}\n"
java -cp build/libs/Triangle-Tools.jar triangle.abstractMachine.Interpreter $1.tam
else
printf "${RED}[ERROR] Could not complie $1.tri ...${NC}"
err=$(java -cp build/libs/Triangle-Tools.jar triangle.Compiler programs/$1.tri -o=$1.tam)
printf "${RED}\n$err\n${NC}"
exit 1
fi