Merge branch 'refs/heads/main' into testsuites

This commit is contained in:
JonathanFleischmann 2024-06-30 20:52:32 +02:00
commit 122b165410
19 changed files with 216 additions and 121 deletions

View File

@ -46,7 +46,8 @@ public class ExpressionGenerator extends DecafBaseVisitor<Expression> {
Expression recipient = null;
if (ctx.fieldVarAccess().recipient() != null) {
List<DecafParser.RecipientContext> recipientList = ctx.fieldVarAccess().recipient();
recipient = ExpressionGenerator.generateRecursiveOwnerChain(recipientList, ctx.fieldVarAccess().newCall() != null ? StatementGenerator.generateNew(ctx.fieldVarAccess().newCall()) : null);
recipient = ExpressionGenerator.generateRecursiveOwnerChain(recipientList, ctx.fieldVarAccess().newCall() != null ? StatementGenerator.generateNew(ctx.fieldVarAccess().newCall()) : null, isField);
return new FieldVarAccess(true, recipient, ctx.fieldVarAccess().id().IDENTIFIER().getText());
}
return new FieldVarAccess(isField, recipient, ctx.fieldVarAccess().id().IDENTIFIER().getText());
}
@ -106,7 +107,7 @@ public class ExpressionGenerator extends DecafBaseVisitor<Expression> {
Expression recursiveOwnerChain = null;
if (ctx.methCall().recipient() != null) {
List<DecafParser.RecipientContext> recipientList = ctx.methCall().recipient();
recursiveOwnerChain = ExpressionGenerator.generateRecursiveOwnerChain(recipientList, ctx.methCall().newCall() != null ? StatementGenerator.generateNew(ctx.methCall().newCall()) : null);
recursiveOwnerChain = ExpressionGenerator.generateRecursiveOwnerChain(recipientList, ctx.methCall().newCall() != null ? StatementGenerator.generateNew(ctx.methCall().newCall()) : null, isField);
}
List<Expression> args = new ArrayList<>();
if (ctx.methCall().methName().args() != null) {
@ -115,7 +116,10 @@ public class ExpressionGenerator extends DecafBaseVisitor<Expression> {
args.add(astExpr);
}
}
return new MethodCall(new FieldVarAccess(isField, recursiveOwnerChain, ctx.methCall().methName().id().IDENTIFIER().getText()), args);
if (recursiveOwnerChain == null) {
return new MethodCall(new FieldVarAccess(isField, null, ctx.methCall().methName().id().IDENTIFIER().getText()), args);
}
return new MethodCall(new FieldVarAccess(true, recursiveOwnerChain, ctx.methCall().methName().id().IDENTIFIER().getText()), args);
}
@Override
@ -124,7 +128,7 @@ public class ExpressionGenerator extends DecafBaseVisitor<Expression> {
}
public static Expression generateRecursiveOwnerChain(List<DecafParser.RecipientContext> ctxList, Expression recipient) {
public static Expression generateRecursiveOwnerChain(List<DecafParser.RecipientContext> ctxList, Expression recipient, Boolean isField) {
if (ctxList.isEmpty()) {
return recipient;
}
@ -132,7 +136,10 @@ public class ExpressionGenerator extends DecafBaseVisitor<Expression> {
DecafParser.RecipientContext ctx = ctxList.get(lastElement);
ctxList.remove(lastElement);
if (ctx.id() != null) {
return new FieldVarAccess(true, generateRecursiveOwnerChain(ctxList, recipient), ctx.id().IDENTIFIER().getText());
if (ctxList.isEmpty()) {
return new FieldVarAccess(isField, recipient, ctx.id().IDENTIFIER().getText());
}
return new FieldVarAccess(true, generateRecursiveOwnerChain(ctxList, recipient, isField), ctx.id().IDENTIFIER().getText());
}
if (ctx.methName() != null) {
List<Expression> args = new ArrayList<>();
@ -142,7 +149,10 @@ public class ExpressionGenerator extends DecafBaseVisitor<Expression> {
args.add(astExpr);
}
}
return new MethodCall(new FieldVarAccess(true, generateRecursiveOwnerChain(ctxList, recipient), ctx.methName().id().IDENTIFIER().getText()), args);
if (ctxList.isEmpty()) {
return new MethodCall(new FieldVarAccess(isField, recipient, ctx.methName().id().IDENTIFIER().getText()), args);
}
return new MethodCall(new FieldVarAccess(true, generateRecursiveOwnerChain(ctxList, recipient, isField), ctx.methName().id().IDENTIFIER().getText()), args);
}
throw new RuntimeException();

View File

@ -101,9 +101,13 @@ public class StatementGenerator extends DecafBaseVisitor<List<Statement>> {
}
private FieldVarAccess generateField(DecafParser.FieldVarAccessContext fieldIdContext) {
return new FieldVarAccess(fieldIdContext.THIS() != null,
ExpressionGenerator.generateRecursiveOwnerChain(fieldIdContext.recipient(),
null), fieldIdContext.id().IDENTIFIER().getText());
Boolean isField = fieldIdContext.THIS() != null;
Expression recipient = null;
if (fieldIdContext.recipient() != null) {
recipient = ExpressionGenerator.generateRecursiveOwnerChain(fieldIdContext.recipient(), null, isField);
return new FieldVarAccess(true, recipient, fieldIdContext.id().IDENTIFIER().getText());
}
return new FieldVarAccess(isField, recipient, fieldIdContext.id().IDENTIFIER().getText());
}
@Override
@ -115,11 +119,6 @@ public class StatementGenerator extends DecafBaseVisitor<List<Statement>> {
@Override
public List<Statement> visitMethodCall(DecafParser.MethodCallContext ctx) {
boolean isField = ctx.methCall().THIS() != null;
Expression recursiveOwnerChain = null;
if (ctx.methCall().recipient() != null) {
List<DecafParser.RecipientContext> recipientList = ctx.methCall().recipient();
recursiveOwnerChain = ExpressionGenerator.generateRecursiveOwnerChain(recipientList, ctx.methCall().newCall() != null ? generateNew(ctx.methCall().newCall()) : null);
}
List<Expression> args = new ArrayList<>();
if (ctx.methCall().methName().args() != null) {
for (var expr : ctx.methCall().methName().args().expr()) {
@ -127,6 +126,12 @@ public class StatementGenerator extends DecafBaseVisitor<List<Statement>> {
args.add(astExpr);
}
}
Expression recursiveOwnerChain = null;
if (ctx.methCall().recipient() != null) {
List<DecafParser.RecipientContext> recipientList = ctx.methCall().recipient();
recursiveOwnerChain = ExpressionGenerator.generateRecursiveOwnerChain(recipientList, ctx.methCall().newCall() != null ? generateNew(ctx.methCall().newCall()) : null, isField);
return List.of(new MethodCall(new FieldVarAccess(true, recursiveOwnerChain, ctx.methCall().methName().id().IDENTIFIER().getText()), args));
}
return List.of(new MethodCall(new FieldVarAccess(isField, recursiveOwnerChain, ctx.methCall().methName().id().IDENTIFIER().getText()), args));
}

View File

@ -31,11 +31,15 @@ public class TypedAssignment implements TypedStatement {
public void convertToTypedAssignment(TypedProgram typedProgram, Assignment untyped) {
value = convertExpression(typedProgram, untyped.value());
location = new TypedFieldVarAccess(typedProgram, untyped.location());
//location.typeCheck(typedProgram);
}
@Override
public Type typeCheck(TypedProgram typedProgram) {
TypedClass currentClass = typedProgram.getCurrentClass();
if (currentClass.isCurrentMainMethodPresent() && location.getField() && location.getRecursiveOwnerChain() == null) {
throw new RuntimeException("Main Method, is not allowed to have fields, they are not static");
}
Type typeLeft = getTypeLeft(typedProgram);
Type typeRight = value.typeCheck(typedProgram);
@ -70,7 +74,7 @@ public class TypedAssignment implements TypedStatement {
if (currentMethod.isLocalVariableInMethod(name)) {
return currentMethod.getLocalVariableType(name);
} else if (currentClass.isThereField(name)) {
throw new RuntimeException("Field Variable "+ name + " should be used with `this´");
throw new RuntimeException("Field Variable " + name + " should be used with `this´");
} else {
throw new RuntimeException("Variable " + name + " not declared in method");
}
@ -80,7 +84,7 @@ public class TypedAssignment implements TypedStatement {
if (currentConstructor.isLocalVariableInConstructor(name)) {
return currentConstructor.getLocalVariableType(name);
} else if (currentClass.isThereField(name)) {
throw new RuntimeException("Field Variable "+ name+ " should be used with `this´");
throw new RuntimeException("Field Variable " + name + " should be used with `this´");
} else {
throw new RuntimeException("Variable " + name + " not declared in constructor");
}
@ -88,7 +92,7 @@ public class TypedAssignment implements TypedStatement {
@Override
public void codeGen(MethodContext ctx) {
if(value instanceof TypedMethodCall) {
if (value instanceof TypedMethodCall) {
value.codeGen(ctx);
getOwnerChain(ctx);
} else {
@ -112,7 +116,7 @@ public class TypedAssignment implements TypedStatement {
return;
}
MethodContext.LocalVariable localVariable = localVariableOptional.get();
if(value.getType().getKind() == Type.Kind.REFERENCE) {
if (value.getType().getKind() == Type.Kind.REFERENCE) {
LOGGER.finest("ASTORE " + localVariable.index());
ctx.getMv().visitVarInsn(Opcodes.ASTORE, localVariable.index());
} else {

View File

@ -52,8 +52,8 @@ public class TypedBinary implements TypedExpression {
} else {
throw new RuntimeException("Type mismatch in " + op);
}
} else if(op == Operator.EQ || op == Operator.NE || op == Operator.AND || op == Operator.OR){
if(leftType == Type.INT && rightType == Type.INT || leftType == Type.BOOL && rightType == Type.BOOL){
} else if (op == Operator.EQ || op == Operator.NE || op == Operator.AND || op == Operator.OR) {
if (leftType == Type.INT && rightType == Type.INT || leftType == Type.BOOL && rightType == Type.BOOL) {
type = Type.BOOL;
return Type.BOOL;
} else {

View File

@ -97,16 +97,20 @@ public class TypedBlock implements TypedNode {
return type;
}
private void clearLocalVariable(TypedProgram typedProgram){
for(var typedLocalVariable : vars){
if (typedProgram.getCurrentClass().isCurrentMethodPresent() && !typedProgram.getCurrentClass().isCurrentConstructorPresent()) {
if (typedProgram.getCurrentClass().getCurrentMethod().isLocalVariableInMethod(typedLocalVariable.getName())) {
typedProgram.getCurrentClass().getCurrentMethod().deleteLocalVariableInMethod(typedLocalVariable.getName());
private void clearLocalVariable(TypedProgram typedProgram) {
TypedClass typedClass = typedProgram.getCurrentClass();
TypedMethod typedMethod = typedClass.getCurrentMethod();
TypedConstructor typedConstructor = typedClass.getCurrentConstructor();
for (var typedLocalVariable : vars) {
if (typedClass.isCurrentMethodPresent() && !typedClass.isCurrentConstructorPresent()) {
if (typedMethod.isLocalVariableInMethod(typedLocalVariable.getName())) {
typedMethod.deleteLocalVariableInMethod(typedLocalVariable.getName());
}
}
if (!typedProgram.getCurrentClass().isCurrentMethodPresent() && typedProgram.getCurrentClass().isCurrentConstructorPresent()) {
if (typedProgram.getCurrentClass().getCurrentConstructor().isLocalVariableInConstructor(typedLocalVariable.getName())) {
typedProgram.getCurrentClass().getCurrentConstructor().deleteLocalVariableInConstructor(typedLocalVariable.getName());
if (!typedClass.isCurrentMethodPresent() && typedClass.isCurrentConstructorPresent()) {
if (typedConstructor.isLocalVariableInConstructor(typedLocalVariable.getName())) {
typedConstructor.deleteLocalVariableInConstructor(typedLocalVariable.getName());
}
}
}

View File

@ -17,7 +17,6 @@ public class TypedBoolLiteral implements TypedExpression {
private Boolean value;
private Type type;
public TypedBoolLiteral(BoolLiteral unTypedBoolLiteral) {
convertToTypedBoolLiteral(unTypedBoolLiteral);
}

View File

@ -13,7 +13,7 @@ public class TypedCharLiteral implements TypedExpression {
private char value;
private Type type;
public TypedCharLiteral( CharLiteral unTypedCharLiteral) {
public TypedCharLiteral(CharLiteral unTypedCharLiteral) {
convertToCharLiteral(unTypedCharLiteral);
}

View File

@ -6,6 +6,7 @@ import de.maishai.ast.records.Declaration;
import de.maishai.ast.records.Method;
import de.maishai.typedast.ClassContext;
import de.maishai.typedast.Type;
import de.maishai.typedast.TypedExpression;
import de.maishai.typedast.TypedNode;
import lombok.AllArgsConstructor;
import lombok.Data;
@ -28,22 +29,24 @@ public class TypedClass implements TypedNode {
private TypedMethod currentMethod;
private TypedConstructor currentConstructor;
private Type type;
private boolean isMainCurrentMethod;
public TypedClass(Class c) {
className = c.classname();
type = Type.REFERENCE(className);
isMainCurrentMethod = false;
}
public boolean isParameterNameInCurrentConstructor(String parameterName) {
if (currentConstructor == null) {
return false;
}
for (TypedParameter p : currentConstructor.getTypedParameters()) {
if (p.getParaName().equals(parameterName)) {
return true;
}
}
return false;
public TypedClass(String className, List<TypedDeclaration> typedDeclarations, List<TypedMethod> typedMethods, List<TypedConstructor> typedConstructors, TypedMain typedMain, TypedMethod currentMethod, TypedConstructor currentConstructor, Type type) {
this.className = className;
this.typedDeclarations = typedDeclarations;
this.typedMethods = typedMethods;
this.typedConstructors = typedConstructors;
this.typedMain = typedMain;
this.currentMethod = currentMethod;
this.currentConstructor = currentConstructor;
this.type = type;
isMainCurrentMethod = false;
}
public void convertMethodsAndConstructorsAndFields(TypedProgram typedProgram, Class c) {
@ -86,18 +89,40 @@ public class TypedClass implements TypedNode {
if (c.mainmeth() != null) {
enterCurrentMethod(typedMain.getTypedMethod());
isMainCurrentMethod = true;
typedMain.convertToTypedMethod(typedProgram, c);
isMainCurrentMethod = false;
exitCurrentMethod();
} else {
typedMain = null;
}
}
public void checkMethodExists(TypedMethod typedMethod) {
typedMethods.stream().filter(method -> method.equals(typedMethod)).findFirst().ifPresentOrElse(
method -> {
throw new RuntimeException("Method " + typedMethod.getName() + " already exists");
}, () -> {
});
}
@Override
public Type typeCheck(TypedProgram typedProgram) {
return type;
}
public boolean isParameterNameInCurrentConstructor(String parameterName) {
if (currentConstructor == null) {
return false;
}
for (TypedParameter p : currentConstructor.getTypedParameters()) {
if (p.getParaName().equals(parameterName)) {
return true;
}
}
return false;
}
public boolean isParameterWitNameInCurrentMethod(String parameterName) {
return this.getCurrentMethod().getTypedParameters().stream().anyMatch(parameter -> parameter.getParaName().equals(parameterName));
}
@ -174,6 +199,9 @@ public class TypedClass implements TypedNode {
return currentConstructor != null;
}
public boolean isCurrentMainMethodPresent() {
return isMainCurrentMethod;
}
public byte[] codeGen() {
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);

View File

@ -33,6 +33,32 @@ public class TypedConstructor implements TypedNode {
this.typedBlock = typedBlock;
}
public void convertToTypedConstructor(TypedProgram typedProgram, Constructor unTypedConstructor) {
name = unTypedConstructor.className();
convertToTypedParameter(typedProgram, unTypedConstructor.params());
type = Type.VOID;
}
private void convertToTypedParameter(TypedProgram typedProgram, List<Parameter> params) {
for (Parameter param : params) {
TypedParameter typedParameter = new TypedParameter(typedProgram, param);
checkIfParameterExists(typedParameter.getParaName());
typedParameters.add(typedParameter);
localVariables.add(new TypedLocalVariable(typedParameter.getParaName(), typedParameter.getType()));
}
}
@Override
public Type typeCheck(TypedProgram typedProgram) {
type = typedBlock.typeCheck(typedProgram);
if (type != Type.VOID) {
throw new RuntimeException("Constructor must not habe a return statement");
}
return type;
}
public TypedConstructor(TypedProgram typedProgram, Constructor unTypedConstructor) {
convertToTypedConstructor(typedProgram, unTypedConstructor);
}
@ -53,19 +79,7 @@ public class TypedConstructor implements TypedNode {
return localVariables.stream().filter(localVariable -> localVariable.getName().equals(localVarName)).findFirst().get().getType();
}
public void convertToTypedConstructor(TypedProgram typedProgram, Constructor unTypedConstructor) {
name = unTypedConstructor.className();
for (Parameter param : unTypedConstructor.params()) {
TypedParameter typedParameter = new TypedParameter(typedProgram, param);
checkIfParameterExists(typedParameter.getParaName());
typedParameters.add(typedParameter);
localVariables.add(new TypedLocalVariable(typedParameter.getParaName(), typedParameter.getType()));
}
type = Type.VOID;
}
public void checkIfParameterExists(String paraName) {
private void checkIfParameterExists(String paraName) {
if (typedParameters.stream().anyMatch(parameter -> parameter.getParaName().equals(paraName))) {
throw new RuntimeException("Parameter " + paraName + " already exists");
}
@ -75,20 +89,11 @@ public class TypedConstructor implements TypedNode {
this.typedBlock = new TypedBlock(typedProgram, unTypedConstructor.block());
typeCheck(typedProgram);
}
public void deleteLocalVariableInConstructor(String localVarName){
public void deleteLocalVariableInConstructor(String localVarName) {
localVariables.removeIf(localVariable -> localVariable.getName().equals(localVarName));
}
@Override
public Type typeCheck(TypedProgram typedProgram) {
type = typedBlock.typeCheck(typedProgram);
if (type != Type.VOID) {
throw new RuntimeException("Constructor must not habe a return statement");
}
return type;
}
public void codeGen(ClassContext ctx) {
int accessModifier = Opcodes.ACC_PUBLIC;

View File

@ -29,12 +29,15 @@ public final class TypedDeclaration implements TypedNode {
@Override
public Type typeCheck(TypedProgram typedProgram) {
if (type.getReference() != null && !typedProgram.getCurrentClass().getClassName().equals(type.getReference())) {
TypedClass currentClass = typedProgram.getCurrentClass();
if (type.getReference() != null && !currentClass.getClassName().equals(type.getReference())) {
if (!typedProgram.isTypedClassPresent(type.getReference())) {
throw new RuntimeException("Type " + type.getReference() + " not found");
}
}
if (typedProgram.getCurrentClass().isThereField(name)) {
if (currentClass.isThereField(name)) {
throw new RuntimeException("Field " + name + " already declared");
}
return type;

View File

@ -48,22 +48,24 @@ public class TypedFieldVarAccess implements TypedExpression {
}
private Type checkFieldOrMethodType(TypedProgram typedProgram) {
if (typedProgram.getCurrentClass().isThereField(name)) {
TypedClass currentClass = typedProgram.getCurrentClass();
if (currentClass.isThereField(name)) {
return checkTypeField(typedProgram);
} else if (typedProgram.getCurrentClass().isMethodOfCurrentClass(name)) {
type = typedProgram.getCurrentClass().getMethodType(name);
} else if (currentClass.isMethodOfCurrentClass(name)) {
type = currentClass.getMethodType(name);
return type;
} else if (recursiveOwnerChain instanceof TypedFieldVarAccess typedFieldVarAccess) {
if (typedProgram.isClassWithNamePresent(recursiveOwnerChain.getType().getReference())) {
boolean isClassWithNamePresent = typedProgram.isClassWithNamePresent(recursiveOwnerChain.getType().getReference());
if (isClassWithNamePresent) {
Type typeofFieldNameInClass = typedProgram.getTypeOfFieldNameInClass(recursiveOwnerChain.getType().getReference(), name);
if(typeofFieldNameInClass != null){
if (typeofFieldNameInClass != null) {
return typeofFieldNameInClass;
}else{
} else {
throw new RuntimeException("Field " + name + " not declared in class " + recursiveOwnerChain.getType().getReference());
}
}
type = typedProgram.getCurrentClass().getFieldType(typedFieldVarAccess.getName());
type = currentClass.getFieldType(typedFieldVarAccess.getName());
return type;
} else {
throw new RuntimeException("Field " + name + " not declared");
@ -71,9 +73,11 @@ public class TypedFieldVarAccess implements TypedExpression {
}
private Type checkVariableType(TypedProgram typedProgram) {
if (typedProgram.getCurrentClass().isCurrentConstructorPresent()) {
TypedClass currentClass = typedProgram.getCurrentClass();
if (currentClass.isCurrentConstructorPresent()) {
return checkConstructorVariableType(typedProgram);
} else if (typedProgram.getCurrentClass().isCurrentMethodPresent()) {
} else if (currentClass.isCurrentMethodPresent()) {
return checkMethodVariableType(typedProgram);
} else {
throw new RuntimeException("Variable " + name + " not declared");
@ -81,10 +85,13 @@ public class TypedFieldVarAccess implements TypedExpression {
}
private Type checkConstructorVariableType(TypedProgram typedProgram) {
if (typedProgram.getCurrentClass().isParameterNameInCurrentConstructor(name)) {
type = typedProgram.getCurrentClass().getParameterTypeInCurrentConstructor(name);
} else if (typedProgram.getCurrentClass().getCurrentConstructor().isLocalVariablePresent(name)) {
type = typedProgram.getCurrentClass().getCurrentConstructor().getLocalVariableType(name);
TypedClass currentClass = typedProgram.getCurrentClass();
TypedConstructor currentConstructor = currentClass.getCurrentConstructor();
if (currentClass.isParameterNameInCurrentConstructor(name)) {
type = currentClass.getParameterTypeInCurrentConstructor(name);
} else if (currentConstructor.isLocalVariablePresent(name)) {
type = currentConstructor.getLocalVariableType(name);
} else {
return checkFieldOrMethodOrRecursiveType(typedProgram);
}
@ -92,10 +99,13 @@ public class TypedFieldVarAccess implements TypedExpression {
}
private Type checkMethodVariableType(TypedProgram typedProgram) {
if (typedProgram.getCurrentClass().isParameterWitNameInCurrentMethod(name)) {
type = typedProgram.getCurrentClass().getParameterTypeInCurrentMethod(name);
} else if (typedProgram.getCurrentClass().getCurrentMethod().isLocalVariablePresent(name)) {
type = typedProgram.getCurrentClass().getCurrentMethod().getLocalVariableType(name);
TypedClass currentClass = typedProgram.getCurrentClass();
TypedMethod currentMethod = currentClass.getCurrentMethod();
if (currentClass.isParameterWitNameInCurrentMethod(name)) {
type = currentClass.getParameterTypeInCurrentMethod(name);
} else if (currentMethod.isLocalVariablePresent(name)) {
type = currentMethod.getLocalVariableType(name);
} else {
return checkFieldOrMethodOrRecursiveType(typedProgram);
}
@ -103,17 +113,20 @@ public class TypedFieldVarAccess implements TypedExpression {
}
private Type checkFieldOrMethodOrRecursiveType(TypedProgram typedProgram) {
if (typedProgram.getCurrentClass().isThereField(name)) {
type = typedProgram.getCurrentClass().getFieldType(name);
} else if (typedProgram.getCurrentClass().isMethodOfCurrentClass(name)) {
type = typedProgram.getCurrentClass().getMethodType(name);
TypedClass currentClass = typedProgram.getCurrentClass();
if (currentClass.isThereField(name)) {
type = currentClass.getFieldType(name);
} else if (currentClass.isMethodOfCurrentClass(name)) {
type = currentClass.getMethodType(name);
} else if (recursiveOwnerChain instanceof TypedFieldVarAccess typedFieldVarAccess) {
type = typedProgram.getCurrentClass().getFieldType(typedFieldVarAccess.getName());
type = currentClass.getFieldType(typedFieldVarAccess.getName());
} else {
throw new RuntimeException("Variable " + name + " not declared");
}
return type;
}
private Type checkTypeField(TypedProgram typedProgram) {
if (recursiveOwnerChain != null) {
if (recursiveOwnerChain.getType() != null) {
@ -123,6 +136,7 @@ public class TypedFieldVarAccess implements TypedExpression {
type = typedProgram.getCurrentClass().getFieldType(name);
return type;
}
@Override
public void codeGen(MethodContext ctx) {
if (recursiveOwnerChain != null) {

View File

@ -20,7 +20,6 @@ public class TypedIntLiteral implements TypedExpression {
private Integer value;
private Type type;
public TypedIntLiteral(IntLiteral unTypedIntLiteral) {
convertToTypedIntLiteral(unTypedIntLiteral);
}

View File

@ -28,18 +28,22 @@ public final class TypedLocalVariable implements TypedNode {
@Override
public Type typeCheck(TypedProgram typedProgram) {
if (typedProgram.getCurrentClass().isCurrentMethodPresent() && !typedProgram.getCurrentClass().isCurrentConstructorPresent()) {
if (typedProgram.getCurrentClass().getCurrentMethod().isLocalVariableInMethod(name)) {
TypedClass currentClass = typedProgram.getCurrentClass();
TypedMethod currentMethod = currentClass.getCurrentMethod();
TypedConstructor currentConstructor = currentClass.getCurrentConstructor();
if (currentClass.isCurrentMethodPresent() && !currentClass.isCurrentConstructorPresent()) {
if (currentMethod.isLocalVariableInMethod(name)) {
throw new RuntimeException("Variable " + name + " already declared");
}
typedProgram.getCurrentClass().getCurrentMethod().getLocalVariables().add(this);
currentMethod.getLocalVariables().add(this);
return type;
}
if (!typedProgram.getCurrentClass().isCurrentMethodPresent() && typedProgram.getCurrentClass().isCurrentConstructorPresent()) {
if (typedProgram.getCurrentClass().getCurrentConstructor().isLocalVariableInConstructor(name)) {
if (!currentClass.isCurrentMethodPresent() && currentClass.isCurrentConstructorPresent()) {
if (currentConstructor.isLocalVariableInConstructor(name)) {
throw new RuntimeException("Variable " + name + " already declared");
}
typedProgram.getCurrentClass().getCurrentConstructor().getLocalVariables().add(this);
currentConstructor.getLocalVariables().add(this);
return type;
}
throw new RuntimeException("not found method or constructor in class");

View File

@ -15,14 +15,14 @@ public class TypedMain implements TypedNode {
private Type type = Type.VOID;
private TypedMethod typedMethod;
public TypedMain(){
public TypedMain() {
typedMethod = new TypedMethod();
typedMethod.setName("main");
typedMethod.setReturnType(type);
typedMethod.setTypedParameters(List.of(new TypedParameter("args", Type.REFERENCE("String[]"))));
}
public void convertToTypedMethod(TypedProgram typedProgram, Class unTypedClass){
public void convertToTypedMethod(TypedProgram typedProgram, Class unTypedClass) {
typedMethod.setTypedBlock(new TypedBlock(typedProgram, unTypedClass.mainmeth()));
}

View File

@ -1,6 +1,7 @@
package de.maishai.typedast.typedclass;
import de.maishai.ast.records.Method;
import de.maishai.ast.records.Parameter;
import de.maishai.typedast.*;
import lombok.AllArgsConstructor;
import lombok.Data;
@ -26,21 +27,21 @@ public class TypedMethod implements TypedNode {
}
public void convertToTypedMethod(TypedProgram typedProgram, Method unTypedMethod) {
TypedClass currentClass = typedProgram.getCurrentClass();
name = unTypedMethod.methodName();
returnType = unTypedMethod.type();
for (var parameter : unTypedMethod.params()) {
TypedParameter typedParameter = new TypedParameter(typedProgram, parameter);
convertToTypedParameter(typedProgram, unTypedMethod.params());
currentClass.checkMethodExists(this);
}
private void convertToTypedParameter(TypedProgram typedProgram, List<Parameter> params) {
for (Parameter param : params) {
TypedParameter typedParameter = new TypedParameter(typedProgram, param);
checkIfParameterExists(typedParameter.getParaName());
typedParameters.add(typedParameter);
localVariables.add(new TypedLocalVariable(typedParameter.getParaName(), typedParameter.getType()));
}
typedProgram.getCurrentClass().getTypedMethods().stream().filter(method -> method.equals(this)).findFirst().ifPresentOrElse(
method -> {
throw new RuntimeException("Method " + name + " already exists");
}, () -> {
});
}
public void checkIfParameterExists(String parameterName) {
@ -49,6 +50,7 @@ public class TypedMethod implements TypedNode {
}
}
public void convertToTypedBlock(TypedProgram typedProgram, Method unTypedMethod) {
typedBlock = new TypedBlock(typedProgram, unTypedMethod.block());
typeCheck(typedProgram);
@ -67,9 +69,10 @@ public class TypedMethod implements TypedNode {
return isLocalVariablePresent(localVarName) || isParameterPresent(localVarName);
}
public void deleteLocalVariableInMethod(String localVarName){
public void deleteLocalVariableInMethod(String localVarName) {
localVariables.removeIf(localVariable -> localVariable.getName().equals(localVarName));
}
public Type getLocalVariableType(String localVarName) {
return localVariables.stream().filter(localVariable -> localVariable.getName().equals(localVarName)).findFirst().get().getType();
}
@ -117,7 +120,7 @@ public class TypedMethod implements TypedNode {
public Type typeCheck(TypedProgram typedProgram) {
if (returnType != Type.VOID && !checkReturn(typedBlock.getStmts())) {
if (typedBlock.typeCheck(typedProgram).getKind() != returnType.getKind()) {
throw new RuntimeException("please use ´return´ correctly in the method " + name);
throw new RuntimeException("please use ´return´ correctly in the method " + name);
}
}
return returnType;

View File

@ -41,12 +41,17 @@ public class TypedMethodCall implements TypedExpression, TypedStatement {
@Override
public Type typeCheck(TypedProgram typedProgram) {
TypedClass currentClass = typedProgram.getCurrentClass();
String ownerChainName = null;
if (currentClass.isCurrentMainMethodPresent() && recipient.getRecursiveOwnerChain() == null) {
throw new RuntimeException("Main Method, is not allowed to have methods, they are not static");
}
if (recipient.getRecursiveOwnerChain() != null) {
ownerChainName = recipient.getRecursiveOwnerChain().getType().getReference();
}
if (!typedProgram.getCurrentClass().getClassName().equals(ownerChainName) && ownerChainName != null) {
if (!currentClass.getClassName().equals(ownerChainName) && ownerChainName != null) {
Optional<Type> matchingMethod = findMatchingMethod(typedProgram.getTypedClass(ownerChainName), recipient.getName());
if (matchingMethod.isPresent()) {
type = matchingMethod.get();
@ -54,8 +59,8 @@ public class TypedMethodCall implements TypedExpression, TypedStatement {
}
}
if (typedProgram.getCurrentClass().isCurrentMethodPresent() || typedProgram.getCurrentClass().isCurrentConstructorPresent()) {
Optional<Type> matchingMethod = findMatchingMethod(typedProgram.getCurrentClass(), recipient.getName());
if (currentClass.isCurrentMethodPresent() || currentClass.isCurrentConstructorPresent()) {
Optional<Type> matchingMethod = findMatchingMethod(currentClass, recipient.getName());
if (matchingMethod.isPresent()) {
type = matchingMethod.get();
return type;

View File

@ -35,29 +35,36 @@ public class TypedNew implements TypedExpression, TypedStatement {
@Override
public Type typeCheck(TypedProgram typedProgram) {
TypedClass currentClass = typedProgram.getCurrentClass();
if (typedProgram.isTypedClassPresent(type.getReference())) {
return Type.REFERENCE(type.getReference());
}
for (var constructor : typedProgram.getCurrentClass().getTypedConstructors()) {
return findMatchingConstructorType(typedProgram, args);
}
private Type findMatchingConstructorType(TypedProgram typedProgram, List<TypedExpression> args) {
TypedClass currentClass = typedProgram.getCurrentClass();
List<TypedConstructor> constructors = currentClass.getTypedConstructors();
for (var constructor : constructors) {
if (constructor.getTypedParameters().size() == args.size()) {
boolean valid = true;
for (int i = 0; i < args.size(); i++) {
if (!constructor.getTypedParameters().get(i).getType().equals(args.get(i).typeCheck(typedProgram))) {
boolean typeOfPara = constructor.getTypedParameters().get(i).getType().equals(args.get(i).typeCheck(typedProgram));
if (!typeOfPara) {
valid = false;
break;
}
}
if (valid) {
return Type.REFERENCE(typedProgram.getCurrentClass().getClassName());
return Type.REFERENCE(currentClass.getClassName());
}
}
}
throw new RuntimeException("No matching constructor found");
}
@Override
public void codeGen(MethodContext ctx) {
ctx.getMv().visitTypeInsn(Opcodes.NEW, type.getReference());

View File

@ -47,9 +47,11 @@ public class TypedProgram {
public boolean isClassWithNamePresent(String className) {
return typedClasses.stream().anyMatch(clas -> clas.getClassName().equals(className));
}
public Type getTypeOfFieldNameInClass(String className, String fieldName) {
return typedClasses.stream().filter(clas -> clas.getClassName().equals(className)).findFirst().get().getFieldType(fieldName);
}
public TypedClass getTypedClass(String className) {
return typedClasses.stream().filter(clas -> clas.getClassName().equals(className)).findFirst().get();
}
@ -71,7 +73,7 @@ public class TypedProgram {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
TypedProgram other = (TypedProgram) obj;
if(typedClasses.equals(other.typedClasses) &&
if (typedClasses.equals(other.typedClasses) &&
(currentClass == null && other.currentClass == null
|| currentClass.equals(other.currentClass))) {
return true;

View File

@ -36,13 +36,16 @@ public class TypedReturn implements TypedStatement {
@Override
public Type typeCheck(TypedProgram typedProgram) {
if (typedProgram.getCurrentClass().isCurrentMethodPresent()) {
if (typedProgram.getCurrentClass().getCurrentMethod().getReturnType().getKind() != this.type.getKind()) {
TypedClass currentClass = typedProgram.getCurrentClass();
TypedMethod currentMethod = currentClass.getCurrentMethod();
if (currentClass.isCurrentMethodPresent()) {
if (currentMethod.getReturnType().getKind() != this.type.getKind()) {
StringBuilder exp = new StringBuilder();
exp.append("\nMismatched return type: ");
exp.append("\nExpected: ").append(typedProgram.getCurrentClass().getCurrentMethod().getReturnType().getKind());
exp.append("\nExpected: ").append(currentMethod.getReturnType().getKind());
exp.append("\nActual: ").append(this.type.getKind());
exp.append("\nMethod name: ").append(typedProgram.getCurrentClass().getCurrentMethod().getName());
exp.append("\nMethod name: ").append(currentMethod.getName());
throw new RuntimeException(exp.toString());
}
}