debugging.odin 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. package regex_compiler
  2. /*
  3. (c) Copyright 2024 Feoramund <[email protected]>.
  4. Made available under Odin's BSD-3 license.
  5. List of contributors:
  6. Feoramund: Initial implementation.
  7. */
  8. import "base:intrinsics"
  9. import "core:io"
  10. import "core:text/regex/common"
  11. import "core:text/regex/virtual_machine"
  12. get_jump_targets :: proc(code: []Opcode) -> (jump_targets: map[int]int) {
  13. iter := virtual_machine.Opcode_Iterator{ code, 0 }
  14. for opcode, pc in virtual_machine.iterate_opcodes(&iter) {
  15. #partial switch opcode {
  16. case .Jump:
  17. jmp := cast(int)intrinsics.unaligned_load(cast(^u16)&code[pc+1])
  18. jump_targets[jmp] = pc
  19. case .Split:
  20. jmp_x := cast(int)intrinsics.unaligned_load(cast(^u16)&code[pc+1])
  21. jmp_y := cast(int)intrinsics.unaligned_load(cast(^u16)&code[pc+3])
  22. jump_targets[jmp_x] = pc
  23. jump_targets[jmp_y] = pc
  24. }
  25. }
  26. return
  27. }
  28. trace :: proc(w: io.Writer, code: []Opcode) {
  29. jump_targets := get_jump_targets(code)
  30. defer delete(jump_targets)
  31. iter := virtual_machine.Opcode_Iterator{ code, 0 }
  32. for opcode, pc in virtual_machine.iterate_opcodes(&iter) {
  33. if src, ok := jump_targets[pc]; ok {
  34. io.write_string(w, "--")
  35. common.write_padded_hex(w, src, 4)
  36. io.write_string(w, "--> ")
  37. } else {
  38. io.write_string(w, " ")
  39. }
  40. io.write_string(w, "[PC: ")
  41. common.write_padded_hex(w, pc, 4)
  42. io.write_string(w, "] ")
  43. io.write_string(w, virtual_machine.opcode_to_name(opcode))
  44. io.write_byte(w, ' ')
  45. #partial switch opcode {
  46. case .Byte:
  47. operand := cast(rune)code[pc+1]
  48. io.write_encoded_rune(w, operand)
  49. case .Rune:
  50. operand := intrinsics.unaligned_load(cast(^rune)&code[pc+1])
  51. io.write_encoded_rune(w, operand)
  52. case .Rune_Class, .Rune_Class_Negated:
  53. operand := cast(u8)code[pc+1]
  54. common.write_padded_hex(w, operand, 2)
  55. case .Jump:
  56. jmp := intrinsics.unaligned_load(cast(^u16)&code[pc+1])
  57. io.write_string(w, "-> $")
  58. common.write_padded_hex(w, jmp, 4)
  59. case .Split:
  60. jmp_x := intrinsics.unaligned_load(cast(^u16)&code[pc+1])
  61. jmp_y := intrinsics.unaligned_load(cast(^u16)&code[pc+3])
  62. io.write_string(w, "=> $")
  63. common.write_padded_hex(w, jmp_x, 4)
  64. io.write_string(w, ", $")
  65. common.write_padded_hex(w, jmp_y, 4)
  66. case .Save:
  67. operand := cast(u8)code[pc+1]
  68. common.write_padded_hex(w, operand, 2)
  69. case .Wait_For_Byte:
  70. operand := cast(rune)code[pc+1]
  71. io.write_encoded_rune(w, operand)
  72. case .Wait_For_Rune:
  73. operand := (cast(^rune)&code[pc+1])^
  74. io.write_encoded_rune(w, operand)
  75. case .Wait_For_Rune_Class:
  76. operand := cast(u8)code[pc+1]
  77. common.write_padded_hex(w, operand, 2)
  78. case .Wait_For_Rune_Class_Negated:
  79. operand := cast(u8)code[pc+1]
  80. common.write_padded_hex(w, operand, 2)
  81. }
  82. io.write_byte(w, '\n')
  83. }
  84. }