From 6318085c00ff75677033bda4fe69775d235a202d Mon Sep 17 00:00:00 2001 From: Bruder John Date: Tue, 14 May 2024 12:51:49 +0200 Subject: [PATCH] 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); //