# Conflicts:
#	src/main/java/abstractSyntaxTree/Class/MethodDecl.java
#	src/main/java/abstractSyntaxTree/StatementExpression/AssignStatementExpression.java
#	src/main/java/abstractSyntaxTree/StatementExpression/MethodCallStatementExpression.java
This commit is contained in:
Krauß, Josefine 2024-05-31 11:00:50 +02:00
commit ef38079f58
15 changed files with 87 additions and 63 deletions

View File

@ -46,7 +46,7 @@ public class MethodDecl implements Node {
//Need to get the returnType of the method if it is an object //Need to get the returnType of the method if it is an object
// methodContext (class, (returnType, (identifier, parameter))) // methodContext (class, (returnType, (identifier, parameter)))
public void codeGen(ClassWriter cw, HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext) throws Exception { public void codeGen(ClassWriter cw, HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext, HashMap<String, HashMap<String, String>> typeContext) throws Exception {
localVars.put("this", classThatContainsMethod); localVars.put("this", classThatContainsMethod);
for (Parameter param : parameters.parameterList) { for (Parameter param : parameters.parameterList) {
@ -75,7 +75,7 @@ public class MethodDecl implements Node {
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", descriptor, false); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", descriptor, false);
mv.visitCode(); mv.visitCode();
//codeBlock.codeGen(mv, localVars); codeBlock.codeGen(mv, localVars, typeContext);
mv.visitInsn(Opcodes.RETURN); mv.visitInsn(Opcodes.RETURN);
//automatically computed max stack and max locals //automatically computed max stack and max locals
@ -87,7 +87,7 @@ public class MethodDecl implements Node {
MethodVisitor mv = cw.visitMethod(access, name, "([Ljava/lang/String;)V", null, null); MethodVisitor mv = cw.visitMethod(access, name, "([Ljava/lang/String;)V", null, null);
mv.visitCode(); mv.visitCode();
//codeBlock.codeGen(mv, localVars); codeBlock.codeGen(mv, localVars, typeContext);
mv.visitInsn(Opcodes.RETURN); mv.visitInsn(Opcodes.RETURN);
mv.visitMaxs(0, 0); mv.visitMaxs(0, 0);
@ -97,7 +97,7 @@ public class MethodDecl implements Node {
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, name, getMethodDescriptor(methodContext), null, null); MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, name, getMethodDescriptor(methodContext), null, null);
mv.visitCode(); mv.visitCode();
//codeBlock.codeGen(mv, localVars); codeBlock.codeGen(mv, localVars, typeContext);
// We have to check the return type to get the return opcode // We have to check the return type to get the return opcode
// For methods which return an actual value, the return opcode is created in the method body to ensure the // For methods which return an actual value, the return opcode is created in the method body to ensure the

View File

@ -2,6 +2,7 @@ package abstractSyntaxTree.Class;
import TypeCheck.AbstractType; import TypeCheck.AbstractType;
import TypeCheck.TypeCheckResult; import TypeCheck.TypeCheckResult;
import abstractSyntaxTree.Expression.IExpression;
import abstractSyntaxTree.Node; import abstractSyntaxTree.Node;
import abstractSyntaxTree.Parameter.ParameterList; import abstractSyntaxTree.Parameter.ParameterList;
import org.objectweb.asm.ClassWriter; import org.objectweb.asm.ClassWriter;
@ -29,6 +30,7 @@ public class RefType extends AbstractType implements Node {
this.fieldDecls = fieldDecls; this.fieldDecls = fieldDecls;
this.methodDecls = methodDecls; this.methodDecls = methodDecls;
this.hasMain = hasMain; this.hasMain = hasMain;
} }
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext, public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext,
@ -75,7 +77,7 @@ public class RefType extends AbstractType implements Node {
// Method for code generation which iterates over all the field declarations // Method for code generation which iterates over all the field declarations
// and method declarations and calls their CodeGen methods // and method declarations and calls their CodeGen methods
public void codeGen(ClassWriter cw, HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext) throws Exception { public void codeGen(ClassWriter cw, HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext, HashMap<String, HashMap<String, String>> typeContext) throws Exception {
cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, name, null, cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, name, null,
"java/lang/Object", null); "java/lang/Object", null);
@ -85,7 +87,7 @@ public class RefType extends AbstractType implements Node {
} }
for (MethodDecl method : methodDecls) { for (MethodDecl method : methodDecls) {
method.codeGen(cw, methodContext); method.codeGen(cw, methodContext, typeContext);
} }
cw.visitEnd(); cw.visitEnd();
} }

View File

@ -67,7 +67,7 @@ public class BinaryExpression extends AbstractType implements IExpression{
} }
@Override @Override
public void codeGen(MethodVisitor mv, HashMap<String, HashMap<String, String>> typeContext, LinkedHashMap<String, String> localVars) throws Exception { public void codeGen(MethodVisitor mv, LinkedHashMap<String, String> localVars, HashMap<String, HashMap<String, String>> typeContext) throws Exception {
// Label for the jump instruction // Label for the jump instruction
Label operationFalse = new Label(); //Operation is false Label operationFalse = new Label(); //Operation is false
Label operationTrue = new Label(); //Operation is true Label operationTrue = new Label(); //Operation is true
@ -77,88 +77,88 @@ public class BinaryExpression extends AbstractType implements IExpression{
// Bytecode for the binary operation // Bytecode for the binary operation
switch (operator) { switch (operator) {
case "&&": case "&&":
left.codeGen(mv, typeContext, localVars); left.codeGen(mv, localVars, typeContext);
mv.visitJumpInsn(Opcodes.IFEQ, operationFalse); // IFEQ --> "if equals to zero" (false) --> if left exp is false mv.visitJumpInsn(Opcodes.IFEQ, operationFalse); // IFEQ --> "if equals to zero" (false) --> if left exp is false
right.codeGen(mv, typeContext, localVars); right.codeGen(mv, localVars, typeContext);
mv.visitJumpInsn(Opcodes.IFEQ, operationFalse); // If right exp is false, jump to the end of the whole expression mv.visitJumpInsn(Opcodes.IFEQ, operationFalse); // If right exp is false, jump to the end of the whole expression
mv.visitJumpInsn(Opcodes.GOTO, operationTrue); // If it reaches this point, the right exp is true mv.visitJumpInsn(Opcodes.GOTO, operationTrue); // If it reaches this point, the right exp is true
break; break;
case "||": case "||":
left.codeGen(mv, typeContext, localVars); left.codeGen(mv, localVars, typeContext);
mv.visitJumpInsn(Opcodes.IFNE, operationTrue); // IFNE --> "if not equals to zero" (true) --> if left exp is true mv.visitJumpInsn(Opcodes.IFNE, operationTrue); // IFNE --> "if not equals to zero" (true) --> if left exp is true
right.codeGen(mv, typeContext, localVars); right.codeGen(mv, localVars, typeContext);
mv.visitJumpInsn(Opcodes.IFNE, operationTrue); mv.visitJumpInsn(Opcodes.IFNE, operationTrue);
break; break;
case "==": case "==":
// Keep in mind that only primitive types are allowed in this case (at this time) // Keep in mind that only primitive types are allowed in this case (at this time)
left.codeGen(mv, typeContext, localVars); left.codeGen(mv, localVars, typeContext);
right.codeGen(mv, typeContext, localVars); right.codeGen(mv, localVars, typeContext);
mv.visitJumpInsn(Opcodes.IF_ICMPEQ, operationTrue); // If the two values are equal, jump to the end of the expression mv.visitJumpInsn(Opcodes.IF_ICMPEQ, operationTrue); // If the two values are equal, jump to the end of the expression
break; break;
case "<": case "<":
left.codeGen(mv, typeContext, localVars); left.codeGen(mv, localVars, typeContext);
right.codeGen(mv, typeContext, localVars); right.codeGen(mv, localVars, typeContext);
mv.visitJumpInsn(Opcodes.IF_ICMPLT, operationTrue); // Checks only on less than, not equal mv.visitJumpInsn(Opcodes.IF_ICMPLT, operationTrue); // Checks only on less than, not equal
break; break;
case ">": case ">":
left.codeGen(mv, typeContext, localVars); left.codeGen(mv, localVars, typeContext);
right.codeGen(mv, typeContext, localVars); right.codeGen(mv, localVars, typeContext);
mv.visitJumpInsn(Opcodes.IF_ICMPGT, operationTrue); // Checks only on greater than, not equal mv.visitJumpInsn(Opcodes.IF_ICMPGT, operationTrue); // Checks only on greater than, not equal
break; break;
case "<=": case "<=":
left.codeGen(mv, typeContext, localVars); left.codeGen(mv, localVars, typeContext);
right.codeGen(mv, typeContext, localVars); right.codeGen(mv, localVars, typeContext);
mv.visitJumpInsn(Opcodes.IF_ICMPLE, operationTrue); // Checks on less than OR equal mv.visitJumpInsn(Opcodes.IF_ICMPLE, operationTrue); // Checks on less than OR equal
break; break;
case ">=": case ">=":
left.codeGen(mv, typeContext, localVars); left.codeGen(mv, localVars, typeContext);
right.codeGen(mv, typeContext, localVars); right.codeGen(mv, localVars, typeContext);
mv.visitJumpInsn(Opcodes.IF_ICMPGE, operationTrue); // Checks on greater than OR equal mv.visitJumpInsn(Opcodes.IF_ICMPGE, operationTrue); // Checks on greater than OR equal
break; break;
case "!=": case "!=":
left.codeGen(mv, typeContext, localVars); left.codeGen(mv, localVars, typeContext);
right.codeGen(mv, typeContext, localVars); right.codeGen(mv, localVars, typeContext);
mv.visitJumpInsn(Opcodes.IF_ICMPNE, operationTrue); // Checks on not equal mv.visitJumpInsn(Opcodes.IF_ICMPNE, operationTrue); // Checks on not equal
break; break;
case "+": case "+":
left.codeGen(mv, typeContext, localVars); left.codeGen(mv, localVars, typeContext);
right.codeGen(mv, typeContext, localVars); right.codeGen(mv, localVars, typeContext);
mv.visitInsn(Opcodes.IADD); mv.visitInsn(Opcodes.IADD);
break; break;
case "-": case "-":
left.codeGen(mv, typeContext, localVars); left.codeGen(mv, localVars, typeContext);
right.codeGen(mv, typeContext, localVars); right.codeGen(mv, localVars, typeContext);
mv.visitInsn(Opcodes.ISUB); mv.visitInsn(Opcodes.ISUB);
break; break;
case "*": case "*":
left.codeGen(mv, typeContext, localVars); left.codeGen(mv, localVars, typeContext);
right.codeGen(mv, typeContext, localVars); right.codeGen(mv, localVars, typeContext);
mv.visitInsn(Opcodes.IMUL); mv.visitInsn(Opcodes.IMUL);
break; break;
case "/": case "/":
left.codeGen(mv, typeContext, localVars); left.codeGen(mv, localVars, typeContext);
right.codeGen(mv, typeContext, localVars); right.codeGen(mv, localVars, typeContext);
mv.visitInsn(Opcodes.IDIV); mv.visitInsn(Opcodes.IDIV);
break; break;

View File

@ -14,5 +14,5 @@ public interface IExpression extends Node {
TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext, HashMap<String, HashMap<String, String>> typeContext, HashMap<String, String> localVars) throws Exception; TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext, HashMap<String, HashMap<String, String>> typeContext, HashMap<String, String> localVars) throws Exception;
// visit method for code generation // visit method for code generation
void codeGen(MethodVisitor mv, HashMap<String, HashMap<String, String>> typeContext, LinkedHashMap<String, String> localVars) throws Exception; void codeGen(MethodVisitor mv, LinkedHashMap<String, String> localVars, HashMap<String, HashMap<String, String>> typeContext) throws Exception;
} }

View File

@ -35,7 +35,7 @@ public class InstVarExpression implements IExpression{
@Override @Override
// typeContext: (ClassName, (FieldName, FieldType)) // typeContext: (ClassName, (FieldName, FieldType))
public void codeGen(MethodVisitor mv, HashMap<String, HashMap<String, String>> typeContext, LinkedHashMap<String, String> localVars) throws Exception { public void codeGen(MethodVisitor mv, LinkedHashMap<String, String> localVars, HashMap<String, HashMap<String, String>> typeContext) throws Exception {
// Load "this" onto the stack // Load "this" onto the stack
mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitVarInsn(Opcodes.ALOAD, 0);

View File

@ -28,7 +28,7 @@ public class LocalVarIdentifier implements IExpression{
} }
@Override @Override
public void codeGen(MethodVisitor mv, HashMap<String, HashMap<String, String>> typeContext, LinkedHashMap<String, String> localVars) throws Exception { public void codeGen(MethodVisitor mv, LinkedHashMap<String, String> localVars, HashMap<String, HashMap<String, String>> typeContext) throws Exception {
// Check if the variable is in the list of local variables // Check if the variable is in the list of local variables
String type = localVars.get(identifier); String type = localVars.get(identifier);
if (type == null){ if (type == null){

View File

@ -50,7 +50,7 @@ public class UnaryExpression extends AbstractType implements IExpression{
} }
@Override @Override
public void codeGen(MethodVisitor mv, HashMap<String, HashMap<String, String>> typeContext, LinkedHashMap<String, String> localVars) throws Exception { public void codeGen(MethodVisitor mv, LinkedHashMap<String, String> localVars, HashMap<String, HashMap<String, String>> typeContext) throws Exception {
operand.codeGen(mv); operand.codeGen(mv);

View File

@ -68,7 +68,7 @@ public class Program implements Node {
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES); ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, oneClass.name, null, "java/lang/Object", null); cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, oneClass.name, null, "java/lang/Object", null);
// oneClass.codeGen(cw); oneClass.codeGen(cw, methodContext, typeContext);
cw.visitEnd(); cw.visitEnd();
byte[] bytecode = cw.toByteArray(); byte[] bytecode = cw.toByteArray();

View File

@ -58,7 +58,7 @@ public class IfElseStatement extends AbstractType implements IStatement{
Label conditionFalse = new Label(); Label conditionFalse = new Label();
Label statementEnd = new Label(); Label statementEnd = new Label();
condition.codeGen(mv, typeContext, localVars); condition.codeGen(mv, localVars, typeContext);
mv.visitJumpInsn(Opcodes.IFEQ, conditionFalse); //Checks if the condition is false (0) mv.visitJumpInsn(Opcodes.IFEQ, conditionFalse); //Checks if the condition is false (0)
ifStatement.codeGen(mv, blockLocalVars, typeContext); //If the condition is true, execute the ifBlock ifStatement.codeGen(mv, blockLocalVars, typeContext); //If the condition is true, execute the ifBlock

View File

@ -43,7 +43,7 @@ public class IfStatement extends AbstractType implements IStatement{
Label conditionFalse = new Label(); Label conditionFalse = new Label();
condition.codeGen(mv, typeContext, localVars); condition.codeGen(mv, localVars, typeContext);
mv.visitJumpInsn(Opcodes.IFEQ, conditionFalse); //Checks if the condition is false (0) mv.visitJumpInsn(Opcodes.IFEQ, conditionFalse); //Checks if the condition is false (0)
ifStatement.codeGen(mv, blockLocalVars, typeContext); ifStatement.codeGen(mv, blockLocalVars, typeContext);

View File

@ -38,7 +38,7 @@ public class ReturnStatement extends AbstractType implements IStatement{
public void codeGen(MethodVisitor mv, LinkedHashMap<String, String> localVars, HashMap<String, HashMap<String, String>> typeContext) throws Exception { public void codeGen(MethodVisitor mv, LinkedHashMap<String, String> localVars, HashMap<String, HashMap<String, String>> typeContext) throws Exception {
if (expression != null) { if (expression != null) {
expression.codeGen(mv, typeContext, localVars); expression.codeGen(mv, localVars, typeContext);
//Get the Type of the expression //Get the Type of the expression
//TODO: Resolve how do we get the type of the expression //TODO: Resolve how do we get the type of the expression
String type = expression.typeCheck(null, null, null).type; String type = expression.typeCheck(null, null, null).type;

View File

@ -48,7 +48,7 @@ public class WhileStatement extends AbstractType implements IStatement {
mv.visitLabel(LoopStart); mv.visitLabel(LoopStart);
condition.codeGen(mv, typeContext, localVars); condition.codeGen(mv, localVars, typeContext);
mv.visitJumpInsn(Opcodes.IFEQ, conditionFalse); // Checks if the condition is false (0) mv.visitJumpInsn(Opcodes.IFEQ, conditionFalse); // Checks if the condition is false (0)
statement.codeGen(mv, blockLocalVars, typeContext); statement.codeGen(mv, blockLocalVars, typeContext);

View File

@ -20,7 +20,7 @@ public class AssignStatementExpression extends AbstractType implements IExpressi
public IExpression right; public IExpression right;
private InstVarExpression instVar; private InstVarExpression instVar;
public AssignStatementExpression(String operator, IExpression leftExpression, IExpression rightExpression) { public AssignStatementExpression(String operator, IExpression leftExpression, IExpression rightExpression){
this.operator = operator; this.operator = operator;
this.left = leftExpression; this.left = leftExpression;
this.right = rightExpression; this.right = rightExpression;
@ -38,7 +38,7 @@ public class AssignStatementExpression extends AbstractType implements IExpressi
LocalVarIdentifier localVarIdentifier = (LocalVarIdentifier) left; LocalVarIdentifier localVarIdentifier = (LocalVarIdentifier) left;
String identifier = localVarIdentifier.getIdentifier(); String identifier = localVarIdentifier.getIdentifier();
leftType.type = localVars.get(identifier); leftType.type = localVars.get(identifier);
} else { }else{
leftType = left.typeCheck(methodContext, typeContext, localVars); leftType = left.typeCheck(methodContext, typeContext, localVars);
} }
TypeCheckResult rightType = right.typeCheck(methodContext, typeContext, localVars); TypeCheckResult rightType = right.typeCheck(methodContext, typeContext, localVars);
@ -62,12 +62,12 @@ public class AssignStatementExpression extends AbstractType implements IExpressi
} }
@Override @Override
public void codeGen(MethodVisitor mv, HashMap<String, HashMap<String, String>> typeContext, LinkedHashMap<String, String> localVars) throws Exception { public void codeGen(MethodVisitor mv, LinkedHashMap<String, String> localVars, HashMap<String, HashMap<String, String>> typeContext) throws Exception {
//TODO: Do we need the value on the stack after assigning it? //TODO: Do we need the value on the stack after assigning it?
//TODO: WE do not differentiate between InstanceVar and FieldVar //TODO: WE do not differentiate between InstanceVar and FieldVar
// Call the codeGen on the right expression which will push the value of the right expression onto the stack // Call the codeGen on the right expression which will push the value of the right expression onto the stack
right.codeGen(mv, typeContext, localVars); right.codeGen(mv, localVars, typeContext);
if (left instanceof LocalVarIdentifier) { if (left instanceof LocalVarIdentifier) {
LocalVarIdentifier localVar = (LocalVarIdentifier) left; LocalVarIdentifier localVar = (LocalVarIdentifier) left;
@ -104,6 +104,13 @@ public class AssignStatementExpression extends AbstractType implements IExpressi
// Load "this" onto the stack // Load "this" onto the stack
mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitVarInsn(Opcodes.ALOAD, 0);
}
/*
if (left instanceof VarRefExpression varRef) {
//TODO: Implement the handling of a variable reference --> I need a list of local variables
// for that to determine if the variable is a local or field variable
} else if (left instanceof InstVarExpression instVar) {
mv.visitInsn(Opcodes.DUP_X1);
// if (left instanceof VarRefExpression varRef) { // if (left instanceof VarRefExpression varRef) {
// //TODO: Implement the handling of a variable reference --> I need a list of local variables // //TODO: Implement the handling of a variable reference --> I need a list of local variables
@ -114,6 +121,5 @@ public class AssignStatementExpression extends AbstractType implements IExpressi
// // We now again need the owner (class reference), name (of the Field in the owner) and type of the field // // We now again need the owner (class reference), name (of the Field in the owner) and type of the field
// //mv.visitFieldInsn(Opcodes.PUTFIELD, instVar.className, instVar.varName, instVar.type); // //mv.visitFieldInsn(Opcodes.PUTFIELD, instVar.className, instVar.varName, instVar.type);
// } // }
}
} }
} }

View File

@ -51,16 +51,10 @@ public class MethodCallStatementExpression extends AbstractType implements IExpr
return null; return null;
} }
@Override
public void codeGen(MethodVisitor mv, LinkedHashMap<String, String> localVars, HashMap<String, HashMap<String, String>> typeContext) throws Exception {
}
//Errors occur due to the change in parameter in the RefType class //Errors occur due to the change in parameter in the RefType class
// I need the methodContext here to get the method descriptor // I need the methodContext here to get the method descriptor
@Override @Override
public void codeGen(MethodVisitor mv, HashMap<String, HashMap<String, String>> typeContext, LinkedHashMap<String, String> localVars) throws Exception { public void codeGen(MethodVisitor mv, LinkedHashMap<String, String> localVars, HashMap<String, HashMap<String, String>> typeContext) throws Exception {
//Generate Bytecode for the receiver //Generate Bytecode for the receiver
if(classThatHasTheMethodIfNotThis != null){ if(classThatHasTheMethodIfNotThis != null){
//TODO: classThatHasTheMethodIfNotThis must be an object --> instance of the class not the class itself //TODO: classThatHasTheMethodIfNotThis must be an object --> instance of the class not the class itself
@ -71,10 +65,10 @@ public class MethodCallStatementExpression extends AbstractType implements IExpr
for (MethodDecl methodDecl : methodDecls) { for (MethodDecl methodDecl : methodDecls) {
if (methodDecl.name.equals(methodName)) { if (methodDecl.name.equals(methodName)) {
//Get the method descriptor //Get the method descriptor
// descriptor = methodDecl.getMethodDescriptor(methodContext); //descriptor = methodDecl.getMethodDescriptor(methodContext);
} }
} }
// mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, classThatHasTheMethodIfNotThis.name, methodName, descriptor, false); //mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, classThatHasTheMethodIfNotThis.name, methodName, descriptor, false);
} else { } else {
// Load this onto the stack // Load this onto the stack
@ -82,7 +76,7 @@ public class MethodCallStatementExpression extends AbstractType implements IExpr
} }
for (IExpression argument : arguments) { for (IExpression argument : arguments) {
argument.codeGen(mv, typeContext, localVars); argument.codeGen(mv, localVars, typeContext);
} }
// Get the method descriptor // Get the method descriptor
@ -91,9 +85,9 @@ public class MethodCallStatementExpression extends AbstractType implements IExpr
for (MethodDecl methodDecl : methodDecls) { for (MethodDecl methodDecl : methodDecls) {
if (methodDecl.name.equals(methodName)) { if (methodDecl.name.equals(methodName)) {
//Get the method descriptor //Get the method descriptor
// descriptor = methodDecl.getMethodDescriptor(methodContext); //descriptor = methodDecl.getMethodDescriptor(methodContext);
} }
} }
// mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, thisClass.name, methodName, descriptor, false); //mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, thisClass.name, methodName, descriptor, false);
} }
} }

View File

@ -5,6 +5,8 @@ import abstractSyntaxTree.Class.MethodDecl;
import abstractSyntaxTree.Class.RefType; import abstractSyntaxTree.Class.RefType;
import abstractSyntaxTree.Expression.BinaryExpression; import abstractSyntaxTree.Expression.BinaryExpression;
import abstractSyntaxTree.Expression.IExpression; import abstractSyntaxTree.Expression.IExpression;
import abstractSyntaxTree.Expression.IntConstantExpression;
import abstractSyntaxTree.Expression.LocalVarIdentifier;
import abstractSyntaxTree.Node; import abstractSyntaxTree.Node;
import abstractSyntaxTree.Parameter.Parameter; import abstractSyntaxTree.Parameter.Parameter;
import abstractSyntaxTree.Parameter.ParameterList; import abstractSyntaxTree.Parameter.ParameterList;
@ -132,12 +134,12 @@ public class ASTGenerator extends DecafBaseVisitor<Node> {
@Override @Override
public Node visitIfElseStmt(DecafParser.IfElseStmtContext ctx) { public Node visitIfElseStmt(DecafParser.IfElseStmtContext ctx) {
if (ctx.elseStmt() != null) { if (ctx.elseStmt() != null) {
return visitIfStmt(ctx.ifStmt());
} else {
Node expression = visitExpression(ctx.ifStmt().expression()); Node expression = visitExpression(ctx.ifStmt().expression());
Node ifStatement = visitStatement(ctx.ifStmt().statement()); Node ifStatement = visitStatement(ctx.ifStmt().statement());
Node elseStatement = visitStatement(ctx.elseStmt().statement()); Node elseStatement = visitStatement(ctx.elseStmt().statement());
return new IfElseStatement((IExpression) expression, (IStatement) ifStatement, (IStatement) elseStatement); return new IfElseStatement((IExpression) expression, (IStatement) ifStatement, (IStatement) elseStatement);
} else {
return visitIfStmt(ctx.ifStmt());
} }
} }
@ -190,7 +192,7 @@ public class ASTGenerator extends DecafBaseVisitor<Node> {
@Override @Override
public Node visitExpression(DecafParser.ExpressionContext ctx) { public Node visitExpression(DecafParser.ExpressionContext ctx) {
if (ctx.subExpression() != null) { if (ctx.subExpression() != null) {
return visitSubExpression(ctx.subExpression());
} else if (ctx.binaryExpr() != null) { } else if (ctx.binaryExpr() != null) {
return visitBinaryExpr(ctx.binaryExpr()); return visitBinaryExpr(ctx.binaryExpr());
} }
@ -238,7 +240,15 @@ public class ASTGenerator extends DecafBaseVisitor<Node> {
//todo //todo
@Override @Override
public Node visitDotSubExpr(DecafParser.DotSubExprContext ctx) { public Node visitDotSubExpr(DecafParser.DotSubExprContext ctx) {
return super.visitDotSubExpr(ctx); // if (ctx.IntValue() != null) {
// int value = Integer.parseInt(ctx.IntValue().getText());
// return new IntConstantExpression(value);
// }
if(ctx.Identifier() != null) {
String identifier = ctx.Identifier().getText();
return new LocalVarIdentifier(identifier);
}
return null;
} }
@Override @Override
@ -256,8 +266,20 @@ public class ASTGenerator extends DecafBaseVisitor<Node> {
@Override @Override
public Node visitSubExpression(DecafParser.SubExpressionContext ctx) { public Node visitSubExpression(DecafParser.SubExpressionContext ctx) {
if (ctx.subExpression() != null) { if (ctx.assignableExpr() != null) {
visitSubExpression(ctx.subExpression()); return visitAssignableExpr(ctx.assignableExpr());
} else if (ctx.stmtExpr() != null) {
return visitStmtExpr(ctx.stmtExpr());
} else if (ctx.subExpression() != null) {
return visitSubExpression(ctx.subExpression());
}
return null;
}
@Override
public Node visitAssignableExpr(DecafParser.AssignableExprContext ctx) {
if (ctx.Identifier() != null) {
return new LocalVarIdentifier(ctx.Identifier().getText());
} }
return null; return null;
} }