summaryrefslogtreecommitdiff
path: root/dis.c
diff options
context:
space:
mode:
Diffstat (limited to 'dis.c')
-rw-r--r--dis.c48
1 files changed, 34 insertions, 14 deletions
diff --git a/dis.c b/dis.c
index c4492df..9033bff 100644
--- a/dis.c
+++ b/dis.c
@@ -3,41 +3,61 @@
#include <stdio.h>
#include <stdint.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) {
for (size_t ip = 0; ip < ch->bc.len; ) {
uint8_t instr = ch->bc.d[ip];
printf("%04zd\t",ip);
ip ++;
-#define SIMPLE_INSTR(opcode, str) \
- case opcode: puts(str); break;
switch (instr) {
- SIMPLE_INSTR(OP_RET, "ret")
case OP_LOADK: {
uint8_t ix = ch->bc.d[ip++];
printf("loadk #%d\t; ",ix);
- Val k = ch->consts.d[ix];
- printf("%-4s : ",typename_str(k));
- println_val(k);
+ print_const(ch, ix);
break;
}
case OP_GETGLOBAL: {
uint8_t ix = ch->bc.d[ip++];
printf("getglobal #%d\t; ",ix);
- Val k = ch->consts.d[ix];
- printf("%-4s : ",typename_str(k));
- println_val(k);
+ print_const(ch, ix);
break;
}
case OP_SETGLOBAL: {
uint8_t ix = ch->bc.d[ip++];
printf("setglobal #%d\t; ",ix);
- Val k = ch->consts.d[ix];
- printf("%-4s : ",typename_str(k));
- println_val(k);
+ 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("0branch -%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_PRINT, "print")
SIMPLE_INSTR(OP_DROP, "drop")
SIMPLE_INSTR(OP_ADD, "add")
@@ -47,10 +67,10 @@ void disasm_chunk(Chunk *ch) {
SIMPLE_INSTR(OP_NIL, "nil")
SIMPLE_INSTR(OP_TRUE, "true")
SIMPLE_INSTR(OP_FALSE, "false")
+#undef SIMPLE_INSTR
}
}
-#undef SIMPLE_INSTR
}