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;
import de.maishai.ast.records.Assignment;
import de.maishai.ast.records.*;
import de.maishai.typedast.MethodContext;
import de.maishai.typedast.TypedExpression;
import de.maishai.typedast.TypedNode;
@ -11,17 +11,25 @@ import org.objectweb.asm.MethodVisitor;
import java.util.Map;
import static de.maishai.typedast.Util.TypedExpressionUtil.GET_KIND_OF_EXPRESSION;
@Data
public class TypedAssignment implements TypedStatement {
private String varName;
private TypedExpression value;
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
public Type typeCheck(Map<String, Type> localVar, Map<String, TypedClass> classes) {
if (!localVar.containsKey(varName)) {
throw new RuntimeException("Variable not declared");
}
Type typeLeft = localVar.get(varName);
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");
}
@Override
public TypedNode convertToTypedAST(Map<String, Type> localVar, Map<String, TypedClass> classes, de.maishai.ast.records.Node unTypedAST) {
Assignment untyped = (Assignment) unTypedAST;
@ -45,4 +52,5 @@ public class TypedAssignment implements TypedStatement {
public void codeGen(MethodVisitor mv, MethodContext ctx) {
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -16,15 +16,24 @@ import java.util.Map;
public final class TypedLocalVariable implements TypedNode {
private String name;
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
public Type typeCheck(Map<String, Type> localVar, Map<String, TypedClass> classes) {
if(localVar.containsKey(name)) {
throw new RuntimeException("Variable " + name + " already exists");
}
localVar.put(name, type);
Type type = localVar.get(name);
if(type == this.type) {
return type;
}
throw new RuntimeException("type of left not equals with type of right");
}
@Override
public TypedNode convertToTypedAST(Map<String, Type> localVar, Map<String, TypedClass> classes, de.maishai.ast.records.Node unTypedAST) {

View File

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

View File

@ -8,10 +8,19 @@ import de.maishai.typedast.Type;
import lombok.Data;
import java.util.Map;
import static de.maishai.typedast.Util.TypedExpressionUtil.GET_KIND_OF_EXPRESSION;
@Data
public class TypedUnary implements TypedExpression {
private UnaryOperator op;
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
public Type typeCheck(Map<String, Type> localVar, Map<String, TypedClass> classes) {

View File

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