class RegularExpression::Interpreter
An interpreter for our compiled bytecode. Maybe we could make this possible to enter at a given state and deoptimise to it from the compiled code?
Attributes
bytecode[R]
Public Class Methods
new(bytecode)
click to toggle source
# File lib/regular_expression/interpreter.rb, line 9 def initialize(bytecode) @bytecode = bytecode end
Public Instance Methods
match?(string)
click to toggle source
# File lib/regular_expression/interpreter.rb, line 19 def match?(string) stack = [] (0..string.size).any? do |start_n| string_n = start_n insn_n = 0 loop do insn = bytecode.insns[insn_n] case insn when Bytecode::Insns::PushIndex stack << string_n insn_n += 1 when Bytecode::Insns::PopIndex string_n = stack.pop insn_n += 1 when Bytecode::Insns::GuardBegin return false if start_n != 0 insn_n = bytecode.labels[insn.guarded] when Bytecode::Insns::GuardEnd break if string_n != string.size insn_n = bytecode.labels[insn.guarded] when Bytecode::Insns::JumpAny if string_n < string.size string_n += 1 insn_n = bytecode.labels[insn.target] else insn_n += 1 end when Bytecode::Insns::JumpValue if string_n < string.size && string[string_n] == insn.char string_n += 1 insn_n = bytecode.labels[insn.target] else insn_n += 1 end when Bytecode::Insns::JumpValuesInvert if string_n < string.size && !insn.chars.include?(string[string_n]) string_n += 1 insn_n = bytecode.labels[insn.target] else insn_n += 1 end when Bytecode::Insns::JumpRange if string_n < string.size && string[string_n] >= insn.left && string[string_n] <= insn.right string_n += 1 insn_n = bytecode.labels[insn.target] else insn_n += 1 end when Bytecode::Insns::JumpRangeInvert if string_n < string.size && (string[string_n] < insn.left || string[string_n] > insn.right) string_n += 1 insn_n = bytecode.labels[insn.target] else insn_n += 1 end when Bytecode::Insns::Jump insn_n = bytecode.labels[insn.target] when Bytecode::Insns::Match return true when Bytecode::Insns::Fail break else raise end end end end
to_proc()
click to toggle source
This is just here for API parity with the compiled outputs.
# File lib/regular_expression/interpreter.rb, line 14 def to_proc interpreter = self ->(string) { interpreter.match?(string) } end