aboutsummaryrefslogtreecommitdiff
path: root/core/text/regex/compiler/debugging.odin
diff options
context:
space:
mode:
authorFeoramund <161657516+Feoramund@users.noreply.github.com>2024-07-21 21:58:25 -0400
committerFeoramund <161657516+Feoramund@users.noreply.github.com>2024-07-22 14:25:12 -0400
commitcb0704d51c6a170bca8206a9bb3e9796c71c6341 (patch)
tree2e275eb1a22d74ddd5d5052a4f89aa45ef9245b0 /core/text/regex/compiler/debugging.odin
parentccf8b2764d4a3add4a575b2c88b710b2d15ebae8 (diff)
Add `core:text/regex`
Diffstat (limited to 'core/text/regex/compiler/debugging.odin')
-rw-r--r--core/text/regex/compiler/debugging.odin84
1 files changed, 84 insertions, 0 deletions
diff --git a/core/text/regex/compiler/debugging.odin b/core/text/regex/compiler/debugging.odin
new file mode 100644
index 000000000..1ef3e6d78
--- /dev/null
+++ b/core/text/regex/compiler/debugging.odin
@@ -0,0 +1,84 @@
+package regex_compiler
+
+import "core:io"
+import "core:text/regex/common"
+import "core:text/regex/virtual_machine"
+
+get_jump_targets :: proc(code: []Opcode) -> (jump_targets: map[int]int) {
+ iter := virtual_machine.Opcode_Iterator{ code, 0 }
+ for opcode, pc in virtual_machine.iterate_opcodes(&iter) {
+ #partial switch opcode {
+ case .Jump:
+ jmp := cast(int)(cast(^u16)&code[pc+1])^
+ jump_targets[jmp] = pc
+ case .Split:
+ jmp_x := cast(int)(cast(^u16)&code[pc+1])^
+ jmp_y := cast(int)(cast(^u16)&code[pc+3])^
+ jump_targets[jmp_x] = pc
+ jump_targets[jmp_y] = pc
+ }
+ }
+ return
+}
+
+trace :: proc(w: io.Writer, code: []Opcode) {
+ jump_targets := get_jump_targets(code)
+ defer delete(jump_targets)
+
+ iter := virtual_machine.Opcode_Iterator{ code, 0 }
+ for opcode, pc in virtual_machine.iterate_opcodes(&iter) {
+ if src, ok := jump_targets[pc]; ok {
+ io.write_string(w, "--")
+ common.write_padded_hex(w, src, 4)
+ io.write_string(w, "--> ")
+ } else {
+ io.write_string(w, " ")
+ }
+
+ io.write_string(w, "[PC: ")
+ common.write_padded_hex(w, pc, 4)
+ io.write_string(w, "] ")
+ io.write_string(w, virtual_machine.opcode_to_name(opcode))
+ io.write_byte(w, ' ')
+
+ #partial switch opcode {
+ case .Byte:
+ operand := cast(rune)code[pc+1]
+ io.write_encoded_rune(w, operand)
+ case .Rune:
+ operand := (cast(^rune)&code[pc+1])^
+ io.write_encoded_rune(w, operand)
+ case .Rune_Class, .Rune_Class_Negated:
+ operand := cast(u8)code[pc+1]
+ common.write_padded_hex(w, operand, 2)
+ case .Jump:
+ jmp := (cast(^u16)&code[pc+1])^
+ io.write_string(w, "-> $")
+ common.write_padded_hex(w, jmp, 4)
+ case .Split:
+ jmp_x := (cast(^u16)&code[pc+1])^
+ jmp_y := (cast(^u16)&code[pc+3])^
+ io.write_string(w, "=> $")
+ common.write_padded_hex(w, jmp_x, 4)
+ io.write_string(w, ", $")
+ common.write_padded_hex(w, jmp_y, 4)
+ case .Save:
+ operand := cast(u8)code[pc+1]
+ common.write_padded_hex(w, operand, 2)
+ case .Wait_For_Byte:
+ operand := cast(rune)code[pc+1]
+ io.write_encoded_rune(w, operand)
+ case .Wait_For_Rune:
+ operand := (cast(^rune)&code[pc+1])^
+ io.write_encoded_rune(w, operand)
+ case .Wait_For_Rune_Class:
+ operand := cast(u8)code[pc+1]
+ common.write_padded_hex(w, operand, 2)
+ case .Wait_For_Rune_Class_Negated:
+ operand := cast(u8)code[pc+1]
+ common.write_padded_hex(w, operand, 2)
+ }
+
+ io.write_byte(w, '\n')
+ }
+}