Trying to change to new AST
Some checks are pending
Gitea Actions Demo / Explore-Gitea-Actions (push) Waiting to run

This commit is contained in:
Bruder John 2024-06-20 11:43:58 +02:00
parent 978b5a2b4a
commit fd8c3b066a
17 changed files with 171 additions and 495 deletions

View File

@ -1,6 +1,5 @@
import oldAst.ASTNode; import ast.*;
import org.antlr.v4.runtime.*; import org.antlr.v4.runtime.*;
import oldAst.ProgramNode;
import bytecode.ByteCodeGenerator; import bytecode.ByteCodeGenerator;
import org.antlr.v4.runtime.CharStream; import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.CharStreams; import org.antlr.v4.runtime.CharStreams;

View File

@ -9,16 +9,15 @@ import semantic.SemanticVisitor;
import typechecker.TypeCheckResult; import typechecker.TypeCheckResult;
import visitor.Visitable; import visitor.Visitable;
import java.util.ArrayList;
import java.util.List; import java.util.List;
public class MethodNode implements MemberNode { public class MethodNode implements MemberNode, Visitable {
AccessModifierNode accesModifier; AccessModifierNode accesModifier;
TypeNode type; TypeNode type;
Boolean voidType; Boolean voidType;
String identifier; String identifier;
List<ParameterNode> parameters; List<ParameterNode> parameters;
BlockNode block; public BlockNode block;
public MethodNode() {} public MethodNode() {}
@ -55,6 +54,8 @@ public class MethodNode implements MemberNode {
return isSame; return isSame;
} }
*/
@Override @Override
public TypeCheckResult accept(SemanticVisitor visitor) { public TypeCheckResult accept(SemanticVisitor visitor) {
return visitor.analyze(this); return visitor.analyze(this);
@ -64,6 +65,6 @@ public class MethodNode implements MemberNode {
public void accept(MethodVisitor methodVisitor) { public void accept(MethodVisitor methodVisitor) {
methodVisitor.visit(this); methodVisitor.visit(this);
} }
*/
} }

View File

@ -2,10 +2,6 @@ package ast.statement;
import ast.ASTNode; import ast.ASTNode;
import ast.expression.ExpressionNode; import ast.expression.ExpressionNode;
import ast.type.TypeNode;
import java.util.ArrayList;
import java.util.List;
public class ReturnStatementNode implements ASTNode { public class ReturnStatementNode implements ASTNode {
public ExpressionNode expression; public ExpressionNode expression;

View File

@ -4,11 +4,10 @@ import ast.ClassNode;
import ast.member.FieldNode; import ast.member.FieldNode;
import ast.member.MemberNode; import ast.member.MemberNode;
import ast.member.MethodNode; import ast.member.MethodNode;
import ast.type.BaseTypeNode; import ast.type.TypeNode;
import bytecode.visitor.ClassVisitor; import bytecode.visitor.ClassVisitor;
import java.io.File; import java.io.File;
import org.objectweb.asm.ClassWriter; import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
@ -25,8 +24,8 @@ public class ClassCodeGen implements ClassVisitor {
@Override @Override
public void visit(ClassNode classNode) { public void visit(ClassNode classNode) {
classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
classWriter.visit(Opcodes.V1_5, mapper.mapAccessTypeToOpcode(classNode.accessType), classNode.identifier, null, // classWriter.visit(Opcodes.V1_5, mapper.mapAccessTypeToOpcode(classNode.accessType), classNode.identifier, null,
"java/lang/Object", null); // "java/lang/Object", null);
for (MemberNode memberNode : classNode.members) { for (MemberNode memberNode : classNode.members) {
if (memberNode instanceof FieldNode) { if (memberNode instanceof FieldNode) {
@ -45,8 +44,8 @@ public class ClassCodeGen implements ClassVisitor {
@Override @Override
public void visit(FieldNode fieldNode) { public void visit(FieldNode fieldNode) {
if(fieldNode.type instanceof BaseTypeNode baseTypeNode){ if(fieldNode.type instanceof TypeNode baseTypeNode){
classWriter.visitField(mapper.mapAccessTypeToOpcode(fieldNode.accessTypeNode), fieldNode.identifier, mapper.getTypeChar(baseTypeNode.enumType), null, null ); // classWriter.visitField(mapper.mapAccessTypeToOpcode(fieldNode.accessTypeNode), fieldNode.identifier, mapper.getTypeChar(baseTypeNode.enumType), null, null );
} }
classWriter.visitEnd(); classWriter.visitEnd();
} }

View File

@ -1,44 +1,41 @@
package bytecode; package bytecode;
import ast.parameter.ParameterNode;
import ast.type.*; import ast.type.*;
import org.objectweb.asm.Opcodes;
import ast.type.BaseTypeNode;
public class Mapper { public class Mapper {
public int mapAccessTypeToOpcode(AccessTypeNode type) { // public int mapAccessTypeToOpcode(AccessModifierNode type) {
switch (type.enumAccessTypeNode) { // switch (type.enumAccessTypeNode) {
case EnumAccessTypeNode.PUBLIC: // case EnumAccessTypeNode.PUBLIC:
return Opcodes.ACC_PUBLIC; // return Opcodes.ACC_PUBLIC;
case EnumAccessTypeNode.PRIVATE: // case EnumAccessTypeNode.PRIVATE:
return Opcodes.ACC_PRIVATE; // return Opcodes.ACC_PRIVATE;
} // }
return 0; // return 0;
} // }
public String generateMethodDescriptor(BaseTypeNode baseTypeNode, ParameterListNode parameterListNode) { // public String generateMethodDescriptor(BaseTypeNode baseTypeNode, ParameterListNode parameterListNode) {
String descriptor = "("; // String descriptor = "(";
for(ParameterNode parameterNode : parameterListNode.parameters) { // for(ParameterNode parameterNode : parameterListNode.parameters) {
descriptor += getTypeChar(EnumTypeNode.INT); // descriptor += getTypeChar(EnumTypeNode.INT);
} // }
descriptor += ")"; // descriptor += ")";
descriptor += getTypeChar(baseTypeNode.enumType); // descriptor += getTypeChar(baseTypeNode.enumType);
return descriptor; // return descriptor;
} // }
public String getTypeChar(EnumTypeNode enumTypeNode) { // public String getTypeChar(TypeEnum enumTypeNode) {
String typeChar = ""; // String typeChar = "";
switch (enumTypeNode) { // switch (enumTypeNode) {
case EnumTypeNode.INT: // case TypeEnum.INT:
typeChar = "I"; // typeChar = "I";
break; // break;
case EnumTypeNode.CHAR: // case TypeEnum.CHAR:
typeChar = "C"; // typeChar = "C";
break; // break;
case EnumTypeNode.BOOLEAN: // case TypeEnum.BOOLEAN:
typeChar = "Z"; // typeChar = "Z";
break; // break;
} // }
return typeChar; // return typeChar;
} // }
} }

View File

@ -2,12 +2,8 @@ package bytecode;
import ast.member.ConstructorNode; import ast.member.ConstructorNode;
import ast.member.MethodNode; import ast.member.MethodNode;
import ast.parameter.ParameterNode;
import ast.type.BaseTypeNode;
import org.objectweb.asm.ClassWriter; import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -31,12 +27,12 @@ public class MethodCodeGen implements bytecode.visitor.MethodVisitor {
@Override @Override
public void visit(ConstructorNode constructorNode) { public void visit(ConstructorNode constructorNode) {
methodVisitor = // methodVisitor =
classWriter.visitMethod(mapper.mapAccessTypeToOpcode(constructorNode.visibility), // classWriter.visitMethod(mapper.mapAccessTypeToOpcode(constructorNode.visibility),
"<init>", // "<init>",
"()V", // "()V",
null, // null,
null); // null);
methodVisitor.visitCode(); methodVisitor.visitCode();
methodVisitor.visitVarInsn(ALOAD, 0); methodVisitor.visitVarInsn(ALOAD, 0);
methodVisitor.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false); methodVisitor.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
@ -47,52 +43,52 @@ public class MethodCodeGen implements bytecode.visitor.MethodVisitor {
@Override @Override
public void visit(MethodNode methodNode) { public void visit(MethodNode methodNode) {
if (methodNode.type instanceof BaseTypeNode baseTypeNode) { // if (methodNode.type instanceof BaseTypeNode baseTypeNode) {
methodVisitor = classWriter.visitMethod(mapper.mapAccessTypeToOpcode(methodNode.visibility), // methodVisitor = classWriter.visitMethod(mapper.mapAccessTypeToOpcode(methodNode.visibility),
methodNode.identifier, // methodNode.identifier,
mapper.generateMethodDescriptor(baseTypeNode, methodNode.parameters), // mapper.generateMethodDescriptor(baseTypeNode, methodNode.parameters),
null, // null,
null); // null);
methodVisitor.visitCode(); methodVisitor.visitCode();
localVaribales.add("this"); localVaribales.add("this");
for (ParameterNode parameterNode : methodNode.parameters.parameters) { // for (ParameterNode parameterNode : methodNode.parameters.parameters) {
localVaribales.add(parameterNode.identifier); // localVaribales.add(parameterNode.identifier);
} // }
//test(); //test();
methodVisitor.visitMaxs(1, localVaribales.size()); methodVisitor.visitMaxs(1, localVaribales.size());
methodVisitor.visitEnd(); methodVisitor.visitEnd();
} // }
} }
public void test() { // public void test() {
Label start = new Label(); // Label start = new Label();
Label loop = new Label(); // Label loop = new Label();
Label end = new Label(); // Label end = new Label();
methodVisitor.visitLabel(start); // methodVisitor.visitLabel(start);
//methodVisitor.visitVarInsn(Opcodes.ICONST_M1, 99); // //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.visitInsn(Opcodes.ICONST_5);
methodVisitor.visitLdcInsn(99); // methodVisitor.visitJumpInsn(Opcodes.IF_ICMPGE, end);
// methodVisitor.visitInsn(Opcodes.ICONST_0); // methodVisitor.visitFieldInsn(Opcodes.GETSTATIC,
//methodVisitor.visitVarInsn(Opcodes.ILOAD, 2); // "java/lang/System", "out",
methodVisitor.visitVarInsn(Opcodes.ISTORE, 1); // "Ljava/io/PrintStream;");
methodVisitor.visitLabel(loop); // methodVisitor.visitLdcInsn("Bytecode");
methodVisitor.visitVarInsn(Opcodes.ILOAD, 1); // methodVisitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
methodVisitor.visitInsn(Opcodes.ICONST_5); // "java/io/PrintStream", "println",
methodVisitor.visitJumpInsn(Opcodes.IF_ICMPGE, end); // "(Ljava/lang/String;)V", false);
methodVisitor.visitFieldInsn(Opcodes.GETSTATIC, // methodVisitor.visitIincInsn(1, 1);
"java/lang/System", "out", // methodVisitor.visitJumpInsn(Opcodes.GOTO, loop);
"Ljava/io/PrintStream;"); // methodVisitor.visitLabel(end);
methodVisitor.visitLdcInsn("Bytecode"); // methodVisitor.visitVarInsn(Opcodes.ILOAD, 1);
methodVisitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, // methodVisitor.visitInsn(Opcodes.IRETURN);
"java/io/PrintStream", "println", // methodVisitor.visitEnd();
"(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();
}
} }

View File

@ -1,6 +1,6 @@
package semantic; package semantic;
import oldAst.type.TypeNode; import ast.type.TypeNode;
import java.util.HashMap; import java.util.HashMap;
import java.util.Stack; import java.util.Stack;

View File

@ -1,25 +1,16 @@
package semantic; 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.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import oldAst.type.BaseTypeNode; import ast.*;
import oldAst.type.TypeNode; import ast.member.*;
import ast.statement.*;
import ast.statement.ifstatement.IfStatementNode;
import ast.type.*;
import semantic.context.Context; import semantic.context.Context;
import semantic.exeptions.AlreadyDeclearedException; import semantic.exeptions.AlreadyDeclearedException;
import semantic.exeptions.NotDeclearedException; import semantic.exeptions.NotDeclearedException;
@ -90,10 +81,7 @@ public class SemanticAnalyzer implements SemanticVisitor {
for(MethodNode methode : currentClass.getMethods()){ for(MethodNode methode : currentClass.getMethods()){
if(methode.equals(methodNode)) if(methode.equals(methodNode))
break; break;
if(methode.isSame(methodNode)){
errors.add(new AlreadyDeclearedException("This method has already been declared"));
valid = false;
}
} }
var result = methodNode.accept(this); var result = methodNode.accept(this);
valid = valid && result.isValid(); valid = valid && result.isValid();
@ -110,32 +98,6 @@ public class SemanticAnalyzer implements SemanticVisitor {
currentScope.pushScope(); 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(); currentScope.popScope();
return new TypeCheckResult(valid, null); return new TypeCheckResult(valid, null);
} }
@ -151,80 +113,6 @@ public class SemanticAnalyzer implements SemanticVisitor {
return new TypeCheckResult(true, null); 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 @Override
public TypeCheckResult analyze(IfStatementNode toCheck) { public TypeCheckResult analyze(IfStatementNode toCheck) {
return null; return null;
@ -240,40 +128,4 @@ public class SemanticAnalyzer implements SemanticVisitor {
return null; 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());
}
} }

View File

@ -1,18 +1,10 @@
package semantic; package semantic;
import ast.ClassNode; import ast.*;
import ast.expression.LiteralNode; import ast.member.*;
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.statement.*; import ast.statement.*;
import ast.expression.This; import ast.statement.ifstatement.*;
import ast.statement.ifstatement.IfStatementNode;
import typechecker.TypeCheckResult; import typechecker.TypeCheckResult;
public interface SemanticVisitor { public interface SemanticVisitor {
@ -25,25 +17,10 @@ public interface SemanticVisitor {
TypeCheckResult analyze(FieldNode toCheck); 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(IfStatementNode toCheck);
TypeCheckResult analyze(ReturnStatementNode toCheck); TypeCheckResult analyze(ReturnStatementNode toCheck);
TypeCheckResult analyze(WhileStatementNode toCheck); TypeCheckResult analyze(WhileStatementNode toCheck);
TypeCheckResult analyze(LiteralNode toCheck);
TypeCheckResult analyze(InstVar toCheck);
TypeCheckResult analyze(This toCheck);
} }

View File

@ -1,7 +1,7 @@
package semantic.context; package semantic.context;
import oldAst.ClassNode; import ast.ClassNode;
import oldAst.member.FieldNode; import ast.member.FieldNode;
import java.util.HashMap; import java.util.HashMap;
public class ClassContext { public class ClassContext {

View File

@ -1,6 +1,6 @@
package semantic.context; package semantic.context;
import oldAst.ProgramNode; import ast.ProgramNode;
import java.util.HashMap; import java.util.HashMap;
public class Context { public class Context {

View File

@ -1,12 +1,11 @@
package semantic.context; package semantic.context;
import oldAst.member.FieldNode; import ast.member.FieldNode;
import oldAst.type.AccessTypeNode; import ast.type.*;
import oldAst.type.TypeNode;
public class FieldContext { public class FieldContext {
private AccessTypeNode accessModifier; private AccessModifierNode accessModifier;
private TypeNode type; private TypeNode type;
public FieldContext(FieldNode field) { public FieldContext(FieldNode field) {

View File

@ -1,7 +1,7 @@
package typechecker; package typechecker;
import oldAst.type.TypeNode; import ast.type.TypeNode;
public class TypeCheckResult { public class TypeCheckResult {

View File

@ -1,76 +1,36 @@
package semantic; package semantic;
import oldAst.ClassNode; import ast.*;
import oldAst.expression.LiteralNode; import ast.block.BlockNode;
import oldAst.ProgramNode; import ast.member.MethodNode;
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 java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import static parser.generated.SimpleJavaParser.Identifier;
public class Mocker { public class Mocker {
public static ProgramNode mockCorrectProgrammNode(){ public static ProgramNode mockCorrectClass(){
ProgramNode p = new ProgramNode();
ProgramNode programNode = new ProgramNode(); ClassNode c = new ClassNode();
List<ClassNode> classList = new ArrayList<ClassNode>(); c.identifier = "testClass";
AccessTypeNode accessTypeNode = new AccessTypeNode(EnumAccessTypeNode.PUBLIC);
ClassNode classNode = new ClassNode(accessTypeNode, "testClass");
MemberNode memberNode1 = new FieldNode(accessTypeNode, new BaseTypeNode(EnumTypeNode.INT), "testVar1"); MethodNode m = new MethodNode();
classNode.members.add(memberNode1);
MemberNode memberNode2 = new FieldNode(accessTypeNode, new BaseTypeNode(EnumTypeNode.INT), "objectVar"); BlockNode b = new BlockNode();
classNode.members.add(memberNode2);
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(); m.block = b;
expressionNodeRight.setType(new BaseTypeNode(EnumTypeNode.INT));
StatementNode statementNode1 = new AssignmentStatementNode(expressionNodeLeft, expressionNodeRight); c.members.add(m);
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;
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;
}
} }

View File

@ -1,161 +1,13 @@
package semantic; package semantic;
import oldAst.*;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; 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 { public class SemanticTest {
@BeforeEach
public void init() {
SemanticAnalyzer.clearAnalyzier();
}
@Test @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);
} }

View 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");
}
}

View File

@ -0,0 +1,7 @@
public class Test {
public void test(){
}
}