Added MethodContext to MethodCallStatementExpression
This commit is contained in:
parent
ed2f64eff9
commit
d8602ddd18
@ -18,7 +18,7 @@ public class Compiler {
|
|||||||
|
|
||||||
public static void main(String[] args) throws Exception{
|
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
|
// todo remove this debug info
|
||||||
|
@ -84,7 +84,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, typeContext);
|
codeBlock.codeGen(mv, localVars, typeContext, methodContext);
|
||||||
mv.visitInsn(Opcodes.RETURN);
|
mv.visitInsn(Opcodes.RETURN);
|
||||||
|
|
||||||
//automatically computed max stack and max locals
|
//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);
|
MethodVisitor mv = cw.visitMethod(access, name, "([Ljava/lang/String;)V", null, null);
|
||||||
|
|
||||||
mv.visitCode();
|
mv.visitCode();
|
||||||
codeBlock.codeGen(mv, localVars, typeContext);
|
codeBlock.codeGen(mv, localVars, typeContext, methodContext);
|
||||||
mv.visitInsn(Opcodes.RETURN);
|
mv.visitInsn(Opcodes.RETURN);
|
||||||
|
|
||||||
mv.visitMaxs(0, 0);
|
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);
|
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, name, getMethodDescriptor(methodContext), null, null);
|
||||||
|
|
||||||
mv.visitCode();
|
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
|
// 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
|
||||||
|
@ -67,7 +67,7 @@ public class BinaryExpression extends AbstractType implements IExpression{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
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, HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext) 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, localVars, typeContext);
|
left.codeGen(mv, localVars, typeContext, methodContext);
|
||||||
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, 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.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, 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
|
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);
|
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, localVars, typeContext);
|
left.codeGen(mv, localVars, typeContext, methodContext);
|
||||||
right.codeGen(mv, localVars, typeContext);
|
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
|
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, localVars, typeContext);
|
left.codeGen(mv, localVars, typeContext, methodContext);
|
||||||
right.codeGen(mv, localVars, typeContext);
|
right.codeGen(mv, localVars, typeContext, methodContext);
|
||||||
|
|
||||||
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, localVars, typeContext);
|
left.codeGen(mv, localVars, typeContext, methodContext);
|
||||||
right.codeGen(mv, localVars, typeContext);
|
right.codeGen(mv, localVars, typeContext, methodContext);
|
||||||
|
|
||||||
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, localVars, typeContext);
|
left.codeGen(mv, localVars, typeContext, methodContext);
|
||||||
right.codeGen(mv, localVars, typeContext);
|
right.codeGen(mv, localVars, typeContext, methodContext);
|
||||||
|
|
||||||
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, localVars, typeContext);
|
left.codeGen(mv, localVars, typeContext, methodContext);
|
||||||
right.codeGen(mv, localVars, typeContext);
|
right.codeGen(mv, localVars, typeContext, methodContext);
|
||||||
|
|
||||||
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, localVars, typeContext);
|
left.codeGen(mv, localVars, typeContext, methodContext);
|
||||||
right.codeGen(mv, localVars, typeContext);
|
right.codeGen(mv, localVars, typeContext, methodContext);
|
||||||
|
|
||||||
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, localVars, typeContext);
|
left.codeGen(mv, localVars, typeContext, methodContext);
|
||||||
right.codeGen(mv, localVars, typeContext);
|
right.codeGen(mv, localVars, typeContext, methodContext);
|
||||||
mv.visitInsn(Opcodes.IADD);
|
mv.visitInsn(Opcodes.IADD);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "-":
|
case "-":
|
||||||
left.codeGen(mv, localVars, typeContext);
|
left.codeGen(mv, localVars, typeContext, methodContext);
|
||||||
right.codeGen(mv, localVars, typeContext);
|
right.codeGen(mv, localVars, typeContext, methodContext);
|
||||||
mv.visitInsn(Opcodes.ISUB);
|
mv.visitInsn(Opcodes.ISUB);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "*":
|
case "*":
|
||||||
left.codeGen(mv, localVars, typeContext);
|
left.codeGen(mv, localVars, typeContext, methodContext);
|
||||||
right.codeGen(mv, localVars, typeContext);
|
right.codeGen(mv, localVars, typeContext, methodContext);
|
||||||
mv.visitInsn(Opcodes.IMUL);
|
mv.visitInsn(Opcodes.IMUL);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "/":
|
case "/":
|
||||||
left.codeGen(mv, localVars, typeContext);
|
left.codeGen(mv, localVars, typeContext, methodContext);
|
||||||
right.codeGen(mv, localVars, typeContext);
|
right.codeGen(mv, localVars, typeContext, methodContext);
|
||||||
mv.visitInsn(Opcodes.IDIV);
|
mv.visitInsn(Opcodes.IDIV);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ public class BooleanConstantExpression extends AbstractType implements IExpressi
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
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, HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext) throws Exception {
|
||||||
if (value){
|
if (value){
|
||||||
mv.visitInsn(Opcodes.ICONST_1);
|
mv.visitInsn(Opcodes.ICONST_1);
|
||||||
} else {
|
} else {
|
||||||
|
@ -25,7 +25,7 @@ public class CharConstantExpression extends AbstractType implements IExpression{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
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, HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext) throws Exception {
|
||||||
mv.visitIntInsn(Opcodes.BIPUSH, (int) value);
|
mv.visitIntInsn(Opcodes.BIPUSH, (int) value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ 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 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
|
// visit method for code generation
|
||||||
void codeGen(MethodVisitor mv, LinkedHashMap<String, String> localVars, HashMap<String, HashMap<String, String>> typeContext) 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();
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ public class InstVarExpression extends AbstractType implements IExpression{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
// typeContext: (ClassName, (FieldName, FieldType))
|
// typeContext: (ClassName, (FieldName, FieldType))
|
||||||
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, HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext) throws Exception {
|
||||||
// Load "this" onto the stack
|
// Load "this" onto the stack
|
||||||
mv.visitVarInsn(Opcodes.ALOAD, 0);
|
mv.visitVarInsn(Opcodes.ALOAD, 0);
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ public class IntConstantExpression extends AbstractType implements IExpression{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
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, HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext) throws Exception {
|
||||||
//TODO: When we are finished this can be done more efficiently
|
//TODO: When we are finished this can be done more efficiently
|
||||||
mv.visitLdcInsn(value);
|
mv.visitLdcInsn(value);
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@ public class LocalVarIdentifier extends AbstractType implements IExpression{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
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, HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext) 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){
|
||||||
|
@ -51,7 +51,7 @@ public class UnaryExpression extends AbstractType implements IExpression{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
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, HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext) throws Exception {
|
||||||
|
|
||||||
operand.codeGen(mv);
|
operand.codeGen(mv);
|
||||||
|
|
||||||
|
@ -107,7 +107,7 @@ public class BlockStatement extends AbstractType implements IStatement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
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, HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext) throws Exception {
|
||||||
// Create a new HashMap for the local variables of the block
|
// Create a new HashMap for the local variables of the block
|
||||||
// It has every variable of the parent block
|
// It has every variable of the parent block
|
||||||
// This Map is discarded at the end of the block
|
// This Map is discarded at the end of the block
|
||||||
@ -115,7 +115,7 @@ public class BlockStatement extends AbstractType implements IStatement {
|
|||||||
LinkedHashMap<String, String> blockLocalVars = new LinkedHashMap<>(localVars);
|
LinkedHashMap<String, String> blockLocalVars = new LinkedHashMap<>(localVars);
|
||||||
|
|
||||||
for (IStatement statement : statements) {
|
for (IStatement statement : statements) {
|
||||||
statement.codeGen(mv, blockLocalVars, typeContext);
|
statement.codeGen(mv, blockLocalVars, typeContext, methodContext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ public class EmptyStatement extends AbstractType implements IStatement{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
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, HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext) throws Exception {
|
||||||
//An empty statement does not generate any code
|
//An empty statement does not generate any code
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,6 +14,6 @@ public interface IStatement extends Node {
|
|||||||
|
|
||||||
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;
|
||||||
|
|
||||||
void codeGen(MethodVisitor mv, LinkedHashMap<String, String> localVars, HashMap<String, HashMap<String, String>> typeContext) 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();
|
||||||
}
|
}
|
||||||
|
@ -56,21 +56,21 @@ public class IfElseStatement extends AbstractType implements IStatement{
|
|||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
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, HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext) throws Exception {
|
||||||
|
|
||||||
LinkedHashMap<String, String> blockLocalVars = new LinkedHashMap<>(localVars);
|
LinkedHashMap<String, String> blockLocalVars = new LinkedHashMap<>(localVars);
|
||||||
|
|
||||||
Label conditionFalse = new Label();
|
Label conditionFalse = new Label();
|
||||||
Label statementEnd = 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)
|
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.visitJumpInsn(Opcodes.GOTO, statementEnd); //Jump to the end of the if-else statement
|
||||||
|
|
||||||
mv.visitLabel(conditionFalse);
|
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
|
mv.visitLabel(statementEnd); //End of the if-else statement
|
||||||
|
|
||||||
|
@ -43,16 +43,16 @@ public class IfStatement extends AbstractType implements IStatement{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
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, HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext) throws Exception {
|
||||||
|
|
||||||
LinkedHashMap<String, String> blockLocalVars = new LinkedHashMap<>(localVars);
|
LinkedHashMap<String, String> blockLocalVars = new LinkedHashMap<>(localVars);
|
||||||
|
|
||||||
Label conditionFalse = new Label();
|
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)
|
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
|
mv.visitLabel(conditionFalse); // If the condition is false, the Statements in the ifBlock will not be executed
|
||||||
}
|
}
|
||||||
|
@ -47,27 +47,40 @@ public class LocalVarDecl extends AbstractType implements IStatement{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
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, HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext) throws Exception {
|
||||||
localVars.put(identifier, type);
|
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
|
// Store the result in the local variable
|
||||||
switch (type){
|
switch (type){
|
||||||
case "int":
|
case "int", "char", "boolean":
|
||||||
mv.visitInsn(Opcodes.ICONST_0);
|
mv.visitVarInsn(Opcodes.ISTORE, index);
|
||||||
mv.visitVarInsn(Opcodes.ISTORE, index);
|
break;
|
||||||
break;
|
default:
|
||||||
case "boolean":
|
mv.visitVarInsn(Opcodes.ASTORE, index);
|
||||||
mv.visitInsn(Opcodes.ICONST_0);
|
}
|
||||||
mv.visitVarInsn(Opcodes.ISTORE, index);
|
} else {
|
||||||
break;
|
|
||||||
case "void":
|
// Set a default value for the variable --> less problems
|
||||||
break;
|
switch (type) {
|
||||||
default:
|
case "int":
|
||||||
mv.visitInsn(Opcodes.ACONST_NULL);
|
mv.visitInsn(Opcodes.ICONST_1);
|
||||||
mv.visitVarInsn(Opcodes.ASTORE, index);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
// 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
|
// At this point in time we can either return reference types or have an error message
|
||||||
@Override
|
@Override
|
||||||
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, HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext) throws Exception {
|
||||||
|
|
||||||
if (expression != null) {
|
if (expression != null) {
|
||||||
expression.codeGen(mv, localVars, typeContext);
|
expression.codeGen(mv, localVars, typeContext, methodContext);
|
||||||
//Get the Type of the expression
|
//Get the Type of the expression
|
||||||
//TODO: Resolve how do we get the type of the expression
|
|
||||||
String type = expression.getTypeCheckResult().type;
|
String type = expression.getTypeCheckResult().type;
|
||||||
|
|
||||||
if (type.equals("int") || type.equals("boolean") || type.equals("char")) {
|
if (type.equals("int") || type.equals("boolean") || type.equals("char")) {
|
||||||
|
@ -42,7 +42,7 @@ public class WhileStatement extends AbstractType implements IStatement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
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, HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext) throws Exception {
|
||||||
|
|
||||||
LinkedHashMap<String, String> blockLocalVars = new LinkedHashMap<>(localVars);
|
LinkedHashMap<String, String> blockLocalVars = new LinkedHashMap<>(localVars);
|
||||||
|
|
||||||
@ -51,10 +51,10 @@ public class WhileStatement extends AbstractType implements IStatement {
|
|||||||
|
|
||||||
mv.visitLabel(LoopStart);
|
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)
|
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);
|
//statement.codeGen(mv);
|
||||||
//TODO: If the block ends with a return statement, we might have to pop it from the stack
|
//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
|
// So the next iteration starts with a clean stack
|
||||||
|
@ -66,12 +66,12 @@ public class AssignStatementExpression extends AbstractType implements IExpressi
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
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, HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext) 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, localVars, typeContext);
|
right.codeGen(mv, localVars, typeContext, methodContext);
|
||||||
|
|
||||||
if (left instanceof LocalVarIdentifier) {
|
if (left instanceof LocalVarIdentifier) {
|
||||||
LocalVarIdentifier localVar = (LocalVarIdentifier) left;
|
LocalVarIdentifier localVar = (LocalVarIdentifier) left;
|
||||||
|
@ -80,49 +80,9 @@ public class MethodCallStatementExpression extends AbstractType implements IExpr
|
|||||||
}
|
}
|
||||||
|
|
||||||
//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
|
|
||||||
@Override
|
@Override
|
||||||
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, HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext) 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);
|
|
||||||
|
|
||||||
} 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<MethodDecl> 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
|
@Override
|
||||||
|
@ -39,7 +39,7 @@ public class NewStatementExpression extends AbstractType implements IExpression,
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
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, HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext) throws Exception {
|
||||||
//Create new instance of the class
|
//Create new instance of the class
|
||||||
mv.visitTypeInsn(Opcodes.NEW, className);
|
mv.visitTypeInsn(Opcodes.NEW, className);
|
||||||
|
|
||||||
@ -47,7 +47,7 @@ public class NewStatementExpression extends AbstractType implements IExpression,
|
|||||||
mv.visitInsn(Opcodes.DUP);
|
mv.visitInsn(Opcodes.DUP);
|
||||||
|
|
||||||
for (IExpression argument : arguments) {
|
for (IExpression argument : arguments) {
|
||||||
argument.codeGen(mv, localVars, typeContext);
|
argument.codeGen(mv, localVars, typeContext, methodContext);
|
||||||
}
|
}
|
||||||
String descriptor = getConstructorDescriptor();
|
String descriptor = getConstructorDescriptor();
|
||||||
|
|
||||||
@ -59,7 +59,8 @@ public class NewStatementExpression extends AbstractType implements IExpression,
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String getConstructorDescriptor() {
|
private String getConstructorDescriptor() {
|
||||||
StringBuilder descriptor = new StringBuilder();
|
StringBuilder descriptor = new StringBuilder("(");
|
||||||
|
|
||||||
|
|
||||||
for (IExpression parameter : arguments) {
|
for (IExpression parameter : arguments) {
|
||||||
TypeCheckResult result = parameter.getTypeCheckResult();
|
TypeCheckResult result = parameter.getTypeCheckResult();
|
||||||
|
Loading…
Reference in New Issue
Block a user