Class: Twostroke::Runtime::Types::RegExp

Inherits:
Object
  • Object
show all
Defined in:
lib/twostroke/runtime/types/regexp.rb

Instance Attribute Summary collapse

Attributes inherited from Object

#_class, #accessors, #data, #extensible, #properties, #prototype

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Object

#can_put, #construct, #constructing?, #default_value, #define_own_property, #delete, #delete!, #each_enumerable_property, #generic_items, #get, #get_own_property, #get_property, #has_accessor, #has_own_property, #has_property, #proto_put, #put, set_global_prototype, #typeof

Methods inherited from Value

#has_instance

Constructor Details

#initialize(regexp_source, options) ⇒ RegExp

Returns a new instance of RegExp.



12
13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/twostroke/runtime/types/regexp.rb', line 12

def initialize(regexp_source, options)
  opts = 0
  (options ||= "").each_char do |opt|
    opts |= case opt
    when "m"; Regexp::MULTILINE
    when "i"; Regexp::IGNORECASE
    else; 0
    end
  end
  @regexp = Regexp.new RegExp.to_ruby_regexp(regexp_source), opts
  @global = options.include? "g"
  @prototype = RegExp.constructor_function.get("prototype")
  super()
end

Instance Attribute Details

#globalObject (readonly)

Returns the value of attribute global.



11
12
13
# File 'lib/twostroke/runtime/types/regexp.rb', line 11

def global
  @global
end

#regexpObject (readonly)

Returns the value of attribute regexp.



10
11
12
# File 'lib/twostroke/runtime/types/regexp.rb', line 10

def regexp
  @regexp
end

Class Method Details

.all_matches(scope, this, args) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/twostroke/runtime/types/regexp.rb', line 57

def self.all_matches(scope, this, args)
  re = this.is_a?(RegExp) ? this : constructor_function.(nil, nil, this)
  str = Twostroke::Runtime::Types.to_string(args[0] || Twostroke::Runtime::Types::Undefined.new).string
  arr = []
  idx = 0
  while md = re.regexp.match(str, idx)
    arr << Twostroke::Runtime::Types::String.new(md[0])
    idx = md.offset(0).last
  end
  if arr.any?
    result = Twostroke::Runtime::Types::Array.new arr
    result.put "index", Twostroke::Runtime::Types::Number.new(re.regexp.match(str).offset(0).first)
    result.put "input", Twostroke::Runtime::Types::String.new(str)
    result
  else
    Twostroke::Runtime::Types::Null.new
  end
end

.constructor_functionObject



3
4
5
6
7
8
# File 'lib/twostroke/runtime/types/regexp.rb', line 3

def self.constructor_function
  @@constructor_function ||=
    Function.new(->(scope, this, args) {
      RegExp.new((args[0] && !args[0].is_a?(Undefined)) ? Twostroke::Runtime::Types.to_string(args[0]).string : "", args[1] && Twostroke::Runtime::Types.to_string(args[1]).string)
    }, nil, "RegExp", [])
end

.exec(scope, this, args) ⇒ Object



42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/twostroke/runtime/types/regexp.rb', line 42

def self.exec(scope, this, args)
  re = this.is_a?(RegExp) ? this : constructor_function.(nil, nil, this)
  str = Twostroke::Runtime::Types.to_string(args[0] || Twostroke::Runtime::Types::Undefined.new).string
  idx = re.global ? Twostroke::Runtime::Types.to_uint32(re.get("lastIndex")) : 0
  if md = re.regexp.match(str, idx)
    result = Twostroke::Runtime::Types::Array.new md.to_a.map { |s| s ? Twostroke::Runtime::Types::String.new(s) : Twostroke::Runtime::Types::Undefined.new }
    result.put "index", Twostroke::Runtime::Types::Number.new(md.offset(0).first)
    result.put "input", Twostroke::Runtime::Types::String.new(str)
    re.put "lastIndex", Twostroke::Runtime::Types::Number.new(md.offset(0).last)
    result
  else
    Twostroke::Runtime::Types::Null.new
  end
end

.to_ruby_regexp(src) ⇒ Object



31
32
33
34
35
36
37
38
39
40
# File 'lib/twostroke/runtime/types/regexp.rb', line 31

def self.to_ruby_regexp(src)
  src.
  
  # javascript's ^$ match the start and end of the entire string
  # ruby's ^$ are line-based, so convert to \A and \z
    gsub(/([^\[]|\A)\^/,"\\1\\A").gsub(/((\]|\A)([^\[]*))\$/,"\\1\\z").
  
  # javascript supports \cA through \cZ for control characters
    gsub(/\\c[a-z]/i) { |m| (m[-1].downcase.ord - 'a'.ord + 1).chr }
end

Instance Method Details

#to_rubyObject



27
28
29
# File 'lib/twostroke/runtime/types/regexp.rb', line 27

def to_ruby
  regexp
end