core/text/regex/virtual_machine
regex_vm
Types
13Jump
Jump :: struct #packed {
opcode: Opcode,
target: i16,
}SourceMachine
Machine :: struct {
// Program state
memory: string,
class_data: []Rune_Class_Data,
code: Program,
// Thread state
top_thread: int,
threads: [^]Thread,
next_threads: [^]Thread,
// The busy map is used to merge threads based on their program counters.
busy_map: []u64,
// Global state
string_pointer: int,
current_rune: rune,
current_rune_size: int,
next_rune: rune,
next_rune_size: int,
last_rune: rune,
}SourceOpcode
Opcode :: enum u8 {
// | [ operands ]
Match = 0, // |
Match_And_Exit = 1, // |
Byte = 2, // | u8
Rune = 3, // | i32
Rune_Class = 4, // | u8
Rune_Class_Negated = 5, // | u8
Wildcard = 6, // |
Jump = 7, // | u16
Split = 8, // | u16, u16
Save = 9, // | u8
Assert_Start = 10, // |
Assert_Start_Multiline = 11, // |
Assert_End = 12, // |
Assert_Word_Boundary = 13, // |
Assert_Non_Word_Boundary = 14, // |
Multiline_Open = 15, // |
Multiline_Close = 16, // |
Wait_For_Byte = 17, // | u8
Wait_For_Rune = 18, // | i32
Wait_For_Rune_Class = 19, // | u8
Wait_For_Rune_Class_Negated = 20, // | u8
Match_All_And_Escape = 21, // |
}SourceOpcode_Iterator
Opcode_Iterator :: struct {
code: Program,
pc: int,
}Source(c) Copyright 2024 Feoramund <rune@swevencraft.org>.
Made available under Odin's license.
List of contributors:
Feoramund: Initial implementation.Program
Program :: []OpcodeSourceRune_Class_Data
Rune_Class_Data :: struct {
runes: []rune,
ranges: []Rune_Class_Range,
}SourceNOTE: This structure differs intentionally from the one in regex/parser, as this data doesn't need to be a dynamic array once it hits the VM.
Save
Save :: struct #packed {
opcode: Opcode,
operand: Opcode,
}SourceSplit
Split :: struct #packed {
opcode: Opcode,
left: i16,
right: i16,
}SourceThread
Thread :: struct {
pc: int,
saved: ^[2 * common.MAX_CAPTURE_GROUPS]int,
}SourceWait_For_Byte
Wait_For_Byte :: struct #packed {
opcode: Opcode,
operand: Opcode,
}SourceWait_For_Rune
Wait_For_Rune :: struct #packed {
opcode: Opcode,
operand: rune,
}SourceWait_For_Rune_Class
Wait_For_Rune_Class :: struct #packed {
opcode: Opcode,
operand: Opcode,
}SourceWait_For_Rune_Class_Negated
Wait_For_Rune_Class_Negated :: struct #packed {
opcode: Opcode,
operand: Opcode,
}SourceConstants
1Procedures
10add_thread
add_thread :: proc(vm: ^Machine, saved: ^[2 * common.MAX_CAPTURE_GROUPS]int, pc: int)Sourcecheck_busy_map
check_busy_map :: proc(vm: ^Machine, pc: int) -> (bool)Sourcecreate
create :: proc(code: Program, str: string, allocator: mem.Allocator = context.allocator) -> (vm: Machine)Sourcedestroy
destroy :: proc(vm: Machine, allocator: mem.Allocator = context.allocator)Sourceis_word_class
is_word_class :: proc(r: rune) -> (bool)Source@MetaCharacter NOTE: This must be kept in sync with the compiler & tokenizer.
iterate_opcodes
iterate_opcodes :: proc(iter: ^Opcode_Iterator) -> (opcode: Opcode, pc: int, ok: bool)Sourceopcode_count
opcode_count :: proc(code: Program) -> (opcodes: int)Sourceopcode_to_name
opcode_to_name :: proc(opcode: Opcode) -> (str: string)Sourcerun
run :: proc(vm: ^Machine, UNICODE_MODE: bool) -> (saved: ^[2 * common.MAX_CAPTURE_GROUPS]int, ok: bool)Sourceset_busy_map
set_busy_map :: proc(vm: ^Machine, pc: int) -> (bool)Source