Merge remote-tracking branch 'origin/master'

This commit is contained in:
Krauß, Josefine 2024-06-25 08:16:47 +02:00
commit 7daece9b8f
12 changed files with 63 additions and 48 deletions

View File

@ -28,7 +28,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/InputTest.java");
// todo remove this debug info

View File

@ -24,7 +24,7 @@ public class TypeCheckHelper {
}
public static boolean typeExists(String type, List<String> customTypeslist) {
if(type.equals("int") || type.equals("bool") || type.equals("char")){
if(type.equals("int") || type.equals("boolean") || type.equals("char")){
return true;
}
return customTypeslist.contains(type);

View File

@ -125,7 +125,7 @@ public class MethodDecl implements Node {
for (Parameter param : parameters.parameterList) {
switch (param.type) {
case "int" -> descriptor.append("I");
case "bool" -> descriptor.append("Z");
case "boolean" -> descriptor.append("Z");
case "char" -> descriptor.append("C");
case "void" -> descriptor.append("V");
default -> {
@ -144,11 +144,12 @@ public class MethodDecl implements Node {
} else {
switch (returnType) {
case "int" -> descriptor.append("I");
case "bool" -> descriptor.append("Z");
case "boolean" -> descriptor.append("Z");
case "char" -> descriptor.append("C");
case "void" -> descriptor.append("V");
default -> {
// object
// methodContext (class, (returnType, (identifier, parameter)))
HashMap<String, HashMap<String, ParameterList>> classMethods = methodContext.get(classThatContainsMethod);
HashMap<String, ParameterList> methodDetails = classMethods.get(name);

View File

@ -5,6 +5,7 @@ import TypeCheck.TypeCheckException;
import TypeCheck.TypeCheckResult;
import abstractSyntaxTree.Parameter.ParameterList;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import java.util.HashMap;
import java.util.LinkedHashMap;
@ -26,7 +27,11 @@ public class BooleanConstantExpression extends AbstractType implements IExpressi
@Override
public void codeGen(MethodVisitor mv, LinkedHashMap<String, String> localVars, HashMap<String, HashMap<String, String>> typeContext) throws Exception {
if (value){
mv.visitInsn(Opcodes.ICONST_1);
} else {
mv.visitInsn(Opcodes.ICONST_0);
}
}
@Override
public TypeCheckResult getTypeCheckResult() {

View File

@ -4,6 +4,7 @@ import TypeCheck.AbstractType;
import TypeCheck.TypeCheckResult;
import abstractSyntaxTree.Parameter.ParameterList;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import java.util.HashMap;
import java.util.LinkedHashMap;
@ -25,7 +26,7 @@ public class CharConstantExpression extends AbstractType implements IExpression{
@Override
public void codeGen(MethodVisitor mv, LinkedHashMap<String, String> localVars, HashMap<String, HashMap<String, String>> typeContext) throws Exception {
mv.visitIntInsn(Opcodes.BIPUSH, (int) value);
}
@Override

View File

@ -4,6 +4,7 @@ import TypeCheck.AbstractType;
import TypeCheck.TypeCheckResult;
import abstractSyntaxTree.Parameter.ParameterList;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import java.util.HashMap;
import java.util.LinkedHashMap;
@ -27,7 +28,8 @@ public class IntConstantExpression extends AbstractType implements IExpression{
@Override
public void codeGen(MethodVisitor mv, LinkedHashMap<String, String> localVars, HashMap<String, HashMap<String, String>> typeContext) throws Exception {
//TODO: When we are finished this can be done more efficiently
mv.visitLdcInsn(value);
}
@Override

View File

@ -45,12 +45,12 @@ public class LocalVarIdentifier extends AbstractType implements IExpression{
throw new Exception("Variable " + identifier + " not declared");
}
// Load the variable onto the stack
// Find the index of the variable
int index = -1;
int counter = 0;
for (String key : localVars.keySet()){
if (key.equals(identifier)){
index = counter;
index = counter+1; // +1 because the first local variable is at index 1, 0 is used for "this"
break;
}
counter++;
@ -65,7 +65,7 @@ public class LocalVarIdentifier extends AbstractType implements IExpression{
case "int":
mv.visitVarInsn(Opcodes.ILOAD, index);
break;
case "bool":
case "boolean":
mv.visitVarInsn(Opcodes.ILOAD, index);
break;
case "void":

View File

@ -43,15 +43,16 @@ public class LocalVarDecl extends AbstractType implements IStatement{
public void codeGen(MethodVisitor mv, LinkedHashMap<String, String> localVars, HashMap<String, HashMap<String, String>> typeContext) throws Exception {
localVars.put(identifier, type);
// Set a default value for the variable --> less problems
int index = localVars.size()-1;
// 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 "bool":
case "boolean":
mv.visitInsn(Opcodes.ICONST_0);
mv.visitVarInsn(Opcodes.ISTORE, index);
break;

View File

@ -50,7 +50,6 @@ public class ReturnStatement extends AbstractType implements IStatement{
mv.visitInsn(Opcodes.IRETURN);
} else {
mv.visitInsn(Opcodes.ARETURN);
}
} else {
mv.visitInsn(Opcodes.RETURN);

View File

@ -46,7 +46,7 @@ public class AssignStatementExpression extends AbstractType implements IExpressi
String upperbound = TypeCheckHelper.upperBound(leftType.type, rightType.type);
if(Objects.equals(leftType.type, "boolean"))
leftType.type = "bool";
leftType.type = "boolean";
if (!Objects.equals(upperbound, leftType.type)) {
throw new TypeCheckException("The upper bound of assignment is not the left type.");
}
@ -77,7 +77,7 @@ public class AssignStatementExpression extends AbstractType implements IExpressi
int counter = 0;
for (String key : localVars.keySet()) {
if (key.equals(varName)) {
index = counter;
index = counter+1;
break;
}
counter++;
@ -89,8 +89,7 @@ public class AssignStatementExpression extends AbstractType implements IExpressi
String type = localVars.get(localVar.getIdentifier());
switch (type) {
case "int":
case "bool":
case "int", "char", "boolean":
mv.visitVarInsn(Opcodes.ISTORE, index);
break;
default:
@ -116,7 +115,7 @@ public class AssignStatementExpression extends AbstractType implements IExpressi
case "int":
descriptor.append("I");
break;
case "bool":
case "boolean":
descriptor.append("Z");
break;
default:

View File

@ -65,41 +65,45 @@ public class MethodCallStatementExpression extends AbstractType implements IExpr
@Override
public void codeGen(MethodVisitor mv, LinkedHashMap<String, String> localVars, HashMap<String, HashMap<String, String>> typeContext) throws Exception {
//Generate Bytecode for the receiver
if (classThatHasTheMethodIfNotThis != null) {
//TODO: classThatHasTheMethodIfNotThis must be an object --> instance of the class not the class itself
// This is not finished
// Need to call codeGen so it pushes the instance onto the stack, which will be popped of
//classThatHasTheMethodIfNotThis.codeGen();
String descriptor;
List<MethodDecl> methodDecls = thisClass.methodDecls;
for (MethodDecl methodDecl : methodDecls) {
if (methodDecl.name.equals(methodName)) {
//Get the method descriptor
// descriptor = methodDecl.getMethodDescriptor(methodContext);
}
}
// mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, classThatHasTheMethodIfNotThis.name, methodName, descriptor, false);
} else {
// Load this onto the stack
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);
}
// Get the method descriptor
String descriptor;
List<MethodDecl> methodDecls = thisClass.methodDecls;
for (MethodDecl methodDecl : methodDecls) {
if (methodDecl.name.equals(methodName)) {
//Get the method descriptor
//descriptor = methodDecl.getMethodDescriptor(methodContext);
//descriptor = methodDecl.getMethodDescriptor(methodContext); //methodContext is missing
}
}
// mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, thisClass.name, methodName, descriptor, false);
}
// Invoke the method
String className = classThatHasTheMethodIfNotThis != null ? classThatHasTheMethodIfNotThis.name : thisClass.name;
//mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, className, methodName, descriptor, false);
}
@Override

View File

@ -53,6 +53,9 @@ public class NewStatementExpression extends AbstractType implements IExpression,
//Call the constructor
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, className, "<init>", descriptor, false);
// One instance of the class remains now on the stack
// Which will then be used in an assignment or method call
}
private String getConstructorDescriptor() {
@ -66,7 +69,7 @@ public class NewStatementExpression extends AbstractType implements IExpression,
case "int":
descriptor.append("I");
break;
case "bool":
case "boolean":
descriptor.append("Z");
break;
case "char":