This commit is contained in:
Julian Murek 2024-07-04 13:36:16 +02:00
commit 4b36453ff3
21 changed files with 174 additions and 101 deletions

20
Examples/Fakultaet.java Normal file
View File

@ -0,0 +1,20 @@
class Fakultaet {
public int fak(int number) {
if (number < 0) {
return 1;
}
int factorial = 1;
int i = 1;
while(i <= number){
factorial = factorial * i;
i = i + 1;
}
return factorial;
}
public static void main(String[] args) {
Fakultaet f = new Fakultaet();
int result = f.fak(5);
print(result);
}
}

View File

@ -0,0 +1,40 @@
class FieldAccessAndMethodCalls {
public static void main(String[] args) {
Class1 c1 = new Class1();
int i = c1.c2.c3.m3(1).m2().m1();
print(i);
}
}
class Class1{
int i1;
Class2 c2;
public Class1() {
this.c2 = new Class2();
}
public int m1(){
return i1;
}
}
class Class2{
int i2;
Class3 c3;
public Class2(){
this.c3 = new Class3();
}
public Class1 m2(){
Class1 c1 = new Class1();
c1.i1 = i2;
return c1;
}
}
class Class3{
int i3;
public Class2 m3(int i){
Class2 c2 = new Class2();
c2.i2 = i;
return c2;
}
}

View File

@ -9,6 +9,7 @@ import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.tree.ParseTree; import org.antlr.v4.runtime.tree.ParseTree;
import java.io.Console;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
@ -18,16 +19,15 @@ public class Compiler {
public static void main(String[] args) throws Exception{ public static void main(String[] args) throws Exception{
// todo code für jar
// if (args.length < 1) {
// System.out.println("Usage: java -jar Compiler.jar <file_path> [--suppress-details]");
// return;
// }
//String filePath = args[0]; if (args.length < 1) {
String filePath = "src/main/java/TestClass.java"; System.out.println("Usage: java -jar Compiler.jar <file_path> [--suppress-details]");
// TODO false setzen für jar-Build return;
boolean suppressDetails = true; }
String filePath = args[0];
boolean suppressDetails = false;
if (args.length > 1 && args[1].equals("--suppress-details")) { if (args.length > 1 && args[1].equals("--suppress-details")) {
suppressDetails = true; suppressDetails = true;
@ -64,7 +64,7 @@ public class Compiler {
} }
String readableTokens = stringBuilder.toString().trim(); String readableTokens = stringBuilder.toString().trim();
System.out.println("The tokens of your input are: \n" + readableTokens); System.out.println("The tokens of your input are: \n" + readableTokens + "\n");
} }
@ -80,26 +80,34 @@ public class Compiler {
if(!suppressDetails) { if(!suppressDetails) {
System.out.println("Parsed " + abstractSyntaxTree.classes.size() + " classes: "); System.out.println("Parsed " + abstractSyntaxTree.classes.size() + " classes: ");
abstractSyntaxTree.classes.forEach(refType -> { abstractSyntaxTree.classes.forEach(refType -> {
System.out.print(refType.name); System.out.println("\t" + refType.name);
if (abstractSyntaxTree.classes.indexOf(refType) < abstractSyntaxTree.classes.size() - 1) { });
System.out.print(", ");
} else {
System.out.println(); System.out.println();
} }
});
} try {
// try {
// abstractSyntaxTree.typeCheck();
// }catch(TypeCheckException e){
// System.out.println("A TypeCheck error occurred. The compilation was stopped.");
// System.out.println(e);
// return;
// }
abstractSyntaxTree.typeCheck(); abstractSyntaxTree.typeCheck();
}catch(TypeCheckException e){
System.out.println("A TypeCheck error was found in you input. Your input was not compiled.");
System.out.println(e);
return;
}catch (Exception e){
System.out.println("A unexpected error occurred in TypeCheck.");
System.out.println(e);
return;
}
if(!suppressDetails) if(!suppressDetails)
System.out.println("No TypeCheck errors found."); System.out.println("No TypeCheck errors found.");
abstractSyntaxTree.codeGen();//todo remove
try {
abstractSyntaxTree.codeGen(); abstractSyntaxTree.codeGen();
System.out.println("Your input was compiled. You can find the output at ???");// todo wo output? überhaupt hinschreiben? }catch (Exception e){
System.out.println("A error occurred during code generation. Your input was not compiled.");
System.out.println(e);
return;
}
System.out.println("Your input was compiled. You can find the output in your current working directory.");
} }
} }

View File

@ -114,7 +114,7 @@ New : 'new';
//Values //Values
IntValue : ('+'|'-')*[0-9]+; IntValue : ('+'|'-')?[0-9]+;
CharValue: '\''~[\r\n]?'\''; CharValue: '\''~[\r\n]?'\'';

View File

@ -1,13 +1,40 @@
class Example1b { class FieldAccessAndMethodCalls {
public int fak(int number){ public static void main(String[] args) {
if(number < 0){ Class1 c1 = new Class1();
return 1; int i = c1.c2.c3.m3(1).m2().m1();
} System.out.println(i);
int factorial = 1; }
int i = 0; }
while(i < number){
factorial = factorial * i; class Class1{
} int i1;
return factorial; Class2 c2;
public Class1() {
this.c2 = new Class2();
}
public int m1(){
return i1;
}
}
class Class2{
int i2;
Class3 c3;
public Class2(){
this.c3 = new Class3();
}
public Class1 m2(){
Class1 c1 = new Class1();
c1.i1 = i2;
return c1;
}
}
class Class3{
int i3;
public Class2 m3(int i){
Class2 c2 = new Class2();
c2.i2 = i;
return c2;
} }
} }

View File

@ -18,9 +18,9 @@ import java.util.Objects;
public class FieldDecl extends AbstractType implements Node { public class FieldDecl extends AbstractType implements Node {
public String type; // from parser public String type;
public String identifier;// from parser public String identifier;
public IExpression expression; // value of the field public IExpression expression;
public FieldDecl(String type, String identifier, IExpression expression){ public FieldDecl(String type, String identifier, IExpression expression){
this.type = type; this.type = type;
@ -44,8 +44,6 @@ public class FieldDecl extends AbstractType implements Node {
setTypeCheckResult(result); setTypeCheckResult(result);
return result; return result;
//write field table
} }
public void codeGen(ClassWriter cw) { public void codeGen(ClassWriter cw) {

View File

@ -35,7 +35,6 @@ public class MethodDecl implements Node {
} }
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext, HashMap<String, HashMap<String, String>> typeContext) throws TypeCheckException { public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext, HashMap<String, HashMap<String, String>> typeContext) throws TypeCheckException {
// jede methode als block statement aufrufen und jede neue locale varibale in localvars schreiben
List<Parameter> parametersList = parameters.parameterList; List<Parameter> parametersList = parameters.parameterList;
for(Parameter parameter : parametersList){ for(Parameter parameter : parametersList){
localVars.put(parameter.identifier, parameter.type); localVars.put(parameter.identifier, parameter.type);

View File

@ -68,7 +68,6 @@ public class RefType extends AbstractType implements Node {
// type check each method // type check each method
for (MethodDecl methodDecl : methodDecls) { for (MethodDecl methodDecl : methodDecls) {
// methodDecl.classThatContainsMethod = this.name;
methodDecl.typeCheck(methodContext, typeContext); methodDecl.typeCheck(methodContext, typeContext);
} }

View File

@ -5,14 +5,9 @@ import TypeCheck.TypeCheckResult;
import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.MethodVisitor;
public interface IDatatype { public interface IDatatype {
// typeCheck method
TypeCheckResult typeCheck() throws TypeCheckException; TypeCheckResult typeCheck() throws TypeCheckException;
// visit method for code generation
void codeGen(MethodVisitor mv) throws Exception; void codeGen(MethodVisitor mv) throws Exception;
TypeCheckResult getTypeCheckResult(); TypeCheckResult getTypeCheckResult();
} }
//TODO: Check if we need to differentiate between primitive types and reference types --> for example in "=="

View File

@ -58,9 +58,6 @@ public class BinaryExpression extends AbstractType implements IExpression{
result.type = "int"; result.type = "int";
} }
break; break;
//case "&" ist für logisches und auf bit level
//case "|" ist für logisches oder auf bit level
} }
setTypeCheckResult(result); setTypeCheckResult(result);

View File

@ -10,11 +10,7 @@ import java.util.HashMap;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
public interface IExpression extends Node { public interface IExpression extends Node {
// typeCheck method
//TypeCheckResult typeCheck() throws Exception;
TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext, HashMap<String, HashMap<String, String>> typeContext, HashMap<String, String> localVars) throws TypeCheckException; TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext, HashMap<String, HashMap<String, String>> typeContext, HashMap<String, String> localVars) throws TypeCheckException;
// visit method for code generation
void codeGen(MethodVisitor mv, LinkedHashMap<String, String> localVars, HashMap<String, HashMap<String, String>> typeContext, HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext) throws Exception; void codeGen(MethodVisitor mv, LinkedHashMap<String, String> localVars, HashMap<String, HashMap<String, String>> typeContext, HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext) throws Exception;
TypeCheckResult getTypeCheckResult(); TypeCheckResult getTypeCheckResult();

View File

@ -87,7 +87,6 @@ public class Program implements Node {
typeContext.put(oneClass.name, classVars); typeContext.put(oneClass.name, classVars);
// build method context // build method context
HashMap<String, HashMap<String, ParameterList>> identifierAndMethod = new HashMap<>(); HashMap<String, HashMap<String, ParameterList>> identifierAndMethod = new HashMap<>();
for (MethodDecl methodDecl : oneClass.methodDecls){ for (MethodDecl methodDecl : oneClass.methodDecls){
if(methodDecl.returnType == null) continue; if(methodDecl.returnType == null) continue;
@ -98,8 +97,8 @@ public class Program implements Node {
methodContext.put(oneClass.name, identifierAndMethod); methodContext.put(oneClass.name, identifierAndMethod);
} }
int mainCounter = 0;
// check if main exists // check if main exists
int mainCounter = 0;
for(RefType oneClass : classes){ for(RefType oneClass : classes){
if(oneClass.hasMain) if(oneClass.hasMain)
mainCounter++; mainCounter++;

View File

@ -17,13 +17,10 @@ import java.util.List;
import java.util.Objects; import java.util.Objects;
public class BlockStatement extends AbstractType implements IStatement { public class BlockStatement extends AbstractType implements IStatement {
//We will need a parameter which holds the symbol table
HashMap<String, String> localVars; HashMap<String, String> localVars;
public String returnType; // "not" --> not void public String returnType;
public List<IStatement> statements; public List<IStatement> statements;
public String thisClass; public String thisClass;
// do we need expression, statementexpression
public BlockStatement(List<IStatement> statements, String returnType) { public BlockStatement(List<IStatement> statements, String returnType) {
this.statements = statements; this.statements = statements;

View File

@ -14,8 +14,6 @@ import java.util.Objects;
public class IfStatement extends AbstractType implements IStatement{ public class IfStatement extends AbstractType implements IStatement{
public IExpression condition; public IExpression condition;
//Do we need a block statement here?
IStatement ifStatement; IStatement ifStatement;
public String thisClass; public String thisClass;

View File

@ -60,9 +60,13 @@ public class PrintStatement extends AbstractType implements IStatement {
} }
counter++; counter++;
} }
// If not a localVar, maybe a class field of this class
if (index == -1){ if (index == -1){
throw new Exception("Variable " + variableName + " not found"); String typeOfField = typeContext.get(thisClass).get(variableName);
if (typeOfField == null){
throw new Exception("Variable " + variableName + " not found in local variables or class fields.");
}
mv.visitFieldInsn(Opcodes.GETSTATIC, thisClass, variableName, "I");
} }
mv.visitVarInsn(Opcodes.ILOAD, index); mv.visitVarInsn(Opcodes.ILOAD, index);

View File

@ -5,6 +5,7 @@ import TypeCheck.TypeCheckResult;
import TypeCheck.AbstractType; import TypeCheck.AbstractType;
import abstractSyntaxTree.Expression.IExpression; import abstractSyntaxTree.Expression.IExpression;
import abstractSyntaxTree.Expression.InstVarExpression; import abstractSyntaxTree.Expression.InstVarExpression;
import abstractSyntaxTree.Expression.LocalVarIdentifier;
import abstractSyntaxTree.Parameter.ParameterList; import abstractSyntaxTree.Parameter.ParameterList;
import abstractSyntaxTree.StatementExpression.MethodCallStatementExpression; import abstractSyntaxTree.StatementExpression.MethodCallStatementExpression;
import org.objectweb.asm.*; import org.objectweb.asm.*;
@ -33,6 +34,8 @@ public class ReturnStatement extends AbstractType implements IStatement{
methodCallStatementExpression.thisClass = this.thisClass; methodCallStatementExpression.thisClass = this.thisClass;
else if(expression instanceof InstVarExpression instVarExpression) else if(expression instanceof InstVarExpression instVarExpression)
instVarExpression.thisClass = this.thisClass; instVarExpression.thisClass = this.thisClass;
else if(expression instanceof LocalVarIdentifier localVarIdentifier)
localVarIdentifier.thisClass = this.thisClass;
TypeCheckResult typedExpression = expression.typeCheck(methodContext, typeContext, localVars); TypeCheckResult typedExpression = expression.typeCheck(methodContext, typeContext, localVars);
result.type = typedExpression.type; result.type = typedExpression.type;
} }

View File

@ -29,7 +29,7 @@ public class WhileStatement extends AbstractType implements IStatement {
// check condition // check condition
TypeCheckResult conditionType = condition.typeCheck(methodContext, typeContext, localVars); TypeCheckResult conditionType = condition.typeCheck(methodContext, typeContext, localVars);
if (!conditionType.type.equals("boolean")) { if (!conditionType.type.equals("boolean")) {
throw new IllegalArgumentException("Expected boolean"); throw new TypeCheckException("Condition of while-statement is of type " + conditionType.type + " but should be boolean.");
} }
// check code block // check code block

View File

@ -36,6 +36,7 @@ public class AssignStatementExpression extends AbstractType implements IExpressi
TypeCheckResult leftType; TypeCheckResult leftType;
if (left instanceof LocalVarIdentifier localVarIdentifier) { if (left instanceof LocalVarIdentifier localVarIdentifier) {
localVarIdentifier.thisClass = thisClass;
leftType = new TypeCheckResult(); leftType = new TypeCheckResult();
String identifier = localVarIdentifier.getIdentifier(); String identifier = localVarIdentifier.getIdentifier();
leftType.type = localVars.get(identifier); leftType.type = localVars.get(identifier);
@ -51,6 +52,8 @@ public class AssignStatementExpression extends AbstractType implements IExpressi
} }
if(right instanceof MethodCallStatementExpression methodCallStatementExpression) if(right instanceof MethodCallStatementExpression methodCallStatementExpression)
methodCallStatementExpression.thisClass = this.thisClass; methodCallStatementExpression.thisClass = this.thisClass;
if(right instanceof LocalVarIdentifier localVarIdentifierRight)
localVarIdentifierRight.thisClass = this.thisClass;
TypeCheckResult rightType = right.typeCheck(methodContext, typeContext, localVars); TypeCheckResult rightType = right.typeCheck(methodContext, typeContext, localVars);

View File

@ -34,7 +34,6 @@ public class MethodCallStatementExpression extends AbstractType implements IExpr
String classToSearchMethodIn = thisClass; String classToSearchMethodIn = thisClass;
//method is called on something that is not this ???
if (this.receiver != null) { if (this.receiver != null) {
if (!receiver.thisExpression) { if (!receiver.thisExpression) {
classToSearchMethodIn = localVars.get(receiver.identifier); classToSearchMethodIn = localVars.get(receiver.identifier);
@ -51,11 +50,7 @@ public class MethodCallStatementExpression extends AbstractType implements IExpr
receiver.instVarExpression.thisClass = this.thisClass; receiver.instVarExpression.thisClass = this.thisClass;
String typeOfSubreceiver = receiver.instVarExpression.typeCheck(methodContext, typeContext, localVars).type; String typeOfSubreceiver = receiver.instVarExpression.typeCheck(methodContext, typeContext, localVars).type;
String lastField = receiver.instVarExpression.fieldName;
currentType = typeOfSubreceiver; currentType = typeOfSubreceiver;
//currentType = typeContext.get(receiver.instVarExpression.getTypeCheckResult().type).get(mostLeftField);
} else { } else {
currentType = classToSearchMethodIn; currentType = classToSearchMethodIn;
} }
@ -63,16 +58,11 @@ public class MethodCallStatementExpression extends AbstractType implements IExpr
currentType = thisClass; currentType = thisClass;
} }
//if classToSearchMethodIn does not contain method, throw exception. go through list and check each
for (int i = 0; i < receivingMethods.size(); i++) { for (int i = 0; i < receivingMethods.size(); i++) {
currentType = (String) methodContext.get(currentType).get(receivingMethods.get(i).methodName).keySet().toArray()[0]; currentType = (String) methodContext.get(currentType).get(receivingMethods.get(i).methodName).keySet().toArray()[0];
if (currentType == null) if (currentType == null)
throw new TypeCheckException("The method " + methodName + " was not found in " + classToSearchMethodIn + "."); throw new TypeCheckException("The method " + methodName + " was not found in " + classToSearchMethodIn + ".");
receivingMethods.get(i).thisClass = this.thisClass; receivingMethods.get(i).thisClass = this.thisClass;
// currentType = return type
// ThisClass = class von methode
receivingMethods.get(i).checkParameters(methodContext, typeContext, localVars); receivingMethods.get(i).checkParameters(methodContext, typeContext, localVars);
} }
currentType = (String) methodContext.get(currentType).get(methodName).keySet().toArray()[0]; currentType = (String) methodContext.get(currentType).get(methodName).keySet().toArray()[0];

View File

@ -19,7 +19,7 @@ public class NewStatementExpression extends AbstractType implements IExpression,
public String thisClass; public String thisClass;
private String className; private String className;
private List<IExpression> arguments; //These need to have a TypeCheckResult private List<IExpression> arguments;
public NewStatementExpression(String className, List<IExpression> arguments) { public NewStatementExpression(String className, List<IExpression> arguments) {
this.className = className; this.className = className;

View File

@ -32,27 +32,27 @@ public class ASTGenerator extends DecafBaseVisitor<Node> {
List<FieldDecl> fieldDecls = new ArrayList<>(); List<FieldDecl> fieldDecls = new ArrayList<>();
List<MethodDecl> methodDecls = new ArrayList<>(); List<MethodDecl> methodDecls = new ArrayList<>();
boolean hasMain; boolean hasMain;
if(ctx.MainMethodDecl() != null) { if (ctx.MainMethodDecl() != null) {
hasMain = true; hasMain = true;
MethodDecl mainMethod = new MethodDecl(name, "void", "main", new ParameterList(new ArrayList<>()),(BlockStatement) visitBlock(ctx.block())); MethodDecl mainMethod = new MethodDecl(name, "void", "main", new ParameterList(new ArrayList<>()), (BlockStatement) visitBlock(ctx.block()));
methodDecls.add(mainMethod); methodDecls.add(mainMethod);
} else { } else {
hasMain = false; hasMain = false;
} }
for (DecafParser.LocalVarDeclContext fieldDecl: ctx.localVarDecl()) { for (DecafParser.LocalVarDeclContext fieldDecl : ctx.localVarDecl()) {
fieldDecls.add((FieldDecl) generateFieldDecl(fieldDecl)); fieldDecls.add((FieldDecl) generateFieldDecl(fieldDecl));
} }
for (DecafParser.ConstuctorDeclContext constDecl: ctx.constuctorDecl()) { for (DecafParser.ConstuctorDeclContext constDecl : ctx.constuctorDecl()) {
MethodDecl constructor = ((MethodDecl) visit(constDecl)); MethodDecl constructor = ((MethodDecl) visit(constDecl));
constructor.classThatContainsMethod = name; constructor.classThatContainsMethod = name;
methodDecls.add(constructor); methodDecls.add(constructor);
} }
for (DecafParser.MethodDeclContext methodDecl: ctx.methodDecl()) { for (DecafParser.MethodDeclContext methodDecl : ctx.methodDecl()) {
MethodDecl method = (MethodDecl) visit(methodDecl); MethodDecl method = (MethodDecl) visit(methodDecl);
method.classThatContainsMethod = name; method.classThatContainsMethod = name;
methodDecls.add(method); methodDecls.add(method);
} }
return new RefType(name,fieldDecls, methodDecls, hasMain); return new RefType(name, fieldDecls, methodDecls, hasMain);
} }
public Node generateFieldDecl(DecafParser.LocalVarDeclContext ctx) { public Node generateFieldDecl(DecafParser.LocalVarDeclContext ctx) {
@ -99,7 +99,7 @@ public class ASTGenerator extends DecafBaseVisitor<Node> {
} else { } else {
type = ctx.type().getText(); type = ctx.type().getText();
} }
return new MethodDecl("", type , name, parameterList, block); return new MethodDecl("", type, name, parameterList, block);
} }
@Override @Override
@ -110,7 +110,7 @@ public class ASTGenerator extends DecafBaseVisitor<Node> {
@Override @Override
public Node visitParameterList(DecafParser.ParameterListContext ctx) { public Node visitParameterList(DecafParser.ParameterListContext ctx) {
List<Parameter> parameters = new ArrayList<>(); List<Parameter> parameters = new ArrayList<>();
for (DecafParser.ParameterContext parameter: ctx.parameter()) { for (DecafParser.ParameterContext parameter : ctx.parameter()) {
parameters.add((Parameter) visit(parameter)); parameters.add((Parameter) visit(parameter));
} }
return new ParameterList(parameters); return new ParameterList(parameters);
@ -151,7 +151,7 @@ public class ASTGenerator extends DecafBaseVisitor<Node> {
@Override @Override
public Node visitBlock(DecafParser.BlockContext ctx) { public Node visitBlock(DecafParser.BlockContext ctx) {
List<IStatement> stmts = new ArrayList<>(); List<IStatement> stmts = new ArrayList<>();
for (DecafParser.StatementContext stmt: ctx.statement()) { for (DecafParser.StatementContext stmt : ctx.statement()) {
Node statement = visitStatement(stmt); Node statement = visitStatement(stmt);
stmts.add((IStatement) statement); stmts.add((IStatement) statement);
} }
@ -211,7 +211,7 @@ public class ASTGenerator extends DecafBaseVisitor<Node> {
public Node visitAssign(DecafParser.AssignContext ctx) { public Node visitAssign(DecafParser.AssignContext ctx) {
Node right = visitExpression(ctx.expression()); Node right = visitExpression(ctx.expression());
Node left = visitAssignableExpr(ctx.assignableExpr()); Node left = visitAssignableExpr(ctx.assignableExpr());
return new AssignStatementExpression(ctx.Assign().getText(),(IExpression) left, (IExpression) right); return new AssignStatementExpression(ctx.Assign().getText(), (IExpression) left, (IExpression) right);
} }
@Override @Override
@ -219,7 +219,7 @@ public class ASTGenerator extends DecafBaseVisitor<Node> {
String methodName = ctx.Identifier().getText(); String methodName = ctx.Identifier().getText();
List<IExpression> arguments = generateExpressions(ctx.argumentList()); List<IExpression> arguments = generateExpressions(ctx.argumentList());
List<ReceivingMethod> receivingMethods = new ArrayList<>(); List<ReceivingMethod> receivingMethods = new ArrayList<>();
for(DecafParser.ReceivingMethodContext receivingMethod: ctx.receivingMethod()) { for (DecafParser.ReceivingMethodContext receivingMethod : ctx.receivingMethod()) {
receivingMethods.add((ReceivingMethod) visit(receivingMethod)); receivingMethods.add((ReceivingMethod) visit(receivingMethod));
} }
if (ctx.receiver() != null) { if (ctx.receiver() != null) {
@ -320,14 +320,14 @@ public class ASTGenerator extends DecafBaseVisitor<Node> {
if (ctx.IntValue() != null) { if (ctx.IntValue() != null) {
int value = Integer.parseInt(ctx.IntValue().getText()); int value = Integer.parseInt(ctx.IntValue().getText());
return new IntConstantExpression(value); return new IntConstantExpression(value);
} else if(ctx.Identifier() != null) { } else if (ctx.Identifier() != null) {
String identifier = ctx.Identifier().getText(); String identifier = ctx.Identifier().getText();
return new LocalVarIdentifier(identifier); return new LocalVarIdentifier(identifier);
} else if(ctx.instVar() != null) { } else if (ctx.instVar() != null) {
return visitInstVar(ctx.instVar()); return visitInstVar(ctx.instVar());
} else if(ctx.methodCall() != null) { } else if (ctx.methodCall() != null) {
return visitMethodCall(ctx.methodCall()); return visitMethodCall(ctx.methodCall());
} else if(ctx.calcExpr() != null) { } else if (ctx.calcExpr() != null) {
return visitCalcExpr(ctx.calcExpr()); return visitCalcExpr(ctx.calcExpr());
} }
return null; return null;
@ -336,7 +336,7 @@ public class ASTGenerator extends DecafBaseVisitor<Node> {
@Override @Override
public Node visitNonCalcExpr(DecafParser.NonCalcExprContext ctx) { public Node visitNonCalcExpr(DecafParser.NonCalcExprContext ctx) {
String operator; String operator;
if(ctx.nonCalcOperator().LogicalOpertor() != null) { if (ctx.nonCalcOperator().LogicalOpertor() != null) {
operator = ctx.nonCalcOperator().LogicalOpertor().getText(); operator = ctx.nonCalcOperator().LogicalOpertor().getText();
} else { } else {
operator = ctx.nonCalcOperator().ComparisonOperator().getText(); operator = ctx.nonCalcOperator().ComparisonOperator().getText();
@ -373,10 +373,10 @@ public class ASTGenerator extends DecafBaseVisitor<Node> {
List<SubReceiver> receivers = new ArrayList<>(); List<SubReceiver> receivers = new ArrayList<>();
List<ReceivingMethod> receivingMethods = new ArrayList<>(); List<ReceivingMethod> receivingMethods = new ArrayList<>();
String fieldName = ctx.Identifier().getText(); String fieldName = ctx.Identifier().getText();
for(DecafParser.SubReceiverContext subReceiver : ctx.subReceiver()) { for (DecafParser.SubReceiverContext subReceiver : ctx.subReceiver()) {
receivers.add((SubReceiver) visit(subReceiver)); receivers.add((SubReceiver) visit(subReceiver));
} }
for(DecafParser.ReceivingMethodContext receivingMethod: ctx.receivingMethod()) { for (DecafParser.ReceivingMethodContext receivingMethod : ctx.receivingMethod()) {
receivingMethods.add((ReceivingMethod) visit(receivingMethod)); receivingMethods.add((ReceivingMethod) visit(receivingMethod));
} }
return new InstVarExpression(receivers, receivingMethods, fieldName); return new InstVarExpression(receivers, receivingMethods, fieldName);