Skip to content

Commit

Permalink
got factorial working
Browse files Browse the repository at this point in the history
  • Loading branch information
parrt committed May 10, 2014
1 parent 9e2406e commit 47b9f0a
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 22 deletions.
43 changes: 37 additions & 6 deletions src/vm/Test.java
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand All @@ -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
Expand All @@ -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();
}
Expand Down
58 changes: 42 additions & 16 deletions src/vm/VM.java
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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();
}

Expand All @@ -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
Expand Down Expand Up @@ -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<String> operands = new ArrayList<String>();
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; i<operands.size(); i++) {
String s = operands.get(i);
if ( i>0 ) 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();
}
}

0 comments on commit 47b9f0a

Please sign in to comment.