diff --git a/src/main/java/Input.java b/src/main/java/Input.java index 80b66b6..4b8b0f9 100644 --- a/src/main/java/Input.java +++ b/src/main/java/Input.java @@ -7,7 +7,9 @@ class Example { class Example2 { boolean instVarBool; int m(int n){ - if(instVarBool){ + boolean localBool; + localBool = true; + if(localBool){ return n; } return -1; diff --git a/src/main/java/abstractSyntaxTree/Expression/IntConstantExpression.java b/src/main/java/abstractSyntaxTree/Expression/IntConstantExpression.java index b1fd5de..b1a1d88 100644 --- a/src/main/java/abstractSyntaxTree/Expression/IntConstantExpression.java +++ b/src/main/java/abstractSyntaxTree/Expression/IntConstantExpression.java @@ -1,6 +1,12 @@ package abstractSyntaxTree.Expression; import TypeCheck.AbstractType; +import TypeCheck.TypeCheckResult; +import abstractSyntaxTree.Parameter.ParameterList; +import org.objectweb.asm.MethodVisitor; + +import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Objects; @@ -11,6 +17,16 @@ public class IntConstantExpression extends AbstractType implements IExpression{ this.value = value; } + @Override + public TypeCheckResult typeCheck(HashMap>> methodContext, HashMap> typeContext, HashMap localVars) throws Exception { + return null; + } + + @Override + public void codeGen(MethodVisitor mv, LinkedHashMap localVars, HashMap> typeContext) throws Exception { + + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/src/main/java/abstractSyntaxTree/Expression/LocalVarIdentifier.java b/src/main/java/abstractSyntaxTree/Expression/LocalVarIdentifier.java index 141e318..2e3ceb9 100644 --- a/src/main/java/abstractSyntaxTree/Expression/LocalVarIdentifier.java +++ b/src/main/java/abstractSyntaxTree/Expression/LocalVarIdentifier.java @@ -25,7 +25,13 @@ public class LocalVarIdentifier implements IExpression{ @Override public TypeCheckResult typeCheck(HashMap>> methodContext, HashMap> typeContext, HashMap localVars) throws Exception { - return null; + TypeCheckResult result = new TypeCheckResult(); + if (localVars.containsKey(identifier)) { + result.type = localVars.get(identifier); + } else { + throw new Exception("TypeCheck Exception: local var does not exist"); + } + return result; } @Override diff --git a/src/main/java/abstractSyntaxTree/Statement/BlockStatement.java b/src/main/java/abstractSyntaxTree/Statement/BlockStatement.java index 543d058..b573fbc 100644 --- a/src/main/java/abstractSyntaxTree/Statement/BlockStatement.java +++ b/src/main/java/abstractSyntaxTree/Statement/BlockStatement.java @@ -36,35 +36,38 @@ public class BlockStatement extends AbstractType implements IStatement { } for (IStatement statement : statements) { - TypeCheckResult typeOfCurrentStatement = statement.typeCheck(methodContext, typeContext, localVars); + // todo remove later if there are no null statement any more + if (statement != null) { + TypeCheckResult typeOfCurrentStatement = statement.typeCheck(methodContext, typeContext, localVars); - if (typeOfCurrentStatement.type.contains(",")) { - // else if has 2 returns, all code paths must retrun a value. - String[] substrings = typeOfCurrentStatement.type.split(","); + if (typeOfCurrentStatement.type.contains(",")) { + // else if has 2 returns, all code paths must retrun a value. + String[] substrings = typeOfCurrentStatement.type.split(","); - String firstType = substrings[0]; - String secondType = substrings[1]; + String firstType = substrings[0]; + String secondType = substrings[1]; - if(!firstType.equals(this.returnType) || !firstType.equals(this.returnType)){ - if(!firstType.equals("void")){ - throw new Exception("TypeCeck Exception: if paths return wrong type"); - } - if(!secondType.equals("void")){ - throw new Exception("TypeCeck Exception: else paths return wrong type"); - } - boolean firstIsVoid = firstType.equals("void"); + if (!firstType.equals(this.returnType) || !firstType.equals(this.returnType)) { + if (!firstType.equals("void")) { + throw new Exception("TypeCeck Exception: if paths return wrong type"); + } + if (!secondType.equals("void")) { + throw new Exception("TypeCeck Exception: else paths return wrong type"); + } + boolean firstIsVoid = firstType.equals("void"); - if(!firstIsVoid){ - typeOfCurrentStatement.type = firstType; - }else{ - typeOfCurrentStatement.type = secondType; + if (!firstIsVoid) { + typeOfCurrentStatement.type = firstType; + } else { + typeOfCurrentStatement.type = secondType; + } } } - } - if (!typeOfCurrentStatement.type.equals(this.returnType)) { - if (!typeOfCurrentStatement.type.equals("void")) - throw new Exception("TypeCheck Exception: Block returns the wrong type."); + if (!typeOfCurrentStatement.type.equals(this.returnType)) { + if (!typeOfCurrentStatement.type.equals("void")) + throw new Exception("TypeCheck Exception: Block returns the wrong type."); + } } } result.type = this.returnType; diff --git a/src/main/java/astGenerator/ASTGenerator.java b/src/main/java/astGenerator/ASTGenerator.java index b628494..8ae4d20 100644 --- a/src/main/java/astGenerator/ASTGenerator.java +++ b/src/main/java/astGenerator/ASTGenerator.java @@ -3,10 +3,7 @@ package astGenerator; import abstractSyntaxTree.Class.FieldDecl; import abstractSyntaxTree.Class.MethodDecl; import abstractSyntaxTree.Class.RefType; -import abstractSyntaxTree.Expression.BinaryExpression; -import abstractSyntaxTree.Expression.IExpression; -import abstractSyntaxTree.Expression.IntConstantExpression; -import abstractSyntaxTree.Expression.LocalVarIdentifier; +import abstractSyntaxTree.Expression.*; import abstractSyntaxTree.Node; import abstractSyntaxTree.Parameter.Parameter; import abstractSyntaxTree.Parameter.ParameterList; @@ -176,9 +173,12 @@ public class ASTGenerator extends DecafBaseVisitor { @Override public Node visitAssign(DecafParser.AssignContext ctx) { - return new AssignStatementExpression("", null, null); + Node right = visitExpression(ctx.expression()); + Node left = visitAssignableExpr(ctx.assignableExpr()); + return new AssignStatementExpression(ctx.Assign().getText(),(IExpression) left, (IExpression) right); } + @Override public Node visitMethodCall(DecafParser.MethodCallContext ctx) { return super.visitMethodCall(ctx); @@ -240,13 +240,14 @@ public class ASTGenerator extends DecafBaseVisitor { //todo @Override public Node visitDotSubExpr(DecafParser.DotSubExprContext ctx) { -// if (ctx.IntValue() != null) { -// int value = Integer.parseInt(ctx.IntValue().getText()); -// return new IntConstantExpression(value); -// } - if(ctx.Identifier() != null) { + if (ctx.IntValue() != null) { + int value = Integer.parseInt(ctx.IntValue().getText()); + return new IntConstantExpression(value); + } else if(ctx.Identifier() != null) { String identifier = ctx.Identifier().getText(); return new LocalVarIdentifier(identifier); + } else if(ctx.instVar() != null) { + return visitInstVar(ctx.instVar()); } return null; } @@ -283,4 +284,20 @@ public class ASTGenerator extends DecafBaseVisitor { } return null; } + + @Override + public Node visitInstVar(DecafParser.InstVarContext ctx) { + return super.visitInstVar(ctx); + } + +// @Override +// public Node visitArgumentList(DecafParser.ArgumentListContext ctx) { +// if (ctx.expression().size() == 1) { +// return visitExpression(ctx.expression(0)); +// } else if (ctx.expression().size() >= 2) { +// for(DecafParser.ExpressionContext expressionContext: ctx.expression()) { +// +// } +// } +// } }