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
|
#include "dis.h"
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
static void print_const(Chunk *ch, uint8_t ix) {
Val k = ch->consts.d[ix];
printf("%-4s : ", typename_str(k));
println_val(k);
}
void disasm_chunk(Chunk *ch) {
puts("constants:");
for (uint8_t cix = 0; cix < ch->consts.len; cix++) {
printf("%hd\t",cix);
print_const(ch, cix);
}
puts("bytecode:");
for (size_t ip = 0; ip < ch->bc.len; ) {
uint8_t instr = ch->bc.d[ip];
printf("%04zd\t",ip);
ip ++;
switch (instr) {
case OP_LOADK: {
uint8_t ix = ch->bc.d[ip++];
printf("loadk #%d\t; ",ix);
print_const(ch, ix);
break;
}
case OP_GETGLOBAL: {
uint8_t ix = ch->bc.d[ip++];
printf("getglobal #%d\t; ",ix);
print_const(ch, ix);
break;
}
case OP_SETGLOBAL: {
uint8_t ix = ch->bc.d[ip++];
printf("setglobal #%d\t; ",ix);
print_const(ch, ix);
break;
}
#define RSHORT() (uint16_t)( ch->bc.d[ip-2] | ch->bc.d[ip-1] << 8 )
case OP_SKIP: {
ip += 2;
uint16_t offset = RSHORT();
printf("skip +%5hu\t; -> %04zd\n", offset, ip + offset);
break;
}
case OP_0BRANCH: {
ip += 2;
uint16_t offset = RSHORT();
printf("0branch +%5hu\t; -> %04zd\n", offset, ip + offset);
break;
}
case OP_REDO: {
ip += 2;
uint16_t offset = RSHORT();
printf("redo -%5hu\t; -> %04zd\n", offset, ip - offset);
break;
}
#undef RSHORT
#define SIMPLE_INSTR(opcode, str) \
case opcode: puts(str); break;
SIMPLE_INSTR(OP_RET, "ret")
SIMPLE_INSTR(OP_PUTS, "puts")
SIMPLE_INSTR(OP_PRINT, "print")
SIMPLE_INSTR(OP_DROP, "drop")
SIMPLE_INSTR(OP_ADD, "add")
SIMPLE_INSTR(OP_SUB, "sub")
SIMPLE_INSTR(OP_MUL, "mul")
SIMPLE_INSTR(OP_DIV, "div")
SIMPLE_INSTR(OP_MOD, "mod")
SIMPLE_INSTR(OP_NIL, "nil")
SIMPLE_INSTR(OP_TRUE, "true")
SIMPLE_INSTR(OP_FALSE, "false")
SIMPLE_INSTR(OP_CMP, "cmp")
SIMPLE_INSTR(OP_EQU, "equ")
#undef SIMPLE_INSTR
default:
printf("unknown opcode %d\n", instr);
exit(2);
}
}
printf("\n");
for (uint8_t cix = 0; cix < ch->consts.len; cix++) {
Val c = ch->consts.d[cix];
if (IS_FUNC(c)) {
printf("const %d is function:\n", cix);
disasm_chunk(&AS_FUNC(c)->chunk);
}
}
}
|