mirror of
https://github.com/JonathanFleischmann/CompilerULTIMATE.git
synced 2024-12-27 08:38:03 +00:00
renamed and refactored
This commit is contained in:
parent
5d7f7ef546
commit
a05a4c8744
@ -9,7 +9,7 @@ import java.util.Map;
|
||||
|
||||
public class TypedExpressionHelp {
|
||||
|
||||
public static TypedExpression getKindOfExpression(Map<String, Type> localVar, TypedClass clas, Expression expression) {
|
||||
public static TypedExpression convertExpression(Map<String, Type> localVar, TypedClass clas, Expression expression) {
|
||||
if (expression instanceof BoolLiteral boolLiteral) {
|
||||
TypedBoolLiteral typedBoolLiteral = new TypedBoolLiteral(localVar, clas, boolLiteral);
|
||||
typedBoolLiteral.typeCheck(localVar, clas);
|
||||
|
@ -1,6 +1,7 @@
|
||||
package de.maishai.typedast.typedclass;
|
||||
|
||||
import de.maishai.ast.records.Assignment;
|
||||
import de.maishai.ast.records.Expression;
|
||||
import de.maishai.typedast.MethodContext;
|
||||
import de.maishai.typedast.TypedExpression;
|
||||
import de.maishai.typedast.TypedStatement;
|
||||
@ -11,12 +12,13 @@ import org.objectweb.asm.Opcodes;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static de.maishai.typedast.Help.TypedExpressionHelp.getKindOfExpression;
|
||||
import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression;
|
||||
|
||||
@Data
|
||||
public class TypedAssignment implements TypedStatement {
|
||||
private String varName;
|
||||
private TypedExpression value;
|
||||
// private TypedExpression recursiveOwnerChain;
|
||||
private Type type;
|
||||
|
||||
public TypedAssignment(Map<String, Type> localVar, TypedClass clas, Assignment untyped) {
|
||||
@ -25,21 +27,22 @@ public class TypedAssignment implements TypedStatement {
|
||||
|
||||
public void convertToTypedAssignment(Map<String, Type> localVar, TypedClass clas, Assignment untyped) {
|
||||
varName = untyped.location().id();
|
||||
value = getKindOfExpression(localVar, clas, untyped.value());
|
||||
value = convertExpression(localVar, clas, untyped.value());
|
||||
// recursiveOwnerChain = convertExpression(localVar, clas, untyped.location().recursiveOwnerChain());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type typeCheck(Map<String, Type> localVar, TypedClass clas) {
|
||||
public Type typeCheck(Map<String, Type> localVar, TypedClass clas) {
|
||||
Type typeLeft = null;
|
||||
|
||||
if (!localVar.containsKey(varName)) {
|
||||
if(clas.isThereField(varName)){
|
||||
if (clas.isThereField(varName)) {
|
||||
typeLeft = clas.getFieldType(varName);
|
||||
}else if(clas.isParameterWitNameInMethod(varName)) {
|
||||
} else if (clas.isParameterWitNameInMethod(varName)) {
|
||||
typeLeft = clas.getParameterTypeInCurrentMethod(varName);
|
||||
}else if(clas.isParameterNameInCurrentConstructor(varName)) {
|
||||
} else if (clas.isParameterNameInCurrentConstructor(varName)) {
|
||||
typeLeft = clas.getParameterTypeInCurrentConstructor(varName);
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
throw new RuntimeException("Variable not declared");
|
||||
}
|
||||
} else {
|
||||
|
@ -11,7 +11,7 @@ import org.objectweb.asm.MethodVisitor;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static de.maishai.typedast.Help.TypedExpressionHelp.getKindOfExpression;
|
||||
import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@ -26,40 +26,44 @@ public class TypedBinary implements TypedExpression {
|
||||
}
|
||||
|
||||
public void convertToTypedBinary(Map<String, Type> localVar, TypedClass clas, Binary unTypedBinary) {
|
||||
left = getKindOfExpression(localVar, clas, unTypedBinary.left());
|
||||
right = getKindOfExpression(localVar, clas, unTypedBinary.right());
|
||||
left = convertExpression(localVar, clas, unTypedBinary.left());
|
||||
right = convertExpression(localVar, clas, unTypedBinary.right());
|
||||
op = unTypedBinary.op();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type typeCheck(Map<String, Type> localVar, TypedClass clas) {
|
||||
Type leftType = left.typeCheck(localVar, clas);
|
||||
Type rightType = right.typeCheck(localVar, clas);
|
||||
|
||||
if (op == Operator.ADD || op == Operator.SUB || op == Operator.MUL) {
|
||||
if (left.typeCheck(localVar, clas) == Type.INT &&
|
||||
right.typeCheck(localVar, clas) == Type.INT) {
|
||||
if (leftType == Type.INT && rightType == Type.INT) {
|
||||
type = Type.INT;
|
||||
return Type.INT;
|
||||
} else {
|
||||
throw new RuntimeException("Type mismatch in " + op);
|
||||
}
|
||||
} else if (op == Operator.GT || op == Operator.LT || op == Operator.GE || op == Operator.LE || op == Operator.EQ || op == Operator.NE ) {
|
||||
if (left.typeCheck(localVar, clas) == Type.INT &&
|
||||
right.typeCheck(localVar, clas) == Type.INT) {
|
||||
} else if (op == Operator.GT || op == Operator.LT || op == Operator.GE || op == Operator.LE) {
|
||||
if (leftType == Type.INT && rightType == Type.INT) {
|
||||
type = Type.BOOL;
|
||||
return Type.BOOL;
|
||||
} else {
|
||||
throw new RuntimeException("Type mismatch in " + op);
|
||||
}
|
||||
} else if (op == Operator.AND || op == Operator.OR) {
|
||||
if (left.typeCheck(localVar, clas) == Type.BOOL &&
|
||||
right.typeCheck(localVar, clas) == Type.BOOL) {
|
||||
if (leftType == Type.BOOL && rightType == Type.BOOL) {
|
||||
type = Type.BOOL;
|
||||
return Type.BOOL;
|
||||
} else {
|
||||
throw new RuntimeException("Type mismatch in " + op);
|
||||
}
|
||||
} else {
|
||||
throw new RuntimeException("Invalid operator");
|
||||
}
|
||||
|
||||
if (leftType == rightType && leftType != Type.VOID) {
|
||||
type = rightType;
|
||||
return type;
|
||||
}
|
||||
throw new RuntimeException("Void can not be compared with Void");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,7 +1,10 @@
|
||||
package de.maishai.typedast.typedclass;
|
||||
|
||||
import de.maishai.ast.records.*;
|
||||
import de.maishai.typedast.*;
|
||||
import de.maishai.typedast.MethodContext;
|
||||
import de.maishai.typedast.Type;
|
||||
import de.maishai.typedast.TypedNode;
|
||||
import de.maishai.typedast.TypedStatement;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
@ -15,28 +18,28 @@ import java.util.Map;
|
||||
@AllArgsConstructor
|
||||
@Data
|
||||
public class TypedBlock implements TypedNode {
|
||||
private List<TypedLocalVariable> vars = new ArrayList<>();
|
||||
private List<TypedDeclaration> vars = new ArrayList<>();
|
||||
private List<TypedStatement> stmts = new ArrayList<>();
|
||||
private Type type;
|
||||
|
||||
|
||||
|
||||
public TypedBlock(Map<String, Type> localVar, TypedClass clas, Block unTypedBlock) {
|
||||
convertToTypedBlock(localVar, clas, unTypedBlock);
|
||||
}
|
||||
public TypedBlock(List<TypedLocalVariable> vars, List<TypedStatement> stmts) {
|
||||
|
||||
public TypedBlock(List<TypedDeclaration> vars, List<TypedStatement> stmts) {
|
||||
this.vars = vars;
|
||||
this.stmts = stmts;
|
||||
}
|
||||
|
||||
public void convertToTypedBlock(Map<String, Type> localVar, TypedClass clas, Block unTypedBlock) {
|
||||
|
||||
if(unTypedBlock == null) {
|
||||
if (unTypedBlock == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (Declaration var : unTypedBlock.localVariables()) {
|
||||
TypedLocalVariable typedVar = new TypedLocalVariable(localVar, clas, var);
|
||||
TypedDeclaration typedVar = new TypedDeclaration(localVar, clas, var);
|
||||
vars.add(typedVar);
|
||||
}
|
||||
|
||||
@ -85,9 +88,7 @@ public class TypedBlock implements TypedNode {
|
||||
}
|
||||
|
||||
if (stmt instanceof Break) {
|
||||
TypedBreak typedBreak = new TypedBreak();
|
||||
typedBreak.typeCheck(localVar, clas);
|
||||
stmts.add(typedBreak);
|
||||
stmts.add(new TypedBreak());
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -104,7 +105,7 @@ public class TypedBlock implements TypedNode {
|
||||
@Override
|
||||
public Type typeCheck(Map<String, Type> localVar, TypedClass clas) {
|
||||
|
||||
for (TypedLocalVariable var : vars) {
|
||||
for (TypedDeclaration var : vars) {
|
||||
var.typeCheck(localVar, clas);
|
||||
}
|
||||
|
||||
@ -112,12 +113,13 @@ public class TypedBlock implements TypedNode {
|
||||
stmt.typeCheck(localVar, clas);
|
||||
}
|
||||
|
||||
//TODO: Type von Return zurückgeben
|
||||
type = Type.VOID;
|
||||
return type;
|
||||
}
|
||||
|
||||
public void codeGen(MethodVisitor mv, MethodContext ctx) {
|
||||
for (TypedLocalVariable var : vars) {
|
||||
for (TypedDeclaration var : vars) {
|
||||
//var.codeGen(mv, ctx);
|
||||
}
|
||||
for (TypedStatement stmt : stmts) {
|
||||
|
@ -12,6 +12,7 @@ import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public class TypedBoolLiteral implements TypedExpression {
|
||||
@ -36,9 +37,9 @@ public class TypedBoolLiteral implements TypedExpression {
|
||||
|
||||
@Override
|
||||
public void codeGen(MethodVisitor mv, MethodContext ctx) {
|
||||
if(value){
|
||||
if (value) {
|
||||
mv.visitInsn(Opcodes.ICONST_1);
|
||||
}else{
|
||||
} else {
|
||||
mv.visitInsn(Opcodes.ICONST_0);
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ import lombok.Data;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Data
|
||||
public class TypedBreak implements TypedStatement {
|
||||
private Type type = Type.VOID;
|
||||
@ -19,7 +20,6 @@ public class TypedBreak implements TypedStatement {
|
||||
}
|
||||
@Override
|
||||
public Type typeCheck(Map<String, Type> localVar, TypedClass clas) {
|
||||
type = Type.VOID;
|
||||
return type;
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,7 @@ import lombok.Data;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Data
|
||||
public class TypedCharLiteral implements TypedExpression {
|
||||
private char value;
|
||||
@ -18,10 +19,12 @@ public class TypedCharLiteral implements TypedExpression {
|
||||
public TypedCharLiteral(Map<String, Type> localVar, TypedClass clas, CharLiteral unTypedCharLiteral) {
|
||||
convertToCharLiteral(localVar, clas, unTypedCharLiteral);
|
||||
}
|
||||
|
||||
public void convertToCharLiteral(Map<String, Type> localVar, TypedClass clas, CharLiteral unTypedCharLiteral) {
|
||||
value = unTypedCharLiteral.value();
|
||||
type = Type.CHAR;
|
||||
value = unTypedCharLiteral.value();
|
||||
type = Type.CHAR;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type typeCheck(Map<String, Type> localVar, TypedClass clas) {
|
||||
return type;
|
||||
|
@ -32,24 +32,31 @@ public class TypedClass implements TypedNode {
|
||||
public TypedClass(Map<String, Type> localVar, Class c) {
|
||||
convertToTypedClass(localVar, 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;
|
||||
@ -61,6 +68,7 @@ public class TypedClass implements TypedNode {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isParameterNameInCurrentConstructor(String parameterName) {
|
||||
if (currentConstructor == null) {
|
||||
return false;
|
||||
@ -80,13 +88,17 @@ public class TypedClass implements TypedNode {
|
||||
for (Declaration field : c.fieldDeclarations()) {
|
||||
typedFields.add(new TypedField(localVar, this, field));
|
||||
}
|
||||
for (Constructor constructor : c.constructors()){
|
||||
// Am Anfang werden die Konstruktoren und Methoden in die Listen eingefügt
|
||||
// Methoden können verwendet werden, bevor deren Blöcke ausgeführt werden
|
||||
for (Constructor constructor : c.constructors()) {
|
||||
typedConstructors.add(new TypedConstructor(localVar, this, constructor));
|
||||
}
|
||||
|
||||
for (Method method : c.methods()) {
|
||||
typedMethods.add(new TypedMethod(localVar, this, method));
|
||||
}
|
||||
|
||||
// Hier werden die Blöcke der Konstruktoren und Methoden ausgeführt
|
||||
int i = 0;
|
||||
for (Constructor constructor : c.constructors()) {
|
||||
enterCurrentConstructor(typedConstructors.get(i));
|
||||
@ -102,25 +114,13 @@ public class TypedClass implements TypedNode {
|
||||
exitCurrentMethod();
|
||||
j++;
|
||||
}
|
||||
|
||||
System.out.println("TypedClass: " + this.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type typeCheck(Map<String, Type> localVar, TypedClass clas) {
|
||||
|
||||
if (clas == null) {
|
||||
throw new RuntimeException("Class not found");
|
||||
}
|
||||
|
||||
for (TypedField field : typedFields) {
|
||||
field.typeCheck(localVar, clas);
|
||||
}
|
||||
for (TypedConstructor constructor : typedConstructors) {
|
||||
constructor.typeCheck(localVar, clas);
|
||||
}
|
||||
for (TypedMethod typedMethod : typedMethods) {
|
||||
typedMethod.typeCheck(localVar, clas);
|
||||
}
|
||||
return Type.REFERENCE(className);
|
||||
return type;
|
||||
}
|
||||
|
||||
public TypedNode startConversion(Class c) {
|
||||
@ -139,6 +139,7 @@ public class TypedClass implements TypedNode {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isParameterWitNameInConstructor(String parameterName) {
|
||||
for (TypedConstructor c : typedConstructors) {
|
||||
for (TypedParameter p : c.getTypedParameters()) {
|
||||
@ -160,6 +161,7 @@ public class TypedClass implements TypedNode {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Type getParameterTypeInCurrentConstructor(String parameterName) {
|
||||
for (TypedParameter p : currentConstructor.getTypedParameters()) {
|
||||
if (p.getParaName().equals(parameterName)) {
|
||||
@ -170,28 +172,23 @@ public class TypedClass implements TypedNode {
|
||||
}
|
||||
|
||||
public boolean isThereField(String fieldName) {
|
||||
|
||||
for (TypedField f : typedFields) {
|
||||
if (f.getVarName().equals(getFieldNameWithOutThis(fieldName))) {
|
||||
if (f.getVarName().equals(fieldName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
private String getFieldNameWithOutThis(String fieldName) {
|
||||
if(fieldName.startsWith("this.")){
|
||||
fieldName = fieldName.substring(5);
|
||||
}
|
||||
return fieldName;
|
||||
}
|
||||
|
||||
public Type getFieldType(String fieldName) {
|
||||
for (TypedField f : typedFields) {
|
||||
if (f.getVarName().equals(getFieldNameWithOutThis(fieldName))) {
|
||||
if (f.getVarName().equals(fieldName)) {
|
||||
return f.getType();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Type getMethodType(String methodName) {
|
||||
for (TypedMethod m : typedMethods) {
|
||||
if (m.getName().equals(methodName)) {
|
||||
|
@ -26,11 +26,13 @@ public class TypedConstructor implements TypedNode {
|
||||
private List<TypedParameter> typedParameters = new ArrayList<>();
|
||||
private TypedBlock typedBlock;
|
||||
private Type type;
|
||||
|
||||
public TypedConstructor(String name, List<TypedParameter> typedParameters, TypedBlock typedBlock) {
|
||||
this.name = name;
|
||||
this.typedParameters = typedParameters;
|
||||
this.typedBlock = typedBlock;
|
||||
}
|
||||
|
||||
public TypedConstructor(Map<String, Type> localVar, TypedClass clas, Constructor unTypedConstructor) {
|
||||
convertToTypedConstructor(localVar, clas, unTypedConstructor);
|
||||
}
|
||||
@ -41,16 +43,16 @@ public class TypedConstructor implements TypedNode {
|
||||
for (Parameter param : unTypedConstructor.params()) {
|
||||
typedParameters.add(new TypedParameter(localVar, clas, param));
|
||||
}
|
||||
// Konstrukteur hat den Rückgabetyp wie der Klassenname, obwohl es keinen expliziten Rückgabetyp gibt
|
||||
type = clas.getType();
|
||||
|
||||
type = Type.VOID;
|
||||
}
|
||||
|
||||
public void convertToBlock(Map<String, Type> localVar, TypedClass clas, Constructor unTypedConstructor) {
|
||||
this.typedBlock = new TypedBlock(localVar, clas ,unTypedConstructor.block());
|
||||
this.typedBlock = new TypedBlock(localVar, clas, unTypedConstructor.block());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type typeCheck(Map<String, Type> localVar, TypedClass clas) {
|
||||
//TODO: check if return is there
|
||||
return type;
|
||||
}
|
||||
|
||||
@ -69,6 +71,6 @@ public class TypedConstructor implements TypedNode {
|
||||
|
||||
mv.visitInsn(Opcodes.RETURN);
|
||||
|
||||
context.wrapUp(0,0);
|
||||
context.wrapUp(0, 0);
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package de.maishai.typedast.typedclass;
|
||||
|
||||
import de.maishai.ast.records.Declaration;
|
||||
import de.maishai.ast.records.Node;
|
||||
import de.maishai.typedast.MethodContext;
|
||||
import de.maishai.typedast.TypedNode;
|
||||
import de.maishai.typedast.Type;
|
||||
@ -11,32 +10,34 @@ import lombok.NoArgsConstructor;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public final class TypedLocalVariable implements TypedNode {
|
||||
public final class TypedDeclaration implements TypedNode {
|
||||
private String name;
|
||||
private Type type;
|
||||
|
||||
public TypedLocalVariable(Map<String, Type> localVar, TypedClass clas, Declaration declaration){
|
||||
public TypedDeclaration(Map<String, Type> localVar, TypedClass clas, Declaration declaration) {
|
||||
convertToTypedLocalVariable(localVar, clas, declaration);
|
||||
}
|
||||
public void convertToTypedLocalVariable(Map<String, Type> localVar, TypedClass clas, Declaration declaration){
|
||||
if(localVar.containsKey(declaration.name())){
|
||||
|
||||
public void convertToTypedLocalVariable(Map<String, Type> localVar, TypedClass clas, Declaration declaration) {
|
||||
if (localVar.containsKey(declaration.name())) {
|
||||
throw new RuntimeException("Variable " + declaration.name() + " already declared");
|
||||
}
|
||||
this.setName(declaration.name());
|
||||
this.setType(declaration.type());
|
||||
name = declaration.name();
|
||||
type = declaration.type();
|
||||
localVar.put(this.name, this.type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type typeCheck(Map<String, Type> localVar, TypedClass clas) {
|
||||
Type type = localVar.get(name);
|
||||
if(type == this.type) {
|
||||
return type;
|
||||
}
|
||||
throw new RuntimeException("type of left not equals with type of right");
|
||||
Type type = localVar.get(name);
|
||||
if (type == this.type) {
|
||||
return type;
|
||||
}
|
||||
throw new RuntimeException("type of left not equals with type of right");
|
||||
}
|
||||
|
||||
public void codeGen(MethodVisitor mv, MethodContext ctx) {
|
@ -7,7 +7,7 @@ import org.objectweb.asm.MethodVisitor;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static de.maishai.typedast.Help.TypedExpressionHelp.getKindOfExpression;
|
||||
import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression;
|
||||
|
||||
@Data
|
||||
public class TypedDoWhile implements TypedStatement {
|
||||
@ -18,9 +18,10 @@ public class TypedDoWhile implements TypedStatement {
|
||||
public TypedDoWhile(Map<String, Type> localVar, TypedClass clas, DoWhile unTypedDoWhile) {
|
||||
convertToTypedDoWhile(localVar, clas, unTypedDoWhile);
|
||||
}
|
||||
|
||||
public void convertToTypedDoWhile(Map<String, Type> localVar, TypedClass clas, DoWhile unTypedDoWhile) {
|
||||
typedBlock = new TypedBlock(localVar, clas, unTypedDoWhile.block());
|
||||
cond = getKindOfExpression(localVar, clas, unTypedDoWhile.cond());
|
||||
cond = convertExpression(localVar, clas, unTypedDoWhile.cond());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -21,12 +21,12 @@ public class TypedField implements TypedNode {
|
||||
private String varName;
|
||||
private Type type;
|
||||
|
||||
public TypedField(Map<String, Type> localVar, TypedClass clas, Declaration declaration){
|
||||
//TODO: remove TypedField
|
||||
public TypedField(Map<String, Type> localVar, TypedClass clas, Declaration declaration) {
|
||||
convertToTypedField(localVar, clas, declaration);
|
||||
}
|
||||
|
||||
public void convertToTypedField(Map<String, Type> localVar, TypedClass clas, Declaration declaration){
|
||||
|
||||
public void convertToTypedField(Map<String, Type> localVar, TypedClass clas, Declaration declaration) {
|
||||
this.type = declaration.type();
|
||||
varName = declaration.name();
|
||||
this.typeCheck(localVar, clas);
|
||||
@ -35,11 +35,11 @@ public class TypedField implements TypedNode {
|
||||
@Override
|
||||
public Type typeCheck(Map<String, Type> localVar, TypedClass clas) {
|
||||
|
||||
if(clas.isThereField(varName)){
|
||||
if (clas.isThereField(varName)) {
|
||||
throw new RuntimeException("Field " + varName + " already declared");
|
||||
}
|
||||
if(type.getKind() == REFERENCE){
|
||||
if(!type.getReference().equals(clas.getClassName())){
|
||||
if (type.getKind() == REFERENCE) {
|
||||
if (!type.getReference().equals(clas.getClassName())) {
|
||||
throw new RuntimeException("Field " + varName + " has wrong type");
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,7 @@ import org.objectweb.asm.MethodVisitor;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static de.maishai.typedast.Help.TypedExpressionHelp.getKindOfExpression;
|
||||
import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@ -23,40 +23,43 @@ public class TypedFieldVarAccess implements TypedExpression {
|
||||
public TypedFieldVarAccess(Map<String, Type> localVar, TypedClass clas, FieldVarAccess unTypedFieldVarAccess) {
|
||||
convertToTypedFieldVarAccess(localVar, clas, unTypedFieldVarAccess);
|
||||
}
|
||||
|
||||
public void convertToTypedFieldVarAccess(Map<String, Type> localVar, TypedClass clas, FieldVarAccess unTypedFieldVarAccess) {
|
||||
field = unTypedFieldVarAccess.field();
|
||||
recursiveOwnerChain = getKindOfExpression(localVar, clas, unTypedFieldVarAccess.recursiveOwnerChain());
|
||||
recursiveOwnerChain = convertExpression(localVar, clas, unTypedFieldVarAccess.recursiveOwnerChain());
|
||||
name = unTypedFieldVarAccess.id();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type typeCheck(Map<String, Type> localVar, TypedClass clas) {
|
||||
if(field){
|
||||
if (field) {
|
||||
if (clas.isThereField(name)) {
|
||||
type = clas.getFieldType(name);
|
||||
return clas.getFieldType(name);
|
||||
}
|
||||
}else{
|
||||
} else {
|
||||
|
||||
if (clas.isThereField(name)) {
|
||||
type = clas.getFieldType(name);
|
||||
return clas.getFieldType(name);
|
||||
}else if(clas.isCurrentConstructorPresent()){
|
||||
if(clas.isParameterNameInCurrentConstructor(name)){
|
||||
} else if (clas.isCurrentConstructorPresent()) {
|
||||
if (clas.isParameterNameInCurrentConstructor(name)) {
|
||||
type = clas.getParameterTypeInCurrentConstructor(name);
|
||||
return clas.getParameterTypeInCurrentConstructor(name);
|
||||
}
|
||||
}else if(clas.isCurrentMethodPresent()){
|
||||
if(clas.isParameterWitNameInMethod(name)){
|
||||
} else if (clas.isCurrentMethodPresent()) {
|
||||
if (clas.isParameterWitNameInMethod(name)) {
|
||||
type = clas.getParameterTypeInCurrentMethod(name);
|
||||
return clas.getParameterTypeInCurrentMethod(name);
|
||||
}
|
||||
}
|
||||
if(localVar.containsKey(name)) {
|
||||
if (localVar.containsKey(name)) {
|
||||
type = localVar.get(name);
|
||||
return localVar.get(name);
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("Variable "+name+" not declared ");
|
||||
|
||||
throw new RuntimeException("Variable " + name + " not declared ");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -9,7 +9,7 @@ import org.objectweb.asm.MethodVisitor;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static de.maishai.typedast.Help.TypedExpressionHelp.getKindOfExpression;
|
||||
import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@ -19,14 +19,16 @@ public class TypedFor implements TypedStatement {
|
||||
private TypedExpression cond;
|
||||
private TypedAssignment inc;
|
||||
private TypedBlock typedBlock;
|
||||
//TODO: add Type
|
||||
//TODO: type of block in for loop
|
||||
private Type type;
|
||||
|
||||
public TypedFor(Map<String, Type> localVar, TypedClass clas, For unTypedFor) {
|
||||
convertToTypedFor(localVar, clas, unTypedFor);
|
||||
}
|
||||
public void convertToTypedFor(Map<String, Type> localVar,TypedClass clas, For unTypedFor) {
|
||||
|
||||
public void convertToTypedFor(Map<String, Type> localVar, TypedClass clas, For unTypedFor) {
|
||||
assign = new TypedAssignment(localVar, clas, unTypedFor.assign());
|
||||
cond = getKindOfExpression(localVar, clas, unTypedFor.cond());
|
||||
cond = convertExpression(localVar, clas, unTypedFor.cond());
|
||||
inc = new TypedAssignment(localVar, clas, unTypedFor.inc());
|
||||
typedBlock = new TypedBlock(localVar, clas, unTypedFor.block());
|
||||
}
|
||||
@ -38,7 +40,8 @@ public class TypedFor implements TypedStatement {
|
||||
throw new RuntimeException("Condition must be a boolean");
|
||||
}
|
||||
inc.typeCheck(localVar, clas);
|
||||
return typedBlock.typeCheck(localVar, clas);
|
||||
type = typedBlock.typeCheck(localVar, clas);
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -10,7 +10,7 @@ import org.objectweb.asm.Opcodes;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static de.maishai.typedast.Help.TypedExpressionHelp.getKindOfExpression;
|
||||
import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@ -19,14 +19,16 @@ public class TypedIfElse implements TypedStatement {
|
||||
private TypedBlock ifTypedBlock;
|
||||
private TypedBlock elseTypedBlock;
|
||||
//TODO: add Type
|
||||
private Type type;
|
||||
|
||||
public TypedIfElse(Map<String, Type> localVar, TypedClass clas, IfElse unTypedIfElse) {
|
||||
convertToTypedIfElse(localVar, clas, unTypedIfElse);
|
||||
}
|
||||
|
||||
public void convertToTypedIfElse(Map<String, Type> localVar, TypedClass clas, IfElse unTypedIfElse) {
|
||||
ifTypedBlock = new TypedBlock(localVar, clas, unTypedIfElse.ifBlock());
|
||||
elseTypedBlock = new TypedBlock(localVar, clas, unTypedIfElse.elseBlock());
|
||||
typedCon = getKindOfExpression(localVar, clas, unTypedIfElse.cond());
|
||||
typedCon = convertExpression(localVar, clas, unTypedIfElse.cond());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -38,7 +40,13 @@ public class TypedIfElse implements TypedStatement {
|
||||
if (ifTypedBlock.typeCheck(localVar, clas) != Type.VOID) {
|
||||
throw new RuntimeException("If block must be of type void");
|
||||
}
|
||||
return Type.VOID;
|
||||
|
||||
//TODO: catch all cases of return when one method has a return type
|
||||
if (ifTypedBlock.typeCheck(localVar, clas) == elseTypedBlock.typeCheck(localVar, clas)) {
|
||||
type = ifTypedBlock.typeCheck(localVar, clas);
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -23,6 +23,7 @@ public class TypedIntLiteral implements TypedExpression {
|
||||
public TypedIntLiteral(Map<String, Type> localVar, TypedClass clas, IntLiteral unTypedIntLiteral) {
|
||||
convertToTypedIntLiteral(localVar, clas, unTypedIntLiteral);
|
||||
}
|
||||
|
||||
public void convertToTypedIntLiteral(Map<String, Type> localVar, TypedClass clas, IntLiteral unTypedIntLiteral) {
|
||||
value = unTypedIntLiteral.value();
|
||||
type = Type.INT;
|
||||
@ -32,6 +33,7 @@ public class TypedIntLiteral implements TypedExpression {
|
||||
public Type typeCheck(Map<String, Type> localVar, TypedClass clas) {
|
||||
return type;
|
||||
}
|
||||
|
||||
public TypedIntLiteral(Integer value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
@ -21,33 +21,35 @@ public class TypedMethod implements TypedNode {
|
||||
private Type returnType;
|
||||
private List<TypedParameter> typedParameters = new ArrayList<>();
|
||||
private TypedBlock typedBlock;
|
||||
//private List<TypedLocalVariable> localVariables = new ArrayList<>();
|
||||
|
||||
public TypedMethod(Map<String, Type> localVar, TypedClass clas, Method unTypedMethod) {
|
||||
convertToTypedMethod(localVar, clas, unTypedMethod);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof TypedMethod) {
|
||||
TypedMethod other = (TypedMethod) obj;
|
||||
return name.equals(other.name) && returnType.equals(other.returnType) && typedParameters.equals(other.typedParameters);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void convertToTypedMethod(Map<String, Type> localVar, TypedClass clas, Method unTypedMethod) {
|
||||
|
||||
name = unTypedMethod.methodName();
|
||||
returnType = unTypedMethod.type();
|
||||
for (Parameter parameter : unTypedMethod.params()) {
|
||||
for (var parameter : unTypedMethod.params()) {
|
||||
typedParameters.add(new TypedParameter(localVar, clas, parameter));
|
||||
}
|
||||
for (var method : clas.getTypedMethods()) {
|
||||
if (method.getName().equals(name) && method.getTypedParameters().size() == typedParameters.size()
|
||||
&& method.getReturnType().equals(returnType)) {
|
||||
|
||||
for (int i = 0; i < method.getTypedParameters().size(); i++){
|
||||
if(method.getTypedParameters().get(i).getType().equals(typedParameters.get(i).getType())){
|
||||
throw new RuntimeException("Method " + name + " already exists");
|
||||
}
|
||||
}
|
||||
|
||||
if (method.getTypedParameters().isEmpty() && typedParameters.isEmpty()) {
|
||||
clas.getTypedMethods().stream().filter(method -> method.equals(this)).findFirst().ifPresentOrElse(
|
||||
method -> {
|
||||
throw new RuntimeException("Method " + name + " already exists");
|
||||
}
|
||||
}
|
||||
}
|
||||
}, () -> {
|
||||
});
|
||||
|
||||
localVar.put(name, returnType);
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,7 @@ import org.objectweb.asm.MethodVisitor;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static de.maishai.typedast.Help.TypedExpressionHelp.getKindOfExpression;
|
||||
import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@ -26,13 +26,13 @@ public class TypedMethodCall implements TypedExpression, TypedStatement {
|
||||
public void convertToTypedMethodCall(Map<String, Type> localVar, TypedClass clas, MethodCall unTypedMethodCall) {
|
||||
recipient = new TypedFieldVarAccess(localVar, clas, unTypedMethodCall.recipient());
|
||||
for (Expression arg : unTypedMethodCall.args()) {
|
||||
args.add(getKindOfExpression(localVar, clas, arg));
|
||||
args.add(convertExpression(localVar, clas, arg));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type typeCheck(Map<String, Type> localVar, TypedClass clas) {
|
||||
|
||||
//TODO: implement this
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static de.maishai.typedast.Help.TypedExpressionHelp.getKindOfExpression;
|
||||
import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression;
|
||||
|
||||
@Data
|
||||
public class TypedNew implements TypedExpression, TypedStatement {
|
||||
@ -23,16 +23,12 @@ public class TypedNew implements TypedExpression, TypedStatement {
|
||||
public void convertToTypedNew(Map<String, Type> localVar, TypedClass clas, New unTypedNew) {
|
||||
type = unTypedNew.type();
|
||||
for (Expression arg : unTypedNew.args()) {
|
||||
args.add(getKindOfExpression(localVar, clas, arg));
|
||||
args.add(convertExpression(localVar, clas, arg));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type typeCheck(Map<String, Type> localVar, TypedClass clas) {
|
||||
if(clas == null){
|
||||
throw new RuntimeException("Class not found");
|
||||
}
|
||||
|
||||
for(var constructor : clas.getTypedConstructors()){
|
||||
if(constructor.getTypedParameters().size() == args.size()){
|
||||
boolean valid = true;
|
||||
|
@ -1,17 +1,14 @@
|
||||
package de.maishai.typedast.typedclass;
|
||||
|
||||
import de.maishai.ast.records.Node;
|
||||
import de.maishai.ast.records.Parameter;
|
||||
import de.maishai.typedast.TypedNode;
|
||||
import de.maishai.typedast.Type;
|
||||
import de.maishai.typedast.TypedNode;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@AllArgsConstructor
|
||||
@RequiredArgsConstructor
|
||||
@Data
|
||||
public class TypedParameter implements TypedNode {
|
||||
private String paraName;
|
||||
@ -20,22 +17,31 @@ public class TypedParameter implements TypedNode {
|
||||
public TypedParameter(Map<String, Type> localVar, TypedClass clas, Parameter unTypedParameter) {
|
||||
convertToTypedParameter(localVar, clas, unTypedParameter);
|
||||
}
|
||||
|
||||
public void convertToTypedParameter(Map<String, Type> localVar, TypedClass clas, Parameter unTypedParameter) {
|
||||
paraName = unTypedParameter.name();
|
||||
type = unTypedParameter.type();
|
||||
//localVar.put(paraName, type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof TypedParameter) {
|
||||
TypedParameter other = (TypedParameter) obj;
|
||||
return paraName.equals(other.paraName) && type.equals(other.type);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Type typeCheck(Map<String, Type> localVar, TypedClass clas) {
|
||||
|
||||
if(clas.isCurrentMethodPresent()){
|
||||
if(clas.isParameterWitNameInMethod(paraName)) {
|
||||
if (clas.isCurrentMethodPresent()) {
|
||||
if (clas.isParameterWitNameInMethod(paraName)) {
|
||||
throw new RuntimeException("Parameter " + paraName + " already exists");
|
||||
}
|
||||
}else if(clas.isCurrentConstructorPresent()){
|
||||
if(clas.isParameterWitNameInConstructor(paraName)) {
|
||||
} else if (clas.isCurrentConstructorPresent()) {
|
||||
if (clas.isParameterWitNameInConstructor(paraName)) {
|
||||
throw new RuntimeException("Parameter " + paraName + " already exists");
|
||||
}
|
||||
}
|
||||
@ -44,5 +50,4 @@ public class TypedParameter implements TypedNode {
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ import org.objectweb.asm.Opcodes;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static de.maishai.typedast.Help.TypedExpressionHelp.getKindOfExpression;
|
||||
import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@ -21,15 +21,16 @@ public class TypedReturn implements TypedStatement {
|
||||
public TypedReturn(Map<String, Type> localVar, TypedClass clas, Return unTypedReturn) {
|
||||
convertToTypedReturn(localVar, clas, unTypedReturn);
|
||||
}
|
||||
|
||||
public void convertToTypedReturn(Map<String, Type> localVar, TypedClass clas, Return unTypedReturn) {
|
||||
ret = getKindOfExpression(localVar, clas, unTypedReturn.ret());
|
||||
ret = convertExpression(localVar, clas, unTypedReturn.ret());
|
||||
type = ret.getType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type typeCheck(Map<String, Type> localVar, TypedClass clas) {
|
||||
if(clas.isCurrentMethodPresent()){
|
||||
if(clas.getCurrentMethod().getReturnType().getKind() != this.type.getKind()){
|
||||
if (clas.isCurrentMethodPresent()) {
|
||||
if (clas.getCurrentMethod().getReturnType().getKind() != this.type.getKind()) {
|
||||
StringBuilder exp = new StringBuilder();
|
||||
exp.append("\nMismatched return type: ");
|
||||
exp.append("\nExpected: ").append(clas.getCurrentMethod().getReturnType().getKind());
|
||||
|
@ -11,7 +11,7 @@ import org.objectweb.asm.Opcodes;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static de.maishai.typedast.Help.TypedExpressionHelp.getKindOfExpression;
|
||||
import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression;
|
||||
|
||||
@Data
|
||||
public class TypedUnary implements TypedExpression {
|
||||
@ -19,25 +19,27 @@ public class TypedUnary implements TypedExpression {
|
||||
private TypedExpression right;
|
||||
private Type type;
|
||||
|
||||
public TypedUnary(Map<String, Type> localVar, TypedClass clas, Unary unTypedUnary){
|
||||
public TypedUnary(Map<String, Type> localVar, TypedClass clas, Unary unTypedUnary) {
|
||||
convertToTypedUnary(localVar, clas, unTypedUnary);
|
||||
}
|
||||
|
||||
public void convertToTypedUnary(Map<String, Type> localVar, TypedClass clas, Unary unTypedUnary) {
|
||||
op = unTypedUnary.op();
|
||||
right = getKindOfExpression(localVar, clas, unTypedUnary.right());
|
||||
right = convertExpression(localVar, clas, unTypedUnary.right());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type typeCheck(Map<String, Type> localVar, TypedClass clas) {
|
||||
|
||||
if(op == UnaryOperator.NOT){
|
||||
if(right.typeCheck(localVar, clas) != Type.BOOL){
|
||||
if (op == UnaryOperator.NOT) {
|
||||
if (right.typeCheck(localVar, clas) != Type.BOOL) {
|
||||
throw new RuntimeException("Not operator must be applied to boolean");
|
||||
}
|
||||
return Type.BOOL;
|
||||
}
|
||||
|
||||
if(op == UnaryOperator.SUB){
|
||||
if(right.typeCheck(localVar, clas) != Type.INT){
|
||||
if (op == UnaryOperator.SUB) {
|
||||
if (right.typeCheck(localVar, clas) != Type.INT) {
|
||||
throw new RuntimeException("Minus operator must be applied to int");
|
||||
}
|
||||
return Type.INT;
|
||||
@ -48,11 +50,11 @@ public class TypedUnary implements TypedExpression {
|
||||
@Override
|
||||
public void codeGen(MethodVisitor mv, MethodContext ctx) {
|
||||
right.codeGen(mv, ctx);
|
||||
if(op == UnaryOperator.NOT){
|
||||
if (op == UnaryOperator.NOT) {
|
||||
mv.visitInsn(Opcodes.ICONST_1);
|
||||
mv.visitInsn(Opcodes.IXOR);
|
||||
}
|
||||
if(op == UnaryOperator.SUB){
|
||||
if (op == UnaryOperator.SUB) {
|
||||
mv.visitInsn(Opcodes.INEG);
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ import org.objectweb.asm.MethodVisitor;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static de.maishai.typedast.Help.TypedExpressionHelp.getKindOfExpression;
|
||||
import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression;
|
||||
|
||||
@Data
|
||||
public class TypedWhile implements TypedStatement {
|
||||
@ -20,17 +20,17 @@ public class TypedWhile implements TypedStatement {
|
||||
}
|
||||
|
||||
public void convertToTypedWhile(Map<String, Type> localVar, TypedClass clas, While unTypedWhile) {
|
||||
cond = getKindOfExpression(localVar, clas, unTypedWhile.cond());
|
||||
cond = convertExpression(localVar, clas, unTypedWhile.cond());
|
||||
typedBlock = new TypedBlock(localVar, clas, unTypedWhile.block());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type typeCheck(Map<String, Type> localVar, TypedClass clas) {
|
||||
if(cond.typeCheck(localVar, clas) != Type.BOOL){
|
||||
if (cond.typeCheck(localVar, clas) != Type.BOOL) {
|
||||
throw new RuntimeException("While condition must be a boolean");
|
||||
}
|
||||
typedBlock.typeCheck(localVar, clas);
|
||||
this.type = Type.VOID;
|
||||
return Type.BOOL;
|
||||
type = typedBlock.typeCheck(localVar, clas);
|
||||
return type;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user