Assignments
Some checks are pending
Gitea Actions Demo / Explore-Gitea-Actions (push) Waiting to run

This commit is contained in:
i22007 2024-06-20 18:12:04 -04:00
parent af64f88198
commit b9f6014f59
13 changed files with 125 additions and 120 deletions

View File

@ -1,4 +1,6 @@
package ast.expression; package ast.expression;
public class ExpressionNode { import visitor.Visitable;
public abstract class ExpressionNode implements Visitable {
} }

View File

@ -6,8 +6,8 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
public class MemberAccessNode implements ASTNode { public class MemberAccessNode implements ASTNode {
Boolean thisExpr; public Boolean thisExpr;
List<String> identifiers = new ArrayList<>(); public List<String> identifiers = new ArrayList<>();
public MemberAccessNode(Boolean thisExpr) { public MemberAccessNode(Boolean thisExpr) {
this.thisExpr = thisExpr; this.thisExpr = thisExpr;

View File

@ -9,7 +9,7 @@ import visitor.Visitable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
public class ConstructorNode extends MethodNode { public class ConstructorNode extends MethodNode implements Visitable {
public AccessModifierNode accessType; public AccessModifierNode accessType;
public String identifier; public String identifier;
public List<ParameterNode> parameters = new ArrayList<>(); public List<ParameterNode> parameters = new ArrayList<>();
@ -30,10 +30,9 @@ public class ConstructorNode extends MethodNode {
parameters.add(parameterNode); parameters.add(parameterNode);
} }
/*
@Override @Override
public void accept(MethodVisitor methodVisitor) { public void accept(MethodVisitor methodVisitor) {
methodVisitor.visit(this); methodVisitor.visit(this);
} }
*/
} }

View File

@ -9,24 +9,24 @@ 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; public AccessModifierNode accesModifier;
TypeNode type; public TypeNode type;
Boolean voidType; public Boolean voidType;
String identifier; public String identifier;
List<ParameterNode> parameters; public List<ParameterNode> parameters;
BlockNode block; public BlockNode block;
public MethodNode() {} public MethodNode() {
}
public MethodNode(BlockNode block){ public MethodNode(BlockNode block) {
this.block = 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.accesModifier = accessModifier;
this.type = type; this.type = type;
this.voidType = voidType; this.voidType = voidType;
@ -54,7 +54,7 @@ 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 +64,6 @@ public class MethodNode implements MemberNode {
public void accept(MethodVisitor methodVisitor) { public void accept(MethodVisitor methodVisitor) {
methodVisitor.visit(this); methodVisitor.visit(this);
} }
*/
} }

View File

@ -4,8 +4,8 @@ import ast.ASTNode;
import ast.type.TypeNode; import ast.type.TypeNode;
public class ParameterNode implements ASTNode { public class ParameterNode implements ASTNode {
TypeNode type; public TypeNode type;
String identifier; public String identifier;
public ParameterNode(TypeNode type, String identifier) { public ParameterNode(TypeNode type, String identifier) {
this.type = type; this.type = type;

View File

@ -5,10 +5,10 @@ import ast.expression.ExpressionNode;
import ast.type.TypeNode; import ast.type.TypeNode;
public class LocalVariableDeclarationNode implements ASTNode { public class LocalVariableDeclarationNode implements ASTNode {
TypeNode type; public TypeNode type;
String identifier; public String identifier;
String assign; public String assign;
ExpressionNode expression; public ExpressionNode expression;
public LocalVariableDeclarationNode(TypeNode type, String identifier, String assign, ExpressionNode expression) { public LocalVariableDeclarationNode(TypeNode type, String identifier, String assign, ExpressionNode expression) {
this.type = type; this.type = type;

View File

@ -3,14 +3,28 @@ package ast.statement;
import ast.ASTNode; import ast.ASTNode;
import ast.expression.ExpressionNode; import ast.expression.ExpressionNode;
import ast.type.TypeNode; import ast.type.TypeNode;
import bytecode.visitor.MethodVisitor;
import semantic.SemanticVisitor;
import typechecker.TypeCheckResult;
import visitor.Visitable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
public class ReturnStatementNode implements ASTNode { public class ReturnStatementNode implements ASTNode, Visitable {
public ExpressionNode expression; public ExpressionNode expression;
public ReturnStatementNode(ExpressionNode expression) { public ReturnStatementNode(ExpressionNode expression) {
this.expression = expression; this.expression = expression;
} }
@Override
public void accept(MethodVisitor methodVisitor) {
methodVisitor.visit(this);
}
@Override
public TypeCheckResult accept(SemanticVisitor visitor) {
return null;
}
} }

View File

@ -1,2 +1,6 @@
package ast.statement;public class StatementNode { package ast.statement;
import visitor.Visitable;
public abstract class StatementNode implements Visitable {
} }

View File

@ -4,8 +4,8 @@ import ast.ASTNode;
import ast.expression.ExpressionNode; import ast.expression.ExpressionNode;
public class AssignStatementExpressionNode implements ASTNode { public class AssignStatementExpressionNode implements ASTNode {
AssignableExpressionNode assignable; public AssignableExpressionNode assignable;
ExpressionNode expression; public ExpressionNode expression;
public AssignStatementExpressionNode(AssignableExpressionNode assignable, ExpressionNode expression) { public AssignStatementExpressionNode(AssignableExpressionNode assignable, ExpressionNode expression) {
this.assignable = assignable; this.assignable = assignable;

View File

@ -4,8 +4,8 @@ import ast.ASTNode;
import ast.expression.unaryexpression.MemberAccessNode; import ast.expression.unaryexpression.MemberAccessNode;
public class AssignableExpressionNode implements ASTNode { public class AssignableExpressionNode implements ASTNode {
String identifier; public String identifier;
MemberAccessNode memberAccess; public MemberAccessNode memberAccess;
public AssignableExpressionNode(String identifier) { public AssignableExpressionNode(String identifier) {
this.identifier = identifier; this.identifier = identifier;

View File

@ -4,6 +4,8 @@ import ast.parameter.ParameterNode;
import ast.type.*; import ast.type.*;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;
import java.util.List;
public class Mapper { public class Mapper {
public int mapAccessTypeToOpcode(AccessModifierNode accessModifierNode) { public int mapAccessTypeToOpcode(AccessModifierNode accessModifierNode) {
switch (accessModifierNode.accessType) { switch (accessModifierNode.accessType) {
@ -19,13 +21,13 @@ public class Mapper {
return 0; return 0;
} }
public String generateMethodDescriptor(TypeNode typeNode, ParameterListNode parameterListNode) { public String generateMethodDescriptor(TypeNode typeNode, List<ParameterNode> parameters) {
String descriptor = "("; String descriptor = "(";
for(ParameterNode parameterNode : parameterListNode.parameters) { for (ParameterNode parameterNode : parameters) {
descriptor += getTypeChar(EnumTypeNode.INT); descriptor += getTypeChar(parameterNode.type.type);
} }
descriptor += ")"; descriptor += ")";
descriptor += getTypeChar(baseTypeNode.enumType); descriptor += getTypeChar(typeNode.type);
return descriptor; return descriptor;
} }

View File

@ -1,14 +1,14 @@
package bytecode; package bytecode;
import ast.LiteralNode;
import ast.expression.BinaryExpressionNode;
import ast.expression.IdentifierExpressionNode;
import ast.expression.UnaryExpressionNode;
import ast.member.ConstructorNode; import ast.member.ConstructorNode;
import ast.member.MethodNode; import ast.member.MethodNode;
import ast.parameter.ParameterNode; import ast.parameter.ParameterNode;
import ast.statement.*; 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.ClassWriter;
import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.MethodVisitor;
@ -50,59 +50,36 @@ 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) { methodVisitor = classWriter.visitMethod(mapper.mapAccessTypeToOpcode(methodNode.accesModifier),
methodVisitor = classWriter.visitMethod(mapper.mapAccessTypeToOpcode(methodNode.visibility) | ACC_STATIC,
methodNode.identifier, methodNode.identifier,
mapper.generateMethodDescriptor(baseTypeNode, methodNode.parameters), mapper.generateMethodDescriptor(methodNode.type, methodNode.parameters),
null, null,
null); null);
methodVisitor.visitCode(); methodVisitor.visitCode();
localVaribales.add("this"); localVaribales.add("this");
// Add all method parameters to localVariables // Add all method parameters to localVariables
for (ParameterNode parameterNode : methodNode.parameters.parameters) { for (ParameterNode parameterNode : methodNode.parameters) {
localVaribales.add(parameterNode.identifier); localVaribales.add(parameterNode.identifier);
} }
// Visit all statements // Visit all statements
for(StatementNode statementNode : methodNode.statements) { for (StatementNode statementNode : methodNode.block.statements) {
statementNode.accept(this); statementNode.accept(this);
} }
methodVisitor.visitMaxs(1, localVaribales.size()); methodVisitor.visitMaxs(1, localVaribales.size());
methodVisitor.visitEnd(); methodVisitor.visitEnd();
} }
@Override
public void visit(ElseStatementNode elseStatementNode) {
} }
@Override @Override
public void visit(AssignmentStatementNode assignmentStatementNode) { public void visit(IfElseStatementNode ifElseStatementNode) {
BinaryExpressionNode expressionNode = assignmentStatementNode.expression;
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));
}
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 @Override
@ -111,38 +88,43 @@ public class MethodCodeGen implements bytecode.visitor.MethodVisitor {
} }
@Override @Override
public void visit(ReturnStatementNode returnStatementNode) { public void visit(ForStatementNode forStatementNode) {
returnStatementNode.expression.accept(this);
methodVisitor.visitInsn(IRETURN);
} }
@Override @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 @Override
public void visit(WhileStatementNode whileStatementNode) { 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);
}
} }

View File

@ -1,23 +1,25 @@
package bytecode.visitor; 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.ConstructorNode;
import ast.member.MethodNode; import ast.member.MethodNode;
import ast.statement.*; 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 { public interface MethodVisitor {
void visit(ConstructorNode constructorNode); void visit(ConstructorNode constructorNode);
void visit(MethodNode methodNode); void visit(MethodNode methodNode);
void visit(AssignmentStatementNode assignmentStatementNode);
void visit(ElseStatementNode elseStatementNode);
void visit(IfElseStatementNode ifElseStatementNode);
void visit(IfStatementNode ifStatementNode); void visit(IfStatementNode ifStatementNode);
void visit(AssignStatementExpressionNode assignStatementExpressionNode);
void visit(ForStatementNode forStatementNode);
void visit(LocalVariableDeclarationNode localVariableDeclarationNode);
void visit(ReturnStatementNode returnStatementNode); void visit(ReturnStatementNode returnStatementNode);
void visit(VariableDeclarationStatementNode variableDeclarationStatementNode);
void visit(WhileStatementNode whileStatementNode); void visit(WhileStatementNode whileStatementNode);
void visit(BinaryExpressionNode binaryExpressionNode);
void visit(IdentifierExpressionNode identifierExpressionNode);
void visit(UnaryExpressionNode unaryExpressionNode);
void visit(LiteralNode literalNode);
} }