Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
77bf6cff62
@ -2,11 +2,21 @@ package abstractSyntaxTree.Datatype;
|
|||||||
|
|
||||||
import TypeCheck.AbstractType;
|
import TypeCheck.AbstractType;
|
||||||
import TypeCheck.TypeCheckResult;
|
import TypeCheck.TypeCheckResult;
|
||||||
|
import abstractSyntaxTree.Class.RefType;
|
||||||
import org.objectweb.asm.*;
|
import org.objectweb.asm.*;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
public class BoolDatatype extends AbstractType implements IDatatype{
|
public class BoolDatatype extends AbstractType implements IDatatype{
|
||||||
boolean value;
|
boolean value;
|
||||||
@Override
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
BoolDatatype boolDatatype = (BoolDatatype) o;
|
||||||
|
return (Objects.equals(value, boolDatatype.value));
|
||||||
|
}
|
||||||
|
@Override
|
||||||
public TypeCheckResult typeCheck() throws Exception {
|
public TypeCheckResult typeCheck() throws Exception {
|
||||||
TypeCheckResult result = new TypeCheckResult();
|
TypeCheckResult result = new TypeCheckResult();
|
||||||
|
|
||||||
@ -24,4 +34,6 @@ public class BoolDatatype extends AbstractType implements IDatatype{
|
|||||||
mv.visitInsn(Opcodes.ICONST_0); // 0 for false
|
mv.visitInsn(Opcodes.ICONST_0); // 0 for false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,11 @@ import TypeCheck.AbstractType;
|
|||||||
import TypeCheck.TypeCheckResult;
|
import TypeCheck.TypeCheckResult;
|
||||||
import org.objectweb.asm.MethodVisitor;
|
import org.objectweb.asm.MethodVisitor;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
public class CharDatatype extends AbstractType implements IDatatype{
|
public class CharDatatype extends AbstractType implements IDatatype{
|
||||||
char value;
|
char value;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeCheckResult typeCheck() throws Exception {
|
public TypeCheckResult typeCheck() throws Exception {
|
||||||
TypeCheckResult result = new TypeCheckResult();
|
TypeCheckResult result = new TypeCheckResult();
|
||||||
@ -24,4 +27,11 @@ public class CharDatatype extends AbstractType implements IDatatype{
|
|||||||
|
|
||||||
mv.visitLdcInsn((int)value);
|
mv.visitLdcInsn((int)value);
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
CharDatatype charDatatype = (CharDatatype) o;
|
||||||
|
return (Objects.equals(value, charDatatype.value));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,8 @@ import TypeCheck.TypeCheckResult;
|
|||||||
import org.objectweb.asm.MethodVisitor;
|
import org.objectweb.asm.MethodVisitor;
|
||||||
import org.objectweb.asm.Opcodes;
|
import org.objectweb.asm.Opcodes;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
public class IntDatatype extends AbstractType implements IDatatype{
|
public class IntDatatype extends AbstractType implements IDatatype{
|
||||||
int value;
|
int value;
|
||||||
@Override
|
@Override
|
||||||
@ -31,4 +33,12 @@ public class IntDatatype extends AbstractType implements IDatatype{
|
|||||||
else
|
else
|
||||||
mv.visitLdcInsn(value);
|
mv.visitLdcInsn(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
IntDatatype intDatatype = (IntDatatype) o;
|
||||||
|
return (Objects.equals(value, intDatatype.value));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package abstractSyntaxTree.Expression;
|
|||||||
import TypeCheck.TypeCheckResult;
|
import TypeCheck.TypeCheckResult;
|
||||||
import TypeCheck.TypeCheckHelper;
|
import TypeCheck.TypeCheckHelper;
|
||||||
import TypeCheck.AbstractType;
|
import TypeCheck.AbstractType;
|
||||||
|
import abstractSyntaxTree.Datatype.IntDatatype;
|
||||||
import abstractSyntaxTree.Parameter.ParameterList;
|
import abstractSyntaxTree.Parameter.ParameterList;
|
||||||
import org.objectweb.asm.*;
|
import org.objectweb.asm.*;
|
||||||
|
|
||||||
@ -175,4 +176,15 @@ public class BinaryExpression extends AbstractType implements IExpression{
|
|||||||
|
|
||||||
mv.visitLabel(expressionEnd);
|
mv.visitLabel(expressionEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
BinaryExpression binaryExpression = (BinaryExpression) o;
|
||||||
|
return (Objects.equals(operator, binaryExpression.operator)
|
||||||
|
&& Objects.equals(left, binaryExpression.left)
|
||||||
|
&& Objects.equals(right, binaryExpression.right)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
@ -9,6 +9,7 @@ import org.objectweb.asm.Opcodes;
|
|||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
public class InstVarExpression implements IExpression{
|
public class InstVarExpression implements IExpression{
|
||||||
|
|
||||||
@ -63,4 +64,14 @@ public class InstVarExpression implements IExpression{
|
|||||||
// Load the variable onto the stack
|
// Load the variable onto the stack
|
||||||
mv.visitFieldInsn(Opcodes.GETFIELD, classRef.name, fieldName, fieldDescriptor);
|
mv.visitFieldInsn(Opcodes.GETFIELD, classRef.name, fieldName, fieldDescriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
InstVarExpression instVarExpression = (InstVarExpression) o;
|
||||||
|
return (Objects.equals(classRef, instVarExpression.classRef)
|
||||||
|
&& Objects.equals(fieldName, instVarExpression.fieldName)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,8 @@ import org.objectweb.asm.MethodVisitor;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
public class IntConstantExpression extends AbstractType implements IExpression{
|
public class IntConstantExpression extends AbstractType implements IExpression{
|
||||||
public int value;
|
public int value;
|
||||||
|
|
||||||
@ -24,4 +26,13 @@ public class IntConstantExpression extends AbstractType implements IExpression{
|
|||||||
public void codeGen(MethodVisitor mv, LinkedHashMap<String, String> localVars, HashMap<String, HashMap<String, String>> typeContext) throws Exception {
|
public void codeGen(MethodVisitor mv, LinkedHashMap<String, String> localVars, HashMap<String, HashMap<String, String>> typeContext) throws Exception {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
IntConstantExpression intConstantExpression = (IntConstantExpression) o;
|
||||||
|
return (Objects.equals(value, intConstantExpression.value)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ import abstractSyntaxTree.Parameter.ParameterList;
|
|||||||
import org.objectweb.asm.MethodVisitor;
|
import org.objectweb.asm.MethodVisitor;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
public class LocalVarIdentifier implements IExpression{
|
public class LocalVarIdentifier implements IExpression{
|
||||||
|
|
||||||
@ -71,4 +72,13 @@ public class LocalVarIdentifier implements IExpression{
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
LocalVarIdentifier localVarIdentifier = (LocalVarIdentifier) o;
|
||||||
|
return (Objects.equals(identifier, localVarIdentifier.identifier)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -70,4 +70,14 @@ public class UnaryExpression extends AbstractType implements IExpression{
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
UnaryExpression unaryExpression = (UnaryExpression) o;
|
||||||
|
return (Objects.equals(operator, unaryExpression.operator)
|
||||||
|
&& Objects.equals(operand, unaryExpression.operand)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
package abstractSyntaxTree.Parameter;
|
package abstractSyntaxTree.Parameter;
|
||||||
|
|
||||||
|
import abstractSyntaxTree.Expression.UnaryExpression;
|
||||||
import abstractSyntaxTree.Node;
|
import abstractSyntaxTree.Node;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
public class Parameter implements Node {
|
public class Parameter implements Node {
|
||||||
public String type;
|
public String type;
|
||||||
public String identifier;
|
public String identifier;
|
||||||
@ -10,4 +13,14 @@ public class Parameter implements Node {
|
|||||||
this.type = type;
|
this.type = type;
|
||||||
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;
|
||||||
|
Parameter parameter = (Parameter) o;
|
||||||
|
return (Objects.equals(type, parameter.type)
|
||||||
|
&& Objects.equals(identifier, parameter.identifier)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package abstractSyntaxTree.Parameter;
|
|||||||
import abstractSyntaxTree.Node;
|
import abstractSyntaxTree.Node;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
public class ParameterList implements Node {
|
public class ParameterList implements Node {
|
||||||
public List<Parameter> parameterList;
|
public List<Parameter> parameterList;
|
||||||
@ -10,4 +11,13 @@ public class ParameterList implements Node {
|
|||||||
public ParameterList(List<Parameter> parameterList) {
|
public ParameterList(List<Parameter> parameterList) {
|
||||||
this.parameterList = parameterList;
|
this.parameterList = parameterList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
ParameterList parameterListObj = (ParameterList) o;
|
||||||
|
return (Objects.equals(parameterList, parameterListObj.parameterList)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,12 +3,14 @@ package abstractSyntaxTree.Statement;
|
|||||||
import TypeCheck.TypeCheckResult;
|
import TypeCheck.TypeCheckResult;
|
||||||
import TypeCheck.AbstractType;
|
import TypeCheck.AbstractType;
|
||||||
import abstractSyntaxTree.Class.FieldDecl;
|
import abstractSyntaxTree.Class.FieldDecl;
|
||||||
|
import abstractSyntaxTree.Parameter.Parameter;
|
||||||
import abstractSyntaxTree.Parameter.ParameterList;
|
import abstractSyntaxTree.Parameter.ParameterList;
|
||||||
import org.objectweb.asm.*;
|
import org.objectweb.asm.*;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
public class BlockStatement extends AbstractType implements IStatement {
|
public class BlockStatement extends AbstractType implements IStatement {
|
||||||
|
|
||||||
@ -86,4 +88,15 @@ public class BlockStatement extends AbstractType implements IStatement {
|
|||||||
statement.codeGen(mv, blockLocalVars, typeContext);
|
statement.codeGen(mv, blockLocalVars, typeContext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
BlockStatement blockStatement = (BlockStatement) o;
|
||||||
|
return (Objects.equals(localVars, blockStatement.localVars)
|
||||||
|
&& Objects.equals(returnType, blockStatement.returnType)
|
||||||
|
&& Objects.equals(statements, blockStatement.statements)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
@ -8,6 +8,7 @@ import org.objectweb.asm.MethodVisitor;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
public class EmptyStatement extends AbstractType implements IStatement{
|
public class EmptyStatement extends AbstractType implements IStatement{
|
||||||
|
|
||||||
@ -22,4 +23,9 @@ public class EmptyStatement extends AbstractType implements IStatement{
|
|||||||
public void codeGen(MethodVisitor mv, LinkedHashMap<String, String> localVars, HashMap<String, HashMap<String, String>> typeContext) throws Exception {
|
public void codeGen(MethodVisitor mv, LinkedHashMap<String, String> localVars, HashMap<String, HashMap<String, String>> typeContext) throws Exception {
|
||||||
//An empty statement does not generate any code
|
//An empty statement does not generate any code
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -70,4 +70,15 @@ public class IfElseStatement extends AbstractType implements IStatement{
|
|||||||
mv.visitLabel(statementEnd); //End of the if-else statement
|
mv.visitLabel(statementEnd); //End of the if-else statement
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
IfElseStatement ifElseStatement = (IfElseStatement) o;
|
||||||
|
return (Objects.equals(condition, ifElseStatement.condition)
|
||||||
|
&& Objects.equals(ifStatement, ifElseStatement.ifStatement)
|
||||||
|
&& Objects.equals(elseStatement, ifElseStatement.elseStatement)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ import org.objectweb.asm.*;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
public class IfStatement extends AbstractType implements IStatement{
|
public class IfStatement extends AbstractType implements IStatement{
|
||||||
IExpression condition;
|
IExpression condition;
|
||||||
@ -50,6 +51,16 @@ public class IfStatement extends AbstractType implements IStatement{
|
|||||||
|
|
||||||
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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
IfStatement ifStatementObj = (IfStatement) o;
|
||||||
|
return (Objects.equals(condition, ifStatementObj.condition)
|
||||||
|
&& Objects.equals(ifStatement, ifStatementObj.ifStatement)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -49,4 +49,14 @@ public class LocalVarDecl implements IStatement{
|
|||||||
mv.visitVarInsn(Opcodes.ASTORE, index);
|
mv.visitVarInsn(Opcodes.ASTORE, index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
LocalVarDecl localVarDecl = (LocalVarDecl) o;
|
||||||
|
return (Objects.equals(type, localVarDecl.type)
|
||||||
|
&& Objects.equals(identifier, localVarDecl.identifier)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ import org.objectweb.asm.*;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
public class ReturnStatement extends AbstractType implements IStatement{
|
public class ReturnStatement extends AbstractType implements IStatement{
|
||||||
IExpression expression;
|
IExpression expression;
|
||||||
@ -53,4 +54,13 @@ public class ReturnStatement extends AbstractType implements IStatement{
|
|||||||
mv.visitInsn(Opcodes.RETURN);
|
mv.visitInsn(Opcodes.RETURN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
ReturnStatement returnStatement = (ReturnStatement) o;
|
||||||
|
return (Objects.equals(expression, returnStatement.expression)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ import org.objectweb.asm.*;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
public class WhileStatement extends AbstractType implements IStatement {
|
public class WhileStatement extends AbstractType implements IStatement {
|
||||||
IExpression condition;
|
IExpression condition;
|
||||||
@ -59,4 +60,14 @@ public class WhileStatement extends AbstractType implements IStatement {
|
|||||||
|
|
||||||
mv.visitLabel(conditionFalse);
|
mv.visitLabel(conditionFalse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
WhileStatement whileStatement = (WhileStatement) o;
|
||||||
|
return (Objects.equals(condition, whileStatement.condition)
|
||||||
|
&& Objects.equals(statement, whileStatement.statement)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
@ -8,6 +8,7 @@ import abstractSyntaxTree.Expression.InstVarExpression;
|
|||||||
import abstractSyntaxTree.Expression.LocalVarIdentifier;
|
import abstractSyntaxTree.Expression.LocalVarIdentifier;
|
||||||
import abstractSyntaxTree.Parameter.ParameterList;
|
import abstractSyntaxTree.Parameter.ParameterList;
|
||||||
import abstractSyntaxTree.Statement.IStatement;
|
import abstractSyntaxTree.Statement.IStatement;
|
||||||
|
import abstractSyntaxTree.Statement.WhileStatement;
|
||||||
import org.objectweb.asm.*;
|
import org.objectweb.asm.*;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -112,4 +113,15 @@ public class AssignStatementExpression extends AbstractType implements IExpressi
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
AssignStatementExpression assignStatementExpression = (AssignStatementExpression) o;
|
||||||
|
return (Objects.equals(operator, assignStatementExpression.operator)
|
||||||
|
&& Objects.equals(left, assignStatementExpression.left)
|
||||||
|
&& Objects.equals(right, assignStatementExpression.right)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
@ -14,6 +14,7 @@ import org.objectweb.asm.Opcodes;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
public class MethodCallStatementExpression extends AbstractType implements IExpression, IStatement {
|
public class MethodCallStatementExpression extends AbstractType implements IExpression, IStatement {
|
||||||
String methodName;
|
String methodName;
|
||||||
@ -56,8 +57,9 @@ public class MethodCallStatementExpression extends AbstractType implements IExpr
|
|||||||
@Override
|
@Override
|
||||||
public void codeGen(MethodVisitor mv, LinkedHashMap<String, String> localVars, HashMap<String, HashMap<String, String>> typeContext) throws Exception {
|
public void codeGen(MethodVisitor mv, LinkedHashMap<String, String> localVars, HashMap<String, HashMap<String, String>> typeContext) throws Exception {
|
||||||
//Generate Bytecode for the receiver
|
//Generate Bytecode for the receiver
|
||||||
if(classThatHasTheMethodIfNotThis != null){
|
if (classThatHasTheMethodIfNotThis != null) {
|
||||||
//TODO: classThatHasTheMethodIfNotThis must be an object --> instance of the class not the class itself
|
//TODO: classThatHasTheMethodIfNotThis must be an object --> instance of the class not the class itself
|
||||||
|
// Need to call codeGen so it pushes the instance onto the stack, which will be popped of
|
||||||
//classThatHasTheMethodIfNotThis.codeGen();
|
//classThatHasTheMethodIfNotThis.codeGen();
|
||||||
|
|
||||||
String descriptor;
|
String descriptor;
|
||||||
@ -65,29 +67,39 @@ public class MethodCallStatementExpression extends AbstractType implements IExpr
|
|||||||
for (MethodDecl methodDecl : methodDecls) {
|
for (MethodDecl methodDecl : methodDecls) {
|
||||||
if (methodDecl.name.equals(methodName)) {
|
if (methodDecl.name.equals(methodName)) {
|
||||||
//Get the method descriptor
|
//Get the method descriptor
|
||||||
//descriptor = methodDecl.getMethodDescriptor(methodContext);
|
descriptor = methodDecl.getMethodDescriptor(methodContext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, classThatHasTheMethodIfNotThis.name, methodName, descriptor, false);
|
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, classThatHasTheMethodIfNotThis.name, methodName, descriptor, false);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Load this onto the stack
|
// Load this onto the stack
|
||||||
mv.visitVarInsn(Opcodes.ALOAD, 0);
|
mv.visitVarInsn(Opcodes.ALOAD, 0);
|
||||||
}
|
|
||||||
|
|
||||||
for (IExpression argument : arguments) {
|
for (IExpression argument : arguments) {
|
||||||
argument.codeGen(mv, localVars, typeContext);
|
argument.codeGen(mv, localVars, typeContext);
|
||||||
}
|
|
||||||
|
|
||||||
// Get the method descriptor
|
|
||||||
String descriptor;
|
|
||||||
List<MethodDecl> methodDecls = thisClass.methodDecls;
|
|
||||||
for (MethodDecl methodDecl : methodDecls) {
|
|
||||||
if (methodDecl.name.equals(methodName)) {
|
|
||||||
//Get the method descriptor
|
|
||||||
//descriptor = methodDecl.getMethodDescriptor(methodContext);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the method descriptor
|
||||||
|
String descriptor;
|
||||||
|
List<MethodDecl> methodDecls = thisClass.methodDecls;
|
||||||
|
for (MethodDecl methodDecl : methodDecls) {
|
||||||
|
if (methodDecl.name.equals(methodName)) {
|
||||||
|
//Get the method descriptor
|
||||||
|
descriptor = methodDecl.getMethodDescriptor(methodContext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, thisClass.name, methodName, descriptor, false);
|
||||||
}
|
}
|
||||||
//mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, thisClass.name, methodName, descriptor, false);
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
MethodCallStatementExpression methodCallStatementExpression = (MethodCallStatementExpression) o;
|
||||||
|
return (Objects.equals(methodName, methodCallStatementExpression.methodName)
|
||||||
|
&& Objects.equals(arguments, methodCallStatementExpression.arguments)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import abstractSyntaxTree.Expression.IExpression;
|
|||||||
import abstractSyntaxTree.Parameter.ParameterList;
|
import abstractSyntaxTree.Parameter.ParameterList;
|
||||||
import abstractSyntaxTree.Statement.IStatement;
|
import abstractSyntaxTree.Statement.IStatement;
|
||||||
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;
|
||||||
@ -13,6 +14,11 @@ import java.util.List;
|
|||||||
|
|
||||||
public class NewStatementExpression extends AbstractType implements IExpression, IStatement {
|
public class NewStatementExpression extends AbstractType implements IExpression, IStatement {
|
||||||
|
|
||||||
|
private String className;
|
||||||
|
|
||||||
|
public NewStatementExpression(String className) {
|
||||||
|
this.className = className;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext, HashMap<String, HashMap<String, String>> typeContext, HashMap<String, String> localVars) 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 {
|
||||||
@ -21,8 +27,12 @@ public class NewStatementExpression extends AbstractType implements IExpression,
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void codeGen(MethodVisitor mv, LinkedHashMap<String, String> localVars, HashMap<String, HashMap<String, String>> typeContext) throws Exception {
|
public void codeGen(MethodVisitor mv, LinkedHashMap<String, String> localVars, HashMap<String, HashMap<String, String>> typeContext) throws Exception {
|
||||||
|
//Create new instance of the class
|
||||||
|
mv.visitTypeInsn(Opcodes.NEW, className);
|
||||||
|
|
||||||
|
//Duplicate the reference, so I can use it after the INVOKE consumes one
|
||||||
|
mv.visitInsn(Opcodes.DUP);
|
||||||
|
//Call the constructor
|
||||||
|
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, className, "<init>", "()V", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,16 +0,0 @@
|
|||||||
package ByteCode;
|
|
||||||
|
|
||||||
import java.security.SecureClassLoader;
|
|
||||||
public class ByteCodeLoader extends SecureClassLoader {
|
|
||||||
private final byte[] bytecode;
|
|
||||||
|
|
||||||
public ByteCodeLoader(byte[] bytecode) {
|
|
||||||
this.bytecode = bytecode;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Class<?> findClass(String name) throws ClassNotFoundException {
|
|
||||||
return defineClass(name, bytecode, 0, bytecode.length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
110
src/test/java/ByteCode/CompareByteCodeBehaviour.java
Normal file
110
src/test/java/ByteCode/CompareByteCodeBehaviour.java
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
package ByteCode;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
|
||||||
|
import static ByteCode.CompareByteCodeSyntax.compareMethod;
|
||||||
|
|
||||||
|
public class CompareByteCodeBehaviour {
|
||||||
|
ArrayList<Method> methodArray1;
|
||||||
|
ArrayList<Method> methodArray2;
|
||||||
|
|
||||||
|
public CompareByteCodeBehaviour(){
|
||||||
|
methodArray1 = new ArrayList<Method>();
|
||||||
|
methodArray2 = new ArrayList<Method>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void clearMethods(){
|
||||||
|
methodArray1.clear();
|
||||||
|
methodArray2.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean functionAlreadyAdded(Method method1, Method method2){
|
||||||
|
int lengthOfArray = methodArray1.size();
|
||||||
|
for (int i = 0; i < lengthOfArray; i++) {
|
||||||
|
if (method1.getName().equals(this.methodArray1.get(i).getName()) ||
|
||||||
|
method2.getName().equals(this.methodArray1.get(i).getName())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sortMethods(Class<?> class1, Class<?> class2) {
|
||||||
|
this.clearMethods();
|
||||||
|
Method[] methods1 = class1.getDeclaredMethods();
|
||||||
|
Method[] methods2 = class2.getDeclaredMethods();
|
||||||
|
|
||||||
|
for (Method method1 : methods1) {
|
||||||
|
for (Method method2 : methods2) {
|
||||||
|
if (compareMethod(method1, method2)) {
|
||||||
|
if (!functionAlreadyAdded(method1, method2)) {
|
||||||
|
this.methodArray1.add(method1);
|
||||||
|
this.methodArray2.add(method2);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void compareMethodBehaviour(Class<?> class1, Class<?> class2){
|
||||||
|
try {
|
||||||
|
this.sortMethods(class1, class2);
|
||||||
|
// Create instances
|
||||||
|
Constructor<?> constructor1 = class1.getDeclaredConstructor();
|
||||||
|
Constructor<?> constructor2 = class2.getDeclaredConstructor();
|
||||||
|
Object obj1 = constructor1.newInstance();
|
||||||
|
Object obj2 = constructor2.newInstance();
|
||||||
|
|
||||||
|
// Get methods
|
||||||
|
Method[] methods1 = new Method[this.methodArray1.size()];
|
||||||
|
methods1 = this.methodArray1.toArray(methods1);
|
||||||
|
Method[] methods2 = new Method[this.methodArray2.size()];
|
||||||
|
methods2 = this.methodArray2.toArray(methods2);
|
||||||
|
|
||||||
|
|
||||||
|
// Compare methods
|
||||||
|
for (int i = 0; i < methods1.length; i++) {
|
||||||
|
Method method1 = methods1[i];
|
||||||
|
Method method2 = methods2[i];
|
||||||
|
|
||||||
|
|
||||||
|
// Test with some sample inputs
|
||||||
|
Object[] testInputs = getTestInputs(method1.getParameterTypes());
|
||||||
|
|
||||||
|
Object result1 = method1.invoke(obj1, testInputs);
|
||||||
|
Object result2 = method2.invoke(obj2, testInputs);
|
||||||
|
|
||||||
|
/*
|
||||||
|
if (!result1.equals(result2)) {
|
||||||
|
System.out.println("Methods " + method1.getName() + " do not produce the same result");
|
||||||
|
} else {
|
||||||
|
System.out.println("Methods " + method1.getName() + " produce the same result");
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (InstantiationException | IllegalAccessException |
|
||||||
|
NoSuchMethodException | InvocationTargetException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Object[] getTestInputs(Class<?>[] parameterTypes) {
|
||||||
|
// Create test inputs based on parameter types
|
||||||
|
Object[] inputs = new Object[parameterTypes.length];
|
||||||
|
for (int i = 0; i < parameterTypes.length; i++) {
|
||||||
|
if (parameterTypes[i] == int.class) {
|
||||||
|
inputs[i] = 1; // example value
|
||||||
|
} else if (parameterTypes[i] == String.class) {
|
||||||
|
inputs[i] = "test"; // example value
|
||||||
|
}
|
||||||
|
// Add more cases as needed for different parameter types
|
||||||
|
}
|
||||||
|
return inputs;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
122
src/test/java/ByteCode/CompareByteCodeSyntax.java
Normal file
122
src/test/java/ByteCode/CompareByteCodeSyntax.java
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
package ByteCode;
|
||||||
|
|
||||||
|
import java.lang.annotation.Annotation;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.Arrays;
|
||||||
|
public class CompareByteCodeSyntax {
|
||||||
|
|
||||||
|
public static boolean haveSameBehavior(Class<?> class1, Class<?> class2) {
|
||||||
|
if (!compareClassSignatures(class1, class2)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!compareMethods(class1, class2)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!compareFields(class1, class2)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!compareAnnotations(class1.getAnnotations(), class2.getAnnotations())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean compareClassSignatures(Class<?> class1, Class<?> class2) {
|
||||||
|
if (!Arrays.equals(class1.getInterfaces(), class2.getInterfaces())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (class1.getSuperclass() != class2.getSuperclass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean compareMethods(Class<?> class1, Class<?> class2) {
|
||||||
|
Method[] methods1 = class1.getDeclaredMethods();
|
||||||
|
Method[] methods2 = class2.getDeclaredMethods();
|
||||||
|
if (methods1.length != methods2.length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (Method method1 : methods1) {
|
||||||
|
boolean found = false;
|
||||||
|
for (Method method2 : methods2) {
|
||||||
|
if (compareMethod(method1, method2)) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean compareMethod(Method method1, Method method2) {
|
||||||
|
if (!method1.getReturnType().equals(method2.getReturnType())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!Arrays.equals(method1.getParameterTypes(), method2.getParameterTypes())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!Arrays.equals(method1.getExceptionTypes(), method2.getExceptionTypes())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!compareAnnotations(method1.getAnnotations(), method2.getAnnotations())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean compareFields(Class<?> class1, Class<?> class2) {
|
||||||
|
Field[] fields1 = class1.getDeclaredFields();
|
||||||
|
Field[] fields2 = class2.getDeclaredFields();
|
||||||
|
if (fields1.length != fields2.length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (Field field1 : fields1) {
|
||||||
|
boolean found = false;
|
||||||
|
for (Field field2 : fields2) {
|
||||||
|
if (compareField(field1, field2)) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean compareField(Field field1, Field field2) {
|
||||||
|
if (!field1.getType().equals(field2.getType())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!compareAnnotations(field1.getAnnotations(), field2.getAnnotations())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean compareAnnotations(Annotation[] annotations1, Annotation[] annotations2) {
|
||||||
|
if (annotations1.length != annotations2.length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (Annotation annotation1 : annotations1) {
|
||||||
|
boolean found = false;
|
||||||
|
for (Annotation annotation2 : annotations2) {
|
||||||
|
if (annotation1.annotationType().equals(annotation2.annotationType())) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
4
src/test/java/ByteCode/TestAll.java
Normal file
4
src/test/java/ByteCode/TestAll.java
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
package ByteCode;
|
||||||
|
|
||||||
|
public class TestAll {
|
||||||
|
}
|
5
src/test/java/Typecheck/TestAll.java
Normal file
5
src/test/java/Typecheck/TestAll.java
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
package Typecheck;
|
||||||
|
|
||||||
|
public class TestAll {
|
||||||
|
|
||||||
|
}
|
30
src/test/java/Typecheck/TypeChecker.java
Normal file
30
src/test/java/Typecheck/TypeChecker.java
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
package Typecheck;
|
||||||
|
|
||||||
|
import TypeCheck.TypeCheckResult;
|
||||||
|
import abstractSyntaxTree.Program;
|
||||||
|
import gen.DecafLexer;
|
||||||
|
import org.antlr.v4.runtime.CharStream;
|
||||||
|
import org.antlr.v4.runtime.CharStreams;
|
||||||
|
import org.antlr.v4.runtime.CommonTokenStream;
|
||||||
|
import org.antlr.v4.runtime.Token;
|
||||||
|
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
public class TypeChecker {
|
||||||
|
// Method to test if the TypeCheck returns the expected Result
|
||||||
|
public void assertTypeCheckResult(Program programmToBeTested, boolean expectedResult) throws Exception {
|
||||||
|
boolean actualResult;
|
||||||
|
try {
|
||||||
|
TypeCheckResult typeCheckResult = programmToBeTested.typeCheck();
|
||||||
|
actualResult = true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
actualResult = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEquals(expectedResult, actualResult);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user