parameterlist, typecheck
This commit is contained in:
parent
74e3cb8016
commit
a59950e186
@ -91,6 +91,16 @@ public class Compiler {
|
|||||||
// System.out.println(refType.name);
|
// 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.typeCheck();
|
||||||
|
|
||||||
abstractSyntaxTree.codeGen();
|
abstractSyntaxTree.codeGen();
|
||||||
|
@ -6,8 +6,6 @@ class Example {
|
|||||||
}
|
}
|
||||||
class Example2 {
|
class Example2 {
|
||||||
boolean instVarBool;
|
boolean instVarBool;
|
||||||
void m(int i){
|
int m(int n){return 1;}
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Stack;
|
import java.util.Stack;
|
||||||
|
|
||||||
public class MethodDecl implements IClass, Node {
|
public class MethodDecl implements Node {
|
||||||
|
|
||||||
//Class Name
|
//Class Name
|
||||||
public String classThatContainsMethod;
|
public String classThatContainsMethod;
|
||||||
|
@ -3,6 +3,7 @@ package abstractSyntaxTree.Class;
|
|||||||
import TypeCheck.AbstractType;
|
import TypeCheck.AbstractType;
|
||||||
import TypeCheck.TypeCheckResult;
|
import TypeCheck.TypeCheckResult;
|
||||||
import abstractSyntaxTree.Node;
|
import abstractSyntaxTree.Node;
|
||||||
|
import abstractSyntaxTree.Parameter.ParameterList;
|
||||||
import org.objectweb.asm.ClassWriter;
|
import org.objectweb.asm.ClassWriter;
|
||||||
import org.objectweb.asm.Opcodes;
|
import org.objectweb.asm.Opcodes;
|
||||||
|
|
||||||
@ -29,7 +30,7 @@ public class RefType extends AbstractType implements Node {
|
|||||||
this.hasMain = hasMain;
|
this.hasMain = hasMain;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, List<String>>>> methodContext,
|
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext,
|
||||||
HashMap<String, HashMap<String, String>> typeContext) throws Exception {
|
HashMap<String, HashMap<String, String>> typeContext) throws Exception {
|
||||||
TypeCheckResult result = new TypeCheckResult();
|
TypeCheckResult result = new TypeCheckResult();
|
||||||
|
|
||||||
@ -83,7 +84,7 @@ public class RefType extends AbstractType implements Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (MethodDecl method : methodDecls) {
|
for (MethodDecl method : methodDecls) {
|
||||||
method.codeGen(cw);
|
// method.codeGen(cw);
|
||||||
}
|
}
|
||||||
cw.visitEnd();
|
cw.visitEnd();
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ public class BinaryExpression extends AbstractType implements IExpression{
|
|||||||
case "<=":
|
case "<=":
|
||||||
case ">=":
|
case ">=":
|
||||||
case "!=":
|
case "!=":
|
||||||
result.type = helper.upperBound(leftType.type, rightType.type);
|
result.type = helper.upperBound(leftType.type, rightType.type);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "-":
|
case "-":
|
||||||
@ -86,11 +86,11 @@ public class BinaryExpression extends AbstractType implements IExpression{
|
|||||||
mv.visitJumpInsn(Opcodes.IFNE, operationTrue);
|
mv.visitJumpInsn(Opcodes.IFNE, operationTrue);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "==":
|
case "==":
|
||||||
// Keep in mind that only primitive types are allowed in this case (at this time)
|
// Keep in mind that only primitive types are allowed in this case (at this time)
|
||||||
|
|
||||||
left.codeGen(mv);
|
left.codeGen(mv);
|
||||||
right.codeGen(mv);
|
right.codeGen(mv);
|
||||||
|
|
||||||
mv.visitJumpInsn(Opcodes.IF_ICMPEQ, operationTrue); // If the two values are equal, jump to the end of the expression
|
mv.visitJumpInsn(Opcodes.IF_ICMPEQ, operationTrue); // If the two values are equal, jump to the end of the expression
|
||||||
break;
|
break;
|
||||||
@ -167,4 +167,4 @@ public class BinaryExpression extends AbstractType implements IExpression{
|
|||||||
|
|
||||||
mv.visitLabel(expressionEnd);
|
mv.visitLabel(expressionEnd);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,11 +1,15 @@
|
|||||||
package abstractSyntaxTree.Expression;
|
package abstractSyntaxTree.Expression;
|
||||||
|
|
||||||
import TypeCheck.TypeCheckResult;
|
import TypeCheck.TypeCheckResult;
|
||||||
|
import abstractSyntaxTree.Parameter.ParameterList;
|
||||||
import org.objectweb.asm.MethodVisitor;
|
import org.objectweb.asm.MethodVisitor;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
public interface IExpression {
|
public interface IExpression {
|
||||||
// typeCheck method
|
// typeCheck method
|
||||||
TypeCheckResult typeCheck() throws Exception;
|
//TypeCheckResult typeCheck() throws Exception;
|
||||||
|
TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext, HashMap<String, HashMap<String, String>> typeContext, HashMap<String, String> localVars) throws Exception;
|
||||||
|
|
||||||
// visit method for code generation
|
// visit method for code generation
|
||||||
void codeGen(MethodVisitor mv) throws Exception;
|
void codeGen(MethodVisitor mv) throws Exception;
|
||||||
|
@ -2,9 +2,12 @@ package abstractSyntaxTree.Expression;
|
|||||||
|
|
||||||
import TypeCheck.TypeCheckResult;
|
import TypeCheck.TypeCheckResult;
|
||||||
import abstractSyntaxTree.Class.RefType;
|
import abstractSyntaxTree.Class.RefType;
|
||||||
|
import abstractSyntaxTree.Parameter.ParameterList;
|
||||||
import jdk.jshell.spi.ExecutionControl;
|
import jdk.jshell.spi.ExecutionControl;
|
||||||
import org.objectweb.asm.MethodVisitor;
|
import org.objectweb.asm.MethodVisitor;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
public class InstVarExpression implements IExpression{
|
public class InstVarExpression implements IExpression{
|
||||||
|
|
||||||
//TODO: We have to decide upon more parameters and where they come from, for
|
//TODO: We have to decide upon more parameters and where they come from, for
|
||||||
@ -12,13 +15,15 @@ public class InstVarExpression implements IExpression{
|
|||||||
private RefType classRef;
|
private RefType classRef;
|
||||||
private String fieldName;
|
private String fieldName;
|
||||||
|
|
||||||
/* public InstVarExpression(RefType classRef, String fieldName){
|
public InstVarExpression(RefType classRef, String fieldName){
|
||||||
this.classRef = classRef;
|
this.classRef = classRef;
|
||||||
this.fieldName = fieldName;
|
this.fieldName = fieldName;
|
||||||
}*/
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeCheckResult typeCheck() throws Exception {
|
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
|
@Override
|
||||||
|
@ -20,7 +20,7 @@ import java.util.jar.JarOutputStream;
|
|||||||
public class Program implements Node {
|
public class Program implements Node {
|
||||||
public List<RefType> classes;
|
public List<RefType> classes;
|
||||||
public HashMap<String, HashMap<String, String>> typeContext; // (class, (type, identifier))
|
public HashMap<String, HashMap<String, String>> typeContext; // (class, (type, identifier))
|
||||||
public HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext; // (class, (returntype, (identifier, parameterList)))
|
public HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext; // (class, (returntype, (identifier, parameter)))
|
||||||
|
|
||||||
public Program(List<RefType> classes){
|
public Program(List<RefType> classes){
|
||||||
this.classes = classes;
|
this.classes = classes;
|
||||||
@ -41,11 +41,11 @@ public class Program implements Node {
|
|||||||
typeContext.put(oneClass.name, classVars);
|
typeContext.put(oneClass.name, classVars);
|
||||||
|
|
||||||
// build method context
|
// build method context
|
||||||
HashMap<String, List<String>> methodIdentifierAndParameter = new HashMap<>();
|
HashMap<String, ParameterList> methodIdentifierAndParameter = new HashMap<>();
|
||||||
HashMap<String, HashMap<String, List<String >>> returnTypeAndMethod = new HashMap<>();
|
HashMap<String, HashMap<String, ParameterList>> returnTypeAndMethod = new HashMap<>();
|
||||||
for (MethodDecl methodDecl : oneClass.methodDecls){
|
for (MethodDecl methodDecl : oneClass.methodDecls){
|
||||||
|
|
||||||
methodIdentifierAndParameter.put(methodDecl.name, (List<String>) methodDecl.parameters);
|
methodIdentifierAndParameter.put(methodDecl.name, methodDecl.parameters);
|
||||||
returnTypeAndMethod.put(methodDecl.returnType, methodIdentifierAndParameter);
|
returnTypeAndMethod.put(methodDecl.returnType, methodIdentifierAndParameter);
|
||||||
}
|
}
|
||||||
methodContext.put(oneClass.name, returnTypeAndMethod);
|
methodContext.put(oneClass.name, returnTypeAndMethod);
|
||||||
@ -66,7 +66,7 @@ public class Program implements Node {
|
|||||||
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
|
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
|
||||||
cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, oneClass.name, null, "java/lang/Object", null);
|
cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, oneClass.name, null, "java/lang/Object", null);
|
||||||
|
|
||||||
oneClass.codeGen(cw, methodContext);
|
// oneClass.codeGen(cw);
|
||||||
|
|
||||||
cw.visitEnd();
|
cw.visitEnd();
|
||||||
byte[] bytecode = cw.toByteArray();
|
byte[] bytecode = cw.toByteArray();
|
||||||
@ -102,4 +102,4 @@ public class Program implements Node {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -51,11 +51,11 @@ public class IfElseStatement extends AbstractType implements IStatement{
|
|||||||
condition.codeGen(mv);
|
condition.codeGen(mv);
|
||||||
|
|
||||||
mv.visitJumpInsn(Opcodes.IFEQ, conditionFalse); //Checks if the condition is false (0)
|
mv.visitJumpInsn(Opcodes.IFEQ, conditionFalse); //Checks if the condition is false (0)
|
||||||
ifStatement.codeGen(mv); //If the condition is true, execute the ifBlock
|
//ifStatement.codeGen(mv); //If the condition is true, execute the ifBlock
|
||||||
mv.visitJumpInsn(Opcodes.GOTO, statementEnd); //Jump to the end of the if-else statement
|
mv.visitJumpInsn(Opcodes.GOTO, statementEnd); //Jump to the end of the if-else statement
|
||||||
|
|
||||||
mv.visitLabel(conditionFalse);
|
mv.visitLabel(conditionFalse);
|
||||||
elseStatement.codeGen(mv); //If the condition is false, execute the elseBlock
|
//elseStatement.codeGen(mv); //If the condition is false, execute the elseBlock
|
||||||
|
|
||||||
mv.visitLabel(statementEnd); //End of the if-else statement
|
mv.visitLabel(statementEnd); //End of the if-else statement
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ public class IfStatement extends AbstractType implements IStatement{
|
|||||||
condition.codeGen(mv);
|
condition.codeGen(mv);
|
||||||
|
|
||||||
mv.visitJumpInsn(Opcodes.IFEQ, conditionFalse); //Checks if the condition is false (0)
|
mv.visitJumpInsn(Opcodes.IFEQ, conditionFalse); //Checks if the condition is false (0)
|
||||||
ifStatement.codeGen(mv);
|
//ifStatement.codeGen(mv);
|
||||||
|
|
||||||
mv.visitLabel(conditionFalse); // If the condition is false, the Statements in the ifBlock will not be executed
|
mv.visitLabel(conditionFalse); // If the condition is false, the Statements in the ifBlock will not be executed
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ public class WhileStatement extends AbstractType implements IStatement {
|
|||||||
condition.codeGen(mv);
|
condition.codeGen(mv);
|
||||||
mv.visitJumpInsn(Opcodes.IFEQ, conditionFalse); // Checks if the condition is false (0)
|
mv.visitJumpInsn(Opcodes.IFEQ, conditionFalse); // Checks if the condition is false (0)
|
||||||
|
|
||||||
statement.codeGen(mv);
|
//statement.codeGen(mv);
|
||||||
//TODO: If the block ends with a return statement, we might have to pop it from the stack
|
//TODO: If the block ends with a return statement, we might have to pop it from the stack
|
||||||
// So the next iteration starts with a clean stack
|
// So the next iteration starts with a clean stack
|
||||||
mv.visitJumpInsn(Opcodes.GOTO, LoopStart); // Jump to the start of the while loop
|
mv.visitJumpInsn(Opcodes.GOTO, LoopStart); // Jump to the start of the while loop
|
||||||
|
@ -29,15 +29,15 @@ public class AssignStatementExpression extends AbstractType implements IExpressi
|
|||||||
TypeCheckHelper helper = new TypeCheckHelper();
|
TypeCheckHelper helper = new TypeCheckHelper();
|
||||||
TypeCheckResult result = new TypeCheckResult();
|
TypeCheckResult result = new TypeCheckResult();
|
||||||
|
|
||||||
TypeCheckResult leftType = left.typeCheck();
|
TypeCheckResult leftType;
|
||||||
if(leftType == null){ //left expression is the identifier of a var
|
|
||||||
|
if (left instanceof LocalVarIdentifier) {
|
||||||
leftType = new TypeCheckResult();
|
leftType = new TypeCheckResult();
|
||||||
if (left instanceof LocalVarIdentifier) {
|
LocalVarIdentifier localVarIdentifier = (LocalVarIdentifier) left;
|
||||||
LocalVarIdentifier localVarIdentifier = (LocalVarIdentifier) left;
|
String identifier = localVarIdentifier.getIdentifier();
|
||||||
String identifier = localVarIdentifier.getIdentifier();
|
leftType.type = localVars.get(identifier);
|
||||||
leftType.type = localVars.get(identifier);
|
}else{
|
||||||
}
|
leftType = left.typeCheck();
|
||||||
// not local var
|
|
||||||
}
|
}
|
||||||
TypeCheckResult rightType = right.typeCheck();
|
TypeCheckResult rightType = right.typeCheck();
|
||||||
|
|
||||||
@ -64,14 +64,14 @@ public class AssignStatementExpression extends AbstractType implements IExpressi
|
|||||||
left.codeGen(mv);
|
left.codeGen(mv);
|
||||||
right.codeGen(mv);
|
right.codeGen(mv);
|
||||||
|
|
||||||
if (left instanceof VarRefExpression varRef) {
|
// if (left instanceof VarRefExpression varRef) {
|
||||||
//TODO: Implement the handling of a variable reference --> I need a list of local variables
|
// //TODO: Implement the handling of a variable reference --> I need a list of local variables
|
||||||
// for that to determine if the variable is a local or field variable
|
// // for that to determine if the variable is a local or field variable
|
||||||
} else if (left instanceof InstVarExpression instVar) {
|
// } else if (left instanceof InstVarExpression instVar) {
|
||||||
mv.visitInsn(Opcodes.DUP_X1);
|
// mv.visitInsn(Opcodes.DUP_X1);
|
||||||
|
//
|
||||||
// We now again need the owner (class reference), name (of the Field in the owner) and type of the field
|
// // We now again need the owner (class reference), name (of the Field in the owner) and type of the field
|
||||||
//mv.visitFieldInsn(Opcodes.PUTFIELD, instVar.className, instVar.varName, instVar.type);
|
// //mv.visitFieldInsn(Opcodes.PUTFIELD, instVar.className, instVar.varName, instVar.type);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -61,7 +61,7 @@ public class MethodCallStatementExpression extends AbstractType implements IExpr
|
|||||||
public void codeGen(MethodVisitor mv) throws Exception {
|
public void codeGen(MethodVisitor mv) throws Exception {
|
||||||
//Generate Bytecode for the receiver
|
//Generate Bytecode for the receiver
|
||||||
if(classThatHasTheMethodIfNotThis != null){
|
if(classThatHasTheMethodIfNotThis != null){
|
||||||
classThatHasTheMethodIfNotThis.codeGen(new ClassWriter(ClassWriter.COMPUTE_FRAMES));
|
// classThatHasTheMethodIfNotThis.codeGen(new ClassWriter(ClassWriter.COMPUTE_FRAMES));
|
||||||
} else {
|
} else {
|
||||||
mv.visitVarInsn(Opcodes.ALOAD, 0);
|
mv.visitVarInsn(Opcodes.ALOAD, 0);
|
||||||
}
|
}
|
||||||
|
@ -170,7 +170,7 @@ public class ASTGenerator extends DecafBaseVisitor<Node> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Node visitAssign(DecafParser.AssignContext ctx) {
|
public Node visitAssign(DecafParser.AssignContext ctx) {
|
||||||
return new AssignStatementExpression();
|
return new AssignStatementExpression("", null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Loading…
Reference in New Issue
Block a user