-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathdebug.odin
More file actions
122 lines (102 loc) · 3.72 KB
/
debug.odin
File metadata and controls
122 lines (102 loc) · 3.72 KB
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
package main
import "core:fmt"
chunk_disassemble :: proc(chunk: ^Chunk, name: string) {
fmt.printf("== %s ==\n", name)
for offset := 0; offset < len(chunk.code); {
offset = chunk_disassemble_instruction(chunk, offset)
}
}
chunk_disassemble_instruction :: proc(chunk: ^Chunk, offset: int) -> int {
fmt.printf("%04d ", offset)
if offset > 0 && chunk.lines[offset] == chunk.lines[offset-1] {
fmt.printf(" | ")
} else {
fmt.printf("%4d ", chunk.lines[offset])
}
// TODO(daniel): print the opcode directly
switch opcode := OpCode(chunk.code[offset]); opcode {
case .Constant:
return constant_instruction("OP_CONSTANT", chunk, offset)
case .False:
return simple_instruction("OP_FALSE", offset)
case .Equal:
return simple_instruction("OP_EQUAL", offset)
case .Greater:
return simple_instruction("OP_GREATER", offset)
case .Less:
return simple_instruction("OP_LESS", offset)
case .True:
return simple_instruction("OP_TRUE", offset)
case .Nil:
return simple_instruction("OP_NIL", offset)
case .Pop:
return simple_instruction("OP_POP", offset)
case .DefineGlobal:
return constant_instruction("OP_DEFINE_GLOBAL", chunk, offset)
case .GetLocal:
return byte_instruction("OP_GET_LOCAL", chunk, offset)
case .SetLocal:
return byte_instruction("OP_SET_LOCAL", chunk, offset)
case .GetGlobal:
return constant_instruction("OP_GET_GLOBAL", chunk, offset)
case .SetGlobal:
return constant_instruction("OP_SET_GLOBAL", chunk, offset)
case .Add:
return simple_instruction("OP_ADD", offset)
case .Subtract:
return simple_instruction("OP_SUBTRACT", offset)
case .Multiply:
return simple_instruction("OP_MULTIPLY", offset)
case .Divide:
return simple_instruction("OP_DIVIDE", offset)
case .Not:
return simple_instruction("OP_NOT", offset)
case .Negate:
return simple_instruction("OP_NEGATE", offset)
case .Print:
return simple_instruction("OP_PRINT", offset)
case .Return:
return simple_instruction("OP_RETURN", offset)
case .Jump:
return jump_instruction("OP_JUMP", 1, chunk, offset)
case .JumpIfFalse:
return jump_instruction("OP_JUMP_IF_FALSE", 1, chunk, offset)
case .Loop:
return jump_instruction("OP_LOOP", -1, chunk, offset)
case .Call:
return byte_instruction("OP_CALL", chunk, offset)
case .Closure:
return closure_instruction("OP_CLOSURE", chunk, offset)
case:
fmt.printf("Unknown opcode %d\n", opcode)
return offset + 1
}
}
closure_instruction :: proc(name: string, chunk: ^Chunk, offset: int) -> int {
constant := chunk.code[offset+1]
fmt.printf("%-16s %4d ", "OP_CLOSURE", constant)
value_print(chunk.constants.values[constant])
fmt.printf("\n")
return offset + 2
}
simple_instruction :: proc(name: string, offset: int) -> int {
fmt.printf("%s\n", name)
return offset + 1
}
constant_instruction :: proc(name: string, chunk: ^Chunk, offset: int) -> int {
constant := chunk.code[offset+1]
fmt.printf("%-16s %4d '", name, constant)
value_print(chunk.constants.values[constant])
fmt.printf("'\n")
return offset + 2
}
byte_instruction :: proc(name: string, chunk: ^Chunk, offset: int) -> int {
slot := chunk.code[offset+1]
fmt.printf("%-16s %4d\n", name, slot);
return offset + 2
}
jump_instruction :: proc(name: string, sign: int, chunk: ^Chunk, offset: int) -> int {
jump := int((u16(chunk.code[offset+1]) << 8) | u16(chunk.code[offset+2]))
fmt.printf("%-16s %4d -> %d\n", name, offset, offset + 3 + sign * jump)
return offset + 3
}