Implementation for testing

This commit is contained in:
Ahmad 2024-05-08 15:05:04 +02:00
parent 6e62b0c21c
commit 45f834722b
8 changed files with 147 additions and 10 deletions

View File

@ -1,6 +1,5 @@
package de.maishai.typedast.typedclass; package de.maishai.typedast.typedclass;
import de.maishai.ast.AssignSign;
import de.maishai.ast.records.Assignment; import de.maishai.ast.records.Assignment;
import de.maishai.typedast.MethodContext; import de.maishai.typedast.MethodContext;
import de.maishai.typedast.TypedExpression; import de.maishai.typedast.TypedExpression;
@ -16,7 +15,7 @@ import java.util.Map;
public class TypedAssignment implements TypedStatement { public class TypedAssignment implements TypedStatement {
private String varName; private String varName;
private TypedExpression value; private TypedExpression value;
private Type type;
@Override @Override
public Type typeCheck(Map<String, Type> localVar, Map<String, TypedClass> classes) { public Type typeCheck(Map<String, Type> localVar, Map<String, TypedClass> classes) {
if (!localVar.containsKey(varName)) { if (!localVar.containsKey(varName)) {
@ -27,10 +26,18 @@ public class TypedAssignment implements TypedStatement {
Type typeRight = value.typeCheck(localVar, classes); Type typeRight = value.typeCheck(localVar, classes);
if (typeLeft.equals(typeRight) ) { if (typeLeft.equals(typeRight) ) {
type = typeLeft;
return typeLeft; return typeLeft;
} }
throw new RuntimeException("type of left not equals with type of right"); throw new RuntimeException("type of left not equals with type of right");
} }
// int y = 5;
// int x = (y + 5 + z);
//TypedAssignment([
// localVar("x", "int"),
// localVar("y","int")
// ],
// "int")
@Override @Override
public TypedNode convertToTypedAST(Map<String, Type> localVar, Map<String, TypedClass> classes, de.maishai.ast.records.Node unTypedAST) { public TypedNode convertToTypedAST(Map<String, Type> localVar, Map<String, TypedClass> classes, de.maishai.ast.records.Node unTypedAST) {

View File

@ -13,11 +13,13 @@ public class TypedBinary implements TypedExpression {
private TypedExpression left; private TypedExpression left;
private Operator op; private Operator op;
private TypedExpression right; private TypedExpression right;
private Type type;
@Override @Override
public Type typeCheck(Map<String, Type> localVar, Map<String, TypedClass> classes) { public Type typeCheck(Map<String, Type> localVar, Map<String, TypedClass> classes) {
if(op == Operator.ADD || op == Operator.SUB || op == Operator.MUL) { if(op == Operator.ADD || op == Operator.SUB || op == Operator.MUL) {
if (left.typeCheck(localVar, classes) == Type.INT && if (left.typeCheck(localVar, classes) == Type.INT &&
right.typeCheck(localVar, classes) == Type.INT) { right.typeCheck(localVar, classes) == Type.INT) {
type = Type.INT;
return Type.INT; return Type.INT;
} else { } else {
throw new RuntimeException("Type mismatch"); throw new RuntimeException("Type mismatch");
@ -25,6 +27,7 @@ public class TypedBinary implements TypedExpression {
}else if(op == Operator.GT || op == Operator.LT || op == Operator.GE || op == Operator.LE || op == Operator.EQ || op == Operator.NE || op == Operator.AND || op == Operator.OR) { }else if(op == Operator.GT || op == Operator.LT || op == Operator.GE || op == Operator.LE || op == Operator.EQ || op == Operator.NE || op == Operator.AND || op == Operator.OR) {
if (left.typeCheck(localVar, classes) == Type.INT && if (left.typeCheck(localVar, classes) == Type.INT &&
right.typeCheck(localVar, classes) == Type.INT) { right.typeCheck(localVar, classes) == Type.INT) {
type = Type.BOOL;
return Type.BOOL; return Type.BOOL;
} else { } else {
throw new RuntimeException("Type mismatch"); throw new RuntimeException("Type mismatch");
@ -32,6 +35,7 @@ public class TypedBinary implements TypedExpression {
} else if (op == Operator.AND || op == Operator.OR) { } else if (op == Operator.AND || op == Operator.OR) {
if (left.typeCheck(localVar, classes) == Type.BOOL && if (left.typeCheck(localVar, classes) == Type.BOOL &&
right.typeCheck(localVar, classes) == Type.BOOL) { right.typeCheck(localVar, classes) == Type.BOOL) {
type = Type.BOOL;
return Type.BOOL; return Type.BOOL;
} else { } else {
throw new RuntimeException("Type mismatch"); throw new RuntimeException("Type mismatch");

View File

@ -17,6 +17,35 @@ public class TypedBlock implements TypedNode {
private List<TypedLocalVariable> vars; private List<TypedLocalVariable> vars;
private List<TypedStatement> stmts; private List<TypedStatement> stmts;
public TypedBlock unTypedBlockToTypedBlock(Block unTypedBlock) {
TypedBlock typedBlock = new TypedBlock();
for (LocalVariable var : unTypedBlock.vars()) {
TypedLocalVariable typedVar = new TypedLocalVariable();
typedVar.setName(var.name().name());
switch (var.type()) {
case INT:
typedVar.setType(Type.INT);
break;
case BOOL:
typedVar.setType(Type.BOOL);
break;
case CHAR:
typedVar.setType(Type.CHAR);
break;
case OBJECT:
typedVar.setType(Type.REFERENCE(var.name().name()));
break;
}
typedBlock.getVars().add(typedVar);
}
typedBlock.getStmts().add((TypedStatement) unTypedBlock.stmts());
return typedBlock;
}
@Override @Override
public Type typeCheck(Map<String, Type> localVar, Map<String, TypedClass> classes) { public Type typeCheck(Map<String, Type> localVar, Map<String, TypedClass> classes) {
Type typeOfLastStmt = Type.VOID; Type typeOfLastStmt = Type.VOID;

View File

@ -11,9 +11,10 @@ import java.util.Map;
public class TypedBoolLiteral implements TypedExpression { public class TypedBoolLiteral implements TypedExpression {
private Boolean value; private Boolean value;
private Type type;
@Override @Override
public Type typeCheck(Map<String, Type> localVar, Map<String, TypedClass> classes) { public Type typeCheck(Map<String, Type> localVar, Map<String, TypedClass> classes) {
type = Type.BOOL;
return Type.BOOL; return Type.BOOL;
} }

View File

@ -1,8 +1,11 @@
package de.maishai.typedast.typedclass; package de.maishai.typedast.typedclass;
import de.maishai.ast.records.*;
import de.maishai.ast.records.Class;
import de.maishai.typedast.CodeGenUtils; import de.maishai.typedast.CodeGenUtils;
import de.maishai.typedast.TypedNode; import de.maishai.typedast.TypedNode;
import de.maishai.typedast.Type; import de.maishai.typedast.Type;
import de.maishai.typedast.TypedStatement;
import lombok.Data; import lombok.Data;
import org.objectweb.asm.ClassWriter; import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;
@ -50,17 +53,26 @@ public class TypedClass implements TypedNode {
@Override @Override
public TypedNode convertToTypedAST(Map<String, Type> localVar, Map<String, TypedClass> classes, de.maishai.ast.records.Node unTypedAST) { public TypedNode convertToTypedAST(Map<String, Type> localVar, Map<String, TypedClass> classes, de.maishai.ast.records.Node unTypedAST) {
TypedClass typedClass = new TypedClass(); TypedClass typedClass = new TypedClass();
Class c = (Class) unTypedAST;
for (TypedField field : typedFields) { for (Field field : c.fields()) {
typedClass.getTypedFields().add((TypedField) field.convertToTypedAST(localVar, classes, unTypedAST)); TypedField typedField = new TypedField();
typedClass.getTypedFields().add(typedField.unTypedFieldToTypedField(field));
} }
for (TypedConstructor constructor : typedConstructors) { for (Constructor constructor : c.constructors()) {
typedClass.getTypedConstructors().add((TypedConstructor) constructor.convertToTypedAST(localVar, classes, unTypedAST)); TypedConstructor typedConstructor = new TypedConstructor();
typedClass.getTypedConstructors().add(typedConstructor.unTypedContructorToTypedConstructor(constructor));
} }
for (TypedMethod method : typedMethods) { for(Constructor constructor : c.constructors()){
typedClass.getTypedMethods().add((TypedMethod) method.convertToTypedAST(localVar, classes, unTypedAST)); TypedConstructor typedConstructor = new TypedConstructor();
typedClass.getTypedConstructors().add(typedConstructor.unTypedContructorToTypedConstructor(constructor));
}
for (Method method : c.methods()) {
TypedMethod typedMethod = new TypedMethod();
typedClass.getTypedMethods().add(typedMethod.unTypedMethodToTypedMethod(method));
} }
return typedClass; return typedClass;

View File

@ -43,6 +43,42 @@ public class TypedConstructor implements TypedNode {
return Type.VOID; return Type.VOID;
} }
public TypedConstructor unTypedContructorToTypedConstructor(de.maishai.ast.records.Constructor unTypedConstructor) {
TypedConstructor typedConstructor = new TypedConstructor();
typedConstructor.setName(unTypedConstructor.id().name());
if (unTypedConstructor.params().isEmpty()) {
typedConstructor.setTypedParameters(null);
} else {
for (Parameter param : unTypedConstructor.params()) {
TypedParameter typedParam = new TypedParameter();
typedParam.setParaName(param.name());
switch(param.type()) {
case INT:
typedParam.setType(Type.INT);
break;
case BOOL:
typedParam.setType(Type.BOOL);
break;
case CHAR:
typedParam.setType(Type.CHAR);
break;
case OBJECT:
typedParam.setType(Type.REFERENCE(param.type().name()));
break;
}
typedConstructor.getTypedParameters().add(typedParam);
}
}
Block block = unTypedConstructor.block();
TypedBlock typedBlock = new TypedBlock();
typedConstructor.setTypedBlock(typedBlock.unTypedBlockToTypedBlock(block));
return typedConstructor;
}
@Override @Override
public TypedNode convertToTypedAST(Map<String, Type> localVar, Map<String, TypedClass> classes, de.maishai.ast.records.Node unTypedAST) { public TypedNode convertToTypedAST(Map<String, Type> localVar, Map<String, TypedClass> classes, de.maishai.ast.records.Node unTypedAST) {
Constructor untyped = (Constructor) unTypedAST; Constructor untyped = (Constructor) unTypedAST;

View File

@ -19,6 +19,27 @@ public class TypedField implements TypedNode {
private String varName; private String varName;
private Type type; private Type type;
public TypedField unTypedFieldToTypedField(Field field){
TypedField typedField = new TypedField();
switch(field.type()) {
case INT:
typedField.setType(Type.INT);
break;
case BOOL:
typedField.setType(Type.BOOL);
break;
case CHAR:
typedField.setType(Type.CHAR);
break;
case OBJECT:
typedField.setType(Type.REFERENCE(typedField.varName));
break;
}
typedField.setVarName(field.name().name());
return typedField;
}
@Override @Override
public Type typeCheck(Map<String, Type> localVar, Map<String, TypedClass> classes) { public Type typeCheck(Map<String, Type> localVar, Map<String, TypedClass> classes) {
if (localVar.containsKey(varName)) { if (localVar.containsKey(varName)) {

View File

@ -19,9 +19,36 @@ public class TypedMethod implements TypedNode {
private List<TypedParameter> typedParameters; private List<TypedParameter> typedParameters;
private TypedBlock typedBlock; private TypedBlock typedBlock;
public TypedMethod unTypedMethodToTypedMethod(Method unTypedMethod) {
TypedMethod typedMethod = new TypedMethod();
typedMethod.setName(unTypedMethod.id().name());
for(Parameter parameter : unTypedMethod.params()){
TypedParameter typedParameter = new TypedParameter();
typedParameter.setParaName(parameter.name());
switch(parameter.type()) {
case INT:
typedParameter.setType(Type.INT);
break;
case BOOL:
typedParameter.setType(Type.BOOL);
break;
case CHAR:
typedParameter.setType(Type.CHAR);
break;
case OBJECT:
typedParameter.setType(Type.REFERENCE(parameter.name()));
break;
}
typedParameters.add(typedParameter);
}
TypedBlock block = new TypedBlock();
typedMethod.setTypedBlock(block.unTypedBlockToTypedBlock(unTypedMethod.block()));
return typedMethod;
}
@Override @Override
public Type typeCheck(Map<String, Type> localVar, Map<String, TypedClass> classes) { public Type typeCheck(Map<String, Type> localVar, Map<String, TypedClass> classes) {
if(localVar.containsKey(name)) { if(localVar.containsKey(name)) {
throw new RuntimeException("Method " + name + " already exists"); throw new RuntimeException("Method " + name + " already exists");
} }
localVar.put(name, returnType); localVar.put(name, returnType);