Merge remote-tracking branch 'origin/master'

This commit is contained in:
StefanZ3 2024-06-25 17:09:26 +02:00
commit 9cf2ff6f37
11 changed files with 71 additions and 40 deletions

View File

@ -1,15 +1,5 @@
import abstractSyntaxTree.Class.RefType;
import abstractSyntaxTree.Datatype.BoolDatatype;
import abstractSyntaxTree.Datatype.IntDatatype;
import abstractSyntaxTree.Expression.InstVarExpression;
import abstractSyntaxTree.Expression.LocalVarIdentifier;
import abstractSyntaxTree.Expression.UnaryExpression;
import abstractSyntaxTree.Program;
import abstractSyntaxTree.Statement.IStatement;
import abstractSyntaxTree.Statement.IfElseStatement;
import abstractSyntaxTree.Statement.LocalVarDecl;
import abstractSyntaxTree.Statement.ReturnStatement;
import abstractSyntaxTree.StatementExpression.AssignStatementExpression;
import astGenerator.ASTGenerator;
import gen.DecafLexer;
import gen.DecafParser;
@ -81,6 +71,6 @@ public class Compiler {
abstractSyntaxTree.typeCheck();
abstractSyntaxTree.codeGen();
//abstractSyntaxTree.codeGen();
}
}

View File

@ -9,6 +9,7 @@ class Example1 {
x = -3;
int i = 5;
Example e = new Example();
e.m(1);
return 0;
}
}

View File

@ -42,9 +42,10 @@ public class MethodDecl implements Node {
}
TypeCheckResult result = new TypeCheckResult();
codeBlock.thisClass = classThatContainsMethod;
String CodeBlockType = codeBlock.typeCheck(methodContext, typeContext, localVars).type;
if(!Objects.equals(this.returnType, CodeBlockType))
throw new TypeCheckException("Method returns " + CodeBlockType + ", but should retrun " + this.returnType + ". ");
throw new TypeCheckException("Method returns " + CodeBlockType + ", but should return " + this.returnType + ". ");
result.type = codeBlock.returnType;
return result;
}

View File

@ -67,6 +67,7 @@ public class RefType extends AbstractType implements Node {
// type check each method
for (MethodDecl methodDecl : methodDecls) {
// methodDecl.classThatContainsMethod = this.name;
methodDecl.typeCheck(methodContext, typeContext);
}

View File

@ -42,14 +42,13 @@ public class Program implements Node {
typeContext.put(oneClass.name, classVars);
// build method context
HashMap<String, ParameterList> methodIdentifierAndParameter = new HashMap<>();
HashMap<String, HashMap<String, ParameterList>> returnTypeAndMethod = new HashMap<>();
HashMap<String, ParameterList> returnTypeAndParameter = new HashMap<>();
HashMap<String, HashMap<String, ParameterList>> identifierAndMethod = new HashMap<>();
for (MethodDecl methodDecl : oneClass.methodDecls){
methodIdentifierAndParameter.put(methodDecl.name, methodDecl.parameters);
returnTypeAndMethod.put(methodDecl.returnType, methodIdentifierAndParameter);
returnTypeAndParameter.put(methodDecl.returnType, methodDecl.parameters);
identifierAndMethod.put(methodDecl.name, returnTypeAndParameter);
}
methodContext.put(oneClass.name, returnTypeAndMethod);
methodContext.put(oneClass.name, identifierAndMethod);
}
// typecheck each class

View File

@ -6,6 +6,8 @@ import TypeCheck.AbstractType;
import abstractSyntaxTree.Class.FieldDecl;
import abstractSyntaxTree.Parameter.Parameter;
import abstractSyntaxTree.Parameter.ParameterList;
import abstractSyntaxTree.StatementExpression.AssignStatementExpression;
import abstractSyntaxTree.StatementExpression.MethodCallStatementExpression;
import org.objectweb.asm.*;
import java.util.HashMap;
@ -19,6 +21,7 @@ public class BlockStatement extends AbstractType implements IStatement {
HashMap<String, String> localVars;
public String returnType; // "not" --> not void
public List<IStatement> statements;
public String thisClass;
// do we need expression, statementexpression
public BlockStatement(List<IStatement> statements, String returnType) {
@ -33,15 +36,30 @@ public class BlockStatement extends AbstractType implements IStatement {
TypeCheckResult result = new TypeCheckResult();
this.localVars = localVars;
if (statements.size() == 0) {
if (statements.isEmpty()) {
result.type = "void";
}
for (IStatement statement : statements) {
if(statement instanceof IfStatement ifStatement){
ifStatement.thisClass = this.thisClass;
}
if(statement instanceof IfElseStatement ifElseStatement){
ifElseStatement.thisClass = this.thisClass;
}
if(statement instanceof WhileStatement whileStatement){
whileStatement.thisClass = this.thisClass;
}
if(statement instanceof MethodCallStatementExpression methodCall){
methodCall.thisClass = thisClass;
}
if(statement instanceof AssignStatementExpression assignStatementExpression){
assignStatementExpression.thisClass = thisClass;
}
TypeCheckResult typeOfCurrentStatement = statement.typeCheck(methodContext, typeContext, localVars);
if(statement instanceof LocalVarDecl){
LocalVarDecl localVarDecl = (LocalVarDecl) statement;
if(statement instanceof LocalVarDecl localVarDecl){
localVars.put(localVarDecl.identifier, localVarDecl.type);
}
@ -70,7 +88,6 @@ public class BlockStatement extends AbstractType implements IStatement {
}
}
if(typeOfCurrentStatement.type.equals("void"))
continue;
// set return of block if not known yet

View File

@ -16,6 +16,7 @@ public class IfElseStatement extends AbstractType implements IStatement{
public IExpression condition;
IStatement ifStatement;
IStatement elseStatement;
public String thisClass;
public IfElseStatement(IExpression condition, IStatement ifStatement, IStatement elseStatement) {
this.condition = condition;
@ -23,11 +24,17 @@ public class IfElseStatement extends AbstractType implements IStatement{
this.elseStatement = elseStatement;
}
@Override
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext, HashMap<String, HashMap<String, String>> typeContext, HashMap<String, String> localVars) throws TypeCheckException {
TypeCheckResult result = new TypeCheckResult();
if(ifStatement instanceof BlockStatement blockStatement){
blockStatement.thisClass = thisClass;
}
if(elseStatement instanceof BlockStatement blockStatement){
blockStatement.thisClass = thisClass;
}
TypeCheckResult conditionType = condition.typeCheck(methodContext, typeContext, localVars);
if (!conditionType.type.equals("boolean")) {

View File

@ -17,6 +17,7 @@ public class IfStatement extends AbstractType implements IStatement{
//Do we need a block statement here?
IStatement ifStatement;
public String thisClass;
public IfStatement(IExpression condition, IStatement ifStatement) {
this.condition = condition;
@ -33,6 +34,9 @@ public class IfStatement extends AbstractType implements IStatement{
throw new TypeCheckException("Condition of If-Statement should is " + conditionType.type + ", but should be boolean.");
}
if(ifStatement instanceof BlockStatement blockStatement){
blockStatement.thisClass = thisClass;
}
TypeCheckResult ifStatementType = ifStatement.typeCheck(methodContext, typeContext, localVars);
result.type = ifStatementType.type;
return result;

View File

@ -15,6 +15,7 @@ import java.util.Objects;
public class WhileStatement extends AbstractType implements IStatement {
IExpression condition;
IStatement statement;
public String thisClass;
public WhileStatement(IExpression condition, IStatement statement) {
this.condition = condition;

View File

@ -21,6 +21,7 @@ public class AssignStatementExpression extends AbstractType implements IExpressi
public IExpression left;
public IExpression right;
private InstVarExpression instVar;
public String thisClass;
public AssignStatementExpression(String operator, IExpression leftExpression, IExpression rightExpression){
this.operator = operator;
@ -34,16 +35,15 @@ public class AssignStatementExpression extends AbstractType implements IExpressi
TypeCheckResult leftType;
if (left instanceof LocalVarIdentifier) {
if (left instanceof LocalVarIdentifier localVarIdentifier) {
leftType = new TypeCheckResult();
LocalVarIdentifier localVarIdentifier = (LocalVarIdentifier) left;
String identifier = localVarIdentifier.getIdentifier();
leftType.type = localVars.get(identifier);
// actually instavar of this
// if(leftType == null){
// localVarIdentifier.
// }
// local var may be actually instvar of this
if(leftType.type == null){
leftType.type = typeContext.get(thisClass).get(identifier);
}
}else{
leftType = left.typeCheck(methodContext, typeContext, localVars);
}

View File

@ -20,8 +20,7 @@ public class MethodCallStatementExpression extends AbstractType implements IExpr
List<IExpression> arguments;
Receiver receiver;
List<ReceivingMethod> receivingMethods;
RefType classThatHasTheMethodIfNotThis;
RefType thisClass;
public String thisClass;
public MethodCallStatementExpression(String methodName, Receiver receiver, List<ReceivingMethod> receivingMethods, List<IExpression> arguments) {
this.methodName = methodName;
@ -33,8 +32,18 @@ public class MethodCallStatementExpression extends AbstractType implements IExpr
@Override
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext, HashMap<String, HashMap<String, String>> typeContext, HashMap<String, String> localVars) throws TypeCheckException {
//todo i really dont get this. waiting for tuesday meeting
throw new TypeCheckException("NOT IMPLEMENTED");
String classToSearchMethodIn = thisClass;
//method is called on something that is not this
if(!receiver.thisExpression){
classToSearchMethodIn = localVars.get(receiver.identifier);
}
//if classToSearchMethodIn does not conatin method, throw exception. go through list and check each
throw new TypeCheckException("NOT IMPLEMENTED");
// TypeCheckResult result = new TypeCheckResult();
// String receivingField;
// String classContainingMethod;
@ -58,6 +67,7 @@ public class MethodCallStatementExpression extends AbstractType implements IExpr
// }
//
// return result;
//return null;
}
//Errors occur due to the change in parameter in the RefType class
@ -94,15 +104,15 @@ public class MethodCallStatementExpression extends AbstractType implements IExpr
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
}
}
// 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;
// String className = classThatHasTheMethodIfNotThis != null ? classThatHasTheMethodIfNotThis.name : thisClass.name;
//mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, className, methodName, descriptor, false);
}