2
0

util.odin 3.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. package regex_vm
  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. Opcode_Iterator :: struct {
  9. code: Program,
  10. pc: int,
  11. }
  12. iterate_opcodes :: proc(iter: ^Opcode_Iterator) -> (opcode: Opcode, pc: int, ok: bool) {
  13. if iter.pc >= len(iter.code) {
  14. return
  15. }
  16. opcode = iter.code[iter.pc]
  17. pc = iter.pc
  18. ok = true
  19. switch opcode {
  20. case .Match: iter.pc += size_of(Opcode)
  21. case .Match_And_Exit: iter.pc += size_of(Opcode)
  22. case .Byte: iter.pc += size_of(Opcode) + size_of(u8)
  23. case .Rune: iter.pc += size_of(Opcode) + size_of(rune)
  24. case .Rune_Class: iter.pc += size_of(Opcode) + size_of(u8)
  25. case .Rune_Class_Negated: iter.pc += size_of(Opcode) + size_of(u8)
  26. case .Wildcard: iter.pc += size_of(Opcode)
  27. case .Jump: iter.pc += size_of(Opcode) + size_of(u16)
  28. case .Split: iter.pc += size_of(Opcode) + 2 * size_of(u16)
  29. case .Save: iter.pc += size_of(Opcode) + size_of(u8)
  30. case .Assert_Start: iter.pc += size_of(Opcode)
  31. case .Assert_Start_Multiline: iter.pc += size_of(Opcode)
  32. case .Assert_End: iter.pc += size_of(Opcode)
  33. case .Assert_Word_Boundary: iter.pc += size_of(Opcode)
  34. case .Assert_Non_Word_Boundary: iter.pc += size_of(Opcode)
  35. case .Multiline_Open: iter.pc += size_of(Opcode)
  36. case .Multiline_Close: iter.pc += size_of(Opcode)
  37. case .Wait_For_Byte: iter.pc += size_of(Opcode) + size_of(u8)
  38. case .Wait_For_Rune: iter.pc += size_of(Opcode) + size_of(rune)
  39. case .Wait_For_Rune_Class: iter.pc += size_of(Opcode) + size_of(u8)
  40. case .Wait_For_Rune_Class_Negated: iter.pc += size_of(Opcode) + size_of(u8)
  41. case .Match_All_And_Escape: iter.pc += size_of(Opcode)
  42. case:
  43. panic("Invalid opcode found in RegEx program.")
  44. }
  45. return
  46. }
  47. opcode_to_name :: proc(opcode: Opcode) -> (str: string) {
  48. switch opcode {
  49. case .Match: str = "Match"
  50. case .Match_And_Exit: str = "Match_And_Exit"
  51. case .Byte: str = "Byte"
  52. case .Rune: str = "Rune"
  53. case .Rune_Class: str = "Rune_Class"
  54. case .Rune_Class_Negated: str = "Rune_Class_Negated"
  55. case .Wildcard: str = "Wildcard"
  56. case .Jump: str = "Jump"
  57. case .Split: str = "Split"
  58. case .Save: str = "Save"
  59. case .Assert_Start: str = "Assert_Start"
  60. case .Assert_Start_Multiline: str = "Assert_Start_Multiline"
  61. case .Assert_End: str = "Assert_End"
  62. case .Assert_Word_Boundary: str = "Assert_Word_Boundary"
  63. case .Assert_Non_Word_Boundary: str = "Assert_Non_Word_Boundary"
  64. case .Multiline_Open: str = "Multiline_Open"
  65. case .Multiline_Close: str = "Multiline_Close"
  66. case .Wait_For_Byte: str = "Wait_For_Byte"
  67. case .Wait_For_Rune: str = "Wait_For_Rune"
  68. case .Wait_For_Rune_Class: str = "Wait_For_Rune_Class"
  69. case .Wait_For_Rune_Class_Negated: str = "Wait_For_Rune_Class_Negated"
  70. case .Match_All_And_Escape: str = "Match_All_And_Escape"
  71. case: str = "<UNKNOWN>"
  72. }
  73. return
  74. }