From 47b9f0aa62655f08a523cecfa5e1e92efa8ad931 Mon Sep 17 00:00:00 2001 From: Terence Parr Date: Fri, 9 May 2014 22:08:40 -0700 Subject: [PATCH] got factorial working --- src/vm/Test.java | 43 ++++++++++++++++++++++++++++++----- src/vm/VM.java | 58 +++++++++++++++++++++++++++++++++++------------- 2 files changed, 79 insertions(+), 22 deletions(-) diff --git a/src/vm/Test.java b/src/vm/Test.java index 239dea4..90be2c3 100644 --- a/src/vm/Test.java +++ b/src/vm/Test.java @@ -2,13 +2,18 @@ import static vm.Bytecode.BR; import static vm.Bytecode.BRF; +import static vm.Bytecode.CALL; import static vm.Bytecode.GLOAD; import static vm.Bytecode.GSTORE; import static vm.Bytecode.HALT; import static vm.Bytecode.IADD; import static vm.Bytecode.ICONST; import static vm.Bytecode.ILT; +import static vm.Bytecode.IMUL; +import static vm.Bytecode.ISUB; +import static vm.Bytecode.LOAD; import static vm.Bytecode.PRINT; +import static vm.Bytecode.RET; public class Test { static int[] hello = { @@ -19,8 +24,8 @@ public class Test { static int[] loop = { // .GLOBALS 2; N, I - // N = 100000000 ADDRESS - ICONST, 100000000, // 0 + // N = 10 ADDRESS + ICONST, 10, // 0 GSTORE, 0, // 2 // I = 0 ICONST, 0, // 4 @@ -43,14 +48,40 @@ public class Test { }; static int[] factorial = { - +//.def fact: ARGS=1, LOCALS=0 ADDRESS +// IF N < 2 RETURN 1 + LOAD, -3, // 0 + ICONST, 2, // 2 + ILT, // 4 + BRF, 10, // 5 + ICONST, 1, // 7 + RET, // 9 +//CONT: +// RETURN N * FACT(N-1) + LOAD, -3, // 10 + LOAD, -3, // 12 + ICONST, 1, // 14 + ISUB, // 16 + CALL, 0, 1, // 17 + IMUL, // 20 + RET, // 21 +//.DEF MAIN: ARGS=0, LOCALS=0 +// PRINT FACT(10) + ICONST, 5, // 22 + CALL, 0, 1, // 24 + PRINT, // 27 + HALT // 28 }; public static void main(String[] args) { - VM vm = new VM(hello, 0, 0); - vm.exec(); +// VM vm = new VM(hello, 0, 0); +// vm.exec(); +// +// vm = new VM(loop, 0, 2); +// vm.trace = true; +// vm.exec(); - vm = new VM(loop, 0, 2); + VM vm = new VM(factorial, 22, 0); vm.trace = true; vm.exec(); } diff --git a/src/vm/VM.java b/src/vm/VM.java index 201df52..52500ca 100644 --- a/src/vm/VM.java +++ b/src/vm/VM.java @@ -25,8 +25,8 @@ /** A simple stack-based interpreter */ public class VM { public static final int DEFAULT_STACK_SIZE = 1000; - public static final int TRUE = 1; public static final int FALSE = 0; + public static final int TRUE = 1; // registers int ip; // instruction pointer register @@ -50,7 +50,7 @@ public VM(int[] code, int startip, int nglobals) { } public void exec() { - stack[++sp] = 0; // simulate call from operating system + ip = startip; cpu(); } @@ -59,33 +59,33 @@ protected void cpu() { int opcode = code[ip]; int a,b,addr,offset; while (opcode!= HALT && ip < code.length) { - if ( trace ) trace(); + if ( trace ) System.out.printf("%-35s", disInstr()); ip++; //jump to next instruction or to operand switch (opcode) { case IADD: - a = stack[sp--]; // 1st opnd 1 below top b = stack[sp--]; // 2nd opnd at top of stack + a = stack[sp--]; // 1st opnd 1 below top stack[++sp] = a + b; // push result break; case ISUB: - a = stack[sp--]; b = stack[sp--]; + a = stack[sp--]; stack[++sp] = a - b; break; case IMUL: - a = stack[sp--]; b = stack[sp--]; + a = stack[sp--]; stack[++sp] = a * b; break; case ILT : - a = stack[sp--]; b = stack[sp--]; - stack[++sp] = a < b ? TRUE : FALSE; + a = stack[sp--]; + stack[++sp] = (a < b) ? TRUE : FALSE; break; case IEQ : - a = stack[sp--]; b = stack[sp--]; - stack[++sp] = a == b ? TRUE : FALSE; + a = stack[sp--]; + stack[++sp] = (a == b) ? TRUE : FALSE; break; case CALL : // expects all args on stack @@ -146,27 +146,53 @@ protected void cpu() { default : throw new Error("invalid opcode: "+opcode+" at ip="+(ip-1)); } + if ( trace ) System.out.println(stackString()); opcode = code[ip]; } + if ( trace ) System.out.printf("%-35s", disInstr()); + if ( trace ) System.out.println(stackString()); + if ( trace ) dumpDataMemory(); + } + + protected String stackString() { + StringBuilder buf = new StringBuilder(); + buf.append("stack=["); + for (int i = 0; i <= sp; i++) { + int o = stack[i]; + buf.append(" "); + buf.append(o); + } + buf.append(" ]"); + return buf.toString(); } - protected void trace() { + protected String disInstr() { int opcode = code[ip]; String opName = Bytecode.instructions[opcode].name; - System.out.printf("%04d:\t%-11s", ip, opName); + StringBuilder buf = new StringBuilder(); + buf.append(String.format("%04d:\t%-11s", ip, opName)); int nargs = Bytecode.instructions[opcode].n; if ( nargs>0 ) { List operands = new ArrayList(); for (int i=ip+1; i<=ip+nargs; i++) { operands.add(String.valueOf(code[i])); } - for (int i = 0; i < operands.size(); i++) { + for (int i = 0; i0 ) System.out.print(", "); - System.out.print(s); + if ( i>0 ) buf.append(", "); + buf.append(s); } } - System.out.println(); + return buf.toString(); } + protected void dumpDataMemory() { + System.out.println("Data memory:"); + int addr = 0; + for (int o : globals) { + System.out.printf("%04d: %s\n", addr, o); + addr++; + } + System.out.println(); + } }