Merge branch 'master' of https://gitea.hb.dhbw-stuttgart.de/i22022/NichtHaskell
# 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:
commit
ef38079f58
@ -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
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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){
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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();
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
// }
|
// }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user