Merge remote-tracking branch 'origin/master'

# Conflicts:
#	src/main/java/abstractSyntaxTree/StatementExpression/NewStatementExpression.java
This commit is contained in:
Jochen Seyfried 2024-05-31 12:09:47 +02:00
commit 5592a6cfe1
10 changed files with 161 additions and 43 deletions

View File

@ -27,9 +27,21 @@ public class Compiler {
public static void main(String[] args) throws Exception{
Path filePath = Paths.get("NichtHaskell/src/main/java/Input.java");
Path filePath = Paths.get("src/main/java/Input.java");
// todo remove this debug info
Path absolutePath = filePath.toAbsolutePath();
System.out.println("Full path: " + absolutePath);
String content;
try {
content = Files.readString(filePath);
}catch (java.nio.file.NoSuchFileException e){
System.out.println("File not found");
return;
}
String content = Files.readString(filePath);
System.out.println("--- print content ---");
System.out.println(content);
@ -91,16 +103,7 @@ public class Compiler {
// System.out.println(refType.name);
// }
abstractSyntaxTree.classes.get(1).methodDecls.get(0).codeBlock.returnType = "int";
List<IStatement> statementsList = abstractSyntaxTree.classes.get(1).methodDecls.get(0).codeBlock.statements;
statementsList.remove(0);
statementsList.add(new LocalVarDecl("int", "localInt"));
statementsList.add(new LocalVarDecl("bool", "localBool"));
statementsList.add(new LocalVarDecl("char", "localChar"));
statementsList.add(new AssignStatementExpression("=", new LocalVarIdentifier("localInt"), new UnaryExpression("", new IntDatatype())));
statementsList.add(new AssignStatementExpression("=", new InstVarExpression(abstractSyntaxTree.classes.get(1), "instVarBool"), new UnaryExpression("instVarBool", new BoolDatatype())));
abstractSyntaxTree.classes.get(1).methodDecls.get(0).codeBlock.statements.add(new ReturnStatement(new UnaryExpression("", new IntDatatype())));
abstractSyntaxTree.typeCheck();
abstractSyntaxTree.codeGen();

View File

@ -6,6 +6,12 @@ class Example {
}
class Example2 {
boolean instVarBool;
int m(int n){return 1;}
int m(int n){
boolean localBool;
localBool = true;
if(localBool){
return n;
}
return -1;
}
}

View File

@ -0,0 +1,27 @@
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;
public class IntConstantExpression extends AbstractType implements IExpression{
public int value;
public IntConstantExpression(int value) {
this.value = value;
}
@Override
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext, HashMap<String, HashMap<String, String>> typeContext, HashMap<String, String> localVars) throws Exception {
return null;
}
@Override
public void codeGen(MethodVisitor mv, LinkedHashMap<String, String> localVars, HashMap<String, HashMap<String, String>> typeContext) throws Exception {
}
}

View File

@ -24,7 +24,13 @@ public class LocalVarIdentifier implements IExpression{
@Override
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext, HashMap<String, HashMap<String, String>> typeContext, HashMap<String, String> 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

View File

@ -34,13 +34,40 @@ public class BlockStatement extends AbstractType implements IStatement {
}
for (IStatement statement : statements) {
// 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(",");
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 (!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.");
}
}
}
result.type = this.returnType;
// todo check if the block returns the needed return type in every case
// todo ignore unreachable statements?

View File

@ -9,6 +9,7 @@ import org.objectweb.asm.*;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Objects;
public class IfElseStatement extends AbstractType implements IStatement{
IExpression condition;
@ -26,11 +27,11 @@ public class IfElseStatement extends AbstractType implements IStatement{
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext, HashMap<String, HashMap<String, String>> typeContext, HashMap<String, String> localVars) throws Exception {
TypeCheckResult result = new TypeCheckResult();
//TypeCheckResult conditionType = condition.typeCheck();
TypeCheckResult conditionType = condition.typeCheck(methodContext, typeContext, localVars);
// if (!conditionType.equals("bool")) {
// throw new IllegalArgumentException("should be boolean");
// }
if (!conditionType.equals("bool")) {
throw new IllegalArgumentException("should be boolean");
}
TypeCheckResult ifStatementType = ifStatement.typeCheck(methodContext, typeContext, localVars);
TypeCheckResult elseStatementType = elseStatement.typeCheck(methodContext, typeContext, localVars);
@ -38,11 +39,17 @@ public class IfElseStatement extends AbstractType implements IStatement{
if (!ifStatementType.equals(elseStatementType)) {
throw new IllegalArgumentException("if and else have different types");
}
result.type = elseStatementType.type;
if(ifStatementType.type != "void" && elseStatementType.type != "void"){
if(Objects.equals(ifStatementType.type, elseStatementType.type)){
throw new Exception("TypeCeck Exception: If and else return different not-void types");
}
}
result.type = ifStatementType.type + "," + elseStatementType.type;
return result;
}
@Override
public void codeGen(MethodVisitor mv, LinkedHashMap<String, String> localVars, HashMap<String, HashMap<String, String>> typeContext) throws Exception {

View File

@ -25,11 +25,11 @@ public class IfStatement extends AbstractType implements IStatement{
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext, HashMap<String, HashMap<String, String>> typeContext, HashMap<String, String> localVars) throws Exception {
TypeCheckResult result = new TypeCheckResult();
//TypeCheckResult conditionType = condition.typeCheck();
TypeCheckResult conditionType = condition.typeCheck(methodContext, typeContext, localVars);
// if (!conditionType.equals("bool")) {
// throw new Exception("TypeCheck Exception: Condition of If-Statement should be bool.");
// }
if (!conditionType.equals("bool")) {
throw new Exception("TypeCheck Exception: Condition of If-Statement should be bool.");
}
TypeCheckResult ifStatementType = ifStatement.typeCheck(methodContext, typeContext, localVars);
result.type = ifStatementType.type;

View File

@ -23,15 +23,18 @@ public class WhileStatement extends AbstractType implements IStatement {
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext, HashMap<String, HashMap<String, String>> typeContext, HashMap<String, String> localVars) throws Exception {
TypeCheckResult result = new TypeCheckResult();
// TypeCheckResult conditionType = condition.typeCheck();
//
// if (!conditionType.equals("bool")) {
// throw new IllegalArgumentException("Expected boolean");
// }
// check condition
TypeCheckResult conditionType = condition.typeCheck(methodContext, typeContext, localVars);
if (!conditionType.equals("bool")) {
throw new IllegalArgumentException("Expected boolean");
}
// check code block
TypeCheckResult statementType = statement.typeCheck(methodContext, typeContext, localVars);
// set result
result.type = statementType.type;
setTypeCheckResult(result);
return result;
}

View File

@ -3,8 +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.*;
import abstractSyntaxTree.Node;
import abstractSyntaxTree.Parameter.Parameter;
import abstractSyntaxTree.Parameter.ParameterList;
@ -132,12 +131,12 @@ public class ASTGenerator extends DecafBaseVisitor<Node> {
@Override
public Node visitIfElseStmt(DecafParser.IfElseStmtContext ctx) {
if (ctx.elseStmt() != null) {
return visitIfStmt(ctx.ifStmt());
} else {
Node expression = visitExpression(ctx.ifStmt().expression());
Node ifStatement = visitStatement(ctx.ifStmt().statement());
Node elseStatement = visitStatement(ctx.elseStmt().statement());
return new IfElseStatement((IExpression) expression, (IStatement) ifStatement, (IStatement) elseStatement);
} else {
return visitIfStmt(ctx.ifStmt());
}
}
@ -174,9 +173,12 @@ public class ASTGenerator extends DecafBaseVisitor<Node> {
@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);
@ -190,7 +192,7 @@ public class ASTGenerator extends DecafBaseVisitor<Node> {
@Override
public Node visitExpression(DecafParser.ExpressionContext ctx) {
if (ctx.subExpression() != null) {
return visitSubExpression(ctx.subExpression());
} else if (ctx.binaryExpr() != null) {
return visitBinaryExpr(ctx.binaryExpr());
}
@ -238,7 +240,16 @@ public class ASTGenerator extends DecafBaseVisitor<Node> {
//todo
@Override
public Node visitDotSubExpr(DecafParser.DotSubExprContext ctx) {
return super.visitDotSubExpr(ctx);
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;
}
@Override
@ -256,9 +267,37 @@ public class ASTGenerator extends DecafBaseVisitor<Node> {
@Override
public Node visitSubExpression(DecafParser.SubExpressionContext ctx) {
if (ctx.subExpression() != null) {
visitSubExpression(ctx.subExpression());
if (ctx.assignableExpr() != null) {
return visitAssignableExpr(ctx.assignableExpr());
} else if (ctx.stmtExpr() != null) {
return visitStmtExpr(ctx.stmtExpr());
} else if (ctx.subExpression() != null) {
return visitSubExpression(ctx.subExpression());
}
return null;
}
@Override
public Node visitAssignableExpr(DecafParser.AssignableExprContext ctx) {
if (ctx.Identifier() != null) {
return new LocalVarIdentifier(ctx.Identifier().getText());
}
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()) {
//
// }
// }
// }
}