001: /* -*- mode: Java; c-basic-offset: 2; -*- */
002:
003: /***
004: * InstructionPrinter.java
005: * Author: Oliver Steele, P T Withington
006: * Description: Implements an Emitter that just prints the instructions
007: */package org.openlaszlo.sc;
008:
009: import java.io.*;
010: import java.util.*;
011: import org.openlaszlo.sc.Instructions.*;
012: import org.openlaszlo.sc.Emitter;
013: import org.openlaszlo.sc.Actions.*;
014:
015: public class InstructionPrinter implements Emitter {
016: Stack labelStack = new Stack();
017: int nextLabel = 1;
018: String linePrefix = "";
019: PrintStream writer;
020:
021: public InstructionPrinter(PrintStream writer, String prefix) {
022: this .linePrefix = prefix;
023: this .writer = writer;
024: }
025:
026: public InstructionPrinter(PrintStream writer) {
027: this (writer, "");
028: }
029:
030: public InstructionPrinter() {
031: this (System.out);
032: }
033:
034: public byte[] assemble(List instrs) {
035: for (Iterator i = instrs.iterator(); i.hasNext();) {
036: emit((Instruction) i.next());
037: }
038: return null;
039: }
040:
041: public static class StackEntry {
042: Action sourceType;
043: Object label;
044:
045: StackEntry(Action sourceType, Object label) {
046: this .sourceType = sourceType;
047: this .label = label;
048: }
049: }
050:
051: public void emit(Instruction instr) {
052: if (instr instanceof LABELInstruction) {
053: Object name = ((LABELInstruction) instr).name;
054: StackEntry entry;
055: if (!labelStack.empty()
056: && ((StackEntry) labelStack.peek()).label == name) {
057: while (!labelStack.empty()
058: && (entry = (StackEntry) labelStack.peek()).label == name) {
059: Action sourceType = entry.sourceType;
060: labelStack.pop();
061: linePrefix = linePrefix.substring(0, linePrefix
062: .length() - 2);
063: String comment = "";
064: if (sourceType == Actions.DefineFunction
065: || sourceType == Actions.DefineFunction2) {
066: comment = " // of function\n";
067: }
068: writer.print(linePrefix);
069: writer.print("end");
070: writer.println(comment);
071: }
072: } else {
073: writer.println(instr.toString());
074: }
075: return;
076: }
077: if (instr instanceof ConcreteInstruction) {
078: ConcreteInstruction cInstr = ((ConcreteInstruction) instr);
079: Action op = cInstr.op;
080: List args = cInstr.args;
081: if (op == Actions.DefineFunction
082: || op == Actions.DefineFunction2) {
083: String target = (String) args.get(0);
084: labelStack.push(new StackEntry(op, target));
085: writer.print(linePrefix);
086: writer.println(cInstr.toString());
087: linePrefix += " ";
088: } else if (op == Actions.WITH) {
089: labelStack
090: .push(new StackEntry(op, (String) args.get(0)));
091: writer.print(linePrefix);
092: writer.println(cInstr.toString());
093: linePrefix += " ";
094: }
095: } else {
096: // TODO: [2005-11-15 ptw] Why do we need this?
097: // if (instr instanceof TargetInstruction) {
098: // instr = instr.replaceTarget(instr.getTarget());
099: // }
100: writer.print(linePrefix);
101: writer.println(instr.toString());
102: }
103: }
104: }
|