Add a new method to each class in TypedAST package and implement it

This commit is contained in:
Ahmad 2024-05-09 15:51:31 +02:00
parent 37950dee82
commit 65dd9152f0
13 changed files with 140 additions and 39 deletions

View File

@ -1,6 +1,6 @@
package de.maishai.typedast.typedclass; package de.maishai.typedast.typedclass;
import de.maishai.ast.records.Assignment; import de.maishai.ast.records.*;
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.TypedNode;
@ -11,17 +11,25 @@ import org.objectweb.asm.MethodVisitor;
import java.util.Map; import java.util.Map;
import static de.maishai.typedast.Util.TypedExpressionUtil.GET_KIND_OF_EXPRESSION;
@Data @Data
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; private Type type;
public TypedAssignment convertToTypedAssignment(Map<String, Type> localVar, Map<String, TypedClass> classes, Assignment untyped) {
varName = untyped.location().id();
value = GET_KIND_OF_EXPRESSION(localVar, classes, untyped.value());
return this;
}
@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)) {
throw new RuntimeException("Variable not declared"); throw new RuntimeException("Variable not declared");
} }
Type typeLeft = localVar.get(varName); Type typeLeft = localVar.get(varName);
Type typeRight = value.typeCheck(localVar, classes); Type typeRight = value.typeCheck(localVar, classes);
@ -31,7 +39,6 @@ public class TypedAssignment implements TypedStatement {
} }
throw new RuntimeException("type of left not equals with type of right"); throw new RuntimeException("type of left not equals with type of right");
} }
@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) {
Assignment untyped = (Assignment) unTypedAST; Assignment untyped = (Assignment) unTypedAST;
@ -45,4 +52,5 @@ public class TypedAssignment implements TypedStatement {
public void codeGen(MethodVisitor mv, MethodContext ctx) { public void codeGen(MethodVisitor mv, MethodContext ctx) {
} }
} }

View File

@ -1,36 +1,47 @@
package de.maishai.typedast.typedclass; package de.maishai.typedast.typedclass;
import de.maishai.ast.Operator; import de.maishai.ast.Operator;
import de.maishai.ast.records.Binary; import de.maishai.ast.records.*;
import de.maishai.typedast.TypedExpression; import de.maishai.typedast.TypedExpression;
import de.maishai.typedast.TypedNode; import de.maishai.typedast.TypedNode;
import de.maishai.typedast.Type; import de.maishai.typedast.Type;
import lombok.Data; import lombok.Data;
import java.util.Map; import java.util.Map;
import static de.maishai.typedast.Util.TypedExpressionUtil.GET_KIND_OF_EXPRESSION;
@Data @Data
public class TypedBinary implements TypedExpression { 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; private Type type;
public TypedBinary convertToTypedBinary(Map<String, Type> localVar, Map<String, TypedClass> classes, Binary unTypedBinary) {
left = GET_KIND_OF_EXPRESSION(localVar, classes, unTypedBinary.left());
right = GET_KIND_OF_EXPRESSION(localVar, classes, unTypedBinary.right());
op = unTypedBinary.op();
return this;
}
@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; type = Type.INT;
return Type.INT; return Type.INT;
} else { } else {
throw new RuntimeException("Type mismatch"); 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 || 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; type = Type.BOOL;
return Type.BOOL; return Type.BOOL;
} else { } else {
throw new RuntimeException("Type mismatch"); throw new RuntimeException("Type mismatch in " + op);
} }
} 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 &&
@ -38,7 +49,7 @@ public class TypedBinary implements TypedExpression {
type = Type.BOOL; type = Type.BOOL;
return Type.BOOL; return Type.BOOL;
} else { } else {
throw new RuntimeException("Type mismatch"); throw new RuntimeException("Type mismatch in " + op);
} }
} else { } else {
throw new RuntimeException("Invalid operator"); throw new RuntimeException("Invalid operator");

View File

@ -12,6 +12,12 @@ public class TypedBoolLiteral implements TypedExpression {
private Boolean value; private Boolean value;
private Type type; private Type type;
public TypedBoolLiteral convertToTypedBoolLiteral(Map<String, Type> localVar, Map<String, TypedClass> classes,BoolLiteral unTypedBoolLiteral) {
value = unTypedBoolLiteral.value();
return this;
}
@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; type = Type.BOOL;

View File

@ -11,9 +11,15 @@ import org.objectweb.asm.MethodVisitor;
import java.util.Map; import java.util.Map;
@Data @Data
public class TypedBreak implements TypedStatement { public class TypedBreak implements TypedStatement {
private Type type;
public TypedBreak convertToTypedBreak(Break unTypedBreak) {
return this;
}
@Override @Override
public Type typeCheck(Map<String, Type> localVar, Map<String, TypedClass> classes) { public Type typeCheck(Map<String, Type> localVar, Map<String, TypedClass> classes) {
return Type.VOID; type = Type.VOID;
return type;
} }
@Override @Override

View File

@ -10,6 +10,11 @@ import java.util.Map;
@Data @Data
public class TypedCharLiteral implements TypedExpression { public class TypedCharLiteral implements TypedExpression {
private char value; private char value;
public TypedCharLiteral convertToCharLiteral(Map<String, Type> localVar, Map<String, TypedClass> classes, CharLiteral unTypedCharLiteral) {
value = unTypedCharLiteral.value();
return this;
}
@Override @Override
public Type typeCheck(Map<String, Type> localVar, Map<String, TypedClass> classes) { public Type typeCheck(Map<String, Type> localVar, Map<String, TypedClass> classes) {
return Type.CHAR; return Type.CHAR;

View File

@ -18,12 +18,14 @@ public class TypedField implements TypedNode {
private String varName; private String varName;
private Type type; private Type type;
public TypedField convertToTypedField(Map<String, Type> localVar, Map<String, TypedClass> classes, Declaration declaration){
public TypedField unTypedFieldToTypedField(Declaration declaration){ if(localVar.containsKey(declaration.name())){
TypedField typedField = new TypedField(); throw new RuntimeException("Variable " + declaration.name() + " already declared");
typedField.setType(declaration.type()); }
typedField.setVarName(declaration.name()); varName = declaration.name();
return typedField; type = declaration.type();
localVar.put(this.varName, this.type);
return this;
} }
@Override @Override

View File

@ -1,6 +1,6 @@
package de.maishai.typedast.typedclass; package de.maishai.typedast.typedclass;
import de.maishai.ast.records.For; import de.maishai.ast.records.*;
import de.maishai.typedast.*; import de.maishai.typedast.*;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
@ -9,18 +9,29 @@ import org.objectweb.asm.MethodVisitor;
import java.util.Map; import java.util.Map;
import static de.maishai.typedast.Util.TypedExpressionUtil.GET_KIND_OF_EXPRESSION;
@Data @Data
@AllArgsConstructor @AllArgsConstructor
@NoArgsConstructor @NoArgsConstructor
public class TypedFor implements TypedStatement { public class TypedFor implements TypedStatement {
private TypedExpression assign; private TypedAssignment assign;
private TypedExpression cond; private TypedExpression cond;
private TypedExpression inc; private TypedAssignment inc;
private TypedBlock typedBlock; private TypedBlock typedBlock;
public TypedFor convertToTypedFor(Map<String, Type> localVar, Map<String, TypedClass> classes, For unTypedFor) {
assign = new TypedAssignment().convertToTypedAssignment(localVar, classes, unTypedFor.assign());
cond = GET_KIND_OF_EXPRESSION(localVar, classes, unTypedFor.cond());
inc = new TypedAssignment().convertToTypedAssignment(localVar, classes, unTypedFor.inc());
typedBlock = new TypedBlock().blockToTypedBlock(localVar, classes, unTypedFor.block());
return this;
}
@Override @Override
public Type typeCheck(Map<String, Type> localVar, Map<String, TypedClass> classes) { public Type typeCheck(Map<String, Type> localVar, Map<String, TypedClass> classes) {
assign.typeCheck(localVar, classes); assign.typeCheck(localVar, classes);
if(!cond.typeCheck(localVar, classes).equals(Type.BOOL)) { if (!cond.typeCheck(localVar, classes).equals(Type.BOOL)) {
throw new RuntimeException("Condition must be a boolean"); throw new RuntimeException("Condition must be a boolean");
} }
inc.typeCheck(localVar, classes); inc.typeCheck(localVar, classes);
@ -31,12 +42,14 @@ public class TypedFor implements TypedStatement {
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) {
For untyped = (For) unTypedAST; For untyped = (For) unTypedAST;
TypedFor typedFor = new TypedFor(); TypedFor typedFor = new TypedFor();
typedFor.setAssign((TypedExpression) assign.convertToTypedAST(localVar, classes, untyped.assign())); TypedAssignment assign = new TypedAssignment();
typedFor.setCond((TypedExpression) cond.convertToTypedAST(localVar, classes, untyped.cond())); typedFor.setAssign(assign.convertToTypedAssignment(localVar,classes,untyped.assign()));
typedFor.setInc((TypedExpression) inc.convertToTypedAST(localVar, classes, untyped.inc())); TypedAssignment lnc = new TypedAssignment();
typedFor.setInc(lnc.convertToTypedAssignment(localVar,classes,untyped.inc()));
typedFor.setCond(null);
TypedBlock typedBlock = new TypedBlock(); TypedBlock typedBlock = new TypedBlock();
typedFor.setTypedBlock(typedBlock.unTypedBlockToTypedBlock(untyped.block())); typedFor.setTypedBlock(typedBlock.blockToTypedBlock(localVar, classes, untyped.block()));
return typedFor; return typedFor;
} }

View File

@ -1,25 +1,33 @@
package de.maishai.typedast.typedclass; package de.maishai.typedast.typedclass;
import de.maishai.ast.records.IfElse; 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 org.objectweb.asm.MethodVisitor;
import java.util.Map; import java.util.Map;
import static de.maishai.typedast.Util.TypedExpressionUtil.GET_KIND_OF_EXPRESSION;
@Data @Data
public class TypedIfElse implements TypedStatement { public class TypedIfElse implements TypedStatement {
private TypedExpression typedCon; private TypedExpression typedCon;
private TypedBlock ifTypedBlock; private TypedBlock ifTypedBlock;
private TypedBlock elseTypedBlock; private TypedBlock elseTypedBlock;
public TypedIfElse convertToTypedIfElse(Map<String, Type> localVar, Map<String, TypedClass> classes, IfElse unTypedIfElse) {
ifTypedBlock = new TypedBlock().blockToTypedBlock(localVar, classes, unTypedIfElse.ifBlock());
elseTypedBlock = new TypedBlock().blockToTypedBlock(localVar, classes, unTypedIfElse.elseBlock());
typedCon = GET_KIND_OF_EXPRESSION(localVar, classes, unTypedIfElse.cond());
return this;
}
@Override @Override
public Type typeCheck(Map<String, Type> localVar, Map<String, TypedClass> classes) { public Type typeCheck(Map<String, Type> localVar, Map<String, TypedClass> classes) {
// condition must be a boolean
if (typedCon.typeCheck(localVar, classes) != Type.BOOL) { if (typedCon.typeCheck(localVar, classes) != Type.BOOL) {
throw new RuntimeException("If condition must be a boolean"); throw new RuntimeException("If condition must be a boolean");
} }
//Statement1 and Statement2 must be of type void
if (ifTypedBlock.typeCheck(localVar, classes) != Type.VOID) { if (ifTypedBlock.typeCheck(localVar, classes) != Type.VOID) {
throw new RuntimeException("If block must be of type void"); throw new RuntimeException("If block must be of type void");
} }
@ -35,8 +43,8 @@ public class TypedIfElse implements TypedStatement {
TypedBlock ifTypedBlock = new TypedBlock(); TypedBlock ifTypedBlock = new TypedBlock();
TypedBlock elseTypedBlock = new TypedBlock(); TypedBlock elseTypedBlock = new TypedBlock();
typedIfElse.setIfTypedBlock(ifTypedBlock.unTypedBlockToTypedBlock(ifElse.ifBlock())); typedIfElse.setIfTypedBlock(ifTypedBlock.blockToTypedBlock(localVar, classes, ifElse.ifBlock()));
typedIfElse.setElseTypedBlock(elseTypedBlock.unTypedBlockToTypedBlock(ifElse.elseBlock())); typedIfElse.setElseTypedBlock(elseTypedBlock.blockToTypedBlock(localVar, classes, ifElse.elseBlock()));
return typedIfElse; return typedIfElse;
} }

View File

@ -15,6 +15,11 @@ import java.util.Map;
@NoArgsConstructor @NoArgsConstructor
public class TypedIntLiteral implements TypedExpression { public class TypedIntLiteral implements TypedExpression {
private Integer value; private Integer value;
public TypedIntLiteral convertToTypedIntLiteral(Map<String, Type> localVar, Map<String, TypedClass> classes, IntLiteral unTypedIntLiteral) {
value = unTypedIntLiteral.value();
return this;
}
@Override @Override
public Type typeCheck(Map<String, Type> localVar, Map<String, TypedClass> classes) { public Type typeCheck(Map<String, Type> localVar, Map<String, TypedClass> classes) {
return Type.INT; return Type.INT;

View File

@ -16,14 +16,23 @@ import java.util.Map;
public final class TypedLocalVariable implements TypedNode { public final class TypedLocalVariable implements TypedNode {
private String name; private String name;
private Type type; private Type type;
public TypedLocalVariable convertToTypedLocalVariable(Map<String, Type> localVar, Map<String, TypedClass> classes, Declaration declaration){
if(localVar.containsKey(declaration.name())){
throw new RuntimeException("Variable " + declaration.name() + " already declared");
}
this.setName(declaration.name());
this.setType(declaration.type());
localVar.put(this.name, this.type);
return this;
}
@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)) { Type type = localVar.get(name);
throw new RuntimeException("Variable " + name + " already exists"); if(type == this.type) {
} return type;
localVar.put(name, type); }
return type; throw new RuntimeException("type of left not equals with type of right");
} }
@Override @Override

View File

@ -1,19 +1,28 @@
package de.maishai.typedast.typedclass; package de.maishai.typedast.typedclass;
import de.maishai.ast.records.Return; 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 org.objectweb.asm.MethodVisitor;
import java.util.Map; import java.util.Map;
import static de.maishai.typedast.Util.TypedExpressionUtil.GET_KIND_OF_EXPRESSION;
@Data @Data
public class TypedReturn implements TypedStatement { public class TypedReturn implements TypedStatement {
private TypedExpression ret; private TypedExpression ret;
public TypedReturn convertToTypedReturn(Map<String, Type> localVar, Map<String, TypedClass> classes, Return unTypedReturn) {
ret = GET_KIND_OF_EXPRESSION(localVar, classes, unTypedReturn.ret());
return this;
}
@Override @Override
public Type typeCheck(Map<String, Type> localVar, Map<String, TypedClass> classes) { public Type typeCheck(Map<String, Type> localVar, Map<String, TypedClass> classes) {
return ret.typeCheck(localVar, classes); //TODO: Implement typeCheck for Return
return null;
} }
@Override @Override

View File

@ -8,10 +8,19 @@ import de.maishai.typedast.Type;
import lombok.Data; import lombok.Data;
import java.util.Map; import java.util.Map;
import static de.maishai.typedast.Util.TypedExpressionUtil.GET_KIND_OF_EXPRESSION;
@Data @Data
public class TypedUnary implements TypedExpression { public class TypedUnary implements TypedExpression {
private UnaryOperator op; private UnaryOperator op;
private TypedExpression right; private TypedExpression right;
public TypedUnary convertToTypedUnary(Map<String, Type> localVar, Map<String, TypedClass> classes, Unary unTypedUnary) {
op = unTypedUnary.op();
right = GET_KIND_OF_EXPRESSION(localVar, classes, unTypedUnary.right());
return this;
}
@Override @Override
public Type typeCheck(Map<String, Type> localVar, Map<String, TypedClass> classes) { public Type typeCheck(Map<String, Type> localVar, Map<String, TypedClass> classes) {

View File

@ -1,22 +1,31 @@
package de.maishai.typedast.typedclass; package de.maishai.typedast.typedclass;
import de.maishai.ast.records.While; 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 org.objectweb.asm.MethodVisitor;
import java.util.Map; import java.util.Map;
import static de.maishai.typedast.Util.TypedExpressionUtil.GET_KIND_OF_EXPRESSION;
@Data @Data
public class TypedWhile implements TypedStatement { public class TypedWhile implements TypedStatement {
private TypedExpression cond; private TypedExpression cond;
private TypedBlock typedBlock; private TypedBlock typedBlock;
public TypedWhile convertToTypedWhile(Map<String, Type> localVar, Map<String, TypedClass> classes, While unTypedWhile) {
cond = GET_KIND_OF_EXPRESSION(localVar, classes, unTypedWhile.cond());
typedBlock = new TypedBlock().blockToTypedBlock(localVar, classes, unTypedWhile.block());
return this;
}
@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(cond.typeCheck(localVar, classes) != Type.BOOL){ if(cond.typeCheck(localVar, classes) != Type.BOOL){
throw new RuntimeException("While condition must be a boolean"); throw new RuntimeException("While condition must be a boolean");
} }
return typedBlock.typeCheck(localVar, classes); typedBlock.typeCheck(localVar, classes);
return Type.BOOL;
} }
@Override @Override
@ -25,10 +34,11 @@ public class TypedWhile implements TypedStatement {
TypedWhile typedWhile = new TypedWhile(); TypedWhile typedWhile = new TypedWhile();
typedWhile.setCond((TypedExpression) cond.convertToTypedAST(localVar, classes, untyped.cond())); typedWhile.setCond((TypedExpression) cond.convertToTypedAST(localVar, classes, untyped.cond()));
TypedBlock typedBlock = new TypedBlock(); TypedBlock typedBlock = new TypedBlock();
typedWhile.setTypedBlock(typedBlock.unTypedBlockToTypedBlock(untyped.block())); typedWhile.setTypedBlock(typedBlock.blockToTypedBlock(localVar, classes, untyped.block()));
return typedWhile; return typedWhile;
} }
@Override @Override
public void codeGen(MethodVisitor mv, MethodContext ctx) { public void codeGen(MethodVisitor mv, MethodContext ctx) {