parameterlist, typecheck

This commit is contained in:
Krauß, Josefine 2024-05-14 15:15:58 +02:00
parent 74e3cb8016
commit a59950e186
14 changed files with 64 additions and 46 deletions

View File

@ -91,6 +91,16 @@ public class Compiler {
// System.out.println(refType.name); // System.out.println(refType.name);
// } // }
abstractSyntaxTree.classes.get(1).methodDecls.get(0).codeBlock.returnType = "int";
List<IStatement> statementsList = abstractSyntaxTree.classes.get(1).methodDecls.get(0).codeBlock.statements;
statementsList.remove(0);
statementsList.add(new LocalVarDecl("int", "localInt"));
statementsList.add(new LocalVarDecl("bool", "localBool"));
statementsList.add(new LocalVarDecl("char", "localChar"));
statementsList.add(new AssignStatementExpression("=", new LocalVarIdentifier("localInt"), new UnaryExpression("", new IntDatatype())));
statementsList.add(new AssignStatementExpression("=", new InstVarExpression(abstractSyntaxTree.classes.get(1), "instVarBool"), new UnaryExpression("instVarBool", new BoolDatatype())));
abstractSyntaxTree.classes.get(1).methodDecls.get(0).codeBlock.statements.add(new ReturnStatement(new UnaryExpression("", new IntDatatype())));
abstractSyntaxTree.typeCheck(); abstractSyntaxTree.typeCheck();
abstractSyntaxTree.codeGen(); abstractSyntaxTree.codeGen();

View File

@ -6,8 +6,6 @@ class Example {
} }
class Example2 { class Example2 {
boolean instVarBool; boolean instVarBool;
void m(int i){ int m(int n){return 1;}
return;
}
} }

View File

@ -14,7 +14,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Stack; import java.util.Stack;
public class MethodDecl implements IClass, Node { public class MethodDecl implements Node {
//Class Name //Class Name
public String classThatContainsMethod; public String classThatContainsMethod;

View File

@ -3,6 +3,7 @@ package abstractSyntaxTree.Class;
import TypeCheck.AbstractType; import TypeCheck.AbstractType;
import TypeCheck.TypeCheckResult; import TypeCheck.TypeCheckResult;
import abstractSyntaxTree.Node; import abstractSyntaxTree.Node;
import abstractSyntaxTree.Parameter.ParameterList;
import org.objectweb.asm.ClassWriter; import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;
@ -29,7 +30,7 @@ public class RefType extends AbstractType implements Node {
this.hasMain = hasMain; this.hasMain = hasMain;
} }
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, List<String>>>> methodContext, public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext,
HashMap<String, HashMap<String, String>> typeContext) throws Exception { HashMap<String, HashMap<String, String>> typeContext) throws Exception {
TypeCheckResult result = new TypeCheckResult(); TypeCheckResult result = new TypeCheckResult();
@ -83,7 +84,7 @@ public class RefType extends AbstractType implements Node {
} }
for (MethodDecl method : methodDecls) { for (MethodDecl method : methodDecls) {
method.codeGen(cw); // method.codeGen(cw);
} }
cw.visitEnd(); cw.visitEnd();
} }

View File

@ -37,7 +37,7 @@ public class BinaryExpression extends AbstractType implements IExpression{
case "<=": case "<=":
case ">=": case ">=":
case "!=": case "!=":
result.type = helper.upperBound(leftType.type, rightType.type); result.type = helper.upperBound(leftType.type, rightType.type);
break; break;
case "-": case "-":
@ -86,11 +86,11 @@ public class BinaryExpression extends AbstractType implements IExpression{
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); left.codeGen(mv);
right.codeGen(mv); right.codeGen(mv);
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;
@ -167,4 +167,4 @@ public class BinaryExpression extends AbstractType implements IExpression{
mv.visitLabel(expressionEnd); mv.visitLabel(expressionEnd);
} }
} }

View File

@ -1,11 +1,15 @@
package abstractSyntaxTree.Expression; package abstractSyntaxTree.Expression;
import TypeCheck.TypeCheckResult; import TypeCheck.TypeCheckResult;
import abstractSyntaxTree.Parameter.ParameterList;
import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.MethodVisitor;
import java.util.HashMap;
public interface IExpression { public interface IExpression {
// typeCheck method // typeCheck method
TypeCheckResult typeCheck() throws Exception; //TypeCheckResult typeCheck() 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) throws Exception; void codeGen(MethodVisitor mv) throws Exception;

View File

@ -2,9 +2,12 @@ package abstractSyntaxTree.Expression;
import TypeCheck.TypeCheckResult; import TypeCheck.TypeCheckResult;
import abstractSyntaxTree.Class.RefType; import abstractSyntaxTree.Class.RefType;
import abstractSyntaxTree.Parameter.ParameterList;
import jdk.jshell.spi.ExecutionControl; import jdk.jshell.spi.ExecutionControl;
import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.MethodVisitor;
import java.util.HashMap;
public class InstVarExpression implements IExpression{ public class InstVarExpression implements IExpression{
//TODO: We have to decide upon more parameters and where they come from, for //TODO: We have to decide upon more parameters and where they come from, for
@ -12,13 +15,15 @@ public class InstVarExpression implements IExpression{
private RefType classRef; private RefType classRef;
private String fieldName; private String fieldName;
/* public InstVarExpression(RefType classRef, String fieldName){ public InstVarExpression(RefType classRef, String fieldName){
this.classRef = classRef; this.classRef = classRef;
this.fieldName = fieldName; this.fieldName = fieldName;
}*/ }
@Override @Override
public TypeCheckResult typeCheck() throws Exception { public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext, HashMap<String, HashMap<String, String>> typeContext, HashMap<String, String> localVars) throws Exception {
return null;
} }
@Override @Override

View File

@ -20,7 +20,7 @@ import java.util.jar.JarOutputStream;
public class Program implements Node { public class Program implements Node {
public List<RefType> classes; public List<RefType> classes;
public HashMap<String, HashMap<String, String>> typeContext; // (class, (type, identifier)) public HashMap<String, HashMap<String, String>> typeContext; // (class, (type, identifier))
public HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext; // (class, (returntype, (identifier, parameterList))) public HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext; // (class, (returntype, (identifier, parameter)))
public Program(List<RefType> classes){ public Program(List<RefType> classes){
this.classes = classes; this.classes = classes;
@ -41,11 +41,11 @@ public class Program implements Node {
typeContext.put(oneClass.name, classVars); typeContext.put(oneClass.name, classVars);
// build method context // build method context
HashMap<String, List<String>> methodIdentifierAndParameter = new HashMap<>(); HashMap<String, ParameterList> methodIdentifierAndParameter = new HashMap<>();
HashMap<String, HashMap<String, List<String >>> returnTypeAndMethod = new HashMap<>(); HashMap<String, HashMap<String, ParameterList>> returnTypeAndMethod = new HashMap<>();
for (MethodDecl methodDecl : oneClass.methodDecls){ for (MethodDecl methodDecl : oneClass.methodDecls){
methodIdentifierAndParameter.put(methodDecl.name, (List<String>) methodDecl.parameters); methodIdentifierAndParameter.put(methodDecl.name, methodDecl.parameters);
returnTypeAndMethod.put(methodDecl.returnType, methodIdentifierAndParameter); returnTypeAndMethod.put(methodDecl.returnType, methodIdentifierAndParameter);
} }
methodContext.put(oneClass.name, returnTypeAndMethod); methodContext.put(oneClass.name, returnTypeAndMethod);
@ -66,7 +66,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, methodContext); // oneClass.codeGen(cw);
cw.visitEnd(); cw.visitEnd();
byte[] bytecode = cw.toByteArray(); byte[] bytecode = cw.toByteArray();
@ -102,4 +102,4 @@ public class Program implements Node {
} }
*/ */
} }
} }

View File

@ -51,11 +51,11 @@ public class IfElseStatement extends AbstractType implements IStatement{
condition.codeGen(mv); condition.codeGen(mv);
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); //If the condition is true, execute the ifBlock //ifStatement.codeGen(mv); //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); //If the condition is false, execute the elseBlock //elseStatement.codeGen(mv); //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

View File

@ -43,7 +43,7 @@ public class IfStatement extends AbstractType implements IStatement{
condition.codeGen(mv); condition.codeGen(mv);
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); //ifStatement.codeGen(mv);
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
} }

View File

@ -44,7 +44,7 @@ public class WhileStatement extends AbstractType implements IStatement {
condition.codeGen(mv); condition.codeGen(mv);
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); //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
mv.visitJumpInsn(Opcodes.GOTO, LoopStart); // Jump to the start of the while loop mv.visitJumpInsn(Opcodes.GOTO, LoopStart); // Jump to the start of the while loop

View File

@ -29,15 +29,15 @@ public class AssignStatementExpression extends AbstractType implements IExpressi
TypeCheckHelper helper = new TypeCheckHelper(); TypeCheckHelper helper = new TypeCheckHelper();
TypeCheckResult result = new TypeCheckResult(); TypeCheckResult result = new TypeCheckResult();
TypeCheckResult leftType = left.typeCheck(); TypeCheckResult leftType;
if(leftType == null){ //left expression is the identifier of a var
if (left instanceof LocalVarIdentifier) {
leftType = new TypeCheckResult(); leftType = new TypeCheckResult();
if (left instanceof LocalVarIdentifier) { 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{
} leftType = left.typeCheck();
// not local var
} }
TypeCheckResult rightType = right.typeCheck(); TypeCheckResult rightType = right.typeCheck();
@ -64,14 +64,14 @@ public class AssignStatementExpression extends AbstractType implements IExpressi
left.codeGen(mv); left.codeGen(mv);
right.codeGen(mv); right.codeGen(mv);
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
// for that to determine if the variable is a local or field variable // // for that to determine if the variable is a local or field variable
} else if (left instanceof InstVarExpression instVar) { // } else if (left instanceof InstVarExpression instVar) {
mv.visitInsn(Opcodes.DUP_X1); // mv.visitInsn(Opcodes.DUP_X1);
//
// We now again need the owner (class reference), name (of the Field in the owner) and type of the field // // We now again need the owner (class reference), name (of the Field in the owner) and type of the field
//mv.visitFieldInsn(Opcodes.PUTFIELD, instVar.className, instVar.varName, instVar.type); // //mv.visitFieldInsn(Opcodes.PUTFIELD, instVar.className, instVar.varName, instVar.type);
} // }
} }
} }

View File

@ -61,7 +61,7 @@ public class MethodCallStatementExpression extends AbstractType implements IExpr
public void codeGen(MethodVisitor mv) throws Exception { public void codeGen(MethodVisitor mv) throws Exception {
//Generate Bytecode for the receiver //Generate Bytecode for the receiver
if(classThatHasTheMethodIfNotThis != null){ if(classThatHasTheMethodIfNotThis != null){
classThatHasTheMethodIfNotThis.codeGen(new ClassWriter(ClassWriter.COMPUTE_FRAMES)); // classThatHasTheMethodIfNotThis.codeGen(new ClassWriter(ClassWriter.COMPUTE_FRAMES));
} else { } else {
mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitVarInsn(Opcodes.ALOAD, 0);
} }

View File

@ -170,7 +170,7 @@ public class ASTGenerator extends DecafBaseVisitor<Node> {
@Override @Override
public Node visitAssign(DecafParser.AssignContext ctx) { public Node visitAssign(DecafParser.AssignContext ctx) {
return new AssignStatementExpression(); return new AssignStatementExpression("", null, null);
} }
@Override @Override