Adicionado operadores relacionais.
[myPerl.git] / vm.c
blobcaa3d32b57dec25f40ffc9987b4752694f851dc2
1 #include <stdio.h>
2 #include <assert.h>
3 #include "heap.h"
4 #include "code.h"
5 #include "symtab.h"
6 #include "vm.h"
8 #define STACK_SIZE 4096
10 static int top = -1;
11 static int stack[STACK_SIZE];
13 static int fun_top = -1;
14 static int fun_stack[STACK_SIZE];
16 static int pc = 0; /* program counter */
18 enum {
19 O_ADD, O_SUB, O_MUL, O_DIV, O_MOD,
20 O_EQL, O_NE, O_GEQL, O_LEQL, O_GT, O_LT };
22 static void
23 bin_op(int op)
25 assert(top >= 1);
26 switch(op) {
27 case O_ADD:
28 stack[top-1] = stack[top-1] + stack[top];
29 break;
30 case O_SUB:
31 stack[top-1] = stack[top-1] - stack[top];
32 break;
33 case O_MUL:
34 stack[top-1] = stack[top-1] * stack[top];
35 break;
36 case O_DIV:
37 stack[top-1] = stack[top-1] / stack[top];
38 break;
39 case O_MOD:
40 stack[top-1] = stack[top-1] % stack[top];
41 break;
42 case O_EQL:
43 stack[top-1] = stack[top-1] == stack[top];
44 break;
45 case O_NE:
46 stack[top-1] = stack[top-1] != stack[top];
47 break;
48 case O_GEQL:
49 stack[top-1] = stack[top-1] >= stack[top];
50 break;
51 case O_LEQL:
52 stack[top-1] = stack[top-1] <= stack[top];
53 break;
54 case O_GT:
55 stack[top-1] = stack[top-1] > stack[top];
56 break;
57 case O_LT:
58 stack[top-1] = stack[top-1] < stack[top];
59 break;
60 default:
61 fprintf(stderr, "Operacao %d nao reconhecida\n", op);
62 break;
64 --top;
65 pc++;
68 void
69 vm_halt(int arg)
73 void
74 vm_add(int arg)
76 bin_op(O_ADD);
79 void
80 vm_sub(int arg)
82 bin_op(O_SUB);
85 void
86 vm_mul(int arg)
88 bin_op(O_MUL);
91 void
92 vm_div(int arg)
94 bin_op(O_DIV);
97 void
98 vm_mod(int arg)
100 bin_op(O_MOD);
103 void
104 vm_cmp_eql(int arg)
106 bin_op(O_EQL);
109 void
110 vm_cmp_ne(int arg)
112 bin_op(O_NE);
115 void
116 vm_cmp_geql(int arg)
118 bin_op(O_GEQL);
121 void
122 vm_cmp_leql(int arg)
124 bin_op(O_LEQL);
127 void
128 vm_cmp_gt(int arg)
130 bin_op(O_GT);
133 void
134 vm_cmp_lt(int arg)
136 bin_op(O_LT);
139 void
140 vm_load_var(int arg)
142 int off = stack[top--];
143 stack[++top] = data_get(arg, off);
144 pc++;
147 void
148 vm_load_int(int arg)
150 stack[++top] = arg;
151 pc++;
154 void
155 vm_load_off(int arg)
157 stack[++top] = arg;
158 pc++;
161 void
162 vm_store(int arg)
164 int off = stack[top--];
165 assert(top >= 0);
166 data_put(arg, off, stack[top]);
167 top--;
168 pc++;
171 void
172 vm_jmp_false(int arg)
174 if (stack[top] == 0)
175 pc = arg;
176 else
177 pc++;
178 top--;
181 void
182 vm_goto(int arg)
184 pc = arg;
187 void
188 vm_write_int(int arg)
190 printf("%d\n", stack[top]);
191 top--;
192 pc++;
195 void
196 vm_call(int arg)
198 scope++;
199 pc = arg;
202 void
203 vm_push_int(int arg)
205 fun_stack[++fun_top] = arg;
206 pc++;
209 void
210 vm_push_var(int arg)
212 fun_stack[++fun_top] = data_get(arg, stack[top--]);
213 pc++;
216 void
217 vm_ret(int arg)
219 int nargs;
221 pc = fun_stack[fun_top--];
222 nargs = fun_stack[fun_top--];
224 top -= nargs;
226 assert(fun_top >= -1 && top >= -1);
228 scoperem(scope--);
232 vm_loop(void)
234 while (code[pc].op != HALT) {
235 ops[code[pc].op].op(code[pc].arg);
238 return 0;