opal 0.3.16 → 0.3.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +2 -0
- data/CHANGELOG.md +12 -0
- data/Gemfile +8 -7
- data/README.md +21 -13
- data/Rakefile +64 -78
- data/bin/opal +18 -29
- data/core/alpha.rb +2 -9
- data/core/array.rb +106 -50
- data/core/basic_object.rb +10 -8
- data/core/boolean.rb +2 -0
- data/core/class.rb +25 -13
- data/core/comparable.rb +6 -6
- data/core/enumerable.rb +90 -94
- data/core/enumerator.rb +3 -3
- data/core/hash.rb +86 -46
- data/core/kernel.rb +55 -39
- data/core/load_order +2 -5
- data/core/match_data.rb +1 -1
- data/core/module.rb +45 -20
- data/core/nil_class.rb +6 -2
- data/core/numeric.rb +20 -10
- data/core/proc.rb +2 -2
- data/core/range.rb +72 -13
- data/core/regexp.rb +5 -3
- data/core/runtime.js +228 -287
- data/core/string.rb +345 -37
- data/core/top_self.rb +1 -1
- data/lib/opal.rb +13 -91
- data/lib/opal/builder.rb +47 -120
- data/lib/opal/builder_task.rb +74 -0
- data/lib/opal/{parser/grammar.rb → grammar.rb} +1094 -1083
- data/lib/opal/{parser/grammar.y → grammar.y} +7 -0
- data/lib/opal/{parser/lexer.rb → lexer.rb} +32 -11
- data/lib/opal/{parser/parser.rb → parser.rb} +232 -238
- data/lib/opal/{parser/scope.rb → scope.rb} +72 -9
- data/lib/opal/version.rb +2 -3
- data/opal.gemspec +1 -2
- data/{core_spec → spec}/core/array/allocate_spec.rb +1 -3
- data/{core_spec → spec}/core/array/append_spec.rb +1 -4
- data/{core_spec → spec}/core/array/assoc_spec.rb +1 -4
- data/{core_spec → spec}/core/array/at_spec.rb +1 -3
- data/{core_spec → spec}/core/array/clear_spec.rb +1 -3
- data/spec/core/array/clone_spec.rb +15 -0
- data/{core_spec/core/array/shared/collect.rb → spec/core/array/collect_spec.rb} +1 -1
- data/{core_spec → spec}/core/array/compact_spec.rb +1 -3
- data/{core_spec → spec}/core/array/concat_spec.rb +1 -3
- data/{core_spec → spec}/core/array/constructor_spec.rb +9 -3
- data/{core_spec → spec}/core/array/count_spec.rb +1 -3
- data/{core_spec → spec}/core/array/delete_at_spec.rb +1 -4
- data/{core_spec → spec}/core/array/delete_if_spec.rb +1 -4
- data/{core_spec → spec}/core/array/delete_spec.rb +1 -4
- data/{core_spec → spec}/core/array/each_index_spec.rb +1 -4
- data/{core_spec → spec}/core/array/each_spec.rb +1 -4
- data/{core_spec → spec}/core/array/element_reference_spec.rb +74 -4
- data/{core_spec → spec}/core/array/empty_spec.rb +1 -4
- data/{core_spec/core/array/shared/eql.rb → spec/core/array/eql_spec.rb} +1 -1
- data/{core_spec → spec}/core/array/fetch_spec.rb +1 -4
- data/{core_spec → spec}/core/array/first_spec.rb +1 -3
- data/{core_spec → spec}/core/array/flatten_spec.rb +1 -3
- data/{core_spec → spec}/core/array/include_spec.rb +1 -3
- data/{core_spec → spec}/core/array/insert_spec.rb +1 -4
- data/{core_spec → spec}/core/array/last_spec.rb +1 -4
- data/{core_spec/core/array/shared/length.rb → spec/core/array/length_spec.rb} +1 -1
- data/spec/core/array/map_spec.rb +53 -0
- data/{core_spec → spec}/core/array/plus_spec.rb +1 -4
- data/{core_spec → spec}/core/array/pop_spec.rb +1 -4
- data/{core_spec → spec}/core/array/push_spec.rb +1 -4
- data/{core_spec → spec}/core/array/rassoc_spec.rb +1 -4
- data/{core_spec → spec}/core/array/reject_spec.rb +1 -4
- data/{core_spec/core/array/shared/replace.rb → spec/core/array/replace_spec.rb} +1 -1
- data/{core_spec → spec}/core/array/reverse_each_spec.rb +1 -4
- data/{core_spec → spec}/core/array/reverse_spec.rb +1 -4
- data/spec/core/array/size_spec.rb +6 -0
- data/spec/core/array/to_ary_spec.rb +6 -0
- data/spec/core/array/uniq_spec.rb +22 -0
- data/spec/core/array/zip_spec.rb +20 -0
- data/{core_spec → spec}/core/class/new_spec.rb +1 -4
- data/{core_spec → spec}/core/enumerable/all_spec.rb +1 -4
- data/{core_spec → spec}/core/enumerable/any_spec.rb +1 -4
- data/{core_spec/core/enumerable/shared/collect.rb → spec/core/enumerable/collect_spec.rb} +1 -1
- data/{core_spec → spec}/core/enumerable/count_spec.rb +2 -5
- data/{core_spec → spec}/core/enumerable/fixtures/classes.rb +1 -2
- data/{core_spec → spec}/core/false/and_spec.rb +1 -3
- data/{core_spec → spec}/core/false/inspect_spec.rb +1 -3
- data/{core_spec → spec}/core/false/or_spec.rb +1 -3
- data/{core_spec → spec}/core/false/to_s_spec.rb +1 -3
- data/{core_spec → spec}/core/false/xor_spec.rb +1 -3
- data/{core_spec → spec}/core/hash/allocate_spec.rb +1 -3
- data/spec/core/hash/assoc_spec.rb +25 -0
- data/{core_spec → spec}/core/hash/clear_spec.rb +1 -3
- data/{core_spec → spec}/core/hash/clone_spec.rb +1 -3
- data/{core_spec → spec}/core/hash/default_spec.rb +1 -3
- data/{core_spec → spec}/core/hash/delete_if_spec.rb +1 -3
- data/{core_spec → spec}/core/hash/element_reference_spec.rb +1 -3
- data/{core_spec → spec}/core/hash/element_set_spec.rb +1 -3
- data/spec/core/hash/merge_spec.rb +37 -0
- data/{core_spec → spec}/core/hash/new_spec.rb +1 -3
- data/{core_spec → spec}/core/matchdata/to_a_spec.rb +1 -3
- data/{core_spec → spec}/core/nil/and_spec.rb +1 -4
- data/{core_spec → spec}/core/nil/inspect_spec.rb +1 -4
- data/{core_spec → spec}/core/nil/nil_spec.rb +1 -4
- data/{core_spec → spec}/core/nil/or_spec.rb +1 -4
- data/{core_spec → spec}/core/nil/to_a_spec.rb +1 -4
- data/{core_spec → spec}/core/nil/to_f_spec.rb +1 -4
- data/{core_spec → spec}/core/nil/to_i_spec.rb +1 -4
- data/{core_spec → spec}/core/nil/to_s_spec.rb +1 -4
- data/{core_spec → spec}/core/nil/xor_spec.rb +1 -4
- data/{core_spec → spec}/core/numeric/equal_value_spec.rb +1 -3
- data/{core_spec → spec}/core/regexp/match_spec.rb +10 -3
- data/{core_spec → spec}/core/symbol/to_proc_spec.rb +1 -3
- data/{core_spec → spec}/core/true/and_spec.rb +1 -3
- data/{core_spec → spec}/core/true/inspect_spec.rb +1 -3
- data/{core_spec → spec}/core/true/or_spec.rb +1 -3
- data/{core_spec → spec}/core/true/to_s_spec.rb +1 -3
- data/{core_spec → spec}/core/true/xor_spec.rb +1 -3
- data/spec/index.html +11 -0
- data/{core_spec → spec}/language/alias_spec.rb +1 -3
- data/{core_spec → spec}/language/and_spec.rb +1 -4
- data/{core_spec → spec}/language/array_spec.rb +1 -4
- data/{core_spec → spec}/language/block_spec.rb +20 -3
- data/{core_spec → spec}/language/break_spec.rb +40 -3
- data/{core_spec → spec}/language/case_spec.rb +1 -4
- data/{core_spec → spec}/language/defined_spec.rb +9 -3
- data/{core_spec → spec}/language/ensure_spec.rb +38 -3
- data/{core_spec → spec}/language/hash_spec.rb +1 -3
- data/{core_spec → spec}/language/if_spec.rb +1 -4
- data/{core_spec → spec}/language/loop_spec.rb +1 -3
- data/spec/language/metaclass_spec.rb +13 -0
- data/{core_spec → spec}/language/next_spec.rb +47 -3
- data/{core_spec → spec}/language/or_spec.rb +1 -4
- data/{core_spec → spec}/language/predefined_spec.rb +1 -3
- data/{core_spec/language/regexp/interpolation_spec.rb → spec/language/regexp_spec.rb} +6 -3
- data/{core_spec → spec}/language/send_spec.rb +38 -4
- data/spec/language/singleton_class_spec.rb +31 -0
- data/spec/language/super_spec.rb +188 -0
- data/{core_spec → spec}/language/symbol_spec.rb +1 -3
- data/{core_spec → spec}/language/undef_spec.rb +1 -3
- data/{core_spec → spec}/language/unless_spec.rb +1 -4
- data/{core_spec → spec}/language/until_spec.rb +1 -3
- data/{core_spec → spec}/language/variables_spec.rb +1 -3
- data/{core_spec → spec}/language/while_spec.rb +1 -3
- data/{spec → test}/builder/build_source_spec.rb +0 -0
- data/{spec → test}/builder/fixtures/build_source/adam.rb +0 -0
- data/{spec → test}/builder/fixtures/build_source/bar/a.rb +0 -0
- data/{spec → test}/builder/fixtures/build_source/bar/wow/b.rb +0 -0
- data/{spec → test}/builder/fixtures/build_source/bar/wow/cow/c.rb +0 -0
- data/{spec → test}/builder/fixtures/build_source/beynon.rb +0 -0
- data/{spec → test}/builder/fixtures/build_source/charles.js +0 -0
- data/{spec → test}/builder/fixtures/build_source/foo/a.rb +0 -0
- data/{spec → test}/builder/fixtures/build_source/foo/b.rb +0 -0
- data/{spec → test}/builder/fixtures/build_source/foo/x.js +0 -0
- data/{spec → test}/builder/fixtures/build_source/foo/y.js +0 -0
- data/{spec → test}/grammar/alias_spec.rb +0 -0
- data/{spec → test}/grammar/and_spec.rb +0 -0
- data/{spec → test}/grammar/array_spec.rb +0 -0
- data/{spec → test}/grammar/attrasgn_spec.rb +0 -0
- data/{spec → test}/grammar/begin_spec.rb +0 -0
- data/{spec → test}/grammar/block_spec.rb +0 -0
- data/{spec → test}/grammar/break_spec.rb +0 -0
- data/{spec → test}/grammar/call_spec.rb +0 -0
- data/{spec → test}/grammar/class_spec.rb +0 -0
- data/{spec → test}/grammar/const_spec.rb +0 -0
- data/{spec → test}/grammar/cvar_spec.rb +0 -0
- data/{spec → test}/grammar/def_spec.rb +0 -0
- data/{spec → test}/grammar/false_spec.rb +0 -0
- data/{spec → test}/grammar/file_spec.rb +0 -0
- data/{spec → test}/grammar/gvar_spec.rb +0 -0
- data/{spec → test}/grammar/hash_spec.rb +0 -0
- data/{spec → test}/grammar/iasgn_spec.rb +0 -0
- data/{spec → test}/grammar/if_spec.rb +0 -0
- data/{spec → test}/grammar/iter_spec.rb +0 -0
- data/{spec → test}/grammar/ivar_spec.rb +0 -0
- data/{spec → test}/grammar/lasgn_spec.rb +0 -0
- data/{spec → test}/grammar/line_spec.rb +0 -0
- data/{spec → test}/grammar/lvar_spec.rb +0 -0
- data/{spec → test}/grammar/masgn_spec.rb +0 -0
- data/{spec → test}/grammar/module_spec.rb +0 -0
- data/{spec → test}/grammar/nil_spec.rb +0 -0
- data/{spec → test}/grammar/not_spec.rb +0 -0
- data/{spec → test}/grammar/op_asgn1_spec.rb +0 -0
- data/{spec → test}/grammar/op_asgn2_spec.rb +0 -0
- data/{spec → test}/grammar/or_spec.rb +0 -0
- data/{spec → test}/grammar/return_spec.rb +0 -0
- data/{spec → test}/grammar/sclass_spec.rb +0 -0
- data/{spec → test}/grammar/self_spec.rb +0 -0
- data/{spec → test}/grammar/str_spec.rb +0 -0
- data/{spec → test}/grammar/super_spec.rb +0 -0
- data/{spec → test}/grammar/true_spec.rb +0 -0
- data/{spec → test}/grammar/undef_spec.rb +0 -0
- data/{spec → test}/grammar/unless_spec.rb +0 -0
- data/{spec → test}/grammar/while_spec.rb +0 -0
- data/{spec → test}/grammar/xstr_spec.rb +0 -0
- data/{spec → test}/grammar/yield_spec.rb +0 -0
- data/{spec → test}/spec_helper.rb +0 -0
- metadata +330 -264
- data/core/debug.js +0 -59
- data/core/debug.rb +0 -35
- data/core/dir.rb +0 -90
- data/core/file.rb +0 -83
- data/core/gemlib.rb +0 -30
- data/core/io.rb +0 -44
- data/core_spec/README.md +0 -34
- data/core_spec/core/array/collect_spec.rb +0 -3
- data/core_spec/core/array/element_set_spec.rb +0 -7
- data/core_spec/core/array/eql_spec.rb +0 -3
- data/core_spec/core/array/equal_value_spec.rb +0 -3
- data/core_spec/core/array/fixtures/classes.rb +0 -8
- data/core_spec/core/array/length_spec.rb +0 -3
- data/core_spec/core/array/map_spec.rb +0 -3
- data/core_spec/core/array/replace_spec.rb +0 -3
- data/core_spec/core/enumerable/collect_spec.rb +0 -3
- data/core_spec/core/enumerable/detect_spec.rb +0 -3
- data/core_spec/core/enumerable/find_spec.rb +0 -3
- data/core_spec/core/enumerable/first_spec.rb +0 -3
- data/core_spec/core/enumerable/shared/entries.rb +0 -7
- data/core_spec/core/enumerable/shared/find.rb +0 -49
- data/core_spec/core/enumerable/shared/take.rb +0 -31
- data/core_spec/core/enumerable/to_a_spec.rb +0 -7
- data/core_spec/core/hash/assoc_spec.rb +0 -29
- data/core_spec/core/object/is_a_spec.rb +0 -2
- data/core_spec/core/object/shared/kind_of.rb +0 -0
- data/core_spec/core/regexp/shared/match.rb +0 -11
- data/core_spec/language/fixtures/block.rb +0 -19
- data/core_spec/language/fixtures/break.rb +0 -39
- data/core_spec/language/fixtures/defined.rb +0 -9
- data/core_spec/language/fixtures/ensure.rb +0 -37
- data/core_spec/language/fixtures/next.rb +0 -46
- data/core_spec/language/fixtures/send.rb +0 -36
- data/core_spec/language/fixtures/super.rb +0 -43
- data/core_spec/language/regexp_spec.rb +0 -7
- data/core_spec/language/string_spec.rb +0 -4
- data/core_spec/language/super_spec.rb +0 -18
- data/core_spec/language/versions/hash_1.9.rb +0 -20
- data/core_spec/opal/opal/defined_spec.rb +0 -15
- data/core_spec/opal/opal/function_spec.rb +0 -11
- data/core_spec/opal/opal/native_spec.rb +0 -16
- data/core_spec/opal/opal/null_spec.rb +0 -10
- data/core_spec/opal/opal/number_spec.rb +0 -11
- data/core_spec/opal/opal/object_spec.rb +0 -16
- data/core_spec/opal/opal/string_spec.rb +0 -11
- data/core_spec/opal/opal/typeof_spec.rb +0 -9
- data/core_spec/opal/opal/undefined_spec.rb +0 -10
- data/core_spec/opal/true/case_compare_spec.rb +0 -12
- data/core_spec/opal/true/class_spec.rb +0 -10
- data/core_spec/release_runner.html +0 -17
- data/core_spec/runner.html +0 -16
- data/core_spec/spec_helper.rb +0 -23
- data/lib/opal/context.rb +0 -269
- data/lib/opal/dependency_builder.rb +0 -133
- data/lib/opal/environment.rb +0 -87
- data/lib/opal/parser/sexp.rb +0 -17
@@ -1062,6 +1062,10 @@ method_call:
|
|
1062
1062
|
{
|
1063
1063
|
result = new_call val[0], val[2].intern, val[3]
|
1064
1064
|
}
|
1065
|
+
| primary_value '.' paren_args
|
1066
|
+
{
|
1067
|
+
result = new_call val[0], :call, val[2]
|
1068
|
+
}
|
1065
1069
|
| primary_value '::' operation2 paren_args
|
1066
1070
|
| primary_value '::' operation3
|
1067
1071
|
| SUPER paren_args
|
@@ -1182,6 +1186,9 @@ string1:
|
|
1182
1186
|
result = val[1]
|
1183
1187
|
}
|
1184
1188
|
| STRING
|
1189
|
+
{
|
1190
|
+
result = s(:str, val[0])
|
1191
|
+
}
|
1185
1192
|
|
1186
1193
|
xstring:
|
1187
1194
|
XSTRING_BEG xstring_contents STRING_END
|
@@ -1,12 +1,10 @@
|
|
1
|
-
require 'opal/
|
2
|
-
require 'opal/parser/sexp'
|
3
|
-
|
1
|
+
require 'opal/grammar'
|
4
2
|
require 'strscan'
|
5
3
|
|
6
4
|
module Opal
|
7
5
|
class Grammar < Racc::Parser
|
8
6
|
|
9
|
-
class
|
7
|
+
class OpalParseError < StandardError; end
|
10
8
|
|
11
9
|
attr_reader :line
|
12
10
|
|
@@ -21,7 +19,7 @@ module Opal
|
|
21
19
|
end
|
22
20
|
|
23
21
|
def s *parts
|
24
|
-
sexp =
|
22
|
+
sexp = parts
|
25
23
|
sexp.line = @line
|
26
24
|
sexp
|
27
25
|
end
|
@@ -37,6 +35,10 @@ module Opal
|
|
37
35
|
result
|
38
36
|
end
|
39
37
|
|
38
|
+
def on_error(t, val, vstack)
|
39
|
+
raise OpalParseError, "parse error on value #{val.inspect} (line #{@line})"
|
40
|
+
end
|
41
|
+
|
40
42
|
class LexerScope
|
41
43
|
attr_reader :locals
|
42
44
|
attr_accessor :parent
|
@@ -140,7 +142,7 @@ module Opal
|
|
140
142
|
|
141
143
|
def new_sclass expr, body
|
142
144
|
scope = s(:scope)
|
143
|
-
scope << body unless body.size == 1
|
145
|
+
scope << body #unless body.size == 1
|
144
146
|
scope.line = body.line
|
145
147
|
s = s(:sclass, expr, scope)
|
146
148
|
s
|
@@ -224,7 +226,7 @@ module Opal
|
|
224
226
|
if block
|
225
227
|
b = block.to_s[1..-1].intern
|
226
228
|
res << s(:block_pass, s(:lasgn, b))
|
227
|
-
@scope.add_local
|
229
|
+
@scope.add_local b
|
228
230
|
end
|
229
231
|
|
230
232
|
res << opt if opt
|
@@ -435,8 +437,8 @@ module Opal
|
|
435
437
|
|
436
438
|
def next_token
|
437
439
|
t = get_next_token
|
438
|
-
#puts "returning token #{t.inspect}"
|
439
|
-
#t[1] = { :value => t[1], :line => @line }
|
440
|
+
# puts "returning token #{t.inspect}"
|
441
|
+
# t[1] = { :value => t[1], :line => @line }
|
440
442
|
t
|
441
443
|
end
|
442
444
|
|
@@ -1005,7 +1007,26 @@ module Opal
|
|
1005
1007
|
return [result, result]
|
1006
1008
|
|
1007
1009
|
elsif scanner.scan(/\?/)
|
1008
|
-
|
1010
|
+
# FIXME: :expr_arg shouldnt really be here
|
1011
|
+
if [:expr_end, :expr_endarg, :expr_arg].include?(@lex_state)
|
1012
|
+
@lex_state = :expr_beg
|
1013
|
+
return '?', scanner.matched
|
1014
|
+
end
|
1015
|
+
|
1016
|
+
#if scanner.scan(/\\/)
|
1017
|
+
#c = if scanner.scan(/n/)
|
1018
|
+
#"\n"
|
1019
|
+
#else
|
1020
|
+
#scanner.scan(/./)
|
1021
|
+
#scanner.matched
|
1022
|
+
#end
|
1023
|
+
#else
|
1024
|
+
#c = scanner.scan(/./)
|
1025
|
+
#end
|
1026
|
+
|
1027
|
+
#@lex_state = :expr_end
|
1028
|
+
#return :STRING, c
|
1029
|
+
@lex_state = :expr_beg
|
1009
1030
|
return '?', scanner.matched
|
1010
1031
|
|
1011
1032
|
elsif scanner.scan(/\=\=\=/)
|
@@ -1331,7 +1352,7 @@ module Opal
|
|
1331
1352
|
end
|
1332
1353
|
return [false, false] if scanner.eos?
|
1333
1354
|
|
1334
|
-
raise
|
1355
|
+
raise OpalParseError, "Unexpected content in parsing stream `#{scanner.peek 5}`"
|
1335
1356
|
end
|
1336
1357
|
end
|
1337
1358
|
end
|
@@ -1,18 +1,19 @@
|
|
1
|
-
require 'opal/
|
2
|
-
require 'opal/
|
3
|
-
require 'opal/
|
1
|
+
require 'opal/lexer'
|
2
|
+
require 'opal/grammar'
|
3
|
+
require 'opal/scope'
|
4
|
+
|
5
|
+
class Array
|
6
|
+
attr_accessor :line
|
7
|
+
attr_accessor :end_line
|
8
|
+
end
|
4
9
|
|
5
10
|
module Opal
|
6
11
|
class OpalParseError < Exception; end
|
7
12
|
|
8
13
|
class Parser
|
9
|
-
def self.to_syms(ary)
|
10
|
-
ary.map &:to_sym
|
11
|
-
end
|
12
|
-
|
13
14
|
INDENT = ' '
|
14
15
|
|
15
|
-
LEVEL =
|
16
|
+
LEVEL = [:statement, :statement_closure, :list, :expression, :receiver]
|
16
17
|
|
17
18
|
# Maths operators
|
18
19
|
MATH = %w(+ - / * %)
|
@@ -20,7 +21,7 @@ module Opal
|
|
20
21
|
# Comparison operators
|
21
22
|
COMPARE = %w(< <= > >=)
|
22
23
|
|
23
|
-
# All
|
24
|
+
# All Operators that can be optimized in method calls
|
24
25
|
CALL_OPERATORS = MATH + COMPARE
|
25
26
|
|
26
27
|
# Reserved javascript keywords - we cannot create variables with the
|
@@ -76,7 +77,13 @@ module Opal
|
|
76
77
|
singleton: 0x0800
|
77
78
|
}
|
78
79
|
|
79
|
-
STATEMENTS =
|
80
|
+
STATEMENTS = [:xstr, :dxstr]
|
81
|
+
|
82
|
+
attr_reader :grammar
|
83
|
+
|
84
|
+
def self.parse(str)
|
85
|
+
self.new.parse str
|
86
|
+
end
|
80
87
|
|
81
88
|
def initialize(opts = {})
|
82
89
|
@debug = opts[:debug] or false
|
@@ -85,34 +92,26 @@ module Opal
|
|
85
92
|
def parse(source, file = '(file)')
|
86
93
|
@file = file
|
87
94
|
@helpers = {
|
88
|
-
:breaker
|
89
|
-
:
|
95
|
+
:breaker => true,
|
96
|
+
:klass => true,
|
97
|
+
:const_get => true,
|
98
|
+
:slice => true
|
99
|
+
# :nil => true
|
90
100
|
}
|
91
101
|
|
92
|
-
|
102
|
+
@grammar = Grammar.new
|
93
103
|
reset
|
94
|
-
|
95
|
-
# Debug mode always uses FILE for sending methods which have stack traces
|
96
|
-
@uses_file = true if @debug
|
97
|
-
|
98
|
-
# $send is needed in debug mode
|
99
|
-
@helpers[:send] = true if @debug
|
100
|
-
|
101
|
-
begin
|
102
|
-
top parser.parse(source, file)
|
103
|
-
rescue Exception => e
|
104
|
-
raise OpalParseError.new("#{e.message} in #{file}:#{parser.line}")
|
105
|
-
end
|
104
|
+
top @grammar.parse(source, file)
|
106
105
|
end
|
107
106
|
|
108
107
|
def s(*parts)
|
109
|
-
sexp =
|
108
|
+
sexp = parts
|
110
109
|
sexp.line = @line
|
111
110
|
sexp
|
112
111
|
end
|
113
112
|
|
114
113
|
def reset
|
115
|
-
@line
|
114
|
+
@line = 1
|
116
115
|
@indent = ''
|
117
116
|
@unique = 0
|
118
117
|
end
|
@@ -135,19 +134,20 @@ module Opal
|
|
135
134
|
vars = []
|
136
135
|
|
137
136
|
in_scope(:top) do
|
138
|
-
|
137
|
+
indent {
|
138
|
+
code = @indent + process(s(:scope, sexp), :statement)
|
139
|
+
}
|
139
140
|
|
140
|
-
vars << "
|
141
|
-
vars << "nil =
|
142
|
-
vars
|
143
|
-
vars.concat @scope.
|
144
|
-
vars.concat @
|
145
|
-
vars.concat @helpers.keys.map { |h| "$#{h} = $opal.#{h}" }
|
141
|
+
vars << "__scope = Opal.constants"
|
142
|
+
vars << "nil = Opal.nil"
|
143
|
+
# vars.concat @scope.locals.map { |t| "#{t}" }
|
144
|
+
# vars.concat @scope.temps.map { |t| t }
|
145
|
+
vars.concat @helpers.keys.map { |h| "__#{h} = Opal.#{h}" }
|
146
146
|
|
147
|
-
code = "var #{vars.join ', '}
|
147
|
+
code = "var #{vars.join ', '};\n" + @scope.to_vars + "\n" + code
|
148
148
|
end
|
149
149
|
|
150
|
-
pre = "(function(
|
150
|
+
pre = "(function() {\n"
|
151
151
|
post = ""
|
152
152
|
|
153
153
|
uniques = []
|
@@ -158,7 +158,7 @@ module Opal
|
|
158
158
|
post += ";var #{uniques.join ', '};"
|
159
159
|
end
|
160
160
|
|
161
|
-
post += "\n}).call(
|
161
|
+
post += "\n}).call(Opal.top);\n"
|
162
162
|
|
163
163
|
pre + code + post
|
164
164
|
end
|
@@ -167,7 +167,7 @@ module Opal
|
|
167
167
|
return unless block_given?
|
168
168
|
|
169
169
|
parent = @scope
|
170
|
-
@scope = Scope.new(type).tap { |s| s.parent = parent }
|
170
|
+
@scope = Scope.new(type, self).tap { |s| s.parent = parent }
|
171
171
|
yield @scope
|
172
172
|
|
173
173
|
@scope = parent
|
@@ -203,24 +203,13 @@ module Opal
|
|
203
203
|
end
|
204
204
|
|
205
205
|
def process(sexp, level)
|
206
|
+
# puts "PROCESS: (#{level})"
|
207
|
+
# puts " #{sexp.inspect}"
|
206
208
|
type = sexp.shift
|
207
209
|
|
208
210
|
raise "Unsupported sexp: #{type}" unless respond_to? type
|
209
211
|
|
210
|
-
|
211
|
-
code = __send__ type, sexp, level
|
212
|
-
line + code
|
213
|
-
end
|
214
|
-
|
215
|
-
def fix_line(line)
|
216
|
-
res = ""
|
217
|
-
|
218
|
-
if @line < line
|
219
|
-
res = "\n" * (line - @line)
|
220
|
-
res += @indent
|
221
|
-
@line = line
|
222
|
-
end
|
223
|
-
res
|
212
|
+
__send__ type, sexp, level
|
224
213
|
end
|
225
214
|
|
226
215
|
def returns(sexp)
|
@@ -277,11 +266,11 @@ module Opal
|
|
277
266
|
until sexp.empty?
|
278
267
|
stmt = sexp.shift
|
279
268
|
expr = expression?(stmt) and LEVEL.index(level) < LEVEL.index(:list)
|
280
|
-
|
281
|
-
result << ";"
|
269
|
+
code = process(stmt, level)
|
270
|
+
result << (expr ? "#{code};" : code)
|
282
271
|
end
|
283
272
|
|
284
|
-
result.join
|
273
|
+
result.join "\n#@indent"
|
285
274
|
end
|
286
275
|
|
287
276
|
def scope(sexp, level)
|
@@ -302,12 +291,6 @@ module Opal
|
|
302
291
|
sexp.shift.to_s
|
303
292
|
end
|
304
293
|
|
305
|
-
# s(:js_block_given)
|
306
|
-
def js_block_given(sexp, level)
|
307
|
-
@scope.uses_block!
|
308
|
-
"$block_given"
|
309
|
-
end
|
310
|
-
|
311
294
|
def js_operator_call(sexp, level)
|
312
295
|
recv = sexp[0]
|
313
296
|
meth = sexp[1]
|
@@ -329,41 +312,10 @@ module Opal
|
|
329
312
|
res
|
330
313
|
end
|
331
314
|
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
arg = args[1] || raise("No argument given to compile helper: #{meth}")
|
338
|
-
arg = process arg, :expression
|
339
|
-
tmp = @scope.new_temp
|
340
|
-
|
341
|
-
res = case meth
|
342
|
-
when :object?
|
343
|
-
"(!!(#{tmp} = #{arg}, #{tmp} != null && #{tmp}.$klass))"
|
344
|
-
when :native?
|
345
|
-
"(!!(#{tmp} = #{arg}, #{tmp} == null || !#{tmp}.$klass))"
|
346
|
-
when :string?
|
347
|
-
"(typeof #{arg} === 'string')"
|
348
|
-
when :number?
|
349
|
-
"(typeof #{arg} === 'number')"
|
350
|
-
when :function?
|
351
|
-
"(typeof #{arg} === 'function')"
|
352
|
-
when :defined?
|
353
|
-
"((#{tmp} = typeof(#{arg})) === 'undefined' ? nil : #{tmp})"
|
354
|
-
when :undefined?
|
355
|
-
"(typeof(#{arg}) === 'undefined')"
|
356
|
-
when :null?
|
357
|
-
"(#{arg} === null)"
|
358
|
-
when :typeof
|
359
|
-
"(typeof(#{arg}))"
|
360
|
-
else
|
361
|
-
raise "Bad compile time helper: #{meth}"
|
362
|
-
end
|
363
|
-
|
364
|
-
@scope.queue_temp tmp
|
365
|
-
|
366
|
-
res
|
315
|
+
# s(:js_block_given)
|
316
|
+
def js_block_given(sexp, level)
|
317
|
+
@scope.uses_block!
|
318
|
+
"!!#{@scope.block_name}"
|
367
319
|
end
|
368
320
|
|
369
321
|
# s(:lit, 1)
|
@@ -378,7 +330,8 @@ module Opal
|
|
378
330
|
when Regexp
|
379
331
|
val == // ? /^/.inspect : val.inspect
|
380
332
|
when Range
|
381
|
-
|
333
|
+
@helpers[:range] = true
|
334
|
+
"__range(#{val.begin}, #{val.end}, #{val.exclude_end?})"
|
382
335
|
else
|
383
336
|
raise "Bad lit: #{val.inspect}"
|
384
337
|
end
|
@@ -398,8 +351,14 @@ module Opal
|
|
398
351
|
"(new RegExp(#{parts.join ' + '}))"
|
399
352
|
end
|
400
353
|
|
401
|
-
def dot2
|
402
|
-
|
354
|
+
def dot2(sexp, level)
|
355
|
+
@helpers[:range] = true
|
356
|
+
"__range(#{process sexp[0], :expression}, #{process sexp[1], :expression}, false)"
|
357
|
+
end
|
358
|
+
|
359
|
+
def dot3(sexp, level)
|
360
|
+
@helpers[:range] = true
|
361
|
+
"__range(#{process sexp[0], :expression}, #{process sexp[1], :expression}, true)"
|
403
362
|
end
|
404
363
|
|
405
364
|
# s(:str, "string")
|
@@ -407,7 +366,7 @@ module Opal
|
|
407
366
|
str = sexp.shift
|
408
367
|
if str == @file
|
409
368
|
@uses_file = true
|
410
|
-
"FILE"
|
369
|
+
"'FILE'"
|
411
370
|
else
|
412
371
|
str.inspect
|
413
372
|
end
|
@@ -435,20 +394,18 @@ module Opal
|
|
435
394
|
|
436
395
|
# s(:not, sexp)
|
437
396
|
def not(sexp, level)
|
438
|
-
|
439
|
-
code = "((#{tmp} = #{process sexp.shift, :expression}) === false || #{tmp} === nil)"
|
440
|
-
@scope.queue_temp tmp
|
397
|
+
code = "!#{process sexp.shift, :expression}"
|
441
398
|
code
|
442
399
|
end
|
443
400
|
|
444
401
|
def block_pass(exp, level)
|
445
402
|
pass = process exp.shift, level
|
446
|
-
|
403
|
+
return "(#{pass} || function(){})"
|
447
404
|
tmp = @scope.new_temp
|
448
405
|
|
449
406
|
to_proc = process(s(:call, s(:js_tmp, tmp), :to_proc, s(:arglist)), :expression)
|
450
407
|
|
451
|
-
code = "(#{tmp} = #{pass}, (typeof(#{tmp}) === 'function' || #{tmp} ==
|
408
|
+
code = "(#{tmp} = #{pass}, (typeof(#{tmp}) === 'function' || #{tmp} == null ? #{tmp} : #{to_proc}))"
|
452
409
|
|
453
410
|
@scope.queue_temp tmp
|
454
411
|
|
@@ -465,13 +422,15 @@ module Opal
|
|
465
422
|
body = returns body
|
466
423
|
code = ""
|
467
424
|
params = nil
|
425
|
+
scope_name = nil
|
468
426
|
|
469
427
|
args = nil if Fixnum === args # argh
|
470
428
|
args ||= s(:masgn, s(:array))
|
471
429
|
args = args.first == :lasgn ? s(:array, args) : args[1]
|
472
430
|
|
473
431
|
if args.last[0] == :block_pass
|
474
|
-
args.pop
|
432
|
+
block_arg = args.pop
|
433
|
+
block_arg = block_arg[1][1].intern
|
475
434
|
end
|
476
435
|
|
477
436
|
if args.last[0] == :splat
|
@@ -483,25 +442,36 @@ module Opal
|
|
483
442
|
indent do
|
484
443
|
in_scope(:iter) do
|
485
444
|
args[1..-1].each do |arg|
|
486
|
-
|
487
|
-
|
488
|
-
code += "if (#{arg}
|
445
|
+
arg = arg[1]
|
446
|
+
arg = "#{arg}$" if RESERVED.include? arg.to_s
|
447
|
+
code += "if (#{arg} == null) #{arg} = nil;\n"
|
489
448
|
end
|
490
449
|
|
491
450
|
params = js_block_args(args[1..-1])
|
451
|
+
# params.unshift '_$'
|
492
452
|
|
493
453
|
if splat
|
494
454
|
params << splat
|
495
|
-
code += "#{splat} =
|
455
|
+
code += "#{splat} = __slice.call(arguments, #{len - 1});"
|
496
456
|
end
|
497
457
|
|
498
|
-
|
458
|
+
if block_arg
|
459
|
+
@scope.add_arg block_arg
|
460
|
+
code += "var #{block_arg} = _$ || nil, $context = #{block_arg}.$S;"
|
461
|
+
end
|
462
|
+
|
463
|
+
code += "\n#@indent" + process(body, :statement)
|
464
|
+
|
465
|
+
code = "\n#@indent#{@scope.to_vars}\n#@indent#{code}"
|
499
466
|
|
500
|
-
|
467
|
+
scope_name = @scope.identity
|
501
468
|
end
|
502
469
|
end
|
503
470
|
|
504
|
-
|
471
|
+
itercode = "function(#{params.join ', '}) {\n#{code}\n#@indent}"
|
472
|
+
itercode = "#{scope_name} = #{itercode}" if scope_name
|
473
|
+
call << itercode
|
474
|
+
|
505
475
|
process call, level
|
506
476
|
end
|
507
477
|
|
@@ -527,6 +497,15 @@ module Opal
|
|
527
497
|
return process(s(:call, recv, mid, arglist), level)
|
528
498
|
end
|
529
499
|
|
500
|
+
# s(:math_op, :op, lhs, rhs)
|
501
|
+
def math_op(exp, level)
|
502
|
+
op = exp[0]
|
503
|
+
lhs = exp[1]
|
504
|
+
rhs = exp[2]
|
505
|
+
|
506
|
+
"#{process lhs, level} #{op} #{process rhs, level}"
|
507
|
+
end
|
508
|
+
|
530
509
|
# s(:call, recv, :mid, s(:arglist))
|
531
510
|
# s(:call, nil, :mid, s(:arglist))
|
532
511
|
def call(sexp, level)
|
@@ -538,63 +517,45 @@ module Opal
|
|
538
517
|
mid = mid_to_jsid meth.to_s
|
539
518
|
|
540
519
|
return js_operator_call(sexp, level) if CALL_OPERATORS.include? meth.to_s
|
541
|
-
return js_compile_time_helpers(sexp, level) if recv && recv == [:const, :Opal]
|
542
520
|
return js_block_given(sexp, level) if meth == :block_given?
|
543
|
-
return "undefined" if meth == :undefined
|
544
521
|
|
545
522
|
splat = arglist[1..-1].any? { |a| a.first == :splat }
|
546
523
|
|
547
|
-
if
|
548
|
-
|
549
|
-
|
550
|
-
block = process arglist.pop, :expression
|
524
|
+
if Array === arglist.last and arglist.last.first == :block_pass
|
525
|
+
tmpmeth = @scope.new_temp
|
526
|
+
block = process s(:js_tmp, process(arglist.pop, :expression)), :expression
|
551
527
|
elsif iter
|
552
|
-
|
528
|
+
tmpmeth = @scope.new_temp
|
529
|
+
block = iter
|
530
|
+
end
|
531
|
+
|
532
|
+
recv ||= [:self]
|
533
|
+
|
534
|
+
if block
|
553
535
|
tmprecv = @scope.new_temp
|
554
|
-
|
555
|
-
elsif splat or @debug
|
536
|
+
elsif splat and recv != [:self] and recv[0] != :lvar
|
556
537
|
tmprecv = @scope.new_temp
|
557
538
|
end
|
539
|
+
|
540
|
+
recv_code = process recv, :receiver
|
541
|
+
args = ""
|
558
542
|
|
559
|
-
|
560
|
-
|
561
|
-
recv_code = recv.nil? ? 'this' : process(recv, :receiver)
|
543
|
+
@scope.queue_temp tmprecv if tmprecv
|
544
|
+
@scope.queue_temp tmpmeth if tmpmeth
|
562
545
|
|
563
|
-
if
|
564
|
-
|
565
|
-
debugblock = "(#{tmpproc}=#{block},#{tmpproc}.$S=this, #{tmpproc})"
|
566
|
-
elsif block
|
567
|
-
debugblock = block
|
568
|
-
else
|
569
|
-
debugblock = 'null'
|
570
|
-
end
|
571
|
-
arglist.insert 1, s(:js_tmp, recv_code), s(:js_tmp, debugblock), s(:js_tmp, mid.inspect)
|
546
|
+
if tmpmeth and !splat
|
547
|
+
arglist.insert 1, s(:js_tmp, tmprecv)
|
572
548
|
end
|
573
549
|
|
574
550
|
args = process arglist, :expression
|
575
551
|
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
splat ? "$send.apply(null, #{args})" : "$send(#{args})"
|
581
|
-
elsif @method_missing
|
582
|
-
pre = "((#{tmprecv}=#{recv_code}).#{mid} || $opal.mm('#{mid}'))."
|
583
|
-
splat ? "#{pre}apply(#{tmprecv}, #{args})" : "#{pre}call(#{tmprecv}#{args == '' ? '' : ", #{args}"})"
|
552
|
+
if tmpmeth
|
553
|
+
dispatch = "(((#{tmpmeth} = (#{tmprecv} = #{recv_code})"
|
554
|
+
dispatch += ".#{mid})._p = #{block})._s = this, #{tmpmeth})"
|
555
|
+
splat ? "#{dispatch}.apply(#{tmprecv}, #{args})" : "#{dispatch}.call(#{args})"
|
584
556
|
else
|
585
|
-
|
586
|
-
|
587
|
-
call = "(#{tmpproc}=(#{tmprecv}=#{recv_code}).#{mid}, (#{tmpproc}.$P = #{block}).$S = this, #{tmpproc})"
|
588
|
-
else # block_pass
|
589
|
-
call = "(#{tmpproc}=(#{tmprecv}=#{recv_code}).#{mid}, #{tmpproc}.$P = #{block}, #{tmpproc})"
|
590
|
-
end
|
591
|
-
|
592
|
-
args = ", #{args}" unless args.empty?
|
593
|
-
splat ? "#{call}.apply(#{tmprecv}#{args})" : "#{call}.call(#{tmprecv}#{args})"
|
594
|
-
|
595
|
-
else
|
596
|
-
splat ? "(#{tmprecv}=#{recv_code}).#{mid}.apply(#{tmprecv}, #{args})" : "#{recv_code}.#{mid}(#{args})"
|
597
|
-
end
|
557
|
+
dispatch = tmprecv ? "(#{tmprecv} = #{recv_code}).#{mid}" : "#{recv_code}.#{mid}"
|
558
|
+
splat ? "#{dispatch}.apply(#{tmprecv || recv_code}, #{args})" : "#{dispatch}(#{args})"
|
598
559
|
end
|
599
560
|
end
|
600
561
|
|
@@ -657,23 +618,23 @@ module Opal
|
|
657
618
|
name = cid[2].to_s.inspect
|
658
619
|
elsif cid[0] == :colon3
|
659
620
|
donates_methods = (cid[1] === :Object || cid[1] === :BasicObject)
|
660
|
-
base = '
|
621
|
+
base = 'opal.Object'
|
661
622
|
name = cid[1].to_s.inspect
|
662
623
|
else
|
663
624
|
raise "Bad receiver in class"
|
664
625
|
end
|
665
626
|
|
666
|
-
sup = sup ? process(sup, :expression) : '
|
627
|
+
sup = sup ? process(sup, :expression) : 'null'
|
667
628
|
|
668
629
|
indent do
|
669
630
|
in_scope(:class) do
|
670
631
|
@scope.donates_methods = donates_methods
|
671
|
-
code = @scope.to_vars + process(body, :statement)
|
672
|
-
code += @scope.to_donate_methods if @scope.donates_methods
|
632
|
+
code = @indent + @scope.to_vars + "\n#@indent" + process(body, :statement)
|
633
|
+
code += "\n#{@scope.to_donate_methods}" if @scope.donates_methods
|
673
634
|
end
|
674
635
|
end
|
675
636
|
|
676
|
-
"
|
637
|
+
"__klass(#{base}, #{sup}, #{name}, function() {\n#{code}\n#@indent}, 0)"
|
677
638
|
end
|
678
639
|
|
679
640
|
# s(:sclass, recv, body)
|
@@ -687,7 +648,7 @@ module Opal
|
|
687
648
|
code = @scope.to_vars + process(body, :statement)
|
688
649
|
end
|
689
650
|
|
690
|
-
"
|
651
|
+
"__klass(#{base}, null, null, function() {#{code}}, 2)"
|
691
652
|
end
|
692
653
|
|
693
654
|
# s(:module, cid, body)
|
@@ -703,7 +664,7 @@ module Opal
|
|
703
664
|
base = process(cid[1], :expression)
|
704
665
|
name = cid[2].to_s.inspect
|
705
666
|
elsif cid[0] == :colon3
|
706
|
-
base = '
|
667
|
+
base = 'opal.Object'
|
707
668
|
name = cid[1].to_s.inspect
|
708
669
|
else
|
709
670
|
raise "Bad receiver in class"
|
@@ -712,15 +673,15 @@ module Opal
|
|
712
673
|
indent do
|
713
674
|
in_scope(:module) do
|
714
675
|
@scope.donates_methods = true
|
715
|
-
code = @scope.to_vars + process(body, :statement) + @scope.to_donate_methods
|
676
|
+
code = @indent + @scope.to_vars + "\n#@indent" + process(body, :statement) + "\n#@indent" + @scope.to_donate_methods
|
716
677
|
end
|
717
678
|
end
|
718
679
|
|
719
|
-
"
|
680
|
+
"__klass(#{base}, null, #{name}, function() {\n#{code}\n#@indent}, 1)"
|
720
681
|
end
|
721
682
|
|
722
683
|
def undef(exp, level)
|
723
|
-
"
|
684
|
+
"opal.undef(this, #{process exp.shift, :expression})"
|
724
685
|
end
|
725
686
|
|
726
687
|
# s(:defn, mid, s(:args), s(:scope))
|
@@ -744,10 +705,11 @@ module Opal
|
|
744
705
|
mid = mid_to_jsid mid.to_s
|
745
706
|
|
746
707
|
if recvr
|
747
|
-
|
708
|
+
@helpers[:defs] = true
|
709
|
+
type = '__defs'
|
748
710
|
recv = process(recvr, :expression)
|
749
711
|
else
|
750
|
-
type = '
|
712
|
+
type = 'Opal.defn'
|
751
713
|
recv = 'this'
|
752
714
|
end
|
753
715
|
|
@@ -756,7 +718,7 @@ module Opal
|
|
756
718
|
scope_name = nil
|
757
719
|
|
758
720
|
# opt args if last arg is sexp
|
759
|
-
opt = args.pop if
|
721
|
+
opt = args.pop if Array === args.last
|
760
722
|
|
761
723
|
# block name &block
|
762
724
|
if args.last.to_s[0] == '&'
|
@@ -774,52 +736,50 @@ module Opal
|
|
774
736
|
end
|
775
737
|
end
|
776
738
|
|
777
|
-
aritycode = arity_check(args, opt, splat) if @debug && false
|
739
|
+
# aritycode = arity_check(args, opt, splat) if @debug && false
|
778
740
|
|
779
741
|
indent do
|
780
742
|
in_scope(:def) do
|
781
|
-
|
743
|
+
@scope.mid = mid
|
782
744
|
|
783
745
|
if block_name
|
784
|
-
@scope.add_arg block_name
|
785
746
|
@scope.uses_block!
|
786
747
|
end
|
787
748
|
|
749
|
+
yielder = block_name || '__yield'
|
750
|
+
@scope.block_name = yielder
|
751
|
+
|
752
|
+
params = process args, :expression
|
753
|
+
|
788
754
|
opt[1..-1].each do |o|
|
789
755
|
next if o[2][2] == :undefined
|
790
756
|
id = process s(:lvar, o[1]), :expression
|
791
|
-
code += "if (#{id}
|
757
|
+
code += "if (#{id} == null) {\n#@indent#{INDENT}#{process o, :expression};\n#@indent}"
|
792
758
|
end if opt
|
793
759
|
|
794
|
-
code += "#{splat} =
|
795
|
-
code += process(stmts, :statement)
|
796
|
-
|
797
|
-
if @scope.uses_block?
|
798
|
-
scope_name = @scope.name = unique_temp
|
799
|
-
blk = "var $yield = #{scope_name}.$P;"
|
800
|
-
blk += "if ($yield) { var $context = $yield.$S"
|
801
|
-
blk += ", $block_given = true"
|
802
|
-
blk += ", #{block_name} = $yield" if block_name
|
803
|
-
blk += "; #{scope_name}.$P = null; }"
|
760
|
+
code += "#{splat} = __slice.call(arguments, #{len});" if splat
|
761
|
+
code += "\n#@indent" + process(stmts, :statement)
|
804
762
|
|
805
|
-
|
806
|
-
|
807
|
-
blk += "; }"
|
763
|
+
# Returns the identity name if identified, nil otherwise
|
764
|
+
scope_name = @scope.identity
|
808
765
|
|
766
|
+
if @scope.uses_block?
|
767
|
+
@scope.add_local '__context'
|
768
|
+
@scope.add_local yielder
|
769
|
+
blk = "\n#{@indent}if (#{yielder} = #{scope_name}._p) {\n#{@indent + INDENT}__context = #{yielder}._s"
|
770
|
+
blk += ";\n#{@indent + INDENT}#{scope_name}._p = null;\n#{@indent}}"
|
809
771
|
code = blk + code
|
810
772
|
end
|
811
773
|
|
812
|
-
code = aritycode.to_s + code
|
813
|
-
|
814
774
|
if @scope.catches_break?
|
815
|
-
code = "try {#{code}} catch (e) { if (e ===
|
775
|
+
# code = "try {#{code}} catch (e) { if (e === __breaker) { return e.$v; }; throw e;}"
|
816
776
|
end
|
817
777
|
|
818
|
-
code = @scope.to_vars + code
|
778
|
+
code = "#@indent#{@scope.to_vars}" + code
|
819
779
|
end
|
820
780
|
end
|
821
781
|
|
822
|
-
defcode = "#{"#{scope_name} = " if scope_name}function(#{params}) {#{code}
|
782
|
+
defcode = "#{"#{scope_name} = " if scope_name}function(#{params}) {\n#{code}\n#@indent}"
|
823
783
|
|
824
784
|
if @debug
|
825
785
|
"#{type}(#{recv}, '#{mid}', #{defcode}, FILE, #{line})"
|
@@ -846,9 +806,9 @@ module Opal
|
|
846
806
|
|
847
807
|
aritycode = "var $arity = arguments.length; if ($arity !== 0) { $arity -= 1; }"
|
848
808
|
if arity < 0 # splat or opt args
|
849
|
-
aritycode + "if ($arity < #{-(arity + 1)}) {
|
809
|
+
aritycode + "if ($arity < #{-(arity + 1)}) { opal.arg_error($arity, #{arity}); }"
|
850
810
|
else
|
851
|
-
aritycode + "if ($arity !== #{arity}) {
|
811
|
+
aritycode + "if ($arity !== #{arity}) { opal.arg_error($arity, #{arity}); }"
|
852
812
|
end
|
853
813
|
end
|
854
814
|
|
@@ -872,13 +832,16 @@ module Opal
|
|
872
832
|
|
873
833
|
# s(:true) # => true
|
874
834
|
# s(:false) # => false
|
875
|
-
|
876
|
-
%w(true false nil).each do |name|
|
835
|
+
%w(true false).each do |name|
|
877
836
|
define_method name do |exp, level|
|
878
837
|
name
|
879
838
|
end
|
880
839
|
end
|
881
840
|
|
841
|
+
def nil(*)
|
842
|
+
"nil"
|
843
|
+
end
|
844
|
+
|
882
845
|
# s(:array [, sexp [, sexp]])
|
883
846
|
def array(sexp, level)
|
884
847
|
return '[]' if sexp.empty?
|
@@ -914,7 +877,7 @@ module Opal
|
|
914
877
|
|
915
878
|
# s(:hash, key1, val1, key2, val2...)
|
916
879
|
def hash(sexp, level)
|
917
|
-
"
|
880
|
+
"Opal.hash(#{sexp.map { |p| process p, :expression }.join ', '})"
|
918
881
|
end
|
919
882
|
|
920
883
|
# s(:while, exp, block, true)
|
@@ -995,9 +958,10 @@ module Opal
|
|
995
958
|
#
|
996
959
|
# s(:alias, s(:lit, :foo), s(:lit, :bar))
|
997
960
|
def alias(exp, level)
|
961
|
+
@helpers['alias'] = true
|
998
962
|
new = exp[0]
|
999
963
|
old = exp[1]
|
1000
|
-
"
|
964
|
+
"__alias(this, #{process new, :expression}, #{process old, :expression})"
|
1001
965
|
end
|
1002
966
|
|
1003
967
|
def masgn(sexp, level)
|
@@ -1023,11 +987,11 @@ module Opal
|
|
1023
987
|
|
1024
988
|
if l.first == :splat
|
1025
989
|
s = l[1]
|
1026
|
-
s << s(:js_tmp, "
|
990
|
+
s << s(:js_tmp, "__slice.call(#{tmp}, #{idx})")
|
1027
991
|
code << process(s, :expression)
|
1028
992
|
else
|
1029
993
|
if idx >= len
|
1030
|
-
l << s(:js_tmp, "(#{tmp}[#{idx}]
|
994
|
+
l << s(:js_tmp, "(#{tmp}[#{idx}] == null ? nil : #{tmp}[#{idx}])")
|
1031
995
|
else
|
1032
996
|
l << s(:js_tmp, "#{tmp}[#{idx}]")
|
1033
997
|
end
|
@@ -1049,7 +1013,8 @@ module Opal
|
|
1049
1013
|
rhs = sexp[1]
|
1050
1014
|
lvar = "#{lvar}$".intern if RESERVED.include? lvar.to_s
|
1051
1015
|
@scope.add_local lvar
|
1052
|
-
"#{lvar} = #{process rhs, :expression}"
|
1016
|
+
res = "#{lvar} = #{process rhs, :expression}"
|
1017
|
+
level == :receiver ? "(#{res})" : res
|
1053
1018
|
end
|
1054
1019
|
|
1055
1020
|
# s(:lvar, :lvar)
|
@@ -1079,25 +1044,24 @@ module Opal
|
|
1079
1044
|
# s(:gvar, gvar)
|
1080
1045
|
def gvar(sexp, level)
|
1081
1046
|
gvar = sexp.shift.to_s
|
1082
|
-
|
1083
|
-
|
1084
|
-
@scope.queue_temp tmp
|
1085
|
-
code
|
1047
|
+
@helpers['gvars'] = true
|
1048
|
+
"__gvars[#{gvar.inspect}]"
|
1086
1049
|
end
|
1087
1050
|
|
1088
1051
|
# s(:gasgn, :gvar, rhs)
|
1089
1052
|
def gasgn(sexp, level)
|
1090
1053
|
gvar = sexp[0]
|
1091
1054
|
rhs = sexp[1]
|
1092
|
-
|
1055
|
+
@helpers['gvars'] = true
|
1056
|
+
"__gvars[#{gvar.to_s.inspect}] = #{process rhs, :expression}"
|
1093
1057
|
end
|
1094
1058
|
|
1095
1059
|
# s(:const, :const)
|
1096
1060
|
def const(sexp, level)
|
1097
1061
|
if @debug
|
1098
|
-
"
|
1062
|
+
"Opal.const_get(__scope, #{sexp.shift.to_s.inspect})"
|
1099
1063
|
else
|
1100
|
-
"
|
1064
|
+
"__scope.#{sexp.shift}"
|
1101
1065
|
end
|
1102
1066
|
end
|
1103
1067
|
|
@@ -1105,7 +1069,7 @@ module Opal
|
|
1105
1069
|
def cdecl(sexp, level)
|
1106
1070
|
const = sexp[0]
|
1107
1071
|
rhs = sexp[1]
|
1108
|
-
"
|
1072
|
+
"__scope.#{const} = #{process rhs, :expression}"
|
1109
1073
|
end
|
1110
1074
|
|
1111
1075
|
# s(:return [val])
|
@@ -1134,7 +1098,7 @@ module Opal
|
|
1134
1098
|
if String === p
|
1135
1099
|
p.to_s
|
1136
1100
|
elsif p.first == :evstr
|
1137
|
-
process p.last, :
|
1101
|
+
process p.last, :statement
|
1138
1102
|
elsif p.first == :str
|
1139
1103
|
p.last.to_s
|
1140
1104
|
else
|
@@ -1153,7 +1117,7 @@ module Opal
|
|
1153
1117
|
if String === p
|
1154
1118
|
p.inspect
|
1155
1119
|
elsif p.first == :evstr
|
1156
|
-
process
|
1120
|
+
process p.last, :expression
|
1157
1121
|
elsif p.first == :str
|
1158
1122
|
p.last.inspect
|
1159
1123
|
else
|
@@ -1161,7 +1125,8 @@ module Opal
|
|
1161
1125
|
end
|
1162
1126
|
end
|
1163
1127
|
|
1164
|
-
|
1128
|
+
res = parts.join ' + '
|
1129
|
+
level == :receiver ? "(#{res})" : res
|
1165
1130
|
end
|
1166
1131
|
|
1167
1132
|
def dsym(sexp, level)
|
@@ -1182,19 +1147,19 @@ module Opal
|
|
1182
1147
|
|
1183
1148
|
# s(:if, test, truthy, falsy)
|
1184
1149
|
def if(sexp, level)
|
1185
|
-
test
|
1150
|
+
test = sexp[0]
|
1186
1151
|
truthy = sexp[1]
|
1187
|
-
falsy
|
1152
|
+
falsy = sexp[2]
|
1188
1153
|
|
1189
1154
|
if level == :expression or level == :receiver
|
1190
1155
|
truthy = returns(truthy || s(:nil))
|
1191
1156
|
falsy = returns(falsy || s(:nil))
|
1192
1157
|
end
|
1193
1158
|
|
1194
|
-
code = "if (#{js_truthy test}) {"
|
1195
|
-
indent { code += process(truthy, :statement) } if truthy
|
1196
|
-
indent { code += "} else {#{process falsy, :statement}" } if falsy
|
1197
|
-
code += "
|
1159
|
+
code = "if (#{js_truthy test}) {\n"
|
1160
|
+
indent { code += @indent + process(truthy, :statement) } if truthy
|
1161
|
+
indent { code += "\n#@indent} else {\n#@indent#{process falsy, :statement}" } if falsy
|
1162
|
+
code += "\n#@indent}"
|
1198
1163
|
|
1199
1164
|
code = "(function() { #{code}; return nil; }).call(this)" if level == :expression or level == :receiver
|
1200
1165
|
|
@@ -1237,8 +1202,8 @@ module Opal
|
|
1237
1202
|
}
|
1238
1203
|
end
|
1239
1204
|
|
1240
|
-
code = "(#{tmp} = #{process lhs, :expression}, #{tmp} !== false && "
|
1241
|
-
code += "#{tmp}
|
1205
|
+
code = "((#{tmp} = #{process lhs, :expression}, #{tmp} !== false && "
|
1206
|
+
code += "#{tmp} !== nil) ? #{process rhs, :expression} : #{tmp})"
|
1242
1207
|
@scope.queue_temp tmp
|
1243
1208
|
|
1244
1209
|
code
|
@@ -1258,7 +1223,7 @@ module Opal
|
|
1258
1223
|
end
|
1259
1224
|
|
1260
1225
|
code = "(#{tmp} = #{process lhs, :expression}, #{tmp} !== false && "
|
1261
|
-
code += "#{tmp}
|
1226
|
+
code += "#{tmp} !== nil ? #{tmp} : #{process rhs, :expression})"
|
1262
1227
|
@scope.queue_temp tmp
|
1263
1228
|
|
1264
1229
|
code
|
@@ -1266,25 +1231,35 @@ module Opal
|
|
1266
1231
|
|
1267
1232
|
# s(:yield, arg1, arg2)
|
1268
1233
|
def yield(sexp, level)
|
1234
|
+
# puts sexp.inspect
|
1235
|
+
# puts level.inspect
|
1269
1236
|
@scope.uses_block!
|
1270
1237
|
splat = sexp.any? { |s| s.first == :splat }
|
1271
|
-
sexp.unshift s(:js_tmp, '
|
1238
|
+
# sexp.unshift s(:js_tmp, 'null')
|
1239
|
+
sexp.unshift s(:js_tmp, '__context') unless splat
|
1272
1240
|
args = arglist(sexp, level)
|
1273
1241
|
|
1242
|
+
yielder = @scope.block_name || '__yield'
|
1243
|
+
|
1274
1244
|
call = if splat
|
1275
|
-
"
|
1245
|
+
"#{yielder}.apply(__context, #{args})"
|
1276
1246
|
else
|
1277
|
-
"
|
1247
|
+
"#{yielder}.call(#{args})"
|
1278
1248
|
end
|
1279
1249
|
|
1280
|
-
|
1281
|
-
|
1282
|
-
|
1283
|
-
|
1284
|
-
|
1285
|
-
|
1250
|
+
# FIXME: yield as an expression (when used with js_return) should have the
|
1251
|
+
# right action. We should then warn when used as an expression in other cases
|
1252
|
+
# that we would need to use a try/catch/throw block (which is slow and bad
|
1253
|
+
# mmmkay).
|
1254
|
+
|
1255
|
+
# if level == :receiver or level == :expression
|
1256
|
+
# tmp = @scope.new_temp
|
1257
|
+
# @scope.catches_break!
|
1258
|
+
# code = "((#{tmp} = #{call}) === __breaker ? #{tmp}.$t() : #{tmp})"
|
1259
|
+
# @scope.queue_temp tmp
|
1260
|
+
# else
|
1286
1261
|
code = call
|
1287
|
-
end
|
1262
|
+
# end
|
1288
1263
|
|
1289
1264
|
code
|
1290
1265
|
end
|
@@ -1298,7 +1273,7 @@ module Opal
|
|
1298
1273
|
"break;"
|
1299
1274
|
end
|
1300
1275
|
else
|
1301
|
-
"return (
|
1276
|
+
"return (__breaker.$v = #{val}, __breaker)"
|
1302
1277
|
end
|
1303
1278
|
end
|
1304
1279
|
|
@@ -1379,7 +1354,7 @@ module Opal
|
|
1379
1354
|
# s(:cvar, name)
|
1380
1355
|
def cvar(exp, level)
|
1381
1356
|
tmp = @scope.new_temp
|
1382
|
-
code = "((#{tmp} =
|
1357
|
+
code = "((#{tmp} = Opal.cvars[#{exp.shift.to_s.inspect}]) == null ? null : #{tmp})"
|
1383
1358
|
@scope.queue_temp tmp
|
1384
1359
|
code
|
1385
1360
|
end
|
@@ -1388,11 +1363,11 @@ module Opal
|
|
1388
1363
|
#
|
1389
1364
|
# s(:cvasgn, :@@name, rhs)
|
1390
1365
|
def cvasgn(exp, level)
|
1391
|
-
"(
|
1366
|
+
"(Opal.cvars[#{exp.shift.to_s.inspect}] = #{process exp.shift, :expression})"
|
1392
1367
|
end
|
1393
1368
|
|
1394
1369
|
def cvdecl(exp, level)
|
1395
|
-
"(
|
1370
|
+
"(Opal.cvars[#{exp.shift.to_s.inspect}] = #{process exp.shift, :expression})"
|
1396
1371
|
end
|
1397
1372
|
|
1398
1373
|
# BASE::NAME
|
@@ -1401,11 +1376,11 @@ module Opal
|
|
1401
1376
|
def colon2(sexp, level)
|
1402
1377
|
base = sexp[0]
|
1403
1378
|
name = sexp[1]
|
1404
|
-
"
|
1379
|
+
"Opal.const_get((#{process base, :expression})._scope, #{name.to_s.inspect})"
|
1405
1380
|
end
|
1406
1381
|
|
1407
1382
|
def colon3(exp, level)
|
1408
|
-
"
|
1383
|
+
"Opal.const_get(Opal.Object._scope, #{exp.shift.to_s.inspect})"
|
1409
1384
|
end
|
1410
1385
|
|
1411
1386
|
# super a, b, c
|
@@ -1416,14 +1391,33 @@ module Opal
|
|
1416
1391
|
until sexp.empty?
|
1417
1392
|
args << process(sexp.shift, :expression)
|
1418
1393
|
end
|
1419
|
-
|
1394
|
+
|
1395
|
+
# args.unshift 'null'
|
1396
|
+
|
1397
|
+
js_super "[#{ args.join ', ' }]"
|
1420
1398
|
end
|
1421
1399
|
|
1422
1400
|
# super
|
1423
1401
|
#
|
1424
1402
|
# s(:zsuper)
|
1425
1403
|
def zsuper(exp, level)
|
1426
|
-
|
1404
|
+
|
1405
|
+
js_super "__slice.call(arguments)"
|
1406
|
+
end
|
1407
|
+
|
1408
|
+
def js_super args
|
1409
|
+
if @scope.type == :def
|
1410
|
+
mid = @scope.mid
|
1411
|
+
identity = @scope.identify!
|
1412
|
+
"Opal.zuper(#{identity}, '#{mid}', this, #{args})"
|
1413
|
+
|
1414
|
+
elsif @scope.type == :iter
|
1415
|
+
chain, defn, mid = @scope.get_super_chain
|
1416
|
+
"Opal.dsuper([#{chain.join ', '}], #{defn}, #{mid}, this, #{args})"
|
1417
|
+
|
1418
|
+
else
|
1419
|
+
raise "Cannot call super() from outside a method block"
|
1420
|
+
end
|
1427
1421
|
end
|
1428
1422
|
|
1429
1423
|
# a ||= rhs
|
@@ -1511,7 +1505,7 @@ module Opal
|
|
1511
1505
|
}.join ', '
|
1512
1506
|
err = "true" if err.empty?
|
1513
1507
|
|
1514
|
-
if
|
1508
|
+
if Array === args.last and [:lasgn, :iasgn].include? args.last.first
|
1515
1509
|
val = args.last
|
1516
1510
|
val[2] = s(:js_tmp, "$err")
|
1517
1511
|
val = process(val, :expression) + ";"
|