Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
cd9fc46a1f
@ -63,7 +63,7 @@ AccessModifierPublic : 'public' ;
|
|||||||
MainMethodDecl : 'public static void main(String[] args)';
|
MainMethodDecl : 'public static void main(String[] args)';
|
||||||
|
|
||||||
//Print Statement print(VariableA);
|
//Print Statement print(VariableA);
|
||||||
print: 'print('Identifier');';
|
print: 'print' OpenRoundBracket Identifier ClosedRoundBracket Semicolon;
|
||||||
|
|
||||||
//Types
|
//Types
|
||||||
Void : 'void';
|
Void : 'void';
|
||||||
|
@ -54,7 +54,7 @@ public class MethodDecl implements Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Need to get the returnType of the method if it is an object
|
//Need to get the returnType of the method if it is an object
|
||||||
// methodContext (class, (returnType, (identifier, parameter)))
|
// methodContext (class, (identifier, (returnType, parameter)))
|
||||||
// typeContext (class, (type, identifier))
|
// typeContext (class, (type, identifier))
|
||||||
public void codeGen(ClassWriter cw, HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext, HashMap<String, HashMap<String, String>> typeContext, List<FieldDecl> fieldDecls) throws Exception {
|
public void codeGen(ClassWriter cw, HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext, HashMap<String, HashMap<String, String>> typeContext, List<FieldDecl> fieldDecls) throws Exception {
|
||||||
|
|
||||||
@ -75,6 +75,7 @@ public class MethodDecl implements Node {
|
|||||||
|
|
||||||
HashMap<String, String> classFields = typeContext.get(classThatContainsMethod);
|
HashMap<String, String> classFields = typeContext.get(classThatContainsMethod);
|
||||||
|
|
||||||
|
//Set the fields of the class
|
||||||
for (Map.Entry<String, String> entry : classFields.entrySet()) {
|
for (Map.Entry<String, String> entry : classFields.entrySet()) {
|
||||||
String fieldName = entry.getKey();
|
String fieldName = entry.getKey();
|
||||||
for (FieldDecl field : fieldDecls) {
|
for (FieldDecl field : fieldDecls) {
|
||||||
|
@ -3,6 +3,8 @@ package abstractSyntaxTree.Expression;
|
|||||||
import abstractSyntaxTree.Node;
|
import abstractSyntaxTree.Node;
|
||||||
import abstractSyntaxTree.StatementExpression.NewStatementExpression;
|
import abstractSyntaxTree.StatementExpression.NewStatementExpression;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
public class SubReceiver implements Node {
|
public class SubReceiver implements Node {
|
||||||
boolean thisExpression;
|
boolean thisExpression;
|
||||||
public NewStatementExpression newStatementExpression;
|
public NewStatementExpression newStatementExpression;
|
||||||
@ -19,4 +21,16 @@ public class SubReceiver implements Node {
|
|||||||
public SubReceiver(String identifier) {
|
public SubReceiver(String identifier) {
|
||||||
this.identifier = identifier;
|
this.identifier = identifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
SubReceiver subReceiver = (SubReceiver) o;
|
||||||
|
boolean result = (Objects.equals(thisExpression, subReceiver.thisExpression)
|
||||||
|
);
|
||||||
|
System.out.println("In SubReceiver: " + result);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -77,9 +77,12 @@ public class UnaryExpression extends AbstractType implements IExpression{
|
|||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
UnaryExpression unaryExpression = (UnaryExpression) o;
|
UnaryExpression unaryExpression = (UnaryExpression) o;
|
||||||
return (Objects.equals(operator, unaryExpression.operator)
|
boolean result = (Objects.equals(operator, unaryExpression.operator)
|
||||||
&& Objects.equals(operand, unaryExpression.operand)
|
&& Objects.equals(operand, unaryExpression.operand)
|
||||||
);
|
);
|
||||||
|
System.out.println("In UnaryExpression: " + result);
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -19,8 +19,11 @@ public class Parameter implements Node {
|
|||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
Parameter parameter = (Parameter) o;
|
Parameter parameter = (Parameter) o;
|
||||||
return (Objects.equals(type, parameter.type)
|
boolean result = (Objects.equals(type, parameter.type)
|
||||||
&& Objects.equals(identifier, parameter.identifier)
|
&& Objects.equals(identifier, parameter.identifier)
|
||||||
);
|
);
|
||||||
|
System.out.println("In Parameter: " + result);
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,10 @@ public class ParameterList implements Node {
|
|||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
ParameterList parameterListObj = (ParameterList) o;
|
ParameterList parameterListObj = (ParameterList) o;
|
||||||
return (Objects.equals(parameterList, parameterListObj.parameterList)
|
boolean result = (Objects.equals(parameterList, parameterListObj.parameterList)
|
||||||
);
|
);
|
||||||
|
System.out.println("In ParameterList: " + result);
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -129,10 +129,13 @@ public class BlockStatement extends AbstractType implements IStatement {
|
|||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
BlockStatement blockStatement = (BlockStatement) o;
|
BlockStatement blockStatement = (BlockStatement) o;
|
||||||
return (Objects.equals(localVars, blockStatement.localVars)
|
boolean result = (Objects.equals(localVars, blockStatement.localVars)
|
||||||
&& Objects.equals(returnType, blockStatement.returnType)
|
&& Objects.equals(returnType, blockStatement.returnType)
|
||||||
&& Objects.equals(statements, blockStatement.statements)
|
&& Objects.equals(statements, blockStatement.statements)
|
||||||
);
|
);
|
||||||
|
System.out.println("In ParameterList: " + result);
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -24,13 +24,16 @@ public class EmptyStatement extends AbstractType implements IStatement{
|
|||||||
//An empty statement does not generate any code
|
//An empty statement does not generate any code
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeCheckResult getTypeCheckResult() {
|
public TypeCheckResult getTypeCheckResult() {
|
||||||
return super.getTypeCheckResult();
|
return super.getTypeCheckResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -82,10 +82,13 @@ public class IfElseStatement extends AbstractType implements IStatement{
|
|||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
IfElseStatement ifElseStatement = (IfElseStatement) o;
|
IfElseStatement ifElseStatement = (IfElseStatement) o;
|
||||||
return (Objects.equals(condition, ifElseStatement.condition)
|
boolean result = (Objects.equals(condition, ifElseStatement.condition)
|
||||||
&& Objects.equals(ifStatement, ifElseStatement.ifStatement)
|
&& Objects.equals(ifStatement, ifElseStatement.ifStatement)
|
||||||
&& Objects.equals(elseStatement, ifElseStatement.elseStatement)
|
&& Objects.equals(elseStatement, ifElseStatement.elseStatement)
|
||||||
);
|
);
|
||||||
|
System.out.println("In PrintStatement: " + result);
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -62,9 +62,12 @@ public class IfStatement extends AbstractType implements IStatement{
|
|||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
IfStatement ifStatementObj = (IfStatement) o;
|
IfStatement ifStatementObj = (IfStatement) o;
|
||||||
return (Objects.equals(condition, ifStatementObj.condition)
|
boolean result = (Objects.equals(condition, ifStatementObj.condition)
|
||||||
&& Objects.equals(ifStatement, ifStatementObj.ifStatement)
|
&& Objects.equals(ifStatement, ifStatementObj.ifStatement)
|
||||||
);
|
);
|
||||||
|
System.out.println("In IfStatement: " + result);
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -102,9 +102,12 @@ public class LocalVarDecl extends AbstractType implements IStatement{
|
|||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
LocalVarDecl localVarDecl = (LocalVarDecl) o;
|
LocalVarDecl localVarDecl = (LocalVarDecl) o;
|
||||||
return (Objects.equals(type, localVarDecl.type)
|
boolean result = (Objects.equals(type, localVarDecl.type)
|
||||||
&& Objects.equals(identifier, localVarDecl.identifier)
|
&& Objects.equals(identifier, localVarDecl.identifier)
|
||||||
);
|
);
|
||||||
|
System.out.println("In LocalVarDecl: " + result);
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -5,6 +5,7 @@ import TypeCheck.TypeCheckException;
|
|||||||
import TypeCheck.TypeCheckResult;
|
import TypeCheck.TypeCheckResult;
|
||||||
import abstractSyntaxTree.Parameter.ParameterList;
|
import abstractSyntaxTree.Parameter.ParameterList;
|
||||||
import org.objectweb.asm.MethodVisitor;
|
import org.objectweb.asm.MethodVisitor;
|
||||||
|
import org.objectweb.asm.Opcodes;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
@ -14,6 +15,18 @@ public class PrintStatement extends AbstractType implements IStatement {
|
|||||||
String variableName;
|
String variableName;
|
||||||
public String thisClass;
|
public String thisClass;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
PrintStatement printStatement = (PrintStatement) o;
|
||||||
|
boolean result = (Objects.equals(variableName, printStatement.variableName)
|
||||||
|
);
|
||||||
|
System.out.println("In PrintStatement: " + result);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
public PrintStatement(String variableName) {
|
public PrintStatement(String variableName) {
|
||||||
this.variableName = variableName;
|
this.variableName = variableName;
|
||||||
}
|
}
|
||||||
@ -34,6 +47,28 @@ public class PrintStatement extends AbstractType implements IStatement {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void codeGen(MethodVisitor mv, LinkedHashMap<String, String> localVars, HashMap<String, HashMap<String, String>> typeContext, HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext) throws Exception {
|
public void codeGen(MethodVisitor mv, LinkedHashMap<String, String> localVars, HashMap<String, HashMap<String, String>> typeContext, HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext) throws Exception {
|
||||||
|
// Load System.out onto the stack
|
||||||
|
mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
|
||||||
|
|
||||||
|
// Load the value of the variable onto the stack
|
||||||
|
int index = -1;
|
||||||
|
int counter = 0;
|
||||||
|
for (String key : localVars.keySet()){
|
||||||
|
if (key.equals(variableName)){
|
||||||
|
index = counter+1; // +1 because the first local variable is at index 1, 0 is used for "this"
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
counter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index == -1){
|
||||||
|
throw new Exception("Variable " + variableName + " not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
mv.visitVarInsn(Opcodes.ILOAD, index);
|
||||||
|
|
||||||
|
// Call the println method
|
||||||
|
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(I)V", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -60,8 +60,11 @@ public class ReturnStatement extends AbstractType implements IStatement{
|
|||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
ReturnStatement returnStatement = (ReturnStatement) o;
|
ReturnStatement returnStatement = (ReturnStatement) o;
|
||||||
return (Objects.equals(expression, returnStatement.expression)
|
boolean result = (Objects.equals(expression, returnStatement.expression)
|
||||||
);
|
);
|
||||||
|
System.out.println("In PrintStatement: " + result);
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -67,9 +67,13 @@ public class WhileStatement extends AbstractType implements IStatement {
|
|||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
WhileStatement whileStatement = (WhileStatement) o;
|
WhileStatement whileStatement = (WhileStatement) o;
|
||||||
return (Objects.equals(condition, whileStatement.condition)
|
boolean result = (Objects.equals(condition, whileStatement.condition)
|
||||||
&& Objects.equals(statement, whileStatement.statement)
|
&& Objects.equals(statement, whileStatement.statement)
|
||||||
);
|
);
|
||||||
|
System.out.println("In PrintStatement: " + result);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -105,7 +105,7 @@ public class MethodCallStatementExpression extends AbstractType implements IExpr
|
|||||||
mv.visitFieldInsn(Opcodes.GETFIELD, thisClass, receiver.identifier, "L" + type + ";"); // Load the field onto the stack
|
mv.visitFieldInsn(Opcodes.GETFIELD, thisClass, receiver.identifier, "L" + type + ";"); // Load the field onto the stack
|
||||||
} else {
|
} else {
|
||||||
// It's a local variable
|
// It's a local variable
|
||||||
int index = localVars.keySet().stream().toList().indexOf(receiver.identifier);
|
int index = localVars.keySet().stream().toList().indexOf(receiver.identifier)+1; // +1 because the first local variable is at index 1, 0 is used for "this"
|
||||||
int opcode = type.equals("int") ? Opcodes.ILOAD : Opcodes.ALOAD;
|
int opcode = type.equals("int") ? Opcodes.ILOAD : Opcodes.ALOAD;
|
||||||
mv.visitVarInsn(opcode, index); // Load local variable onto the stack
|
mv.visitVarInsn(opcode, index); // Load local variable onto the stack
|
||||||
}
|
}
|
||||||
@ -134,12 +134,12 @@ public class MethodCallStatementExpression extends AbstractType implements IExpr
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Invoke the method
|
// Invoke the method
|
||||||
String descriptor = getMethodDescriptor();
|
String descriptor = getMethodDescriptor(localVars, methodContext);
|
||||||
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, owner, methodName, descriptor, false);
|
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, owner, methodName, descriptor, false);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
// ()I
|
||||||
private String getMethodDescriptor() {
|
private String getMethodDescriptor(LinkedHashMap<String, String> localVars, HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext) {
|
||||||
StringBuilder descriptor = new StringBuilder("(");
|
StringBuilder descriptor = new StringBuilder("(");
|
||||||
|
|
||||||
for (IExpression argument : arguments) {
|
for (IExpression argument : arguments) {
|
||||||
@ -166,7 +166,36 @@ public class MethodCallStatementExpression extends AbstractType implements IExpr
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
descriptor.append(")"); // Methods always return void
|
descriptor.append(")");
|
||||||
|
|
||||||
|
//Return Type
|
||||||
|
String classToSearchMethodIn = localVars.get(receiver.identifier);
|
||||||
|
if (classToSearchMethodIn == null)
|
||||||
|
classToSearchMethodIn = thisClass;
|
||||||
|
|
||||||
|
String returnType = methodContext.get(classToSearchMethodIn).get(methodName).keySet().toArray()[0].toString();
|
||||||
|
|
||||||
|
switch (returnType) {
|
||||||
|
case "int":
|
||||||
|
descriptor.append("I");
|
||||||
|
break;
|
||||||
|
case "boolean":
|
||||||
|
descriptor.append("Z");
|
||||||
|
break;
|
||||||
|
case "char":
|
||||||
|
descriptor.append("C");
|
||||||
|
break;
|
||||||
|
case "void":
|
||||||
|
descriptor.append("V");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// If it is a class reference replace the "." with "/" and return it
|
||||||
|
if (returnType.contains(".")) returnType = returnType.replaceAll("\\.", "/");
|
||||||
|
descriptor.append("L").append(returnType).append(";");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
System.out.println("Descriptor: " + descriptor.toString());
|
||||||
|
|
||||||
return descriptor.toString();
|
return descriptor.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user