From c4061125c45aa6e339f9387bb35fcaade71bb865 Mon Sep 17 00:00:00 2001 From: i22007 Date: Tue, 14 May 2024 11:39:14 +0200 Subject: [PATCH 1/6] Add method parameters to bytecode --- src/main/java/ast/parameter/ParameterListNode.java | 2 +- src/main/java/bytecode/Mapper.java | 10 ++++++++-- src/main/java/bytecode/MethodCodeGen.java | 8 +++++--- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/main/java/ast/parameter/ParameterListNode.java b/src/main/java/ast/parameter/ParameterListNode.java index 34c615a..f409a65 100644 --- a/src/main/java/ast/parameter/ParameterListNode.java +++ b/src/main/java/ast/parameter/ParameterListNode.java @@ -6,7 +6,7 @@ import java.util.ArrayList; import java.util.List; public class ParameterListNode extends ASTNode { - List parameters = new ArrayList<>(); + public List parameters = new ArrayList<>(); public ParameterListNode(List parameters){ this.parameters = parameters; diff --git a/src/main/java/bytecode/Mapper.java b/src/main/java/bytecode/Mapper.java index 7f1b219..dbc452e 100644 --- a/src/main/java/bytecode/Mapper.java +++ b/src/main/java/bytecode/Mapper.java @@ -1,5 +1,7 @@ package bytecode; +import ast.parameter.ParameterListNode; +import ast.parameter.ParameterNode; import ast.type.AccessTypeNode; import ast.type.EnumAccessTypeNode; import ast.type.EnumTypeNode; @@ -17,8 +19,12 @@ public class Mapper { return 0; } - public String generateMethodDescriptor(TypeNode typeNode) { - String descriptor = "()"; + public String generateMethodDescriptor(TypeNode typeNode, ParameterListNode parameterListNode) { + String descriptor = "("; + for(ParameterNode parameterNode : parameterListNode.parameters) { + descriptor += getTypeChar(parameterNode.type.enumTypeNode); + } + descriptor += ")"; descriptor += getTypeChar(typeNode.enumTypeNode); return descriptor; } diff --git a/src/main/java/bytecode/MethodCodeGen.java b/src/main/java/bytecode/MethodCodeGen.java index fd8a29a..2e352be 100644 --- a/src/main/java/bytecode/MethodCodeGen.java +++ b/src/main/java/bytecode/MethodCodeGen.java @@ -9,6 +9,7 @@ public class MethodCodeGen implements bytecode.visitor.MethodVisitor { private ClassWriter classWriter; Mapper mapper = new Mapper(); + private MethodVisitor methodVisitor; public MethodCodeGen(ClassWriter classWriter) { this.classWriter = classWriter; @@ -27,12 +28,13 @@ public class MethodCodeGen implements bytecode.visitor.MethodVisitor { @Override public void visit(MethodNode methodNode) { - MethodVisitor method = classWriter.visitMethod(mapper.mapAccesTypeToOpcode(methodNode.visibility), + methodVisitor = classWriter.visitMethod(mapper.mapAccesTypeToOpcode(methodNode.visibility), methodNode.identifier, - mapper.generateMethodDescriptor(methodNode.type), + mapper.generateMethodDescriptor(methodNode.type, methodNode.parameters), null, null); - method.visitEnd(); + // methodNode.parameters.accept(this); + methodVisitor.visitEnd(); } } From b7d5a5c6254ce1d3e1c514ce67de81327ab65755 Mon Sep 17 00:00:00 2001 From: i22007 Date: Tue, 14 May 2024 15:26:05 +0200 Subject: [PATCH 2/6] Fixed empty class code gen --- .../java/ast/parameter/ParameterListNode.java | 2 +- src/main/java/bytecode/ClassCodeGen.java | 13 +++- src/main/java/bytecode/FieldCodeGen.java | 13 ---- src/main/java/bytecode/Mapper.java | 12 ++- src/main/java/bytecode/MethodCodeGen.java | 75 +++++++++++++++++-- 5 files changed, 86 insertions(+), 29 deletions(-) delete mode 100644 src/main/java/bytecode/FieldCodeGen.java diff --git a/src/main/java/ast/parameter/ParameterListNode.java b/src/main/java/ast/parameter/ParameterListNode.java index 69d12f3..ff1c58d 100644 --- a/src/main/java/ast/parameter/ParameterListNode.java +++ b/src/main/java/ast/parameter/ParameterListNode.java @@ -6,7 +6,7 @@ import java.util.ArrayList; import java.util.List; public class ParameterListNode implements ASTNode { - List parameters = new ArrayList<>(); + public List parameters = new ArrayList<>(); public ParameterListNode(List parameters){ this.parameters = parameters; diff --git a/src/main/java/bytecode/ClassCodeGen.java b/src/main/java/bytecode/ClassCodeGen.java index 7a1c0f0..b0afa69 100644 --- a/src/main/java/bytecode/ClassCodeGen.java +++ b/src/main/java/bytecode/ClassCodeGen.java @@ -13,14 +13,19 @@ import org.objectweb.asm.Opcodes; import java.io.FileOutputStream; import java.io.IOException; + public class ClassCodeGen implements ClassVisitor { - Mapper mapper = new Mapper(); - ClassWriter classWriter; + private Mapper mapper; + private ClassWriter classWriter; + + public ClassCodeGen() { + mapper = new Mapper(); + } @Override public void visit(ClassNode classNode) { classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); - classWriter.visit(Opcodes.V1_8, mapper.mapAccesTypeToOpcode(classNode.accessType), classNode.identifier, null, + classWriter.visit(Opcodes.V1_5, mapper.mapAccessTypeToOpcode(classNode.accessType), classNode.identifier, null, "java/lang/Object", null); for (MemberNode memberNode : classNode.members) { @@ -41,7 +46,7 @@ public class ClassCodeGen implements ClassVisitor { @Override public void visit(FieldNode fieldNode) { if(fieldNode.type instanceof BaseTypeNode baseTypeNode){ - classWriter.visitField(mapper.mapAccesTypeToOpcode(fieldNode.accessTypeNode), fieldNode.identifier, mapper.getTypeChar(baseTypeNode.enumType), null, null ); + classWriter.visitField(mapper.mapAccessTypeToOpcode(fieldNode.accessTypeNode), fieldNode.identifier, mapper.getTypeChar(baseTypeNode.enumType), null, null ); } classWriter.visitEnd(); } diff --git a/src/main/java/bytecode/FieldCodeGen.java b/src/main/java/bytecode/FieldCodeGen.java deleted file mode 100644 index abbda43..0000000 --- a/src/main/java/bytecode/FieldCodeGen.java +++ /dev/null @@ -1,13 +0,0 @@ -package bytecode; - -import ast.member.FieldNode; -import org.objectweb.asm.ClassWriter; -import org.objectweb.asm.FieldVisitor; - -public class FieldCodeGen { - - public void generateFieldCode(ClassWriter classWriter, FieldNode fieldNode) { - Mapper mapper = new Mapper(); - FieldVisitor fieldVisitor = classWriter.visitField(mapper.mapAccesTypeToOpcode(fieldNode.accessTypeNode), fieldNode.identifier, "", null, null); - } -} diff --git a/src/main/java/bytecode/Mapper.java b/src/main/java/bytecode/Mapper.java index fb4f484..4bc1e7c 100644 --- a/src/main/java/bytecode/Mapper.java +++ b/src/main/java/bytecode/Mapper.java @@ -1,10 +1,12 @@ package bytecode; +import ast.parameter.ParameterListNode; +import ast.parameter.ParameterNode; import ast.type.*; import org.objectweb.asm.Opcodes; public class Mapper { - public int mapAccesTypeToOpcode(AccessTypeNode type) { + public int mapAccessTypeToOpcode(AccessTypeNode type) { switch (type.enumAccessTypeNode) { case EnumAccessTypeNode.PUBLIC: return Opcodes.ACC_PUBLIC; @@ -14,8 +16,12 @@ public class Mapper { return 0; } - public String generateMethodDescriptor(BaseTypeNode baseTypeNode) { - String descriptor = "()"; + 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; } diff --git a/src/main/java/bytecode/MethodCodeGen.java b/src/main/java/bytecode/MethodCodeGen.java index c8a38f3..a4249f1 100644 --- a/src/main/java/bytecode/MethodCodeGen.java +++ b/src/main/java/bytecode/MethodCodeGen.java @@ -2,40 +2,99 @@ package bytecode; import ast.member.ConstructorNode; import ast.member.MethodNode; +import ast.parameter.ParameterListNode; +import ast.parameter.ParameterNode; import ast.type.BaseTypeNode; +import ast.type.EnumTypeNode; 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; + +import static org.objectweb.asm.Opcodes.*; + public class MethodCodeGen implements bytecode.visitor.MethodVisitor { private ClassWriter classWriter; - Mapper mapper = new Mapper(); + private Mapper mapper; private MethodVisitor methodVisitor; + private List localVaribales; + public MethodCodeGen(ClassWriter classWriter) { this.classWriter = classWriter; + mapper = new Mapper(); + localVaribales = new ArrayList<>(); } @Override public void visit(ConstructorNode constructorNode) { - MethodVisitor constructor = - classWriter.visitMethod(mapper.mapAccesTypeToOpcode(constructorNode.visibility), + methodVisitor = + classWriter.visitMethod(mapper.mapAccessTypeToOpcode(constructorNode.visibility), "", "()V", null, null); - constructor.visitEnd(); + methodVisitor.visitCode(); + methodVisitor.visitVarInsn(ALOAD, 0); + methodVisitor.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "", "()V", false); + methodVisitor.visitInsn(RETURN); + methodVisitor.visitMaxs(1, 1); + methodVisitor.visitEnd(); } @Override public void visit(MethodNode methodNode) { - if(methodNode.type instanceof BaseTypeNode baseTypeNode){ - MethodVisitor method = classWriter.visitMethod(mapper.mapAccesTypeToOpcode(methodNode.visibility), + if (methodNode.type instanceof BaseTypeNode baseTypeNode) { + methodVisitor = classWriter.visitMethod(mapper.mapAccessTypeToOpcode(methodNode.visibility), methodNode.identifier, - mapper.generateMethodDescriptor(baseTypeNode), + mapper.generateMethodDescriptor(baseTypeNode, methodNode.parameters), null, null); - method.visitEnd(); + + methodVisitor.visitCode(); + localVaribales.add("this"); + for (ParameterNode parameterNode : methodNode.parameters.parameters) { + localVaribales.add(parameterNode.identifier); + } + + //test(); + methodVisitor.visitMaxs(1, localVaribales.size()); + 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(); + } } From c5bb038fc352b8f049731d4401aaa40193f64b0a Mon Sep 17 00:00:00 2001 From: Bruder John Date: Tue, 14 May 2024 15:31:02 +0200 Subject: [PATCH 3/6] added same Method Declaration --- src/main/java/CompilerInput.txt | 13 ---- src/main/java/Main.java | 20 ++++-- src/main/java/ast/ClassNode.java | 11 ++++ src/main/java/ast/member/MethodNode.java | 16 +++++ .../java/ast/parameter/ParameterListNode.java | 2 +- src/main/java/classFileOutput/Example.class | Bin 131 -> 125 bytes src/main/java/parser/ASTBuilder.java | 6 +- src/main/java/semantic/Scope.java | 4 ++ src/main/java/semantic/SemanticAnalyzer.java | 60 ++++++++++++++++-- .../exeptions/AlreadyDeclearedException.java | 9 +++ src/main/resources/CompilerInput.java | 10 +++ 11 files changed, 123 insertions(+), 28 deletions(-) delete mode 100644 src/main/java/CompilerInput.txt create mode 100644 src/main/java/semantic/exeptions/AlreadyDeclearedException.java create mode 100644 src/main/resources/CompilerInput.java diff --git a/src/main/java/CompilerInput.txt b/src/main/java/CompilerInput.txt deleted file mode 100644 index 918c686..0000000 --- a/src/main/java/CompilerInput.txt +++ /dev/null @@ -1,13 +0,0 @@ -public class Example { - - public int testVar; - - public static int testMethod(char b){ - - int a; - int a; - - - } - -} \ No newline at end of file diff --git a/src/main/java/Main.java b/src/main/java/Main.java index 97ea0ef..a4c274d 100644 --- a/src/main/java/Main.java +++ b/src/main/java/Main.java @@ -16,16 +16,20 @@ import java.nio.file.Paths; public class Main { public static void main(String[] args) throws Exception { - try { - CharStream codeCharStream = CharStreams.fromPath(Paths.get("src/main/java/CompilerInput.txt")); - parseFile(codeCharStream); - } catch (IOException e) { - System.err.println("Error reading the file: " + e.getMessage()); + if(args.length > 0) { + + } else { + try { + CharStream codeCharStream = CharStreams.fromPath(Paths.get("src/main/resources/CompilerInput.java")); + parseFile(codeCharStream); + } catch (IOException e) { + System.err.println("Error reading the file: " + e.getMessage()); + } } } - static void parseFile(CharStream codeCharStream){ + static void parseFile(CharStream codeCharStream) { SimpleJavaLexer lexer = new SimpleJavaLexer(codeCharStream); CommonTokenStream tokens = new CommonTokenStream(lexer); SimpleJavaParser parser = new SimpleJavaParser(tokens); @@ -38,6 +42,8 @@ public class Main { ProgramNode typedAst = (ProgramNode) SemanticAnalyzer.generateTast(ast); ByteCodeGenerator byteCodeGenerator = new ByteCodeGenerator(); - byteCodeGenerator.visit(typedAst); + if (typedAst != null) + byteCodeGenerator.visit(typedAst); } + } \ No newline at end of file diff --git a/src/main/java/ast/ClassNode.java b/src/main/java/ast/ClassNode.java index 947a977..f1f5a4c 100644 --- a/src/main/java/ast/ClassNode.java +++ b/src/main/java/ast/ClassNode.java @@ -2,6 +2,7 @@ package ast; import ast.member.ConstructorNode; import ast.member.MemberNode; +import ast.member.MethodNode; import ast.type.AccessTypeNode; import ast.type.EnumAccessTypeNode; @@ -38,6 +39,16 @@ public class ClassNode implements ASTNode, Visitable { } } + public List getMethods(){ + List methods = new ArrayList<>(); + for (MemberNode member : members) { + if (member instanceof MethodNode methodNode) { + methods.add(methodNode); + } + } + return methods; + } + @Override public TypeCheckResult accept(SemanticVisitor visitor) { return visitor.analyze(this); diff --git a/src/main/java/ast/member/MethodNode.java b/src/main/java/ast/member/MethodNode.java index c50f6af..bd67bc4 100644 --- a/src/main/java/ast/member/MethodNode.java +++ b/src/main/java/ast/member/MethodNode.java @@ -36,6 +36,22 @@ public class MethodNode implements MemberNode, Visitable { this.identifier = identifier; } + public boolean isSame(MethodNode methodNode){ + boolean isSame = false; + if(methodNode.identifier.equals(identifier)){ + if(parameters != null && methodNode.parameters != null){ + if(parameters.parameters.size() == methodNode.parameters.parameters.size()){ + for(int i = 0; i < parameters.parameters.size(); i++){ + if(parameters.parameters.get(i).identifier.equals(methodNode.parameters.parameters.get(i).identifier)){ + isSame = true; + } + } + } + } + } + return isSame; + } + @Override public TypeCheckResult accept(SemanticVisitor visitor) { return visitor.analyze(this); diff --git a/src/main/java/ast/parameter/ParameterListNode.java b/src/main/java/ast/parameter/ParameterListNode.java index 69d12f3..ff1c58d 100644 --- a/src/main/java/ast/parameter/ParameterListNode.java +++ b/src/main/java/ast/parameter/ParameterListNode.java @@ -6,7 +6,7 @@ import java.util.ArrayList; import java.util.List; public class ParameterListNode implements ASTNode { - List parameters = new ArrayList<>(); + public List parameters = new ArrayList<>(); public ParameterListNode(List parameters){ this.parameters = parameters; diff --git a/src/main/java/classFileOutput/Example.class b/src/main/java/classFileOutput/Example.class index c99f3e0a3a2dd9b7fed70513cb143dffa46429a0..925c770cf46b781b3d6401539912811aecebfb50 100644 GIT binary patch delta 11 ScmZo>tes%T#F#kI%@zO@UIRz~ delta 17 Ycmb { AccessTypeNode accessType = (AccessTypeNode) visit(ctx.accessType()); TypeNode returnType = (TypeNode) visit(ctx.type()); String methodName = ctx.IDENTIFIER().getText(); - ParameterListNode parameterListNode = (ParameterListNode) visit(ctx.parameterList()); + + ParameterListNode parameterListNode = null; + if(ctx.parameterList() != null) { + parameterListNode = (ParameterListNode) visit(ctx.parameterList()); + } List statements = new ArrayList<>(); for (SimpleJavaParser.StatementContext stmtCtx : ctx.statement()) { statements.add((StatementNode) visit(stmtCtx)); diff --git a/src/main/java/semantic/Scope.java b/src/main/java/semantic/Scope.java index ab5c0cb..7cf4cc9 100644 --- a/src/main/java/semantic/Scope.java +++ b/src/main/java/semantic/Scope.java @@ -9,6 +9,10 @@ public class Scope { private Stack> localVars; + public Scope() { + localVars = new Stack>(); + } + public void addLocalVar(String name, TypeNode type) { if (this.contains(name)) { throw new RuntimeException("Variable " + name + " already exists in this scope"); diff --git a/src/main/java/semantic/SemanticAnalyzer.java b/src/main/java/semantic/SemanticAnalyzer.java index 7a6002b..e6cdc99 100644 --- a/src/main/java/semantic/SemanticAnalyzer.java +++ b/src/main/java/semantic/SemanticAnalyzer.java @@ -5,32 +5,42 @@ import ast.*; import ast.expression.BinaryExpressionNode; import ast.expression.IdentifierExpressionNode; import ast.expression.UnaryExpressionNode; +import ast.member.ConstructorNode; import ast.member.FieldNode; import ast.member.MemberNode; import ast.member.MethodNode; +import ast.parameter.ParameterListNode; +import ast.parameter.ParameterNode; import ast.statement.*; import java.util.ArrayList; import java.util.List; +import semantic.exeptions.AlreadyDeclearedException; import typechecker.TypeCheckResult; public class SemanticAnalyzer implements SemanticVisitor { private ArrayList currentFields = new ArrayList<>(); - private Scope currentScope; + public static ArrayList errors = new ArrayList<>(); - public static ASTNode generateTast(ASTNode node) throws RuntimeException { + private Scope currentScope; + private ClassNode currentClass; + + public static ASTNode generateTast(ASTNode node) { SemanticAnalyzer semanticCheck = new SemanticAnalyzer(); ProgramNode programNode = (ProgramNode) node; var result = programNode.accept(semanticCheck); if (result.isValid()) { return node; } else { - throw new RuntimeException("Not Valid"); + for (Exception e : errors) { + e.printStackTrace(System.out); + } } + return null; } @Override @@ -38,6 +48,8 @@ public class SemanticAnalyzer implements SemanticVisitor { var valid = true; + currentScope = new Scope(); + List classes = node.classes; for (ClassNode classNode : classes) { var result = classNode.accept(this); @@ -49,12 +61,25 @@ public class SemanticAnalyzer implements SemanticVisitor { @Override public TypeCheckResult analyze(ClassNode classNode) { var valid = true; + + currentClass = classNode; + List members = classNode.members; for (MemberNode memberNode : members) { if (memberNode instanceof FieldNode fieldNode) { + //LocalFields var result = fieldNode.accept(this); valid = valid && result.isValid(); } else if (memberNode instanceof MethodNode methodNode) { + //Methods + for(MethodNode methode : currentClass.getMethods()){ + if(methode.equals(methodNode)) + break; + if(methode.isSame(methodNode)){ + errors.add(new AlreadyDeclearedException("This method has already been declared")); + valid = false; + } + } var result = methodNode.accept(this); valid = valid && result.isValid(); } @@ -68,8 +93,23 @@ public class SemanticAnalyzer implements SemanticVisitor { public TypeCheckResult analyze(MethodNode methodNode) { var valid = true; - currentLocalScope.pushScope(); + currentScope.pushScope(); + //Parameter + ParameterListNode parameterListNode = methodNode.parameters; + if (parameterListNode != null) { + List parameters = parameterListNode.parameters; + for (ParameterNode parameter : parameters) { + if (currentScope.contains(parameter.identifier)) { + errors.add(new AlreadyDeclearedException("Duplicated Parameter " + parameter.identifier)); + return new TypeCheckResult(false, null); + } else { + currentScope.addLocalVar(parameter.identifier, parameter.type); + } + } + } + + //Statements List statements = methodNode.statements; for (StatementNode statement : statements) { if (statement instanceof AssignmentStatementNode assignmentStatementNode) { @@ -80,13 +120,16 @@ public class SemanticAnalyzer implements SemanticVisitor { valid = valid && result.isValid(); } } + + currentScope.popScope(); return new TypeCheckResult(valid, null); } @Override public TypeCheckResult analyze(FieldNode toCheck) { if (currentFields.contains(toCheck.identifier)) { - throw new RuntimeException(toCheck.identifier + " Is Already Declared"); + errors.add(new AlreadyDeclearedException("Already declared " + toCheck.identifier)); + return new TypeCheckResult(false, null); } else { currentFields.add(toCheck.identifier); } @@ -124,7 +167,12 @@ public class SemanticAnalyzer implements SemanticVisitor { @Override public TypeCheckResult analyze(VariableDeclarationStatementNode toCheck) { - + if (currentScope.contains(toCheck.identifier)) { + errors.add(new AlreadyDeclearedException("Already declared " + toCheck.identifier + " in this scope")); + return new TypeCheckResult(false, null); + } else { + currentScope.addLocalVar(toCheck.identifier, toCheck.type); + } return new TypeCheckResult(true, null); } diff --git a/src/main/java/semantic/exeptions/AlreadyDeclearedException.java b/src/main/java/semantic/exeptions/AlreadyDeclearedException.java new file mode 100644 index 0000000..d00fd36 --- /dev/null +++ b/src/main/java/semantic/exeptions/AlreadyDeclearedException.java @@ -0,0 +1,9 @@ +package semantic.exeptions; + +public class AlreadyDeclearedException extends RuntimeException { + + public AlreadyDeclearedException(String message) { + super(message); + } + +} diff --git a/src/main/resources/CompilerInput.java b/src/main/resources/CompilerInput.java new file mode 100644 index 0000000..2efd50e --- /dev/null +++ b/src/main/resources/CompilerInput.java @@ -0,0 +1,10 @@ +public class Example { + + public int a; + + public static int testMethod(char x, int a){ + + + } + +} \ No newline at end of file From 8b9b70b9ee12870a24191f7c165840d03383def7 Mon Sep 17 00:00:00 2001 From: Bruder John Date: Tue, 14 May 2024 17:47:26 +0200 Subject: [PATCH 4/6] Added Test for Semantic Analyzier --- .idea/misc.xml | 2 +- src/main/java/Main.java | 6 +- src/main/java/ast/VarNode.java | 7 +- src/main/java/classFileOutput/Example.class | Bin 125 -> 167 bytes src/main/java/parser/ASTBuilder.java | 2 +- src/main/java/semantic/SemanticAnalyzer.java | 13 ++- src/test/java/semantic/SemanticTester.java | 98 +++++++++++++++++++ 7 files changed, 117 insertions(+), 11 deletions(-) create mode 100644 src/test/java/semantic/SemanticTester.java diff --git a/.idea/misc.xml b/.idea/misc.xml index eddc20d..f26d89f 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -40,7 +40,7 @@ - + \ No newline at end of file diff --git a/src/main/java/Main.java b/src/main/java/Main.java index 91fcd6e..d5aa802 100644 --- a/src/main/java/Main.java +++ b/src/main/java/Main.java @@ -32,7 +32,7 @@ public class Main { } - static void parsefile(CharStream codeCharStream) { + static void parseFile(CharStream codeCharStream) { /* ------------------------- Scanner -> tokens ------------------------- */ SimpleJavaLexer lexer = new SimpleJavaLexer(codeCharStream); CommonTokenStream tokenStream = new CommonTokenStream(lexer); @@ -73,8 +73,8 @@ public class Main { /* * ------------------------- Semantic Analyzer -> Tast ------------------------- */ - SemanticAnalyzer.generateTast(abstractSyntaxTree); - ProgramNode typedAst = (ProgramNode) SemanticAnalyzer.generateTast(abstractSyntaxTree); + SemanticAnalyzer semanticAnalyzer = new SemanticAnalyzer(); + ProgramNode typedAst = (ProgramNode) semanticAnalyzer.generateTast(abstractSyntaxTree); // Printing the Tast System.out.println("Tast generated"); diff --git a/src/main/java/ast/VarNode.java b/src/main/java/ast/VarNode.java index 9349eb4..519f552 100644 --- a/src/main/java/ast/VarNode.java +++ b/src/main/java/ast/VarNode.java @@ -1,5 +1,6 @@ package ast; +import ast.type.TypeNode; import semantic.SemanticVisitor; import typechecker.TypeCheckResult; import visitor.Visitable; @@ -7,14 +8,14 @@ import visitor.Visitable; public class VarNode implements ASTNode, Visitable { private String identifier; - private String type; + private TypeNode type; - public VarNode(String type, String identifier){ + public VarNode(TypeNode type, String identifier){ this.type = type; this.identifier = identifier; } - public String getType(){ + public TypeNode getType(){ return type; } diff --git a/src/main/java/classFileOutput/Example.class b/src/main/java/classFileOutput/Example.class index 925c770cf46b781b3d6401539912811aecebfb50..522ae9edd25429b756d2dd98d755bdedb11f81c3 100644 GIT binary patch delta 125 zcmb!WO3=D=0d=t5hvUwO-8Q8cOSQywD85k3R*prcgt0c9!#5c7hBR_?a zfmOrPQxho2;+&t7%D~9L1XRlaq!}4F8MuHfCLjxF1d!wf@&v&$3=FJV+Zi}E0tG-y Jxfyss3;;S451{}6 delta 83 zcmZ3^Sj%!WO3=Ad=+!MKs92prH6M@*1k%6luwYbDLwIm}yg^__-L(`Lik%5VU c1*jA#&%n;W0c0@&S*#3fU@=YxE+EYS0Lw-TZvX%Q diff --git a/src/main/java/parser/ASTBuilder.java b/src/main/java/parser/ASTBuilder.java index ff41738..e32be97 100644 --- a/src/main/java/parser/ASTBuilder.java +++ b/src/main/java/parser/ASTBuilder.java @@ -144,7 +144,7 @@ public class ASTBuilder extends SimpleJavaBaseVisitor { @Override public ASTNode visitVar(SimpleJavaParser.VarContext ctx) { - return new VarNode("int", ctx.getText()); + return new VarNode(new BaseTypeNode(EnumTypeNode.INT), ctx.getText()); } @Override diff --git a/src/main/java/semantic/SemanticAnalyzer.java b/src/main/java/semantic/SemanticAnalyzer.java index e6cdc99..362af42 100644 --- a/src/main/java/semantic/SemanticAnalyzer.java +++ b/src/main/java/semantic/SemanticAnalyzer.java @@ -22,12 +22,12 @@ import typechecker.TypeCheckResult; public class SemanticAnalyzer implements SemanticVisitor { - private ArrayList currentFields = new ArrayList<>(); + private static ArrayList currentFields = new ArrayList<>(); public static ArrayList errors = new ArrayList<>(); - private Scope currentScope; - private ClassNode currentClass; + private static Scope currentScope; + private static ClassNode currentClass; public static ASTNode generateTast(ASTNode node) { SemanticAnalyzer semanticCheck = new SemanticAnalyzer(); @@ -43,6 +43,13 @@ public class SemanticAnalyzer implements SemanticVisitor { return null; } + public static void clearAnalyzier(){ + currentFields.clear(); + errors.clear(); + currentScope = null; + currentClass = null; + } + @Override public TypeCheckResult analyze(ProgramNode node) { diff --git a/src/test/java/semantic/SemanticTester.java b/src/test/java/semantic/SemanticTester.java new file mode 100644 index 0000000..2c27e1c --- /dev/null +++ b/src/test/java/semantic/SemanticTester.java @@ -0,0 +1,98 @@ +package semantic; + + +import ast.*; +import ast.expression.ExpressionNode; +import ast.member.FieldNode; +import ast.member.MemberNode; +import ast.member.MethodNode; +import ast.parameter.ParameterListNode; +import ast.parameter.ParameterNode; +import ast.statement.AssignmentStatementNode; +import ast.statement.StatementNode; +import ast.type.AccessTypeNode; +import ast.type.BaseTypeNode; +import ast.type.EnumAccessTypeNode; +import ast.type.EnumTypeNode; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import semantic.exeptions.AlreadyDeclearedException; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class SemanticTester { + + @BeforeEach + public void init() { + SemanticAnalyzer.clearAnalyzier(); + } + + @Test + public void alreadyDeclaredLocalFieldVar(){ + + ProgramNode programNode = new ProgramNode(); + List classList = new ArrayList(); + AccessTypeNode accessTypeNode = new AccessTypeNode(EnumAccessTypeNode.PUBLIC); + ClassNode classNode = new ClassNode(accessTypeNode, "testClass"); + + MemberNode memberNode1 = new FieldNode(accessTypeNode, new BaseTypeNode(EnumTypeNode.INT), "testVar"); + classNode.members.add(memberNode1); + + MemberNode memberNode2 = new FieldNode(accessTypeNode, new BaseTypeNode(EnumTypeNode.INT), "testVar"); + classNode.members.add(memberNode2); + + classList.add(classNode); + programNode.classes = classList; + + ASTNode typedAst = SemanticAnalyzer.generateTast(programNode); + + assertEquals(1, SemanticAnalyzer.errors.size()); + assertEquals(true, SemanticAnalyzer.errors.get(0) instanceof AlreadyDeclearedException); + assertEquals(null, typedAst); + + } + + @Test + public void shouldWorkWithNoError(){ + + ProgramNode programNode = new ProgramNode(); + List classList = new ArrayList(); + AccessTypeNode accessTypeNode = new AccessTypeNode(EnumAccessTypeNode.PUBLIC); + ClassNode classNode = new ClassNode(accessTypeNode, "testClass"); + + MemberNode memberNode1 = new FieldNode(accessTypeNode, new BaseTypeNode(EnumTypeNode.INT), "testVar1"); + classNode.members.add(memberNode1); + + MemberNode memberNode2 = new FieldNode(accessTypeNode, new BaseTypeNode(EnumTypeNode.INT), "testVar2"); + classNode.members.add(memberNode2); + + List parameterNodeList = new ArrayList(); + ParameterNode parameterNode1 = new ParameterNode(new BaseTypeNode(EnumTypeNode.INT), "param1"); + parameterNodeList.add(parameterNode1); + ParameterListNode parameterListNode = new ParameterListNode(parameterNodeList); + + List statementNodeList = new ArrayList(); + + VarNode varNode = new VarNode(new BaseTypeNode(EnumTypeNode.INT), "localVar1"); + ExpressionNode expressionNode = new LiteralNode(1); + + StatementNode statementNode1 = new AssignmentStatementNode(varNode, expressionNode); + statementNodeList.add(statementNode1); + + MemberNode memberNode3 = new MethodNode(accessTypeNode, new BaseTypeNode(EnumTypeNode.INT), "testVar2",parameterListNode, statementNodeList ); + classNode.members.add(memberNode3); + + classList.add(classNode); + programNode.classes = classList; + + ASTNode typedAst = SemanticAnalyzer.generateTast(programNode); + + assertEquals(0, SemanticAnalyzer.errors.size()); + assertEquals(programNode, typedAst); + + } + +} From d91e3ad819da108a487296eb24ee8df0c2ee7b9d Mon Sep 17 00:00:00 2001 From: Bruder John Date: Tue, 14 May 2024 17:59:53 +0200 Subject: [PATCH 5/6] added maven test --- .gitea/workflows/test.yml | 15 +++++++++++++++ .../{SemanticTester.java => SemanticTest.java} | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 .gitea/workflows/test.yml rename src/test/java/semantic/{SemanticTester.java => SemanticTest.java} (99%) diff --git a/.gitea/workflows/test.yml b/.gitea/workflows/test.yml new file mode 100644 index 0000000..96ab991 --- /dev/null +++ b/.gitea/workflows/test.yml @@ -0,0 +1,15 @@ +name: Gitea Actions Demo +run-name: ${{ gitea.actor }} is testing out Gitea Actions 🚀 +on: [push] + +jobs: + Explore-Gitea-Actions: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 + with: + java-version: '17' + distribution: 'temurin' + - name: Run the Maven verify phase + run: mvn --batch-mode --update-snapshots verify \ No newline at end of file diff --git a/src/test/java/semantic/SemanticTester.java b/src/test/java/semantic/SemanticTest.java similarity index 99% rename from src/test/java/semantic/SemanticTester.java rename to src/test/java/semantic/SemanticTest.java index 2c27e1c..d35a93f 100644 --- a/src/test/java/semantic/SemanticTester.java +++ b/src/test/java/semantic/SemanticTest.java @@ -23,7 +23,7 @@ import java.util.List; import static org.junit.jupiter.api.Assertions.assertEquals; -public class SemanticTester { +public class SemanticTest { @BeforeEach public void init() { From 403ab706559ff91c954e4fdf218f19ff027b0520 Mon Sep 17 00:00:00 2001 From: Bruder John Date: Thu, 30 May 2024 19:07:29 +0200 Subject: [PATCH 6/6] Adapted Binary Expression --- .idea/misc.xml | 2 +- src/main/java/Main.java | 38 +++++++++---------- src/main/java/ast/VarNode.java | 30 --------------- .../ast/expression/BinaryExpressionNode.java | 4 +- .../ast/expression/ExpresssionOperator.java | 14 +++++++ .../ast/expression/UnaryExpressionNode.java | 2 + .../statement/AssignmentStatementNode.java | 9 ++--- src/main/java/parser/ASTBuilder.java | 12 +++--- src/main/java/semantic/SemanticAnalyzer.java | 18 ++++----- src/main/java/semantic/SemanticVisitor.java | 3 -- src/main/resources/CompilerInput.java | 12 +++++- src/test/java/semantic/SemanticTest.java | 15 ++++++-- 12 files changed, 76 insertions(+), 83 deletions(-) delete mode 100644 src/main/java/ast/VarNode.java create mode 100644 src/main/java/ast/expression/ExpresssionOperator.java diff --git a/.idea/misc.xml b/.idea/misc.xml index f26d89f..bb14756 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -40,7 +40,7 @@ - + \ No newline at end of file diff --git a/src/main/java/Main.java b/src/main/java/Main.java index d5aa802..94d29cf 100644 --- a/src/main/java/Main.java +++ b/src/main/java/Main.java @@ -38,37 +38,37 @@ public class Main { CommonTokenStream tokenStream = new CommonTokenStream(lexer); // Printing the tokens - tokenStream.fill(); - List tokens = tokenStream.getTokens(); - System.out.println("-------------------- Scanner -> tokens --------------------"); - for (Token token : tokens) { - String tokenType = SimpleJavaLexer.VOCABULARY.getSymbolicName(token.getType()); - String tokenText = token.getText(); - // System.out.println("Token Type: " + tokenType + ", Token Text: " + - // tokenText); - System.out.println(tokenType + " " + tokenText); - } - System.out.println(); +// tokenStream.fill(); +// List tokens = tokenStream.getTokens(); +// System.out.println("-------------------- Scanner -> tokens --------------------"); +// for (Token token : tokens) { +// String tokenType = SimpleJavaLexer.VOCABULARY.getSymbolicName(token.getType()); +// String tokenText = token.getText(); +// // System.out.println("Token Type: " + tokenType + ", Token Text: " + +// // tokenText); +// System.out.println(tokenType + " " + tokenText); +// } +// System.out.println(); /* ------------------------- Parser -> Parsetree ------------------------- */ SimpleJavaParser parser = new SimpleJavaParser(tokenStream); ParseTree parseTree = parser.program(); // parse the input // Printing the parse tree - System.out.println("-------------------- Parser -> Parsetree --------------------"); - System.out.println(parseTree.toStringTree(parser)); - printTree(parseTree, parser, 0); - System.out.println(); +// System.out.println("-------------------- Parser -> Parsetree --------------------"); +// System.out.println(parseTree.toStringTree(parser)); +// printTree(parseTree, parser, 0); +// System.out.println(); /* ------------------------- AST builder -> AST ------------------------- */ ASTBuilder astBuilder = new ASTBuilder(); ProgramNode abstractSyntaxTree = (ProgramNode) astBuilder.visit(parseTree); // Printing the AST - System.out.println("-------------------- AST builder -> AST --------------------"); - // System.out.println("AST: " + ast.toString()); - printAST(abstractSyntaxTree, 0); - System.out.println(); +// System.out.println("-------------------- AST builder -> AST --------------------"); +// // System.out.println("AST: " + ast.toString()); +// printAST(abstractSyntaxTree, 0); +// System.out.println(); /* * ------------------------- Semantic Analyzer -> Tast ------------------------- diff --git a/src/main/java/ast/VarNode.java b/src/main/java/ast/VarNode.java deleted file mode 100644 index 519f552..0000000 --- a/src/main/java/ast/VarNode.java +++ /dev/null @@ -1,30 +0,0 @@ -package ast; - -import ast.type.TypeNode; -import semantic.SemanticVisitor; -import typechecker.TypeCheckResult; -import visitor.Visitable; - -public class VarNode implements ASTNode, Visitable { - - private String identifier; - private TypeNode type; - - public VarNode(TypeNode type, String identifier){ - this.type = type; - this.identifier = identifier; - } - - public TypeNode getType(){ - return type; - } - - public String getIdentifier(){ - return identifier; - } - - @Override - public TypeCheckResult accept(SemanticVisitor visitor) { - return visitor.analyze(this); - } -} diff --git a/src/main/java/ast/expression/BinaryExpressionNode.java b/src/main/java/ast/expression/BinaryExpressionNode.java index c912408..e4a0e41 100644 --- a/src/main/java/ast/expression/BinaryExpressionNode.java +++ b/src/main/java/ast/expression/BinaryExpressionNode.java @@ -7,9 +7,9 @@ import visitor.Visitable; public class BinaryExpressionNode implements ExpressionNode, Visitable { public ExpressionNode left; public ExpressionNode right; - public String operator; // Stores the operator as a string (e.g., "+", "-", "&&") + public ExpresssionOperator operator; // Stores the operator as a string (e.g., "+", "-", "&&") - public BinaryExpressionNode(ExpressionNode left, ExpressionNode right, String operator) { + public BinaryExpressionNode(ExpressionNode left, ExpressionNode right, ExpresssionOperator operator) { this.left = left; this.right = right; this.operator = operator; diff --git a/src/main/java/ast/expression/ExpresssionOperator.java b/src/main/java/ast/expression/ExpresssionOperator.java new file mode 100644 index 0000000..b1f62a3 --- /dev/null +++ b/src/main/java/ast/expression/ExpresssionOperator.java @@ -0,0 +1,14 @@ +package ast.expression; + +public enum ExpresssionOperator { + DOT, // . + PLUS, // + + MINUS, // - + MULTIPLY, // * + DIVIDE, // / + NOT, // ! + ASSIGNMENT, // = + EQUALS, // == + UNEQUALS, // != + ERROR //TODO: Remove This +} diff --git a/src/main/java/ast/expression/UnaryExpressionNode.java b/src/main/java/ast/expression/UnaryExpressionNode.java index 24d1832..be1a660 100644 --- a/src/main/java/ast/expression/UnaryExpressionNode.java +++ b/src/main/java/ast/expression/UnaryExpressionNode.java @@ -18,3 +18,5 @@ public class UnaryExpressionNode implements ExpressionNode, Visitable { return visitor.analyze(this); } } + + diff --git a/src/main/java/ast/statement/AssignmentStatementNode.java b/src/main/java/ast/statement/AssignmentStatementNode.java index 9f6a395..f9fd38e 100644 --- a/src/main/java/ast/statement/AssignmentStatementNode.java +++ b/src/main/java/ast/statement/AssignmentStatementNode.java @@ -1,17 +1,14 @@ package ast.statement; -import ast.VarNode; -import ast.expression.ExpressionNode; +import ast.expression.BinaryExpressionNode; import semantic.SemanticVisitor; import typechecker.TypeCheckResult; import visitor.Visitable; public class AssignmentStatementNode extends StatementNode implements Visitable { - public VarNode varNode; - public ExpressionNode expression; + public BinaryExpressionNode expression; - public AssignmentStatementNode(VarNode varNode, ExpressionNode expression) { - this.varNode = varNode; + public AssignmentStatementNode(BinaryExpressionNode expression) { this.expression = expression; } diff --git a/src/main/java/parser/ASTBuilder.java b/src/main/java/parser/ASTBuilder.java index e32be97..0f3b09c 100644 --- a/src/main/java/parser/ASTBuilder.java +++ b/src/main/java/parser/ASTBuilder.java @@ -3,6 +3,7 @@ package parser; import ast.*; import ast.expression.BinaryExpressionNode; import ast.expression.ExpressionNode; +import ast.expression.ExpresssionOperator; import ast.expression.IdentifierExpressionNode; import ast.expression.UnaryExpressionNode; import ast.member.FieldNode; @@ -137,14 +138,14 @@ public class ASTBuilder extends SimpleJavaBaseVisitor { @Override public ASTNode visitAssignmentStatement(SimpleJavaParser.AssignmentStatementContext ctx) { - VarNode varNode = (VarNode) visit(ctx.var()); - ExpressionNode expression = (ExpressionNode) visit(ctx.expression()); - return new AssignmentStatementNode(varNode, expression); + + BinaryExpressionNode expression = (BinaryExpressionNode) visit(ctx.expression()); + return new AssignmentStatementNode(expression); } @Override public ASTNode visitVar(SimpleJavaParser.VarContext ctx) { - return new VarNode(new BaseTypeNode(EnumTypeNode.INT), ctx.getText()); + return null; } @Override @@ -180,8 +181,7 @@ public class ASTBuilder extends SimpleJavaBaseVisitor { if (ctx.getChildCount() == 3 && ctx.getChild(1) instanceof TerminalNode) { ExpressionNode left = (ExpressionNode) visit(ctx.expression(0)); ExpressionNode right = (ExpressionNode) visit(ctx.expression(1)); - String operator = ctx.getChild(1).getText(); - return new BinaryExpressionNode(left, right, operator); + return new BinaryExpressionNode(left, right, ExpresssionOperator.ERROR); } // Handle unary operations else if (ctx.getChildCount() == 2) { diff --git a/src/main/java/semantic/SemanticAnalyzer.java b/src/main/java/semantic/SemanticAnalyzer.java index 362af42..9ccfe98 100644 --- a/src/main/java/semantic/SemanticAnalyzer.java +++ b/src/main/java/semantic/SemanticAnalyzer.java @@ -145,21 +145,17 @@ public class SemanticAnalyzer implements SemanticVisitor { @Override public TypeCheckResult analyze(AssignmentStatementNode assignmentStatementNode) { - if (assignmentStatementNode.expression instanceof LiteralNode literalNode) { - TypeCheckResult varResult = assignmentStatementNode.varNode.accept(this); - TypeCheckResult expressionResult = assignmentStatementNode.expression.accept(this); - } - return new TypeCheckResult(true, null); - } - - @Override - public TypeCheckResult analyze(VarNode toCheck) { - return new TypeCheckResult(true, null); + boolean valid = true; + BinaryExpressionNode binaryExpressionNode = assignmentStatementNode.expression; + var result = binaryExpressionNode.accept(this); + valid = valid && result.isValid(); + return new TypeCheckResult(valid, null); } @Override public TypeCheckResult analyze(BinaryExpressionNode toCheck) { - return null; + boolean valid = true; + return new TypeCheckResult(valid, null); } @Override diff --git a/src/main/java/semantic/SemanticVisitor.java b/src/main/java/semantic/SemanticVisitor.java index 99d0cb8..66db83e 100644 --- a/src/main/java/semantic/SemanticVisitor.java +++ b/src/main/java/semantic/SemanticVisitor.java @@ -3,7 +3,6 @@ package semantic; import ast.ClassNode; import ast.ProgramNode; -import ast.VarNode; import ast.expression.BinaryExpressionNode; import ast.expression.IdentifierExpressionNode; import ast.expression.UnaryExpressionNode; @@ -24,8 +23,6 @@ public interface SemanticVisitor { TypeCheckResult analyze(AssignmentStatementNode toCheck); - TypeCheckResult analyze(VarNode toCheck); - TypeCheckResult analyze(BinaryExpressionNode toCheck); TypeCheckResult analyze(IdentifierExpressionNode toCheck); diff --git a/src/main/resources/CompilerInput.java b/src/main/resources/CompilerInput.java index 2efd50e..1cbe5ca 100644 --- a/src/main/resources/CompilerInput.java +++ b/src/main/resources/CompilerInput.java @@ -2,9 +2,17 @@ public class Example { public int a; - public static int testMethod(char x, int a){ - + public static int testMethod(char x){ } +} + +public class Test { + + public static int testMethod(char x, int a){ + + + + } } \ No newline at end of file diff --git a/src/test/java/semantic/SemanticTest.java b/src/test/java/semantic/SemanticTest.java index d35a93f..83287ca 100644 --- a/src/test/java/semantic/SemanticTest.java +++ b/src/test/java/semantic/SemanticTest.java @@ -2,7 +2,10 @@ package semantic; import ast.*; +import ast.expression.BinaryExpressionNode; import ast.expression.ExpressionNode; +import ast.expression.ExpresssionOperator; +import ast.expression.IdentifierExpressionNode; import ast.member.FieldNode; import ast.member.MemberNode; import ast.member.MethodNode; @@ -76,10 +79,16 @@ public class SemanticTest { List statementNodeList = new ArrayList(); - VarNode varNode = new VarNode(new BaseTypeNode(EnumTypeNode.INT), "localVar1"); - ExpressionNode expressionNode = new LiteralNode(1); + ExpressionNode expressionNodeObjectVariableLeft = new IdentifierExpressionNode("this"); + ExpressionNode expressionNodeObjectVariableRight = new IdentifierExpressionNode("objectVar"); - StatementNode statementNode1 = new AssignmentStatementNode(varNode, expressionNode); + ExpressionNode expressionNodeLeft = new BinaryExpressionNode(expressionNodeObjectVariableLeft, expressionNodeObjectVariableRight, ExpresssionOperator.DOT); + + ExpressionNode expressionNodeRight = new LiteralNode(1); + + BinaryExpressionNode expressionNode = new BinaryExpressionNode(expressionNodeLeft, expressionNodeRight, ExpresssionOperator.ASSIGNMENT); + + StatementNode statementNode1 = new AssignmentStatementNode(expressionNode); statementNodeList.add(statementNode1); MemberNode memberNode3 = new MethodNode(accessTypeNode, new BaseTypeNode(EnumTypeNode.INT), "testVar2",parameterListNode, statementNodeList );