<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">import java.util.ArrayList;
import java.util.Iterator;
import java.io.PrintWriter;

/**
 * An example AST (Abstract Syntax Tree) for a Simple language.
 * 
 * For CS 212, Sep 2007.
 * 
 * There are 6 tree node types: ProgramNode, DoNode, AssignmentNode, VariableNode,
 * NumberNode, and OperatorNode.  They all inherit from SimpleAST.
 * 
 * @author Paul Chew
 */
public abstract class SimpleAST {
    
    protected static int counter = 0;       // Source of unique number (for labels)
    static String[] operatorCommands = new String[]{"ADD", "SUB", "TIMES", "DIV"};

    /**
     * Generate appropriate SaM code for the AST node.
     */
    public abstract void generate (PrintWriter out);
}

/**
 * ProgramNode.
 */
class ProgramNode extends SimpleAST {
    
    ArrayList&lt;SimpleAST&gt; statements;       // List of all statements in a program.
    
    /**
     * @param statements list of all the statement nodes of the program
     */
    public ProgramNode (ArrayList&lt;SimpleAST&gt; statements) {
        this.statements = statements;
    }
    
    public String toString () {
        if (statements.size() == 0) return "P()";
        String s = "P(";
        Iterator&lt;SimpleAST&gt; it = statements.iterator();
        s = s + it.next();
        while (it.hasNext()) s = s + ", " + it.next();
        return s + ")";
    }
    
    public void generate (PrintWriter out) {
        out.println("ADDSP 3");                         // Make room for our 3 variables
        for (SimpleAST s: statements) s.generate(out);  // Generate code for all statements
        out.println("WRITE");                           // Write out our 3 variables
        out.println("WRITE");
        out.println("WRITE");
        out.println("STOP");
    }
}

/**
 * DoNode.
 */
class DoNode extends SimpleAST {
    
    SimpleAST expression;                 // The expression for the do-statement
    ArrayList&lt;SimpleAST&gt; statements;      // List of all statements in loop-body
    
    /**
     * @param expression represents the number of repetitions for the loop
     * @param statements list of all statments in the loop body
     */
    public DoNode (SimpleAST expression, ArrayList&lt;SimpleAST&gt; statements) {
        this.expression = expression;
        this.statements = statements;
    }
    
    public String toString () {
        String s = "D(" + expression;
        for (SimpleAST node: statements) s = s + ", " + node;
        return s + ")";
    }
    
    public void generate (PrintWriter out) {
        int doNumber = counter++;                      // Unique number
        expression.generate(out);                      // Count of times loop will be done
        out.println("do" + doNumber + ": DUP");        // Test for 0 (leave count on stack)
        out.println("NOT");
        out.println("JUMPC end" + doNumber);           // Jump to end if count is 0
        for (SimpleAST s: statements) s.generate(out); // Produce code for loop body
        out.println("PUSHIMM 1");                      // Subtract 1 from count
        out.println("SUB");
        out.println("JUMP do" + doNumber);             // Jump to top of loop
        out.println("end" + doNumber + ": ADDSP -1");  // Clear count from stack
            
    }
}

/**
 * AssignmentNode.
 */
class AssignmentNode extends SimpleAST {
    
    String target;              // The variable assigned to
    SimpleAST expression;       // The expression
    
    /**
     * @param target the target variable for the assignment statement
     * @param expression the expression of the assignment statement
     */
    public AssignmentNode (String target, SimpleAST expression) {
        this.target = target;
        this.expression = expression;
    }
    
    public String toString () {
        return "A(" + target + ", " + expression + ")";
    }
    
    public void generate (PrintWriter out) {
        expression.generate(out);
        out.println("STOREOFF " + "xyz".indexOf(target));
    }
}

/**
 * OperatorNode.
 */
class OperatorNode extends SimpleAST {
    
    String op;                  // The operator
    SimpleAST left, right;      // The operands
    
    /**
     * @param op the operator
     * @param left the left-side operand
     * @param right the right-side operand
     */
    public OperatorNode (String op, SimpleAST left, SimpleAST right) {
        this.op = op;
        this.left = left;
        this.right = right;
    }
    
    public String toString () {
        return op + "(" + left + ", " + right + ")";
    }
    
    public void generate (PrintWriter out) {
        left.generate(out);
        right.generate(out);
        String command = operatorCommands["+-*/".indexOf(op)];
        out.println(command);
    }
}

/**
 * VariableNode.
 */
class VariableNode extends SimpleAST {
    
    String variableName;        // Name of the variable
    
    /**
     * @param variableName the name of the variable
     */
    public VariableNode (String variableName) {
        this.variableName = variableName;
    }
    
    public String toString () {
        return "V[" + variableName + "]";
    }
    
    public void generate (PrintWriter out) {
        out.println("PUSHOFF " + "xyz".indexOf(variableName));
    }
}

/**
 * NumberNode.
 */
class NumberNode extends SimpleAST {
    
    int value;                   // Value of the number
    
    /**
     * @param value the number's value
     */
    public NumberNode (int value) {
        this.value = value;
    }
    
    public String toString () {
        return "N[" + value + "]";
    }
    
    public void generate (PrintWriter out) {
        out.println("PUSHIMM " + value);
    }
}</pre></body></html>