Fixed SemanticCheck for new AST and added Some Test
Some checks are pending
Gitea Actions Demo / Explore-Gitea-Actions (push) Waiting to run
Some checks are pending
Gitea Actions Demo / Explore-Gitea-Actions (push) Waiting to run
This commit is contained in:
parent
b5738034b0
commit
b9ada16dd1
@ -4,11 +4,14 @@ import ast.type.AccessModifierNode;
|
||||
import ast.member.ConstructorNode;
|
||||
import ast.member.MemberNode;
|
||||
import ast.member.MethodNode;
|
||||
import semantic.SemanticVisitor;
|
||||
import typechecker.TypeCheckResult;
|
||||
import visitor.Visitable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ClassNode implements ASTNode {
|
||||
public class ClassNode implements ASTNode, Visitable {
|
||||
public AccessModifierNode accessType;
|
||||
public String identifier;
|
||||
public List<MemberNode> members = new ArrayList<>();
|
||||
@ -45,4 +48,10 @@ public class ClassNode implements ASTNode {
|
||||
}
|
||||
return methods;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,13 +1,21 @@
|
||||
package ast;
|
||||
|
||||
import semantic.SemanticVisitor;
|
||||
import typechecker.TypeCheckResult;
|
||||
import visitor.Visitable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ProgramNode implements ASTNode {
|
||||
public class ProgramNode implements ASTNode, Visitable {
|
||||
public List<ClassNode> classes = new ArrayList<>();
|
||||
|
||||
public void addClass(ClassNode classNode) {
|
||||
classes.add(classNode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
}
|
||||
|
@ -2,11 +2,15 @@ package ast.block;
|
||||
|
||||
import ast.ASTNode;
|
||||
import ast.statement.IStatementNode;
|
||||
import semantic.SemanticVisitor;
|
||||
import typechecker.TypeCheckResult;
|
||||
import visitor.Visitable;
|
||||
|
||||
import java.beans.Visibility;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class BlockNode implements ASTNode {
|
||||
public class BlockNode implements ASTNode, Visitable {
|
||||
public List<IStatementNode> statements = new ArrayList<>();
|
||||
|
||||
public BlockNode() {}
|
||||
|
@ -1,5 +1,11 @@
|
||||
package ast.expression;
|
||||
|
||||
import ast.ASTNode;
|
||||
import ast.type.type.TypeNode;
|
||||
import visitor.Visitable;
|
||||
|
||||
public interface IExpressionNode extends ASTNode {}
|
||||
public interface IExpressionNode extends ASTNode, Visitable {
|
||||
|
||||
TypeNode getType();
|
||||
|
||||
}
|
||||
|
@ -1,7 +1,19 @@
|
||||
package ast.expression.binaryexpression;
|
||||
|
||||
import ast.expression.IExpressionNode;
|
||||
import ast.type.type.TypeNode;
|
||||
import semantic.SemanticVisitor;
|
||||
import typechecker.TypeCheckResult;
|
||||
|
||||
import java.beans.Expression;
|
||||
public class BinaryExpressionNode implements IExpressionNode {
|
||||
|
||||
public class BinaryExpressionNode implements IExpressionNode {}
|
||||
@Override
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeNode getType() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
package ast.expression.binaryexpression;
|
||||
|
||||
import ast.ASTNode;
|
||||
import ast.type.type.TypeNode;
|
||||
import semantic.SemanticVisitor;
|
||||
import typechecker.TypeCheckResult;
|
||||
|
||||
public class CalculationExpressionNode extends BinaryExpressionNode {
|
||||
public CalculationExpressionNode calculationExpression;
|
||||
@ -16,4 +18,15 @@ public class CalculationExpressionNode extends BinaryExpressionNode {
|
||||
public CalculationExpressionNode(DotExpressionNode dotExpression) {
|
||||
this.dotExpression = dotExpression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeNode getType() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
package ast.expression.binaryexpression;
|
||||
|
||||
import ast.ASTNode;
|
||||
import ast.type.type.TypeNode;
|
||||
import semantic.SemanticVisitor;
|
||||
import typechecker.TypeCheckResult;
|
||||
|
||||
public class DotExpressionNode extends BinaryExpressionNode {
|
||||
public DotExpressionNode dotExpression;
|
||||
@ -16,4 +18,15 @@ public class DotExpressionNode extends BinaryExpressionNode {
|
||||
public DotExpressionNode(DotSubstractionExpressionNode dotSubstractionExpression) {
|
||||
this.dotSubstractionExpression = dotSubstractionExpression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeNode getType() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,9 +1,11 @@
|
||||
package ast.expression.binaryexpression;
|
||||
|
||||
import ast.ASTNode;
|
||||
import ast.expression.unaryexpression.MemberAccessNode;
|
||||
import ast.statement.statementexpression.methodcallstatementnexpression.MethodCallStatementExpressionNode;
|
||||
import ast.type.type.TypeNode;
|
||||
import ast.type.ValueNode;
|
||||
import semantic.SemanticVisitor;
|
||||
import typechecker.TypeCheckResult;
|
||||
|
||||
public class DotSubstractionExpressionNode extends BinaryExpressionNode {
|
||||
public ValueNode value;
|
||||
@ -28,4 +30,15 @@ public class DotSubstractionExpressionNode extends BinaryExpressionNode {
|
||||
this.methodCall = methodCall;
|
||||
this.calculationExpression = calculationExpression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeNode getType() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,8 +1,10 @@
|
||||
package ast.expression.binaryexpression;
|
||||
|
||||
import ast.ASTNode;
|
||||
import ast.expression.IExpressionNode;
|
||||
import ast.expression.unaryexpression.UnaryExpressionNode;
|
||||
import ast.type.type.TypeNode;
|
||||
import semantic.SemanticVisitor;
|
||||
import typechecker.TypeCheckResult;
|
||||
|
||||
public class NonCalculationExpressionNode extends BinaryExpressionNode {
|
||||
public UnaryExpressionNode unaryExpression;
|
||||
@ -14,4 +16,15 @@ public class NonCalculationExpressionNode extends BinaryExpressionNode {
|
||||
this.operator = operator;
|
||||
this.expression = expression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeNode getType() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -16,4 +16,5 @@ public class MemberAccessNode implements ASTNode {
|
||||
public void addIdentifier(String identifier) {
|
||||
identifiers.add(identifier);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -9,4 +9,5 @@ public class NotExpressionNode implements ASTNode {
|
||||
public NotExpressionNode(IExpressionNode expression) {
|
||||
this.expression = expression;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,7 +2,10 @@ package ast.expression.unaryexpression;
|
||||
|
||||
import ast.expression.IExpressionNode;
|
||||
import ast.statement.IStatementNode;
|
||||
import ast.type.type.TypeNode;
|
||||
import ast.type.ValueNode;
|
||||
import semantic.SemanticVisitor;
|
||||
import typechecker.TypeCheckResult;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@ -14,6 +17,7 @@ public class UnaryExpressionNode implements IExpressionNode {
|
||||
public NotExpressionNode notExpression;
|
||||
public IStatementNode statement;
|
||||
public IExpressionNode expression;
|
||||
private TypeNode type;
|
||||
|
||||
public UnaryExpressionNode(String value) {
|
||||
if(Objects.equals(value, "this")) {
|
||||
@ -42,4 +46,19 @@ public class UnaryExpressionNode implements IExpressionNode {
|
||||
public UnaryExpressionNode(IExpressionNode expression) {
|
||||
this.expression = expression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeNode getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(TypeNode type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,9 +1,12 @@
|
||||
package ast.member;
|
||||
|
||||
import ast.type.AccessModifierNode;
|
||||
import ast.type.TypeNode;
|
||||
import ast.type.type.TypeNode;
|
||||
import semantic.SemanticVisitor;
|
||||
import typechecker.TypeCheckResult;
|
||||
import visitor.Visitable;
|
||||
|
||||
public class FieldNode implements MemberNode {
|
||||
public class FieldNode implements MemberNode, Visitable {
|
||||
public AccessModifierNode accessTypeNode;
|
||||
public TypeNode type;
|
||||
public String identifier;
|
||||
@ -13,4 +16,10 @@ public class FieldNode implements MemberNode {
|
||||
this.type = type;
|
||||
this.identifier = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3,16 +3,21 @@ package ast.member;
|
||||
import ast.block.BlockNode;
|
||||
import ast.parameter.ParameterNode;
|
||||
import ast.type.AccessModifierNode;
|
||||
import ast.type.TypeNode;
|
||||
import ast.type.type.TypeNode;
|
||||
import bytecode.visitor.MethodVisitor;
|
||||
import semantic.SemanticVisitor;
|
||||
import typechecker.TypeCheckResult;
|
||||
import visitor.Visitable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class MethodNode implements MemberNode {
|
||||
public class MethodNode implements MemberNode, Visitable {
|
||||
public AccessModifierNode accesModifier;
|
||||
public TypeNode type;
|
||||
public Boolean voidType;
|
||||
public String identifier;
|
||||
private String identifier;
|
||||
public List<ParameterNode> parameters = new ArrayList<>();
|
||||
public BlockNode block;
|
||||
|
||||
@ -39,8 +44,8 @@ public class MethodNode implements MemberNode {
|
||||
}
|
||||
|
||||
public boolean isSame(MethodNode methodNode){
|
||||
if (!this.identifier.equals(methodNode.identifier) || this.type.equals(methodNode.type)
|
||||
|| this.getParameters().size() != methodNode.getParameters().size()) {
|
||||
if (!(Objects.equals(this.identifier, methodNode.getIdentifier())) || type.equals(methodNode.type)
|
||||
|| getParameters().size() != methodNode.getParameters().size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -62,5 +67,12 @@ public class MethodNode implements MemberNode {
|
||||
methodVisitor.visit(this);
|
||||
}
|
||||
|
||||
public String getIdentifier() {
|
||||
return identifier;
|
||||
}
|
||||
|
||||
public void setIdentifier(String identifier) {
|
||||
this.identifier = identifier;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
package ast.parameter;
|
||||
|
||||
import ast.ASTNode;
|
||||
import ast.type.TypeNode;
|
||||
import ast.type.type.TypeNode;
|
||||
import semantic.SemanticVisitor;
|
||||
import typechecker.TypeCheckResult;
|
||||
import visitor.Visitable;
|
||||
|
@ -2,6 +2,8 @@ package ast.statement;
|
||||
|
||||
import ast.ASTNode;
|
||||
import ast.expression.IExpressionNode;
|
||||
import semantic.SemanticVisitor;
|
||||
import typechecker.TypeCheckResult;
|
||||
|
||||
public class ForStatementNode implements IStatementNode {
|
||||
public IExpressionNode statementExpressionInit;
|
||||
@ -20,4 +22,10 @@ public class ForStatementNode implements IStatementNode {
|
||||
this.expression = expression;
|
||||
this.statementExpression = statementExpression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package ast.statement;
|
||||
|
||||
import ast.ASTNode;
|
||||
import visitor.Visitable;
|
||||
|
||||
public interface IStatementNode extends ASTNode {
|
||||
public interface IStatementNode extends ASTNode, Visitable {
|
||||
}
|
||||
|
@ -1,8 +1,9 @@
|
||||
package ast.statement;
|
||||
|
||||
import ast.ASTNode;
|
||||
import ast.expression.IExpressionNode;
|
||||
import ast.type.TypeNode;
|
||||
import ast.type.type.TypeNode;
|
||||
import semantic.SemanticVisitor;
|
||||
import typechecker.TypeCheckResult;
|
||||
|
||||
public class LocalVariableDeclarationNode implements IStatementNode {
|
||||
public TypeNode type;
|
||||
@ -16,4 +17,10 @@ public class LocalVariableDeclarationNode implements IStatementNode {
|
||||
this.assign = assign;
|
||||
this.expression = expression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,6 +2,8 @@ package ast.statement;
|
||||
|
||||
import ast.ASTNode;
|
||||
import ast.expression.IExpressionNode;
|
||||
import semantic.SemanticVisitor;
|
||||
import typechecker.TypeCheckResult;
|
||||
|
||||
public class ReturnStatementNode implements IStatementNode {
|
||||
public IExpressionNode expression;
|
||||
@ -9,4 +11,10 @@ public class ReturnStatementNode implements IStatementNode {
|
||||
public ReturnStatementNode(IExpressionNode expression) {
|
||||
this.expression = expression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3,6 +3,8 @@ package ast.statement;
|
||||
import ast.ASTNode;
|
||||
import ast.block.BlockNode;
|
||||
import ast.expression.IExpressionNode;
|
||||
import semantic.SemanticVisitor;
|
||||
import typechecker.TypeCheckResult;
|
||||
|
||||
public class WhileStatementNode implements IStatementNode {
|
||||
public IExpressionNode expression;
|
||||
@ -12,4 +14,10 @@ public class WhileStatementNode implements IStatementNode {
|
||||
this.expression = expression;
|
||||
this.block = block;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3,6 +3,8 @@ package ast.statement.ifstatement;
|
||||
import ast.ASTNode;
|
||||
import ast.block.BlockNode;
|
||||
import ast.statement.IStatementNode;
|
||||
import semantic.SemanticVisitor;
|
||||
import typechecker.TypeCheckResult;
|
||||
|
||||
public class ElseStatementNode implements IStatementNode {
|
||||
public BlockNode block;
|
||||
@ -10,4 +12,10 @@ public class ElseStatementNode implements IStatementNode {
|
||||
public ElseStatementNode(BlockNode block) {
|
||||
this.block = block;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,6 +2,8 @@ package ast.statement.ifstatement;
|
||||
|
||||
import ast.ASTNode;
|
||||
import ast.statement.IStatementNode;
|
||||
import semantic.SemanticVisitor;
|
||||
import typechecker.TypeCheckResult;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -18,4 +20,9 @@ public class IfElseStatementNode implements IStatementNode {
|
||||
elseStatements.add(elseStatement);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,6 +4,8 @@ import ast.ASTNode;
|
||||
import ast.block.BlockNode;
|
||||
import ast.expression.IExpressionNode;
|
||||
import ast.statement.IStatementNode;
|
||||
import semantic.SemanticVisitor;
|
||||
import typechecker.TypeCheckResult;
|
||||
|
||||
public class IfStatementNode implements IStatementNode {
|
||||
public IExpressionNode expression;
|
||||
@ -13,4 +15,10 @@ public class IfStatementNode implements IStatementNode {
|
||||
this.expression = expression;
|
||||
this.block = block;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,6 +2,9 @@ package ast.statement.statementexpression;
|
||||
|
||||
import ast.ASTNode;
|
||||
import ast.expression.IExpressionNode;
|
||||
import ast.type.type.TypeNode;
|
||||
import semantic.SemanticVisitor;
|
||||
import typechecker.TypeCheckResult;
|
||||
|
||||
public class AssignStatementExpressionNode implements IStatementExpressionNode {
|
||||
public AssignableExpressionNode assignable;
|
||||
@ -11,4 +14,10 @@ public class AssignStatementExpressionNode implements IStatementExpressionNode {
|
||||
this.assignable = assignable;
|
||||
this.expression = expression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,9 +2,13 @@ package ast.statement.statementexpression;
|
||||
|
||||
import ast.ASTNode;
|
||||
import ast.expression.unaryexpression.MemberAccessNode;
|
||||
import ast.type.type.TypeNode;
|
||||
import semantic.SemanticVisitor;
|
||||
import typechecker.TypeCheckResult;
|
||||
|
||||
public class AssignableExpressionNode implements IStatementExpressionNode {
|
||||
public String identifier;
|
||||
|
||||
public MemberAccessNode memberAccess;
|
||||
|
||||
public AssignableExpressionNode(String identifier) {
|
||||
@ -14,4 +18,10 @@ public class AssignableExpressionNode implements IStatementExpressionNode {
|
||||
public AssignableExpressionNode(MemberAccessNode memberAccess) {
|
||||
this.memberAccess = memberAccess;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,6 +2,8 @@ package ast.statement.statementexpression;
|
||||
|
||||
import ast.ASTNode;
|
||||
import ast.expression.IExpressionNode;
|
||||
import semantic.SemanticVisitor;
|
||||
import typechecker.TypeCheckResult;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -17,4 +19,10 @@ public class NewDeclarationStatementExpressionNode implements IStatementExpressi
|
||||
public void addExpression(IExpressionNode expression) {
|
||||
expressions.add(expression);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3,6 +3,8 @@ package ast.statement.statementexpression.crementExpression;
|
||||
import ast.ASTNode;
|
||||
import ast.statement.statementexpression.AssignableExpressionNode;
|
||||
import ast.statement.statementexpression.IStatementExpressionNode;
|
||||
import semantic.SemanticVisitor;
|
||||
import typechecker.TypeCheckResult;
|
||||
|
||||
public class DecrementExpressionNode implements IStatementExpressionNode {
|
||||
public CrementType crementType;
|
||||
@ -11,4 +13,10 @@ public class DecrementExpressionNode implements IStatementExpressionNode {
|
||||
public DecrementExpressionNode(CrementType crementType, AssignableExpressionNode assignableExpression) {
|
||||
this.assignableExpression = assignableExpression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3,6 +3,8 @@ package ast.statement.statementexpression.crementExpression;
|
||||
import ast.ASTNode;
|
||||
import ast.statement.statementexpression.AssignableExpressionNode;
|
||||
import ast.statement.statementexpression.IStatementExpressionNode;
|
||||
import semantic.SemanticVisitor;
|
||||
import typechecker.TypeCheckResult;
|
||||
|
||||
public class IncrementExpressionNode implements IStatementExpressionNode {
|
||||
public CrementType crementType;
|
||||
@ -11,4 +13,10 @@ public class IncrementExpressionNode implements IStatementExpressionNode {
|
||||
public IncrementExpressionNode(CrementType crementType, AssignableExpressionNode assignableExpression) {
|
||||
this.assignableExpression = assignableExpression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3,6 +3,8 @@ package ast.statement.statementexpression.methodcallstatementnexpression;
|
||||
import ast.ASTNode;
|
||||
import ast.expression.IExpressionNode;
|
||||
import ast.statement.statementexpression.IStatementExpressionNode;
|
||||
import semantic.SemanticVisitor;
|
||||
import typechecker.TypeCheckResult;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -26,5 +28,9 @@ public class MethodCallStatementExpressionNode implements IStatementExpressionNo
|
||||
expressions.add(expression);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
4
src/main/java/ast/type/type/BaseType.java
Normal file
4
src/main/java/ast/type/type/BaseType.java
Normal file
@ -0,0 +1,4 @@
|
||||
package ast.type.type;
|
||||
|
||||
public class BaseType {
|
||||
}
|
4
src/main/java/ast/type/type/ReferenceType.java
Normal file
4
src/main/java/ast/type/type/ReferenceType.java
Normal file
@ -0,0 +1,4 @@
|
||||
package ast.type.type;
|
||||
|
||||
public class ReferenceType {
|
||||
}
|
@ -1,4 +1,6 @@
|
||||
package ast.type;
|
||||
package ast.type.type;
|
||||
|
||||
import ast.type.EnumTypeNode;
|
||||
|
||||
public class TypeNode {
|
||||
public EnumTypeNode type;
|
@ -10,7 +10,7 @@ public class ByteCodeGenerator implements ProgramVisitor {
|
||||
public void visit(ProgramNode programNode) {
|
||||
for (ClassNode classDeclarationNode : programNode.classes) {
|
||||
ClassCodeGen classCodeGen = new ClassCodeGen();
|
||||
classDeclarationNode.accept(classCodeGen);
|
||||
// classDeclarationNode.accept(classCodeGen);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import ast.ClassNode;
|
||||
import ast.member.FieldNode;
|
||||
import ast.member.MemberNode;
|
||||
import ast.member.MethodNode;
|
||||
import ast.type.TypeNode;
|
||||
import ast.type.type.TypeNode;
|
||||
import bytecode.visitor.ClassVisitor;
|
||||
import java.io.File;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
|
@ -10,6 +10,7 @@ import ast.expression.binaryexpression.NonCalculationExpressionNode;
|
||||
import ast.expression.unaryexpression.MemberAccessNode;
|
||||
import ast.expression.unaryexpression.NotExpressionNode;
|
||||
import ast.expression.unaryexpression.UnaryExpressionNode;
|
||||
import ast.member.FieldNode;
|
||||
import ast.member.MethodNode;
|
||||
import ast.statement.ifstatement.ElseStatementNode;
|
||||
import ast.statement.ifstatement.IfElseStatementNode;
|
||||
@ -28,6 +29,7 @@ import ast.statement.statementexpression.methodcallstatementnexpression.ChainedM
|
||||
import ast.statement.statementexpression.methodcallstatementnexpression.MethodCallStatementExpressionNode;
|
||||
import ast.statement.statementexpression.methodcallstatementnexpression.TargetNode;
|
||||
import ast.type.*;
|
||||
import ast.type.type.TypeNode;
|
||||
import org.antlr.v4.runtime.tree.TerminalNode;
|
||||
import parser.generated.*;
|
||||
|
||||
@ -74,13 +76,18 @@ public class ASTBuilder extends SimpleJavaBaseVisitor<ASTNode> {
|
||||
} else {
|
||||
MethodNode methodNode = new MethodNode(ctx.AccessModifier().getText(), null, true, ctx.Identifier().getText(), (BlockNode) visit(ctx.block()));
|
||||
for(SimpleJavaParser.ParameterContext parameter : ctx.parameterList().parameter()) {
|
||||
// methodNode.addParameter((ParameterNode) visit(parameter));
|
||||
methodNode.addParameter((ParameterNode) visit(parameter));
|
||||
}
|
||||
return methodNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ASTNode visitFieldDeclaration(SimpleJavaParser.FieldDeclarationContext ctx) {
|
||||
return new FieldNode(new AccessModifierNode(ctx.AccessModifier().getText()), new TypeNode(ctx.type().getText()), ctx.Identifier().getText());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ASTNode visitParameter(SimpleJavaParser.ParameterContext ctx) {
|
||||
return new ParameterNode(new TypeNode(ctx.type().getText()), ctx.Identifier().getText());
|
||||
|
@ -1,6 +1,7 @@
|
||||
package semantic;
|
||||
|
||||
import ast.type.TypeNode;
|
||||
import ast.type.type.TypeNode;
|
||||
import semantic.exeptions.AlreadyDeclearedException;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Stack;
|
||||
@ -15,7 +16,7 @@ public class Scope {
|
||||
|
||||
public void addLocalVar(String name, TypeNode type) {
|
||||
if (this.contains(name)) {
|
||||
throw new RuntimeException("Variable " + name + " already exists in this scope");
|
||||
throw new AlreadyDeclearedException("Variable " + name + " already exists in this scope");
|
||||
}
|
||||
localVars.peek().put(name, type);
|
||||
}
|
||||
|
@ -8,13 +8,28 @@ import java.util.Objects;
|
||||
|
||||
import ast.*;
|
||||
import ast.block.BlockNode;
|
||||
import ast.expression.IExpressionNode;
|
||||
import ast.expression.binaryexpression.*;
|
||||
import ast.expression.unaryexpression.UnaryExpressionNode;
|
||||
import ast.member.*;
|
||||
import ast.parameter.ParameterNode;
|
||||
import ast.statement.*;
|
||||
import ast.statement.ifstatement.ElseStatementNode;
|
||||
import ast.statement.ifstatement.IfElseStatementNode;
|
||||
import ast.statement.ifstatement.IfStatementNode;
|
||||
import ast.type.*;
|
||||
import ast.statement.statementexpression.AssignStatementExpressionNode;
|
||||
import ast.statement.statementexpression.AssignableExpressionNode;
|
||||
import ast.statement.statementexpression.NewDeclarationStatementExpressionNode;
|
||||
import ast.statement.statementexpression.crementExpression.DecrementExpressionNode;
|
||||
import ast.statement.statementexpression.crementExpression.IncrementExpressionNode;
|
||||
import ast.statement.statementexpression.methodcallstatementnexpression.MethodCallStatementExpressionNode;
|
||||
import ast.type.type.BaseType;
|
||||
import ast.type.type.ReferenceType;
|
||||
import ast.type.type.TypeNode;
|
||||
import semantic.context.Context;
|
||||
import semantic.exeptions.AlreadyDeclearedException;
|
||||
import semantic.exeptions.AlreadyDefinedException;
|
||||
import semantic.exeptions.NotDeclearedException;
|
||||
import semantic.exeptions.TypeMismatchException;
|
||||
import typechecker.TypeCheckResult;
|
||||
|
||||
@ -24,9 +39,10 @@ public class SemanticAnalyzer implements SemanticVisitor {
|
||||
|
||||
public static ArrayList<Exception> errors = new ArrayList<>();
|
||||
|
||||
private Context context;
|
||||
private static Context context;
|
||||
private static Scope currentScope;
|
||||
private static ClassNode currentClass;
|
||||
private static TypeNode currentNullType;
|
||||
|
||||
public static ASTNode generateTast(ASTNode node) {
|
||||
SemanticAnalyzer semanticCheck = new SemanticAnalyzer();
|
||||
@ -42,7 +58,7 @@ public class SemanticAnalyzer implements SemanticVisitor {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void clearAnalyzier(){
|
||||
public static void clearAnalyzer() {
|
||||
currentFields.clear();
|
||||
errors.clear();
|
||||
currentScope = null;
|
||||
@ -79,8 +95,8 @@ public class SemanticAnalyzer implements SemanticVisitor {
|
||||
valid = valid && result.isValid();
|
||||
} else if (memberNode instanceof MethodNode methodNode) {
|
||||
//Methods
|
||||
for(MethodNode methode : currentClass.getMethods()){
|
||||
if(methode.equals(methodNode))
|
||||
for (MethodNode methode : currentClass.getMethods()) {
|
||||
if (methode.equals(methodNode))
|
||||
break;
|
||||
|
||||
}
|
||||
@ -98,11 +114,11 @@ public class SemanticAnalyzer implements SemanticVisitor {
|
||||
var valid = true;
|
||||
|
||||
for (var otherMethod : currentClass.getMethods()) {
|
||||
if (Objects.equals(otherMethod , methodNode))
|
||||
if (Objects.equals(otherMethod, methodNode))
|
||||
break;
|
||||
if (otherMethod.isSame(methodNode)) {
|
||||
errors.add(new AlreadyDeclearedException(
|
||||
"Method " + methodNode.identifier + " is already defined in class "
|
||||
"Method " + methodNode.getIdentifier() + " is already defined in class "
|
||||
+ currentClass.identifier));
|
||||
valid = false;
|
||||
}
|
||||
@ -112,31 +128,41 @@ public class SemanticAnalyzer implements SemanticVisitor {
|
||||
for (var parameter : methodNode.getParameters()) {
|
||||
var result = parameter.accept(this);
|
||||
valid = valid && result.isValid();
|
||||
currentScope.addLocalVar(parameter.identifier, parameter.type);
|
||||
try {
|
||||
currentScope.addLocalVar(parameter.identifier, parameter.type);
|
||||
} catch (AlreadyDeclearedException e) {
|
||||
errors.add(new AlreadyDeclearedException(parameter.identifier));
|
||||
}
|
||||
|
||||
}
|
||||
// Check if this method is already declared
|
||||
|
||||
// currentMethodReturnType = methodDecl.getType();
|
||||
// currentNullType = currentMethodReturnType; // Solange nicht in einem Assign oder Methoden-Aufruf dieser Typ
|
||||
|
||||
// gesetzt ist, ist dieser der Rückgabewert der Methode
|
||||
var result = methodNode.block.accept(this);
|
||||
valid = valid && result.isValid();
|
||||
currentScope.popScope();
|
||||
var resultType = result.getType();
|
||||
TypeNode resultType = new TypeNode("void");
|
||||
|
||||
/*
|
||||
if (resultType == null) {
|
||||
resultType = new BaseType(Primitives.VOID);
|
||||
}
|
||||
if (!resultType.equals(methodDecl.getType())) {
|
||||
errors.add(new TypeMismatchException("Method-Declaration " + methodDecl.getIdentifier() + " with type "
|
||||
+ methodDecl.getType() + " has at least one Mismatching return Type:"
|
||||
+ TypeHelper.generateLocationString(methodDecl.line, methodDecl.column, fileName)));
|
||||
valid = false;
|
||||
if (methodNode.block != null) {
|
||||
// gesetzt ist, ist dieser der Rückgabewert der Methode
|
||||
var result = methodNode.block.accept(this);
|
||||
valid = valid && result.isValid();
|
||||
currentScope.popScope();
|
||||
resultType = result.getType();
|
||||
|
||||
/*
|
||||
if (resultType == null) {
|
||||
resultType = new BaseType(Primitives.VOID);
|
||||
}
|
||||
if (!resultType.equals(methodDecl.getType())) {
|
||||
errors.add(new TypeMismatchException("Method-Declaration " + methodDecl.getIdentifier() + " with type "
|
||||
+ methodDecl.getType() + " has at least one Mismatching return Type:"
|
||||
+ TypeHelper.generateLocationString(methodDecl.line, methodDecl.column, fileName)));
|
||||
valid = false;
|
||||
}
|
||||
|
||||
*/
|
||||
}
|
||||
|
||||
*/
|
||||
return new TypeCheckResult(valid, resultType);
|
||||
}
|
||||
|
||||
@ -168,12 +194,165 @@ public class SemanticAnalyzer implements SemanticVisitor {
|
||||
|
||||
@Override
|
||||
public TypeCheckResult analyze(ParameterNode toCheck) {
|
||||
|
||||
|
||||
return new TypeCheckResult(true, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult analyze(BlockNode toCheck) {
|
||||
public TypeCheckResult analyze(BlockNode blockNode) {
|
||||
|
||||
for (IStatementNode statementNode : blockNode.statements) {
|
||||
statementNode.accept(this);
|
||||
}
|
||||
return new TypeCheckResult(true, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult analyze(AssignableExpressionNode toCheck) {
|
||||
return new TypeCheckResult(true, currentFields.get(toCheck.identifier));
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult analyze(ElseStatementNode toCheck) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult analyze(ForStatementNode toCheck) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult analyze(AssignStatementExpressionNode toCheck) {
|
||||
AssignableExpressionNode assignable = toCheck.assignable;
|
||||
var oldNullType = currentNullType;
|
||||
currentNullType = currentFields.get(toCheck.assignable.identifier);
|
||||
IExpressionNode rExpression = toCheck.expression;
|
||||
currentNullType = oldNullType;
|
||||
var valid = true;
|
||||
|
||||
// This check currently handles things like :
|
||||
/**
|
||||
* private int i;
|
||||
* void foo(int i){
|
||||
* i = i;
|
||||
* }
|
||||
*/
|
||||
if (assignable.equals(rExpression)) {
|
||||
errors.add(new TypeMismatchException("Cannot assign to self"));
|
||||
valid = false;
|
||||
}
|
||||
|
||||
var lResult = assignable.accept(this);
|
||||
currentNullType = lResult.getType();
|
||||
var rResult = rExpression.accept(this);
|
||||
|
||||
if (!Objects.equals(currentFields.get(toCheck.assignable.identifier), rExpression.getType())) {
|
||||
errors.add(new TypeMismatchException(
|
||||
"Mismatch types in Assign-Statement: cannot convert from \"" + lResult.getType() + "\" to \""
|
||||
+ rResult.getType() + "\""));
|
||||
valid = false;
|
||||
}
|
||||
// else {
|
||||
// toCheck.setType(assignable.getType());
|
||||
// }
|
||||
valid = valid && lResult.isValid() && rResult.isValid();
|
||||
currentNullType = null;
|
||||
return new TypeCheckResult(valid, null); // return type is null to get the return type sufficently
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult analyze(DecrementExpressionNode toCheck) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult analyze(IfElseStatementNode toCheck) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult analyze(MethodCallStatementExpressionNode toCheck) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult analyze(LocalVariableDeclarationNode localVarDecl) {
|
||||
var valid = true;
|
||||
|
||||
if (localVarDecl.expression != null) {
|
||||
TypeCheckResult result = localVarDecl.expression.accept(this);
|
||||
|
||||
var resultType = localVarDecl.expression.getType();
|
||||
valid = result.isValid() && valid;
|
||||
|
||||
if (!Objects.equals(resultType, localVarDecl.type)) {
|
||||
errors.add(new TypeMismatchException(
|
||||
"Type mismatch: cannot convert from " + resultType + " to " + localVarDecl.type));
|
||||
valid = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
try {
|
||||
currentScope.addLocalVar(localVarDecl.identifier, localVarDecl.type);
|
||||
} catch (AlreadyDefinedException e) {
|
||||
errors.add(new AlreadyDefinedException(e.getMessage()));
|
||||
valid = false;
|
||||
}
|
||||
return new TypeCheckResult(valid, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult analyze(NewDeclarationStatementExpressionNode toCheck) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult analyze(IncrementExpressionNode toCheck) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult analyze(BinaryExpressionNode toCheck) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult analyze(CalculationExpressionNode calcNode) {
|
||||
if(calcNode.calculationExpression != null){
|
||||
calcNode.calculationExpression.accept(this);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult analyze(DotExpressionNode toCheck) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult analyze(DotSubstractionExpressionNode toCheck) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult analyze(NonCalculationExpressionNode toCheck) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult analyze(UnaryExpressionNode unary) {
|
||||
var valid = true;
|
||||
|
||||
if (!currentScope.contains(unary.identifier)) {
|
||||
errors.add(new NotDeclearedException("Not declared " + unary.identifier));
|
||||
return new TypeCheckResult(false, null);
|
||||
}
|
||||
|
||||
return new TypeCheckResult(valid, unary.getType());
|
||||
}
|
||||
|
||||
}
|
@ -3,10 +3,18 @@ package semantic;
|
||||
|
||||
import ast.*;
|
||||
import ast.block.BlockNode;
|
||||
import ast.expression.binaryexpression.*;
|
||||
import ast.expression.unaryexpression.UnaryExpressionNode;
|
||||
import ast.member.*;
|
||||
import ast.parameter.ParameterNode;
|
||||
import ast.statement.*;
|
||||
import ast.statement.ifstatement.*;
|
||||
import ast.statement.statementexpression.AssignStatementExpressionNode;
|
||||
import ast.statement.statementexpression.AssignableExpressionNode;
|
||||
import ast.statement.statementexpression.NewDeclarationStatementExpressionNode;
|
||||
import ast.statement.statementexpression.crementExpression.DecrementExpressionNode;
|
||||
import ast.statement.statementexpression.crementExpression.IncrementExpressionNode;
|
||||
import ast.statement.statementexpression.methodcallstatementnexpression.MethodCallStatementExpressionNode;
|
||||
import typechecker.TypeCheckResult;
|
||||
|
||||
public interface SemanticVisitor {
|
||||
@ -29,5 +37,36 @@ public interface SemanticVisitor {
|
||||
|
||||
TypeCheckResult analyze(BlockNode toCheck);
|
||||
|
||||
TypeCheckResult analyze(AssignableExpressionNode toCheck);
|
||||
|
||||
TypeCheckResult analyze(ElseStatementNode toCheck);
|
||||
|
||||
TypeCheckResult analyze(ForStatementNode toCheck);
|
||||
|
||||
TypeCheckResult analyze(AssignStatementExpressionNode toCheck);
|
||||
|
||||
TypeCheckResult analyze(DecrementExpressionNode toCheck);
|
||||
|
||||
TypeCheckResult analyze(IfElseStatementNode toCheck);
|
||||
|
||||
TypeCheckResult analyze(MethodCallStatementExpressionNode toCheck);
|
||||
|
||||
TypeCheckResult analyze(LocalVariableDeclarationNode toCheck);
|
||||
|
||||
TypeCheckResult analyze(NewDeclarationStatementExpressionNode toCheck);
|
||||
|
||||
TypeCheckResult analyze(IncrementExpressionNode toCheck);
|
||||
|
||||
TypeCheckResult analyze(BinaryExpressionNode toCheck);
|
||||
|
||||
TypeCheckResult analyze(CalculationExpressionNode toCheck);
|
||||
|
||||
TypeCheckResult analyze(DotExpressionNode toCheck);
|
||||
|
||||
TypeCheckResult analyze(DotSubstractionExpressionNode toCheck);
|
||||
|
||||
TypeCheckResult analyze(NonCalculationExpressionNode toCheck);
|
||||
|
||||
TypeCheckResult analyze(UnaryExpressionNode toCheck);
|
||||
|
||||
}
|
@ -2,6 +2,7 @@ package semantic.context;
|
||||
|
||||
import ast.member.FieldNode;
|
||||
import ast.type.*;
|
||||
import ast.type.type.TypeNode;
|
||||
|
||||
public class FieldContext {
|
||||
|
||||
|
@ -0,0 +1,9 @@
|
||||
package semantic.exeptions;
|
||||
|
||||
public class AlreadyDefinedException extends RuntimeException {
|
||||
|
||||
public AlreadyDefinedException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
package typechecker;
|
||||
|
||||
|
||||
import ast.type.TypeNode;
|
||||
import ast.type.type.TypeNode;
|
||||
|
||||
public class TypeCheckResult {
|
||||
|
||||
|
231
src/test/java/semantic/EndToTAST.java
Normal file
231
src/test/java/semantic/EndToTAST.java
Normal file
@ -0,0 +1,231 @@
|
||||
package semantic;
|
||||
|
||||
import ast.ASTNode;
|
||||
import ast.ProgramNode;
|
||||
import org.antlr.v4.runtime.CharStream;
|
||||
import org.antlr.v4.runtime.CharStreams;
|
||||
import org.antlr.v4.runtime.CommonTokenStream;
|
||||
import org.antlr.v4.runtime.tree.ParseTree;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import parser.astBuilder.ASTBuilder;
|
||||
import parser.generated.SimpleJavaLexer;
|
||||
import parser.generated.SimpleJavaParser;
|
||||
import semantic.exeptions.AlreadyDeclearedException;
|
||||
import semantic.exeptions.NotDeclearedException;
|
||||
import semantic.exeptions.TypeMismatchException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class EndToTAST {
|
||||
|
||||
@BeforeEach
|
||||
public void setup(){
|
||||
SemanticAnalyzer.clearAnalyzer();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void CorrectTest(){
|
||||
|
||||
CharStream codeCharStream = null;
|
||||
try {
|
||||
codeCharStream = CharStreams.fromPath(Paths.get("src/test/resources/semantic/endToTAST/CorrectTest.java"));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
SimpleJavaLexer lexer = new SimpleJavaLexer(codeCharStream);
|
||||
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
|
||||
|
||||
SimpleJavaParser parser = new SimpleJavaParser(tokenStream);
|
||||
ParseTree parseTree = parser.program(); // parse the input
|
||||
|
||||
/* ------------------------- AST builder -> AST ------------------------- */
|
||||
ASTBuilder astBuilder = new ASTBuilder();
|
||||
ProgramNode abstractSyntaxTree = (ProgramNode) astBuilder.visit(parseTree);
|
||||
|
||||
ASTNode tast = SemanticAnalyzer.generateTast(abstractSyntaxTree);
|
||||
|
||||
assertEquals(SemanticAnalyzer.errors.size(), 0);
|
||||
assertNotNull(tast);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void notDecleared() {
|
||||
|
||||
CharStream codeCharStream = null;
|
||||
try {
|
||||
codeCharStream = CharStreams.fromPath(Paths.get("src/test/resources/semantic/endToTAST/NotDecleared.java"));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
SimpleJavaLexer lexer = new SimpleJavaLexer(codeCharStream);
|
||||
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
|
||||
|
||||
SimpleJavaParser parser = new SimpleJavaParser(tokenStream);
|
||||
ParseTree parseTree = parser.program(); // parse the input
|
||||
|
||||
/* ------------------------- AST builder -> AST ------------------------- */
|
||||
ASTBuilder astBuilder = new ASTBuilder();
|
||||
ProgramNode abstractSyntaxTree = (ProgramNode) astBuilder.visit(parseTree);
|
||||
|
||||
ASTNode tast = SemanticAnalyzer.generateTast(abstractSyntaxTree);
|
||||
|
||||
assertFalse(SemanticAnalyzer.errors.isEmpty());
|
||||
assertInstanceOf(NotDeclearedException.class, SemanticAnalyzer.errors.getFirst());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void typeMismatch(){
|
||||
|
||||
CharStream codeCharStream = null;
|
||||
try {
|
||||
codeCharStream = CharStreams.fromPath(Paths.get("src/test/resources/semantic/endToTAST/TypeMismatchIntBool.java"));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
SimpleJavaLexer lexer = new SimpleJavaLexer(codeCharStream);
|
||||
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
|
||||
|
||||
SimpleJavaParser parser = new SimpleJavaParser(tokenStream);
|
||||
ParseTree parseTree = parser.program();
|
||||
|
||||
ASTBuilder astBuilder = new ASTBuilder();
|
||||
ProgramNode abstractSyntaxTree = (ProgramNode) astBuilder.visit(parseTree);
|
||||
|
||||
ASTNode tast = SemanticAnalyzer.generateTast(abstractSyntaxTree);
|
||||
|
||||
assertFalse(SemanticAnalyzer.errors.isEmpty());
|
||||
assertInstanceOf(TypeMismatchException.class, SemanticAnalyzer.errors.getFirst());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parameterAlreadyDecleared(){
|
||||
|
||||
CharStream codeCharStream = null;
|
||||
try {
|
||||
codeCharStream = CharStreams.fromPath(Paths.get("src/test/resources/semantic/endToTAST/ParameterAlreadyDecleared.java"));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
SimpleJavaLexer lexer = new SimpleJavaLexer(codeCharStream);
|
||||
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
|
||||
|
||||
SimpleJavaParser parser = new SimpleJavaParser(tokenStream);
|
||||
ParseTree parseTree = parser.program();
|
||||
|
||||
ASTBuilder astBuilder = new ASTBuilder();
|
||||
ProgramNode abstractSyntaxTree = (ProgramNode) astBuilder.visit(parseTree);
|
||||
|
||||
ASTNode tast = SemanticAnalyzer.generateTast(abstractSyntaxTree);
|
||||
|
||||
assertFalse(SemanticAnalyzer.errors.isEmpty());
|
||||
assertInstanceOf(AlreadyDeclearedException.class, SemanticAnalyzer.errors.getFirst());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fieldAlreadyDecleared(){
|
||||
|
||||
CharStream codeCharStream = null;
|
||||
try {
|
||||
codeCharStream = CharStreams.fromPath(Paths.get("src/test/resources/semantic/endToTAST/FieldAlreadyDecleared.java"));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
SimpleJavaLexer lexer = new SimpleJavaLexer(codeCharStream);
|
||||
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
|
||||
|
||||
SimpleJavaParser parser = new SimpleJavaParser(tokenStream);
|
||||
ParseTree parseTree = parser.program();
|
||||
|
||||
ASTBuilder astBuilder = new ASTBuilder();
|
||||
ProgramNode abstractSyntaxTree = (ProgramNode) astBuilder.visit(parseTree);
|
||||
|
||||
ASTNode tast = SemanticAnalyzer.generateTast(abstractSyntaxTree);
|
||||
|
||||
assertFalse(SemanticAnalyzer.errors.isEmpty());
|
||||
assertInstanceOf(AlreadyDeclearedException.class, SemanticAnalyzer.errors.getFirst());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void correctInstVarTest(){
|
||||
|
||||
CharStream codeCharStream = null;
|
||||
try {
|
||||
codeCharStream = CharStreams.fromPath(Paths.get("src/test/resources/semantic/endToTAST/CorrectInstVar.java"));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
SimpleJavaLexer lexer = new SimpleJavaLexer(codeCharStream);
|
||||
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
|
||||
|
||||
SimpleJavaParser parser = new SimpleJavaParser(tokenStream);
|
||||
ParseTree parseTree = parser.program();
|
||||
|
||||
ASTBuilder astBuilder = new ASTBuilder();
|
||||
ProgramNode abstractSyntaxTree = (ProgramNode) astBuilder.visit(parseTree);
|
||||
|
||||
ASTNode tast = SemanticAnalyzer.generateTast(abstractSyntaxTree);
|
||||
|
||||
assertTrue(SemanticAnalyzer.errors.isEmpty());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void typeMismatchRefType(){
|
||||
|
||||
CharStream codeCharStream = null;
|
||||
try {
|
||||
codeCharStream = CharStreams.fromPath(Paths.get("src/test/resources/semantic/endToTAST/TypeMismatchRefType.java"));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
SimpleJavaLexer lexer = new SimpleJavaLexer(codeCharStream);
|
||||
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
|
||||
|
||||
SimpleJavaParser parser = new SimpleJavaParser(tokenStream);
|
||||
ParseTree parseTree = parser.program();
|
||||
|
||||
ASTBuilder astBuilder = new ASTBuilder();
|
||||
ProgramNode abstractSyntaxTree = (ProgramNode) astBuilder.visit(parseTree);
|
||||
|
||||
ASTNode tast = SemanticAnalyzer.generateTast(abstractSyntaxTree);
|
||||
|
||||
assertFalse(SemanticAnalyzer.errors.isEmpty());
|
||||
assertInstanceOf(TypeMismatchException.class, SemanticAnalyzer.errors.getFirst());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void correctRetType(){
|
||||
|
||||
CharStream codeCharStream = null;
|
||||
try {
|
||||
codeCharStream = CharStreams.fromPath(Paths.get("src/test/resources/semantic/endToTAST/TypeMismatchRefType.java"));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
SimpleJavaLexer lexer = new SimpleJavaLexer(codeCharStream);
|
||||
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
|
||||
|
||||
SimpleJavaParser parser = new SimpleJavaParser(tokenStream);
|
||||
ParseTree parseTree = parser.program();
|
||||
|
||||
ASTBuilder astBuilder = new ASTBuilder();
|
||||
ProgramNode abstractSyntaxTree = (ProgramNode) astBuilder.visit(parseTree);
|
||||
|
||||
ASTNode tast = SemanticAnalyzer.generateTast(abstractSyntaxTree);
|
||||
|
||||
assertFalse(SemanticAnalyzer.errors.isEmpty());
|
||||
assertInstanceOf(TypeMismatchException.class, SemanticAnalyzer.errors.getFirst());
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -5,15 +5,8 @@ import ast.block.BlockNode;
|
||||
import ast.member.FieldNode;
|
||||
import ast.member.MethodNode;
|
||||
import ast.parameter.ParameterNode;
|
||||
import ast.statement.StatementNode;
|
||||
import ast.statement.statementexpression.NewDeclarationStatementExpressionNode;
|
||||
import ast.type.AccessModifierNode;
|
||||
import ast.type.TypeNode;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static parser.generated.SimpleJavaParser.Identifier;
|
||||
import ast.type.type.TypeNode;
|
||||
|
||||
public class Mocker {
|
||||
|
||||
@ -68,7 +61,7 @@ public class Mocker {
|
||||
methodNode.block = new BlockNode();
|
||||
methodNode.type = new TypeNode("int");
|
||||
|
||||
methodNode.identifier = "testMethod";
|
||||
methodNode.setIdentifier("testMethod");
|
||||
|
||||
c.members.add(methodNode);
|
||||
|
||||
@ -76,7 +69,7 @@ public class Mocker {
|
||||
methodNode1.block = new BlockNode();
|
||||
methodNode1.type = new TypeNode("int");
|
||||
|
||||
methodNode1.identifier = "testMethod";
|
||||
methodNode1.setIdentifier("testMethod");
|
||||
|
||||
c.members.add(methodNode1);
|
||||
|
||||
@ -92,13 +85,13 @@ public class Mocker {
|
||||
|
||||
MethodNode methodNode = new MethodNode();
|
||||
methodNode.block = new BlockNode();
|
||||
methodNode.identifier = "testMethod";
|
||||
methodNode.setIdentifier("testMethod");
|
||||
|
||||
c.members.add(methodNode);
|
||||
|
||||
MethodNode methodNode1 = new MethodNode();
|
||||
methodNode1.block = new BlockNode();
|
||||
methodNode1.identifier = "testMethod1";
|
||||
methodNode1.setIdentifier("testMethod1");
|
||||
|
||||
c.members.add(methodNode1);
|
||||
|
||||
|
@ -9,20 +9,17 @@ import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class SemanticTest {
|
||||
|
||||
@BeforeEach
|
||||
public void setup(){
|
||||
SemanticAnalyzer.clearAnalyzier();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void twoFieldsSameName() {
|
||||
|
||||
ASTNode ast = Mocker.mockTwoSameFields();
|
||||
|
||||
ASTNode tast = SemanticAnalyzer.generateTast(ast);
|
||||
SemanticAnalyzer semanticAnalyzer = new SemanticAnalyzer();
|
||||
ASTNode tast = semanticAnalyzer.generateTast(ast);
|
||||
|
||||
assertEquals(SemanticAnalyzer.errors.size(), 1);
|
||||
assertInstanceOf(AlreadyDeclearedException.class, SemanticAnalyzer.errors.getFirst());
|
||||
assertEquals(semanticAnalyzer.errors.size(), 1);
|
||||
assertInstanceOf(AlreadyDeclearedException.class, semanticAnalyzer.errors.getFirst());
|
||||
assertNull(tast);
|
||||
|
||||
}
|
||||
@ -32,9 +29,10 @@ public class SemanticTest {
|
||||
|
||||
ASTNode ast = Mocker.mockSimpleMethod();
|
||||
|
||||
ASTNode tast = SemanticAnalyzer.generateTast(ast);
|
||||
SemanticAnalyzer semanticAnalyzer = new SemanticAnalyzer();
|
||||
ASTNode tast = semanticAnalyzer.generateTast(ast);
|
||||
|
||||
assertEquals(SemanticAnalyzer.errors.size(), 0);
|
||||
assertEquals(semanticAnalyzer.errors.size(), 0);
|
||||
assertNotNull(tast);
|
||||
|
||||
}
|
||||
@ -43,10 +41,11 @@ public class SemanticTest {
|
||||
public void twoSameMethods(){
|
||||
ASTNode ast = Mocker.mockTwoSameMethods();
|
||||
|
||||
ASTNode tast = SemanticAnalyzer.generateTast(ast);
|
||||
SemanticAnalyzer semanticAnalyzer = new SemanticAnalyzer();
|
||||
ASTNode tast = semanticAnalyzer.generateTast(ast);
|
||||
|
||||
assertEquals(1, SemanticAnalyzer.errors.size());
|
||||
assertInstanceOf(AlreadyDeclearedException.class, SemanticAnalyzer.errors.getFirst());
|
||||
assertEquals(1, semanticAnalyzer.errors.size());
|
||||
assertInstanceOf(AlreadyDeclearedException.class, semanticAnalyzer.errors.getFirst());
|
||||
assertNull(tast);
|
||||
}
|
||||
|
||||
@ -54,9 +53,10 @@ public class SemanticTest {
|
||||
public void twoDifferentMethods(){
|
||||
ASTNode ast = Mocker.mockTwoDifferentMethods();
|
||||
|
||||
ASTNode tast = SemanticAnalyzer.generateTast(ast);
|
||||
SemanticAnalyzer semanticAnalyzer = new SemanticAnalyzer();
|
||||
ASTNode tast = semanticAnalyzer.generateTast(ast);
|
||||
|
||||
assertEquals(SemanticAnalyzer.errors.size(), 0);
|
||||
assertEquals(semanticAnalyzer.errors.size(), 0);
|
||||
assertNotNull(tast);
|
||||
}
|
||||
|
||||
|
@ -1,51 +0,0 @@
|
||||
package semantic.endToTAST;
|
||||
|
||||
import ast.ASTNode;
|
||||
import ast.ProgramNode;
|
||||
import org.antlr.v4.runtime.CharStream;
|
||||
import org.antlr.v4.runtime.CharStreams;
|
||||
import org.antlr.v4.runtime.CommonTokenStream;
|
||||
import org.antlr.v4.runtime.tree.ParseTree;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import parser.astBuilder.ASTBuilder;
|
||||
import parser.generated.SimpleJavaLexer;
|
||||
import parser.generated.SimpleJavaParser;
|
||||
import semantic.SemanticAnalyzer;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
public class CorrectTest {
|
||||
|
||||
@Test
|
||||
public void first(){
|
||||
|
||||
CharStream codeCharStream = null;
|
||||
try {
|
||||
codeCharStream = CharStreams.fromPath(Paths.get("src/test/resources/semantic/endToTAST/Test.java"));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
SimpleJavaLexer lexer = new SimpleJavaLexer(codeCharStream);
|
||||
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
|
||||
|
||||
SimpleJavaParser parser = new SimpleJavaParser(tokenStream);
|
||||
ParseTree parseTree = parser.program(); // parse the input
|
||||
|
||||
/* ------------------------- AST builder -> AST ------------------------- */
|
||||
ASTBuilder astBuilder = new ASTBuilder();
|
||||
ProgramNode abstractSyntaxTree = (ProgramNode) astBuilder.visit(parseTree);
|
||||
|
||||
System.out.println("Test");
|
||||
|
||||
ASTNode tast = SemanticAnalyzer.generateTast(abstractSyntaxTree);
|
||||
|
||||
System.out.println("Errors: " + SemanticAnalyzer.errors.size());
|
||||
|
||||
assertEquals(SemanticAnalyzer.errors.size(), 0);
|
||||
|
||||
}
|
||||
|
||||
}
|
18
src/test/resources/semantic/endToTAST/CorrectInstVar.java
Normal file
18
src/test/resources/semantic/endToTAST/CorrectInstVar.java
Normal file
@ -0,0 +1,18 @@
|
||||
public class Test {
|
||||
|
||||
public Example ex;
|
||||
|
||||
public static int testMethod(char x){
|
||||
|
||||
int b = this.ex.a;
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class Example {
|
||||
|
||||
public int a;
|
||||
|
||||
}
|
16
src/test/resources/semantic/endToTAST/CorrectTest.java
Normal file
16
src/test/resources/semantic/endToTAST/CorrectTest.java
Normal file
@ -0,0 +1,16 @@
|
||||
public class Example {
|
||||
|
||||
public int a;
|
||||
|
||||
public static int testMethod(char x){
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class Test {
|
||||
|
||||
public static int testMethod(char x, int a){
|
||||
return x;
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
public class Example {
|
||||
|
||||
public int a;
|
||||
public int a;
|
||||
|
||||
public static int testMethod(char a){
|
||||
|
||||
}
|
||||
|
||||
}
|
6
src/test/resources/semantic/endToTAST/NotDecleared.java
Normal file
6
src/test/resources/semantic/endToTAST/NotDecleared.java
Normal file
@ -0,0 +1,6 @@
|
||||
public class Test {
|
||||
public static int testMethod(int x){
|
||||
int a = b;
|
||||
return x;
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
public class Example {
|
||||
|
||||
public static int testMethod(char a, int a){
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
public class Test {
|
||||
|
||||
public boolean b;
|
||||
public boolean b;
|
||||
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
public class Test {
|
||||
|
||||
public boolean b;
|
||||
|
||||
public static int testMethod(int a){
|
||||
|
||||
b = a;
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
public class Test {
|
||||
|
||||
public static int testMethod(ExampleA exampleA, ExampleB exampleB){
|
||||
|
||||
exampleA = exampleB;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public class ExampleA{
|
||||
public int a;
|
||||
}
|
||||
|
||||
public class ExampleB{
|
||||
public int a;
|
||||
}
|
Loading…
Reference in New Issue
Block a user