Programming-Language-Design / src / visitor / codegeneration / ExecuteCGVisitor.java
ExecuteCGVisitor.java
Raw
package visitor.codegeneration;

import ast.Program;
import ast.definition.classes.FuncDefinition;
import ast.definition.classes.VarDefinition;
import ast.expression.classes.FunctionInvocation;
import ast.statement.classes.*;
import ast.type.classes.FunctionType;
import ast.type.classes.VoidType;
import visitor.codegeneration.utils.ReturnDataObject;

/**
 * Code function for Statement, Program and Definition
 */
public class ExecuteCGVisitor extends AbstractCGVisitor<ReturnDataObject, Void> {

    public ExecuteCGVisitor(CodeGenerator cg) {
        super(cg);
    }

    @Override
    public Void visit(Program ast, ReturnDataObject param) {
        cg.program(ast, executeCGVisitor);
        return null;
    }

    @Override
    public Void visit(VarDefinition ast, ReturnDataObject param) {
        cg.write("' * " + ast.getType() + " " + ast.getName() + " (offset " + ast.getOffset() + ")");
        return null;
    }

    @Override
    public Void visit(FuncDefinition ast, ReturnDataObject param) {
        cg.funcDefinition(ast, executeCGVisitor);
        return null;
    }

    @Override
    public Void visit(WriteStatement ast, ReturnDataObject param) {
        cg.write("' * Write");
        ast.getValue().accept(valueCGVisitor, null);
        cg.write("out" + ast.getValue().getType().suffix());
        return null;
    }

    @Override
    public Void visit(ReadStatement ast, ReturnDataObject param) {
        cg.write("' * Read");
        ast.getValue().accept(addressCGVisitor, null);
        cg.write("in" + ast.getValue().getType().suffix());
        cg.write("store" + ast.getValue().getType().suffix());
        return null;
    }

    @Override
    public Void visit(Assignment ast, ReturnDataObject param) {
        ast.getOperand_1().accept(addressCGVisitor, null);
        ast.getOperand_2().accept(valueCGVisitor, null);
        cg.write("store" + ast.getOperand_1().getType().suffix());
        return null;
    }

    @Override
    public Void visit(Return ast, ReturnDataObject param) {
        cg.write("' * Return");
        ast.getValue().accept(valueCGVisitor, null);
        cg.write("ret " + param.getBytesReturn() + ", " + param.getBytesLocals() + ", " + param.getBytesParams());
        return null;
    }

    @Override
    public Void visit(WhileLoop ast, ReturnDataObject param) {
        cg.whileLoop(ast, executeCGVisitor);
        return null;
    }

    @Override
    public Void visit(IfElse ast, ReturnDataObject param) {
        cg.ifElse(ast, executeCGVisitor);
        return null;
    }

    @Override
    public Void visit(FunctionInvocation ast, ReturnDataObject param) {
        ast.getArguments().forEach(arg -> arg.accept(valueCGVisitor, null));
        cg.write("call " + ast.getFunctionName());
        if (!(((FunctionType) ast.getFunctionName().getType()).getReturnType() instanceof VoidType))
            cg.write("pop" + ((FunctionType) ast.getFunctionName().getType()).getReturnType().suffix());
        return null;
    }

}