// code generator for the bitter compiler
import java.util.*;

class codeGenerator {
    
    private symbolTable symTab;
    int label = 0;
    StringBuffer target = new StringBuffer("");
    
    public codeGenerator(symbolTable s) {
	symTab = s;
    } // end of constructor
    
    String codeGen(token tok) {
	token t;
	int label1, label2;
	switch (tok.type) {
	case scanner._START:
	    target.append("declareq t\n");
	    Enumeration e = symTab.elements();
	    while (e.hasMoreElements()) {
		t = (token)e.nextElement();
		target.append("declareq " + t.name + '\n');
	    }
	    codeGen((token)tok.children.elementAt(0));
	    break;
	case scanner.EQ:
	    codeGen((token)tok.children.elementAt(1));
	    t = (token)tok.children.elementAt(0);
	    target.append("movq t " + t.name+ '\n');
	    if (t.name.equals("_out"))
		target.append("call output " + t.name + '\n');
	    break;
	case scanner.PLUS:
	    label1 = newLabel();
	    label2 = newLabel();
	    codeGen((token)tok.children.elementAt(0));
	    target.append("declareq t" + label1 + '\n');
	    target.append("movq t t" + label1 + '\n');
	    codeGen((token)tok.children.elementAt(1));
	    target.append("shiftl t+4 t" + label1+ '\n');
	    target.append("declarel t" + label2 + '\n');
	    target.append("movl d$\\32 t" + label2 + '\n');
	    target.append("subl t+4 t" + label2 + '\n');
	    target.append("shiftl t" + label2 + " t\n");
	    target.append("unshiftl t" + label2 + " t\n");
	    target.append("orl t" + label1 + " t\n");
	    target.append("addl t" + label1 + "+4 t+4\n"); 
	    break;
	case scanner.MINUS:
	    codeGen((token)tok.children.elementAt(0));
	    target.append("compl t\n");
	    break;
	case scanner.ID:
	    label1 = newLabel();
	    if (tok.name.equals("_in")) 
		target.append("call input " + tok.name+'\n');
	    target.append("movq " + tok.name + " t\n");
	    break;
	case scanner.STRING:
	    target.append("movl b$\\" + tok.name + " t\n");
	    target.append("movl d$\\" + tok.name.length() + " t+4\n");
	    break;
	case scanner._CLEAR:
	    t = (token)tok.children.elementAt(0);
	    target.append("clrq " + t.name+'\n');
	    if (t.name.equals("_out"))
		target.append("call output " + t.name+'\n');
	    codeGen((token)tok.children.elementAt(1));
	    break;
	case scanner.BAR:
	    codeGen((token)tok.children.elementAt(0));
	    codeGen((token)tok.children.elementAt(1));
	    break;
	case scanner.EPSILON:
	    break;
	}
	return target.toString();
    } // end codeGen
    
    private int newLabel(){
	return label++;
    }
    
    
} // end of codeGenerator
