mirror of
https://github.com/JonathanFleischmann/CompilerULTIMATE.git
synced 2024-12-27 08:18:03 +00:00
Refactored typedAST
This commit is contained in:
parent
ae3280fb67
commit
b4fd003f8e
@ -31,13 +31,13 @@ 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(typedProgram.getCurrentClass().isCurrentMainMethodPresent() && location.getField() && location.getRecursiveOwnerChain() == null){
|
||||
if (currentClass.isCurrentMainMethodPresent() && location.getField() && location.getRecursiveOwnerChain() == null) {
|
||||
throw new RuntimeException("Main Method, is not allowed to have fields, they are not static");
|
||||
}
|
||||
|
||||
@ -74,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");
|
||||
}
|
||||
@ -84,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");
|
||||
}
|
||||
@ -92,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 {
|
||||
@ -116,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 {
|
||||
|
@ -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 {
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,6 @@ public class TypedBoolLiteral implements TypedExpression {
|
||||
private Boolean value;
|
||||
private Type type;
|
||||
|
||||
|
||||
public TypedBoolLiteral(BoolLiteral unTypedBoolLiteral) {
|
||||
convertToTypedBoolLiteral(unTypedBoolLiteral);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
@ -36,7 +37,7 @@ public class TypedClass implements TypedNode {
|
||||
isMainCurrentMethod = false;
|
||||
}
|
||||
|
||||
public TypedClass(String className,List<TypedDeclaration> typedDeclarations, List<TypedMethod> typedMethods, List<TypedConstructor> typedConstructors, TypedMain typedMain, TypedMethod currentMethod, TypedConstructor currentConstructor, Type type) {
|
||||
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;
|
||||
@ -47,17 +48,6 @@ public class TypedClass implements TypedNode {
|
||||
this.type = type;
|
||||
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 void convertMethodsAndConstructorsAndFields(TypedProgram typedProgram, Class c) {
|
||||
// Am Anfang werden die Attribute, die Konstruktoren und Methoden in die jeweilige Liste eingefügt.
|
||||
@ -108,11 +98,31 @@ public class TypedClass implements TypedNode {
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
@ -188,6 +198,7 @@ public class TypedClass implements TypedNode {
|
||||
public boolean isCurrentConstructorPresent() {
|
||||
return currentConstructor != null;
|
||||
}
|
||||
|
||||
public boolean isCurrentMainMethodPresent() {
|
||||
return isMainCurrentMethod;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -20,7 +20,6 @@ public class TypedIntLiteral implements TypedExpression {
|
||||
private Integer value;
|
||||
private Type type;
|
||||
|
||||
|
||||
public TypedIntLiteral(IntLiteral unTypedIntLiteral) {
|
||||
convertToTypedIntLiteral(unTypedIntLiteral);
|
||||
}
|
||||
|
@ -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");
|
||||
|
@ -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()));
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -41,8 +41,9 @@ public class TypedMethodCall implements TypedExpression, TypedStatement {
|
||||
|
||||
@Override
|
||||
public Type typeCheck(TypedProgram typedProgram) {
|
||||
TypedClass currentClass = typedProgram.getCurrentClass();
|
||||
String ownerChainName = null;
|
||||
if (typedProgram.getCurrentClass().isCurrentMainMethodPresent() && recipient.getRecursiveOwnerChain() == null) {
|
||||
if (currentClass.isCurrentMainMethodPresent() && recipient.getRecursiveOwnerChain() == null) {
|
||||
throw new RuntimeException("Main Method, is not allowed to have methods, they are not static");
|
||||
}
|
||||
|
||||
@ -50,7 +51,7 @@ public class TypedMethodCall implements TypedExpression, TypedStatement {
|
||||
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();
|
||||
@ -58,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;
|
||||
|
@ -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());
|
||||
|
@ -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;
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user