diff --git a/src/main/java/Compiler.java b/src/main/java/Compiler.java index fb2f6d9..ea7b0d6 100644 --- a/src/main/java/Compiler.java +++ b/src/main/java/Compiler.java @@ -18,7 +18,7 @@ public class Compiler { public static void main(String[] args) throws Exception{ - Path filePath = Paths.get("src/main/java/Input.java"); + Path filePath = Paths.get("src/main/java/TestInput.java"); // todo remove this debug info diff --git a/src/main/java/abstractSyntaxTree/Class/MethodDecl.java b/src/main/java/abstractSyntaxTree/Class/MethodDecl.java index 6d31059..c59353f 100644 --- a/src/main/java/abstractSyntaxTree/Class/MethodDecl.java +++ b/src/main/java/abstractSyntaxTree/Class/MethodDecl.java @@ -84,7 +84,7 @@ public class MethodDecl implements Node { mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "", descriptor, false); mv.visitCode(); - codeBlock.codeGen(mv, localVars, typeContext); + codeBlock.codeGen(mv, localVars, typeContext, methodContext); mv.visitInsn(Opcodes.RETURN); //automatically computed max stack and max locals @@ -96,7 +96,7 @@ public class MethodDecl implements Node { MethodVisitor mv = cw.visitMethod(access, name, "([Ljava/lang/String;)V", null, null); mv.visitCode(); - codeBlock.codeGen(mv, localVars, typeContext); + codeBlock.codeGen(mv, localVars, typeContext, methodContext); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(0, 0); @@ -106,7 +106,7 @@ public class MethodDecl implements Node { MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, name, getMethodDescriptor(methodContext), null, null); mv.visitCode(); - codeBlock.codeGen(mv, localVars, typeContext); + codeBlock.codeGen(mv, localVars, typeContext, methodContext); // 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 diff --git a/src/main/java/abstractSyntaxTree/Expression/BinaryExpression.java b/src/main/java/abstractSyntaxTree/Expression/BinaryExpression.java index d2b4713..5086324 100644 --- a/src/main/java/abstractSyntaxTree/Expression/BinaryExpression.java +++ b/src/main/java/abstractSyntaxTree/Expression/BinaryExpression.java @@ -67,7 +67,7 @@ public class BinaryExpression extends AbstractType implements IExpression{ } @Override - public void codeGen(MethodVisitor mv, LinkedHashMap localVars, HashMap> typeContext) throws Exception { + public void codeGen(MethodVisitor mv, LinkedHashMap localVars, HashMap> typeContext, HashMap>> methodContext) throws Exception { // Label for the jump instruction Label operationFalse = new Label(); //Operation is false Label operationTrue = new Label(); //Operation is true @@ -77,88 +77,88 @@ public class BinaryExpression extends AbstractType implements IExpression{ // Bytecode for the binary operation switch (operator) { case "&&": - left.codeGen(mv, localVars, typeContext); + left.codeGen(mv, localVars, typeContext, methodContext); mv.visitJumpInsn(Opcodes.IFEQ, operationFalse); // IFEQ --> "if equals to zero" (false) --> if left exp is false - right.codeGen(mv, localVars, typeContext); + right.codeGen(mv, localVars, typeContext, methodContext); 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 break; case "||": - left.codeGen(mv, localVars, typeContext); + left.codeGen(mv, localVars, typeContext, methodContext); mv.visitJumpInsn(Opcodes.IFNE, operationTrue); // IFNE --> "if not equals to zero" (true) --> if left exp is true - right.codeGen(mv, localVars, typeContext); + right.codeGen(mv, localVars, typeContext, methodContext); mv.visitJumpInsn(Opcodes.IFNE, operationTrue); break; case "==": // Keep in mind that only primitive types are allowed in this case (at this time) - left.codeGen(mv, localVars, typeContext); - right.codeGen(mv, localVars, typeContext); + left.codeGen(mv, localVars, typeContext, methodContext); + right.codeGen(mv, localVars, typeContext, methodContext); mv.visitJumpInsn(Opcodes.IF_ICMPEQ, operationTrue); // If the two values are equal, jump to the end of the expression break; case "<": - left.codeGen(mv, localVars, typeContext); - right.codeGen(mv, localVars, typeContext); + left.codeGen(mv, localVars, typeContext, methodContext); + right.codeGen(mv, localVars, typeContext, methodContext); mv.visitJumpInsn(Opcodes.IF_ICMPLT, operationTrue); // Checks only on less than, not equal break; case ">": - left.codeGen(mv, localVars, typeContext); - right.codeGen(mv, localVars, typeContext); + left.codeGen(mv, localVars, typeContext, methodContext); + right.codeGen(mv, localVars, typeContext, methodContext); mv.visitJumpInsn(Opcodes.IF_ICMPGT, operationTrue); // Checks only on greater than, not equal break; case "<=": - left.codeGen(mv, localVars, typeContext); - right.codeGen(mv, localVars, typeContext); + left.codeGen(mv, localVars, typeContext, methodContext); + right.codeGen(mv, localVars, typeContext, methodContext); mv.visitJumpInsn(Opcodes.IF_ICMPLE, operationTrue); // Checks on less than OR equal break; case ">=": - left.codeGen(mv, localVars, typeContext); - right.codeGen(mv, localVars, typeContext); + left.codeGen(mv, localVars, typeContext, methodContext); + right.codeGen(mv, localVars, typeContext, methodContext); mv.visitJumpInsn(Opcodes.IF_ICMPGE, operationTrue); // Checks on greater than OR equal break; case "!=": - left.codeGen(mv, localVars, typeContext); - right.codeGen(mv, localVars, typeContext); + left.codeGen(mv, localVars, typeContext, methodContext); + right.codeGen(mv, localVars, typeContext, methodContext); mv.visitJumpInsn(Opcodes.IF_ICMPNE, operationTrue); // Checks on not equal break; case "+": - left.codeGen(mv, localVars, typeContext); - right.codeGen(mv, localVars, typeContext); + left.codeGen(mv, localVars, typeContext, methodContext); + right.codeGen(mv, localVars, typeContext, methodContext); mv.visitInsn(Opcodes.IADD); break; case "-": - left.codeGen(mv, localVars, typeContext); - right.codeGen(mv, localVars, typeContext); + left.codeGen(mv, localVars, typeContext, methodContext); + right.codeGen(mv, localVars, typeContext, methodContext); mv.visitInsn(Opcodes.ISUB); break; case "*": - left.codeGen(mv, localVars, typeContext); - right.codeGen(mv, localVars, typeContext); + left.codeGen(mv, localVars, typeContext, methodContext); + right.codeGen(mv, localVars, typeContext, methodContext); mv.visitInsn(Opcodes.IMUL); break; case "/": - left.codeGen(mv, localVars, typeContext); - right.codeGen(mv, localVars, typeContext); + left.codeGen(mv, localVars, typeContext, methodContext); + right.codeGen(mv, localVars, typeContext, methodContext); mv.visitInsn(Opcodes.IDIV); break; diff --git a/src/main/java/abstractSyntaxTree/Expression/BooleanConstantExpression.java b/src/main/java/abstractSyntaxTree/Expression/BooleanConstantExpression.java index da0e925..1400bd2 100644 --- a/src/main/java/abstractSyntaxTree/Expression/BooleanConstantExpression.java +++ b/src/main/java/abstractSyntaxTree/Expression/BooleanConstantExpression.java @@ -26,7 +26,7 @@ public class BooleanConstantExpression extends AbstractType implements IExpressi } @Override - public void codeGen(MethodVisitor mv, LinkedHashMap localVars, HashMap> typeContext) throws Exception { + public void codeGen(MethodVisitor mv, LinkedHashMap localVars, HashMap> typeContext, HashMap>> methodContext) throws Exception { if (value){ mv.visitInsn(Opcodes.ICONST_1); } else { diff --git a/src/main/java/abstractSyntaxTree/Expression/CharConstantExpression.java b/src/main/java/abstractSyntaxTree/Expression/CharConstantExpression.java index 1485cd5..00df59e 100644 --- a/src/main/java/abstractSyntaxTree/Expression/CharConstantExpression.java +++ b/src/main/java/abstractSyntaxTree/Expression/CharConstantExpression.java @@ -25,7 +25,7 @@ public class CharConstantExpression extends AbstractType implements IExpression{ } @Override - public void codeGen(MethodVisitor mv, LinkedHashMap localVars, HashMap> typeContext) throws Exception { + public void codeGen(MethodVisitor mv, LinkedHashMap localVars, HashMap> typeContext, HashMap>> methodContext) throws Exception { mv.visitIntInsn(Opcodes.BIPUSH, (int) value); } diff --git a/src/main/java/abstractSyntaxTree/Expression/IExpression.java b/src/main/java/abstractSyntaxTree/Expression/IExpression.java index 958a6de..0d51b32 100644 --- a/src/main/java/abstractSyntaxTree/Expression/IExpression.java +++ b/src/main/java/abstractSyntaxTree/Expression/IExpression.java @@ -15,7 +15,7 @@ public interface IExpression extends Node { TypeCheckResult typeCheck(HashMap>> methodContext, HashMap> typeContext, HashMap localVars) throws TypeCheckException; // visit method for code generation - void codeGen(MethodVisitor mv, LinkedHashMap localVars, HashMap> typeContext) throws Exception; + void codeGen(MethodVisitor mv, LinkedHashMap localVars, HashMap> typeContext, HashMap>> methodContext) throws Exception; TypeCheckResult getTypeCheckResult(); } diff --git a/src/main/java/abstractSyntaxTree/Expression/InstVarExpression.java b/src/main/java/abstractSyntaxTree/Expression/InstVarExpression.java index eefab82..ee15a8c 100644 --- a/src/main/java/abstractSyntaxTree/Expression/InstVarExpression.java +++ b/src/main/java/abstractSyntaxTree/Expression/InstVarExpression.java @@ -42,7 +42,7 @@ public class InstVarExpression extends AbstractType implements IExpression{ @Override // typeContext: (ClassName, (FieldName, FieldType)) - public void codeGen(MethodVisitor mv, LinkedHashMap localVars, HashMap> typeContext) throws Exception { + public void codeGen(MethodVisitor mv, LinkedHashMap localVars, HashMap> typeContext, HashMap>> methodContext) throws Exception { // Load "this" onto the stack mv.visitVarInsn(Opcodes.ALOAD, 0); diff --git a/src/main/java/abstractSyntaxTree/Expression/IntConstantExpression.java b/src/main/java/abstractSyntaxTree/Expression/IntConstantExpression.java index fd1fb24..e3a689b 100644 --- a/src/main/java/abstractSyntaxTree/Expression/IntConstantExpression.java +++ b/src/main/java/abstractSyntaxTree/Expression/IntConstantExpression.java @@ -27,7 +27,7 @@ public class IntConstantExpression extends AbstractType implements IExpression{ } @Override - public void codeGen(MethodVisitor mv, LinkedHashMap localVars, HashMap> typeContext) throws Exception { + public void codeGen(MethodVisitor mv, LinkedHashMap localVars, HashMap> typeContext, HashMap>> methodContext) throws Exception { //TODO: When we are finished this can be done more efficiently mv.visitLdcInsn(value); } diff --git a/src/main/java/abstractSyntaxTree/Expression/LocalVarIdentifier.java b/src/main/java/abstractSyntaxTree/Expression/LocalVarIdentifier.java index aa8345e..24827e7 100644 --- a/src/main/java/abstractSyntaxTree/Expression/LocalVarIdentifier.java +++ b/src/main/java/abstractSyntaxTree/Expression/LocalVarIdentifier.java @@ -38,7 +38,7 @@ public class LocalVarIdentifier extends AbstractType implements IExpression{ } @Override - public void codeGen(MethodVisitor mv, LinkedHashMap localVars, HashMap> typeContext) throws Exception { + public void codeGen(MethodVisitor mv, LinkedHashMap localVars, HashMap> typeContext, HashMap>> methodContext) throws Exception { // Check if the variable is in the list of local variables String type = localVars.get(identifier); if (type == null){ diff --git a/src/main/java/abstractSyntaxTree/Expression/UnaryExpression.java b/src/main/java/abstractSyntaxTree/Expression/UnaryExpression.java index 4a2243c..3cf0406 100644 --- a/src/main/java/abstractSyntaxTree/Expression/UnaryExpression.java +++ b/src/main/java/abstractSyntaxTree/Expression/UnaryExpression.java @@ -51,7 +51,7 @@ public class UnaryExpression extends AbstractType implements IExpression{ } @Override - public void codeGen(MethodVisitor mv, LinkedHashMap localVars, HashMap> typeContext) throws Exception { + public void codeGen(MethodVisitor mv, LinkedHashMap localVars, HashMap> typeContext, HashMap>> methodContext) throws Exception { operand.codeGen(mv); diff --git a/src/main/java/abstractSyntaxTree/Statement/BlockStatement.java b/src/main/java/abstractSyntaxTree/Statement/BlockStatement.java index b0f0e48..477cbfa 100644 --- a/src/main/java/abstractSyntaxTree/Statement/BlockStatement.java +++ b/src/main/java/abstractSyntaxTree/Statement/BlockStatement.java @@ -107,7 +107,7 @@ public class BlockStatement extends AbstractType implements IStatement { } @Override - public void codeGen(MethodVisitor mv, LinkedHashMap localVars, HashMap> typeContext) throws Exception { + public void codeGen(MethodVisitor mv, LinkedHashMap localVars, HashMap> typeContext, HashMap>> methodContext) throws Exception { // Create a new HashMap for the local variables of the block // It has every variable of the parent block // This Map is discarded at the end of the block @@ -115,7 +115,7 @@ public class BlockStatement extends AbstractType implements IStatement { LinkedHashMap blockLocalVars = new LinkedHashMap<>(localVars); for (IStatement statement : statements) { - statement.codeGen(mv, blockLocalVars, typeContext); + statement.codeGen(mv, blockLocalVars, typeContext, methodContext); } } diff --git a/src/main/java/abstractSyntaxTree/Statement/EmptyStatement.java b/src/main/java/abstractSyntaxTree/Statement/EmptyStatement.java index 5a91eef..021ac6f 100644 --- a/src/main/java/abstractSyntaxTree/Statement/EmptyStatement.java +++ b/src/main/java/abstractSyntaxTree/Statement/EmptyStatement.java @@ -20,7 +20,7 @@ public class EmptyStatement extends AbstractType implements IStatement{ } @Override - public void codeGen(MethodVisitor mv, LinkedHashMap localVars, HashMap> typeContext) throws Exception { + public void codeGen(MethodVisitor mv, LinkedHashMap localVars, HashMap> typeContext, HashMap>> methodContext) throws Exception { //An empty statement does not generate any code } diff --git a/src/main/java/abstractSyntaxTree/Statement/IStatement.java b/src/main/java/abstractSyntaxTree/Statement/IStatement.java index a270b60..cbc0a76 100644 --- a/src/main/java/abstractSyntaxTree/Statement/IStatement.java +++ b/src/main/java/abstractSyntaxTree/Statement/IStatement.java @@ -14,6 +14,6 @@ public interface IStatement extends Node { TypeCheckResult typeCheck(HashMap>> methodContext, HashMap> typeContext, HashMap localVars) throws TypeCheckException; - void codeGen(MethodVisitor mv, LinkedHashMap localVars, HashMap> typeContext) throws Exception; + void codeGen(MethodVisitor mv, LinkedHashMap localVars, HashMap> typeContext, HashMap>> methodContext) throws Exception; TypeCheckResult getTypeCheckResult(); } diff --git a/src/main/java/abstractSyntaxTree/Statement/IfElseStatement.java b/src/main/java/abstractSyntaxTree/Statement/IfElseStatement.java index af055c4..d380fae 100644 --- a/src/main/java/abstractSyntaxTree/Statement/IfElseStatement.java +++ b/src/main/java/abstractSyntaxTree/Statement/IfElseStatement.java @@ -56,21 +56,21 @@ public class IfElseStatement extends AbstractType implements IStatement{ @Override - public void codeGen(MethodVisitor mv, LinkedHashMap localVars, HashMap> typeContext) throws Exception { + public void codeGen(MethodVisitor mv, LinkedHashMap localVars, HashMap> typeContext, HashMap>> methodContext) throws Exception { LinkedHashMap blockLocalVars = new LinkedHashMap<>(localVars); Label conditionFalse = new Label(); Label statementEnd = new Label(); - condition.codeGen(mv, localVars, typeContext); + condition.codeGen(mv, localVars, typeContext, methodContext); 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, methodContext); //If the condition is true, execute the ifBlock mv.visitJumpInsn(Opcodes.GOTO, statementEnd); //Jump to the end of the if-else statement mv.visitLabel(conditionFalse); - elseStatement.codeGen(mv, blockLocalVars, typeContext); //If the condition is false, execute the elseBlock + elseStatement.codeGen(mv, blockLocalVars, typeContext, methodContext); //If the condition is false, execute the elseBlock mv.visitLabel(statementEnd); //End of the if-else statement diff --git a/src/main/java/abstractSyntaxTree/Statement/IfStatement.java b/src/main/java/abstractSyntaxTree/Statement/IfStatement.java index 0084276..be39432 100644 --- a/src/main/java/abstractSyntaxTree/Statement/IfStatement.java +++ b/src/main/java/abstractSyntaxTree/Statement/IfStatement.java @@ -43,16 +43,16 @@ public class IfStatement extends AbstractType implements IStatement{ } @Override - public void codeGen(MethodVisitor mv, LinkedHashMap localVars, HashMap> typeContext) throws Exception { + public void codeGen(MethodVisitor mv, LinkedHashMap localVars, HashMap> typeContext, HashMap>> methodContext) throws Exception { LinkedHashMap blockLocalVars = new LinkedHashMap<>(localVars); Label conditionFalse = new Label(); - condition.codeGen(mv, localVars, typeContext); + condition.codeGen(mv, localVars, typeContext, methodContext); mv.visitJumpInsn(Opcodes.IFEQ, conditionFalse); //Checks if the condition is false (0) - ifStatement.codeGen(mv, blockLocalVars, typeContext); + ifStatement.codeGen(mv, blockLocalVars, typeContext, methodContext); mv.visitLabel(conditionFalse); // If the condition is false, the Statements in the ifBlock will not be executed } diff --git a/src/main/java/abstractSyntaxTree/Statement/LocalVarDecl.java b/src/main/java/abstractSyntaxTree/Statement/LocalVarDecl.java index 5fbb3cb..5413556 100644 --- a/src/main/java/abstractSyntaxTree/Statement/LocalVarDecl.java +++ b/src/main/java/abstractSyntaxTree/Statement/LocalVarDecl.java @@ -47,27 +47,40 @@ public class LocalVarDecl extends AbstractType implements IStatement{ } @Override - public void codeGen(MethodVisitor mv, LinkedHashMap localVars, HashMap> typeContext) throws Exception { + public void codeGen(MethodVisitor mv, LinkedHashMap localVars, HashMap> typeContext, HashMap>> methodContext) throws Exception { localVars.put(identifier, type); + int index = localVars.size() - 1; - int index = localVars.size()-1; + if (expression != null) { + expression.codeGen(mv, localVars, typeContext,methodContext); - // Set a default value for the variable --> less problems - switch (type){ - case "int": - mv.visitInsn(Opcodes.ICONST_0); - mv.visitVarInsn(Opcodes.ISTORE, index); - break; - case "boolean": - mv.visitInsn(Opcodes.ICONST_0); - mv.visitVarInsn(Opcodes.ISTORE, index); - break; - case "void": - break; - default: - mv.visitInsn(Opcodes.ACONST_NULL); - mv.visitVarInsn(Opcodes.ASTORE, index); + // Store the result in the local variable + switch (type){ + case "int", "char", "boolean": + mv.visitVarInsn(Opcodes.ISTORE, index); + break; + default: + mv.visitVarInsn(Opcodes.ASTORE, index); + } + } else { + + // Set a default value for the variable --> less problems + switch (type) { + case "int": + mv.visitInsn(Opcodes.ICONST_1); + mv.visitVarInsn(Opcodes.ISTORE, index); + break; + case "boolean": + mv.visitInsn(Opcodes.ICONST_0); + mv.visitVarInsn(Opcodes.ISTORE, index); + break; + case "void": + break; + default: + mv.visitInsn(Opcodes.ACONST_NULL); + mv.visitVarInsn(Opcodes.ASTORE, index); + } } } diff --git a/src/main/java/abstractSyntaxTree/Statement/ReturnStatement.java b/src/main/java/abstractSyntaxTree/Statement/ReturnStatement.java index b9a64e4..c40a370 100644 --- a/src/main/java/abstractSyntaxTree/Statement/ReturnStatement.java +++ b/src/main/java/abstractSyntaxTree/Statement/ReturnStatement.java @@ -38,12 +38,11 @@ public class ReturnStatement extends AbstractType implements IStatement{ // This is a problem at "BinaryExpression" and here because we need to know the type to return // At this point in time we can either return reference types or have an error message @Override - public void codeGen(MethodVisitor mv, LinkedHashMap localVars, HashMap> typeContext) throws Exception { + public void codeGen(MethodVisitor mv, LinkedHashMap localVars, HashMap> typeContext, HashMap>> methodContext) throws Exception { if (expression != null) { - expression.codeGen(mv, localVars, typeContext); + expression.codeGen(mv, localVars, typeContext, methodContext); //Get the Type of the expression - //TODO: Resolve how do we get the type of the expression String type = expression.getTypeCheckResult().type; if (type.equals("int") || type.equals("boolean") || type.equals("char")) { diff --git a/src/main/java/abstractSyntaxTree/Statement/WhileStatement.java b/src/main/java/abstractSyntaxTree/Statement/WhileStatement.java index bf61905..47255ea 100644 --- a/src/main/java/abstractSyntaxTree/Statement/WhileStatement.java +++ b/src/main/java/abstractSyntaxTree/Statement/WhileStatement.java @@ -42,7 +42,7 @@ public class WhileStatement extends AbstractType implements IStatement { } @Override - public void codeGen(MethodVisitor mv, LinkedHashMap localVars, HashMap> typeContext) throws Exception { + public void codeGen(MethodVisitor mv, LinkedHashMap localVars, HashMap> typeContext, HashMap>> methodContext) throws Exception { LinkedHashMap blockLocalVars = new LinkedHashMap<>(localVars); @@ -51,10 +51,10 @@ public class WhileStatement extends AbstractType implements IStatement { mv.visitLabel(LoopStart); - condition.codeGen(mv, localVars, typeContext); + condition.codeGen(mv, localVars, typeContext, methodContext); mv.visitJumpInsn(Opcodes.IFEQ, conditionFalse); // Checks if the condition is false (0) - statement.codeGen(mv, blockLocalVars, typeContext); + statement.codeGen(mv, blockLocalVars, typeContext, methodContext); //statement.codeGen(mv); //TODO: If the block ends with a return statement, we might have to pop it from the stack // So the next iteration starts with a clean stack diff --git a/src/main/java/abstractSyntaxTree/StatementExpression/AssignStatementExpression.java b/src/main/java/abstractSyntaxTree/StatementExpression/AssignStatementExpression.java index 7e6f0a0..0f40fca 100644 --- a/src/main/java/abstractSyntaxTree/StatementExpression/AssignStatementExpression.java +++ b/src/main/java/abstractSyntaxTree/StatementExpression/AssignStatementExpression.java @@ -66,12 +66,12 @@ public class AssignStatementExpression extends AbstractType implements IExpressi } @Override - public void codeGen(MethodVisitor mv, LinkedHashMap localVars, HashMap> typeContext) throws Exception { + public void codeGen(MethodVisitor mv, LinkedHashMap localVars, HashMap> typeContext, HashMap>> methodContext) throws Exception { //TODO: Do we need the value on the stack after assigning it? //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 - right.codeGen(mv, localVars, typeContext); + right.codeGen(mv, localVars, typeContext, methodContext); if (left instanceof LocalVarIdentifier) { LocalVarIdentifier localVar = (LocalVarIdentifier) left; diff --git a/src/main/java/abstractSyntaxTree/StatementExpression/MethodCallStatementExpression.java b/src/main/java/abstractSyntaxTree/StatementExpression/MethodCallStatementExpression.java index 3eab51f..63260de 100644 --- a/src/main/java/abstractSyntaxTree/StatementExpression/MethodCallStatementExpression.java +++ b/src/main/java/abstractSyntaxTree/StatementExpression/MethodCallStatementExpression.java @@ -80,49 +80,9 @@ public class MethodCallStatementExpression extends AbstractType implements IExpr } //Errors occur due to the change in parameter in the RefType class - // I need the methodContext here to get the method descriptor @Override - public void codeGen(MethodVisitor mv, LinkedHashMap localVars, HashMap> typeContext) throws Exception { - //Generate Bytecode for the receiver - if (receiver.thisExpression) { - // If the receiver is "this" then load "this" onto the stack - mv.visitVarInsn(Opcodes.ALOAD, 0); - } else if (receiver.instVarExpression != null) { - receiver.instVarExpression.codeGen(mv, localVars, typeContext); + public void codeGen(MethodVisitor mv, LinkedHashMap localVars, HashMap> typeContext, HashMap>> methodContext) throws Exception { - } else if (receiver.newStatementExpression != null) { - receiver.newStatementExpression.codeGen(mv, localVars, typeContext); - - // Not sure about this part - } else if (receiver.identifier != null) { - // Load local variable onto the stack - for (String key : localVars.keySet()) { - if (key.equals(receiver.identifier)) { - String type = localVars.get(key); - int opcode = type.equals("int") ? Opcodes.ILOAD : Opcodes.ALOAD; - mv.visitVarInsn(opcode, Integer.parseInt(key)); - break; - } - } - } - - // Generate Bytecode for the arguments - for (IExpression argument : arguments) { - argument.codeGen(mv, localVars, typeContext); - } - - - String descriptor; - // List methodDecls = thisClass.methodDecls; -// for (MethodDecl methodDecl : methodDecls) { -// if (methodDecl.name.equals(methodName)) { -// //Get the method descriptor -// //descriptor = methodDecl.getMethodDescriptor(methodContext); //methodContext is missing -// } -// } - // Invoke the method -// String className = classThatHasTheMethodIfNotThis != null ? classThatHasTheMethodIfNotThis.name : thisClass.name; - //mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, className, methodName, descriptor, false); } @Override diff --git a/src/main/java/abstractSyntaxTree/StatementExpression/NewStatementExpression.java b/src/main/java/abstractSyntaxTree/StatementExpression/NewStatementExpression.java index 4188fbd..4b2bc3f 100644 --- a/src/main/java/abstractSyntaxTree/StatementExpression/NewStatementExpression.java +++ b/src/main/java/abstractSyntaxTree/StatementExpression/NewStatementExpression.java @@ -39,7 +39,7 @@ public class NewStatementExpression extends AbstractType implements IExpression, } @Override - public void codeGen(MethodVisitor mv, LinkedHashMap localVars, HashMap> typeContext) throws Exception { + public void codeGen(MethodVisitor mv, LinkedHashMap localVars, HashMap> typeContext, HashMap>> methodContext) throws Exception { //Create new instance of the class mv.visitTypeInsn(Opcodes.NEW, className); @@ -47,7 +47,7 @@ public class NewStatementExpression extends AbstractType implements IExpression, mv.visitInsn(Opcodes.DUP); for (IExpression argument : arguments) { - argument.codeGen(mv, localVars, typeContext); + argument.codeGen(mv, localVars, typeContext, methodContext); } String descriptor = getConstructorDescriptor(); @@ -59,7 +59,8 @@ public class NewStatementExpression extends AbstractType implements IExpression, } private String getConstructorDescriptor() { - StringBuilder descriptor = new StringBuilder(); + StringBuilder descriptor = new StringBuilder("("); + for (IExpression parameter : arguments) { TypeCheckResult result = parameter.getTypeCheckResult();