From 1fbec0d754e62b33ec51a718562885e6469f360b Mon Sep 17 00:00:00 2001 From: i22007 Date: Mon, 13 May 2024 20:15:17 +0200 Subject: [PATCH 1/7] First try with visitors --- src/main/java/Main.java | 2 +- src/main/java/ast/ClassNode.java | 9 ++++++++- src/main/java/ast/ProgramNode.java | 9 ++++++++- src/main/java/bytecode/ByteCodeGenerator.java | 10 ++++++---- src/main/java/bytecode/ClassCodeGen.java | 11 ++++++++--- src/main/java/bytecode/visitor/ClassVisitor.java | 7 +++++++ src/main/java/bytecode/visitor/ProgramVisitor.java | 7 +++++++ src/main/java/bytecode/visitor/Visitable.java | 11 +++++++++++ 8 files changed, 56 insertions(+), 10 deletions(-) create mode 100644 src/main/java/bytecode/visitor/ClassVisitor.java create mode 100644 src/main/java/bytecode/visitor/ProgramVisitor.java create mode 100644 src/main/java/bytecode/visitor/Visitable.java diff --git a/src/main/java/Main.java b/src/main/java/Main.java index bcb48c5..fd3f22a 100644 --- a/src/main/java/Main.java +++ b/src/main/java/Main.java @@ -48,6 +48,6 @@ public class Main { semanticAnalyzer.analyze(ast); ByteCodeGenerator byteCodeGenerator = new ByteCodeGenerator(); - byteCodeGenerator.generateByteCode(ast); + byteCodeGenerator.visit(ast); } } \ No newline at end of file diff --git a/src/main/java/ast/ClassNode.java b/src/main/java/ast/ClassNode.java index 2f27d08..a8e5516 100644 --- a/src/main/java/ast/ClassNode.java +++ b/src/main/java/ast/ClassNode.java @@ -5,10 +5,12 @@ import ast.member.MemberNode; import ast.type.AccessTypeNode; import ast.type.EnumAccessTypeNode; +import bytecode.visitor.ClassVisitor; +import bytecode.visitor.Visitable; import java.util.ArrayList; import java.util.List; -public class ClassNode extends ASTNode{ +public class ClassNode extends ASTNode implements Visitable { public IdentifierNode identifier; public AccessTypeNode accessType; public String name; @@ -33,4 +35,9 @@ public class ClassNode extends ASTNode{ members.add(0,constructor); } } + + @Override + public void accept(ClassVisitor classVisitor) { + classVisitor.visit(this); + } } diff --git a/src/main/java/ast/ProgramNode.java b/src/main/java/ast/ProgramNode.java index 1fcc193..85c0682 100644 --- a/src/main/java/ast/ProgramNode.java +++ b/src/main/java/ast/ProgramNode.java @@ -1,12 +1,19 @@ package ast; +import bytecode.visitor.ProgramVisitor; +import bytecode.visitor.Visitable; import java.util.ArrayList; import java.util.List; -public class ProgramNode extends ASTNode { +public class ProgramNode extends ASTNode implements Visitable { public List classes = new ArrayList<>(); public void addClass(ClassNode classNode) { classes.add(classNode); } + + @Override + public void accept(ProgramVisitor programVisitor) { + programVisitor.visit(this); + } } \ No newline at end of file diff --git a/src/main/java/bytecode/ByteCodeGenerator.java b/src/main/java/bytecode/ByteCodeGenerator.java index 0846386..5494255 100644 --- a/src/main/java/bytecode/ByteCodeGenerator.java +++ b/src/main/java/bytecode/ByteCodeGenerator.java @@ -2,13 +2,15 @@ package bytecode; import ast.ProgramNode; import ast.ClassNode; +import bytecode.visitor.ProgramVisitor; -public class ByteCodeGenerator { +public class ByteCodeGenerator implements ProgramVisitor { - public void generateByteCode(ProgramNode ast) { - for (ClassNode classDeclarationNode : ast.classes) { + @Override + public void visit(ProgramNode programNode) { + for (ClassNode classDeclarationNode : programNode.classes) { ClassCodeGen classCodeGen = new ClassCodeGen(); - classCodeGen.generateClassCode(classDeclarationNode); + classDeclarationNode.accept(classCodeGen); } } } diff --git a/src/main/java/bytecode/ClassCodeGen.java b/src/main/java/bytecode/ClassCodeGen.java index 1e931c0..d278901 100644 --- a/src/main/java/bytecode/ClassCodeGen.java +++ b/src/main/java/bytecode/ClassCodeGen.java @@ -1,9 +1,12 @@ package bytecode; import ast.ClassNode; +import ast.ProgramNode; import ast.member.FieldNode; import ast.member.MemberNode; import ast.member.MethodNode; +import bytecode.visitor.ClassVisitor; +import bytecode.visitor.ProgramVisitor; import java.io.File; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.Opcodes; @@ -11,12 +14,14 @@ import org.objectweb.asm.Opcodes; import java.io.FileOutputStream; import java.io.IOException; -public class ClassCodeGen { - public void generateClassCode(ClassNode classNode) { +public class ClassCodeGen implements ClassVisitor { + + @Override + public void visit(ClassNode classNode) { ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); Mapper mapper = new Mapper(); classWriter.visit(Opcodes.V1_8, mapper.mapAccesTypeToOpcode(classNode.accessType), classNode.name, null, - "java/lang/Object", null); + "java/lang/Object", null); for (MemberNode memberNode : classNode.members) { if (memberNode instanceof FieldNode) { diff --git a/src/main/java/bytecode/visitor/ClassVisitor.java b/src/main/java/bytecode/visitor/ClassVisitor.java new file mode 100644 index 0000000..85d1c15 --- /dev/null +++ b/src/main/java/bytecode/visitor/ClassVisitor.java @@ -0,0 +1,7 @@ +package bytecode.visitor; + +import ast.ClassNode; + +public interface ClassVisitor { + void visit(ClassNode classNode); +} diff --git a/src/main/java/bytecode/visitor/ProgramVisitor.java b/src/main/java/bytecode/visitor/ProgramVisitor.java new file mode 100644 index 0000000..d569ec6 --- /dev/null +++ b/src/main/java/bytecode/visitor/ProgramVisitor.java @@ -0,0 +1,7 @@ +package bytecode.visitor; + +import ast.ProgramNode; + +public interface ProgramVisitor { + void visit(ProgramNode programNode); +} diff --git a/src/main/java/bytecode/visitor/Visitable.java b/src/main/java/bytecode/visitor/Visitable.java new file mode 100644 index 0000000..af7a369 --- /dev/null +++ b/src/main/java/bytecode/visitor/Visitable.java @@ -0,0 +1,11 @@ +package bytecode.visitor; + +public interface Visitable { + + default void accept(ProgramVisitor programVisitor) { + + } + default void accept(ClassVisitor classVisitor) { + + } +} From d27ec0643ae85466a120d2fcafb3100f200e443d Mon Sep 17 00:00:00 2001 From: i22007 Date: Tue, 14 May 2024 10:58:04 +0200 Subject: [PATCH 2/7] Add visitor for class code generation --- src/main/java/ast/ClassNode.java | 9 ++++-- src/main/java/ast/ProgramNode.java | 11 +++++-- src/main/java/ast/member/ConstructorNode.java | 9 +++++- src/main/java/ast/member/FieldNode.java | 6 ++++ src/main/java/ast/member/MethodNode.java | 7 +++++ src/main/java/bytecode/ClassCodeGen.java | 20 +++++++----- src/main/java/bytecode/Mapper.java | 24 +++++++++++++++ src/main/java/bytecode/MethodCodeGen.java | 29 +++++++++++++++--- .../java/bytecode/visitor/ClassVisitor.java | 3 ++ .../java/bytecode/visitor/MethodVisitor.java | 9 ++++++ src/main/java/bytecode/visitor/Visitable.java | 11 ------- src/main/java/classFileOutput/Example.class | Bin 111 -> 132 bytes src/main/java/typechecker/Visitable.java | 20 +++++++----- 13 files changed, 121 insertions(+), 37 deletions(-) create mode 100644 src/main/java/bytecode/visitor/MethodVisitor.java delete mode 100644 src/main/java/bytecode/visitor/Visitable.java diff --git a/src/main/java/ast/ClassNode.java b/src/main/java/ast/ClassNode.java index b7cde2e..654b745 100644 --- a/src/main/java/ast/ClassNode.java +++ b/src/main/java/ast/ClassNode.java @@ -5,10 +5,10 @@ import ast.member.MemberNode; import ast.type.AccessTypeNode; import ast.type.EnumAccessTypeNode; -import bytecode.visitor.ClassVisitor; -import bytecode.visitor.Visitable; import java.util.ArrayList; import java.util.List; + +import bytecode.visitor.ClassVisitor; import semantic.SemanticVisitor; import typechecker.TypeCheckResult; import typechecker.Visitable; @@ -42,4 +42,9 @@ public class ClassNode extends ASTNode implements Visitable { public TypeCheckResult accept(SemanticVisitor visitor) { return visitor.typeCheck(this); } + + @Override + public void accept(ClassVisitor classVisitor) { + classVisitor.visit(this); + } } diff --git a/src/main/java/ast/ProgramNode.java b/src/main/java/ast/ProgramNode.java index c76ce42..cdfdd34 100644 --- a/src/main/java/ast/ProgramNode.java +++ b/src/main/java/ast/ProgramNode.java @@ -1,14 +1,14 @@ package ast; -import bytecode.visitor.ProgramVisitor; -import bytecode.visitor.Visitable; import java.util.ArrayList; import java.util.List; + +import bytecode.visitor.ProgramVisitor; import semantic.SemanticVisitor; import typechecker.TypeCheckResult; import typechecker.Visitable; -public class ProgramNode extends ASTNode implements Visitable{ +public class ProgramNode extends ASTNode implements Visitable { public List classes = new ArrayList<>(); public void addClass(ClassNode classNode) { @@ -19,4 +19,9 @@ public class ProgramNode extends ASTNode implements Visitable{ public TypeCheckResult accept(SemanticVisitor visitor) { return visitor.typeCheck(this); } + + @Override + public void accept(ProgramVisitor programVisitor) { + programVisitor.visit(this); + } } \ No newline at end of file diff --git a/src/main/java/ast/member/ConstructorNode.java b/src/main/java/ast/member/ConstructorNode.java index b411ff1..c729dc1 100644 --- a/src/main/java/ast/member/ConstructorNode.java +++ b/src/main/java/ast/member/ConstructorNode.java @@ -1,9 +1,16 @@ package ast.member; import ast.type.AccessTypeNode; +import bytecode.visitor.MethodVisitor; +import typechecker.Visitable; -public class ConstructorNode extends MethodNode { +public class ConstructorNode extends MethodNode implements Visitable { public ConstructorNode(AccessTypeNode visibility, String name) { super(visibility, name); } + + @Override + public void accept(MethodVisitor methodVisitor) { + methodVisitor.visit(this); + } } diff --git a/src/main/java/ast/member/FieldNode.java b/src/main/java/ast/member/FieldNode.java index cfefdfc..cbb70d4 100644 --- a/src/main/java/ast/member/FieldNode.java +++ b/src/main/java/ast/member/FieldNode.java @@ -2,6 +2,7 @@ package ast.member; import ast.type.AccessTypeNode; import ast.type.TypeNode; +import bytecode.visitor.ClassVisitor; import semantic.SemanticVisitor; import typechecker.TypeCheckResult; import typechecker.Visitable; @@ -21,4 +22,9 @@ public class FieldNode extends MemberNode implements Visitable { public TypeCheckResult accept(SemanticVisitor visitor) { return visitor.typeCheck(this); } + + @Override + public void accept(ClassVisitor classVisitor) { + classVisitor.visit(this); + } } diff --git a/src/main/java/ast/member/MethodNode.java b/src/main/java/ast/member/MethodNode.java index 122eb5e..3bc7732 100644 --- a/src/main/java/ast/member/MethodNode.java +++ b/src/main/java/ast/member/MethodNode.java @@ -7,6 +7,8 @@ import ast.type.TypeNode; import java.util.ArrayList; import java.util.List; + +import bytecode.visitor.MethodVisitor; import semantic.SemanticVisitor; import typechecker.TypeCheckResult; import typechecker.Visitable; @@ -38,4 +40,9 @@ public class MethodNode extends MemberNode implements Visitable { public TypeCheckResult accept(SemanticVisitor visitor) { return visitor.typeCheck(this); } + + @Override + public void accept(MethodVisitor methodVisitor) { + methodVisitor.visit(this); + } } diff --git a/src/main/java/bytecode/ClassCodeGen.java b/src/main/java/bytecode/ClassCodeGen.java index dfdf2c6..59be9ee 100644 --- a/src/main/java/bytecode/ClassCodeGen.java +++ b/src/main/java/bytecode/ClassCodeGen.java @@ -1,12 +1,10 @@ package bytecode; import ast.ClassNode; -import ast.ProgramNode; import ast.member.FieldNode; import ast.member.MemberNode; import ast.member.MethodNode; import bytecode.visitor.ClassVisitor; -import bytecode.visitor.ProgramVisitor; import java.io.File; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.Opcodes; @@ -15,21 +13,21 @@ import java.io.FileOutputStream; import java.io.IOException; public class ClassCodeGen implements ClassVisitor { + Mapper mapper = new Mapper(); + ClassWriter classWriter; @Override public void visit(ClassNode classNode) { - ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); - Mapper mapper = new Mapper(); + classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); classWriter.visit(Opcodes.V1_8, mapper.mapAccesTypeToOpcode(classNode.accessType), classNode.identifier, null, "java/lang/Object", null); for (MemberNode memberNode : classNode.members) { if (memberNode instanceof FieldNode) { - FieldCodeGen fieldCodeGen = new FieldCodeGen(); - fieldCodeGen.generateFieldCode(classWriter, (FieldNode) memberNode); + visit((FieldNode) memberNode); } else if (memberNode instanceof MethodNode) { - MethodCodeGen methodCodeGen = new MethodCodeGen(); - methodCodeGen.generateMethodCode(classWriter, (MethodNode) memberNode); + MethodCodeGen methodCodeGen = new MethodCodeGen(classWriter); + ((MethodNode) memberNode).accept(methodCodeGen); } } @@ -39,6 +37,12 @@ public class ClassCodeGen implements ClassVisitor { classWriter.visitEnd(); } + @Override + public void visit(FieldNode fieldNode) { + classWriter.visitField(mapper.mapAccesTypeToOpcode(fieldNode.accessTypeNode), fieldNode.identifier, mapper.getTypeChar(fieldNode.type.enumTypeNode), null, null ); + classWriter.visitEnd(); + } + private void printIntoClassFile(byte[] byteCode, String name) { String directoryPath = "src/main/java/classFileOutput"; File directory = new File(directoryPath); diff --git a/src/main/java/bytecode/Mapper.java b/src/main/java/bytecode/Mapper.java index 168e1e2..7f1b219 100644 --- a/src/main/java/bytecode/Mapper.java +++ b/src/main/java/bytecode/Mapper.java @@ -2,6 +2,8 @@ package bytecode; import ast.type.AccessTypeNode; import ast.type.EnumAccessTypeNode; +import ast.type.EnumTypeNode; +import ast.type.TypeNode; import org.objectweb.asm.Opcodes; public class Mapper { @@ -14,4 +16,26 @@ public class Mapper { } return 0; } + + public String generateMethodDescriptor(TypeNode typeNode) { + String descriptor = "()"; + descriptor += getTypeChar(typeNode.enumTypeNode); + return descriptor; + } + + public String getTypeChar(EnumTypeNode enumTypeNode) { + String typeChar = ""; + switch (enumTypeNode) { + case EnumTypeNode.INT: + typeChar = "I"; + break; + case EnumTypeNode.CHAR: + typeChar = "C"; + break; + case EnumTypeNode.BOOLEAN: + typeChar = "Z"; + break; + } + return typeChar; + } } diff --git a/src/main/java/bytecode/MethodCodeGen.java b/src/main/java/bytecode/MethodCodeGen.java index 066905f..fd8a29a 100644 --- a/src/main/java/bytecode/MethodCodeGen.java +++ b/src/main/java/bytecode/MethodCodeGen.java @@ -1,17 +1,38 @@ package bytecode; +import ast.member.ConstructorNode; import ast.member.MethodNode; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.MethodVisitor; -public class MethodCodeGen { - public void generateMethodCode(ClassWriter classWriter, MethodNode methodNode) { - Mapper mapper = new Mapper(); +public class MethodCodeGen implements bytecode.visitor.MethodVisitor { + + private ClassWriter classWriter; + Mapper mapper = new Mapper(); + + public MethodCodeGen(ClassWriter classWriter) { + this.classWriter = classWriter; + } + + @Override + public void visit(ConstructorNode constructorNode) { MethodVisitor constructor = - classWriter.visitMethod(mapper.mapAccesTypeToOpcode(methodNode.visibility), + classWriter.visitMethod(mapper.mapAccesTypeToOpcode(constructorNode.visibility), "", "()V", null, null); + constructor.visitEnd(); + } + + @Override + public void visit(MethodNode methodNode) { + MethodVisitor method = classWriter.visitMethod(mapper.mapAccesTypeToOpcode(methodNode.visibility), + methodNode.identifier, + mapper.generateMethodDescriptor(methodNode.type), + null, + null); + + method.visitEnd(); } } diff --git a/src/main/java/bytecode/visitor/ClassVisitor.java b/src/main/java/bytecode/visitor/ClassVisitor.java index 85d1c15..98ef25c 100644 --- a/src/main/java/bytecode/visitor/ClassVisitor.java +++ b/src/main/java/bytecode/visitor/ClassVisitor.java @@ -1,7 +1,10 @@ package bytecode.visitor; import ast.ClassNode; +import ast.member.FieldNode; +import org.objectweb.asm.ClassWriter; public interface ClassVisitor { void visit(ClassNode classNode); + void visit(FieldNode fieldNode); } diff --git a/src/main/java/bytecode/visitor/MethodVisitor.java b/src/main/java/bytecode/visitor/MethodVisitor.java new file mode 100644 index 0000000..70177ce --- /dev/null +++ b/src/main/java/bytecode/visitor/MethodVisitor.java @@ -0,0 +1,9 @@ +package bytecode.visitor; + +import ast.member.ConstructorNode; +import ast.member.MethodNode; + +public interface MethodVisitor { + void visit(ConstructorNode constructorNode); + void visit(MethodNode methodNode); +} diff --git a/src/main/java/bytecode/visitor/Visitable.java b/src/main/java/bytecode/visitor/Visitable.java deleted file mode 100644 index af7a369..0000000 --- a/src/main/java/bytecode/visitor/Visitable.java +++ /dev/null @@ -1,11 +0,0 @@ -package bytecode.visitor; - -public interface Visitable { - - default void accept(ProgramVisitor programVisitor) { - - } - default void accept(ClassVisitor classVisitor) { - - } -} diff --git a/src/main/java/classFileOutput/Example.class b/src/main/java/classFileOutput/Example.class index c0d9270e1638a12598a097c3a813e0adcc1b821b..e2994804a9b99ea9c567e9caec4c6109835e84dc 100644 GIT binary patch delta 67 zcmd0AVdOgXZ`VEs1_l!b?ulG_YAhO>!C{OH>?NtiC1Ht0j0}vPj0{{Lo^NVNMt%w- T1G9!^)I?8tc1{K^pf&~oVSo>n delta 46 zcmZo+%;!4wZ`VEs1_l!b&WT)lg3KD4VT=syC8@ Date: Tue, 14 May 2024 11:19:31 +0200 Subject: [PATCH 3/7] changed to interfaces --- .idea/misc.xml | 2 +- src/main/java/CompilerInput.txt | 4 +++- src/main/java/ast/ASTNode.java | 2 +- src/main/java/ast/ClassNode.java | 4 ++-- src/main/java/ast/ProgramNode.java | 4 ++-- src/main/java/ast/VarNode.java | 2 +- src/main/java/ast/expression/ExpressionNode.java | 2 +- src/main/java/ast/member/FieldNode.java | 4 ++-- src/main/java/ast/member/MemberNode.java | 2 +- src/main/java/ast/member/MethodNode.java | 4 ++-- src/main/java/ast/parameter/ParameterListNode.java | 2 +- src/main/java/ast/parameter/ParameterNode.java | 2 +- .../java/ast/statement/AssignmentStatementNode.java | 2 +- src/main/java/ast/statement/StatementNode.java | 2 +- src/main/java/ast/type/AccessTypeNode.java | 2 +- src/main/java/ast/type/BaseTypeNode.java | 11 +++++++++++ src/main/java/ast/type/ReferenceTypeNode.java | 4 ++++ src/main/java/ast/type/TypeNode.java | 7 +------ src/main/java/parser/ASTBuilder.java | 11 ++++------- src/main/java/semantic/SemanticAnalyzer.java | 12 ++++++------ src/main/java/semantic/SemanticVisitor.java | 10 +++++----- 21 files changed, 52 insertions(+), 43 deletions(-) create mode 100644 src/main/java/ast/type/BaseTypeNode.java create mode 100644 src/main/java/ast/type/ReferenceTypeNode.java diff --git a/.idea/misc.xml b/.idea/misc.xml index bb14756..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/CompilerInput.txt b/src/main/java/CompilerInput.txt index 49da971..b784cf7 100644 --- a/src/main/java/CompilerInput.txt +++ b/src/main/java/CompilerInput.txt @@ -5,7 +5,9 @@ public class Example { public static int testMethod(char b){ int a; - a = 3; + boolean b; + char c; + b = 3; } diff --git a/src/main/java/ast/ASTNode.java b/src/main/java/ast/ASTNode.java index 9c5880e..9944050 100644 --- a/src/main/java/ast/ASTNode.java +++ b/src/main/java/ast/ASTNode.java @@ -1,6 +1,6 @@ package ast; -public class ASTNode { +public interface ASTNode { } diff --git a/src/main/java/ast/ClassNode.java b/src/main/java/ast/ClassNode.java index c57a400..dacd4b4 100644 --- a/src/main/java/ast/ClassNode.java +++ b/src/main/java/ast/ClassNode.java @@ -11,7 +11,7 @@ import semantic.SemanticVisitor; import typechecker.TypeCheckResult; import typechecker.Visitable; -public class ClassNode extends ASTNode implements Visitable { +public class ClassNode implements ASTNode, Visitable { public String identifier; public AccessTypeNode accessType; public List members = new ArrayList<>(); @@ -38,6 +38,6 @@ public class ClassNode extends ASTNode implements Visitable { @Override public TypeCheckResult accept(SemanticVisitor visitor) { - return visitor.typeCheck(this); + return visitor.analyze(this); } } diff --git a/src/main/java/ast/ProgramNode.java b/src/main/java/ast/ProgramNode.java index 3d0af61..44b1ad2 100644 --- a/src/main/java/ast/ProgramNode.java +++ b/src/main/java/ast/ProgramNode.java @@ -6,7 +6,7 @@ import semantic.SemanticVisitor; import typechecker.TypeCheckResult; import typechecker.Visitable; -public class ProgramNode extends ASTNode implements Visitable{ +public class ProgramNode implements ASTNode, Visitable{ public List classes = new ArrayList<>(); public void addClass(ClassNode classNode) { @@ -15,6 +15,6 @@ public class ProgramNode extends ASTNode implements Visitable{ @Override public TypeCheckResult accept(SemanticVisitor visitor) { - return visitor.typeCheck(this); + return visitor.analyze(this); } } \ No newline at end of file diff --git a/src/main/java/ast/VarNode.java b/src/main/java/ast/VarNode.java index a3ac170..e27f080 100644 --- a/src/main/java/ast/VarNode.java +++ b/src/main/java/ast/VarNode.java @@ -1,6 +1,6 @@ package ast; -public class VarNode extends ASTNode{ +public class VarNode implements ASTNode{ private String identifier; private String type; diff --git a/src/main/java/ast/expression/ExpressionNode.java b/src/main/java/ast/expression/ExpressionNode.java index 8204bed..5dbead0 100644 --- a/src/main/java/ast/expression/ExpressionNode.java +++ b/src/main/java/ast/expression/ExpressionNode.java @@ -2,7 +2,7 @@ package ast.expression; import ast.ASTNode; -public class ExpressionNode extends ASTNode { +public class ExpressionNode implements ASTNode { diff --git a/src/main/java/ast/member/FieldNode.java b/src/main/java/ast/member/FieldNode.java index cfefdfc..2525171 100644 --- a/src/main/java/ast/member/FieldNode.java +++ b/src/main/java/ast/member/FieldNode.java @@ -6,7 +6,7 @@ import semantic.SemanticVisitor; import typechecker.TypeCheckResult; import typechecker.Visitable; -public class FieldNode extends MemberNode implements Visitable { +public class FieldNode implements MemberNode, Visitable { public AccessTypeNode accessTypeNode; public TypeNode type; public String identifier; @@ -19,6 +19,6 @@ public class FieldNode extends MemberNode implements Visitable { @Override public TypeCheckResult accept(SemanticVisitor visitor) { - return visitor.typeCheck(this); + return visitor.analyze(this); } } diff --git a/src/main/java/ast/member/MemberNode.java b/src/main/java/ast/member/MemberNode.java index aa823af..f186835 100644 --- a/src/main/java/ast/member/MemberNode.java +++ b/src/main/java/ast/member/MemberNode.java @@ -2,5 +2,5 @@ package ast.member; import ast.ASTNode; -public class MemberNode extends ASTNode { +public interface MemberNode extends ASTNode { } diff --git a/src/main/java/ast/member/MethodNode.java b/src/main/java/ast/member/MethodNode.java index 122eb5e..ae6ef68 100644 --- a/src/main/java/ast/member/MethodNode.java +++ b/src/main/java/ast/member/MethodNode.java @@ -11,7 +11,7 @@ import semantic.SemanticVisitor; import typechecker.TypeCheckResult; import typechecker.Visitable; -public class MethodNode extends MemberNode implements Visitable { +public class MethodNode implements MemberNode, Visitable { public AccessTypeNode visibility; public TypeNode type; public String identifier; @@ -36,6 +36,6 @@ public class MethodNode extends MemberNode implements Visitable { @Override public TypeCheckResult accept(SemanticVisitor visitor) { - return visitor.typeCheck(this); + return visitor.analyze(this); } } diff --git a/src/main/java/ast/parameter/ParameterListNode.java b/src/main/java/ast/parameter/ParameterListNode.java index 34c615a..69d12f3 100644 --- a/src/main/java/ast/parameter/ParameterListNode.java +++ b/src/main/java/ast/parameter/ParameterListNode.java @@ -5,7 +5,7 @@ import ast.ASTNode; import java.util.ArrayList; import java.util.List; -public class ParameterListNode extends ASTNode { +public class ParameterListNode implements ASTNode { List parameters = new ArrayList<>(); public ParameterListNode(List parameters){ diff --git a/src/main/java/ast/parameter/ParameterNode.java b/src/main/java/ast/parameter/ParameterNode.java index 739ae21..f3f5193 100644 --- a/src/main/java/ast/parameter/ParameterNode.java +++ b/src/main/java/ast/parameter/ParameterNode.java @@ -3,7 +3,7 @@ package ast.parameter; import ast.ASTNode; import ast.type.TypeNode; -public class ParameterNode extends ASTNode { +public class ParameterNode implements ASTNode { public TypeNode type; public String identifier; diff --git a/src/main/java/ast/statement/AssignmentStatementNode.java b/src/main/java/ast/statement/AssignmentStatementNode.java index b9158e7..7efbd73 100644 --- a/src/main/java/ast/statement/AssignmentStatementNode.java +++ b/src/main/java/ast/statement/AssignmentStatementNode.java @@ -17,6 +17,6 @@ public class AssignmentStatementNode extends StatementNode implements Visitable @Override public TypeCheckResult accept(SemanticVisitor visitor) { - return visitor.typeCheck(this); + return visitor.analyze(this); } } diff --git a/src/main/java/ast/statement/StatementNode.java b/src/main/java/ast/statement/StatementNode.java index 910a134..6c90f8c 100644 --- a/src/main/java/ast/statement/StatementNode.java +++ b/src/main/java/ast/statement/StatementNode.java @@ -2,6 +2,6 @@ package ast.statement; import ast.ASTNode; -public abstract class StatementNode extends ASTNode { +public abstract class StatementNode implements ASTNode { } diff --git a/src/main/java/ast/type/AccessTypeNode.java b/src/main/java/ast/type/AccessTypeNode.java index ddacf68..ba156c1 100644 --- a/src/main/java/ast/type/AccessTypeNode.java +++ b/src/main/java/ast/type/AccessTypeNode.java @@ -2,7 +2,7 @@ package ast.type; import ast.ASTNode; -public class AccessTypeNode extends ASTNode { +public class AccessTypeNode implements ASTNode { public EnumAccessTypeNode enumAccessTypeNode; public AccessTypeNode(EnumAccessTypeNode enumAccessTypeNode) { diff --git a/src/main/java/ast/type/BaseTypeNode.java b/src/main/java/ast/type/BaseTypeNode.java new file mode 100644 index 0000000..81cdf43 --- /dev/null +++ b/src/main/java/ast/type/BaseTypeNode.java @@ -0,0 +1,11 @@ +package ast.type; + +public class BaseTypeNode implements TypeNode{ + + public EnumTypeNode enumType; + + public BaseTypeNode(EnumTypeNode enumType) { + this.enumType = enumType; + } + +} diff --git a/src/main/java/ast/type/ReferenceTypeNode.java b/src/main/java/ast/type/ReferenceTypeNode.java new file mode 100644 index 0000000..1937054 --- /dev/null +++ b/src/main/java/ast/type/ReferenceTypeNode.java @@ -0,0 +1,4 @@ +package ast.type; + +public class ReferenceTypeNode implements TypeNode{ +} diff --git a/src/main/java/ast/type/TypeNode.java b/src/main/java/ast/type/TypeNode.java index 5b1c2a6..79be9c9 100644 --- a/src/main/java/ast/type/TypeNode.java +++ b/src/main/java/ast/type/TypeNode.java @@ -2,10 +2,5 @@ package ast.type; import ast.ASTNode; -public class TypeNode extends ASTNode { - public EnumTypeNode enumTypeNode; - - public TypeNode(EnumTypeNode enumTypeNode) { - this.enumTypeNode = enumTypeNode; - } +public interface TypeNode extends ASTNode { } \ No newline at end of file diff --git a/src/main/java/parser/ASTBuilder.java b/src/main/java/parser/ASTBuilder.java index 87b0238..1e8cbc3 100644 --- a/src/main/java/parser/ASTBuilder.java +++ b/src/main/java/parser/ASTBuilder.java @@ -11,10 +11,7 @@ import ast.member.MethodNode; import ast.parameter.ParameterListNode; import ast.parameter.ParameterNode; import ast.statement.*; -import ast.type.AccessTypeNode; -import ast.type.EnumAccessTypeNode; -import ast.type.EnumTypeNode; -import ast.type.TypeNode; +import ast.type.*; import org.antlr.v4.runtime.tree.TerminalNode; import java.util.ArrayList; import java.util.List; @@ -87,11 +84,11 @@ public class ASTBuilder extends SimpleJavaBaseVisitor { String typeStr = ctx.getText(); switch (typeStr) { case "int": - return new TypeNode(EnumTypeNode.INT); + return new BaseTypeNode(EnumTypeNode.INT); case "boolean": - return new TypeNode(EnumTypeNode.BOOLEAN); + return new BaseTypeNode(EnumTypeNode.BOOLEAN); case "char": - return new TypeNode(EnumTypeNode.CHAR); + return new BaseTypeNode(EnumTypeNode.CHAR); default: throw new IllegalArgumentException("Unsupported type: " + typeStr); } diff --git a/src/main/java/semantic/SemanticAnalyzer.java b/src/main/java/semantic/SemanticAnalyzer.java index 07d0ca2..d499be2 100644 --- a/src/main/java/semantic/SemanticAnalyzer.java +++ b/src/main/java/semantic/SemanticAnalyzer.java @@ -30,7 +30,7 @@ public class SemanticAnalyzer implements SemanticVisitor { } @Override - public TypeCheckResult typeCheck(ProgramNode node) { + public TypeCheckResult analyze(ProgramNode node) { var valid = true; @@ -42,7 +42,7 @@ public class SemanticAnalyzer implements SemanticVisitor { } @Override - public TypeCheckResult typeCheck(ClassNode classNode) { + public TypeCheckResult analyze(ClassNode classNode) { List members = classNode.members; for (MemberNode memberNode : members) { if (memberNode instanceof FieldNode fieldNode) { @@ -56,7 +56,7 @@ public class SemanticAnalyzer implements SemanticVisitor { } @Override - public TypeCheckResult typeCheck(MethodNode methodNode) { + public TypeCheckResult analyze(MethodNode methodNode) { List statements = methodNode.statements; for (StatementNode statement : statements) { if(statement instanceof AssignmentStatementNode assignmentStatementNode) { @@ -67,7 +67,7 @@ public class SemanticAnalyzer implements SemanticVisitor { } @Override - public TypeCheckResult typeCheck(FieldNode toCheck) { + public TypeCheckResult analyze(FieldNode toCheck) { if(currentFields.contains(toCheck.identifier)){ throw new RuntimeException(toCheck.identifier + " Is Already Declared"); }else { @@ -77,13 +77,13 @@ public class SemanticAnalyzer implements SemanticVisitor { } @Override - public TypeCheckResult typeCheck(AssignmentStatementNode assignmentStatementNode) { + public TypeCheckResult analyze(AssignmentStatementNode assignmentStatementNode) { if(assignmentStatementNode.expression instanceof LiteralNode literalNode) { VarNode varNode = assignmentStatementNode.varNode; if(varNode.getType().equals(literalNode.getType())) { System.out.println("Type is same"); } else { - System.out.println("Type Mismatch"); + throw new RuntimeException("Type mismatch"); } } return null; diff --git a/src/main/java/semantic/SemanticVisitor.java b/src/main/java/semantic/SemanticVisitor.java index 2fbaf41..f1228bb 100644 --- a/src/main/java/semantic/SemanticVisitor.java +++ b/src/main/java/semantic/SemanticVisitor.java @@ -11,15 +11,15 @@ import typechecker.TypeCheckResult; public interface SemanticVisitor { // TypeCheckResult typeCheck(ASTNode toCheck); - TypeCheckResult typeCheck(ProgramNode toCheck); + TypeCheckResult analyze(ProgramNode toCheck); - TypeCheckResult typeCheck(ClassNode toCheck); + TypeCheckResult analyze(ClassNode toCheck); - TypeCheckResult typeCheck(MethodNode toCheck); + TypeCheckResult analyze(MethodNode toCheck); - TypeCheckResult typeCheck(FieldNode toCheck); + TypeCheckResult analyze(FieldNode toCheck); - TypeCheckResult typeCheck(AssignmentStatementNode toCheck); + TypeCheckResult analyze(AssignmentStatementNode toCheck); // // TypeCheckResult typeCheck(MethodParameter toCheck); // From a8638fe70cbdc6cb9a20c708a6baa208c1da6de7 Mon Sep 17 00:00:00 2001 From: Bruder John Date: Tue, 14 May 2024 11:40:43 +0200 Subject: [PATCH 4/7] fixed error --- src/main/java/bytecode/ClassCodeGen.java | 5 ++++- src/main/java/bytecode/Mapper.java | 9 +++------ src/main/java/bytecode/MethodCodeGen.java | 16 +++++++++------- 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/main/java/bytecode/ClassCodeGen.java b/src/main/java/bytecode/ClassCodeGen.java index 59be9ee..7a1c0f0 100644 --- a/src/main/java/bytecode/ClassCodeGen.java +++ b/src/main/java/bytecode/ClassCodeGen.java @@ -4,6 +4,7 @@ import ast.ClassNode; import ast.member.FieldNode; import ast.member.MemberNode; import ast.member.MethodNode; +import ast.type.BaseTypeNode; import bytecode.visitor.ClassVisitor; import java.io.File; import org.objectweb.asm.ClassWriter; @@ -39,7 +40,9 @@ public class ClassCodeGen implements ClassVisitor { @Override public void visit(FieldNode fieldNode) { - classWriter.visitField(mapper.mapAccesTypeToOpcode(fieldNode.accessTypeNode), fieldNode.identifier, mapper.getTypeChar(fieldNode.type.enumTypeNode), null, null ); + if(fieldNode.type instanceof BaseTypeNode baseTypeNode){ + classWriter.visitField(mapper.mapAccesTypeToOpcode(fieldNode.accessTypeNode), fieldNode.identifier, mapper.getTypeChar(baseTypeNode.enumType), null, null ); + } classWriter.visitEnd(); } diff --git a/src/main/java/bytecode/Mapper.java b/src/main/java/bytecode/Mapper.java index 7f1b219..fb4f484 100644 --- a/src/main/java/bytecode/Mapper.java +++ b/src/main/java/bytecode/Mapper.java @@ -1,9 +1,6 @@ package bytecode; -import ast.type.AccessTypeNode; -import ast.type.EnumAccessTypeNode; -import ast.type.EnumTypeNode; -import ast.type.TypeNode; +import ast.type.*; import org.objectweb.asm.Opcodes; public class Mapper { @@ -17,9 +14,9 @@ public class Mapper { return 0; } - public String generateMethodDescriptor(TypeNode typeNode) { + public String generateMethodDescriptor(BaseTypeNode baseTypeNode) { String descriptor = "()"; - descriptor += getTypeChar(typeNode.enumTypeNode); + descriptor += getTypeChar(baseTypeNode.enumType); return descriptor; } diff --git a/src/main/java/bytecode/MethodCodeGen.java b/src/main/java/bytecode/MethodCodeGen.java index fd8a29a..e544a8b 100644 --- a/src/main/java/bytecode/MethodCodeGen.java +++ b/src/main/java/bytecode/MethodCodeGen.java @@ -2,6 +2,7 @@ package bytecode; import ast.member.ConstructorNode; import ast.member.MethodNode; +import ast.type.BaseTypeNode; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.MethodVisitor; @@ -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), - methodNode.identifier, - mapper.generateMethodDescriptor(methodNode.type), - null, - null); - - method.visitEnd(); + if(methodNode.type instanceof BaseTypeNode baseTypeNode){ + MethodVisitor method = classWriter.visitMethod(mapper.mapAccesTypeToOpcode(methodNode.visibility), + methodNode.identifier, + mapper.generateMethodDescriptor(baseTypeNode), + null, + null); + method.visitEnd(); + } } } From 6318085c00ff75677033bda4fe69775d235a202d Mon Sep 17 00:00:00 2001 From: Bruder John Date: Tue, 14 May 2024 12:51:49 +0200 Subject: [PATCH 5/7] added TypeCheckResult --- src/main/java/Main.java | 9 +++-- src/main/java/ast/VarNode.java | 10 ++++- .../java/ast/expression/ExpressionNode.java | 5 +-- src/main/java/classFileOutput/Example.class | Bin 132 -> 131 bytes src/main/java/parser/ASTBuilder.java | 1 + src/main/java/semantic/SemanticAnalyzer.java | 38 +++++++++++------- src/main/java/semantic/SemanticVisitor.java | 6 +-- 7 files changed, 44 insertions(+), 25 deletions(-) diff --git a/src/main/java/Main.java b/src/main/java/Main.java index 9b803ca..97ea0ef 100644 --- a/src/main/java/Main.java +++ b/src/main/java/Main.java @@ -1,3 +1,4 @@ +import ast.ASTNode; import ast.ClassNode; import ast.ProgramNode; import bytecode.ByteCodeGenerator; @@ -17,14 +18,14 @@ 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); + 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); @@ -34,9 +35,9 @@ public class Main { ASTBuilder builder = new ASTBuilder(); ProgramNode ast = (ProgramNode) builder.visit(tree); // build the AST - SemanticAnalyzer.generateTast(ast); + ProgramNode typedAst = (ProgramNode) SemanticAnalyzer.generateTast(ast); ByteCodeGenerator byteCodeGenerator = new ByteCodeGenerator(); - byteCodeGenerator.visit(ast); + byteCodeGenerator.visit(typedAst); } } \ No newline at end of file diff --git a/src/main/java/ast/VarNode.java b/src/main/java/ast/VarNode.java index e27f080..7ef6350 100644 --- a/src/main/java/ast/VarNode.java +++ b/src/main/java/ast/VarNode.java @@ -1,6 +1,10 @@ package ast; -public class VarNode implements ASTNode{ +import semantic.SemanticVisitor; +import typechecker.TypeCheckResult; +import typechecker.Visitable; + +public class VarNode implements ASTNode, Visitable { private String identifier; private String type; @@ -18,4 +22,8 @@ public class VarNode implements ASTNode{ return identifier; } + @Override + public TypeCheckResult accept(SemanticVisitor visitor) { + return visitor.analyze(this); + } } diff --git a/src/main/java/ast/expression/ExpressionNode.java b/src/main/java/ast/expression/ExpressionNode.java index 5dbead0..7e9be2d 100644 --- a/src/main/java/ast/expression/ExpressionNode.java +++ b/src/main/java/ast/expression/ExpressionNode.java @@ -1,9 +1,8 @@ package ast.expression; import ast.ASTNode; +import typechecker.Visitable; -public class ExpressionNode implements ASTNode { - - +public interface ExpressionNode extends ASTNode, Visitable { } diff --git a/src/main/java/classFileOutput/Example.class b/src/main/java/classFileOutput/Example.class index e2994804a9b99ea9c567e9caec4c6109835e84dc..c99f3e0a3a2dd9b7fed70513cb143dffa46429a0 100644 GIT binary patch delta 18 ZcmZo+Y-XHb!OX0oInhRu(Q{&)8UQL-1a<%b delta 19 acmZo>Y+;;W!NQ`U89dQikuhpwtQr6>z69C; diff --git a/src/main/java/parser/ASTBuilder.java b/src/main/java/parser/ASTBuilder.java index 1e8cbc3..3cff8a7 100644 --- a/src/main/java/parser/ASTBuilder.java +++ b/src/main/java/parser/ASTBuilder.java @@ -204,6 +204,7 @@ public class ASTBuilder extends SimpleJavaBaseVisitor { try { int intValue = Integer.parseInt(literalContext.getText()); LiteralNode literalNode = new LiteralNode(intValue); + literalNode.setType("int"); return literalNode; } catch (NumberFormatException ignored) {} diff --git a/src/main/java/semantic/SemanticAnalyzer.java b/src/main/java/semantic/SemanticAnalyzer.java index d499be2..06eab00 100644 --- a/src/main/java/semantic/SemanticAnalyzer.java +++ b/src/main/java/semantic/SemanticAnalyzer.java @@ -12,6 +12,8 @@ import ast.statement.AssignmentStatementNode; import ast.statement.StatementNode; import java.util.ArrayList; import java.util.List; + +import ast.type.TypeNode; import typechecker.TypeCheckResult; public class SemanticAnalyzer implements SemanticVisitor { @@ -36,34 +38,41 @@ public class SemanticAnalyzer implements SemanticVisitor { List classes = node.classes; for (ClassNode classNode : classes) { - classNode.accept(this); + var result = classNode.accept(this); + valid = valid && result.isValid(); } return new TypeCheckResult(valid, null); } @Override public TypeCheckResult analyze(ClassNode classNode) { + var valid = true; List members = classNode.members; for (MemberNode memberNode : members) { if (memberNode instanceof FieldNode fieldNode) { - fieldNode.accept(this); + var result = fieldNode.accept(this); + valid = valid && result.isValid(); } else if (memberNode instanceof MethodNode methodNode) { - methodNode.accept(this); + var result = methodNode.accept(this); + valid = valid && result.isValid(); } } - return null; + return new TypeCheckResult(valid, null); + } @Override public TypeCheckResult analyze(MethodNode methodNode) { + var valid = true; List statements = methodNode.statements; for (StatementNode statement : statements) { if(statement instanceof AssignmentStatementNode assignmentStatementNode) { - assignmentStatementNode.accept(this); + var result = assignmentStatementNode.accept(this); + valid = valid && result.isValid(); } } - return null; + return new TypeCheckResult(valid, null); } @Override @@ -73,20 +82,21 @@ public class SemanticAnalyzer implements SemanticVisitor { }else { currentFields.add(toCheck.identifier); } - return null; + return new TypeCheckResult(true, null); } @Override public TypeCheckResult analyze(AssignmentStatementNode assignmentStatementNode) { if(assignmentStatementNode.expression instanceof LiteralNode literalNode) { - VarNode varNode = assignmentStatementNode.varNode; - if(varNode.getType().equals(literalNode.getType())) { - System.out.println("Type is same"); - } else { - throw new RuntimeException("Type mismatch"); - } + TypeCheckResult varResult = assignmentStatementNode.varNode.accept(this); + TypeCheckResult expressionResult = assignmentStatementNode.expression.accept(this); } - return null; + return new TypeCheckResult(true, null); + } + + @Override + public TypeCheckResult analyze(VarNode toCheck) { + return new TypeCheckResult(true, null); } } \ No newline at end of file diff --git a/src/main/java/semantic/SemanticVisitor.java b/src/main/java/semantic/SemanticVisitor.java index f1228bb..57aabf6 100644 --- a/src/main/java/semantic/SemanticVisitor.java +++ b/src/main/java/semantic/SemanticVisitor.java @@ -3,13 +3,13 @@ package semantic; import ast.ClassNode; import ast.ProgramNode; +import ast.VarNode; import ast.member.FieldNode; import ast.member.MethodNode; import ast.statement.AssignmentStatementNode; import typechecker.TypeCheckResult; public interface SemanticVisitor { -// TypeCheckResult typeCheck(ASTNode toCheck); TypeCheckResult analyze(ProgramNode toCheck); @@ -20,8 +20,8 @@ public interface SemanticVisitor { TypeCheckResult analyze(FieldNode toCheck); TypeCheckResult analyze(AssignmentStatementNode toCheck); -// -// TypeCheckResult typeCheck(MethodParameter toCheck); + + TypeCheckResult analyze(VarNode toCheck); // // TypeCheckResult typeCheck(ForStmt forStmt); // From 33df2c1c0a962b4e6bcffe4dde0a10b6d652b4e5 Mon Sep 17 00:00:00 2001 From: Bruder John Date: Tue, 14 May 2024 12:53:40 +0200 Subject: [PATCH 6/7] Fixed errors --- src/main/java/ast/LiteralNode.java | 8 +++++++- .../java/ast/expression/BinaryExpressionNode.java | 10 +++++++++- .../java/ast/expression/IdentifierExpressionNode.java | 11 ++++++++++- src/main/java/ast/expression/UnaryExpressionNode.java | 10 +++++++++- 4 files changed, 35 insertions(+), 4 deletions(-) diff --git a/src/main/java/ast/LiteralNode.java b/src/main/java/ast/LiteralNode.java index 8fa060a..3873465 100644 --- a/src/main/java/ast/LiteralNode.java +++ b/src/main/java/ast/LiteralNode.java @@ -1,8 +1,10 @@ package ast; import ast.expression.ExpressionNode; +import semantic.SemanticVisitor; +import typechecker.TypeCheckResult; -public class LiteralNode extends ExpressionNode { +public class LiteralNode implements ExpressionNode { int value; private String type; @@ -20,4 +22,8 @@ public class LiteralNode extends ExpressionNode { } + @Override + public TypeCheckResult accept(SemanticVisitor visitor) { + return null; + } } diff --git a/src/main/java/ast/expression/BinaryExpressionNode.java b/src/main/java/ast/expression/BinaryExpressionNode.java index e63bbca..9260d3b 100644 --- a/src/main/java/ast/expression/BinaryExpressionNode.java +++ b/src/main/java/ast/expression/BinaryExpressionNode.java @@ -1,6 +1,9 @@ package ast.expression; -public class BinaryExpressionNode extends ExpressionNode { +import semantic.SemanticVisitor; +import typechecker.TypeCheckResult; + +public class BinaryExpressionNode implements ExpressionNode { public ExpressionNode left; public ExpressionNode right; public String operator; // Stores the operator as a string (e.g., "+", "-", "&&") @@ -10,4 +13,9 @@ public class BinaryExpressionNode extends ExpressionNode { this.right = right; this.operator = operator; } + + @Override + public TypeCheckResult accept(SemanticVisitor visitor) { + return null; + } } \ No newline at end of file diff --git a/src/main/java/ast/expression/IdentifierExpressionNode.java b/src/main/java/ast/expression/IdentifierExpressionNode.java index 7631429..0ad57d0 100644 --- a/src/main/java/ast/expression/IdentifierExpressionNode.java +++ b/src/main/java/ast/expression/IdentifierExpressionNode.java @@ -1,9 +1,18 @@ package ast.expression; -public class IdentifierExpressionNode extends ExpressionNode { +import semantic.SemanticVisitor; +import typechecker.TypeCheckResult; +import typechecker.Visitable; + +public class IdentifierExpressionNode implements ExpressionNode { public String name; public IdentifierExpressionNode(String name) { this.name = name; } + + @Override + public TypeCheckResult accept(SemanticVisitor visitor) { + return null; + } } diff --git a/src/main/java/ast/expression/UnaryExpressionNode.java b/src/main/java/ast/expression/UnaryExpressionNode.java index 0c77ef5..2c93670 100644 --- a/src/main/java/ast/expression/UnaryExpressionNode.java +++ b/src/main/java/ast/expression/UnaryExpressionNode.java @@ -1,6 +1,9 @@ package ast.expression; -public class UnaryExpressionNode extends ExpressionNode { +import semantic.SemanticVisitor; +import typechecker.TypeCheckResult; + +public class UnaryExpressionNode implements ExpressionNode { public ExpressionNode expression; public String operator; // Stores the operator (e.g., "-", "!") @@ -8,4 +11,9 @@ public class UnaryExpressionNode extends ExpressionNode { this.expression = expression; this.operator = operator; } + + @Override + public TypeCheckResult accept(SemanticVisitor visitor) { + return null; + } } From b64e2efc823eedc8ed7bc7c583665af610b70255 Mon Sep 17 00:00:00 2001 From: Bruder John Date: Tue, 14 May 2024 13:46:14 +0200 Subject: [PATCH 7/7] Changed To TypeNode --- src/main/java/CompilerInput.txt | 4 +- src/main/java/ast/ClassNode.java | 2 +- src/main/java/ast/ProgramNode.java | 2 +- src/main/java/ast/VarNode.java | 2 +- .../ast/expression/BinaryExpressionNode.java | 5 +- .../java/ast/expression/ExpressionNode.java | 2 +- .../expression/IdentifierExpressionNode.java | 12 +- .../ast/expression/UnaryExpressionNode.java | 5 +- src/main/java/ast/member/ConstructorNode.java | 2 +- src/main/java/ast/member/FieldNode.java | 2 +- src/main/java/ast/member/MethodNode.java | 4 +- .../statement/AssignmentStatementNode.java | 2 +- .../java/ast/statement/IfStatementNode.java | 7 + .../ast/statement/ReturnStatementNode.java | 7 + .../java/ast/statement/StatementNode.java | 3 +- .../VariableDeclarationStatementNode.java | 9 +- .../ast/statement/WhileStatementNode.java | 7 + src/main/java/ast/type/BaseTypeNode.java | 4 +- src/main/java/ast/type/ReferenceTypeNode.java | 4 +- src/main/java/bytecode/Mapper.java | 1 + src/main/java/parser/ASTBuilder.java | 6 +- src/main/java/semantic/Scope.java | 36 ++++ src/main/java/semantic/SemanticAnalyzer.java | 190 +++++++++++------- src/main/java/semantic/SemanticVisitor.java | 54 ++--- src/main/java/typechecker/Type.java | 5 - .../java/typechecker/TypeCheckResult.java | 8 +- src/main/java/typechecker/Typer.java | 9 - .../{typechecker => visitor}/Visitable.java | 3 +- 28 files changed, 243 insertions(+), 154 deletions(-) create mode 100644 src/main/java/semantic/Scope.java delete mode 100644 src/main/java/typechecker/Type.java delete mode 100644 src/main/java/typechecker/Typer.java rename src/main/java/{typechecker => visitor}/Visitable.java (88%) diff --git a/src/main/java/CompilerInput.txt b/src/main/java/CompilerInput.txt index b784cf7..918c686 100644 --- a/src/main/java/CompilerInput.txt +++ b/src/main/java/CompilerInput.txt @@ -5,9 +5,7 @@ public class Example { public static int testMethod(char b){ int a; - boolean b; - char c; - b = 3; + int a; } diff --git a/src/main/java/ast/ClassNode.java b/src/main/java/ast/ClassNode.java index 2f09f41..947a977 100644 --- a/src/main/java/ast/ClassNode.java +++ b/src/main/java/ast/ClassNode.java @@ -11,7 +11,7 @@ import java.util.List; import bytecode.visitor.ClassVisitor; import semantic.SemanticVisitor; import typechecker.TypeCheckResult; -import typechecker.Visitable; +import visitor.Visitable; public class ClassNode implements ASTNode, Visitable { public String identifier; diff --git a/src/main/java/ast/ProgramNode.java b/src/main/java/ast/ProgramNode.java index 116c5a2..1aac1b1 100644 --- a/src/main/java/ast/ProgramNode.java +++ b/src/main/java/ast/ProgramNode.java @@ -6,7 +6,7 @@ import java.util.List; import bytecode.visitor.ProgramVisitor; import semantic.SemanticVisitor; import typechecker.TypeCheckResult; -import typechecker.Visitable; +import visitor.Visitable; public class ProgramNode implements ASTNode, Visitable{ public List classes = new ArrayList<>(); diff --git a/src/main/java/ast/VarNode.java b/src/main/java/ast/VarNode.java index 7ef6350..9349eb4 100644 --- a/src/main/java/ast/VarNode.java +++ b/src/main/java/ast/VarNode.java @@ -2,7 +2,7 @@ package ast; import semantic.SemanticVisitor; import typechecker.TypeCheckResult; -import typechecker.Visitable; +import visitor.Visitable; public class VarNode implements ASTNode, Visitable { diff --git a/src/main/java/ast/expression/BinaryExpressionNode.java b/src/main/java/ast/expression/BinaryExpressionNode.java index 9260d3b..c912408 100644 --- a/src/main/java/ast/expression/BinaryExpressionNode.java +++ b/src/main/java/ast/expression/BinaryExpressionNode.java @@ -2,8 +2,9 @@ package ast.expression; import semantic.SemanticVisitor; import typechecker.TypeCheckResult; +import visitor.Visitable; -public class BinaryExpressionNode implements ExpressionNode { +public class BinaryExpressionNode implements ExpressionNode, Visitable { public ExpressionNode left; public ExpressionNode right; public String operator; // Stores the operator as a string (e.g., "+", "-", "&&") @@ -16,6 +17,6 @@ public class BinaryExpressionNode implements ExpressionNode { @Override public TypeCheckResult accept(SemanticVisitor visitor) { - return null; + return visitor.analyze(this); } } \ No newline at end of file diff --git a/src/main/java/ast/expression/ExpressionNode.java b/src/main/java/ast/expression/ExpressionNode.java index 7e9be2d..e790795 100644 --- a/src/main/java/ast/expression/ExpressionNode.java +++ b/src/main/java/ast/expression/ExpressionNode.java @@ -1,7 +1,7 @@ package ast.expression; import ast.ASTNode; -import typechecker.Visitable; +import visitor.Visitable; public interface ExpressionNode extends ASTNode, Visitable { diff --git a/src/main/java/ast/expression/IdentifierExpressionNode.java b/src/main/java/ast/expression/IdentifierExpressionNode.java index 0ad57d0..1bb8d56 100644 --- a/src/main/java/ast/expression/IdentifierExpressionNode.java +++ b/src/main/java/ast/expression/IdentifierExpressionNode.java @@ -1,11 +1,15 @@ package ast.expression; +import ast.type.TypeNode; import semantic.SemanticVisitor; -import typechecker.TypeCheckResult; -import typechecker.Visitable; -public class IdentifierExpressionNode implements ExpressionNode { +import typechecker.TypeCheckResult; +import visitor.Visitable; + +public class IdentifierExpressionNode implements ExpressionNode, Visitable { public String name; + public TypeNode type; + public IdentifierExpressionNode(String name) { this.name = name; @@ -13,6 +17,6 @@ public class IdentifierExpressionNode implements ExpressionNode { @Override public TypeCheckResult accept(SemanticVisitor visitor) { - return null; + return visitor.analyze(this); } } diff --git a/src/main/java/ast/expression/UnaryExpressionNode.java b/src/main/java/ast/expression/UnaryExpressionNode.java index 2c93670..24d1832 100644 --- a/src/main/java/ast/expression/UnaryExpressionNode.java +++ b/src/main/java/ast/expression/UnaryExpressionNode.java @@ -2,8 +2,9 @@ package ast.expression; import semantic.SemanticVisitor; import typechecker.TypeCheckResult; +import visitor.Visitable; -public class UnaryExpressionNode implements ExpressionNode { +public class UnaryExpressionNode implements ExpressionNode, Visitable { public ExpressionNode expression; public String operator; // Stores the operator (e.g., "-", "!") @@ -14,6 +15,6 @@ public class UnaryExpressionNode implements ExpressionNode { @Override public TypeCheckResult accept(SemanticVisitor visitor) { - return null; + return visitor.analyze(this); } } diff --git a/src/main/java/ast/member/ConstructorNode.java b/src/main/java/ast/member/ConstructorNode.java index c729dc1..998d727 100644 --- a/src/main/java/ast/member/ConstructorNode.java +++ b/src/main/java/ast/member/ConstructorNode.java @@ -2,7 +2,7 @@ package ast.member; import ast.type.AccessTypeNode; import bytecode.visitor.MethodVisitor; -import typechecker.Visitable; +import visitor.Visitable; public class ConstructorNode extends MethodNode implements Visitable { public ConstructorNode(AccessTypeNode visibility, String name) { diff --git a/src/main/java/ast/member/FieldNode.java b/src/main/java/ast/member/FieldNode.java index 70880c5..60c5411 100644 --- a/src/main/java/ast/member/FieldNode.java +++ b/src/main/java/ast/member/FieldNode.java @@ -5,7 +5,7 @@ import ast.type.TypeNode; import bytecode.visitor.ClassVisitor; import semantic.SemanticVisitor; import typechecker.TypeCheckResult; -import typechecker.Visitable; +import visitor.Visitable; public class FieldNode implements MemberNode, Visitable { public AccessTypeNode accessTypeNode; diff --git a/src/main/java/ast/member/MethodNode.java b/src/main/java/ast/member/MethodNode.java index 88ed182..c50f6af 100644 --- a/src/main/java/ast/member/MethodNode.java +++ b/src/main/java/ast/member/MethodNode.java @@ -3,15 +3,15 @@ package ast.member; import ast.parameter.ParameterListNode; import ast.statement.StatementNode; import ast.type.AccessTypeNode; -import ast.type.TypeNode; import java.util.ArrayList; import java.util.List; +import ast.type.TypeNode; import bytecode.visitor.MethodVisitor; import semantic.SemanticVisitor; import typechecker.TypeCheckResult; -import typechecker.Visitable; +import visitor.Visitable; public class MethodNode implements MemberNode, Visitable { public AccessTypeNode visibility; diff --git a/src/main/java/ast/statement/AssignmentStatementNode.java b/src/main/java/ast/statement/AssignmentStatementNode.java index 7efbd73..9f6a395 100644 --- a/src/main/java/ast/statement/AssignmentStatementNode.java +++ b/src/main/java/ast/statement/AssignmentStatementNode.java @@ -4,7 +4,7 @@ import ast.VarNode; import ast.expression.ExpressionNode; import semantic.SemanticVisitor; import typechecker.TypeCheckResult; -import typechecker.Visitable; +import visitor.Visitable; public class AssignmentStatementNode extends StatementNode implements Visitable { public VarNode varNode; diff --git a/src/main/java/ast/statement/IfStatementNode.java b/src/main/java/ast/statement/IfStatementNode.java index 93eec91..3f585dd 100644 --- a/src/main/java/ast/statement/IfStatementNode.java +++ b/src/main/java/ast/statement/IfStatementNode.java @@ -1,6 +1,8 @@ package ast.statement; import ast.expression.ExpressionNode; +import semantic.SemanticVisitor; +import typechecker.TypeCheckResult; public class IfStatementNode extends StatementNode { public ExpressionNode condition; @@ -12,4 +14,9 @@ public class IfStatementNode extends StatementNode { this.thenStatement = thenStatement; this.elseStatement = elseStatement; } + + @Override + public TypeCheckResult accept(SemanticVisitor visitor) { + return visitor.analyze(this); + } } \ No newline at end of file diff --git a/src/main/java/ast/statement/ReturnStatementNode.java b/src/main/java/ast/statement/ReturnStatementNode.java index 4ca4dfa..c5e4d6b 100644 --- a/src/main/java/ast/statement/ReturnStatementNode.java +++ b/src/main/java/ast/statement/ReturnStatementNode.java @@ -1,6 +1,8 @@ package ast.statement; import ast.expression.ExpressionNode; +import semantic.SemanticVisitor; +import typechecker.TypeCheckResult; public class ReturnStatementNode extends StatementNode { public ExpressionNode expression; @@ -8,4 +10,9 @@ public class ReturnStatementNode extends StatementNode { public ReturnStatementNode(ExpressionNode expression) { this.expression = expression; } + + @Override + public TypeCheckResult accept(SemanticVisitor visitor) { + return visitor.analyze(this); + } } \ No newline at end of file diff --git a/src/main/java/ast/statement/StatementNode.java b/src/main/java/ast/statement/StatementNode.java index 6c90f8c..eff1804 100644 --- a/src/main/java/ast/statement/StatementNode.java +++ b/src/main/java/ast/statement/StatementNode.java @@ -1,7 +1,8 @@ package ast.statement; import ast.ASTNode; +import visitor.Visitable; -public abstract class StatementNode implements ASTNode { +public abstract class StatementNode implements ASTNode, Visitable { } diff --git a/src/main/java/ast/statement/VariableDeclarationStatementNode.java b/src/main/java/ast/statement/VariableDeclarationStatementNode.java index e7f6e32..4302177 100644 --- a/src/main/java/ast/statement/VariableDeclarationStatementNode.java +++ b/src/main/java/ast/statement/VariableDeclarationStatementNode.java @@ -1,7 +1,9 @@ package ast.statement; -import ast.type.TypeNode; import ast.expression.ExpressionNode; +import ast.type.TypeNode; +import semantic.SemanticVisitor; +import typechecker.TypeCheckResult; public class VariableDeclarationStatementNode extends StatementNode { public TypeNode type; @@ -12,4 +14,9 @@ public class VariableDeclarationStatementNode extends StatementNode { this.identifier = identifier; this.expression = expression; } + + @Override + public TypeCheckResult accept(SemanticVisitor visitor) { + return visitor.analyze(this); + } } \ No newline at end of file diff --git a/src/main/java/ast/statement/WhileStatementNode.java b/src/main/java/ast/statement/WhileStatementNode.java index e6a10b1..a3f4007 100644 --- a/src/main/java/ast/statement/WhileStatementNode.java +++ b/src/main/java/ast/statement/WhileStatementNode.java @@ -1,6 +1,8 @@ package ast.statement; import ast.expression.ExpressionNode; +import semantic.SemanticVisitor; +import typechecker.TypeCheckResult; public class WhileStatementNode extends StatementNode { public ExpressionNode condition; @@ -10,4 +12,9 @@ public class WhileStatementNode extends StatementNode { this.condition = condition; this.body = body; } + + @Override + public TypeCheckResult accept(SemanticVisitor visitor) { + return visitor.analyze(this); + } } diff --git a/src/main/java/ast/type/BaseTypeNode.java b/src/main/java/ast/type/BaseTypeNode.java index 81cdf43..2d871ab 100644 --- a/src/main/java/ast/type/BaseTypeNode.java +++ b/src/main/java/ast/type/BaseTypeNode.java @@ -1,6 +1,8 @@ package ast.type; -public class BaseTypeNode implements TypeNode{ +import ast.ASTNode; + +public class BaseTypeNode implements ASTNode, TypeNode { public EnumTypeNode enumType; diff --git a/src/main/java/ast/type/ReferenceTypeNode.java b/src/main/java/ast/type/ReferenceTypeNode.java index 1937054..88225f3 100644 --- a/src/main/java/ast/type/ReferenceTypeNode.java +++ b/src/main/java/ast/type/ReferenceTypeNode.java @@ -1,4 +1,6 @@ package ast.type; -public class ReferenceTypeNode implements TypeNode{ +import ast.ASTNode; + +public class ReferenceTypeNode implements ASTNode, TypeNode { } diff --git a/src/main/java/bytecode/Mapper.java b/src/main/java/bytecode/Mapper.java index fb4f484..08985a6 100644 --- a/src/main/java/bytecode/Mapper.java +++ b/src/main/java/bytecode/Mapper.java @@ -2,6 +2,7 @@ package bytecode; import ast.type.*; import org.objectweb.asm.Opcodes; +import ast.type.BaseTypeNode; public class Mapper { public int mapAccesTypeToOpcode(AccessTypeNode type) { diff --git a/src/main/java/parser/ASTBuilder.java b/src/main/java/parser/ASTBuilder.java index 3cff8a7..ee61b9b 100644 --- a/src/main/java/parser/ASTBuilder.java +++ b/src/main/java/parser/ASTBuilder.java @@ -13,10 +13,12 @@ import ast.parameter.ParameterNode; import ast.statement.*; import ast.type.*; import org.antlr.v4.runtime.tree.TerminalNode; + import java.util.ArrayList; import java.util.List; import parser.generated.*; import parser.generated.SimpleJavaParser.LiteralContext; +import ast.type.BaseTypeNode; public class ASTBuilder extends SimpleJavaBaseVisitor { @Override @@ -74,9 +76,9 @@ public class ASTBuilder extends SimpleJavaBaseVisitor { @Override public ASTNode visitParameter(SimpleJavaParser.ParameterContext ctx) { - TypeNode type = (TypeNode) visit(ctx.type()); + TypeNode typeNode = (TypeNode) visit(ctx.type()); String identifier = ctx.IDENTIFIER().getText(); - return new ParameterNode(type, identifier); + return new ParameterNode(typeNode, identifier); } @Override diff --git a/src/main/java/semantic/Scope.java b/src/main/java/semantic/Scope.java new file mode 100644 index 0000000..ab5c0cb --- /dev/null +++ b/src/main/java/semantic/Scope.java @@ -0,0 +1,36 @@ +package semantic; + +import ast.type.TypeNode; + +import java.util.HashMap; +import java.util.Stack; + +public class Scope { + + private Stack> localVars; + + public void addLocalVar(String name, TypeNode type) { + if (this.contains(name)) { + throw new RuntimeException("Variable " + name + " already exists in this scope"); + } + localVars.peek().put(name, type); + } + + public boolean contains(String name) { + for (HashMap map : localVars) { + if (map.containsKey(name)) { + return true; + } + } + return false; + } + + public void pushScope() { + localVars.push(new HashMap()); + } + + public void popScope() { + localVars.pop(); + } + +} diff --git a/src/main/java/semantic/SemanticAnalyzer.java b/src/main/java/semantic/SemanticAnalyzer.java index 06eab00..7a6002b 100644 --- a/src/main/java/semantic/SemanticAnalyzer.java +++ b/src/main/java/semantic/SemanticAnalyzer.java @@ -2,101 +2,145 @@ package semantic; import ast.*; -import ast.expression.ExpressionNode; -import ast.member.ConstructorNode; +import ast.expression.BinaryExpressionNode; +import ast.expression.IdentifierExpressionNode; +import ast.expression.UnaryExpressionNode; import ast.member.FieldNode; import ast.member.MemberNode; import ast.member.MethodNode; -import ast.statement.AssignmentStatementNode; -import ast.statement.StatementNode; +import ast.statement.*; + import java.util.ArrayList; import java.util.List; -import ast.type.TypeNode; import typechecker.TypeCheckResult; public class SemanticAnalyzer implements SemanticVisitor { - private ArrayList currentFields = new ArrayList<>(); + private ArrayList currentFields = new ArrayList<>(); - public static ASTNode generateTast(ASTNode node) throws RuntimeException { - SemanticAnalyzer semanticCheck = new SemanticAnalyzer(); - ProgramNode programNode = (ProgramNode) node; - var result = programNode.accept(semanticCheck); - if (result.isValid()) { - return node; - } else { - throw new RuntimeException("Not Valid"); - } - } + private Scope currentScope; - @Override - public TypeCheckResult analyze(ProgramNode node) { - - var valid = true; - - List classes = node.classes; - for (ClassNode classNode : classes) { - var result = classNode.accept(this); - valid = valid && result.isValid(); - } - return new TypeCheckResult(valid, null); - } - - @Override - public TypeCheckResult analyze(ClassNode classNode) { - var valid = true; - List members = classNode.members; - for (MemberNode memberNode : members) { - if (memberNode instanceof FieldNode fieldNode) { - var result = fieldNode.accept(this); - valid = valid && result.isValid(); - } else if (memberNode instanceof MethodNode methodNode) { - var result = methodNode.accept(this); - valid = valid && result.isValid(); - } + public static ASTNode generateTast(ASTNode node) throws RuntimeException { + SemanticAnalyzer semanticCheck = new SemanticAnalyzer(); + ProgramNode programNode = (ProgramNode) node; + var result = programNode.accept(semanticCheck); + if (result.isValid()) { + return node; + } else { + throw new RuntimeException("Not Valid"); + } } - return new TypeCheckResult(valid, null); + @Override + public TypeCheckResult analyze(ProgramNode node) { - } + var valid = true; - @Override - public TypeCheckResult analyze(MethodNode methodNode) { - var valid = true; - List statements = methodNode.statements; - for (StatementNode statement : statements) { - if(statement instanceof AssignmentStatementNode assignmentStatementNode) { - var result = assignmentStatementNode.accept(this); - valid = valid && result.isValid(); - } + List classes = node.classes; + for (ClassNode classNode : classes) { + var result = classNode.accept(this); + valid = valid && result.isValid(); + } + return new TypeCheckResult(valid, null); } - return new TypeCheckResult(valid, null); - } - @Override - public TypeCheckResult analyze(FieldNode toCheck) { - if(currentFields.contains(toCheck.identifier)){ - throw new RuntimeException(toCheck.identifier + " Is Already Declared"); - }else { - currentFields.add(toCheck.identifier); + @Override + public TypeCheckResult analyze(ClassNode classNode) { + var valid = true; + List members = classNode.members; + for (MemberNode memberNode : members) { + if (memberNode instanceof FieldNode fieldNode) { + var result = fieldNode.accept(this); + valid = valid && result.isValid(); + } else if (memberNode instanceof MethodNode methodNode) { + var result = methodNode.accept(this); + valid = valid && result.isValid(); + } + } + + return new TypeCheckResult(valid, null); + } - return new TypeCheckResult(true, null); - } - @Override - public TypeCheckResult analyze(AssignmentStatementNode assignmentStatementNode) { - if(assignmentStatementNode.expression instanceof LiteralNode literalNode) { - TypeCheckResult varResult = assignmentStatementNode.varNode.accept(this); - TypeCheckResult expressionResult = assignmentStatementNode.expression.accept(this); + @Override + public TypeCheckResult analyze(MethodNode methodNode) { + var valid = true; + + currentLocalScope.pushScope(); + + List statements = methodNode.statements; + for (StatementNode statement : statements) { + if (statement instanceof AssignmentStatementNode assignmentStatementNode) { + var result = assignmentStatementNode.accept(this); + valid = valid && result.isValid(); + } else if (statement instanceof VariableDeclarationStatementNode variableDeclarationStatementNode) { + var result = variableDeclarationStatementNode.accept(this); + valid = valid && result.isValid(); + } + } + return new TypeCheckResult(valid, null); } - return new TypeCheckResult(true, null); - } - @Override - public TypeCheckResult analyze(VarNode toCheck) { - return new TypeCheckResult(true, null); - } + @Override + public TypeCheckResult analyze(FieldNode toCheck) { + if (currentFields.contains(toCheck.identifier)) { + throw new RuntimeException(toCheck.identifier + " Is Already Declared"); + } else { + currentFields.add(toCheck.identifier); + } + return new TypeCheckResult(true, null); + } + + @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); + } + + @Override + public TypeCheckResult analyze(BinaryExpressionNode toCheck) { + return null; + } + + @Override + public TypeCheckResult analyze(IdentifierExpressionNode toCheck) { + return null; + } + + @Override + public TypeCheckResult analyze(UnaryExpressionNode toCheck) { + return null; + } + + @Override + public TypeCheckResult analyze(VariableDeclarationStatementNode toCheck) { + + return new TypeCheckResult(true, null); + } + + @Override + public TypeCheckResult analyze(IfStatementNode toCheck) { + return null; + } + + @Override + public TypeCheckResult analyze(ReturnStatementNode toCheck) { + return null; + } + + @Override + public TypeCheckResult analyze(WhileStatementNode toCheck) { + return null; + } } \ No newline at end of file diff --git a/src/main/java/semantic/SemanticVisitor.java b/src/main/java/semantic/SemanticVisitor.java index 57aabf6..99d0cb8 100644 --- a/src/main/java/semantic/SemanticVisitor.java +++ b/src/main/java/semantic/SemanticVisitor.java @@ -4,9 +4,12 @@ package semantic; import ast.ClassNode; import ast.ProgramNode; import ast.VarNode; +import ast.expression.BinaryExpressionNode; +import ast.expression.IdentifierExpressionNode; +import ast.expression.UnaryExpressionNode; import ast.member.FieldNode; import ast.member.MethodNode; -import ast.statement.AssignmentStatementNode; +import ast.statement.*; import typechecker.TypeCheckResult; public interface SemanticVisitor { @@ -22,41 +25,18 @@ public interface SemanticVisitor { TypeCheckResult analyze(AssignmentStatementNode toCheck); TypeCheckResult analyze(VarNode toCheck); -// -// TypeCheckResult typeCheck(ForStmt forStmt); -// -// TypeCheckResult typeCheck(WhileStmt whileStmt); -// -// TypeCheckResult typeCheck(ReturnStmt returnStmt); -// -// TypeCheckResult typeCheck(LocalVarDecl localVarDecl); -// -// TypeCheckResult typeCheck(IfStmt ifStmt); -// -// TypeCheckResult typeCheck(Block block); -// -// TypeCheckResult typeCheck(NewDecl newDecl); -// -// TypeCheckResult typeCheck(MethodCall methodCall); -// -// TypeCheckResult typeCheck(Unary unary); -// -// TypeCheckResult typeCheck(This aThis); -// -// TypeCheckResult typeCheck(Null aNull); -// -// TypeCheckResult typeCheck(LocalOrFieldVar localOrFieldVar); -// -// TypeCheckResult typeCheck(IntegerExpr integerExpr); -// -// TypeCheckResult typeCheck(InstVar instVar); -// -// TypeCheckResult typeCheck(CharExpr charExpr); -// -// TypeCheckResult typeCheck(BoolExpr boolExpr); -// -// TypeCheckResult typeCheck(Binary binary); -// -// TypeCheckResult typeCheck(StringExpr instVar); + TypeCheckResult analyze(BinaryExpressionNode toCheck); + + TypeCheckResult analyze(IdentifierExpressionNode toCheck); + + TypeCheckResult analyze(UnaryExpressionNode toCheck); + + TypeCheckResult analyze(VariableDeclarationStatementNode toCheck); + + TypeCheckResult analyze(IfStatementNode toCheck); + + TypeCheckResult analyze(ReturnStatementNode toCheck); + + TypeCheckResult analyze(WhileStatementNode toCheck); } \ No newline at end of file diff --git a/src/main/java/typechecker/Type.java b/src/main/java/typechecker/Type.java deleted file mode 100644 index 89b1c16..0000000 --- a/src/main/java/typechecker/Type.java +++ /dev/null @@ -1,5 +0,0 @@ -package typechecker; - -public interface Type { - boolean equals(Object obj); -} \ No newline at end of file diff --git a/src/main/java/typechecker/TypeCheckResult.java b/src/main/java/typechecker/TypeCheckResult.java index 9068c0d..12143b2 100644 --- a/src/main/java/typechecker/TypeCheckResult.java +++ b/src/main/java/typechecker/TypeCheckResult.java @@ -1,12 +1,14 @@ package typechecker; +import ast.type.TypeNode; + public class TypeCheckResult { private boolean valid; - private Type type; + private TypeNode type; - public TypeCheckResult(boolean valid, Type type) { + public TypeCheckResult(boolean valid, TypeNode type) { this.valid = valid; this.type = type; } @@ -15,7 +17,7 @@ public class TypeCheckResult { return valid; } - public Type getType() { + public TypeNode getType() { return type; } } \ No newline at end of file diff --git a/src/main/java/typechecker/Typer.java b/src/main/java/typechecker/Typer.java deleted file mode 100644 index 3f8872a..0000000 --- a/src/main/java/typechecker/Typer.java +++ /dev/null @@ -1,9 +0,0 @@ -package typechecker; - -public class Typer { - - public static void Typeify(){ - - } - -} diff --git a/src/main/java/typechecker/Visitable.java b/src/main/java/visitor/Visitable.java similarity index 88% rename from src/main/java/typechecker/Visitable.java rename to src/main/java/visitor/Visitable.java index 111c58f..bd69777 100644 --- a/src/main/java/typechecker/Visitable.java +++ b/src/main/java/visitor/Visitable.java @@ -1,9 +1,10 @@ -package typechecker; +package visitor; import bytecode.visitor.ClassVisitor; import bytecode.visitor.MethodVisitor; import bytecode.visitor.ProgramVisitor; import semantic.SemanticVisitor; +import typechecker.TypeCheckResult; public interface Visitable { default void accept(ProgramVisitor programVisitor) {