//VirtualMachine import gi.*; /*\semantics*/import java.util.*; /*\off*/ class VirtualMachine extends SLR1_Grammar { VirtualMachine() throws Exception { put("LITERAL", expression("[[:digit:]]+")); put("IDENTIFIER", expression("[[:alpha:]][[:alnum:]]*")); put("BRANCH", expression("b(lt|eq|gt|ge|ne|le)")); put("SPACE", expression("[[:space:]]+")); // /*\semantics*/semantic specification/*\off*/ //VirtualMachine.InstrList /*\semantics*/ final Map labels = new HashMap(); //VirtualMachine.Program /*\semantics*/ Semantics run = new Semantics() { String operation(ParseTree ic) {return (String)ic.child[0].value;} String operand(ParseTree ic) {return (String)ic.child[1].value;} ParseTree next(ParseTree ic) {return (ParseTree)ic.value;} int pop(Stack runtime) {return ((Integer)runtime.pop()).intValue();} public void f(ParseTree t, int l) { Stack runtime = new Stack(); Map memory = new HashMap(); int comparator = 0; for (ParseTree ic = (ParseTree)t.child[l-1].value; ic != null;) { String operation = operation(ic); // instruction execution //VirtualMachine.Program.instruction /*\semantics*/ if (operation.equals("lc")) { runtime.push(new Integer(operand(ic))); } else if (operation.equals("load")) { runtime.push(memory.get(operand(ic))); } else if (operation.equals("store")) { memory.put(operand(ic), runtime.pop()); } else if (operation.equals("goto")) { ic = (ParseTree)labels.get(operand(ic)); continue; } else if (operation.equals("comp")) { int right = pop(runtime), left = pop(runtime); comparator = (left < right) ? 0x4 : (left == right) ? 0x2 : 0x1; } else if (operation.equals("blt") && (comparator & 0x4) > 0) { ic = (ParseTree)labels.get(operand(ic)); continue; } else if (operation.equals("beq") && (comparator & 0x2) > 0) { ic = (ParseTree)labels.get(operand(ic)); continue; } else if (operation.equals("bgt") && (comparator & 0x1) > 0) { ic = (ParseTree)labels.get(operand(ic)); continue; } else if (operation.equals("bge") && (comparator & 0x3) > 0) { ic = (ParseTree)labels.get(operand(ic)); continue; } else if (operation.equals("bne") && (comparator & 0x5) > 0) { ic = (ParseTree)labels.get(operand(ic)); continue; } else if (operation.equals("ble") && (comparator & 0x6) > 0) { ic = (ParseTree)labels.get(operand(ic)); continue; } else if (operation.equals("add")) { int right = pop(runtime), left = pop(runtime); runtime.push(new Integer(left + right)); } else if (operation.equals("mult")) { int right = pop(runtime), left = pop(runtime); runtime.push(new Integer(left * right)); }/*\off*/ //VirtualMachine.Program ic = next(ic); } System.out.println("runtime = " + runtime); System.out.println("memory = " + memory); System.out.println("comparator = " + comparator); } }; /*\off*/ put("Program", new Object[][] { {"InstrList"/*\semantics*/, run/*\off*/}, }); //VirtualMachine.InstrList Semantics assemble = new Semantics() { public void f(ParseTree t, int l) { t.child[l-2].value = t.child[l-1].value; t.value = t.child[l-2]; } }; Semantics label = new Semantics() { public void f(ParseTree t, int l) { labels.put(t.child[l-3].value, t.child[l-1].value); t.value = t.child[l-1].value; } }; /*\off*/ put("InstrList", new Object[][] { {}, {"Instr", "InstrList"/*\semantics*/, assemble/*\off*/}, {"IDENTIFIER", ":", "InstrList"/*\semantics*/, label/*\off*/}, }); put("Instr", new Object[][] { {"lc", "LITERAL"}, {"load", "IDENTIFIER"}, {"store", "IDENTIFIER"}, {"goto", "IDENTIFIER"}, {"comp"}, {"BRANCH", "IDENTIFIER"}, {"add"}, {"mult"}, }); //VirtualMachine } public static void main(String[] arguments) throws Exception { new VirtualMachine().interpret(arguments); } }