-
Notifications
You must be signed in to change notification settings - Fork 0
/
runner.c
156 lines (123 loc) · 3.09 KB
/
runner.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#include "runner.h"
#include "funcs.h"
#ifdef DEBUG_RUNNER
#include "dis.h"
#endif
// The VM object just exists for slightly more extendability
void run_vm(VM *vm) {
if (run_scope(vm->scope) == INTERP_RET) {
fprintf(stderr, "Return statement outside of a function\n");
exit(-19);
}
}
InterpStat run_scope(Scope *scope) {
InterpStat state;
while ((state = run_next(scope)) == INTERP_OK);
return state;
}
// Run the next instruction
InterpStat run_next(Scope *scope) {
if (scope->ip >= vector_end(scope->chunk->code))
return INTERP_END;
#ifdef DEBUG_RUNNER
uint8_t *fakeip = scope->ip;
dis_instr(&fakeip, scope->chunk);
getchar();
#endif
uint8_t instr = *(scope->ip++);
switch (instr) {
case OP_PUSH:
push_val(scope, copy_val(get_val(scope)));
break;
case OP_NEG:
scope->stack[vector_size(scope->stack)-1].d *= -1;
break;
case OP_LOAD:
op_load(scope);
break;
case OP_BIND:
op_bind(scope);
break;
case OP_STORE:
op_store(scope);
break;
case OP_CONST_STORE:
op_const_store(scope);
break;
case OP_CALL:
#ifdef DEBUG_RUNNER
printf("Enter scope...\n");
#endif
op_call(scope);
#ifdef DEBUG_RUNNER
printf("Exit scope.\n");
#endif
break;
case OP_PRINT:
op_print(scope);
break;
case OP_PUTS:
op_puts(scope);
break;
case OP_ADD:
op_add(scope);
break;
case OP_SUB:
op_sub(scope);
break;
case OP_DIV:
op_div(scope);
break;
case OP_MOD:
op_mod(scope);
break;
case OP_MUL:
op_mul(scope);
break;
case OP_AND:
op_and(scope);
break;
case OP_OR:
op_or(scope);
break;
case OP_NOT:
op_not(scope);
break;
case OP_LT:
op_lt(scope);
break;
case OP_LTE:
op_lte(scope);
break;
case OP_GT:
op_gt(scope);
break;
case OP_GTE:
op_gte(scope);
break;
case OP_EQU:
op_equ(scope);
break;
case OP_IS:
op_is(scope);
break;
case OP_COND_JMP:
op_cond_jmp(scope);
break;
case OP_CONST_JMP:
op_const_jmp(scope);
break;
case OP_POP_TOP:
pop_back(scope);
break;
case OP_RETURN:
return INTERP_RET;
default:
fprintf(stderr, "@%lu: UNRECOGNIZED OPCODE: %u\n", scope->ip-scope->chunk->code-1, instr);
exit(-300);
}
#ifdef DEBUG_RUNNER
print_stack(scope);
#endif
return INTERP_OK;
}