Initial Commit

This commit is contained in:
2018-10-15 12:47:14 -06:00
commit 0c531ffff9
55 changed files with 7285 additions and 0 deletions
+8
View File
@@ -0,0 +1,8 @@
public class IntPair
{
public int first, second;
public IntPair( int a, int b )
{ first = a; second = b; }
}
Executable
+309
View File
@@ -0,0 +1,309 @@
import java.io.File;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.StringTokenizer;
public class VPL
{
static String fileName;
static Scanner keys;
static int max;
static int[] mem;
static int ip, bp, sp, rv, hp, numPassed, gp;
static int step;
public static void main(String[] args) throws Exception {
keys = new Scanner( System.in );
if( args.length != 2 ) {
System.out.println("Usage: java VPL <vpl program> <memory size>" );
System.exit(1);
}
fileName = args[0];
max = Integer.parseInt( args[1] );
mem = new int[max];
// load the program into the front part of
// memory
Scanner input = new Scanner( new File( fileName ) );
String line;
StringTokenizer st;
int opcode;
ArrayList<IntPair> labels, holes;
labels = new ArrayList<IntPair>();
holes = new ArrayList<IntPair>();
int label;
// load the code
int k=0;
while ( input.hasNextLine() ) {
line = input.nextLine();
System.out.println("parsing line [" + line + "]");
if( line != null )
{// extract any tokens
st = new StringTokenizer( line );
if( st.countTokens() > 0 )
{// have a token, so must be an instruction (as opposed to empty line)
opcode = Integer.parseInt(st.nextToken());
// load the instruction into memory:
if( opcode == labelCode )
{// note index that comes where label would go
label = Integer.parseInt(st.nextToken());
labels.add( new IntPair( label, k ) );
}
else if( opcode == noopCode ){
}
else
{// opcode actually gets stored
mem[k] = opcode; k++;
if( opcode == callCode || opcode == jumpCode ||
opcode == condJumpCode )
{// note the hole immediately after the opcode to be filled in later
label = Integer.parseInt( st.nextToken() );
mem[k] = label; holes.add( new IntPair( k, label ) );
++k;
}
// load correct number of arguments (following label, if any):
for( int j=0; j<numArgs(opcode); ++j )
{
mem[k] = Integer.parseInt(st.nextToken());
++k;
}
}// not a label
}// have a token, so must be an instruction
}// have a line
}// loop to load code
//System.out.println("after first scan:");
//showMem( 0, k-1 );
// fill in all the holes:
int index;
for( int m=0; m<holes.size(); ++m )
{
label = holes.get(m).second;
index = -1;
for( int n=0; n<labels.size(); ++n )
if( labels.get(n).first == label )
index = labels.get(n).second;
mem[ holes.get(m).first ] = index;
}
System.out.println("after replacing labels:");
showMem( 0, k-1 );
// initialize registers:
bp = k; sp = k+2; ip = 0; rv = -1; hp = max;
numPassed = 0;
int codeEnd = bp-1;
System.out.println("Code is " );
showMem( 0, codeEnd );
gp = codeEnd + 1;
// start execution:
boolean done = false;
int op, a=0, b=0, c=0;
int actualNumArgs;
int step = 0;
int oldIp = 0;
// repeatedly execute a single operation
// *****************************************************************
do {
/* // show details of current step
System.out.println("--------------------------");
System.out.println("Step of execution with IP = " + ip + " opcode: " +
mem[ip] +
" bp = " + bp + " sp = " + sp + " hp = " + hp + " rv = " + rv );
System.out.println(" chunk of code: " + mem[ip] + " " +
mem[ip+1] + " " + mem[ip+2] + " " + mem[ip+3] );
System.out.println("--------------------------");
System.out.println( " memory from " + (codeEnd+1) + " up: " );
showMem( codeEnd+1, sp+3 );
System.out.println("hit <enter> to go on" );
keys.nextLine();
*/
oldIp = ip;
op = mem[ ip ]; ip++;
// extract the args into a, b, c for convenience:
a = -1; b = -2; c = -3;
// numArgs is wrong for these guys, need one more!
if( op == callCode || op == jumpCode ||
op == condJumpCode )
{
actualNumArgs = numArgs( op ) + 1;
}
else
actualNumArgs = numArgs( op );
if( actualNumArgs == 1 )
{ a = mem[ ip ]; ip++; }
else if( actualNumArgs == 2 )
{ a = mem[ ip ]; ip++; b = mem[ ip ]; ip++; }
else if( actualNumArgs == 3 )
{ a = mem[ ip ]; ip++; b = mem[ ip ]; ip++; c = mem[ ip ]; ip++; }
// implement all operations here:
// ********************************************
// put your work right here!
if ( op == oppCode ) {
mem[ bp+2 + a ] = - mem[ bp+2 + b ];
}
else
{
System.out.println("Fatal error: unknown opcode [" + op + "]" );
System.exit(1);
}
step++;
}while( !done );
}// main
// use symbolic names for all opcodes:
// op to produce comment
private static final int noopCode = 0;
// ops involved with registers
private static final int labelCode = 1;
private static final int callCode = 2;
private static final int passCode = 3;
private static final int allocCode = 4;
private static final int returnCode = 5; // return a means "return and put
// copy of value stored in cell a in register rv
private static final int getRetvalCode = 6;//op a means "copy rv into cell a"
private static final int jumpCode = 7;
private static final int condJumpCode = 8;
// arithmetic ops
private static final int addCode = 9;
private static final int subCode = 10;
private static final int multCode = 11;
private static final int divCode = 12;
private static final int remCode = 13;
private static final int equalCode = 14;
private static final int notEqualCode = 15;
private static final int lessCode = 16;
private static final int lessEqualCode = 17;
private static final int andCode = 18;
private static final int orCode = 19;
private static final int notCode = 20;
private static final int oppCode = 21;
// ops involving transfer of data
private static final int litCode = 22; // litCode a b means "cell a gets b"
private static final int copyCode = 23;// copy a b means "cell a gets cell b"
private static final int getCode = 24; // op a b means "cell a gets
// contents of cell whose
// index is stored in b"
private static final int putCode = 25; // op a b means "put contents
// of cell b in cell whose offset is stored in cell a"
// system-level ops:
private static final int haltCode = 26;
private static final int inputCode = 27;
private static final int outputCode = 28;
private static final int newlineCode = 29;
private static final int symbolCode = 30;
private static final int newCode = 31;
// global variable ops:
private static final int allocGlobalCode = 32;
private static final int toGlobalCode = 33;
private static final int fromGlobalCode = 34;
// debug ops:
private static final int debugCode = 35;
// return the number of arguments after the opcode,
// except ops that have a label return number of arguments
// after the label, which always comes immediately after
// the opcode
private static int numArgs( int opcode )
{
// highlight specially behaving operations
if( opcode == labelCode ) return 1; // not used
else if( opcode == jumpCode ) return 0; // jump label
else if( opcode == condJumpCode ) return 1; // condJump label expr
else if( opcode == callCode ) return 0; // call label
// for all other ops, lump by count:
else if( opcode==noopCode ||
opcode==haltCode ||
opcode==newlineCode ||
opcode==debugCode
)
return 0; // op
else if( opcode==passCode || opcode==allocCode ||
opcode==returnCode || opcode==getRetvalCode ||
opcode==inputCode ||
opcode==outputCode || opcode==symbolCode ||
opcode==allocGlobalCode
)
return 1; // op arg1
else if( opcode==notCode || opcode==oppCode ||
opcode==litCode || opcode==copyCode || opcode==newCode ||
opcode==toGlobalCode || opcode==fromGlobalCode
)
return 2; // op arg1 arg2
else if( opcode==addCode || opcode==subCode || opcode==multCode ||
opcode==divCode || opcode==remCode || opcode==equalCode ||
opcode==notEqualCode || opcode==lessCode ||
opcode==lessEqualCode || opcode==andCode ||
opcode==orCode || opcode==getCode || opcode==putCode
)
return 3;
else
{
System.out.println("Fatal error: unknown opcode [" + opcode + "]" );
System.exit(1);
return -1;
}
}// numArgs
private static void showMem( int a, int b )
{
for( int k=a; k<=b; ++k )
{
System.out.println( k + ": " + mem[k] );
}
}// showMem
}// VPL
Executable
+17
View File
@@ -0,0 +1,17 @@
32 1 allocate one global cell named "0"
4 10 make plenty of scratch space in the "main" stack frame
22 0 17 local cell 0 <- constant 17
33 0 0 global cell 0 <- local cell 0
27 1 local cell 1 <- input from keyboard
34 2 0 local cell 2 <- global cell 0
9 3 1 2 local cell 3 <- input + copy of global value
28 3 display the final answer
29 newline
26 halt
Executable
+33
View File
@@ -0,0 +1,33 @@
0 Here's the map between local cells and names:
0 Local cell: Name:
0 0 n (input value)
0 1 2 (literal)
0 2 1 (literal)
0 3 n % 2
4 4 allocate space for 4 local cells
27 0 local cell 0 <- input value (n)
22 1 2 local cell 1 <- literal 2
22 2 1 local cell 2 <- literal 1
13 3 0 1 local cell 3 <- n % 2 (conveniently 0 or 1
8 1001 3 if n%2 is not 0 jump to 1001
0 case that n is even
28 1 display 2 to say that n is even
29
7 1002 hop over code for odd case
1 1001 case that n is odd
28 2 display 1 to say that n is odd
29
1 1002
26
Executable
+28
View File
@@ -0,0 +1,28 @@
0 Local cell: Name:
0 0 n (display 1..n)
0 1 j (index in loop
0 2 1 (literal)
0 3 n < j
4 4 allocate space for 4 local cells
27 0 n = keyboard input
22 1 1 j <- 1
22 2 1
1 1001 top of loop
16 3 0 1 if n < j exit loop
8 1002 3
28 1 println j
29
9 1 1 2 j = j+1
7 1001 go up to top of loop
1 1002 exit loop
26 halt
Executable
+43
View File
@@ -0,0 +1,43 @@
0 Local cell: Name:
0 0 x
0 1 1
0 2 2
0 3 3
0 4 x==1, x % 2
4 5 allocate local cells in main stack frame
22 1 1 set the literals
22 2 2
22 3 3
27 0 x <- input
1 1001 top of loop
14 4 0 1 local cell 4 <- x == 1
8 1002 4 if x==1 exit loop
28 0 println x
29
13 4 0 2 local cell 4 <- x%2, so is 0 if x even, 1 if x odd
8 1003 4 if x is odd jump
0 didn't jump so x is even
12 0 0 2 x <- x / 2
7 1004 skip over x odd code
1 1003 start of x odd case
11 0 0 3 x <- x*3
9 0 0 1 x <- x+1
1 1004
7 1001 jump to top of loop
1 1002 exit loop
26
Executable
+23
View File
@@ -0,0 +1,23 @@
4 3
27 0
3 0
2 1001
6 1
28 1
29
26
1 1001
4 6
22 2 2
22 1 1
16 6 0 2
8 2001 6
10 3 0 1
3 3
2 1001
6 4
11 5 0 4
5 5
1 2001
5 1
Executable
+103
View File
@@ -0,0 +1,103 @@
0 main subprogram
0 cells used:
0
0 0 holds starting index of list
0 1 holds n=# of items in list
4 2
27 1
3 1
2 100000
6 0
28 0
29
3 0
2 200000
29
26
0 list input subprogram
0 cells used
0 0 parameter (n=desired number of items in list)
0 1 literal 1
0 2 n+1
0 3 index (k) in loop
0 4 holds starting point (a) of list
0 5 boolean result of n < k
0 6 input value
1 100000
4 6
22 1 1 create 1
9 2 0 1 cell 2 = n+1
31 4 2 a = new int[n+1]
22 3 0 k=0
25 4 3 0 a[k] = n
22 3 1 k=1
1 102 top of loop
16 5 0 3 cell 5 = n < k
8 101 5 if n < k jump to 101
27 6 cell 6 = input value
25 4 3 6 a[k] = input value
9 3 3 1 k=k+1
7 102 jump to top of loop
1 101 exit point of loop
5 4 return a
0 list display subprogram
0 cells used:
0 0 index of start of object (a)
0 1 literal 1
0 2 number of items in list (n)
0 3 index k
0 4 ascii code for a space (32)
0 5 n < k
0 6 temp
1 200000
4 5
22 1 1
22 4 32
22 3 0 k=0
24 2 0 3 n=a[0]
22 3 1 k=1
1 201 top of loop
16 5 2 3 cell 5 = n < k
8 202 5 if n < k exit loop
24 6 0 3 temp = a[k]
28 6 print temp
30 4 print a space
9 3 3 1 k=k+1
7 201 jump to top of loop
1 202 exit loop
5 0 return (value stored in RV irrelevant)
Executable
+32
View File
@@ -0,0 +1,32 @@
4 3
27 0
27 1
3 0
3 1
2 101
6 2
28 2
29
26
1 101
4 6
22 2 1
22 5 0
14 6 1 5
8 102 6
14 6 1 0
8 102 6
10 3 0 2
10 4 1 2
3 3
3 4
2 101
6 6
3 3
3 1
2 101
6 7
9 6 6 7
5 6
1 102
5 2
+93
View File
@@ -0,0 +1,93 @@
4 5
27 0
28 0
29
22 0 23
22 1 17
22 3 0
22 4 1
9 2 0 1
28 2
29
10 2 0 1
28 2
29
11 2 0 1
28 2
29
12 2 0 1
28 2
29
13 2 0 1
28 2
29
14 2 0 1
28 2
14 2 1 1
28 2
29
15 2 1 1
28 2
15 2 0 1
28 2
29
16 2 1 0
28 2
16 2 0 1
28 2