Replaced the TypedClass to TypedProgram in typeCheck and others convert methods

This commit is contained in:
ahmad 2024-05-14 22:54:38 +02:00
parent f5cc94316e
commit 98a46b7679
26 changed files with 294 additions and 358 deletions

View File

@ -98,6 +98,8 @@ public class Compiler {
} }
public static void main(String[] args) { public static void main(String[] args) {
generateByteCodeFileFromFile(List.of("src/main/resources/JavaTestfiles/ComplexClass.java"), List.of("ComplexClass")); generateByteCodeFileFromFile(List.of("src/main/resources/JavaTestfiles/ClassWithConstructor.java",
"src/main/resources/JavaTestfiles/ClassWithConstructorAndMethodCall.java"),
List.of("ClassWithConstructor","ClassWithConstructorAndMethodCall"));
} }
} }

View File

@ -1,53 +1,50 @@
package de.maishai.typedast.Help; package de.maishai.typedast.Help;
import de.maishai.ast.records.*; import de.maishai.ast.records.*;
import de.maishai.typedast.Type;
import de.maishai.typedast.TypedExpression; import de.maishai.typedast.TypedExpression;
import de.maishai.typedast.typedclass.*; import de.maishai.typedast.typedclass.*;
import java.util.Map;
public class TypedExpressionHelp { public class TypedExpressionHelp {
public static TypedExpression convertExpression( TypedClass clas, Expression expression) { public static TypedExpression convertExpression( TypedProgram typedProgram, Expression expression) {
if (expression instanceof BoolLiteral boolLiteral) { if (expression instanceof BoolLiteral boolLiteral) {
TypedBoolLiteral typedBoolLiteral = new TypedBoolLiteral( clas, boolLiteral); TypedBoolLiteral typedBoolLiteral = new TypedBoolLiteral( typedProgram, boolLiteral);
typedBoolLiteral.typeCheck( clas); typedBoolLiteral.typeCheck( typedProgram);
return typedBoolLiteral; return typedBoolLiteral;
} }
else if (expression instanceof CharLiteral charLiteral) { else if (expression instanceof CharLiteral charLiteral) {
TypedCharLiteral typedCharLiteral = new TypedCharLiteral( clas, charLiteral); TypedCharLiteral typedCharLiteral = new TypedCharLiteral( typedProgram, charLiteral);
typedCharLiteral.typeCheck( clas); typedCharLiteral.typeCheck( typedProgram);
return typedCharLiteral; return typedCharLiteral;
} }
else if (expression instanceof IntLiteral intLiteral) { else if (expression instanceof IntLiteral intLiteral) {
TypedIntLiteral typedIntLiteral = new TypedIntLiteral( clas, intLiteral); TypedIntLiteral typedIntLiteral = new TypedIntLiteral( typedProgram, intLiteral);
typedIntLiteral.typeCheck( clas); typedIntLiteral.typeCheck( typedProgram);
return typedIntLiteral; return typedIntLiteral;
} }
else if (expression instanceof Binary binary) { else if (expression instanceof Binary binary) {
TypedBinary typedBinary = new TypedBinary( clas, binary); TypedBinary typedBinary = new TypedBinary( typedProgram, binary);
typedBinary.typeCheck( clas); typedBinary.typeCheck( typedProgram);
return typedBinary; return typedBinary;
} }
else if (expression instanceof FieldVarAccess fieldVarAccess) { else if (expression instanceof FieldVarAccess fieldVarAccess) {
TypedFieldVarAccess typedFieldVarAccess = new TypedFieldVarAccess( clas, fieldVarAccess); TypedFieldVarAccess typedFieldVarAccess = new TypedFieldVarAccess( typedProgram, fieldVarAccess);
typedFieldVarAccess.typeCheck( clas); typedFieldVarAccess.typeCheck( typedProgram);
return typedFieldVarAccess; return typedFieldVarAccess;
} }
else if (expression instanceof MethodCall methodCall) { else if (expression instanceof MethodCall methodCall) {
TypedMethodCall typedMethodCall = new TypedMethodCall( clas, methodCall); TypedMethodCall typedMethodCall = new TypedMethodCall( typedProgram, methodCall);
typedMethodCall.typeCheck( clas); typedMethodCall.typeCheck( typedProgram);
return typedMethodCall; return typedMethodCall;
} }
else if (expression instanceof New newStmt) { else if (expression instanceof New newStmt) {
TypedNew typedNew = new TypedNew( clas, newStmt); TypedNew typedNew = new TypedNew( typedProgram, newStmt);
typedNew.typeCheck( clas); typedNew.typeCheck( typedProgram);
return typedNew; return typedNew;
} }
else if (expression instanceof Unary unary) { else if (expression instanceof Unary unary) {
TypedUnary typedUnary = new TypedUnary( clas, unary); TypedUnary typedUnary = new TypedUnary( typedProgram, unary);
typedUnary.typeCheck( clas); typedUnary.typeCheck( typedProgram);
return typedUnary; return typedUnary;
} else { } else {
return null; return null;

View File

@ -1,7 +1,7 @@
package de.maishai.typedast; package de.maishai.typedast;
import de.maishai.typedast.typedclass.TypedClass; import de.maishai.typedast.typedclass.TypedProgram;
public interface TypedNode { public interface TypedNode {
Type typeCheck(TypedClass clas); Type typeCheck(TypedProgram typedProgram);
} }

View File

@ -1,18 +1,14 @@
package de.maishai.typedast.typedclass; package de.maishai.typedast.typedclass;
import de.maishai.ast.records.Assignment; import de.maishai.ast.records.Assignment;
import de.maishai.ast.records.Expression;
import de.maishai.typedast.MethodContext; import de.maishai.typedast.MethodContext;
import de.maishai.typedast.TypedExpression; import de.maishai.typedast.TypedExpression;
import de.maishai.typedast.TypedStatement; import de.maishai.typedast.TypedStatement;
import de.maishai.typedast.Type; import de.maishai.typedast.Type;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;
import java.util.Map;
import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression; import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression;
@Data @Data
@ -22,39 +18,39 @@ public class TypedAssignment implements TypedStatement {
private TypedFieldVarAccess location; private TypedFieldVarAccess location;
private Type type; private Type type;
public TypedAssignment(TypedClass clas, Assignment untyped) { public TypedAssignment(TypedProgram typedProgram, Assignment untyped) {
convertToTypedAssignment(clas, untyped); convertToTypedAssignment(typedProgram, untyped);
} }
public void convertToTypedAssignment(TypedClass clas, Assignment untyped) { public void convertToTypedAssignment(TypedProgram typedProgram, Assignment untyped) {
value = convertExpression(clas, untyped.value()); value = convertExpression(typedProgram, untyped.value());
location = new TypedFieldVarAccess(clas, untyped.location()); location = new TypedFieldVarAccess(typedProgram, untyped.location());
} }
@Override @Override
public Type typeCheck(TypedClass clas) { public Type typeCheck(TypedProgram typedProgram) {
Type typeLeft = null; Type typeLeft = null;
if (clas.isThereField(location.getName())) { if (typedProgram.getCurrentClass().isThereField(location.getName())) {
typeLeft = clas.getFieldType(location.getName()); typeLeft = typedProgram.getCurrentClass().getFieldType(location.getName());
} else { } else {
if (clas.isCurrentMethodPresent() && !clas.isCurrentConstructorPresent()) { if (typedProgram.getCurrentClass().isCurrentMethodPresent() && !typedProgram.getCurrentClass().isCurrentConstructorPresent()) {
if (clas.getCurrentMethod().isLocalVariableInMethod(location.getName())) { if (typedProgram.getCurrentClass().getCurrentMethod().isLocalVariableInMethod(location.getName())) {
typeLeft = clas.getCurrentMethod().getLocalVariableType(location.getName()); typeLeft = typedProgram.getCurrentClass().getCurrentMethod().getLocalVariableType(location.getName());
} else { } else {
throw new RuntimeException("Variable " + location.getName() + " not declared in method"); throw new RuntimeException("Variable " + location.getName() + " not declared in method");
} }
} }
if (!clas.isCurrentMethodPresent() && clas.isCurrentConstructorPresent()) { if (!typedProgram.getCurrentClass().isCurrentMethodPresent() && typedProgram.getCurrentClass().isCurrentConstructorPresent()) {
if (clas.getCurrentConstructor().isLocalVariableInConstructor(location.getName())) { if (typedProgram.getCurrentClass().getCurrentConstructor().isLocalVariableInConstructor(location.getName())) {
typeLeft = clas.getCurrentConstructor().getLocalVariableType(location.getName()); typeLeft = typedProgram.getCurrentClass().getCurrentConstructor().getLocalVariableType(location.getName());
} else { } else {
throw new RuntimeException("Variable " + location.getName() + " not declared in constructor"); throw new RuntimeException("Variable " + location.getName() + " not declared in constructor");
} }
} }
} }
Type typeRight = value.typeCheck(clas); Type typeRight = value.typeCheck(typedProgram);
if (typeLeft.equals(typeRight)) { if (typeLeft.equals(typeRight)) {
type = typeLeft; type = typeLeft;

View File

@ -8,9 +8,6 @@ import de.maishai.typedast.Type;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.objectweb.asm.MethodVisitor;
import java.util.Map;
import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression; import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression;
@ -23,20 +20,20 @@ public class TypedBinary implements TypedExpression {
private TypedExpression right; private TypedExpression right;
private Type type; private Type type;
public TypedBinary(TypedClass clas, Binary unTypedBinary) { public TypedBinary(TypedProgram typedProgram, Binary unTypedBinary) {
convertToTypedBinary(clas, unTypedBinary); convertToTypedBinary(typedProgram, unTypedBinary);
} }
public void convertToTypedBinary(TypedClass clas, Binary unTypedBinary) { public void convertToTypedBinary(TypedProgram typedProgram, Binary unTypedBinary) {
left = convertExpression(clas, unTypedBinary.left()); left = convertExpression(typedProgram, unTypedBinary.left());
right = convertExpression(clas, unTypedBinary.right()); right = convertExpression(typedProgram, unTypedBinary.right());
op = unTypedBinary.op(); op = unTypedBinary.op();
} }
@Override @Override
public Type typeCheck(TypedClass clas) { public Type typeCheck(TypedProgram typedProgram) {
Type leftType = left.typeCheck(clas); Type leftType = left.typeCheck(typedProgram);
Type rightType = right.typeCheck(clas); Type rightType = right.typeCheck(typedProgram);
if (op == Operator.ADD || op == Operator.SUB || op == Operator.MUL) { if (op == Operator.ADD || op == Operator.SUB || op == Operator.MUL) {
if (leftType == Type.INT && rightType == Type.INT) { if (leftType == Type.INT && rightType == Type.INT) {

View File

@ -8,11 +8,9 @@ import de.maishai.typedast.TypedStatement;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.objectweb.asm.MethodVisitor;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@ -23,8 +21,8 @@ public class TypedBlock implements TypedNode {
private Type type; private Type type;
public TypedBlock(TypedClass clas, Block unTypedBlock) { public TypedBlock(TypedProgram typedProgram, Block unTypedBlock) {
convertToTypedBlock(clas, unTypedBlock); convertToTypedBlock(typedProgram, unTypedBlock);
} }
public TypedBlock(List<TypedLocalVariable> vars, List<TypedStatement> stmts) { public TypedBlock(List<TypedLocalVariable> vars, List<TypedStatement> stmts) {
@ -32,56 +30,56 @@ public class TypedBlock implements TypedNode {
this.stmts = stmts; this.stmts = stmts;
} }
public void convertToTypedBlock(TypedClass clas, Block unTypedBlock) { public void convertToTypedBlock(TypedProgram typedProgram, Block unTypedBlock) {
if (unTypedBlock == null) { if (unTypedBlock == null) {
return; return;
} }
for (Declaration var : unTypedBlock.localVariables()) { for (Declaration var : unTypedBlock.localVariables()) {
vars.add(new TypedLocalVariable(clas, var)); vars.add(new TypedLocalVariable(typedProgram, var));
} }
for (var stmt : unTypedBlock.stmts()) { for (var stmt : unTypedBlock.stmts()) {
if (stmt instanceof Assignment assignment) { if (stmt instanceof Assignment assignment) {
TypedAssignment typedAssignment = new TypedAssignment(clas, assignment); TypedAssignment typedAssignment = new TypedAssignment(typedProgram, assignment);
typedAssignment.typeCheck(clas); typedAssignment.typeCheck(typedProgram);
stmts.add(typedAssignment); stmts.add(typedAssignment);
continue; continue;
} }
if (stmt instanceof For forStmt) { if (stmt instanceof For forStmt) {
TypedFor typedFor = new TypedFor(clas, forStmt); TypedFor typedFor = new TypedFor(typedProgram, forStmt);
typedFor.typeCheck(clas); typedFor.typeCheck(typedProgram);
stmts.add(typedFor); stmts.add(typedFor);
continue; continue;
} }
if (stmt instanceof IfElse ifElse) { if (stmt instanceof IfElse ifElse) {
TypedIfElse typedIfElse = new TypedIfElse(clas, ifElse); TypedIfElse typedIfElse = new TypedIfElse(typedProgram, ifElse);
typedIfElse.typeCheck(clas); typedIfElse.typeCheck(typedProgram);
stmts.add(typedIfElse); stmts.add(typedIfElse);
continue; continue;
} }
if (stmt instanceof While whileStmt) { if (stmt instanceof While whileStmt) {
TypedWhile typedWhile = new TypedWhile(clas, whileStmt); TypedWhile typedWhile = new TypedWhile(typedProgram, whileStmt);
typedWhile.typeCheck(clas); typedWhile.typeCheck(typedProgram);
stmts.add(typedWhile); stmts.add(typedWhile);
continue; continue;
} }
if (stmt instanceof DoWhile doWhile) { if (stmt instanceof DoWhile doWhile) {
TypedDoWhile typedDoWhile = new TypedDoWhile(clas, doWhile); TypedDoWhile typedDoWhile = new TypedDoWhile(typedProgram, doWhile);
typedDoWhile.typeCheck(clas); typedDoWhile.typeCheck(typedProgram);
stmts.add(typedDoWhile); stmts.add(typedDoWhile);
continue; continue;
} }
if (stmt instanceof Return returnStmt) { if (stmt instanceof Return returnStmt) {
TypedReturn typedReturn = new TypedReturn(clas, returnStmt); TypedReturn typedReturn = new TypedReturn(typedProgram, returnStmt);
typedReturn.typeCheck(clas); typedReturn.typeCheck(typedProgram);
stmts.add(typedReturn); stmts.add(typedReturn);
continue; continue;
} }
if (stmt instanceof New newStmt) { if (stmt instanceof New newStmt) {
TypedNew typedNew = new TypedNew(clas, newStmt); TypedNew typedNew = new TypedNew(typedProgram, newStmt);
typedNew.typeCheck(clas); typedNew.typeCheck(typedProgram);
stmts.add(typedNew); stmts.add(typedNew);
continue; continue;
} }
@ -92,19 +90,19 @@ public class TypedBlock implements TypedNode {
} }
if (stmt instanceof MethodCall methodCall) { if (stmt instanceof MethodCall methodCall) {
TypedMethodCall typedMethodCall = new TypedMethodCall(clas, methodCall); TypedMethodCall typedMethodCall = new TypedMethodCall(typedProgram, methodCall);
typedMethodCall.typeCheck(clas); typedMethodCall.typeCheck(typedProgram);
stmts.add(typedMethodCall); stmts.add(typedMethodCall);
} }
} }
this.typeCheck(clas); this.typeCheck(typedProgram);
} }
@Override @Override
public Type typeCheck(TypedClass clas) { public Type typeCheck(TypedProgram typedProgram) {
Type chekType = null; Type chekType = null;
for (TypedStatement stmt : stmts) { for (TypedStatement stmt : stmts) {
stmt.typeCheck(clas); stmt.typeCheck(typedProgram);
if(stmt instanceof TypedReturn returnStmt) { if(stmt instanceof TypedReturn returnStmt) {
chekType = returnStmt.getType(); chekType = returnStmt.getType();
} }

View File

@ -1,18 +1,13 @@
package de.maishai.typedast.typedclass; package de.maishai.typedast.typedclass;
import de.maishai.ast.records.BoolLiteral; import de.maishai.ast.records.BoolLiteral;
import de.maishai.ast.records.Node;
import de.maishai.typedast.MethodContext; import de.maishai.typedast.MethodContext;
import de.maishai.typedast.TypedExpression; import de.maishai.typedast.TypedExpression;
import de.maishai.typedast.TypedNode;
import de.maishai.typedast.Type; import de.maishai.typedast.Type;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;
import java.util.Map;
@Data @Data
@NoArgsConstructor @NoArgsConstructor
public class TypedBoolLiteral implements TypedExpression { public class TypedBoolLiteral implements TypedExpression {
@ -21,17 +16,17 @@ public class TypedBoolLiteral implements TypedExpression {
private Type type; private Type type;
public TypedBoolLiteral(TypedClass clas, BoolLiteral unTypedBoolLiteral) { public TypedBoolLiteral(TypedProgram typedProgram, BoolLiteral unTypedBoolLiteral) {
convertToTypedBoolLiteral(clas, unTypedBoolLiteral); convertToTypedBoolLiteral(typedProgram, unTypedBoolLiteral);
} }
public void convertToTypedBoolLiteral(TypedClass clas, BoolLiteral unTypedBoolLiteral) { public void convertToTypedBoolLiteral(TypedProgram typedProgram, BoolLiteral unTypedBoolLiteral) {
value = unTypedBoolLiteral.value(); value = unTypedBoolLiteral.value();
type = Type.BOOL; type = Type.BOOL;
} }
@Override @Override
public Type typeCheck(TypedClass clas) { public Type typeCheck(TypedProgram typedProgram) {
return type; return type;
} }

View File

@ -1,15 +1,10 @@
package de.maishai.typedast.typedclass; package de.maishai.typedast.typedclass;
import de.maishai.ast.records.Break; import de.maishai.ast.records.Break;
import de.maishai.ast.records.Node;
import de.maishai.typedast.MethodContext; import de.maishai.typedast.MethodContext;
import de.maishai.typedast.TypedNode;
import de.maishai.typedast.TypedStatement; import de.maishai.typedast.TypedStatement;
import de.maishai.typedast.Type; import de.maishai.typedast.Type;
import lombok.Data; import lombok.Data;
import org.objectweb.asm.MethodVisitor;
import java.util.Map;
@Data @Data
public class TypedBreak implements TypedStatement { public class TypedBreak implements TypedStatement {
@ -20,7 +15,7 @@ public class TypedBreak implements TypedStatement {
} }
@Override @Override
public Type typeCheck(TypedClass clas) { public Type typeCheck(TypedProgram typedProgram) {
return type; return type;
} }

View File

@ -1,32 +1,27 @@
package de.maishai.typedast.typedclass; package de.maishai.typedast.typedclass;
import de.maishai.ast.records.CharLiteral; import de.maishai.ast.records.CharLiteral;
import de.maishai.ast.records.Node;
import de.maishai.typedast.MethodContext; import de.maishai.typedast.MethodContext;
import de.maishai.typedast.TypedExpression; import de.maishai.typedast.TypedExpression;
import de.maishai.typedast.TypedNode;
import de.maishai.typedast.Type; import de.maishai.typedast.Type;
import lombok.Data; import lombok.Data;
import org.objectweb.asm.MethodVisitor;
import java.util.Map;
@Data @Data
public class TypedCharLiteral implements TypedExpression { public class TypedCharLiteral implements TypedExpression {
private char value; private char value;
private Type type; private Type type;
public TypedCharLiteral(TypedClass clas, CharLiteral unTypedCharLiteral) { public TypedCharLiteral(TypedProgram typedProgram, CharLiteral unTypedCharLiteral) {
convertToCharLiteral(clas, unTypedCharLiteral); convertToCharLiteral(typedProgram, unTypedCharLiteral);
} }
public void convertToCharLiteral(TypedClass clas, CharLiteral unTypedCharLiteral) { public void convertToCharLiteral(TypedProgram typedProgram, CharLiteral unTypedCharLiteral) {
value = unTypedCharLiteral.value(); value = unTypedCharLiteral.value();
type = Type.CHAR; type = Type.CHAR;
} }
@Override @Override
public Type typeCheck(TypedClass clas) { public Type typeCheck(TypedProgram typedProgram) {
return type; return type;
} }

View File

@ -14,9 +14,7 @@ import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
@Data @Data
@AllArgsConstructor @AllArgsConstructor
@ -30,45 +28,12 @@ public class TypedClass implements TypedNode {
private TypedConstructor currentConstructor; private TypedConstructor currentConstructor;
private Type type; private Type type;
public TypedClass(Class c) { public TypedClass(TypedProgram typedProgram, Class c) {
convertToTypedClass(c); className = c.classname();
type = Type.REFERENCE(className);
convertMethodsAndConstructorsAndFields(typedProgram, c);
} }
public void enterCurrentMethod(TypedMethod method) {
currentMethod = method;
}
public void exitCurrentMethod() {
currentMethod = null;
}
public void enterCurrentConstructor(TypedConstructor constructor) {
currentConstructor = constructor;
}
public void exitCurrentConstructor() {
currentConstructor = null;
}
public boolean isCurrentMethodPresent() {
return currentMethod != null;
}
public boolean isCurrentConstructorPresent() {
return currentConstructor != null;
}
public boolean isParameterNameInCurrentMethod(String parameterName) {
if (currentMethod == null) {
return false;
}
for (TypedParameter p : currentMethod.getTypedParameters()) {
if (p.getParaName().equals(parameterName)) {
return true;
}
}
return false;
}
public boolean isParameterNameInCurrentConstructor(String parameterName) { public boolean isParameterNameInCurrentConstructor(String parameterName) {
if (currentConstructor == null) { if (currentConstructor == null) {
@ -82,28 +47,27 @@ public class TypedClass implements TypedNode {
return false; return false;
} }
public void convertToTypedClass(Class c) { public void convertMethodsAndConstructorsAndFields(TypedProgram typedProgram, Class c){
className = c.classname();
type = Type.REFERENCE(className);
// Am Anfang werden die Attribute, die Konstruktoren und Methoden in die jeweilige Liste eingefügt. // Am Anfang werden die Attribute, die Konstruktoren und Methoden in die jeweilige Liste eingefügt.
// damit die Methoden verwendet werden können, bevor deren Blöcke ausgeführt werden // damit die Methoden verwendet werden können, bevor deren Blöcke ausgeführt werden
for (Declaration declaration : c.fieldDeclarations()) { for (Declaration declaration : c.fieldDeclarations()) {
typedDeclarations.add(new TypedDeclaration(this, declaration)); typedDeclarations.add(new TypedDeclaration(typedProgram, declaration));
} }
for (Constructor constructor : c.constructors()) { for (Constructor constructor : c.constructors()) {
typedConstructors.add(new TypedConstructor(this, constructor)); typedConstructors.add(new TypedConstructor(typedProgram, constructor));
} }
for (Method method : c.methods()) { for (Method method : c.methods()) {
typedMethods.add(new TypedMethod(this, method)); typedMethods.add(new TypedMethod(typedProgram, method));
}
} }
public void covertBlocksOfConstructorsAndMethods(TypedProgram typedProgram, Class c){
// Hier werden die Blöcke der Konstruktoren ausgeführt // Hier werden die Blöcke der Konstruktoren ausgeführt
int i = 0; int i = 0;
for (Constructor constructor : c.constructors()) { for (Constructor constructor : c.constructors()) {
enterCurrentConstructor(typedConstructors.get(i)); enterCurrentConstructor(typedConstructors.get(i));
typedConstructors.get(i).convertToBlock(this, constructor); typedConstructors.get(i).convertToBlock(typedProgram, constructor);
exitCurrentConstructor(); exitCurrentConstructor();
i++; i++;
} }
@ -111,24 +75,17 @@ public class TypedClass implements TypedNode {
int j = 0; int j = 0;
for (Method method : c.methods()) { for (Method method : c.methods()) {
enterCurrentMethod(typedMethods.get(j)); enterCurrentMethod(typedMethods.get(j));
typedMethods.get(j).convertToTypedBlock(this, method); typedMethods.get(j).convertToTypedBlock(typedProgram, method);
exitCurrentMethod(); exitCurrentMethod();
j++; j++;
} }
} }
@Override @Override
public Type typeCheck(TypedClass clas) { public Type typeCheck(TypedProgram typedProgram) {
return type; return type;
} }
public TypedNode startConversion(Program p) {
Map<String, Type> local = new HashMap<>();
Class c = p.classes().get(0);
return new TypedClass(c);
}
public boolean isParameterWitNameInMethod(String parameterName) { public boolean isParameterWitNameInMethod(String parameterName) {
for (TypedMethod m : typedMethods) { for (TypedMethod m : typedMethods) {
for (TypedParameter p : m.getTypedParameters()) { for (TypedParameter p : m.getTypedParameters()) {
@ -189,13 +146,28 @@ public class TypedClass implements TypedNode {
return null; return null;
} }
public Type getMethodType(String methodName) { public void enterCurrentMethod(TypedMethod method) {
for (TypedMethod m : typedMethods) { currentMethod = method;
if (m.getName().equals(methodName)) {
return m.getReturnType();
} }
public void exitCurrentMethod() {
currentMethod = null;
} }
return null;
public void enterCurrentConstructor(TypedConstructor constructor) {
currentConstructor = constructor;
}
public void exitCurrentConstructor() {
currentConstructor = null;
}
public boolean isCurrentMethodPresent() {
return currentMethod != null;
}
public boolean isCurrentConstructorPresent() {
return currentConstructor != null;
} }

View File

@ -29,8 +29,8 @@ public class TypedConstructor implements TypedNode {
this.typedBlock = typedBlock; this.typedBlock = typedBlock;
} }
public TypedConstructor(TypedClass clas, Constructor unTypedConstructor) { public TypedConstructor(TypedProgram typedProgram, Constructor unTypedConstructor) {
convertToTypedConstructor(clas, unTypedConstructor); convertToTypedConstructor(typedProgram, unTypedConstructor);
} }
public boolean isLocalVariablePresent(String localVarName) { public boolean isLocalVariablePresent(String localVarName) {
@ -49,23 +49,23 @@ public class TypedConstructor implements TypedNode {
return localVariables.stream().filter(localVariable -> localVariable.getName().equals(localVarName)).findFirst().get().getType(); return localVariables.stream().filter(localVariable -> localVariable.getName().equals(localVarName)).findFirst().get().getType();
} }
public void convertToTypedConstructor(TypedClass clas, Constructor unTypedConstructor) { public void convertToTypedConstructor(TypedProgram typedProgram, Constructor unTypedConstructor) {
name = unTypedConstructor.className(); name = unTypedConstructor.className();
for (Parameter param : unTypedConstructor.params()) { for (Parameter param : unTypedConstructor.params()) {
typedParameters.add(new TypedParameter(clas, param)); typedParameters.add(new TypedParameter(typedProgram, param));
} }
type = Type.VOID; type = Type.VOID;
} }
public void convertToBlock(TypedClass clas, Constructor unTypedConstructor) { public void convertToBlock(TypedProgram typedProgram, Constructor unTypedConstructor) {
this.typedBlock = new TypedBlock(clas, unTypedConstructor.block()); this.typedBlock = new TypedBlock(typedProgram, unTypedConstructor.block());
typeCheck(clas); typeCheck(typedProgram);
} }
@Override @Override
public Type typeCheck(TypedClass clas) { public Type typeCheck(TypedProgram typedProgram) {
type = typedBlock.typeCheck(clas); type = typedBlock.typeCheck(typedProgram);
if (type != Type.VOID) { if (type != Type.VOID) {
throw new RuntimeException("Constructor must not habe a return statement"); throw new RuntimeException("Constructor must not habe a return statement");
} }

View File

@ -1,18 +1,14 @@
package de.maishai.typedast.typedclass; package de.maishai.typedast.typedclass;
import de.maishai.ast.records.Declaration; import de.maishai.ast.records.Declaration;
import de.maishai.typedast.MethodContext;
import de.maishai.typedast.TypedNode; import de.maishai.typedast.TypedNode;
import de.maishai.typedast.Type; import de.maishai.typedast.Type;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.objectweb.asm.ClassWriter; import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;
import java.util.Map;
import static de.maishai.typedast.Type.Kind.REFERENCE; import static de.maishai.typedast.Type.Kind.REFERENCE;
@Data @Data
@ -22,24 +18,24 @@ public final class TypedDeclaration implements TypedNode {
private String name; private String name;
private Type type; private Type type;
public TypedDeclaration(TypedClass clas, Declaration declaration) { public TypedDeclaration(TypedProgram typedProgram, Declaration declaration) {
convertToTypedDeclaration(clas, declaration); convertToTypedDeclaration(typedProgram, declaration);
} }
public void convertToTypedDeclaration(TypedClass clas, Declaration declaration) { public void convertToTypedDeclaration(TypedProgram typedProgram, Declaration declaration) {
name = declaration.name(); name = declaration.name();
type = declaration.type(); type = declaration.type();
typeCheck(clas); typeCheck(typedProgram);
} }
@Override @Override
public Type typeCheck(TypedClass clas) { public Type typeCheck(TypedProgram typedProgram) {
if (clas.isThereField(name)) { if (typedProgram.getCurrentClass().isThereField(name)) {
throw new RuntimeException("Field " + name + " already declared"); throw new RuntimeException("Field " + name + " already declared");
} }
if (type.getKind() == REFERENCE) { if (type.getKind() == REFERENCE) {
if (!type.getReference().equals(clas.getClassName())) { if (!type.getReference().equals(typedProgram.getCurrentClass().getClassName())) {
throw new RuntimeException("Field " + name + " has wrong type"); throw new RuntimeException("Field " + name + " has wrong type");
} }

View File

@ -3,9 +3,6 @@ package de.maishai.typedast.typedclass;
import de.maishai.ast.records.*; import de.maishai.ast.records.*;
import de.maishai.typedast.*; import de.maishai.typedast.*;
import lombok.Data; import lombok.Data;
import org.objectweb.asm.MethodVisitor;
import java.util.Map;
import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression; import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression;
@ -15,21 +12,21 @@ public class TypedDoWhile implements TypedStatement {
private TypedExpression cond; private TypedExpression cond;
private Type type; private Type type;
public TypedDoWhile(TypedClass clas, DoWhile unTypedDoWhile) { public TypedDoWhile(TypedProgram typedProgram, DoWhile unTypedDoWhile) {
convertToTypedDoWhile(clas, unTypedDoWhile); convertToTypedDoWhile(typedProgram, unTypedDoWhile);
} }
public void convertToTypedDoWhile(TypedClass clas, DoWhile unTypedDoWhile) { public void convertToTypedDoWhile(TypedProgram typedProgram, DoWhile unTypedDoWhile) {
typedBlock = new TypedBlock(clas, unTypedDoWhile.block()); typedBlock = new TypedBlock(typedProgram, unTypedDoWhile.block());
cond = convertExpression(clas, unTypedDoWhile.cond()); cond = convertExpression(typedProgram, unTypedDoWhile.cond());
} }
@Override @Override
public Type typeCheck(TypedClass clas) { public Type typeCheck(TypedProgram typedProgram) {
if (cond.typeCheck(clas) != Type.BOOL) { if (cond.typeCheck(typedProgram) != Type.BOOL) {
throw new RuntimeException("Condition must be boolean"); throw new RuntimeException("Condition must be boolean");
} }
typedBlock.typeCheck(clas); typedBlock.typeCheck(typedProgram);
this.type = Type.VOID; this.type = Type.VOID;
return Type.VOID; return Type.VOID;
} }

View File

@ -7,9 +7,6 @@ import de.maishai.typedast.Type;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.objectweb.asm.MethodVisitor;
import java.util.Map;
import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression; import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression;
@ -22,50 +19,50 @@ public class TypedFieldVarAccess implements TypedExpression {
private String name; private String name;
private Type type; private Type type;
public TypedFieldVarAccess(TypedClass clas, FieldVarAccess unTypedFieldVarAccess) { public TypedFieldVarAccess(TypedProgram typedProgram, FieldVarAccess unTypedFieldVarAccess) {
convertToTypedFieldVarAccess(clas, unTypedFieldVarAccess); convertToTypedFieldVarAccess(typedProgram, unTypedFieldVarAccess);
} }
public void convertToTypedFieldVarAccess(TypedClass clas, FieldVarAccess unTypedFieldVarAccess) { public void convertToTypedFieldVarAccess(TypedProgram typedProgram, FieldVarAccess unTypedFieldVarAccess) {
field = unTypedFieldVarAccess.field(); field = unTypedFieldVarAccess.field();
recursiveOwnerChain = convertExpression(clas, unTypedFieldVarAccess.recursiveOwnerChain()); recursiveOwnerChain = convertExpression(typedProgram, unTypedFieldVarAccess.recursiveOwnerChain());
name = unTypedFieldVarAccess.id(); name = unTypedFieldVarAccess.id();
} }
@Override @Override
public Type typeCheck(TypedClass clas) { public Type typeCheck(TypedProgram typedProgram) {
if (field) { if (field) {
if (clas.isThereField(name)) { if (typedProgram.getCurrentClass().isThereField(name)) {
type = clas.getFieldType(name); type = typedProgram.getCurrentClass().getFieldType(name);
return clas.getFieldType(name); return typedProgram.getCurrentClass().getFieldType(name);
}else{ }else{
throw new RuntimeException("Field " + name + " not declared "); throw new RuntimeException("Field " + name + " not declared ");
} }
} else { } else {
if (clas.isCurrentConstructorPresent()) { if (typedProgram.getCurrentClass().isCurrentConstructorPresent()) {
if (clas.isParameterNameInCurrentConstructor(name)) { if (typedProgram.getCurrentClass().isParameterNameInCurrentConstructor(name)) {
type = clas.getParameterTypeInCurrentConstructor(name); type = typedProgram.getCurrentClass().getParameterTypeInCurrentConstructor(name);
return type; return type;
} else if (clas.getCurrentConstructor().isLocalVariablePresent(name)) { } else if (typedProgram.getCurrentClass().getCurrentConstructor().isLocalVariablePresent(name)) {
type = clas.getCurrentConstructor().getLocalVariableType(name); type = typedProgram.getCurrentClass().getCurrentConstructor().getLocalVariableType(name);
return type; return type;
} else if(clas.isThereField(name)){ } else if(typedProgram.getCurrentClass().isThereField(name)){
type = clas.getFieldType(name); type = typedProgram.getCurrentClass().getFieldType(name);
return type; return type;
} }
else { else {
throw new RuntimeException("Variable " + name + " not declared in constructor"); throw new RuntimeException("Variable " + name + " not declared in constructor");
} }
} else if (clas.isCurrentMethodPresent()) { } else if (typedProgram.getCurrentClass().isCurrentMethodPresent()) {
if (clas.isParameterWitNameInMethod(name)) { if (typedProgram.getCurrentClass().isParameterWitNameInMethod(name)) {
type = clas.getParameterTypeInCurrentMethod(name); type = typedProgram.getCurrentClass().getParameterTypeInCurrentMethod(name);
return type; return type;
} else if (clas.getCurrentMethod().isLocalVariablePresent(name)) { } else if (typedProgram.getCurrentClass().getCurrentMethod().isLocalVariablePresent(name)) {
type = clas.getCurrentMethod().getLocalVariableType(name); type = typedProgram.getCurrentClass().getCurrentMethod().getLocalVariableType(name);
return type; return type;
} else if(clas.isThereField(name)){ } else if(typedProgram.getCurrentClass().isThereField(name)){
type = clas.getFieldType(name); type = typedProgram.getCurrentClass().getFieldType(name);
return type; return type;
} }
else { else {

View File

@ -5,9 +5,6 @@ import de.maishai.typedast.*;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.objectweb.asm.MethodVisitor;
import java.util.Map;
import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression; import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression;
@ -21,25 +18,25 @@ public class TypedFor implements TypedStatement {
private TypedBlock typedBlock; private TypedBlock typedBlock;
private Type type; private Type type;
public TypedFor(TypedClass clas, For unTypedFor) { public TypedFor(TypedProgram typedProgram, For unTypedFor) {
convertToTypedFor(clas, unTypedFor); convertToTypedFor(typedProgram, unTypedFor);
} }
public void convertToTypedFor(TypedClass clas, For unTypedFor) { public void convertToTypedFor(TypedProgram typedProgram, For unTypedFor) {
assign = new TypedAssignment(clas, unTypedFor.assign()); assign = new TypedAssignment(typedProgram, unTypedFor.assign());
cond = convertExpression(clas, unTypedFor.cond()); cond = convertExpression(typedProgram, unTypedFor.cond());
inc = new TypedAssignment(clas, unTypedFor.inc()); inc = new TypedAssignment(typedProgram, unTypedFor.inc());
typedBlock = new TypedBlock(clas, unTypedFor.block()); typedBlock = new TypedBlock(typedProgram, unTypedFor.block());
} }
@Override @Override
public Type typeCheck(TypedClass clas) { public Type typeCheck(TypedProgram typedProgram) {
assign.typeCheck(clas); assign.typeCheck(typedProgram);
if (!cond.typeCheck(clas).equals(Type.BOOL)) { if (!cond.typeCheck(typedProgram).equals(Type.BOOL)) {
throw new RuntimeException("Condition must be a boolean"); throw new RuntimeException("Condition must be a boolean");
} }
inc.typeCheck(clas); inc.typeCheck(typedProgram);
type = typedBlock.typeCheck(clas); type = typedBlock.typeCheck(typedProgram);
return type; return type;
} }

View File

@ -5,11 +5,8 @@ import de.maishai.typedast.*;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.objectweb.asm.Label; import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;
import java.util.Map;
import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression; import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression;
@Data @Data
@ -20,35 +17,27 @@ public class TypedIfElse implements TypedStatement {
private TypedBlock elseTypedBlock; private TypedBlock elseTypedBlock;
private Type type; private Type type;
public TypedIfElse(TypedClass clas, IfElse unTypedIfElse) { public TypedIfElse(TypedProgram typedProgram, IfElse unTypedIfElse) {
convertToTypedIfElse(clas, unTypedIfElse); convertToTypedIfElse(typedProgram, unTypedIfElse);
} }
public void convertToTypedIfElse(TypedClass clas, IfElse unTypedIfElse) { public void convertToTypedIfElse(TypedProgram typedProgram, IfElse unTypedIfElse) {
ifTypedBlock = new TypedBlock(clas, unTypedIfElse.ifBlock()); ifTypedBlock = new TypedBlock(typedProgram, unTypedIfElse.ifBlock());
elseTypedBlock = new TypedBlock(clas, unTypedIfElse.elseBlock()); elseTypedBlock = new TypedBlock(typedProgram, unTypedIfElse.elseBlock());
typedCon = convertExpression(clas, unTypedIfElse.cond()); typedCon = convertExpression(typedProgram, unTypedIfElse.cond());
} }
@Override @Override
public Type typeCheck(TypedClass clas) { public Type typeCheck(TypedProgram typedProgram) {
/*
if (typedCon.typeCheck(clas) != Type.BOOL) { if (ifTypedBlock.typeCheck(typedProgram) == elseTypedBlock.typeCheck(typedProgram)) {
throw new RuntimeException("If condition must be a boolean"); type = ifTypedBlock.typeCheck(typedProgram);
} }
if (ifTypedBlock.typeCheck(clas) != Type.VOID) { if (elseTypedBlock.typeCheck(typedProgram) == Type.VOID) {
throw new RuntimeException("If block must be of type void"); type = ifTypedBlock.typeCheck(typedProgram);
} }
*/ if (ifTypedBlock.typeCheck(typedProgram) == Type.VOID) {
//TODO: it still not catching the all cases when return is used type = elseTypedBlock.typeCheck(typedProgram);
if (ifTypedBlock.typeCheck(clas) == elseTypedBlock.typeCheck(clas)) {
type = ifTypedBlock.typeCheck(clas);
}
if (elseTypedBlock.typeCheck(clas) == Type.VOID) {
type = ifTypedBlock.typeCheck(clas);
}
if (ifTypedBlock.typeCheck(clas) == Type.VOID) {
type = elseTypedBlock.typeCheck(clas);
} }
return type; return type;

View File

@ -3,14 +3,10 @@ package de.maishai.typedast.typedclass;
import de.maishai.ast.records.IntLiteral; import de.maishai.ast.records.IntLiteral;
import de.maishai.typedast.MethodContext; import de.maishai.typedast.MethodContext;
import de.maishai.typedast.TypedExpression; import de.maishai.typedast.TypedExpression;
import de.maishai.typedast.TypedNode;
import de.maishai.typedast.Type; import de.maishai.typedast.Type;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.objectweb.asm.MethodVisitor;
import java.util.Map;
@Data @Data
@AllArgsConstructor @AllArgsConstructor
@ -20,17 +16,17 @@ public class TypedIntLiteral implements TypedExpression {
private Type type; private Type type;
public TypedIntLiteral(TypedClass clas, IntLiteral unTypedIntLiteral) { public TypedIntLiteral(TypedProgram typedProgram, IntLiteral unTypedIntLiteral) {
convertToTypedIntLiteral(clas, unTypedIntLiteral); convertToTypedIntLiteral(typedProgram, unTypedIntLiteral);
} }
public void convertToTypedIntLiteral(TypedClass clas, IntLiteral unTypedIntLiteral) { public void convertToTypedIntLiteral(TypedProgram typedProgram, IntLiteral unTypedIntLiteral) {
value = unTypedIntLiteral.value(); value = unTypedIntLiteral.value();
type = Type.INT; type = Type.INT;
} }
@Override @Override
public Type typeCheck(TypedClass clas) { public Type typeCheck(TypedProgram typedProgram) {
return type; return type;
} }

View File

@ -16,30 +16,30 @@ public final class TypedLocalVariable implements TypedNode {
private String name; private String name;
private Type type; private Type type;
public TypedLocalVariable(TypedClass clas, Declaration declaration) { public TypedLocalVariable(TypedProgram typedProgram, Declaration declaration) {
convertToTypedLocalVariable(clas, declaration); convertToTypedLocalVariable(typedProgram, declaration);
} }
public void convertToTypedLocalVariable(TypedClass clas, Declaration declaration) { public void convertToTypedLocalVariable(TypedProgram typedProgram, Declaration declaration) {
name = declaration.name(); name = declaration.name();
type = declaration.type(); type = declaration.type();
typeCheck(clas); typeCheck(typedProgram);
} }
@Override @Override
public Type typeCheck(TypedClass clas) { public Type typeCheck(TypedProgram typedProgram) {
if (clas.isCurrentMethodPresent() && !clas.isCurrentConstructorPresent()) { if (typedProgram.getCurrentClass().isCurrentMethodPresent() && !typedProgram.getCurrentClass().isCurrentConstructorPresent()) {
if (clas.getCurrentMethod().isLocalVariableInMethod(name)) { if (typedProgram.getCurrentClass().getCurrentMethod().isLocalVariableInMethod(name)) {
throw new RuntimeException("Variable " + name + " already declared"); throw new RuntimeException("Variable " + name + " already declared");
} }
clas.getCurrentMethod().getLocalVariables().add(this); typedProgram.getCurrentClass().getCurrentMethod().getLocalVariables().add(this);
return type; return type;
} }
if (!clas.isCurrentMethodPresent() && clas.isCurrentConstructorPresent()) { if (!typedProgram.getCurrentClass().isCurrentMethodPresent() && typedProgram.getCurrentClass().isCurrentConstructorPresent()) {
if (clas.getCurrentConstructor().isLocalVariableInConstructor(name)) { if (typedProgram.getCurrentClass().getCurrentConstructor().isLocalVariableInConstructor(name)) {
throw new RuntimeException("Variable " + name + " already declared"); throw new RuntimeException("Variable " + name + " already declared");
} }
clas.getCurrentConstructor().getLocalVariables().add(this); typedProgram.getCurrentClass().getCurrentConstructor().getLocalVariables().add(this);
return type; return type;
} }
throw new RuntimeException("not found method or constructor in class"); throw new RuntimeException("not found method or constructor in class");

View File

@ -1,6 +1,5 @@
package de.maishai.typedast.typedclass; package de.maishai.typedast.typedclass;
import de.maishai.ast.records.IfElse;
import de.maishai.ast.records.Method; import de.maishai.ast.records.Method;
import de.maishai.typedast.*; import de.maishai.typedast.*;
import lombok.Data; import lombok.Data;
@ -20,28 +19,28 @@ public class TypedMethod implements TypedNode {
private List<TypedLocalVariable> localVariables = new ArrayList<>(); private List<TypedLocalVariable> localVariables = new ArrayList<>();
private TypedBlock typedBlock; private TypedBlock typedBlock;
public TypedMethod(TypedClass clas, Method unTypedMethod) { public TypedMethod(TypedProgram typedProgram, Method unTypedMethod) {
convertToTypedMethod(clas, unTypedMethod); convertToTypedMethod(typedProgram, unTypedMethod);
} }
public void convertToTypedMethod(TypedClass clas, Method unTypedMethod) { public void convertToTypedMethod(TypedProgram typedProgram, Method unTypedMethod) {
name = unTypedMethod.methodName(); name = unTypedMethod.methodName();
returnType = unTypedMethod.type(); returnType = unTypedMethod.type();
for (var parameter : unTypedMethod.params()) { for (var parameter : unTypedMethod.params()) {
typedParameters.add(new TypedParameter(clas, parameter)); typedParameters.add(new TypedParameter(typedProgram, parameter));
} }
clas.getTypedMethods().stream().filter(method -> method.equals(this)).findFirst().ifPresentOrElse( typedProgram.getCurrentClass().getTypedMethods().stream().filter(method -> method.equals(this)).findFirst().ifPresentOrElse(
method -> { method -> {
throw new RuntimeException("Method " + name + " already exists"); throw new RuntimeException("Method " + name + " already exists");
}, () -> { }, () -> {
}); });
} }
public void convertToTypedBlock(TypedClass clas, Method unTypedMethod) { public void convertToTypedBlock(TypedProgram typedProgram, Method unTypedMethod) {
typedBlock = new TypedBlock(clas, unTypedMethod.block()); typedBlock = new TypedBlock(typedProgram, unTypedMethod.block());
typeCheck(clas); typeCheck(typedProgram);
} }
public boolean isLocalVariablePresent(String localVarName) { public boolean isLocalVariablePresent(String localVarName) {
@ -84,9 +83,9 @@ public class TypedMethod implements TypedNode {
} }
@Override @Override
public Type typeCheck(TypedClass clas) { public Type typeCheck(TypedProgram typedProgram) {
if (returnType != Type.VOID && !hasEvenReturnsInIfElseBlocks()) { if (returnType != Type.VOID && !hasEvenReturnsInIfElseBlocks()) {
if (typedBlock.typeCheck(clas).getKind() != returnType.getKind()) { if (typedBlock.typeCheck(typedProgram).getKind() != returnType.getKind()) {
if (hasEvenReturnsInIfElseBlocks()) { if (hasEvenReturnsInIfElseBlocks()) {
throw new RuntimeException("Method " + name + " must have even returns in if else blocks"); throw new RuntimeException("Method " + name + " must have even returns in if else blocks");
} else { } else {

View File

@ -20,22 +20,22 @@ public class TypedMethodCall implements TypedExpression, TypedStatement {
private List<TypedExpression> args = new ArrayList<>(); private List<TypedExpression> args = new ArrayList<>();
private Type type; private Type type;
public TypedMethodCall(TypedClass clas, MethodCall unTypedMethodCall) { public TypedMethodCall(TypedProgram typedProgram, MethodCall unTypedMethodCall) {
convertToTypedMethodCall(clas, unTypedMethodCall); convertToTypedMethodCall(typedProgram, unTypedMethodCall);
} }
public void convertToTypedMethodCall(TypedClass clas, MethodCall unTypedMethodCall) { public void convertToTypedMethodCall(TypedProgram typedProgram, MethodCall unTypedMethodCall) {
recipient = new TypedFieldVarAccess(clas, unTypedMethodCall.recipient()); recipient = new TypedFieldVarAccess(typedProgram, unTypedMethodCall.recipient());
for (Expression arg : unTypedMethodCall.args()) { for (Expression arg : unTypedMethodCall.args()) {
args.add(convertExpression(clas, arg)); args.add(convertExpression(typedProgram, arg));
} }
} }
@Override @Override
public Type typeCheck(TypedClass clas) { public Type typeCheck(TypedProgram typedProgram) {
if (clas.isCurrentMethodPresent() || clas.isCurrentConstructorPresent()) { if (typedProgram.getCurrentClass().isCurrentMethodPresent() || typedProgram.getCurrentClass().isCurrentConstructorPresent()) {
List<TypedMethod> methods = clas.getTypedMethods().stream() List<TypedMethod> methods = typedProgram.getCurrentClass().getTypedMethods().stream()
.filter(method -> method.getName().equals(recipient.getName())) .filter(method -> method.getName().equals(recipient.getName()))
.toList(); .toList();
@ -43,7 +43,7 @@ public class TypedMethodCall implements TypedExpression, TypedStatement {
if (method.getTypedParameters().size() == args.size()) { if (method.getTypedParameters().size() == args.size()) {
boolean allMatch = true; boolean allMatch = true;
for (int i = 0; i < args.size(); i++) { for (int i = 0; i < args.size(); i++) {
if (!args.get(i).typeCheck(clas).equals(method.getTypedParameters().get(i).getType())) { if (!args.get(i).typeCheck(typedProgram).equals(method.getTypedParameters().get(i).getType())) {
allMatch = false; allMatch = false;
break; break;
} }

View File

@ -4,11 +4,9 @@ import de.maishai.ast.records.Expression;
import de.maishai.ast.records.New; import de.maishai.ast.records.New;
import de.maishai.typedast.*; import de.maishai.typedast.*;
import lombok.Data; import lombok.Data;
import org.objectweb.asm.MethodVisitor;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression; import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression;
@ -17,30 +15,30 @@ public class TypedNew implements TypedExpression, TypedStatement {
private Type type; private Type type;
private List<TypedExpression> args = new ArrayList<>(); private List<TypedExpression> args = new ArrayList<>();
public TypedNew(TypedClass clas, New unTypedNew) { public TypedNew(TypedProgram typedProgram, New unTypedNew) {
convertToTypedNew(clas, unTypedNew); convertToTypedNew(typedProgram, unTypedNew);
} }
public void convertToTypedNew(TypedClass clas, New unTypedNew) { public void convertToTypedNew(TypedProgram typedProgram, New unTypedNew) {
type = unTypedNew.type(); type = unTypedNew.type();
for (Expression arg : unTypedNew.args()) { for (Expression arg : unTypedNew.args()) {
args.add(convertExpression(clas, arg)); args.add(convertExpression(typedProgram, arg));
} }
} }
@Override @Override
public Type typeCheck(TypedClass clas) { public Type typeCheck(TypedProgram typedProgram) {
for (var constructor : clas.getTypedConstructors()) { for (var constructor : typedProgram.getCurrentClass().getTypedConstructors()) {
if (constructor.getTypedParameters().size() == args.size()) { if (constructor.getTypedParameters().size() == args.size()) {
boolean valid = true; boolean valid = true;
for (int i = 0; i < args.size(); i++) { for (int i = 0; i < args.size(); i++) {
if (!constructor.getTypedParameters().get(i).getType().equals(args.get(i).typeCheck(clas))) { if (!constructor.getTypedParameters().get(i).getType().equals(args.get(i).typeCheck(typedProgram))) {
valid = false; valid = false;
break; break;
} }
} }
if (valid) { if (valid) {
return Type.REFERENCE(clas.getClassName()); return Type.REFERENCE(typedProgram.getCurrentClass().getClassName());
} }
} }
} }

View File

@ -6,19 +6,17 @@ import de.maishai.typedast.TypedNode;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import java.util.Map;
@AllArgsConstructor @AllArgsConstructor
@Data @Data
public class TypedParameter implements TypedNode { public class TypedParameter implements TypedNode {
private String paraName; private String paraName;
private Type type; private Type type;
public TypedParameter(TypedClass clas, Parameter unTypedParameter) { public TypedParameter(TypedProgram typedProgram, Parameter unTypedParameter) {
convertToTypedParameter(clas, unTypedParameter); convertToTypedParameter(typedProgram, unTypedParameter);
} }
public void convertToTypedParameter(TypedClass clas, Parameter unTypedParameter) { public void convertToTypedParameter(TypedProgram typedProgram, Parameter unTypedParameter) {
paraName = unTypedParameter.name(); paraName = unTypedParameter.name();
type = unTypedParameter.type(); type = unTypedParameter.type();
} }
@ -34,14 +32,14 @@ public class TypedParameter implements TypedNode {
@Override @Override
public Type typeCheck(TypedClass clas) { public Type typeCheck(TypedProgram typedProgram) {
if (clas.isCurrentMethodPresent()) { if (typedProgram.getCurrentClass().isCurrentMethodPresent()) {
if (clas.isParameterWitNameInMethod(paraName)) { if (typedProgram.getCurrentClass().isParameterWitNameInMethod(paraName)) {
throw new RuntimeException("Parameter " + paraName + " already exists"); throw new RuntimeException("Parameter " + paraName + " already exists");
} }
} else if (clas.isCurrentConstructorPresent()) { } else if (typedProgram.getCurrentClass().isCurrentConstructorPresent()) {
if (clas.isParameterWitNameInConstructor(paraName)) { if (typedProgram.getCurrentClass().isParameterWitNameInConstructor(paraName)) {
throw new RuntimeException("Parameter " + paraName + " already exists"); throw new RuntimeException("Parameter " + paraName + " already exists");
} }
} }

View File

@ -11,14 +11,45 @@ import java.util.List;
@AllArgsConstructor @AllArgsConstructor
public class TypedProgram { public class TypedProgram {
private List<TypedClass> typedClasses = new ArrayList<>(); private List<TypedClass> typedClasses = new ArrayList<>();
private TypedClass currentClass;
public TypedProgram(Program program) {
public TypedProgram(Program program){
startConversion(program); startConversion(program);
} }
public void startConversion(Program program){
//TODO: implement public void startConversion(Program program) {
program.classes().toString();
int k = 0;
for (var clas : program.classes()) {
enterCurrentClass(typedClasses.get(k));
typedClasses.add(new TypedClass(this, clas));
exitCurrentClass();
k++;
}
int i = 0;
for(var clas : program.classes()){
enterCurrentClass(typedClasses.get(i));
typedClasses.get(i).covertBlocksOfConstructorsAndMethods(this, clas);
exitCurrentClass();
i++;
}
}
public TypedClass getTypedClass(String className) {
return typedClasses.stream().filter(clas -> clas.getClassName().equals(className)).findFirst().get();
}
public boolean isCurrentClassPresent() {
return currentClass != null;
}
public void enterCurrentClass(TypedClass clas) {
currentClass = clas;
}
public void exitCurrentClass() {
currentClass = null;
} }
} }

View File

@ -5,11 +5,8 @@ import de.maishai.ast.records.*;
import de.maishai.typedast.*; import de.maishai.typedast.*;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;
import java.util.Map;
import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression; import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression;
@Data @Data
@ -18,12 +15,12 @@ public class TypedReturn implements TypedStatement {
private TypedExpression ret; private TypedExpression ret;
private Type type; private Type type;
public TypedReturn(TypedClass clas, Return unTypedReturn) { public TypedReturn(TypedProgram typedProgram, Return unTypedReturn) {
convertToTypedReturn(clas, unTypedReturn); convertToTypedReturn(typedProgram, unTypedReturn);
} }
public void convertToTypedReturn(TypedClass clas, Return unTypedReturn) { public void convertToTypedReturn(TypedProgram typedProgram, Return unTypedReturn) {
ret = convertExpression(clas, unTypedReturn.ret()); ret = convertExpression(typedProgram, unTypedReturn.ret());
if(ret == null){ if(ret == null){
type = Type.VOID; type = Type.VOID;
}else{ }else{
@ -32,14 +29,14 @@ public class TypedReturn implements TypedStatement {
} }
@Override @Override
public Type typeCheck(TypedClass clas) { public Type typeCheck(TypedProgram typedProgram) {
if (clas.isCurrentMethodPresent()) { if (typedProgram.getCurrentClass().isCurrentMethodPresent()) {
if (clas.getCurrentMethod().getReturnType().getKind() != this.type.getKind()) { if (typedProgram.getCurrentClass().getCurrentMethod().getReturnType().getKind() != this.type.getKind()) {
StringBuilder exp = new StringBuilder(); StringBuilder exp = new StringBuilder();
exp.append("\nMismatched return type: "); exp.append("\nMismatched return type: ");
exp.append("\nExpected: ").append(clas.getCurrentMethod().getReturnType().getKind()); exp.append("\nExpected: ").append(typedProgram.getCurrentClass().getCurrentMethod().getReturnType().getKind());
exp.append("\nActual: ").append(this.type.getKind()); exp.append("\nActual: ").append(this.type.getKind());
exp.append("\nMethod name: ").append(clas.getCurrentMethod().getName()); exp.append("\nMethod name: ").append(typedProgram.getCurrentClass().getCurrentMethod().getName());
throw new RuntimeException(exp.toString()); throw new RuntimeException(exp.toString());
} }
} }

View File

@ -6,11 +6,8 @@ import de.maishai.typedast.MethodContext;
import de.maishai.typedast.TypedExpression; import de.maishai.typedast.TypedExpression;
import de.maishai.typedast.Type; import de.maishai.typedast.Type;
import lombok.Data; import lombok.Data;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;
import java.util.Map;
import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression; import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression;
@Data @Data
@ -19,27 +16,27 @@ public class TypedUnary implements TypedExpression {
private TypedExpression right; private TypedExpression right;
private Type type; private Type type;
public TypedUnary(TypedClass clas, Unary unTypedUnary) { public TypedUnary(TypedProgram typedProgram, Unary unTypedUnary) {
convertToTypedUnary(clas, unTypedUnary); convertToTypedUnary(typedProgram, unTypedUnary);
} }
public void convertToTypedUnary(TypedClass clas, Unary unTypedUnary) { public void convertToTypedUnary(TypedProgram typedProgram, Unary unTypedUnary) {
op = unTypedUnary.op(); op = unTypedUnary.op();
right = convertExpression(clas, unTypedUnary.right()); right = convertExpression(typedProgram, unTypedUnary.right());
} }
@Override @Override
public Type typeCheck(TypedClass clas) { public Type typeCheck(TypedProgram typedProgram) {
if (op == UnaryOperator.NOT) { if (op == UnaryOperator.NOT) {
if (right.typeCheck(clas) != Type.BOOL) { if (right.typeCheck(typedProgram) != Type.BOOL) {
throw new RuntimeException("Not operator must be applied to boolean"); throw new RuntimeException("Not operator must be applied to boolean");
} }
return Type.BOOL; return Type.BOOL;
} }
if (op == UnaryOperator.SUB) { if (op == UnaryOperator.SUB) {
if (right.typeCheck(clas) != Type.INT) { if (right.typeCheck(typedProgram) != Type.INT) {
throw new RuntimeException("Minus operator must be applied to int"); throw new RuntimeException("Minus operator must be applied to int");
} }
return Type.INT; return Type.INT;

View File

@ -3,9 +3,6 @@ package de.maishai.typedast.typedclass;
import de.maishai.ast.records.*; import de.maishai.ast.records.*;
import de.maishai.typedast.*; import de.maishai.typedast.*;
import lombok.Data; import lombok.Data;
import org.objectweb.asm.MethodVisitor;
import java.util.Map;
import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression; import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression;
@ -15,21 +12,21 @@ public class TypedWhile implements TypedStatement {
private TypedBlock typedBlock; private TypedBlock typedBlock;
private Type type; private Type type;
public TypedWhile(TypedClass clas, While unTypedWhile) { public TypedWhile(TypedProgram typedProgram, While unTypedWhile) {
convertToTypedWhile(clas, unTypedWhile); convertToTypedWhile(typedProgram, unTypedWhile);
} }
public void convertToTypedWhile(TypedClass clas, While unTypedWhile) { public void convertToTypedWhile(TypedProgram typedProgram, While unTypedWhile) {
cond = convertExpression(clas, unTypedWhile.cond()); cond = convertExpression(typedProgram, unTypedWhile.cond());
typedBlock = new TypedBlock(clas, unTypedWhile.block()); typedBlock = new TypedBlock(typedProgram, unTypedWhile.block());
} }
@Override @Override
public Type typeCheck(TypedClass clas) { public Type typeCheck(TypedProgram typedProgram) {
if (cond.typeCheck(clas) != Type.BOOL) { if (cond.typeCheck(typedProgram) != Type.BOOL) {
throw new RuntimeException("While condition must be a boolean"); throw new RuntimeException("While condition must be a boolean");
} }
type = typedBlock.typeCheck(clas); type = typedBlock.typeCheck(typedProgram);
return type; return type;
} }