Trying to change to new AST
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
978b5a2b4a
commit
fd8c3b066a
@ -1,6 +1,5 @@
|
||||
import oldAst.ASTNode;
|
||||
import ast.*;
|
||||
import org.antlr.v4.runtime.*;
|
||||
import oldAst.ProgramNode;
|
||||
import bytecode.ByteCodeGenerator;
|
||||
import org.antlr.v4.runtime.CharStream;
|
||||
import org.antlr.v4.runtime.CharStreams;
|
||||
|
@ -9,16 +9,15 @@ import semantic.SemanticVisitor;
|
||||
import typechecker.TypeCheckResult;
|
||||
import visitor.Visitable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class MethodNode implements MemberNode {
|
||||
public class MethodNode implements MemberNode, Visitable {
|
||||
AccessModifierNode accesModifier;
|
||||
TypeNode type;
|
||||
Boolean voidType;
|
||||
String identifier;
|
||||
List<ParameterNode> parameters;
|
||||
BlockNode block;
|
||||
public BlockNode block;
|
||||
|
||||
public MethodNode() {}
|
||||
|
||||
@ -55,6 +54,8 @@ public class MethodNode implements MemberNode {
|
||||
return isSame;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
@Override
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return visitor.analyze(this);
|
||||
@ -64,6 +65,6 @@ public class MethodNode implements MemberNode {
|
||||
public void accept(MethodVisitor methodVisitor) {
|
||||
methodVisitor.visit(this);
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
}
|
||||
|
@ -2,10 +2,6 @@ package ast.statement;
|
||||
|
||||
import ast.ASTNode;
|
||||
import ast.expression.ExpressionNode;
|
||||
import ast.type.TypeNode;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ReturnStatementNode implements ASTNode {
|
||||
public ExpressionNode expression;
|
||||
|
@ -4,11 +4,10 @@ import ast.ClassNode;
|
||||
import ast.member.FieldNode;
|
||||
import ast.member.MemberNode;
|
||||
import ast.member.MethodNode;
|
||||
import ast.type.BaseTypeNode;
|
||||
import ast.type.TypeNode;
|
||||
import bytecode.visitor.ClassVisitor;
|
||||
import java.io.File;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
@ -25,8 +24,8 @@ public class ClassCodeGen implements ClassVisitor {
|
||||
@Override
|
||||
public void visit(ClassNode classNode) {
|
||||
classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
|
||||
classWriter.visit(Opcodes.V1_5, mapper.mapAccessTypeToOpcode(classNode.accessType), classNode.identifier, null,
|
||||
"java/lang/Object", null);
|
||||
// classWriter.visit(Opcodes.V1_5, mapper.mapAccessTypeToOpcode(classNode.accessType), classNode.identifier, null,
|
||||
// "java/lang/Object", null);
|
||||
|
||||
for (MemberNode memberNode : classNode.members) {
|
||||
if (memberNode instanceof FieldNode) {
|
||||
@ -45,8 +44,8 @@ public class ClassCodeGen implements ClassVisitor {
|
||||
|
||||
@Override
|
||||
public void visit(FieldNode fieldNode) {
|
||||
if(fieldNode.type instanceof BaseTypeNode baseTypeNode){
|
||||
classWriter.visitField(mapper.mapAccessTypeToOpcode(fieldNode.accessTypeNode), fieldNode.identifier, mapper.getTypeChar(baseTypeNode.enumType), null, null );
|
||||
if(fieldNode.type instanceof TypeNode baseTypeNode){
|
||||
// classWriter.visitField(mapper.mapAccessTypeToOpcode(fieldNode.accessTypeNode), fieldNode.identifier, mapper.getTypeChar(baseTypeNode.enumType), null, null );
|
||||
}
|
||||
classWriter.visitEnd();
|
||||
}
|
||||
|
@ -1,44 +1,41 @@
|
||||
package bytecode;
|
||||
|
||||
import ast.parameter.ParameterNode;
|
||||
import ast.type.*;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import ast.type.BaseTypeNode;
|
||||
|
||||
public class Mapper {
|
||||
public int mapAccessTypeToOpcode(AccessTypeNode type) {
|
||||
switch (type.enumAccessTypeNode) {
|
||||
case EnumAccessTypeNode.PUBLIC:
|
||||
return Opcodes.ACC_PUBLIC;
|
||||
case EnumAccessTypeNode.PRIVATE:
|
||||
return Opcodes.ACC_PRIVATE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
// public int mapAccessTypeToOpcode(AccessModifierNode type) {
|
||||
// switch (type.enumAccessTypeNode) {
|
||||
// case EnumAccessTypeNode.PUBLIC:
|
||||
// return Opcodes.ACC_PUBLIC;
|
||||
// case EnumAccessTypeNode.PRIVATE:
|
||||
// return Opcodes.ACC_PRIVATE;
|
||||
// }
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
public String generateMethodDescriptor(BaseTypeNode baseTypeNode, ParameterListNode parameterListNode) {
|
||||
String descriptor = "(";
|
||||
for(ParameterNode parameterNode : parameterListNode.parameters) {
|
||||
descriptor += getTypeChar(EnumTypeNode.INT);
|
||||
}
|
||||
descriptor += ")";
|
||||
descriptor += getTypeChar(baseTypeNode.enumType);
|
||||
return descriptor;
|
||||
}
|
||||
// public String generateMethodDescriptor(BaseTypeNode baseTypeNode, ParameterListNode parameterListNode) {
|
||||
// String descriptor = "(";
|
||||
// for(ParameterNode parameterNode : parameterListNode.parameters) {
|
||||
// descriptor += getTypeChar(EnumTypeNode.INT);
|
||||
// }
|
||||
// descriptor += ")";
|
||||
// descriptor += getTypeChar(baseTypeNode.enumType);
|
||||
// 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;
|
||||
}
|
||||
// public String getTypeChar(TypeEnum enumTypeNode) {
|
||||
// String typeChar = "";
|
||||
// switch (enumTypeNode) {
|
||||
// case TypeEnum.INT:
|
||||
// typeChar = "I";
|
||||
// break;
|
||||
// case TypeEnum.CHAR:
|
||||
// typeChar = "C";
|
||||
// break;
|
||||
// case TypeEnum.BOOLEAN:
|
||||
// typeChar = "Z";
|
||||
// break;
|
||||
// }
|
||||
// return typeChar;
|
||||
// }
|
||||
}
|
||||
|
@ -2,12 +2,8 @@ package bytecode;
|
||||
|
||||
import ast.member.ConstructorNode;
|
||||
import ast.member.MethodNode;
|
||||
import ast.parameter.ParameterNode;
|
||||
import ast.type.BaseTypeNode;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.Label;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -31,12 +27,12 @@ public class MethodCodeGen implements bytecode.visitor.MethodVisitor {
|
||||
|
||||
@Override
|
||||
public void visit(ConstructorNode constructorNode) {
|
||||
methodVisitor =
|
||||
classWriter.visitMethod(mapper.mapAccessTypeToOpcode(constructorNode.visibility),
|
||||
"<init>",
|
||||
"()V",
|
||||
null,
|
||||
null);
|
||||
// methodVisitor =
|
||||
// classWriter.visitMethod(mapper.mapAccessTypeToOpcode(constructorNode.visibility),
|
||||
// "<init>",
|
||||
// "()V",
|
||||
// null,
|
||||
// null);
|
||||
methodVisitor.visitCode();
|
||||
methodVisitor.visitVarInsn(ALOAD, 0);
|
||||
methodVisitor.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
|
||||
@ -47,52 +43,52 @@ public class MethodCodeGen implements bytecode.visitor.MethodVisitor {
|
||||
|
||||
@Override
|
||||
public void visit(MethodNode methodNode) {
|
||||
if (methodNode.type instanceof BaseTypeNode baseTypeNode) {
|
||||
methodVisitor = classWriter.visitMethod(mapper.mapAccessTypeToOpcode(methodNode.visibility),
|
||||
methodNode.identifier,
|
||||
mapper.generateMethodDescriptor(baseTypeNode, methodNode.parameters),
|
||||
null,
|
||||
null);
|
||||
// if (methodNode.type instanceof BaseTypeNode baseTypeNode) {
|
||||
// methodVisitor = classWriter.visitMethod(mapper.mapAccessTypeToOpcode(methodNode.visibility),
|
||||
// methodNode.identifier,
|
||||
// mapper.generateMethodDescriptor(baseTypeNode, methodNode.parameters),
|
||||
// null,
|
||||
// null);
|
||||
|
||||
methodVisitor.visitCode();
|
||||
localVaribales.add("this");
|
||||
for (ParameterNode parameterNode : methodNode.parameters.parameters) {
|
||||
localVaribales.add(parameterNode.identifier);
|
||||
}
|
||||
// for (ParameterNode parameterNode : methodNode.parameters.parameters) {
|
||||
// localVaribales.add(parameterNode.identifier);
|
||||
// }
|
||||
|
||||
//test();
|
||||
methodVisitor.visitMaxs(1, localVaribales.size());
|
||||
methodVisitor.visitEnd();
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
public void test() {
|
||||
Label start = new Label();
|
||||
Label loop = new Label();
|
||||
Label end = new Label();
|
||||
methodVisitor.visitLabel(start);
|
||||
//methodVisitor.visitVarInsn(Opcodes.ICONST_M1, 99);
|
||||
//methodVisitor.visitInsn(Opcodes.ICONST_5);
|
||||
methodVisitor.visitLdcInsn(99);
|
||||
// methodVisitor.visitInsn(Opcodes.ICONST_0);
|
||||
//methodVisitor.visitVarInsn(Opcodes.ILOAD, 2);
|
||||
methodVisitor.visitVarInsn(Opcodes.ISTORE, 1);
|
||||
methodVisitor.visitLabel(loop);
|
||||
methodVisitor.visitVarInsn(Opcodes.ILOAD, 1);
|
||||
methodVisitor.visitInsn(Opcodes.ICONST_5);
|
||||
methodVisitor.visitJumpInsn(Opcodes.IF_ICMPGE, end);
|
||||
methodVisitor.visitFieldInsn(Opcodes.GETSTATIC,
|
||||
"java/lang/System", "out",
|
||||
"Ljava/io/PrintStream;");
|
||||
methodVisitor.visitLdcInsn("Bytecode");
|
||||
methodVisitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
|
||||
"java/io/PrintStream", "println",
|
||||
"(Ljava/lang/String;)V", false);
|
||||
methodVisitor.visitIincInsn(1, 1);
|
||||
methodVisitor.visitJumpInsn(Opcodes.GOTO, loop);
|
||||
methodVisitor.visitLabel(end);
|
||||
methodVisitor.visitVarInsn(Opcodes.ILOAD, 1);
|
||||
methodVisitor.visitInsn(Opcodes.IRETURN);
|
||||
methodVisitor.visitEnd();
|
||||
}
|
||||
// public void test() {
|
||||
// Label start = new Label();
|
||||
// Label loop = new Label();
|
||||
// Label end = new Label();
|
||||
// methodVisitor.visitLabel(start);
|
||||
// //methodVisitor.visitVarInsn(Opcodes.ICONST_M1, 99);
|
||||
// //methodVisitor.visitInsn(Opcodes.ICONST_5);
|
||||
// methodVisitor.visitLdcInsn(99);
|
||||
// // methodVisitor.visitInsn(Opcodes.ICONST_0);
|
||||
// //methodVisitor.visitVarInsn(Opcodes.ILOAD, 2);
|
||||
// methodVisitor.visitVarInsn(Opcodes.ISTORE, 1);
|
||||
// methodVisitor.visitLabel(loop);
|
||||
// methodVisitor.visitVarInsn(Opcodes.ILOAD, 1);
|
||||
// methodVisitor.visitInsn(Opcodes.ICONST_5);
|
||||
// methodVisitor.visitJumpInsn(Opcodes.IF_ICMPGE, end);
|
||||
// methodVisitor.visitFieldInsn(Opcodes.GETSTATIC,
|
||||
// "java/lang/System", "out",
|
||||
// "Ljava/io/PrintStream;");
|
||||
// methodVisitor.visitLdcInsn("Bytecode");
|
||||
// methodVisitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
|
||||
// "java/io/PrintStream", "println",
|
||||
// "(Ljava/lang/String;)V", false);
|
||||
// methodVisitor.visitIincInsn(1, 1);
|
||||
// methodVisitor.visitJumpInsn(Opcodes.GOTO, loop);
|
||||
// methodVisitor.visitLabel(end);
|
||||
// methodVisitor.visitVarInsn(Opcodes.ILOAD, 1);
|
||||
// methodVisitor.visitInsn(Opcodes.IRETURN);
|
||||
// methodVisitor.visitEnd();
|
||||
// }
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
package semantic;
|
||||
|
||||
import oldAst.type.TypeNode;
|
||||
import ast.type.TypeNode;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Stack;
|
||||
|
@ -1,25 +1,16 @@
|
||||
package semantic;
|
||||
|
||||
|
||||
import oldAst.*;
|
||||
import oldAst.expression.*;
|
||||
import oldAst.member.FieldNode;
|
||||
import oldAst.member.MemberNode;
|
||||
|
||||
import oldAst.member.MethodNode;
|
||||
import oldAst.parameter.ParameterListNode;
|
||||
import oldAst.parameter.ParameterNode;
|
||||
import oldAst.statement.*;
|
||||
import oldAst.type.ReferenceTypeNode;
|
||||
import oldAst.expression.This;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import oldAst.type.BaseTypeNode;
|
||||
import oldAst.type.TypeNode;
|
||||
import ast.*;
|
||||
import ast.member.*;
|
||||
import ast.statement.*;
|
||||
import ast.statement.ifstatement.IfStatementNode;
|
||||
import ast.type.*;
|
||||
import semantic.context.Context;
|
||||
import semantic.exeptions.AlreadyDeclearedException;
|
||||
import semantic.exeptions.NotDeclearedException;
|
||||
@ -90,10 +81,7 @@ public class SemanticAnalyzer implements SemanticVisitor {
|
||||
for(MethodNode methode : currentClass.getMethods()){
|
||||
if(methode.equals(methodNode))
|
||||
break;
|
||||
if(methode.isSame(methodNode)){
|
||||
errors.add(new AlreadyDeclearedException("This method has already been declared"));
|
||||
valid = false;
|
||||
}
|
||||
|
||||
}
|
||||
var result = methodNode.accept(this);
|
||||
valid = valid && result.isValid();
|
||||
@ -110,32 +98,6 @@ public class SemanticAnalyzer implements SemanticVisitor {
|
||||
|
||||
currentScope.pushScope();
|
||||
|
||||
//Parameter
|
||||
ParameterListNode parameterListNode = methodNode.parameters;
|
||||
if (parameterListNode != null) {
|
||||
List<ParameterNode> parameters = parameterListNode.parameters;
|
||||
for (ParameterNode parameter : parameters) {
|
||||
if (currentScope.contains(parameter.identifier)) {
|
||||
errors.add(new AlreadyDeclearedException("Duplicated Parameter " + parameter.identifier));
|
||||
return new TypeCheckResult(false, null);
|
||||
} else {
|
||||
currentScope.addLocalVar(parameter.identifier, parameter.type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Statements
|
||||
List<StatementNode> 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();
|
||||
}
|
||||
}
|
||||
|
||||
currentScope.popScope();
|
||||
return new TypeCheckResult(valid, null);
|
||||
}
|
||||
@ -151,80 +113,6 @@ public class SemanticAnalyzer implements SemanticVisitor {
|
||||
return new TypeCheckResult(true, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult analyze(AssignmentStatementNode assignmentStatementNode) {
|
||||
boolean valid = true;
|
||||
ExpressionNode expressionNodeLeft = assignmentStatementNode.expressionLeft;
|
||||
var resultLeft = expressionNodeLeft.accept(this);
|
||||
valid = valid && resultLeft.isValid();
|
||||
ExpressionNode expressionNodeRight = assignmentStatementNode.expressionRight;
|
||||
var resultRight = expressionNodeRight.accept(this);
|
||||
valid = valid && resultRight.isValid();
|
||||
|
||||
if(Objects.equals(resultLeft.getType(), resultRight.getType())){
|
||||
System.out.println("SAME TYPE");
|
||||
} else {
|
||||
errors.add(new TypeMismatchException("Type mismatch"));
|
||||
valid = false;
|
||||
}
|
||||
|
||||
return new TypeCheckResult(valid, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult analyze(BinaryExpressionNode toCheck) {
|
||||
boolean valid = true;
|
||||
ExpressionNode left = toCheck.left;
|
||||
var resultLeft = left.accept(this);
|
||||
ExpressionNode right = toCheck.right;
|
||||
var resultRight = right.accept(this);
|
||||
|
||||
switch (toCheck.operator) {
|
||||
case ASSIGNMENT:
|
||||
if(Objects.equals(resultRight.getType(), resultLeft.getType())){
|
||||
System.out.println("Correct Type");
|
||||
} else {
|
||||
valid = false;
|
||||
errors.add(new TypeMismatchException("Type Mismatch " + resultLeft.getType() + " and " + resultRight.getType()));
|
||||
}
|
||||
break;
|
||||
case DOT:
|
||||
return new TypeCheckResult(true, resultRight.getType());
|
||||
default:
|
||||
throw new RuntimeException("Unexpected operator: " + toCheck.operator);
|
||||
}
|
||||
|
||||
return new TypeCheckResult(valid, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult analyze(IdentifierExpressionNode toCheck) {
|
||||
if(toCheck.name == "this"){
|
||||
return new TypeCheckResult(true, null);
|
||||
} else if (currentFields.get(toCheck.name) == null) {
|
||||
errors.add(new AlreadyDeclearedException("Not declared " + toCheck.name + " in this scope"));
|
||||
return new TypeCheckResult(false, null);
|
||||
} else {
|
||||
return new TypeCheckResult(false, currentFields.get(toCheck.name));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult analyze(UnaryExpressionNode toCheck) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult analyze(VariableDeclarationStatementNode toCheck) {
|
||||
if (currentScope.contains(toCheck.identifier)) {
|
||||
errors.add(new AlreadyDeclearedException("Already declared " + toCheck.identifier + " in this scope"));
|
||||
return new TypeCheckResult(false, null);
|
||||
} else {
|
||||
currentScope.addLocalVar(toCheck.identifier, toCheck.type);
|
||||
}
|
||||
return new TypeCheckResult(true, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult analyze(IfStatementNode toCheck) {
|
||||
return null;
|
||||
@ -240,40 +128,4 @@ public class SemanticAnalyzer implements SemanticVisitor {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult analyze(LiteralNode toCheck) {
|
||||
return new TypeCheckResult(true, toCheck.getType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult analyze(InstVar toCheck) {
|
||||
boolean valid = true;
|
||||
|
||||
var result = toCheck.expression.accept(this);
|
||||
|
||||
if(result.getType() instanceof BaseTypeNode){
|
||||
throw new RuntimeException("BaseType has no Methods or Fields");
|
||||
} else {
|
||||
//Get typ of Field
|
||||
|
||||
var type = (ReferenceTypeNode)result.getType();
|
||||
var classContext = context.getClass(type.getIdentifier());
|
||||
|
||||
if(classContext == null){
|
||||
errors.add(new NotDeclearedException("Not declared " + type.getIdentifier() + " in this scope"));
|
||||
return new TypeCheckResult(false, null);
|
||||
} else {
|
||||
var field = classContext.getField(toCheck.identifier);
|
||||
|
||||
return new TypeCheckResult(valid, field.getType());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult analyze(This toCheck) {
|
||||
return new TypeCheckResult(true, toCheck.getType());
|
||||
}
|
||||
|
||||
}
|
@ -1,18 +1,10 @@
|
||||
package semantic;
|
||||
|
||||
|
||||
import ast.ClassNode;
|
||||
import ast.expression.LiteralNode;
|
||||
import ast.ProgramNode;
|
||||
import ast.expression.BinaryExpressionNode;
|
||||
import ast.expression.IdentifierExpressionNode;
|
||||
import ast.expression.InstVar;
|
||||
import ast.expression.unaryexpression.UnaryExpressionNode;
|
||||
import ast.member.FieldNode;
|
||||
import ast.member.MethodNode;
|
||||
import ast.*;
|
||||
import ast.member.*;
|
||||
import ast.statement.*;
|
||||
import ast.expression.This;
|
||||
import ast.statement.ifstatement.IfStatementNode;
|
||||
import ast.statement.ifstatement.*;
|
||||
import typechecker.TypeCheckResult;
|
||||
|
||||
public interface SemanticVisitor {
|
||||
@ -25,25 +17,10 @@ public interface SemanticVisitor {
|
||||
|
||||
TypeCheckResult analyze(FieldNode toCheck);
|
||||
|
||||
TypeCheckResult analyze(AssignmentStatementNode toCheck);
|
||||
|
||||
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);
|
||||
|
||||
TypeCheckResult analyze(LiteralNode toCheck);
|
||||
|
||||
TypeCheckResult analyze(InstVar toCheck);
|
||||
|
||||
TypeCheckResult analyze(This toCheck);
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
package semantic.context;
|
||||
|
||||
import oldAst.ClassNode;
|
||||
import oldAst.member.FieldNode;
|
||||
import ast.ClassNode;
|
||||
import ast.member.FieldNode;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class ClassContext {
|
||||
|
@ -1,6 +1,6 @@
|
||||
package semantic.context;
|
||||
|
||||
import oldAst.ProgramNode;
|
||||
import ast.ProgramNode;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class Context {
|
||||
|
@ -1,12 +1,11 @@
|
||||
package semantic.context;
|
||||
|
||||
import oldAst.member.FieldNode;
|
||||
import oldAst.type.AccessTypeNode;
|
||||
import oldAst.type.TypeNode;
|
||||
import ast.member.FieldNode;
|
||||
import ast.type.*;
|
||||
|
||||
public class FieldContext {
|
||||
|
||||
private AccessTypeNode accessModifier;
|
||||
private AccessModifierNode accessModifier;
|
||||
private TypeNode type;
|
||||
|
||||
public FieldContext(FieldNode field) {
|
||||
|
@ -1,7 +1,7 @@
|
||||
package typechecker;
|
||||
|
||||
|
||||
import oldAst.type.TypeNode;
|
||||
import ast.type.TypeNode;
|
||||
|
||||
public class TypeCheckResult {
|
||||
|
||||
|
@ -1,76 +1,36 @@
|
||||
package semantic;
|
||||
|
||||
import oldAst.ClassNode;
|
||||
import oldAst.expression.LiteralNode;
|
||||
import oldAst.ProgramNode;
|
||||
import oldAst.expression.*;
|
||||
import oldAst.member.FieldNode;
|
||||
import oldAst.member.MemberNode;
|
||||
import oldAst.member.MethodNode;
|
||||
import oldAst.parameter.ParameterListNode;
|
||||
import oldAst.parameter.ParameterNode;
|
||||
import oldAst.statement.AssignmentStatementNode;
|
||||
import oldAst.statement.StatementNode;
|
||||
import oldAst.type.*;
|
||||
import ast.*;
|
||||
import ast.block.BlockNode;
|
||||
import ast.member.MethodNode;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static parser.generated.SimpleJavaParser.Identifier;
|
||||
|
||||
public class Mocker {
|
||||
|
||||
public static ProgramNode mockCorrectProgrammNode(){
|
||||
public static ProgramNode mockCorrectClass(){
|
||||
ProgramNode p = new ProgramNode();
|
||||
|
||||
ProgramNode programNode = new ProgramNode();
|
||||
List<ClassNode> classList = new ArrayList<ClassNode>();
|
||||
AccessTypeNode accessTypeNode = new AccessTypeNode(EnumAccessTypeNode.PUBLIC);
|
||||
ClassNode classNode = new ClassNode(accessTypeNode, "testClass");
|
||||
ClassNode c = new ClassNode();
|
||||
c.identifier = "testClass";
|
||||
|
||||
MemberNode memberNode1 = new FieldNode(accessTypeNode, new BaseTypeNode(EnumTypeNode.INT), "testVar1");
|
||||
classNode.members.add(memberNode1);
|
||||
MethodNode m = new MethodNode();
|
||||
|
||||
MemberNode memberNode2 = new FieldNode(accessTypeNode, new BaseTypeNode(EnumTypeNode.INT), "objectVar");
|
||||
classNode.members.add(memberNode2);
|
||||
BlockNode b = new BlockNode();
|
||||
|
||||
List<ParameterNode> parameterNodeList = new ArrayList<ParameterNode>();
|
||||
ParameterNode parameterNode1 = new ParameterNode(new BaseTypeNode(EnumTypeNode.INT), "param1");
|
||||
parameterNodeList.add(parameterNode1);
|
||||
ParameterListNode parameterListNode = new ParameterListNode(parameterNodeList);
|
||||
|
||||
List<StatementNode> statementNodeList = new ArrayList<StatementNode>();
|
||||
|
||||
ExpressionNode expressionNodeLeft = new InstVar(new This("testClass"), "objectVar");
|
||||
// b.statements.add();
|
||||
|
||||
LiteralNode expressionNodeRight = new LiteralNode();
|
||||
expressionNodeRight.setType(new BaseTypeNode(EnumTypeNode.INT));
|
||||
m.block = b;
|
||||
|
||||
StatementNode statementNode1 = new AssignmentStatementNode(expressionNodeLeft, expressionNodeRight);
|
||||
statementNodeList.add(statementNode1);
|
||||
|
||||
MemberNode memberNode3 = new MethodNode(accessTypeNode, new BaseTypeNode(EnumTypeNode.INT), "testVar2",parameterListNode, statementNodeList );
|
||||
classNode.members.add(memberNode3);
|
||||
|
||||
classList.add(classNode);
|
||||
programNode.classes = classList;
|
||||
|
||||
return programNode;
|
||||
c.members.add(m);
|
||||
|
||||
p.classes.add(c);
|
||||
return p;
|
||||
}
|
||||
|
||||
public static ProgramNode mockFieldNodeAlreadyDeclaredProgrammNode(){
|
||||
ProgramNode programNode = new ProgramNode();
|
||||
List<ClassNode> classList = new ArrayList<ClassNode>();
|
||||
AccessTypeNode accessTypeNode = new AccessTypeNode(EnumAccessTypeNode.PUBLIC);
|
||||
ClassNode classNode = new ClassNode(accessTypeNode, "testClass");
|
||||
|
||||
MemberNode memberNode1 = new FieldNode(accessTypeNode, new BaseTypeNode(EnumTypeNode.INT), "testVar");
|
||||
classNode.members.add(memberNode1);
|
||||
|
||||
MemberNode memberNode2 = new FieldNode(accessTypeNode, new BaseTypeNode(EnumTypeNode.INT), "testVar");
|
||||
classNode.members.add(memberNode2);
|
||||
|
||||
classList.add(classNode);
|
||||
programNode.classes = classList;
|
||||
|
||||
return programNode;
|
||||
}
|
||||
}
|
||||
|
@ -1,161 +1,13 @@
|
||||
package semantic;
|
||||
|
||||
|
||||
import oldAst.*;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import semantic.exeptions.AlreadyDeclearedException;
|
||||
import semantic.exeptions.TypeMismatchException;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class SemanticTest {
|
||||
|
||||
@BeforeEach
|
||||
public void init() {
|
||||
SemanticAnalyzer.clearAnalyzier();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void alreadyDeclaredLocalFieldVar() {
|
||||
public void correctClass(){
|
||||
|
||||
//Arrange
|
||||
|
||||
ProgramNode programNode = Mocker.mockFieldNodeAlreadyDeclaredProgrammNode();
|
||||
|
||||
//Act
|
||||
|
||||
ASTNode typedAst = SemanticAnalyzer.generateTast(programNode);
|
||||
|
||||
//Assert
|
||||
|
||||
assertEquals(1, SemanticAnalyzer.errors.size());
|
||||
assertEquals(true, SemanticAnalyzer.errors.get(0) instanceof AlreadyDeclearedException);
|
||||
assertEquals(null, typedAst);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void alreadyDecleared() {
|
||||
|
||||
//Arrange
|
||||
|
||||
ProgramNode programNode = Mocker.mockFieldNodeAlreadyDeclaredProgrammNode();
|
||||
|
||||
//Act
|
||||
|
||||
ASTNode typedAst = SemanticAnalyzer.generateTast(programNode);
|
||||
|
||||
//Assert
|
||||
|
||||
assertEquals(1, SemanticAnalyzer.errors.size());
|
||||
assertInstanceOf(AlreadyDeclearedException.class, SemanticAnalyzer.errors.getFirst());
|
||||
assertNull(typedAst);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldWorkWithNoError() {
|
||||
|
||||
//Arrange
|
||||
|
||||
ProgramNode programNode = Mocker.mockCorrectProgrammNode();
|
||||
|
||||
//Act
|
||||
|
||||
ASTNode typedAst = SemanticAnalyzer.generateTast(programNode);
|
||||
|
||||
//Assert
|
||||
|
||||
assertEquals(0, SemanticAnalyzer.errors.size());
|
||||
assertEquals(programNode, typedAst);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void refTypeCorrect() {
|
||||
|
||||
//Arrange
|
||||
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
ProgramNode programNode = null;
|
||||
try{
|
||||
programNode = objectMapper.readValue(new File("src/test/resources/semantic/correctRefType.json"), ProgramNode.class);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
//Act
|
||||
|
||||
ASTNode typedAst = SemanticAnalyzer.generateTast(programNode);
|
||||
|
||||
//Assert
|
||||
|
||||
assertEquals(0, SemanticAnalyzer.errors.size());
|
||||
assertEquals(programNode, typedAst);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void jsonWriteTest() {
|
||||
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
//Arrange
|
||||
|
||||
ProgramNode programNode = Mocker.mockCorrectProgrammNode();
|
||||
try{
|
||||
objectMapper.writeValue(new File("src/test/resources/semantic/test.json"), programNode);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void jsonReadTest() {
|
||||
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
ProgramNode programNode1 = null;
|
||||
try{
|
||||
programNode1 = objectMapper.readValue(new File("src/test/resources/semantic/test.json"), ProgramNode.class);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
ProgramNode programNode2 = Mocker.mockCorrectProgrammNode();
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void typeMismatch() {
|
||||
|
||||
//Arrange
|
||||
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
ProgramNode programNode = null;
|
||||
try{
|
||||
programNode = objectMapper.readValue(new File("src/test/resources/semantic/refTypeMismatch.json"), ProgramNode.class);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
//Act
|
||||
|
||||
ASTNode typedAst = SemanticAnalyzer.generateTast(programNode);
|
||||
|
||||
//Assert
|
||||
|
||||
assertEquals(1, SemanticAnalyzer.errors.size());
|
||||
assertInstanceOf(TypeMismatchException.class, SemanticAnalyzer.errors.getFirst());
|
||||
assertNull(typedAst);
|
||||
|
||||
}
|
||||
|
||||
|
41
src/test/java/semantic/endToTAST/CorrectTest.java
Normal file
41
src/test/java/semantic/endToTAST/CorrectTest.java
Normal file
@ -0,0 +1,41 @@
|
||||
package semantic.endToTAST;
|
||||
|
||||
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 java.io.IOException;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
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");
|
||||
|
||||
}
|
||||
|
||||
}
|
7
src/test/resources/semantic/endToTAST/Test.java
Normal file
7
src/test/resources/semantic/endToTAST/Test.java
Normal file
@ -0,0 +1,7 @@
|
||||
public class Test {
|
||||
|
||||
public void test(){
|
||||
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user