twostroke 0.2.1 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
@@ -33,7 +33,7 @@ module Twostroke::Runtime::Types
|
|
33
33
|
|
34
34
|
# javascript's ^$ match the start and end of the entire string
|
35
35
|
# ruby's ^$ are line-based, so convert to \A and \z
|
36
|
-
gsub(/([^\[]|\A)\^/,"\\1\\A").gsub("
|
36
|
+
gsub(/([^\[]|\A)\^/,"\\1\\A").gsub(/((\]|\A)([^\[]*))\$/,"\\1\\z").
|
37
37
|
|
38
38
|
# javascript supports \cA through \cZ for control characters
|
39
39
|
gsub(/\\c[a-z]/i) { |m| (m.last.downcase.ord - 'a'.ord).chr }
|
@@ -42,10 +42,12 @@ module Twostroke::Runtime::Types
|
|
42
42
|
def self.exec(scope, this, args)
|
43
43
|
re = this.is_a?(RegExp) ? this : constructor_function.(nil, nil, this)
|
44
44
|
str = Twostroke::Runtime::Types.to_string(args[0] || Twostroke::Runtime::Types::Undefined.new).string
|
45
|
-
|
45
|
+
idx = re.global ? Twostroke::Runtime::Types.to_uint32(re.get("lastIndex")) : 0
|
46
|
+
if md = re.regexp.match(str, idx)
|
46
47
|
result = Twostroke::Runtime::Types::Array.new md.to_a.map { |s| s ? Twostroke::Runtime::Types::String.new(s) : Twostroke::Runtime::Types::Undefined.new }
|
47
48
|
result.put "index", Twostroke::Runtime::Types::Number.new(md.offset(0).first)
|
48
49
|
result.put "input", Twostroke::Runtime::Types::String.new(str)
|
50
|
+
re.put "lastIndex", Twostroke::Runtime::Types::Number.new(md.offset(0).last)
|
49
51
|
result
|
50
52
|
else
|
51
53
|
Twostroke::Runtime::Types::Null.new
|
data/lib/twostroke/runtime/vm.rb
CHANGED
@@ -7,6 +7,7 @@ module Twostroke::Runtime
|
|
7
7
|
@bytecode = bytecode
|
8
8
|
@global_scope = GlobalScope.new self
|
9
9
|
@lib = {}
|
10
|
+
@name_args = {}
|
10
11
|
end
|
11
12
|
|
12
13
|
def execute(section = :main, scope = nil, this = nil)
|
@@ -16,6 +17,18 @@ module Twostroke::Runtime
|
|
16
17
|
def throw_error(type, message)
|
17
18
|
throw :exception, lib[type].(nil, global_scope.root_object, [Types::String.new(message)])
|
18
19
|
end
|
20
|
+
|
21
|
+
def section_name_args(section)
|
22
|
+
unless @name_args[section]
|
23
|
+
ops = bytecode[section].take_while { |ins,arg| [:".name", :".arg"].include? ins }
|
24
|
+
@name_args[section] = [
|
25
|
+
ops.select { |ins,arg| :".name" == ins }.map { |ins,arg| arg }.first,
|
26
|
+
ops.select { |ins,arg| :".arg" == ins }.map { |ins,arg| arg.to_s }
|
27
|
+
]
|
28
|
+
else
|
29
|
+
@name_args[section]
|
30
|
+
end
|
31
|
+
end
|
19
32
|
|
20
33
|
private
|
21
34
|
def error!(msg)
|
@@ -37,10 +37,9 @@ module Twostroke::Runtime
|
|
37
37
|
|
38
38
|
until @return
|
39
39
|
ins, arg = insns[ip]
|
40
|
-
st = @stack.size
|
41
40
|
@ip += 1
|
42
41
|
if respond_to? ins
|
43
|
-
if @exception = catch(:exception) {
|
42
|
+
if @exception = catch(:exception) { send ins, arg; nil }
|
44
43
|
# puts "--> #{Types.to_string(exception).string} #{@name || "(anonymous function)"}:#{@line} <#{@section}+#{@ip}>"
|
45
44
|
throw :exception, @exception if catch_stack.empty? && finally_stack.empty?
|
46
45
|
if catch_stack.any?
|
@@ -411,8 +410,7 @@ module Twostroke::Runtime
|
|
411
410
|
end
|
412
411
|
|
413
412
|
def close(arg)
|
414
|
-
name = vm.
|
415
|
-
arguments = vm.bytecode[arg].select { |ins,arg| ins == :".arg" }.map(&:last).map(&:to_s)
|
413
|
+
name, arguments = vm.section_name_args arg
|
416
414
|
scope = @scope
|
417
415
|
fun = Types::Function.new(->(outer_scope, this, args) { VM::Frame.new(vm, arg, fun).execute(scope.close, this, args) }, "...", name || "", arguments)
|
418
416
|
stack.push fun
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: twostroke
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-01-
|
12
|
+
date: 2012-01-11 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: An implementation of Javascript written in pure Ruby. Twostroke contains
|
15
15
|
a parser, a bytecode compiler, a VM, and a minimal implementation of the Javascript
|
@@ -125,3 +125,4 @@ signing_key:
|
|
125
125
|
specification_version: 3
|
126
126
|
summary: A Ruby implementation of Javascript
|
127
127
|
test_files: []
|
128
|
+
has_rdoc:
|