diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml
index 712ab9d..35e8b50 100644
--- a/.idea/jarRepositories.xml
+++ b/.idea/jarRepositories.xml
@@ -6,6 +6,11 @@
+
+
+
+
+
diff --git a/.idea/misc.xml b/.idea/misc.xml
index fe442df..fc75401 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -6,7 +6,7 @@
-
+
diff --git a/pom.xml b/pom.xml
index 99e9904..e32826e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -44,6 +44,12 @@
3.26.0
test
+
+ org.mockito
+ mockito-core
+ 5.11.0
+ test
+
@@ -78,4 +84,11 @@
+
+
+ maven_central
+ Maven Central
+ https://repo.maven.apache.org/maven2/
+
+
\ No newline at end of file
diff --git a/src/main/java/ast/ProgramNode.java b/src/main/java/ast/ProgramNode.java
index 7fbe3e0..f8ad19a 100644
--- a/src/main/java/ast/ProgramNode.java
+++ b/src/main/java/ast/ProgramNode.java
@@ -1,5 +1,6 @@
package ast;
+import bytecode.visitor.ProgramVisitor;
import semantic.SemanticVisitor;
import typechecker.TypeCheckResult;
import visitor.Visitable;
@@ -18,4 +19,9 @@ public class ProgramNode implements ASTNode, Visitable {
public TypeCheckResult accept(SemanticVisitor visitor) {
return visitor.analyze(this);
}
+
+ @Override
+ public void accept(ProgramVisitor programVisitor) {
+ programVisitor.visit(this);
+ }
}
diff --git a/src/main/java/ast/expressions/binaryexpressions/BinaryNode.java b/src/main/java/ast/expressions/binaryexpressions/BinaryNode.java
index f02aa2f..40b474a 100644
--- a/src/main/java/ast/expressions/binaryexpressions/BinaryNode.java
+++ b/src/main/java/ast/expressions/binaryexpressions/BinaryNode.java
@@ -2,10 +2,12 @@ package ast.expressions.binaryexpressions;
import ast.expressions.IExpressionNode;
import ast.type.type.*;
+import bytecode.visitor.MethodVisitor;
import semantic.SemanticVisitor;
import typechecker.TypeCheckResult;
+import visitor.Visitable;
-public class BinaryNode implements IExpressionNode {
+public class BinaryNode implements IExpressionNode, Visitable {
private ITypeNode typeNode;
@@ -23,4 +25,9 @@ public class BinaryNode implements IExpressionNode {
public void setType(ITypeNode type) {
this.typeNode = type;
}
+
+ @Override
+ public void accept(MethodVisitor methodVisitor) {
+ methodVisitor.visit(this);
+ }
}
diff --git a/src/main/java/ast/expressions/binaryexpressions/CalculationNode.java b/src/main/java/ast/expressions/binaryexpressions/CalculationNode.java
index f97d957..78c059d 100644
--- a/src/main/java/ast/expressions/binaryexpressions/CalculationNode.java
+++ b/src/main/java/ast/expressions/binaryexpressions/CalculationNode.java
@@ -1,6 +1,7 @@
package ast.expressions.binaryexpressions;
import ast.type.type.*;
+import bytecode.visitor.MethodVisitor;
import semantic.SemanticVisitor;
import typechecker.TypeCheckResult;
@@ -33,4 +34,10 @@ public class CalculationNode extends BinaryNode {
return visitor.analyze(this);
}
+
+ @Override
+ public void accept(MethodVisitor methodVisitor) {
+ methodVisitor.visit(this);
+ }
+
}
diff --git a/src/main/java/ast/expressions/binaryexpressions/DotNode.java b/src/main/java/ast/expressions/binaryexpressions/DotNode.java
index 0b31b01..20b6513 100644
--- a/src/main/java/ast/expressions/binaryexpressions/DotNode.java
+++ b/src/main/java/ast/expressions/binaryexpressions/DotNode.java
@@ -1,6 +1,7 @@
package ast.expressions.binaryexpressions;
import ast.type.type.*;
+import bytecode.visitor.MethodVisitor;
import semantic.SemanticVisitor;
import typechecker.TypeCheckResult;
@@ -34,4 +35,9 @@ public class DotNode extends BinaryNode {
return visitor.analyze(this);
}
+ @Override
+ public void accept(MethodVisitor methodVisitor) {
+ methodVisitor.visit(this);
+ }
+
}
diff --git a/src/main/java/ast/expressions/binaryexpressions/DotSubstractionNode.java b/src/main/java/ast/expressions/binaryexpressions/DotSubstractionNode.java
index 812c58c..a93d1c4 100644
--- a/src/main/java/ast/expressions/binaryexpressions/DotSubstractionNode.java
+++ b/src/main/java/ast/expressions/binaryexpressions/DotSubstractionNode.java
@@ -4,6 +4,7 @@ import ast.expressions.unaryexpressions.MemberAccessNode;
import ast.statementexpressions.methodcallstatementnexpressions.MethodCallNode;
import ast.type.type.*;
import ast.type.ValueNode;
+import bytecode.visitor.MethodVisitor;
import semantic.SemanticVisitor;
import typechecker.TypeCheckResult;
@@ -36,4 +37,9 @@ public class DotSubstractionNode extends BinaryNode {
return visitor.analyze(this);
}
+ @Override
+ public void accept(MethodVisitor methodVisitor) {
+ methodVisitor.visit(this);
+ }
+
}
diff --git a/src/main/java/ast/expressions/binaryexpressions/NonCalculationNode.java b/src/main/java/ast/expressions/binaryexpressions/NonCalculationNode.java
index df0489b..c44a103 100644
--- a/src/main/java/ast/expressions/binaryexpressions/NonCalculationNode.java
+++ b/src/main/java/ast/expressions/binaryexpressions/NonCalculationNode.java
@@ -3,6 +3,7 @@ package ast.expressions.binaryexpressions;
import ast.expressions.IExpressionNode;
import ast.expressions.unaryexpressions.UnaryNode;
import ast.type.type.*;
+import bytecode.visitor.MethodVisitor;
import semantic.SemanticVisitor;
import typechecker.TypeCheckResult;
@@ -42,4 +43,9 @@ public class NonCalculationNode extends BinaryNode {
return visitor.analyze(this);
}
+ @Override
+ public void accept(MethodVisitor methodVisitor) {
+ methodVisitor.visit(this);
+ }
+
}
diff --git a/src/main/java/ast/expressions/unaryexpressions/MemberAccessNode.java b/src/main/java/ast/expressions/unaryexpressions/MemberAccessNode.java
index 3ce6471..ca688db 100644
--- a/src/main/java/ast/expressions/unaryexpressions/MemberAccessNode.java
+++ b/src/main/java/ast/expressions/unaryexpressions/MemberAccessNode.java
@@ -1,6 +1,7 @@
package ast.expressions.unaryexpressions;
import ast.ASTNode;
+import bytecode.visitor.MethodVisitor;
import ast.type.type.ITypeNode;
import semantic.SemanticVisitor;
import typechecker.TypeCheckResult;
@@ -23,6 +24,10 @@ public class MemberAccessNode implements ASTNode, Visitable {
}
@Override
+ public void accept(MethodVisitor methodVisitor) {
+ methodVisitor.visit(this);
+ }
+
public TypeCheckResult accept(SemanticVisitor visitor) {
return visitor.analyze(this);
}
diff --git a/src/main/java/ast/expressions/unaryexpressions/NotNode.java b/src/main/java/ast/expressions/unaryexpressions/NotNode.java
index 017dfe1..e0c31a3 100644
--- a/src/main/java/ast/expressions/unaryexpressions/NotNode.java
+++ b/src/main/java/ast/expressions/unaryexpressions/NotNode.java
@@ -2,12 +2,26 @@ package ast.expressions.unaryexpressions;
import ast.ASTNode;
import ast.expressions.IExpressionNode;
+import bytecode.visitor.MethodVisitor;
+import semantic.SemanticVisitor;
+import typechecker.TypeCheckResult;
+import visitor.Visitable;
-public class NotNode implements ASTNode {
+public class NotNode implements ASTNode, Visitable {
public IExpressionNode expression;
public NotNode(IExpressionNode expression) {
this.expression = expression;
}
+ @Override
+ public void accept(MethodVisitor methodVisitor) {
+ methodVisitor.visit(this);
+ }
+
+ @Override
+ public TypeCheckResult accept(SemanticVisitor visitor) {
+ return null;
+ }
+
}
diff --git a/src/main/java/ast/expressions/unaryexpressions/UnaryNode.java b/src/main/java/ast/expressions/unaryexpressions/UnaryNode.java
index 1baa842..21374fa 100644
--- a/src/main/java/ast/expressions/unaryexpressions/UnaryNode.java
+++ b/src/main/java/ast/expressions/unaryexpressions/UnaryNode.java
@@ -4,6 +4,7 @@ import ast.expressions.IExpressionNode;
import ast.statements.IStatementNode;
import ast.type.type.*;
import ast.type.ValueNode;
+import bytecode.visitor.MethodVisitor;
import semantic.SemanticVisitor;
import typechecker.TypeCheckResult;
@@ -61,4 +62,9 @@ public class UnaryNode implements IExpressionNode {
this.type = type;
}
+ @Override
+ public void accept(MethodVisitor methodVisitor) {
+ methodVisitor.visit(this);
+ }
+
}
diff --git a/src/main/java/ast/literal/BooleanLiteralNode.java b/src/main/java/ast/literal/BooleanLiteralNode.java
new file mode 100644
index 0000000..4657df7
--- /dev/null
+++ b/src/main/java/ast/literal/BooleanLiteralNode.java
@@ -0,0 +1,11 @@
+package ast.literal;
+
+public class BooleanLiteralNode {
+ private String value;
+
+ public BooleanLiteralNode(String value) {this.value = value;}
+
+ public String getValue() {
+ return value;
+ }
+}
diff --git a/src/main/java/ast/literal/CharLiteralNode.java b/src/main/java/ast/literal/CharLiteralNode.java
new file mode 100644
index 0000000..c77c073
--- /dev/null
+++ b/src/main/java/ast/literal/CharLiteralNode.java
@@ -0,0 +1,11 @@
+package ast.literal;
+
+public class CharLiteralNode {
+ public String value;
+
+ public CharLiteralNode(String value) {this.value = value;}
+
+ public String getValue() {
+ return value;
+ }
+}
diff --git a/src/main/java/ast/literal/LiteralNode.java b/src/main/java/ast/literal/LiteralNode.java
new file mode 100644
index 0000000..e18ab7b
--- /dev/null
+++ b/src/main/java/ast/literal/LiteralNode.java
@@ -0,0 +1,30 @@
+package ast.literal;
+import ast.expressions.IExpressionNode;
+import ast.type.type.ITypeNode;
+import semantic.SemanticVisitor;
+import typechecker.TypeCheckResult;
+
+public class LiteralNode implements IExpressionNode {
+
+ public String value;
+ private ITypeNode type;
+
+ public LiteralNode(String value, ITypeNode type) {
+ this.value = value;
+ this.type = type;
+ }
+
+ public ITypeNode getType() {
+ return type;
+ }
+
+ public void setType(ITypeNode type) {
+ this.type = type;
+ }
+
+
+ @Override
+ public TypeCheckResult accept(SemanticVisitor visitor) {
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/ast/members/ConstructorNode.java b/src/main/java/ast/members/ConstructorNode.java
index 71e6d89..4e19933 100644
--- a/src/main/java/ast/members/ConstructorNode.java
+++ b/src/main/java/ast/members/ConstructorNode.java
@@ -3,6 +3,8 @@ package ast.members;
import ast.parameters.ParameterNode;
import ast.statements.BlockNode;
import ast.type.AccessModifierNode;
+import bytecode.visitor.MethodVisitor;
+import visitor.Visitable;
import java.util.ArrayList;
import java.util.List;
@@ -21,6 +23,10 @@ public class ConstructorNode extends MethodNode {
}
@Override
+ public void accept(MethodVisitor methodVisitor) {
+ methodVisitor.visit(this);
+ }
+
public boolean isSame(MethodNode methodNode) {
if (!(Objects.equals(this.identifier, methodNode.getIdentifier()))
|| getParameters().size() != methodNode.getParameters().size()) {
diff --git a/src/main/java/ast/members/FieldNode.java b/src/main/java/ast/members/FieldNode.java
index 86d2f59..edf434c 100644
--- a/src/main/java/ast/members/FieldNode.java
+++ b/src/main/java/ast/members/FieldNode.java
@@ -2,6 +2,8 @@ package ast.members;
import ast.type.AccessModifierNode;
import ast.type.type.ITypeNode;
+import bytecode.visitor.ClassVisitor;
+import bytecode.visitor.MethodVisitor;
import semantic.SemanticVisitor;
import typechecker.TypeCheckResult;
import visitor.Visitable;
@@ -22,4 +24,9 @@ public class FieldNode implements MemberNode, Visitable {
return visitor.analyze(this);
}
+ @Override
+ public void accept(ClassVisitor classVisitor) {
+ classVisitor.visit(this);
+ }
+
}
diff --git a/src/main/java/ast/members/MainMethodNode.java b/src/main/java/ast/members/MainMethodNode.java
index 4680a26..314a6d0 100644
--- a/src/main/java/ast/members/MainMethodNode.java
+++ b/src/main/java/ast/members/MainMethodNode.java
@@ -1,10 +1,18 @@
package ast.members;
import ast.statements.BlockNode;
+import bytecode.visitor.MethodVisitor;
+import visitor.Visitable;
-public class MainMethodNode extends MethodNode {
+public class MainMethodNode extends MethodNode implements Visitable {
+ public BlockNode block;
public MainMethodNode(BlockNode block) {
this.block = block;
}
+
+ @Override
+ public void accept(MethodVisitor methodVisitor) {
+ methodVisitor.visit(this);
+ }
}
diff --git a/src/main/java/ast/members/MethodNode.java b/src/main/java/ast/members/MethodNode.java
index a083ca4..3661fb2 100644
--- a/src/main/java/ast/members/MethodNode.java
+++ b/src/main/java/ast/members/MethodNode.java
@@ -21,7 +21,8 @@ public class MethodNode implements MemberNode, Visitable {
public List parameters = new ArrayList<>();
public BlockNode block;
- public MethodNode() {}
+ public MethodNode() {
+ }
public MethodNode(String accessModifier, ITypeNode type, Boolean voidType, String identifier, BlockNode block){
this.accesModifier = new AccessModifierNode(accessModifier);
diff --git a/src/main/java/ast/statement/BlockStatementNode.java b/src/main/java/ast/statement/BlockStatementNode.java
new file mode 100644
index 0000000..6005d1a
--- /dev/null
+++ b/src/main/java/ast/statement/BlockStatementNode.java
@@ -0,0 +1,11 @@
+package ast.statement;
+
+import ast.statements.IStatementNode;
+
+import java.util.List;
+
+public class BlockStatementNode {
+ List statements;
+
+ public BlockStatementNode(List statements) {this.statements = statements;}
+}
diff --git a/src/main/java/ast/statementexpressions/AssignNode.java b/src/main/java/ast/statementexpressions/AssignNode.java
index 4a5022f..c620abd 100644
--- a/src/main/java/ast/statementexpressions/AssignNode.java
+++ b/src/main/java/ast/statementexpressions/AssignNode.java
@@ -1,6 +1,7 @@
package ast.statementexpressions;
import ast.expressions.IExpressionNode;
+import bytecode.visitor.MethodVisitor;
import semantic.SemanticVisitor;
import typechecker.TypeCheckResult;
@@ -18,4 +19,9 @@ public class AssignNode implements IStatementExpressionNode {
return visitor.analyze(this);
}
+ @Override
+ public void accept(MethodVisitor methodVisitor) {
+ methodVisitor.visit(this);
+ }
+
}
diff --git a/src/main/java/ast/statementexpressions/NewDeclarationNode.java b/src/main/java/ast/statementexpressions/NewDeclarationNode.java
index d7a37bc..0964a6c 100644
--- a/src/main/java/ast/statementexpressions/NewDeclarationNode.java
+++ b/src/main/java/ast/statementexpressions/NewDeclarationNode.java
@@ -1,6 +1,7 @@
package ast.statementexpressions;
import ast.expressions.IExpressionNode;
+import bytecode.visitor.MethodVisitor;
import semantic.SemanticVisitor;
import typechecker.TypeCheckResult;
@@ -24,4 +25,9 @@ public class NewDeclarationNode implements IStatementExpressionNode {
return visitor.analyze(this);
}
+ @Override
+ public void accept(MethodVisitor methodVisitor) {
+ methodVisitor.visit(this);
+ }
+
}
diff --git a/src/main/java/ast/statementexpressions/crementexpressions/DecrementNode.java b/src/main/java/ast/statementexpressions/crementexpressions/DecrementNode.java
index 86adfce..97a359f 100644
--- a/src/main/java/ast/statementexpressions/crementexpressions/DecrementNode.java
+++ b/src/main/java/ast/statementexpressions/crementexpressions/DecrementNode.java
@@ -2,8 +2,10 @@ package ast.statementexpressions.crementexpressions;
import ast.statementexpressions.AssignableNode;
import ast.statementexpressions.IStatementExpressionNode;
+import bytecode.visitor.MethodVisitor;
import semantic.SemanticVisitor;
import typechecker.TypeCheckResult;
+import visitor.Visitable;
public class DecrementNode implements IStatementExpressionNode {
public CrementType crementType;
@@ -19,4 +21,9 @@ public class DecrementNode implements IStatementExpressionNode {
return visitor.analyze(this);
}
+ @Override
+ public void accept(MethodVisitor methodVisitor) {
+ methodVisitor.visit(this);
+ }
+
}
diff --git a/src/main/java/ast/statementexpressions/crementexpressions/IncrementNode.java b/src/main/java/ast/statementexpressions/crementexpressions/IncrementNode.java
index e826824..105f11f 100644
--- a/src/main/java/ast/statementexpressions/crementexpressions/IncrementNode.java
+++ b/src/main/java/ast/statementexpressions/crementexpressions/IncrementNode.java
@@ -2,6 +2,7 @@ package ast.statementexpressions.crementexpressions;
import ast.statementexpressions.AssignableNode;
import ast.statementexpressions.IStatementExpressionNode;
+import bytecode.visitor.MethodVisitor;
import semantic.SemanticVisitor;
import typechecker.TypeCheckResult;
@@ -19,4 +20,9 @@ public class IncrementNode implements IStatementExpressionNode {
return visitor.analyze(this);
}
+ @Override
+ public void accept(MethodVisitor methodVisitor) {
+ methodVisitor.visit(this);
+ }
+
}
diff --git a/src/main/java/ast/statementexpressions/methodcallstatementnexpressions/ChainedMethodNode.java b/src/main/java/ast/statementexpressions/methodcallstatementnexpressions/ChainedMethodNode.java
index b9fa8e4..ae01b85 100644
--- a/src/main/java/ast/statementexpressions/methodcallstatementnexpressions/ChainedMethodNode.java
+++ b/src/main/java/ast/statementexpressions/methodcallstatementnexpressions/ChainedMethodNode.java
@@ -2,11 +2,15 @@ package ast.statementexpressions.methodcallstatementnexpressions;
import ast.ASTNode;
import ast.expressions.IExpressionNode;
+import bytecode.visitor.MethodVisitor;
+import semantic.SemanticVisitor;
+import typechecker.TypeCheckResult;
+import visitor.Visitable;
import java.util.ArrayList;
import java.util.List;
-public class ChainedMethodNode implements ASTNode {
+public class ChainedMethodNode implements ASTNode, Visitable {
public String identifier;
public List expressions = new ArrayList<>();
@@ -17,4 +21,14 @@ public class ChainedMethodNode implements ASTNode {
public void addExpression(IExpressionNode expression) {
expressions.add(expression);
}
+
+ @Override
+ public void accept(MethodVisitor methodVisitor) {
+ methodVisitor.visit(this);
+ }
+
+ @Override
+ public TypeCheckResult accept(SemanticVisitor visitor) {
+ return null;
+ }
}
diff --git a/src/main/java/ast/statementexpressions/methodcallstatementnexpressions/MethodCallNode.java b/src/main/java/ast/statementexpressions/methodcallstatementnexpressions/MethodCallNode.java
index b8b7bd3..e88b38b 100644
--- a/src/main/java/ast/statementexpressions/methodcallstatementnexpressions/MethodCallNode.java
+++ b/src/main/java/ast/statementexpressions/methodcallstatementnexpressions/MethodCallNode.java
@@ -2,6 +2,7 @@ package ast.statementexpressions.methodcallstatementnexpressions;
import ast.expressions.IExpressionNode;
import ast.statements.IStatementNode;
+import bytecode.visitor.MethodVisitor;
import semantic.SemanticVisitor;
import typechecker.TypeCheckResult;
@@ -32,4 +33,9 @@ public class MethodCallNode implements IStatementNode {
return visitor.analyze(this);
}
+ @Override
+ public void accept(MethodVisitor methodVisitor) {
+ methodVisitor.visit(this);
+ }
+
}
diff --git a/src/main/java/ast/statementexpressions/methodcallstatementnexpressions/TargetNode.java b/src/main/java/ast/statementexpressions/methodcallstatementnexpressions/TargetNode.java
index 01a1d78..d343dbe 100644
--- a/src/main/java/ast/statementexpressions/methodcallstatementnexpressions/TargetNode.java
+++ b/src/main/java/ast/statementexpressions/methodcallstatementnexpressions/TargetNode.java
@@ -3,6 +3,7 @@ package ast.statementexpressions.methodcallstatementnexpressions;
import ast.ASTNode;
import ast.expressions.unaryexpressions.MemberAccessNode;
import ast.statementexpressions.NewDeclarationNode;
+import bytecode.visitor.MethodVisitor;
import semantic.SemanticVisitor;
import typechecker.TypeCheckResult;
import visitor.Visitable;
@@ -30,6 +31,10 @@ public class TargetNode implements ASTNode, Visitable {
}
@Override
+ public void accept(MethodVisitor methodVisitor) {
+ methodVisitor.visit(this);
+ }
+
public TypeCheckResult accept(SemanticVisitor visitor) {
return visitor.analyze(this);
}
diff --git a/src/main/java/ast/statements/BlockStatementNode.java b/src/main/java/ast/statements/BlockStatementNode.java
new file mode 100644
index 0000000..8a01783
--- /dev/null
+++ b/src/main/java/ast/statements/BlockStatementNode.java
@@ -0,0 +1,10 @@
+package ast.statements;
+
+
+import java.util.List;
+
+public class BlockStatementNode {
+ List statements;
+
+ public BlockStatementNode(List statements) {this.statements = statements;}
+}
diff --git a/src/main/java/ast/statements/ElseNode.java b/src/main/java/ast/statements/ElseNode.java
index 7099895..96e579e 100644
--- a/src/main/java/ast/statements/ElseNode.java
+++ b/src/main/java/ast/statements/ElseNode.java
@@ -1,6 +1,5 @@
package ast.statements;
-import ast.ASTNode;
import semantic.SemanticVisitor;
import typechecker.TypeCheckResult;
diff --git a/src/main/java/ast/statements/IfElseNode.java b/src/main/java/ast/statements/IfElseNode.java
index 55d4191..7126bed 100644
--- a/src/main/java/ast/statements/IfElseNode.java
+++ b/src/main/java/ast/statements/IfElseNode.java
@@ -1,6 +1,5 @@
package ast.statements;
-import ast.ASTNode;
import semantic.SemanticVisitor;
import typechecker.TypeCheckResult;
diff --git a/src/main/java/ast/statements/IfNode.java b/src/main/java/ast/statements/IfNode.java
index 46e15c0..30e4e13 100644
--- a/src/main/java/ast/statements/IfNode.java
+++ b/src/main/java/ast/statements/IfNode.java
@@ -1,6 +1,5 @@
package ast.statements;
-import ast.ASTNode;
import ast.expressions.IExpressionNode;
import semantic.SemanticVisitor;
import typechecker.TypeCheckResult;
diff --git a/src/main/java/ast/statements/LocalVariableDeclarationNode.java b/src/main/java/ast/statements/LocalVariableDeclarationNode.java
index 881c437..726ea24 100644
--- a/src/main/java/ast/statements/LocalVariableDeclarationNode.java
+++ b/src/main/java/ast/statements/LocalVariableDeclarationNode.java
@@ -2,6 +2,7 @@ package ast.statements;
import ast.expressions.IExpressionNode;
import ast.type.type.*;
+import bytecode.visitor.MethodVisitor;
import semantic.SemanticVisitor;
import typechecker.TypeCheckResult;
@@ -23,4 +24,9 @@ public class LocalVariableDeclarationNode implements IStatementNode {
return visitor.analyze(this);
}
+ @Override
+ public void accept(MethodVisitor methodVisitor) {
+ methodVisitor.visit(this);
+ }
+
}
diff --git a/src/main/java/ast/statements/ReturnNode.java b/src/main/java/ast/statements/ReturnNode.java
index e25cf6f..fed9c44 100644
--- a/src/main/java/ast/statements/ReturnNode.java
+++ b/src/main/java/ast/statements/ReturnNode.java
@@ -1,6 +1,7 @@
package ast.statements;
import ast.expressions.IExpressionNode;
+import bytecode.visitor.MethodVisitor;
import semantic.SemanticVisitor;
import typechecker.TypeCheckResult;
@@ -21,4 +22,9 @@ public class ReturnNode implements IStatementNode {
return visitor.analyze(this);
}
+ @Override
+ public void accept(MethodVisitor methodVisitor) {
+ methodVisitor.visit(this);
+ }
+
}
diff --git a/src/main/java/ast/statements/WhileNode.java b/src/main/java/ast/statements/WhileNode.java
index ee93167..6ac7f1f 100644
--- a/src/main/java/ast/statements/WhileNode.java
+++ b/src/main/java/ast/statements/WhileNode.java
@@ -1,6 +1,5 @@
package ast.statements;
-import ast.ASTNode;
import ast.expressions.IExpressionNode;
import semantic.SemanticVisitor;
import typechecker.TypeCheckResult;
diff --git a/src/main/java/ast/type/ValueNode.java b/src/main/java/ast/type/ValueNode.java
index ec35af0..bf00e90 100644
--- a/src/main/java/ast/type/ValueNode.java
+++ b/src/main/java/ast/type/ValueNode.java
@@ -1,6 +1,7 @@
package ast.type;
import ast.ASTNode;
+import bytecode.visitor.MethodVisitor;
import semantic.SemanticVisitor;
import typechecker.TypeCheckResult;
import visitor.Visitable;
@@ -14,6 +15,10 @@ public class ValueNode implements ASTNode, Visitable {
this.value = value;
}
+ @Override
+ public void accept(MethodVisitor methodVisitor) {
+ methodVisitor.visit(this);
+ }
@Override
public TypeCheckResult accept(SemanticVisitor visitor) {
diff --git a/src/main/java/bytecode/ByteCodeGenerator.java b/src/main/java/bytecode/ByteCodeGenerator.java
index 5f3cb4b..280bda1 100644
--- a/src/main/java/bytecode/ByteCodeGenerator.java
+++ b/src/main/java/bytecode/ByteCodeGenerator.java
@@ -2,21 +2,78 @@ package bytecode;
import ast.ProgramNode;
import ast.ClassNode;
+import ast.members.MainMethodNode;
+import ast.members.MemberNode;
import bytecode.visitor.ProgramVisitor;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Manifest;
+
public class ByteCodeGenerator implements ProgramVisitor {
- private final String outputDirectoryPath;
+ private JarOutputStream jarOutputStream;
+ private ByteArrayOutputStream byteArrayOutputStream;
+ private String outputDirectory;
- public ByteCodeGenerator(String outputDirectoryPath) {
- this.outputDirectoryPath = outputDirectoryPath;
- }
-
- @Override
- public void visit(ProgramNode programNode) {
- for (ClassNode classDeclarationNode : programNode.classes) {
-// ClassCodeGen classCodeGen = new ClassCodeGen();
-// classDeclarationNode.accept(classCodeGen);
+ public ByteCodeGenerator(String outputDirectory) {
+ this.outputDirectory = outputDirectory;
+ }
+
+ @Override
+ public void visit(ProgramNode programNode) {
+ byteArrayOutputStream = new ByteArrayOutputStream();
+ try {
+ Manifest manifest = new Manifest();
+ manifest.getMainAttributes().putValue("Manifest-Version", "1.0");
+ boolean foundMainClass = false;
+ for (ClassNode classNode : programNode.classes) {
+ if (foundMainClass) {
+ break;
+ }
+ for (MemberNode memberNode : classNode.members) {
+ if (memberNode instanceof MainMethodNode) {
+ manifest.getMainAttributes().putValue("Main-Class", classNode.identifier);
+ foundMainClass = true;
+ break;
+ }
+ }
+ }
+
+
+ jarOutputStream = new JarOutputStream(byteArrayOutputStream, manifest);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+
+ for (ClassNode classDeclarationNode : programNode.classes) {
+ ClassCodeGen classCodeGen = new ClassCodeGen(jarOutputStream, outputDirectory);
+ classDeclarationNode.accept(classCodeGen);
+ }
+
+ try {
+ jarOutputStream.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ saveJarFile(byteArrayOutputStream.toByteArray(), "output.jar");
+ }
+
+ private void saveJarFile(byte[] jarBytes, String jarFileName) {
+ File directory = new File(outputDirectory);
+ if (!directory.exists()) {
+ directory.mkdirs();
+ }
+
+ File jarFile = new File(directory, jarFileName);
+ try (FileOutputStream fos = new FileOutputStream(jarFile)) {
+ fos.write(jarBytes);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
}
- }
}
diff --git a/src/main/java/bytecode/ClassCodeGen.java b/src/main/java/bytecode/ClassCodeGen.java
index 40dc21e..84c8b92 100644
--- a/src/main/java/bytecode/ClassCodeGen.java
+++ b/src/main/java/bytecode/ClassCodeGen.java
@@ -10,26 +10,31 @@ import bytecode.visitor.ClassVisitor;
import java.io.File;
import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.Opcodes;
import java.io.FileOutputStream;
import java.io.IOException;
+import java.util.jar.JarEntry;
+import java.util.jar.JarOutputStream;
public class ClassCodeGen implements ClassVisitor {
private Mapper mapper;
private ClassWriter classWriter;
- private final String outputDirectoryPath;
+ private JarOutputStream jarOutputStream;
+ private String outputDirectory;
- public ClassCodeGen(String outputDirectoryPath) {
- this.outputDirectoryPath = outputDirectoryPath;
+ public ClassCodeGen(JarOutputStream jarOutputStream, String outputDirectory) {
mapper = new Mapper();
+ this.jarOutputStream = jarOutputStream;
+ this.outputDirectory = outputDirectory;
}
@Override
public void visit(ClassNode classNode) {
classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
-// classWriter.visit(Opcodes.V1_5, mapper.mapAccessTypeToOpcode(classNode.accessType), classNode.identifier, null,
-// "java/lang/Object", null);
+ classWriter.visit(Opcodes.V1_5, mapper.mapAccessTypeToOpcode(classNode.accessType), classNode.identifier, null,
+ "java/lang/Object", null);
for (MemberNode memberNode : classNode.members) {
if (memberNode instanceof FieldNode) {
@@ -41,28 +46,27 @@ public class ClassCodeGen implements ClassVisitor {
}
classWriter.visitEnd();
- printIntoClassFile(classWriter.toByteArray(), classNode.identifier);
+ printIntoClassFile(classWriter.toByteArray(), classNode.identifier, outputDirectory);
+ writeToJar(classWriter.toByteArray(), classNode.identifier);
classWriter.visitEnd();
}
@Override
public void visit(FieldNode fieldNode) {
- if(fieldNode.type instanceof BaseType baseTypeNode){
-// classWriter.visitField(mapper.mapAccessTypeToOpcode(fieldNode.accessTypeNode), fieldNode.identifier, mapper.getTypeChar(baseTypeNode.enumType), null, null );
+ if (fieldNode.type instanceof BaseType) {
+ classWriter.visitField(mapper.mapAccessTypeToOpcode(fieldNode.accessTypeNode), fieldNode.identifier, mapper.getTypeChar((BaseType) fieldNode.type), null, null);
}
classWriter.visitEnd();
}
- private void printIntoClassFile(byte[] byteCode, String name) {
- // String outputDirectoryPath = "src/main/resources/output";
- // System.out.println("Output directory path: " + outputDirectoryPath);
- File directory = new File(outputDirectoryPath);
+ private void printIntoClassFile(byte[] byteCode, String name, String outputDirectory) {
+ File directory = new File(outputDirectory);
if (!directory.exists()) {
directory.mkdirs();
}
- String filePath = outputDirectoryPath + "/" + name + ".class";
+ String filePath = outputDirectory + "/" + name + ".class";
try {
FileOutputStream fileOutputStream = new FileOutputStream(filePath);
fileOutputStream.write(byteCode);
@@ -71,4 +75,15 @@ public class ClassCodeGen implements ClassVisitor {
e.printStackTrace();
}
}
+
+ private void writeToJar(byte[] byteCode, String className) {
+ try {
+ JarEntry jarEntry = new JarEntry(className + ".class");
+ jarOutputStream.putNextEntry(jarEntry);
+ jarOutputStream.write(byteCode);
+ jarOutputStream.closeEntry();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
}
diff --git a/src/main/java/bytecode/Mapper.java b/src/main/java/bytecode/Mapper.java
index 5dad54c..b8170d2 100644
--- a/src/main/java/bytecode/Mapper.java
+++ b/src/main/java/bytecode/Mapper.java
@@ -1,41 +1,60 @@
package bytecode;
+import ast.parameters.ParameterNode;
import ast.type.*;
+import ast.type.type.BaseType;
+import ast.type.type.ReferenceType;
+import ast.type.type.TypeEnum;
+import org.objectweb.asm.Opcodes;
+
+import java.util.List;
public class Mapper {
-// public int mapAccessTypeToOpcode(AccessModifierNode type) {
-// switch (type.enumAccessTypeNode) {
-// case EnumAccessTypeNode.PUBLIC:
-// return Opcodes.ACC_PUBLIC;
-// case EnumAccessTypeNode.PRIVATE:
-// return Opcodes.ACC_PRIVATE;
-// }
-// return 0;
-// }
+ public int mapAccessTypeToOpcode(AccessModifierNode accessModifierNode) {
+ switch (accessModifierNode.accessType) {
+ case EnumAccessModifierNode.PUBLIC:
+ return Opcodes.ACC_PUBLIC;
+ case EnumAccessModifierNode.PRIVATE:
+ return Opcodes.ACC_PRIVATE;
+ case EnumAccessModifierNode.PUBLIC_STATIC:
+ return Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC;
+ case EnumAccessModifierNode.PRIVATE_STATIC:
+ return Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC;
+ }
+ return 0;
+ }
-// public String generateMethodDescriptor(BaseTypeNode baseTypeNode, ParameterListNode parameterListNode) {
-// String descriptor = "(";
-// for(ParameterNode parameterNode : parameterListNode.parameters) {
-// descriptor += getTypeChar(EnumTypeNode.INT);
-// }
-// descriptor += ")";
-// descriptor += getTypeChar(baseTypeNode.enumType);
-// return descriptor;
-// }
+ public String generateMethodDescriptor(BaseType type, List parameters) {
+ String descriptor = "(";
+ for (ParameterNode parameterNode : parameters) {
+ descriptor += getTypeChar((BaseType) parameterNode.type);
+ }
+ descriptor += ")";
+ descriptor += getTypeChar(type);
+ return descriptor;
+ }
-// public String getTypeChar(TypeEnum enumTypeNode) {
-// String typeChar = "";
-// switch (enumTypeNode) {
-// case TypeEnum.INT:
-// typeChar = "I";
-// break;
-// case TypeEnum.CHAR:
-// typeChar = "C";
-// break;
-// case TypeEnum.BOOLEAN:
-// typeChar = "Z";
-// break;
-// }
-// return typeChar;
-// }
+ public String generateMethodDescriptor(ReferenceType type, List parameters) {
+ String descriptor = "()V";
+ return descriptor;
+ }
+
+ public String getTypeChar(BaseType type) {
+ String typeChar = "";
+ switch (type.getTypeEnum()) {
+ case TypeEnum.INT:
+ typeChar = "I";
+ break;
+ case TypeEnum.CHAR:
+ typeChar = "C";
+ break;
+ case TypeEnum.BOOL:
+ typeChar = "Z";
+ break;
+ case TypeEnum.VOID:
+ typeChar = "V";
+ break;
+ }
+ return typeChar;
+ }
}
diff --git a/src/main/java/bytecode/MethodCodeGen.java b/src/main/java/bytecode/MethodCodeGen.java
index 704d9a6..a1776c6 100644
--- a/src/main/java/bytecode/MethodCodeGen.java
+++ b/src/main/java/bytecode/MethodCodeGen.java
@@ -1,9 +1,28 @@
package bytecode;
+import ast.expressions.binaryexpressions.*;
+import ast.expressions.unaryexpressions.MemberAccessNode;
+import ast.expressions.unaryexpressions.NotNode;
+import ast.expressions.unaryexpressions.UnaryNode;
import ast.members.ConstructorNode;
+import ast.members.MainMethodNode;
import ast.members.MethodNode;
+import ast.parameters.ParameterNode;
+import ast.statementexpressions.AssignNode;
+import ast.statementexpressions.NewDeclarationNode;
+import ast.statementexpressions.crementexpressions.DecrementNode;
+import ast.statementexpressions.crementexpressions.IncrementNode;
+import ast.statementexpressions.methodcallstatementnexpressions.ChainedMethodNode;
+import ast.statementexpressions.methodcallstatementnexpressions.MethodCallNode;
+import ast.statementexpressions.methodcallstatementnexpressions.TargetNode;
+import ast.statements.*;
+import ast.type.ValueNode;
+import ast.type.type.BaseType;
+import ast.type.type.TypeEnum;
import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
import java.util.ArrayList;
import java.util.List;
@@ -25,70 +44,433 @@ public class MethodCodeGen implements bytecode.visitor.MethodVisitor {
localVaribales = new ArrayList<>();
}
+
+ // Method nodes
+
@Override
public void visit(ConstructorNode constructorNode) {
-// methodVisitor =
-// classWriter.visitMethod(mapper.mapAccessTypeToOpcode(constructorNode.visibility),
-// "",
-// "()V",
-// null,
-// null);
+ methodVisitor =
+ classWriter.visitMethod(mapper.mapAccessTypeToOpcode(constructorNode.accessType),
+ "",
+ mapper.generateMethodDescriptor(new BaseType(TypeEnum.VOID), constructorNode.parameters),
+ null,
+ null);
+
methodVisitor.visitCode();
+ localVaribales.add("this");
+ // Add all method parameters to localVariables
+ for (ParameterNode parameterNode : constructorNode.parameters) {
+ localVaribales.add(parameterNode.identifier);
+ }
+
methodVisitor.visitVarInsn(ALOAD, 0);
methodVisitor.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "", "()V", false);
- methodVisitor.visitInsn(RETURN);
- methodVisitor.visitMaxs(1, 1);
+
+ // Visit all statements
+ for (IStatementNode statementNode : constructorNode.block.statements) {
+ statementNode.accept(this);
+ }
+
+ methodVisitor.visitMaxs(0, 0);
+ methodVisitor.visitEnd();
+ }
+
+ @Override
+ public void visit(MainMethodNode mainMethodNode) {
+ methodVisitor = classWriter.visitMethod(mapper.mapAccessTypeToOpcode(mainMethodNode.accesModifier),
+ mainMethodNode.getIdentifier(),
+ "([Ljava/lang/String;)V",
+ null,
+ null);
+
+ methodVisitor.visitCode();
+ localVaribales.add("this");
+ localVaribales.add("args");
+
+ // Visit all statements
+ for (IStatementNode statementNode : mainMethodNode.block.statements) {
+ statementNode.accept(this);
+ }
+
+ methodVisitor.visitMaxs(0, 0);
methodVisitor.visitEnd();
}
@Override
public void visit(MethodNode methodNode) {
-// if (methodNode.type instanceof BaseTypeNode baseTypeNode) {
-// methodVisitor = classWriter.visitMethod(mapper.mapAccessTypeToOpcode(methodNode.visibility),
-// methodNode.identifier,
-// mapper.generateMethodDescriptor(baseTypeNode, methodNode.parameters),
-// null,
-// null);
+ methodVisitor = classWriter.visitMethod(mapper.mapAccessTypeToOpcode(methodNode.accesModifier),
+ methodNode.getIdentifier(),
+ mapper.generateMethodDescriptor((BaseType) methodNode.getType(), methodNode.parameters),
+ null,
+ null);
- methodVisitor.visitCode();
- localVaribales.add("this");
-// for (ParameterNode parameterNode : methodNode.parameters.parameters) {
-// localVaribales.add(parameterNode.identifier);
-// }
+ methodVisitor.visitCode();
+ localVaribales.add("this");
+ // Add all method parameters to localVariables
+ for (ParameterNode parameterNode : methodNode.parameters) {
+ localVaribales.add(parameterNode.identifier);
+ }
- //test();
- methodVisitor.visitMaxs(1, localVaribales.size());
- methodVisitor.visitEnd();
-// }
+ // Visit all statements
+ for (IStatementNode statementNode : methodNode.block.statements) {
+ statementNode.accept(this);
+ }
+
+ methodVisitor.visitMaxs(0, 0);
+ methodVisitor.visitEnd();
}
-// public void test() {
-// Label start = new Label();
-// Label loop = new Label();
-// Label end = new Label();
-// methodVisitor.visitLabel(start);
-// //methodVisitor.visitVarInsn(Opcodes.ICONST_M1, 99);
-// //methodVisitor.visitInsn(Opcodes.ICONST_5);
-// methodVisitor.visitLdcInsn(99);
-// // methodVisitor.visitInsn(Opcodes.ICONST_0);
-// //methodVisitor.visitVarInsn(Opcodes.ILOAD, 2);
-// methodVisitor.visitVarInsn(Opcodes.ISTORE, 1);
-// methodVisitor.visitLabel(loop);
-// methodVisitor.visitVarInsn(Opcodes.ILOAD, 1);
-// methodVisitor.visitInsn(Opcodes.ICONST_5);
-// methodVisitor.visitJumpInsn(Opcodes.IF_ICMPGE, end);
-// methodVisitor.visitFieldInsn(Opcodes.GETSTATIC,
-// "java/lang/System", "out",
-// "Ljava/io/PrintStream;");
-// methodVisitor.visitLdcInsn("Bytecode");
-// methodVisitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
-// "java/io/PrintStream", "println",
-// "(Ljava/lang/String;)V", false);
-// methodVisitor.visitIincInsn(1, 1);
-// methodVisitor.visitJumpInsn(Opcodes.GOTO, loop);
-// methodVisitor.visitLabel(end);
-// methodVisitor.visitVarInsn(Opcodes.ILOAD, 1);
-// methodVisitor.visitInsn(Opcodes.IRETURN);
-// methodVisitor.visitEnd();
-// }
+
+ // Binary expressions
+
+ @Override
+ public void visit(BinaryNode binaryNode) {
+ binaryNode.accept(this);
+ }
+
+ @Override
+ public void visit(CalculationNode calculationNode) {
+ calculationNode.dotExpression.accept(this);
+ calculationNode.calculationExpression.accept(this);
+ switch (calculationNode.operator) {
+ case PLUS:
+ methodVisitor.visitInsn(IADD);
+ break;
+ case MINUS:
+ methodVisitor.visitInsn(ISUB);
+ break;
+ }
+ }
+
+ @Override
+ public void visit(DotNode dotNode) {
+ dotNode.dotExpression.accept(this);
+ dotNode.dotSubstractionExpression.accept(this);
+ switch (dotNode.operator) {
+ case DIV:
+ methodVisitor.visitInsn(IDIV);
+ break;
+ case MULT:
+ methodVisitor.visitInsn(IMUL);
+ break;
+ case MOD:
+ methodVisitor.visitInsn(IREM);
+ break;
+ }
+ }
+
+ @Override
+ public void visit(DotSubstractionNode dotSubstractionNode) {
+ if (dotSubstractionNode.value != null) {
+ dotSubstractionNode.value.accept(this);
+ } else if (dotSubstractionNode.identifier != null) {
+ methodVisitor.visitVarInsn(ILOAD, localVaribales.indexOf(dotSubstractionNode.identifier));
+ } else if (dotSubstractionNode.memberAccess != null) {
+ dotSubstractionNode.memberAccess.accept(this);
+ } else if (dotSubstractionNode.methodCall != null) {
+ dotSubstractionNode.methodCall.accept(this);
+ } else if (dotSubstractionNode.calculationExpression != null) {
+ dotSubstractionNode.calculationExpression.accept(this);
+ }
+ }
+
+ @Override
+ public void visit(NonCalculationNode nonCalculationNode) {
+ Label labelFalse = new Label();
+ Label labelTrue = new Label();
+ switch (nonCalculationNode.operator) {
+ case AND:
+ nonCalculationNode.unaryExpression.accept(this);
+ methodVisitor.visitJumpInsn(IFEQ, labelFalse); // Value compared to 0 (false)
+ nonCalculationNode.expression.accept(this);
+ methodVisitor.visitJumpInsn(IFEQ, labelFalse);
+ break;
+ case OR:
+ nonCalculationNode.unaryExpression.accept(this);
+ methodVisitor.visitJumpInsn(IFNE, labelTrue);
+ nonCalculationNode.expression.accept(this);
+ methodVisitor.visitJumpInsn(IFEQ, labelFalse);
+ break;
+ case GREATER:
+ nonCalculationNode.unaryExpression.accept(this);
+ nonCalculationNode.expression.accept(this);
+ methodVisitor.visitJumpInsn(IF_ICMPLE, labelFalse);
+ break;
+ case LESS:
+ nonCalculationNode.unaryExpression.accept(this);
+ nonCalculationNode.expression.accept(this);
+ methodVisitor.visitJumpInsn(IF_ICMPGE, labelFalse);
+ break;
+ case GREATER_EQUAL:
+ nonCalculationNode.unaryExpression.accept(this);
+ nonCalculationNode.expression.accept(this);
+ methodVisitor.visitJumpInsn(IF_ICMPLT, labelFalse);
+ break;
+ case LESS_EQUAL:
+ nonCalculationNode.unaryExpression.accept(this);
+ nonCalculationNode.expression.accept(this);
+ methodVisitor.visitJumpInsn(IF_ICMPGT, labelFalse);
+ break;
+ case EQUAL:
+ nonCalculationNode.unaryExpression.accept(this);
+ nonCalculationNode.expression.accept(this);
+ if (nonCalculationNode.unaryExpression.getType() instanceof BaseType && nonCalculationNode.expression.getType() instanceof BaseType) {
+ methodVisitor.visitJumpInsn(IF_ICMPNE, labelFalse);
+ } else {
+ methodVisitor.visitJumpInsn(IF_ACMPNE, labelFalse);
+ }
+ break;
+ case NOT_EQUAL:
+ nonCalculationNode.unaryExpression.accept(this);
+ nonCalculationNode.expression.accept(this);
+ if (nonCalculationNode.unaryExpression.getType() instanceof BaseType && nonCalculationNode.expression.getType() instanceof BaseType) {
+ methodVisitor.visitJumpInsn(IF_ACMPEQ, labelFalse);
+ } else {
+ methodVisitor.visitJumpInsn(IF_ACMPEQ, labelFalse);
+ }
+ break;
+ }
+
+ Label labelEndLogicalExpression = new Label();
+
+ methodVisitor.visitLabel(labelTrue);
+ methodVisitor.visitInsn(ICONST_1); // true
+ methodVisitor.visitJumpInsn(GOTO, labelEndLogicalExpression);
+
+ methodVisitor.visitLabel(labelFalse);
+ methodVisitor.visitInsn(ICONST_0); // false
+
+ methodVisitor.visitLabel(labelEndLogicalExpression);
+ }
+
+
+ // Unary expressions
+
+ @Override
+ public void visit(MemberAccessNode memberAccessNode) {
+ if (memberAccessNode.thisExpr) {
+ //methodVisitor.visitFieldInsn(PUTFIELD);
+ }
+ }
+
+ @Override
+ public void visit(NotNode notNode) {
+ Label labelFalse = new Label();
+ Label labelTrue = new Label();
+
+ notNode.expression.accept(this);
+ methodVisitor.visitJumpInsn(Opcodes.IFNE, labelFalse); // false if value is true (value != 0)
+
+ Label labelEndLogicalExpression = new Label();
+
+ methodVisitor.visitLabel(labelTrue);
+ methodVisitor.visitInsn(ICONST_1); // true
+ methodVisitor.visitJumpInsn(GOTO, labelEndLogicalExpression);
+
+ methodVisitor.visitLabel(labelFalse);
+ methodVisitor.visitInsn(ICONST_0); // false
+
+ methodVisitor.visitLabel(labelEndLogicalExpression);
+ }
+
+ @Override
+ public void visit(UnaryNode unaryNode) {
+
+ }
+
+
+ // Statements
+
+ @Override
+ public void visit(IfElseNode ifElseNode) {
+ Label elseLabel = new Label();
+
+ Label[] elseIfLabels = new Label[ifElseNode.elseIfStatements.size()];
+ for(int i = 0; i < ifElseNode.elseIfStatements.size(); i++) {
+ elseIfLabels[i] = new Label();
+ }
+
+ ifElseNode.ifStatement.expression.accept(this);
+ if (ifElseNode.elseIfStatements.isEmpty()) {
+ // No else if
+ methodVisitor.visitJumpInsn(IFEQ, elseLabel);
+ } else {
+ // else if statements
+ methodVisitor.visitJumpInsn(IFEQ, elseIfLabels[0]);
+ }
+ ifElseNode.ifStatement.block.accept(this); // accept if block
+
+ Label endLabel = new Label();
+ methodVisitor.visitJumpInsn(GOTO, endLabel);
+
+ for(int i = 0; i < ifElseNode.elseIfStatements.size(); i++) {
+ methodVisitor.visitLabel(elseIfLabels[i]);
+ ifElseNode.elseIfStatements.get(i).expression.accept(this);
+ if(i + 1 < elseIfLabels.length) {
+ // at least one more else if
+ methodVisitor.visitJumpInsn(IFEQ, elseIfLabels[i+1]);
+ } else {
+ methodVisitor.visitJumpInsn(IFEQ, elseLabel);
+ }
+ ifElseNode.elseIfStatements.get(i).block.accept(this);
+ methodVisitor.visitJumpInsn(GOTO, endLabel);
+ }
+
+ if(ifElseNode.elseStatement != null) {
+ methodVisitor.visitLabel(elseLabel);
+ ifElseNode.elseStatement.block.accept(this);
+ }
+
+ methodVisitor.visitLabel(endLabel);
+ }
+
+ @Override
+ public void visit(LocalVariableDeclarationNode localVariableDeclarationNode) {
+ // Process expression
+ localVariableDeclarationNode.expression.accept(this);
+ // Store result of expression in variable
+ methodVisitor.visitVarInsn(ISTORE, localVaribales.indexOf(localVariableDeclarationNode.identifier));
+ }
+
+ @Override
+ public void visit(AssignNode assignNode) {
+ // Process expression
+ assignNode.expression.accept(this);
+ // Store result of expression in variable
+ if (assignNode.assignable.memberAccess.thisExpr) {
+ // Global var
+ // /methodVisitor.visitFieldInsn(PUTFIELD, identifierExpressionNode.name, identifierExpressionNode1.name, mapper.getTypeChar(((BaseTypeNode) type).enumType));
+ } else {
+ // Local var
+ methodVisitor.visitVarInsn(ISTORE, localVaribales.indexOf(assignNode.assignable.identifier));
+ }
+ }
+
+ @Override
+ public void visit(NewDeclarationNode newDeclarationNode) {
+
+ }
+
+ @Override
+ public void visit(ValueNode valueNode) {
+ switch (valueNode.valueType) {
+ case INT_VALUE:
+ int intValue = Integer.parseInt(valueNode.value);
+ if (intValue >= Byte.MIN_VALUE && intValue <= Byte.MAX_VALUE) { // load int as byte
+ methodVisitor.visitIntInsn(BIPUSH, intValue);
+ } else if (intValue >= Short.MIN_VALUE && intValue <= Short.MAX_VALUE) { // load int as short
+ methodVisitor.visitIntInsn(SIPUSH, intValue);
+ } else { // load int as const
+ methodVisitor.visitLdcInsn(intValue);
+ }
+ break;
+ case BOOLEAN_VALUE:
+ if (valueNode.value.equals("true")) {
+ methodVisitor.visitInsn(ICONST_1);
+ } else {
+ methodVisitor.visitInsn(ICONST_0);
+ }
+ break;
+ case CHAR_VALUE:
+ char charValue = valueNode.value.charAt(0);
+ if (charValue <= Byte.MAX_VALUE) { // load char as byte
+ methodVisitor.visitIntInsn(BIPUSH, charValue);
+ } else if (charValue <= Short.MAX_VALUE) { // load char as short
+ methodVisitor.visitIntInsn(SIPUSH, charValue);
+ } else { // load char as const
+ methodVisitor.visitLdcInsn(charValue);
+ }
+ break;
+ case NULL_VALUE:
+ methodVisitor.visitInsn(ACONST_NULL);
+ break;
+ }
+ }
+
+ @Override
+ public void visit(ReturnNode returnNode) {
+ if (returnNode.voidReturn) { // Return nothing
+ methodVisitor.visitInsn(RETURN);
+ } else { // Return something
+ // Process expression
+ returnNode.expression.accept(this);
+ // Return result of expression
+ methodVisitor.visitInsn(IRETURN);
+ }
+ }
+
+
+ @Override
+ public void visit(WhileNode whileNode) {
+ Label loopLabel = new Label();
+ Label endOfLoopLabel = new Label();
+
+ methodVisitor.visitLabel(loopLabel);
+ // while loop
+ whileNode.expression.accept(this);
+ methodVisitor.visitJumpInsn(IFEQ, endOfLoopLabel); // if condition is false, jump out of loop
+
+ whileNode.block.accept(this);
+ methodVisitor.visitJumpInsn(GOTO, loopLabel);
+
+ methodVisitor.visitLabel(endOfLoopLabel);
+ }
+
+ @Override
+ public void visit(DecrementNode decrementNode) {
+ switch (decrementNode.crementType) {
+ case PREFIX: // --i
+ if (decrementNode.assignableExpression.memberAccess == null) { // local Var
+ methodVisitor.visitIincInsn(localVaribales.indexOf(decrementNode.assignableExpression.identifier), -1);
+ } else { // Field or var from other object
+
+ }
+ break;
+ case SUFFIX: // i--
+ if (decrementNode.assignableExpression.memberAccess == null) { // local Var
+ methodVisitor.visitIincInsn(localVaribales.indexOf(decrementNode.assignableExpression.identifier), -1);
+ } else { // Field or var from other object
+
+ }
+ break;
+ }
+ }
+
+ @Override
+ public void visit(IncrementNode incrementNode) {
+ switch (incrementNode.crementType) {
+ case PREFIX: // ++i
+ if (incrementNode.assignableExpression.memberAccess == null) { // local Var
+ methodVisitor.visitIincInsn(localVaribales.indexOf(incrementNode.assignableExpression.identifier), 1);
+ methodVisitor.visitVarInsn(ISTORE, localVaribales.indexOf(incrementNode.assignableExpression.identifier));
+
+ } else { // Field or var from other object
+
+ }
+ break;
+ case SUFFIX: // i++
+ if (incrementNode.assignableExpression.memberAccess == null) { // local Var
+ methodVisitor.visitVarInsn(ISTORE, localVaribales.indexOf(incrementNode.assignableExpression.identifier));
+ methodVisitor.visitIincInsn(localVaribales.indexOf(incrementNode.assignableExpression.identifier), 1);
+ } else { // Field or var from other object
+
+ }
+ break;
+ }
+ }
+
+ @Override
+ public void visit(ChainedMethodNode chainedMethodNode) {
+
+ }
+
+ @Override
+ public void visit(MethodCallNode methodCallNode) {
+
+ }
+
+ @Override
+ public void visit(TargetNode targetNode) {
+
+ }
}
diff --git a/src/main/java/bytecode/visitor/MethodVisitor.java b/src/main/java/bytecode/visitor/MethodVisitor.java
index 150a13d..8baf220 100644
--- a/src/main/java/bytecode/visitor/MethodVisitor.java
+++ b/src/main/java/bytecode/visitor/MethodVisitor.java
@@ -1,9 +1,60 @@
package bytecode.visitor;
+import ast.expressions.binaryexpressions.*;
+import ast.expressions.unaryexpressions.MemberAccessNode;
+import ast.expressions.unaryexpressions.NotNode;
+import ast.expressions.unaryexpressions.UnaryNode;
import ast.members.ConstructorNode;
+import ast.members.MainMethodNode;
import ast.members.MethodNode;
+import ast.statementexpressions.AssignNode;
+import ast.statementexpressions.AssignableNode;
+import ast.statementexpressions.NewDeclarationNode;
+import ast.statementexpressions.crementexpressions.DecrementNode;
+import ast.statementexpressions.crementexpressions.IncrementNode;
+import ast.statementexpressions.methodcallstatementnexpressions.ChainedMethodNode;
+import ast.statementexpressions.methodcallstatementnexpressions.MethodCallNode;
+import ast.statementexpressions.methodcallstatementnexpressions.TargetNode;
+import ast.statements.*;
+import ast.type.ValueNode;
public interface MethodVisitor {
+ // members
void visit(ConstructorNode constructorNode);
void visit(MethodNode methodNode);
+ void visit(MainMethodNode mainMethodNode);
+
+ // Binary expressions
+ void visit(BinaryNode binaryNode);
+ void visit(CalculationNode calculationNode);
+ void visit(DotNode dotNode);
+ void visit(DotSubstractionNode dotSubstractionNode);
+ void visit(NonCalculationNode nonCalculationNode);
+
+ // Unary expressions
+ void visit(MemberAccessNode memberAccessNode);
+ void visit(NotNode notExpressionNode);
+ void visit(UnaryNode unaryExpressionNode);
+
+ // statements
+ void visit(IfElseNode ifElseNode);
+
+ void visit(LocalVariableDeclarationNode localVariableDeclarationNode);
+ void visit(ReturnNode returnNode);
+ void visit(WhileNode whileNode);
+
+ // statement expression
+ void visit(DecrementNode decrementNode);
+ void visit(IncrementNode incrementNode);
+
+ void visit(ChainedMethodNode chainedMethodNode);
+ void visit(MethodCallNode methodCallNode);
+ void visit(TargetNode targetNode);
+
+ void visit(AssignNode assignNode);
+ void visit(NewDeclarationNode newDeclarationNode);
+
+ // type
+ void visit(ValueNode valueNode);
+
}
diff --git a/src/main/java/main/Main.java b/src/main/java/main/Main.java
index 7568d24..c365050 100644
--- a/src/main/java/main/Main.java
+++ b/src/main/java/main/Main.java
@@ -91,15 +91,15 @@ public class Main {
/*------------------------- Semantic Analyzer -> typed AST -------------------------*/
// Use the SemanticAnalyzer to generate a typed AST
- ASTNode typedAst = SemanticAnalyzer.generateTast(abstractSyntaxTree);
+ //ASTNode typedAst = SemanticAnalyzer.generateTast(abstractSyntaxTree);
// Log the typed AST
- RaupenLogger.logSemanticAnalyzer(typedAst);
+ RaupenLogger.logSemanticAnalyzer(abstractSyntaxTree);
/*------------------------- Bytecode Generator -> Bytecode -------------------------*/
// Use the ByteCodeGenerator to generate bytecode from the typed AST and output it to the specified directory
ByteCodeGenerator byteCodeGenerator = new ByteCodeGenerator(outputDirectoryPath);
- assert typedAst != null;
- byteCodeGenerator.visit((ProgramNode) typedAst);
+ assert abstractSyntaxTree != null;
+ byteCodeGenerator.visit((ProgramNode) abstractSyntaxTree);
// Log the bytecode generation
RaupenLogger.logBytecodeGenerator();
}
diff --git a/src/main/java/parser/astBuilder/ASTBuilder.java b/src/main/java/parser/astBuilder/ASTBuilder.java
index fcabdfa..db153db 100644
--- a/src/main/java/parser/astBuilder/ASTBuilder.java
+++ b/src/main/java/parser/astBuilder/ASTBuilder.java
@@ -56,10 +56,12 @@ public class ASTBuilder extends SimpleJavaBaseVisitor {
for (SimpleJavaParser.MemberDeclarationContext member : ctx.memberDeclaration()) {
MemberNode memberNode = (MemberNode) visit(member);
- if(memberNode instanceof ConstructorNode){
- hasConstructor = true;
+ if(memberNode != null) {
+ if(memberNode instanceof ConstructorNode){
+ hasConstructor = true;
+ }
+ classNode.addMember(memberNode);
}
- classNode.addMember(memberNode);
}
if(!hasConstructor){
@@ -73,7 +75,12 @@ public class ASTBuilder extends SimpleJavaBaseVisitor {
@Override
public ASTNode visitConstructorDeclaration(SimpleJavaParser.ConstructorDeclarationContext ctx) {
- ConstructorNode constructorNode = new ConstructorNode(ctx.AccessModifier().getText(), ctx.Identifier().getText(), (BlockNode) visit(ctx.blockStatement()));
+ ConstructorNode constructorNode;
+ if(ctx.AccessModifier() != null) {
+ constructorNode = new ConstructorNode(ctx.AccessModifier().getText(), ctx.Identifier().getText(), (BlockNode) visit(ctx.blockStatement()));
+ } else {
+ constructorNode = new ConstructorNode(null, ctx.Identifier().getText(), (BlockNode) visit(ctx.blockStatement()));
+ }
if(ctx.parameterList() != null) {
for(SimpleJavaParser.ParameterContext parameter : ctx.parameterList().parameter()) {
constructorNode.addParameter((ParameterNode) visit(parameter));
@@ -91,22 +98,43 @@ public class ASTBuilder extends SimpleJavaBaseVisitor {
return mainMethod;
} else {
if(ctx.type() != null) {
- MethodNode methodNode = new MethodNode(ctx.AccessModifier().getText(), createTypeNode(ctx.type().getText()), false, ctx.Identifier().getText(), (BlockNode) visit(ctx.blockStatement()));
- if(ctx.parameterList() != null) {
- for(SimpleJavaParser.ParameterContext parameter : ctx.parameterList().parameter()) {
- methodNode.addParameter((ParameterNode) visit(parameter));
+ if(ctx.AccessModifier() != null) {
+ MethodNode methodNode = new MethodNode(ctx.AccessModifier().getText(), createTypeNode(ctx.type().getText()), false, ctx.Identifier().getText(), (BlockNode) visit(ctx.blockStatement()));
+ if(ctx.parameterList() != null) {
+ for(SimpleJavaParser.ParameterContext parameter : ctx.parameterList().parameter()) {
+ methodNode.addParameter((ParameterNode) visit(parameter));
+ }
}
+ return methodNode;
+ } else {
+ MethodNode methodNode = new MethodNode("public", createTypeNode(ctx.type().getText()), false, ctx.Identifier().getText(), (BlockNode) visit(ctx.blockStatement()));
+ if(ctx.parameterList() != null) {
+ for(SimpleJavaParser.ParameterContext parameter : ctx.parameterList().parameter()) {
+ methodNode.addParameter((ParameterNode) visit(parameter));
+ }
+ }
+ return methodNode;
}
- return methodNode;
} else {
- MethodNode methodNode = new MethodNode(ctx.AccessModifier().getText(), null, true, ctx.Identifier().getText(), (BlockNode) visit(ctx.blockStatement()));
- if(ctx.parameterList() != null) {
- for(SimpleJavaParser.ParameterContext parameter : ctx.parameterList().parameter()) {
- methodNode.addParameter((ParameterNode) visit(parameter));
+ if(ctx.AccessModifier() != null) {
+ MethodNode methodNode = new MethodNode(ctx.AccessModifier().getText(), null, true, ctx.Identifier().getText(), (BlockNode) visit(ctx.blockStatement()));
+ if(ctx.parameterList() != null) {
+ for(SimpleJavaParser.ParameterContext parameter : ctx.parameterList().parameter()) {
+ methodNode.addParameter((ParameterNode) visit(parameter));
+ }
}
+ methodNode.block.addStatement(new ReturnNode(null));
+ return methodNode;
+ } else {
+ MethodNode methodNode = new MethodNode("public", null, true, ctx.Identifier().getText(), (BlockNode) visit(ctx.blockStatement()));
+ if(ctx.parameterList() != null) {
+ for(SimpleJavaParser.ParameterContext parameter : ctx.parameterList().parameter()) {
+ methodNode.addParameter((ParameterNode) visit(parameter));
+ }
+ }
+ methodNode.block.addStatement(new ReturnNode(null));
+ return methodNode;
}
- methodNode.block.addStatement(new ReturnNode(null));
- return methodNode;
}
}
}
@@ -116,7 +144,7 @@ public class ASTBuilder extends SimpleJavaBaseVisitor {
if(ctx.AccessModifier() != null) {
return new FieldNode(new AccessModifierNode(ctx.AccessModifier().getText()), createTypeNode(ctx.type().getText()), ctx.Identifier().getText());
} else {
- return new FieldNode(null, createTypeNode(ctx.type().getText()), ctx.Identifier().getText());
+ return new FieldNode(new AccessModifierNode("public"), createTypeNode(ctx.type().getText()), ctx.Identifier().getText());
}
}
@@ -289,7 +317,12 @@ public class ASTBuilder extends SimpleJavaBaseVisitor {
@Override
public ASTNode visitMethodCall(SimpleJavaParser.MethodCallContext ctx) {
- MethodCallNode methodCallStatementExpressionNode = new MethodCallNode((TargetNode) visit(ctx.target()), ctx.Identifier().getText());
+ MethodCallNode methodCallStatementExpressionNode;
+ if(ctx.target() != null) {
+ methodCallStatementExpressionNode = new MethodCallNode((TargetNode) visit(ctx.target()), ctx.Identifier().getText());
+ } else {
+ methodCallStatementExpressionNode = new MethodCallNode(null, ctx.Identifier().getText());
+ }
for(SimpleJavaParser.ChainedMethodContext chainedMethod : ctx.chainedMethod()) {
methodCallStatementExpressionNode.addChainedMethod((ChainedMethodNode) visit(chainedMethod));
}
diff --git a/src/main/resources/input/CompilerInput.java b/src/main/resources/input/CompilerInput.java
index 825490d..b27068a 100644
--- a/src/main/resources/input/CompilerInput.java
+++ b/src/main/resources/input/CompilerInput.java
@@ -2,13 +2,15 @@ public class Compiler {
public int add(int i, int j) {
return i+j;
}
+ public static void main(String[] args) {
+ int a = 1;
+ }
}
public class Node {
public void main() {
Compiler compiler = new Compiler();
int i = compiler.add(5, 8);
- return i;
}
}
diff --git a/src/main/resources/output/output.jar b/src/main/resources/output/output.jar
new file mode 100644
index 0000000..5749e1b
Binary files /dev/null and b/src/main/resources/output/output.jar differ
diff --git a/src/test/Makefile b/src/test/Makefile
index 883b79c..1464161 100644
--- a/src/test/Makefile
+++ b/src/test/Makefile
@@ -10,7 +10,7 @@ compile-javac:
compile-raupenpiler:
cd ../.. ; mvn -DskipTests install
cd ../.. ; mvn exec:java -Dexec.mainClass="main.Main" -Dexec.args="'src/main/resources/input/CompilerInput.java' 'src/main/resources/output' "
- cp ../main/resources/output/CompilerInput.class .java/resources/output/raupenpiler
+ # cp ../main/resources/output/CompilerInput.class .java/resources/output/raupenpiler
test: compile-javac compile-raupenpiler test-javac test-raupenpiler
@@ -31,6 +31,7 @@ test-raupenpiler:
clean:
# clean output folders
rm -f ../main/resources/output/*.class
+ rm -f ../main/resources/output/*.jar
rm -f ./resources/output/javac/*.class
rm -f ./resources/output/raupenpiler/*.class
# clean logs
diff --git a/src/test/java/main/E2EReflectionsTest.java b/src/test/java/main/E2EReflectionsTest.java
new file mode 100644
index 0000000..453d7b3
--- /dev/null
+++ b/src/test/java/main/E2EReflectionsTest.java
@@ -0,0 +1,177 @@
+package main;
+
+import ast.ASTNode;
+import ast.ProgramNode;
+import bytecode.ByteCodeGenerator;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.antlr.v4.runtime.CharStream;
+import org.antlr.v4.runtime.CommonTokenStream;
+import org.antlr.v4.runtime.tree.ParseTree;
+import parser.astBuilder.ASTBuilder;
+import parser.generated.SimpleJavaLexer;
+import parser.generated.SimpleJavaParser;
+import semantic.SemanticAnalyzer;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.*;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+
+public class E2EReflectionsTest {
+
+
+ private CharStream mockInputCharStream;
+ private String outputDirectoryPath;
+ private SimpleJavaLexer mockLexer;
+ private CommonTokenStream mockTokenStream;
+ private SimpleJavaParser mockParser;
+ private ParseTree mockParseTree;
+ private ASTBuilder mockASTBuilder;
+ private ASTNode mockASTNode;
+ private SemanticAnalyzer mockSemanticAnalyzer;
+ private ASTNode mockTypedAST;
+ private ByteCodeGenerator mockByteCodeGenerator;
+
+ @BeforeEach
+ public void setUp() {
+ mockInputCharStream = mock(CharStream.class);
+ outputDirectoryPath = "path/to/output";
+ mockLexer = mock(SimpleJavaLexer.class);
+ mockTokenStream = mock(CommonTokenStream.class);
+ mockParser = mock(SimpleJavaParser.class);
+ mockParseTree = mock(ParseTree.class);
+ mockASTBuilder = mock(ASTBuilder.class);
+ mockASTNode = mock(ASTNode.class);
+ mockSemanticAnalyzer = mock(SemanticAnalyzer.class);
+ mockTypedAST = mock(ASTNode.class);
+ mockByteCodeGenerator = mock(ByteCodeGenerator.class);
+ }
+
+ @Test
+ public void testCompileFile() throws Exception {
+ // Mock the dependencies
+ SimpleJavaLexer mockLexer = mock(SimpleJavaLexer.class);
+ CommonTokenStream mockTokenStream = mock(CommonTokenStream.class);
+ SimpleJavaParser mockParser = mock(SimpleJavaParser.class);
+ ParseTree mockParseTree = mock(ParseTree.class);
+ ASTBuilder mockASTBuilder = mock(ASTBuilder.class);
+ ASTNode mockASTNode = mock(ASTNode.class);
+ SemanticAnalyzer mockSemanticAnalyzer = mock(SemanticAnalyzer.class);
+ ASTNode mockTypedAST = mock(ASTNode.class);
+ ByteCodeGenerator mockByteCodeGenerator = mock(ByteCodeGenerator.class);
+
+ // Mock the behavior
+ when(mockLexer.nextToken()).thenReturn(null);
+ when(mockTokenStream.getTokens()).thenReturn(new ArrayList<>());
+ when(mockParser.program()).thenReturn((SimpleJavaParser.ProgramContext) mockParseTree);
+ when(mockASTBuilder.visit(mockParseTree)).thenReturn(mockASTNode);
+ when(SemanticAnalyzer.generateTast(mockASTNode)).thenReturn(mockTypedAST);
+
+ // Use reflection to invoke the compileFile method
+ Method compileFileMethod = main.Main.class.getDeclaredMethod("compileFile", CharStream.class, String.class);
+ compileFileMethod.setAccessible(true);
+
+ compileFileMethod.invoke(null, mockInputCharStream, outputDirectoryPath);
+
+ // Verify each step
+ verify(mockLexer, times(1)).nextToken();
+ verify(mockTokenStream, times(1)).getTokens();
+ verify(mockParser, times(1)).program();
+ verify(mockASTBuilder, times(1)).visit(mockParseTree);
+ verify(mockSemanticAnalyzer, times(1)).generateTast(mockASTNode);
+ verify(mockByteCodeGenerator, times(1)).visit((ProgramNode) mockTypedAST);
+ }
+
+ @Test
+ public void testCompileFile2() throws Exception {
+ // Mock the behavior
+ when(mockLexer.nextToken()).thenReturn(null);
+ when(mockTokenStream.getTokens()).thenReturn(new ArrayList<>());
+ when(mockParser.program()).thenReturn((SimpleJavaParser.ProgramContext) mockParseTree);
+ when(mockASTBuilder.visit(mockParseTree)).thenReturn(mockASTNode);
+ when(SemanticAnalyzer.generateTast(mockASTNode)).thenReturn(mockTypedAST);
+
+ // Use reflection to invoke the compileFile method
+ Method compileFileMethod = main.Main.class.getDeclaredMethod("compileFile", CharStream.class, String.class);
+ compileFileMethod.setAccessible(true);
+
+ compileFileMethod.invoke(null, mockInputCharStream, outputDirectoryPath);
+
+ // Verify each step
+ verify(mockLexer, times(1)).nextToken();
+ verify(mockTokenStream, times(1)).getTokens();
+ verify(mockParser, times(1)).program();
+ verify(mockASTBuilder, times(1)).visit(mockParseTree);
+ verify(mockSemanticAnalyzer, times(1)).generateTast(mockASTNode);
+ verify(mockByteCodeGenerator, times(1)).visit((ProgramNode) mockTypedAST);
+ }
+
+
+
+
+
+
+ @Test
+ public void testLexer() {
+ // Mock the behavior
+ when(mockLexer.nextToken()).thenReturn(null);
+
+ // Test the lexer
+ SimpleJavaLexer lexer = new SimpleJavaLexer(mockInputCharStream);
+ CommonTokenStream tokenStream = new CommonTokenStream(lexer);
+ tokenStream.fill();
+
+ assertNotNull(tokenStream.getTokens());
+ verify(mockLexer, atLeastOnce()).nextToken();
+ }
+
+ @Test
+ public void testParser() {
+ // Mock the behavior
+ when(mockParser.program()).thenReturn((SimpleJavaParser.ProgramContext) mockParseTree);
+
+ // Test the parser
+ SimpleJavaParser parser = new SimpleJavaParser(mockTokenStream);
+ ParseTree parseTree = parser.program();
+
+ assertNotNull(parseTree);
+ verify(mockParser, times(1)).program();
+ }
+
+ @Test
+ public void testASTBuilder() {
+ // Mock the behavior
+ when(mockASTBuilder.visit(mockParseTree)).thenReturn(mockASTNode);
+
+ // Test the AST builder
+ ASTBuilder astBuilder = new ASTBuilder();
+ ASTNode abstractSyntaxTree = astBuilder.visit(mockParseTree);
+
+ assertNotNull(abstractSyntaxTree);
+ verify(mockASTBuilder, times(1)).visit(mockParseTree);
+ }
+
+ @Test
+ public void testSemanticAnalyzer() {
+ // Mock the behavior
+ when(SemanticAnalyzer.generateTast(mockASTNode)).thenReturn(mockTypedAST);
+
+ // Test the semantic analyzer
+ ASTNode typedAst = SemanticAnalyzer.generateTast(mockASTNode);
+
+ assertNotNull(typedAst);
+ verify(mockSemanticAnalyzer, times(1)).generateTast(mockASTNode);
+ }
+
+ @Test
+ public void testByteCodeGenerator() {
+ // Test the bytecode generator
+ ByteCodeGenerator byteCodeGenerator = new ByteCodeGenerator(outputDirectoryPath);
+ byteCodeGenerator.visit((ProgramNode) mockTypedAST);
+
+ verify(mockByteCodeGenerator, times(1)).visit((ProgramNode) mockTypedAST);
+ }
+}
+
diff --git a/src/test/java/parser/AstBuilderTest.java b/src/test/java/parser/AstBuilderTest.java
index f239a41..b163a2a 100644
--- a/src/test/java/parser/AstBuilderTest.java
+++ b/src/test/java/parser/AstBuilderTest.java
@@ -4,12 +4,27 @@ package parser;
import ast.ASTNode;
import ast.ClassNode;
import ast.ProgramNode;
+import ast.expressions.IExpressionNode;
+import ast.expressions.unaryexpressions.MemberAccessNode;
+import ast.expressions.unaryexpressions.UnaryNode;
import ast.members.ConstructorNode;
import ast.members.FieldNode;
import ast.members.MemberNode;
+import ast.members.MethodNode;
+import ast.parameters.ParameterNode;
+import ast.statementexpressions.AssignNode;
+import ast.statementexpressions.AssignableNode;
+import ast.statementexpressions.methodcallstatementnexpressions.MethodCallNode;
+import ast.statements.BlockNode;
+import ast.statements.IStatementNode;
+import ast.statements.ReturnNode;
import ast.type.AccessModifierNode;
+import ast.type.EnumValueNode;
+import ast.type.ValueNode;
import ast.type.type.BaseType;
+import ast.type.type.ITypeNode;
import ast.type.type.TypeEnum;
+import com.fasterxml.jackson.annotation.JsonFormat;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream;
@@ -21,6 +36,7 @@ import parser.generated.SimpleJavaLexer;
import parser.generated.SimpleJavaParser;
import java.io.IOException;
+import java.lang.reflect.Member;
import static org.assertj.core.api.Assertions.assertThat;
@@ -41,11 +57,11 @@ class AstBuilderTest {
@Test
@DisplayName("Multiple Empty Classes Test")
public void multipleEmptyClassesTest() {
- ClassNode classNode1 = Helper.generateEmptyClass("TestClass1");
- ClassNode classNode2 = Helper.generateEmptyClass("TestClass2");
+ ClassNode class1 = Helper.generateEmptyClass("TestClass1");
+ ClassNode class2 = Helper.generateEmptyClass("TestClass2");
ProgramNode expected = new ProgramNode();
- expected.addClass(classNode1);
- expected.addClass(classNode2);
+ expected.addClass(class1);
+ expected.addClass(class2);
ASTNode actual = Helper.generateAST("src/test/resources/input/javaCases/MultipleClasses.java");
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
@@ -54,9 +70,9 @@ class AstBuilderTest {
@Test
@DisplayName("Empty Class Test with Constructor")
public void emptyClassWithConstructorTest() {
- ClassNode classNode = Helper.generateEmptyClass("TestClass");
+ ClassNode class1 = Helper.generateEmptyClass("TestClass");
ProgramNode expected = new ProgramNode();
- expected.addClass(classNode);
+ expected.addClass(class1);
ASTNode actual = Helper.generateAST("src/test/resources/input/javaCases/EmptyClassWithConstructor.java");
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
@@ -65,11 +81,11 @@ class AstBuilderTest {
@Test
@DisplayName("Field Test")
public void fieldTest() {
- ClassNode classNode = Helper.generateEmptyClass("TestClass");
- classNode.addMember(new FieldNode(null, new BaseType(TypeEnum.INT), "a"));
+ ClassNode class1 = Helper.generateEmptyClass("TestClass");
+ class1.addMember(new FieldNode(null, new BaseType(TypeEnum.INT), "a"));
ProgramNode expected = new ProgramNode();
- expected.addClass(classNode);
+ expected.addClass(class1);
ASTNode actual = Helper.generateAST("src/test/resources/input/javaCases/Field.java");
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
@@ -78,11 +94,11 @@ class AstBuilderTest {
@Test
@DisplayName("Field Test with Accessmodifier")
public void fieldTestWithModifier() {
- ClassNode classNode = Helper.generateEmptyClass("TestClass");
- classNode.addMember(new FieldNode(new AccessModifierNode("public"), new BaseType(TypeEnum.INT), "a"));
+ ClassNode class1 = Helper.generateEmptyClass("TestClass");
+ class1.addMember(new FieldNode(new AccessModifierNode("public"), new BaseType(TypeEnum.INT), "a"));
ProgramNode expected = new ProgramNode();
- expected.addClass(classNode);
+ expected.addClass(class1);
ASTNode actual = Helper.generateAST("src/test/resources/input/javaCases/FieldWithAccessModifier.java");
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
@@ -91,64 +107,236 @@ class AstBuilderTest {
@Test
@DisplayName("Commments Ignore Test")
public void commmentsIgnoreTest(){
+ ClassNode class1 = Helper.generateEmptyClass("TestClass");
+ class1.addMember(new FieldNode(new AccessModifierNode("private"), new BaseType(TypeEnum.INT), "a"));
- //assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
+ ProgramNode expected = new ProgramNode();
+ expected.addClass(class1);
+
+ ASTNode actual = Helper.generateAST("src/test/resources/input/javaCases/Comments.java");
+
+ assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
}
@Test
@DisplayName("Constructor Paramerter Test")
public void constructorParameterTest(){
+ BlockNode block = new BlockNode();
+ block.addStatement(new ReturnNode(null));
+ ConstructorNode constructor = new ConstructorNode("public", "TestClass", block);
+ constructor.addParameter(new ParameterNode(new BaseType(TypeEnum.INT), "a"));
+ constructor.addParameter(new ParameterNode(new BaseType(TypeEnum.INT), "b"));
- //assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
+ ClassNode class1 = new ClassNode("public", "TestClass");
+ class1.addMember(constructor);
+
+ ProgramNode expected = new ProgramNode();
+ expected.addClass(class1);
+
+ ASTNode actual = Helper.generateAST("src/test/resources/input/javaCases/ConstructorParameter.java");
+
+ assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
}
@Test
@DisplayName("This Dot Test")
public void thisDotTest(){
+ BlockNode block = new BlockNode();
+ MemberAccessNode memberAccess = new MemberAccessNode(true);
+ memberAccess.addIdentifier("a");
- //assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
+ AssignableNode assignable = new AssignableNode(memberAccess);
+
+ ValueNode value = new ValueNode(EnumValueNode.INT_VALUE, "1");
+ IExpressionNode expression = new UnaryNode(value);
+
+ block.addStatement(new AssignNode(assignable, expression));
+ block.addStatement(new ReturnNode(null));
+ ConstructorNode constructor = new ConstructorNode("public", "TestClass", block);
+
+ ClassNode class1 = new ClassNode("public", "TestClass");
+ class1.addMember(new FieldNode(new AccessModifierNode("public"), new BaseType(TypeEnum.INT), "a"));
+ class1.addMember(constructor);
+
+ ProgramNode expected = new ProgramNode();
+ expected.addClass(class1);
+
+ ASTNode actual = Helper.generateAST("src/test/resources/input/javaCases/ThisDot.java");
+
+ assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
}
@Test
@DisplayName("Constructor This Dot Test")
public void constructorThisDotTest(){
+ BlockNode block = new BlockNode();
+ MemberAccessNode memberAccess = new MemberAccessNode(true);
+ memberAccess.addIdentifier("a");
- //assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
+ AssignableNode assignable = new AssignableNode(memberAccess);
+
+ IExpressionNode expression = new UnaryNode("a");
+
+ block.addStatement(new AssignNode(assignable, expression));
+ block.addStatement(new ReturnNode(null));
+ ConstructorNode constructor = new ConstructorNode("public", "TestClass", block);
+ constructor.addParameter(new ParameterNode(new BaseType(TypeEnum.INT), "a"));
+
+ ClassNode class1 = new ClassNode("public", "TestClass");
+ class1.addMember(new FieldNode(new AccessModifierNode("private"), new BaseType(TypeEnum.INT), "a"));
+ class1.addMember(constructor);
+
+ ProgramNode expected = new ProgramNode();
+ expected.addClass(class1);
+
+ ASTNode actual = Helper.generateAST("src/test/resources/input/javaCases/ConstructorThisDot.java");
+
+ assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
}
@Test
@DisplayName("Void Methoden Test")
public void voidMethodenTest(){
+ ClassNode class1 = Helper.generateEmptyClass("TestClass");
+ BlockNode block = new BlockNode();
+ block.addStatement(new ReturnNode(null));
+ class1.addMember(new MethodNode("public", null, true, "test", block));
- //assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
+ ProgramNode expected = new ProgramNode();
+ expected.addClass(class1);
+
+ ASTNode actual = Helper.generateAST("src/test/resources/input/javaCases/VoidMethod.java");
+
+ assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
}
@Test
@DisplayName("Constructor Method call Test")
public void constructorMethodCallTest(){
+ BlockNode blockCon = new BlockNode();
+ MemberAccessNode memberAccess = new MemberAccessNode(true);
+ memberAccess.addIdentifier("a");
- //assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
+ AssignableNode assignable = new AssignableNode(memberAccess);
+
+ IExpressionNode expression = new UnaryNode(new MethodCallNode(null, "testMethod"));
+
+ blockCon.addStatement(new AssignNode(assignable, expression));
+ blockCon.addStatement(new ReturnNode(null));
+ ConstructorNode constructor = new ConstructorNode("public", "TestClass", blockCon);
+
+ BlockNode blockMethod = new BlockNode();
+ blockMethod.addStatement(new ReturnNode(new UnaryNode(new ValueNode(EnumValueNode.INT_VALUE, "1"))));
+ MethodNode method = new MethodNode("public", new BaseType(TypeEnum.INT), false, "testMethod", blockMethod);
+
+ ClassNode class1 = new ClassNode("public", "TestClass");
+ class1.addMember(new FieldNode(new AccessModifierNode("public"), new BaseType(TypeEnum.INT), "a"));
+ class1.addMember(constructor);
+ class1.addMember(method);
+
+ ProgramNode expected = new ProgramNode();
+ expected.addClass(class1);
+
+ ASTNode actual = Helper.generateAST("src/test/resources/input/javaCases/ConstructorMethodCall.java");
+
+ assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
}
@Test
@DisplayName("Constructor Method call Parameters Test")
public void constructorMethodCallParametersTest(){
+ BlockNode blockCon = new BlockNode();
+ MemberAccessNode memberAccess = new MemberAccessNode(true);
+ memberAccess.addIdentifier("a");
- //assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
+ AssignableNode assignable = new AssignableNode(memberAccess);
+
+ MethodCallNode methodCall = new MethodCallNode(null, "testMethod");
+ methodCall.addExpression(new UnaryNode("a"));
+ IExpressionNode expression = new UnaryNode(methodCall);
+
+ blockCon.addStatement(new AssignNode(assignable, expression));
+ blockCon.addStatement(new ReturnNode(null));
+ ConstructorNode constructor = new ConstructorNode("public", "TestClass", blockCon);
+ constructor.addParameter(new ParameterNode(new BaseType(TypeEnum.INT), "a"));
+
+ BlockNode blockMethod = new BlockNode();
+ blockMethod.addStatement(new ReturnNode(new UnaryNode("a")));
+ MethodNode method = new MethodNode("public", new BaseType(TypeEnum.INT), false, "testMethod", blockMethod);
+ method.addParameter(new ParameterNode(new BaseType(TypeEnum.INT), "a"));
+
+ ClassNode class1 = new ClassNode("public", "TestClass");
+ class1.addMember(new FieldNode(new AccessModifierNode("public"), new BaseType(TypeEnum.INT), "a"));
+ class1.addMember(constructor);
+ class1.addMember(method);
+
+ ProgramNode expected = new ProgramNode();
+ expected.addClass(class1);
+
+ ASTNode actual = Helper.generateAST("src/test/resources/input/javaCases/ConstructorMethodCallParameters.java");
+
+ assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
}
@Test
@DisplayName("Char Test")
public void charTest(){
+ BlockNode blockCon = new BlockNode();
+ MemberAccessNode memberAccess = new MemberAccessNode(true);
+ memberAccess.addIdentifier("a");
- //assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
+ AssignableNode assignable = new AssignableNode(memberAccess);
+
+ MethodCallNode methodCall = new MethodCallNode(null, "testMethod");
+ methodCall.addExpression(new UnaryNode("a"));
+ IExpressionNode expression = new UnaryNode(methodCall);
+
+ blockCon.addStatement(new AssignNode(assignable, expression));
+ blockCon.addStatement(new ReturnNode(null));
+ ConstructorNode constructor = new ConstructorNode("public", "TestClass", blockCon);
+ constructor.addParameter(new ParameterNode(new BaseType(TypeEnum.CHAR), "a"));
+
+ BlockNode blockMethod = new BlockNode();
+ blockMethod.addStatement(new ReturnNode(new UnaryNode("a")));
+ MethodNode method = new MethodNode("public", new BaseType(TypeEnum.CHAR), false, "testMethod", blockMethod);
+ method.addParameter(new ParameterNode(new BaseType(TypeEnum.CHAR), "a"));
+
+ ClassNode class1 = new ClassNode("public", "TestClass");
+ class1.addMember(new FieldNode(new AccessModifierNode("public"), new BaseType(TypeEnum.CHAR), "a"));
+ class1.addMember(constructor);
+ class1.addMember(method);
+
+ ProgramNode expected = new ProgramNode();
+ expected.addClass(class1);
+
+ ASTNode actual = Helper.generateAST("src/test/resources/input/javaCases/Char.java");
+
+ assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
}
@Test
@DisplayName("Null Test")
public void nullTest(){
+ BlockNode blockCon = new BlockNode();
+ MemberAccessNode memberAccess = new MemberAccessNode(true);
+ memberAccess.addIdentifier("a");
- //assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
+ AssignableNode assignable = new AssignableNode(memberAccess);
+
+ blockCon.addStatement(new AssignNode(assignable, new UnaryNode(new ValueNode(EnumValueNode.NULL_VALUE, "null"))));
+ blockCon.addStatement(new ReturnNode(null));
+ ConstructorNode constructor = new ConstructorNode("public", "TestClass", blockCon);
+
+ ClassNode class1 = new ClassNode("public", "TestClass");
+ class1.addMember(new FieldNode(new AccessModifierNode("public"), new BaseType(TypeEnum.INT), "a"));
+ class1.addMember(constructor);
+
+ ProgramNode expected = new ProgramNode();
+ expected.addClass(class1);
+
+ ASTNode actual = Helper.generateAST("src/test/resources/input/javaCases/Null.java");
+
+ assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
}
@Test
diff --git a/src/test/resources/input/AllFeaturesClassExample.java b/src/test/resources/input/AllFeaturesClassExample.java
index 1a8493d..73121ee 100644
--- a/src/test/resources/input/AllFeaturesClassExample.java
+++ b/src/test/resources/input/AllFeaturesClassExample.java
@@ -9,42 +9,25 @@ public class AllFeaturesClassExample {
this.b = b;
this.c = c;
}
- private class InnerClass {
- void innerMethod() {
- System.out.println("Inner class method");
- }
- }
// Methode zur Demonstration von Kontrollstrukturen
void controlStructures() {
// if-else Anweisung
if (a > 10) {
- System.out.println("a ist größer als 10");
+ // System.out.println("a ist größer als 10");
} else {
- System.out.println("a ist nicht größer als 10");
+ // System.out.println("a ist nicht größer als 10");
}
// while Schleife
while (a > 0) {
- System.out.println("a ist " + a);
+ // System.out.println("a ist " + a);
a--;
}
// for Schleife
for (int i = 0; i < 5; i++) {
- System.out.println("for Schleife Iteration: " + i);
- }
-
- // switch Anweisung
- switch (c) {
- case 'a':
- System.out.println("c ist ein 'a'");
- break;
- case 'b':
- System.out.println("c ist ein 'b'");
- break;
- default:
- System.out.println("c ist nicht 'a' oder 'b'");
+ // System.out.println("for Schleife Iteration: " + i);
}
}
@@ -52,15 +35,28 @@ public class AllFeaturesClassExample {
void logicalOperations() {
// Logische UND-Operation
if (b && a > 5) {
- System.out.println("a ist größer als 5 und b ist wahr");
+ // System.out.println("a ist größer als 5 und b ist wahr");
}
// Logische ODER-Operation
if (b || a < 5) {
- System.out.println("b ist wahr oder a ist kleiner als 5");
+ // System.out.println("b ist wahr oder a ist kleiner als 5");
}
}
+ void mathOperations() {
+ // Addition
+ int sum = a + 5;
+ // Subtraktion
+ int difference = a - 5;
+ // Multiplikation
+ int product = a * 5;
+ // Division
+ int quotient = a / 5;
+ // Modulo
+ int remainder = a % 5;
+ }
+
public static void main(String[] args) {
AllFeaturesClassExample obj = new AllFeaturesClassExample(12, true, 'a');
obj.controlStructures();
diff --git a/src/test/resources/input/javaCases/ConstructorMehtodCallParameters.java b/src/test/resources/input/javaCases/ConstructorMethodCallParameters.java
similarity index 100%
rename from src/test/resources/input/javaCases/ConstructorMehtodCallParameters.java
rename to src/test/resources/input/javaCases/ConstructorMethodCallParameters.java
diff --git a/src/test/resources/input/javaCases/ThisDot.java b/src/test/resources/input/javaCases/ThisDot.java
index ddff42c..866b39e 100644
--- a/src/test/resources/input/javaCases/ThisDot.java
+++ b/src/test/resources/input/javaCases/ThisDot.java
@@ -2,7 +2,7 @@ class TestClass{
public int a;
- public TestClass{
+ public TestClass() {
this.a = 1;
}
}
\ No newline at end of file
diff --git a/src/test/resources/trees/correctRefType.json b/src/test/resources/trees/correctRefType.json
deleted file mode 100644
index 7e67bbc..0000000
--- a/src/test/resources/trees/correctRefType.json
+++ /dev/null
@@ -1,70 +0,0 @@
-{
- "classes": [
- {
- "identifier": "testClass1",
- "accessType": {
- "enumAccessTypeNode": "PUBLIC"
- },
- "members": [
- {
- "@type": "Field",
- "accessTypeNode": {
- "enumAccessTypeNode": "PUBLIC"
- },
- "type": {
- "@type": "Base",
- "enumType": "INT"
- },
- "identifier": "testVar1"
- },
- {
- "@type": "Method",
- "visibility": {
- "enumAccessTypeNode": "PUBLIC"
- },
- "type": {
- "@type": "Base",
- "enumType": "INT"
- },
- "identifier": "testMethod",
- "parameters": {
- "parameters": [
- {
- "type": {
- "@type": "Base",
- "enumType": "INT"
- },
- "identifier": "param1"
- }
- ]
- },
- "statements": [
- {
- "@type": "Assignment",
- "expressionLeft": {
- "@type": "InstVar",
- "identifier": "testVar1",
- "expression": {
- "@type": "This",
- "type": {
- "@type": "Reference",
- "identifier": "testClass1"
- }
- },
- "type": null
- },
- "expressionRight": {
- "@type": "Literal",
- "type": {
- "@type": "Base",
- "enumType": "INT"
- }
- }
- }
- ]
- }
- ],
- "hasConstructor": false
- }
- ]
-}
\ No newline at end of file
diff --git a/src/test/resources/trees/refTypeMismatch.json b/src/test/resources/trees/refTypeMismatch.json
deleted file mode 100644
index e5ebcd3..0000000
--- a/src/test/resources/trees/refTypeMismatch.json
+++ /dev/null
@@ -1,133 +0,0 @@
-{
- "classes": [
- {
- "identifier": "testClass1",
- "accessType": {
- "enumAccessTypeNode": "PUBLIC"
- },
- "members": [
- {
- "@type": "Field",
- "accessTypeNode": {
- "enumAccessTypeNode": "PUBLIC"
- },
- "type": {
- "@type": "Base",
- "enumType": "INT"
- },
- "identifier": "testVar1"
- },
- {
- "@type": "Method",
- "visibility": {
- "enumAccessTypeNode": "PUBLIC"
- },
- "type": {
- "@type": "Base",
- "enumType": "INT"
- },
- "identifier": "testMethod",
- "parameters": {
- "parameters": [
- {
- "type": {
- "@type": "Base",
- "enumType": "INT"
- },
- "identifier": "param1"
- }
- ]
- },
- "statements": [
- {
- "@type": "Assignment",
- "expressionLeft": {
- "@type": "InstVar",
- "identifier": "testVar1",
- "expression": {
- "@type": "This",
- "type": {
- "@type": "Reference",
- "identifier": "testClass1"
- }
- },
- "type": null
- },
- "expressionRight": {
- "@type": "Literal",
- "type": {
- "@type": "Base",
- "enumType": "BOOLEAN"
- }
- }
- }
- ]
- }
- ],
- "hasConstructor": false,
- "methods": [
- {
- "@type": "Method",
- "visibility": {
- "enumAccessTypeNode": "PUBLIC"
- },
- "type": {
- "@type": "Base",
- "enumType": "INT"
- },
- "identifier": "testMethod",
- "parameters": {
- "parameters": [
- {
- "type": {
- "@type": "Base",
- "enumType": "INT"
- },
- "identifier": "param1"
- }
- ]
- },
- "statements": [
- {
- "@type": "Assignment",
- "expressionLeft": {
- "@type": "InstVar",
- "identifier": "testVar",
- "expression": {
- "@type": "InstVar",
- "identifier": "testVar",
- "expression": {
- "@type": "This",
- "type": {
- "@type": "Reference",
- "identifier": "testClass2"
- }
- },
- "type": null
- },
- "type": null
- },
- "expressionRight": {
- "@type": "Literal",
- "type": null
- },
- "type": null
- },
- {
- "@type": "VariableDeclaration",
- "type": {
- "@type": "Base",
- "enumType": "CHAR"
- },
- "identifier": "objectVar",
- "expression": {
- "@type": "Literal",
- "type": null
- }
- }
- ]
- }
- ]
- }
- ]
-}
\ No newline at end of file
diff --git a/src/test/resources/trees/test.json b/src/test/resources/trees/test.json
deleted file mode 100644
index 7acc30f..0000000
--- a/src/test/resources/trees/test.json
+++ /dev/null
@@ -1 +0,0 @@
-{"classes":[{"identifier":"testClass","accessType":{"enumAccessTypeNode":"PUBLIC"},"members":[{"@type":"Field","accessTypeNode":{"enumAccessTypeNode":"PUBLIC"},"type":{"@type":"Base","enumType":"INT"},"identifier":"testVar1"},{"@type":"Field","accessTypeNode":{"enumAccessTypeNode":"PUBLIC"},"type":{"@type":"Base","enumType":"INT"},"identifier":"objectVar"},{"@type":"Method","visibility":{"enumAccessTypeNode":"PUBLIC"},"type":{"@type":"Base","enumType":"INT"},"identifier":"testVar2","parameters":{"parameters":[{"type":{"@type":"Base","enumType":"INT"},"identifier":"param1"}]},"statements":[{"@type":"Assignment","expressionLeft":{"@type":"InstVar","identifier":"objectVar","expression":{"@type":"This","type":{"@type":"Reference","identifier":"testClass"}},"type":null},"expressionRight":{"@type":"Literal","type":{"@type":"Base","enumType":"INT"}}}]}],"hasConstructor":false,"methods":[{"@type":"Method","visibility":{"enumAccessTypeNode":"PUBLIC"},"type":{"@type":"Base","enumType":"INT"},"identifier":"testVar2","parameters":{"parameters":[{"type":{"@type":"Base","enumType":"INT"},"identifier":"param1"}]},"statements":[{"@type":"Assignment","expressionLeft":{"@type":"InstVar","identifier":"objectVar","expression":{"@type":"This","type":{"@type":"Reference","identifier":"testClass"}},"type":null},"expressionRight":{"@type":"Literal","type":{"@type":"Base","enumType":"INT"}}}]}]}]}
\ No newline at end of file