Compare commits

...

7 Commits

Author SHA1 Message Date
Bruder John
f60fa05153 Merge branch 'main' into johns-branch 2024-05-08 13:34:09 +02:00
Purplumbi
abcd5a55ef Merge remote-tracking branch 'origin/main' 2024-05-08 13:27:48 +02:00
Purplumbi
20052e619d Antlr + Visitors 2024-05-08 13:27:40 +02:00
Lucas
d7a8500109 Merge remote-tracking branch 'origin/main'
# Conflicts:
#	src/main/java/Main.java
#	src/main/java/bytecode/ByteCodeGenerator.java
2024-05-08 13:14:16 +02:00
Lucas
d014cb28c7 Structure and Fixes 2024-05-08 13:10:45 +02:00
ce2ea07f96 Move code generation 2024-05-08 13:10:29 +02:00
b173d77620 Fixed change errors 2024-05-08 13:06:27 +02:00
13 changed files with 200 additions and 21 deletions

View File

@ -9,6 +9,9 @@ import parser.ASTBuilder;
import parser.generated.SimpleJavaLexer; import parser.generated.SimpleJavaLexer;
import parser.generated.SimpleJavaParser; import parser.generated.SimpleJavaParser;
import semantic.SemanticAnalyzer; import semantic.SemanticAnalyzer;
import ast.ClassNode;
import ast.ProgramNode;
import bytecode.ByteCodeGenerator;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Paths; import java.nio.file.Paths;

View File

@ -0,0 +1,4 @@
package ast;
public class ExpressionNode {
}

View File

@ -1,10 +1,10 @@
package ast; package ast;
public class FieldNode { public class FieldNode extends MemberNode {
String type; TypeNode type;
String name; String name;
public FieldNode(String type, String name){ public FieldNode(TypeNode type, String name){
this.type = type; this.type = type;
this.name = name; this.name = name;
} }

View File

@ -1,11 +1,17 @@
package ast; package ast;
import java.util.ArrayList;
import java.util.List;
public class MethodNode extends MemberNode{ public class MethodNode extends MemberNode{
public String visibility; public TypeNode visibility;
public String name; public String name;
public MethodNode(String visibility, String name){ public ParameterListNode parameters;
public MethodNode(TypeNode visibility, String name, ParameterListNode parameters){
this.visibility = visibility; this.visibility = visibility;
this.name = name; this.name = name;
this.parameters = parameters;
} }
} }

View File

@ -0,0 +1,12 @@
package ast;
import java.util.ArrayList;
import java.util.List;
public class ParameterListNode {
List<ParameterNode> parameters = new ArrayList<>();
public ParameterListNode(){
parameters
}
}

View File

@ -0,0 +1,11 @@
package ast;
public class ParameterNode extends ASTNode {
public TypeNode type;
public String identifier;
public ParameterNode(TypeNode type, String identifier) {
this.type = type;
this.identifier = identifier;
}
}

View File

@ -1,12 +1,9 @@
package ast; public class ParameterNode extends ASTNode {
public TypeNode type;
public String identifier;
import java.util.ArrayList; public ParameterNode(TypeNode type, String identifier) {
import java.util.List; this.type = type;
this.identifier = identifier;
public class ProgramNode extends ASTNode {
public List<ClassNode> classes = new ArrayList<>();
public void addClass(ClassNode classNode) {
classes.add(classNode);
} }
} }

View File

@ -0,0 +1,7 @@
package ast;
import ast.ASTNode;
public abstract class StatementNode extends ASTNode {
}

View File

@ -1,5 +1,9 @@
package ast; package ast;
public class TypeNode { public class TypeNode extends ASTNode {
String type; public String typeName;
public TypeNode(String typeName) {
this.typeName = typeName;
}
} }

View File

@ -0,0 +1,13 @@
package ast;
public class VariableDeclarationStatementNode extends StatementNode {
public TypeNode type;
public String identifier;
public ExpressionNode expression; // Nullable for cases without initialization
public VariableDeclarationStatementNode(TypeNode type, String identifier, ExpressionNode expression) {
this.type = type;
this.identifier = identifier;
this.expression = expression;
}
}

View File

@ -0,0 +1,39 @@
package bytecode;
import ast.ClassNode;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;
import java.io.FileOutputStream;
import java.io.IOException;
public class ClassCodeGen {
public void generateClassCode(ClassNode classNode) {
ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
classWriter.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, classNode.name, null,
"java/lang/Object", null);
FieldCodeGen fieldCodeGen = new FieldCodeGen();
fieldCodeGen.generateFieldCode(classWriter);
MethodCodeGen methodCodeGen = new MethodCodeGen();
methodCodeGen.generateMethodCode(classWriter);
classWriter.visitEnd();
printIntoClassFile(classWriter.toByteArray(), classNode.name);
classWriter.visitEnd();
}
private void printIntoClassFile(byte[] byteCode, String name) {
String filePath = "./classFileOutput/" + name + ".class";
try {
FileOutputStream fileOutputStream = new FileOutputStream(filePath);
fileOutputStream.write(byteCode);
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

View File

@ -4,6 +4,9 @@ import ast.*;
import parser.generated.SimpleJavaBaseVisitor; import parser.generated.SimpleJavaBaseVisitor;
import parser.generated.SimpleJavaParser; import parser.generated.SimpleJavaParser;
import java.util.ArrayList;
import java.util.List;
public class ASTBuilder extends SimpleJavaBaseVisitor<ASTNode> { public class ASTBuilder extends SimpleJavaBaseVisitor<ASTNode> {
@Override @Override
public ASTNode visitProgram(SimpleJavaParser.ProgramContext ctx) { public ASTNode visitProgram(SimpleJavaParser.ProgramContext ctx) {
@ -25,4 +28,65 @@ public class ASTBuilder extends SimpleJavaBaseVisitor<ASTNode> {
return classNode; return classNode;
} }
@Override
public ASTNode visitFieldDeclaration(SimpleJavaParser.FieldDeclarationContext ctx) {
TypeNode type = (TypeNode) visit(ctx.type());
String identifier = ctx.IDENTIFIER().getText();
return new FieldNode(type, identifier);
}
@Override
public ASTNode visitMethodDeclaration(SimpleJavaParser.MethodDeclarationContext ctx) {
TypeNode returnType = (TypeNode) visit(ctx.type());
String methodName = ctx.IDENTIFIER().getText();
ParameterListNode = (ParameterListNode) visit(ctx.parameterList());
List<ParameterNode> parameters = new ArrayList<>();
for (SimpleJavaParser.ParameterContext parameter : ctx.parameterList()) {
parameters.add(parameter);
}
MethodNode method = new MethodNode(returnType, methodName);
for (SimpleJavaParser.ParameterContext paramCtx : ctx.parameterList().parameter()) {
method.parameters.add((ParameterNode) visit(paramCtx));
}
for (SimpleJavaParser.StatementContext stmtCtx : ctx.statement()) {
method.statements.add((StatementNode) visit(stmtCtx));
}
return method;
}
@Override
public ASTNode visitType(SimpleJavaParser.TypeContext ctx) {
return new TypeNode(ctx.getText());
}
@Override
public ASTNode visitStatement(SimpleJavaParser.StatementContext ctx) {
if (ctx.variableDeclarationStatement() != null) {
return visitVariableDeclarationStatement(ctx.variableDeclarationStatement());
} else if (ctx.assignmentStatement() != null) {
return visitAssignmentStatement(ctx.assignmentStatement());
}
return null;
}
@Override
public ASTNode visitParameterList(SimpleJavaParser.ParameterListContext ctx) {
List<ParameterNode> parameters = new ArrayList<>();
for (SimpleJavaParser.ParameterContext paramCtx : ctx.parameter()) {
parameters.add((ParameterNode) visitParameter(paramCtx));
}
return new ParameterListNode(parameters); // Assuming you want to keep a dedicated node for the list
}
@Override
public ASTNode visitParameter(SimpleJavaParser.ParameterContext ctx) {
TypeNode type = (TypeNode) visit(ctx.type()); // Assuming visitType returns a TypeNode
String identifier = ctx.IDENTIFIER().getText();
return new ParameterNode(type, identifier);
}
} }

View File

@ -1,4 +1,19 @@
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.CharStreams;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
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 parser.ASTBuilder;
import parser.generated.SimpleJavaLexer;
import parser.generated.SimpleJavaParser;
import ast.ClassNode;
import ast.ProgramNode;
import bytecode.ByteCodeGenerator;
import java.io.IOException;
import java.nio.file.Paths;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
@ -7,10 +22,14 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
*/ */
public class MainTest { public class MainTest {
@Test @Test
void testAdd() { void testEmptyClass() {
//Calculator calculator = new Calculator(); CharStream codeCharStream = null;
//int result = calculator.add(2, 3); try {
//assertEquals(5, result, "2 + 3 should equal 5"); codeCharStream = CharStreams.fromPath(Paths.get("src/main/java/Example.java"));
Main.parsefile(codeCharStream);
} catch (IOException e) {
System.err.println("Error reading the file: " + e.getMessage());
}
} }
} }