Skip to content

Función execute

La función execute se definió mediante dos plantillas, una por cada statement:

execute⟦statementexecute⟦print → expression⟧ =
     #LINE {end.line}
     value⟦expression⟧
     OUT<expression.type>

execute⟦assignment → left:expression right:expression⟧ =
     #LINE {end.line}
     address⟦left⟧
     value⟦right⟧
     STORE<left.type>

La implementación sería en este caso:

java
public class Execute extends AbstractCodeFunction {

    public Object visit(Print print, Object param) {
        line(print);
        value(print.getExpression());
        out("out", print.getExpression().getType());

        return null;
    }

    public Object visit(Assignment assignment, Object param) {
        line(assignment);
        address(assignment.getLeft());
        value(assignment.getRight());
        out("store", assignment.getLeft().getType());

        return null;
    }

    // Auxiliary method
    private void line(AST node) {
        if (node.end() != null)
            out("\n#line " + node.end().getLine());
    }
}

Para simplificar la generación de las variantes de las instrucciones en función de su tipo (las que siguen la notación instruction<type>), se ha añadido una sobrecarga de la función out en la clase AbstractCodeFunction.java:

java
public abstract class AbstractCodeFunction extends ExceptionThrowerVisitor {

    // ... omitted for brevity

    // Métodos auxiliares para la escritura de código
    protected void out(String line) {
        specification.getPrintWriter().println(line);
    }

    protected void out(String instruction, Type type) {
        out(instruction + suffixFor(type));
    }

    protected String suffixFor(Type type) {
        if (type instanceof IntType)
            return "i";
        if (type instanceof FloatType)
            return "f";

        // Sealed classes + pattern matching would avoid this situation. Those features were not
        // finished when this code was implemented
        throw new IllegalArgumentException("Unknown Type: " + type);
    }
}

Los motivos por los que se ha añadido el método out(String, Type) en esta clase y no en otros sitios son:

  • Siguiendo el criterio del patrón visitor, se ha intentando evitar que los visitors añadan métodos propios a los nodos. El método out(String, type) es específico para MAPL y, en un futuro, podría cambiarse a otra arquitectura destino. En ese caso, no se querría que quedaran en el AST métodos de la generación de MAPL.
  • Este método, además, será usado por más visitors, por lo que no es adecuado implementarlo como método private del visitor execute. Por tanto, se pone en la clase base de todos ellos.