Added new experimental VM from Mat. This is the 'faster vm' option.
[retro/experimental.git] / toka / vm.c
blob5e8b8268cf742fe303054a54789680258fafd012
1 /******************************************************
2 * Toka
4 *|F|
5 *|F| FILE: vm.c
6 *|F|
8 * Copyright (c) 2006, 2007 Charles R. Childers
10 * Permission to use, copy, modify, and distribute this
11 * software for any purpose with or without fee is hereby
12 * granted, provided that the above copyright notice and
13 * this permission notice appear in all copies.
15 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR
16 * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
17 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
18 * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE
19 * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
20 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
21 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
22 * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
23 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
24 * OF THIS SOFTWARE.
25 ******************************************************/
27 #include <stdio.h>
28 #include <stdlib.h>
30 #include "toka.h"
33 /******************************************************
34 *|F| Variables:
35 *|F| Inst *heap
36 *|F| Pointer into the current heap
37 *|F|
38 *|F| Inst *ip
39 *|F| The instruction pointer
40 *|F|
41 *|F| VM_STACK data, address, alternate
42 *|F| The data, address, and return stacks
43 *|F|
44 ******************************************************/
45 Inst *heap, *ip;
46 VM_STACK data, address, alternate;
49 /******************************************************
50 *|F| vm_init()
51 *|F| Prepare the virtual machine. This sets up the
52 *|F| stacks, and any other things that need to be
53 *|F| initialized.
54 *|F|
55 ******************************************************/
56 void vm_init()
58 data.stack = gc_alloc(MAX_DATA_STACK, sizeof(long), GC_KEEP);
59 address.stack = gc_alloc(MAX_DATA_STACK, sizeof(long), GC_KEEP);
60 alternate.stack = gc_alloc(MAX_DATA_STACK, sizeof(long), GC_KEEP);
62 data.sp = 0;
63 address.sp = 0;
64 alternate.sp = 0;
68 /******************************************************
69 *|F| vm_run(Inst)
70 *|F| Run through a list of instructions
71 *|F| Side effects:
72 *|F| modifes *ip
73 *|F|
74 ******************************************************/
75 void vm_run(Inst prog[])
77 ip = prog;
78 while (*ip != 0)
80 vm_stack_check();
81 ((*ip++)());
86 /******************************************************
87 *|F| vm_stack_check()
88 *|F| Check for over/underflow and reset if detected
89 *|F| If the return stack over/underflows, exit Toka
90 *|F|
91 ******************************************************/
92 void vm_stack_check()
94 if (data.sp < 0 || data.sp > MAX_DATA_STACK)
95 error(ERROR_STACK);
96 if ((address.sp < 0 || address.sp > MAX_RETURN_STACK) || (alternate.sp < 0 || alternate.sp > MAX_DATA_STACK))
97 error(ERROR_STACK);
101 /******************************************************
102 *|F| vm_push(long a)
103 *|F| Push a number to the stack.
104 *|F|
105 ******************************************************/
106 void vm_push(long a)
108 data.sp++; TOS = a;
112 /******************************************************
113 *|F| vm_lit()
114 *|F| Push the value in the following memory location
115 *|F| to the stack
116 *|F|
117 ******************************************************/
118 void vm_lit()
120 vm_push((long)*ip++);
124 /******************************************************
125 *|F| vm_quote_lit()
126 *|F| Push the value in the following memory location
127 *|F| to the stack
128 *|F|
129 ******************************************************/
130 void vm_quote_lit()
132 vm_push((long)*ip++);
136 /******************************************************
137 *|F| vm_string_lit()
138 *|F| Push the pointer in the following memory location
139 *|F| to the stack. This is a helper function for
140 *|F| strings.
141 *|F|
142 ******************************************************/
143 void vm_string_lit()
145 vm_push((long)*ip++);
149 /******************************************************
150 *|F| vm_primitive()
151 *|F| Invoke the primitive id # specified in the
152 *|F| following cell.
153 ******************************************************/
154 void vm_primitive()
156 Inst xt;
157 xt = (Inst )*ip++;
158 ((xt)());