Assignments
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
af64f88198
commit
b9f6014f59
@ -1,4 +1,6 @@
|
||||
package ast.expression;
|
||||
|
||||
public class ExpressionNode {
|
||||
import visitor.Visitable;
|
||||
|
||||
public abstract class ExpressionNode implements Visitable {
|
||||
}
|
||||
|
@ -6,8 +6,8 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class MemberAccessNode implements ASTNode {
|
||||
Boolean thisExpr;
|
||||
List<String> identifiers = new ArrayList<>();
|
||||
public Boolean thisExpr;
|
||||
public List<String> identifiers = new ArrayList<>();
|
||||
|
||||
public MemberAccessNode(Boolean thisExpr) {
|
||||
this.thisExpr = thisExpr;
|
||||
|
@ -9,7 +9,7 @@ import visitor.Visitable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ConstructorNode extends MethodNode {
|
||||
public class ConstructorNode extends MethodNode implements Visitable {
|
||||
public AccessModifierNode accessType;
|
||||
public String identifier;
|
||||
public List<ParameterNode> parameters = new ArrayList<>();
|
||||
@ -30,10 +30,9 @@ public class ConstructorNode extends MethodNode {
|
||||
parameters.add(parameterNode);
|
||||
}
|
||||
|
||||
/*
|
||||
@Override
|
||||
public void accept(MethodVisitor methodVisitor) {
|
||||
methodVisitor.visit(this);
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
@ -9,24 +9,24 @@ import semantic.SemanticVisitor;
|
||||
import typechecker.TypeCheckResult;
|
||||
import visitor.Visitable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class MethodNode implements MemberNode {
|
||||
AccessModifierNode accesModifier;
|
||||
TypeNode type;
|
||||
Boolean voidType;
|
||||
String identifier;
|
||||
List<ParameterNode> parameters;
|
||||
BlockNode block;
|
||||
public class MethodNode implements MemberNode, Visitable {
|
||||
public AccessModifierNode accesModifier;
|
||||
public TypeNode type;
|
||||
public Boolean voidType;
|
||||
public String identifier;
|
||||
public List<ParameterNode> parameters;
|
||||
public BlockNode block;
|
||||
|
||||
public MethodNode() {}
|
||||
public MethodNode() {
|
||||
}
|
||||
|
||||
public MethodNode(BlockNode block){
|
||||
public MethodNode(BlockNode block) {
|
||||
this.block = block;
|
||||
}
|
||||
|
||||
public MethodNode(AccessModifierNode accessModifier, TypeNode type, Boolean voidType, String identifier, BlockNode block){
|
||||
public MethodNode(AccessModifierNode accessModifier, TypeNode type, Boolean voidType, String identifier, BlockNode block) {
|
||||
this.accesModifier = accessModifier;
|
||||
this.type = type;
|
||||
this.voidType = voidType;
|
||||
@ -54,7 +54,7 @@ public class MethodNode implements MemberNode {
|
||||
}
|
||||
return isSame;
|
||||
}
|
||||
|
||||
*/
|
||||
@Override
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return visitor.analyze(this);
|
||||
@ -64,6 +64,6 @@ public class MethodNode implements MemberNode {
|
||||
public void accept(MethodVisitor methodVisitor) {
|
||||
methodVisitor.visit(this);
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
}
|
||||
|
@ -4,8 +4,8 @@ import ast.ASTNode;
|
||||
import ast.type.TypeNode;
|
||||
|
||||
public class ParameterNode implements ASTNode {
|
||||
TypeNode type;
|
||||
String identifier;
|
||||
public TypeNode type;
|
||||
public String identifier;
|
||||
|
||||
public ParameterNode(TypeNode type, String identifier) {
|
||||
this.type = type;
|
||||
|
@ -5,10 +5,10 @@ import ast.expression.ExpressionNode;
|
||||
import ast.type.TypeNode;
|
||||
|
||||
public class LocalVariableDeclarationNode implements ASTNode {
|
||||
TypeNode type;
|
||||
String identifier;
|
||||
String assign;
|
||||
ExpressionNode expression;
|
||||
public TypeNode type;
|
||||
public String identifier;
|
||||
public String assign;
|
||||
public ExpressionNode expression;
|
||||
|
||||
public LocalVariableDeclarationNode(TypeNode type, String identifier, String assign, ExpressionNode expression) {
|
||||
this.type = type;
|
||||
|
@ -3,14 +3,28 @@ package ast.statement;
|
||||
import ast.ASTNode;
|
||||
import ast.expression.ExpressionNode;
|
||||
import ast.type.TypeNode;
|
||||
import bytecode.visitor.MethodVisitor;
|
||||
import semantic.SemanticVisitor;
|
||||
import typechecker.TypeCheckResult;
|
||||
import visitor.Visitable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ReturnStatementNode implements ASTNode {
|
||||
public class ReturnStatementNode implements ASTNode, Visitable {
|
||||
public ExpressionNode expression;
|
||||
|
||||
public ReturnStatementNode(ExpressionNode expression) {
|
||||
this.expression = expression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(MethodVisitor methodVisitor) {
|
||||
methodVisitor.visit(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -1,2 +1,6 @@
|
||||
package ast.statement;public class StatementNode {
|
||||
package ast.statement;
|
||||
|
||||
import visitor.Visitable;
|
||||
|
||||
public abstract class StatementNode implements Visitable {
|
||||
}
|
||||
|
@ -4,8 +4,8 @@ import ast.ASTNode;
|
||||
import ast.expression.ExpressionNode;
|
||||
|
||||
public class AssignStatementExpressionNode implements ASTNode {
|
||||
AssignableExpressionNode assignable;
|
||||
ExpressionNode expression;
|
||||
public AssignableExpressionNode assignable;
|
||||
public ExpressionNode expression;
|
||||
|
||||
public AssignStatementExpressionNode(AssignableExpressionNode assignable, ExpressionNode expression) {
|
||||
this.assignable = assignable;
|
||||
|
@ -4,8 +4,8 @@ import ast.ASTNode;
|
||||
import ast.expression.unaryexpression.MemberAccessNode;
|
||||
|
||||
public class AssignableExpressionNode implements ASTNode {
|
||||
String identifier;
|
||||
MemberAccessNode memberAccess;
|
||||
public String identifier;
|
||||
public MemberAccessNode memberAccess;
|
||||
|
||||
public AssignableExpressionNode(String identifier) {
|
||||
this.identifier = identifier;
|
||||
|
@ -4,6 +4,8 @@ import ast.parameter.ParameterNode;
|
||||
import ast.type.*;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class Mapper {
|
||||
public int mapAccessTypeToOpcode(AccessModifierNode accessModifierNode) {
|
||||
switch (accessModifierNode.accessType) {
|
||||
@ -14,18 +16,18 @@ public class Mapper {
|
||||
case EnumAccessModifierNode.PUBLIC_STATIC:
|
||||
return Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC;
|
||||
case EnumAccessModifierNode.PRIVATE_STATIC:
|
||||
return Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC;
|
||||
return Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public String generateMethodDescriptor(TypeNode typeNode, ParameterListNode parameterListNode) {
|
||||
public String generateMethodDescriptor(TypeNode typeNode, List<ParameterNode> parameters) {
|
||||
String descriptor = "(";
|
||||
for(ParameterNode parameterNode : parameterListNode.parameters) {
|
||||
descriptor += getTypeChar(EnumTypeNode.INT);
|
||||
for (ParameterNode parameterNode : parameters) {
|
||||
descriptor += getTypeChar(parameterNode.type.type);
|
||||
}
|
||||
descriptor += ")";
|
||||
descriptor += getTypeChar(baseTypeNode.enumType);
|
||||
descriptor += getTypeChar(typeNode.type);
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
|
@ -1,14 +1,14 @@
|
||||
package bytecode;
|
||||
|
||||
import ast.LiteralNode;
|
||||
import ast.expression.BinaryExpressionNode;
|
||||
import ast.expression.IdentifierExpressionNode;
|
||||
import ast.expression.UnaryExpressionNode;
|
||||
import ast.member.ConstructorNode;
|
||||
import ast.member.MethodNode;
|
||||
import ast.parameter.ParameterNode;
|
||||
import ast.statement.*;
|
||||
import ast.type.BaseTypeNode;
|
||||
import ast.statement.ifstatement.ElseStatementNode;
|
||||
import ast.statement.ifstatement.IfElseStatementNode;
|
||||
import ast.statement.ifstatement.IfStatementNode;
|
||||
|
||||
import ast.statement.statementexpression.AssignStatementExpressionNode;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
|
||||
@ -50,59 +50,36 @@ 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) | ACC_STATIC,
|
||||
methodNode.identifier,
|
||||
mapper.generateMethodDescriptor(baseTypeNode, methodNode.parameters),
|
||||
null,
|
||||
null);
|
||||
methodVisitor = classWriter.visitMethod(mapper.mapAccessTypeToOpcode(methodNode.accesModifier),
|
||||
methodNode.identifier,
|
||||
mapper.generateMethodDescriptor(methodNode.type, methodNode.parameters),
|
||||
null,
|
||||
null);
|
||||
|
||||
methodVisitor.visitCode();
|
||||
localVaribales.add("this");
|
||||
// Add all method parameters to localVariables
|
||||
for (ParameterNode parameterNode : methodNode.parameters.parameters) {
|
||||
localVaribales.add(parameterNode.identifier);
|
||||
}
|
||||
|
||||
// Visit all statements
|
||||
for(StatementNode statementNode : methodNode.statements) {
|
||||
statementNode.accept(this);
|
||||
}
|
||||
|
||||
methodVisitor.visitMaxs(1, localVaribales.size());
|
||||
methodVisitor.visitEnd();
|
||||
methodVisitor.visitCode();
|
||||
localVaribales.add("this");
|
||||
// Add all method parameters to localVariables
|
||||
for (ParameterNode parameterNode : methodNode.parameters) {
|
||||
localVaribales.add(parameterNode.identifier);
|
||||
}
|
||||
|
||||
// Visit all statements
|
||||
for (StatementNode statementNode : methodNode.block.statements) {
|
||||
statementNode.accept(this);
|
||||
}
|
||||
|
||||
methodVisitor.visitMaxs(1, localVaribales.size());
|
||||
methodVisitor.visitEnd();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(AssignmentStatementNode assignmentStatementNode) {
|
||||
BinaryExpressionNode expressionNode = assignmentStatementNode.expression;
|
||||
public void visit(ElseStatementNode elseStatementNode) {
|
||||
|
||||
if(expressionNode.left instanceof IdentifierExpressionNode) { // Local var
|
||||
expressionNode.right.accept(this);
|
||||
localVarAssignment((IdentifierExpressionNode) expressionNode.left);
|
||||
} else if(expressionNode.left instanceof BinaryExpressionNode) { // Global var
|
||||
expressionNode.right.accept(this);
|
||||
globalVarAssignment((BinaryExpressionNode) expressionNode.left);
|
||||
}
|
||||
|
||||
assignmentStatementNode.expression.accept(this);
|
||||
methodVisitor.visitVarInsn(ISTORE, 1);
|
||||
}
|
||||
|
||||
private void localVarAssignment(IdentifierExpressionNode expressionNode) {
|
||||
methodVisitor.visitVarInsn(ILOAD, localVaribales.indexOf(expressionNode.name));
|
||||
}
|
||||
@Override
|
||||
public void visit(IfElseStatementNode ifElseStatementNode) {
|
||||
|
||||
private void globalVarAssignment(BinaryExpressionNode expressionNode) {
|
||||
IdentifierExpressionNode identifierExpressionNode = (IdentifierExpressionNode) expressionNode.left;
|
||||
IdentifierExpressionNode identifierExpressionNode1 = (IdentifierExpressionNode) expressionNode.right;
|
||||
TypeNode type = identifierExpressionNode1.type;
|
||||
if(type instanceof BaseTypeNode) {
|
||||
methodVisitor.visitFieldInsn(PUTFIELD, identifierExpressionNode.name, identifierExpressionNode1.name, mapper.getTypeChar(((BaseTypeNode) type).enumType));
|
||||
} else if (type instanceof ReferenceTypeNode) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -111,38 +88,43 @@ public class MethodCodeGen implements bytecode.visitor.MethodVisitor {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ReturnStatementNode returnStatementNode) {
|
||||
returnStatementNode.expression.accept(this);
|
||||
methodVisitor.visitInsn(IRETURN);
|
||||
public void visit(ForStatementNode forStatementNode) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(VariableDeclarationStatementNode variableDeclarationStatementNode) {
|
||||
|
||||
public void visit(LocalVariableDeclarationNode localVariableDeclarationNode) {
|
||||
// Process expression
|
||||
localVariableDeclarationNode.expression.accept(this);
|
||||
// Store result of expression in variable
|
||||
methodVisitor.visitVarInsn(ISTORE, localVaribales.indexOf(localVariableDeclarationNode.identifier));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(AssignStatementExpressionNode assignStatementExpressionNode) {
|
||||
// Process expression
|
||||
assignStatementExpressionNode.expression.accept(this);
|
||||
// Store result of expression in variable
|
||||
if(assignStatementExpressionNode.assignable.memberAccess.thisExpr) {
|
||||
// Global var
|
||||
//methodVisitor.visitFieldInsn(PUTFIELD, identifierExpressionNode.name, identifierExpressionNode1.name, mapper.getTypeChar(((BaseTypeNode) type).enumType));
|
||||
} else {
|
||||
// Local var
|
||||
methodVisitor.visitVarInsn(ISTORE, localVaribales.indexOf(assignStatementExpressionNode.assignable.identifier));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ReturnStatementNode returnStatementNode) {
|
||||
// Process expression
|
||||
returnStatementNode.expression.accept(this);
|
||||
// Return result of expression
|
||||
methodVisitor.visitInsn(IRETURN);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void visit(WhileStatementNode whileStatementNode) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(BinaryExpressionNode binaryExpressionNode) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(IdentifierExpressionNode identifierExpressionNode) {
|
||||
methodVisitor.visitVarInsn(ILOAD, localVaribales.indexOf(identifierExpressionNode.name));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(UnaryExpressionNode unaryExpressionNode) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(LiteralNode literalNode) {
|
||||
methodVisitor.visitVarInsn(BIPUSH, literalNode.value);
|
||||
}
|
||||
}
|
||||
|
@ -1,23 +1,25 @@
|
||||
package bytecode.visitor;
|
||||
|
||||
import ast.LiteralNode;
|
||||
import ast.expression.BinaryExpressionNode;
|
||||
import ast.expression.IdentifierExpressionNode;
|
||||
import ast.expression.UnaryExpressionNode;
|
||||
import ast.member.ConstructorNode;
|
||||
import ast.member.MethodNode;
|
||||
import ast.statement.*;
|
||||
import ast.statement.ifstatement.ElseStatementNode;
|
||||
import ast.statement.ifstatement.IfElseStatementNode;
|
||||
import ast.statement.ifstatement.IfStatementNode;
|
||||
import ast.statement.statementexpression.AssignStatementExpressionNode;
|
||||
|
||||
public interface MethodVisitor {
|
||||
void visit(ConstructorNode constructorNode);
|
||||
void visit(MethodNode methodNode);
|
||||
void visit(AssignmentStatementNode assignmentStatementNode);
|
||||
|
||||
void visit(ElseStatementNode elseStatementNode);
|
||||
void visit(IfElseStatementNode ifElseStatementNode);
|
||||
void visit(IfStatementNode ifStatementNode);
|
||||
|
||||
void visit(AssignStatementExpressionNode assignStatementExpressionNode);
|
||||
|
||||
void visit(ForStatementNode forStatementNode);
|
||||
void visit(LocalVariableDeclarationNode localVariableDeclarationNode);
|
||||
void visit(ReturnStatementNode returnStatementNode);
|
||||
void visit(VariableDeclarationStatementNode variableDeclarationStatementNode);
|
||||
void visit(WhileStatementNode whileStatementNode);
|
||||
void visit(BinaryExpressionNode binaryExpressionNode);
|
||||
void visit(IdentifierExpressionNode identifierExpressionNode);
|
||||
void visit(UnaryExpressionNode unaryExpressionNode);
|
||||
void visit(LiteralNode literalNode);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user