util.odin 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  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_End: iter.pc += size_of(Opcode)
  32. case .Assert_Word_Boundary: iter.pc += size_of(Opcode)
  33. case .Assert_Non_Word_Boundary: iter.pc += size_of(Opcode)
  34. case .Multiline_Open: iter.pc += size_of(Opcode)
  35. case .Multiline_Close: iter.pc += size_of(Opcode)
  36. case .Wait_For_Byte: iter.pc += size_of(Opcode) + size_of(u8)
  37. case .Wait_For_Rune: iter.pc += size_of(Opcode) + size_of(rune)
  38. case .Wait_For_Rune_Class: iter.pc += size_of(Opcode) + size_of(u8)
  39. case .Wait_For_Rune_Class_Negated: iter.pc += size_of(Opcode) + size_of(u8)
  40. case .Match_All_And_Escape: iter.pc += size_of(Opcode)
  41. case:
  42. panic("Invalid opcode found in RegEx program.")
  43. }
  44. return
  45. }
  46. opcode_to_name :: proc(opcode: Opcode) -> (str: string) {
  47. switch opcode {
  48. case .Match: str = "Match"
  49. case .Match_And_Exit: str = "Match_And_Exit"
  50. case .Byte: str = "Byte"
  51. case .Rune: str = "Rune"
  52. case .Rune_Class: str = "Rune_Class"
  53. case .Rune_Class_Negated: str = "Rune_Class_Negated"
  54. case .Wildcard: str = "Wildcard"
  55. case .Jump: str = "Jump"
  56. case .Split: str = "Split"
  57. case .Save: str = "Save"
  58. case .Assert_Start: str = "Assert_Start"
  59. case .Assert_End: str = "Assert_End"
  60. case .Assert_Word_Boundary: str = "Assert_Word_Boundary"
  61. case .Assert_Non_Word_Boundary: str = "Assert_Non_Word_Boundary"
  62. case .Multiline_Open: str = "Multiline_Open"
  63. case .Multiline_Close: str = "Multiline_Close"
  64. case .Wait_For_Byte: str = "Wait_For_Byte"
  65. case .Wait_For_Rune: str = "Wait_For_Rune"
  66. case .Wait_For_Rune_Class: str = "Wait_For_Rune_Class"
  67. case .Wait_For_Rune_Class_Negated: str = "Wait_For_Rune_Class_Negated"
  68. case .Match_All_And_Escape: str = "Match_All_And_Escape"
  69. case: str = "<UNKNOWN>"
  70. }
  71. return
  72. }