opal 0.3.21 → 0.3.22
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +1 -4
- data/Gemfile +9 -4
- data/README.md +10 -589
- data/Rakefile +51 -19
- data/config.ru +17 -0
- data/core/array.rb +42 -34
- data/core/basic_object.rb +4 -4
- data/core/browser.js +31 -0
- data/core/class.rb +7 -7
- data/core/enumerable.rb +65 -69
- data/core/erb.rb +30 -0
- data/core/error.rb +2 -3
- data/core/hash.rb +47 -18
- data/core/kernel.rb +15 -16
- data/core/load_order +2 -1
- data/core/module.rb +19 -37
- data/core/numeric.rb +4 -2
- data/core/object.rb +4 -0
- data/core/proc.rb +6 -3
- data/core/racc.rb +215 -0
- data/core/regexp.rb +16 -21
- data/core/runtime.js +141 -153
- data/core/string.rb +41 -19
- data/core/strscan.rb +61 -0
- data/core/time.rb +1 -5
- data/docs/index.md +616 -0
- data/docs/post.html +2 -8
- data/docs/pre.html +29 -26
- data/docs/try.html +52 -0
- data/lib/opal.rb +33 -3
- data/lib/opal/builder.rb +14 -34
- data/lib/opal/erb_parser.rb +19 -0
- data/lib/opal/grammar.rb +7 -3
- data/lib/opal/grammar.y +3 -0
- data/lib/opal/lexer.rb +16 -8
- data/lib/opal/parser.rb +156 -119
- data/lib/opal/rake_task.rb +2 -2
- data/lib/opal/scope.rb +9 -10
- data/lib/opal/version.rb +1 -1
- data/{test → spec}/core/array/allocate_spec.rb +0 -0
- data/{test → spec}/core/array/append_spec.rb +0 -0
- data/{test → spec}/core/array/assoc_spec.rb +0 -0
- data/{test → spec}/core/array/at_spec.rb +0 -0
- data/{test → spec}/core/array/clear_spec.rb +0 -0
- data/{test → spec}/core/array/clone_spec.rb +0 -0
- data/{test → spec}/core/array/collect_spec.rb +0 -0
- data/{test → spec}/core/array/compact_spec.rb +0 -0
- data/{test → spec}/core/array/concat_spec.rb +0 -0
- data/{test → spec}/core/array/constructor_spec.rb +0 -0
- data/{test → spec}/core/array/count_spec.rb +0 -0
- data/{test → spec}/core/array/delete_at_spec.rb +0 -0
- data/{test → spec}/core/array/delete_if_spec.rb +0 -0
- data/{test → spec}/core/array/delete_spec.rb +0 -0
- data/{test → spec}/core/array/each_index_spec.rb +0 -0
- data/{test → spec}/core/array/each_spec.rb +0 -0
- data/{test → spec}/core/array/element_reference_spec.rb +0 -0
- data/{test → spec}/core/array/empty_spec.rb +0 -0
- data/{test → spec}/core/array/eql_spec.rb +0 -0
- data/{test → spec}/core/array/fetch_spec.rb +0 -0
- data/{test → spec}/core/array/first_spec.rb +0 -0
- data/{test → spec}/core/array/flatten_spec.rb +0 -0
- data/{test → spec}/core/array/include_spec.rb +0 -0
- data/{test → spec}/core/array/insert_spec.rb +0 -0
- data/{test → spec}/core/array/last_spec.rb +0 -0
- data/{test → spec}/core/array/length_spec.rb +0 -0
- data/{test → spec}/core/array/map_spec.rb +0 -0
- data/{test → spec}/core/array/minus_spec.rb +0 -0
- data/{test → spec}/core/array/plus_spec.rb +0 -0
- data/{test → spec}/core/array/pop_spec.rb +0 -0
- data/{test → spec}/core/array/push_spec.rb +0 -0
- data/{test → spec}/core/array/rassoc_spec.rb +0 -0
- data/{test → spec}/core/array/reject_spec.rb +0 -0
- data/{test → spec}/core/array/replace_spec.rb +0 -0
- data/{test → spec}/core/array/reverse_each_spec.rb +0 -0
- data/{test → spec}/core/array/reverse_spec.rb +0 -0
- data/{test → spec}/core/array/size_spec.rb +0 -0
- data/{test → spec}/core/array/to_ary_spec.rb +0 -0
- data/{test → spec}/core/array/uniq_spec.rb +0 -0
- data/{test → spec}/core/array/zip_spec.rb +0 -0
- data/{test → spec}/core/class/fixtures/classes.rb +0 -0
- data/{test → spec}/core/class/new_spec.rb +3 -0
- data/{test → spec}/core/enumerable/all_spec.rb +3 -0
- data/{test → spec}/core/enumerable/any_spec.rb +0 -0
- data/{test → spec}/core/enumerable/collect_spec.rb +0 -0
- data/{test → spec}/core/enumerable/count_spec.rb +0 -0
- data/{test → spec}/core/enumerable/detect_spec.rb +0 -0
- data/{test → spec}/core/enumerable/drop_spec.rb +0 -0
- data/{test → spec}/core/enumerable/drop_while_spec.rb +0 -0
- data/{test → spec}/core/enumerable/each_with_index_spec.rb +0 -0
- data/{test → spec}/core/enumerable/each_with_object_spec.rb +0 -0
- data/{test → spec}/core/enumerable/entries_spec.rb +0 -0
- data/{test → spec}/core/enumerable/find_all_spec.rb +0 -0
- data/{test → spec}/core/enumerable/find_index_spec.rb +0 -0
- data/{test → spec}/core/enumerable/find_spec.rb +0 -0
- data/{test → spec}/core/enumerable/first_spec.rb +0 -0
- data/{test → spec}/core/enumerable/fixtures/classes.rb +0 -0
- data/{test → spec}/core/enumerable/grep_spec.rb +0 -0
- data/{test → spec}/core/enumerable/take_spec.rb +0 -0
- data/{test → spec}/core/enumerable/to_a_spec.rb +0 -0
- data/{test → spec}/core/false/and_spec.rb +0 -0
- data/{test → spec}/core/false/inspect_spec.rb +0 -0
- data/{test → spec}/core/false/or_spec.rb +0 -0
- data/{test → spec}/core/false/to_s_spec.rb +0 -0
- data/{test → spec}/core/false/xor_spec.rb +0 -0
- data/{test → spec}/core/hash/allocate_spec.rb +0 -0
- data/{test → spec}/core/hash/assoc_spec.rb +0 -0
- data/{test → spec}/core/hash/clear_spec.rb +0 -0
- data/{test → spec}/core/hash/clone_spec.rb +0 -0
- data/{test → spec}/core/hash/default_spec.rb +0 -0
- data/{test → spec}/core/hash/delete_if_spec.rb +0 -0
- data/{test → spec}/core/hash/each_key_spec.rb +0 -0
- data/{test → spec}/core/hash/each_pair_spec.rb +0 -0
- data/{test → spec}/core/hash/each_spec.rb +0 -0
- data/{test → spec}/core/hash/each_value_spec.rb +0 -0
- data/{test → spec}/core/hash/element_reference_spec.rb +14 -1
- data/{test → spec}/core/hash/element_set_spec.rb +0 -0
- data/{test → spec}/core/hash/empty_spec.rb +0 -0
- data/{test → spec}/core/hash/fetch_spec.rb +0 -0
- data/{test → spec}/core/hash/flatten_spec.rb +0 -0
- data/{test → spec}/core/hash/has_key_spec.rb +0 -0
- data/{test → spec}/core/hash/has_value_spec.rb +0 -0
- data/{test → spec}/core/hash/include_spec.rb +0 -0
- data/{test → spec}/core/hash/index_spec.rb +0 -0
- data/{test → spec}/core/hash/indexes_spec.rb +0 -0
- data/{test → spec}/core/hash/indices_spec.rb +0 -0
- data/{test → spec}/core/hash/invert_spec.rb +0 -0
- data/{test → spec}/core/hash/keep_if_spec.rb +0 -0
- data/{test → spec}/core/hash/key_spec.rb +0 -0
- data/{test → spec}/core/hash/keys_spec.rb +0 -0
- data/{test → spec}/core/hash/length_spec.rb +0 -0
- data/{test → spec}/core/hash/member_spec.rb +0 -0
- data/{test → spec}/core/hash/merge_spec.rb +0 -0
- data/{test → spec}/core/hash/new_spec.rb +8 -0
- data/{test → spec}/core/hash/rassoc_spec.rb +0 -0
- data/{test → spec}/core/hash/replace_spec.rb +0 -0
- data/{test → spec}/core/hash/select_spec.rb +0 -0
- data/{test → spec}/core/hash/shift_spec.rb +0 -0
- data/{test → spec}/core/hash/size_spec.rb +0 -0
- data/{test → spec}/core/hash/update_spec.rb +0 -0
- data/{test → spec}/core/hash/value_spec.rb +0 -0
- data/{test → spec}/core/hash/values_at_spec.rb +0 -0
- data/{test → spec}/core/hash/values_spec.rb +0 -0
- data/{test → spec}/core/kernel/define_singleton_method_spec.rb +0 -0
- data/{test → spec}/core/kernel/eql_spec.rb +0 -0
- data/{test → spec}/core/kernel/equal_value_spec.rb +0 -0
- data/{test → spec}/core/kernel/loop_spec.rb +0 -0
- data/{test → spec}/core/kernel/nil_spec.rb +0 -0
- data/{test → spec}/core/kernel/proc_spec.rb +4 -0
- data/{test → spec}/core/kernel/rand_spec.rb +0 -0
- data/{test → spec}/core/kernel/respond_to_spec.rb +0 -0
- data/{test → spec}/core/kernel/send_spec.rb +0 -0
- data/{test → spec}/core/kernel/tap_spec.rb +0 -0
- data/{test → spec}/core/kernel/to_s_spec.rb +0 -0
- data/{test → spec}/core/matchdata/to_a_spec.rb +0 -0
- data/{test → spec}/core/nil/and_spec.rb +0 -0
- data/{test → spec}/core/nil/inspect_spec.rb +0 -0
- data/{test → spec}/core/nil/nil_spec.rb +0 -0
- data/{test → spec}/core/nil/or_spec.rb +0 -0
- data/{test → spec}/core/nil/to_a_spec.rb +0 -0
- data/{test → spec}/core/nil/to_f_spec.rb +0 -0
- data/{test → spec}/core/nil/to_i_spec.rb +0 -0
- data/{test → spec}/core/nil/to_s_spec.rb +0 -0
- data/{test → spec}/core/nil/xor_spec.rb +0 -0
- data/{test → spec}/core/numeric/equal_value_spec.rb +0 -0
- data/spec/core/proc/proc_tricks_spec.rb +7 -0
- data/{test → spec}/core/range/begin_spec.rb +0 -0
- data/{test → spec}/core/range/case_compare_spec.rb +0 -0
- data/{test → spec}/core/range/end_spec.rb +0 -0
- data/{test → spec}/core/regexp/match_spec.rb +0 -0
- data/{test → spec}/core/string/capitalize_spec.rb +0 -0
- data/{test → spec}/core/string/casecmp_spec.rb +0 -0
- data/{test → spec}/core/string/chomp_spec.rb +0 -0
- data/{test → spec}/core/string/chop_spec.rb +0 -0
- data/{test → spec}/core/string/chr_spec.rb +0 -0
- data/{test → spec}/core/string/comparison_spec.rb +0 -0
- data/{test → spec}/core/string/downcase_spec.rb +0 -0
- data/{test → spec}/core/string/element_reference_spec.rb +14 -2
- data/{test → spec}/core/string/empty_spec.rb +0 -0
- data/{test → spec}/core/string/end_with_spec.rb +0 -0
- data/{test → spec}/core/string/fixtures/classes.rb +0 -0
- data/{test → spec}/core/string/gsub_spec.rb +0 -0
- data/{test → spec}/core/string/include_spec.rb +0 -0
- data/{test → spec}/core/string/intern_spec.rb +0 -0
- data/{test → spec}/core/string/length_spec.rb +0 -0
- data/{test → spec}/core/string/lstrip_spec.rb +0 -0
- data/{test → spec}/core/string/match_spec.rb +0 -0
- data/{test → spec}/core/string/next_spec.rb +0 -0
- data/{test → spec}/core/string/ord_spec.rb +0 -0
- data/{test → spec}/core/string/partition_spec.rb +0 -0
- data/{test → spec}/core/string/reverse_spec.rb +0 -0
- data/{test → spec}/core/string/rstrip_spec.rb +0 -0
- data/{test → spec}/core/string/size_spec.rb +0 -0
- data/{test → spec}/core/string/slice_spec.rb +4 -1
- data/{test → spec}/core/string/split_spec.rb +0 -0
- data/{test → spec}/core/string/start_with_spec.rb +0 -0
- data/{test → spec}/core/string/strip_spec.rb +0 -0
- data/{test → spec}/core/string/sub_spec.rb +0 -0
- data/{test → spec}/core/string/succ_spec.rb +0 -0
- data/{test → spec}/core/string/sum_spec.rb +0 -0
- data/{test → spec}/core/string/swapcase_spec.rb +0 -0
- data/{test → spec}/core/string/to_a_spec.rb +0 -0
- data/{test → spec}/core/string/to_f_spec.rb +0 -0
- data/{test → spec}/core/string/to_i_spec.rb +0 -0
- data/{test → spec}/core/string/to_s_spec.rb +0 -0
- data/{test → spec}/core/string/to_str_spec.rb +0 -0
- data/{test → spec}/core/string/to_sym_spec.rb +0 -0
- data/{test → spec}/core/string/upcase_spec.rb +0 -0
- data/{test → spec}/core/symbol/to_proc_spec.rb +0 -0
- data/{test → spec}/core/time/at_spec.rb +0 -0
- data/{test → spec}/core/time/day_spec.rb +0 -0
- data/{test → spec}/core/time/friday_spec.rb +0 -0
- data/{test → spec}/core/time/hour_spec.rb +0 -0
- data/{test → spec}/core/time/min_spec.rb +0 -0
- data/{test → spec}/core/time/monday_spec.rb +0 -0
- data/{test → spec}/core/time/month_spec.rb +0 -0
- data/{test → spec}/core/time/now_spec.rb +0 -0
- data/{test → spec}/core/time/saturday_spec.rb +0 -0
- data/{test → spec}/core/true/and_spec.rb +0 -0
- data/{test → spec}/core/true/inspect_spec.rb +0 -0
- data/{test → spec}/core/true/or_spec.rb +0 -0
- data/{test → spec}/core/true/to_s_spec.rb +0 -0
- data/{test → spec}/core/true/xor_spec.rb +0 -0
- data/spec/grammar/lvar_spec.rb +2 -1
- data/spec/grammar/str_spec.rb +1 -1
- data/spec/grammar/xstr_spec.rb +1 -1
- data/{test → spec}/index.html +3 -3
- data/{test → spec}/language/alias_spec.rb +0 -0
- data/{test → spec}/language/and_spec.rb +0 -0
- data/{test → spec}/language/array_spec.rb +0 -0
- data/{test → spec}/language/block_spec.rb +0 -0
- data/{test → spec}/language/break_spec.rb +0 -0
- data/{test → spec}/language/case_spec.rb +0 -0
- data/{test → spec}/language/defined_spec.rb +0 -0
- data/{test → spec}/language/ensure_spec.rb +2 -2
- data/{test → spec}/language/fixtures/next.rb +0 -0
- data/{test → spec}/language/fixtures/yield.rb +0 -0
- data/{test → spec}/language/hash_spec.rb +0 -0
- data/{test → spec}/language/if_spec.rb +0 -0
- data/{test → spec}/language/literal_lambda_spec.rb +0 -0
- data/{test → spec}/language/loop_spec.rb +0 -0
- data/{test → spec}/language/metaclass_spec.rb +0 -0
- data/{test → spec}/language/next_spec.rb +2 -0
- data/{test → spec}/language/or_spec.rb +0 -0
- data/{test → spec}/language/predefined_spec.rb +0 -0
- data/{test → spec}/language/regexp_spec.rb +0 -0
- data/{test → spec}/language/send_spec.rb +0 -0
- data/{test → spec}/language/singleton_class_spec.rb +0 -0
- data/{test → spec}/language/super_spec.rb +0 -0
- data/{test → spec}/language/symbol_spec.rb +0 -0
- data/{test → spec}/language/undef_spec.rb +0 -0
- data/{test → spec}/language/unless_spec.rb +0 -0
- data/{test → spec}/language/until_spec.rb +0 -0
- data/{test → spec}/language/variables_spec.rb +0 -0
- data/{test → spec}/language/while_spec.rb +0 -0
- data/{test → spec}/language/yield_spec.rb +2 -0
- data/{test → spec}/opal/array/subclassing_spec.rb +0 -0
- data/{test → spec}/opal/array/to_json_spec.rb +0 -0
- data/{test → spec}/opal/boolean/singleton_class_spec.rb +0 -0
- data/{test → spec}/opal/boolean/to_json_spec.rb +0 -0
- data/{test → spec}/opal/class/bridge_class_spec.rb +0 -0
- data/spec/opal/erb/erb_spec.rb +15 -0
- data/{test → spec}/opal/exception/subclassing_spec.rb +0 -0
- data/{test → spec}/opal/hash/to_json_spec.rb +0 -0
- data/spec/opal/hash/to_native_spec.rb +5 -0
- data/{test → spec}/opal/json/parse_spec.rb +0 -0
- data/{test → spec}/opal/kernel/to_json_spec.rb +0 -0
- data/{test → spec}/opal/nil/to_json_spec.rb +0 -0
- data/{test → spec}/opal/numeric/to_json_spec.rb +0 -0
- data/{test → spec}/opal/runtime/call_spec.rb +0 -0
- data/{test → spec}/opal/runtime/class_hierarchy_spec.rb +0 -0
- data/{test → spec}/opal/runtime/def_spec.rb +0 -0
- data/{test → spec}/opal/runtime/defined_spec.rb +0 -0
- data/{test → spec}/opal/runtime/method_missing_spec.rb +3 -3
- data/{test → spec}/opal/runtime/super_spec.rb +0 -0
- data/{test → spec}/opal/string/subclassing_spec.rb +0 -0
- data/{test → spec}/opal/string/to_json_spec.rb +0 -0
- data/spec/opal/strscan/check_spec.rb +13 -0
- data/spec/opal/strscan/scan_spec.rb +33 -0
- data/spec/parser/simple_spec.rb +44 -0
- data/spec/spec_helper.rb +7 -7
- metadata +487 -497
- data/core/dir.rb +0 -89
- data/core/file.rb +0 -85
- data/spec/browser_spec.rb +0 -28
- data/spec/builder/fixtures/build_source/adam.rb +0 -0
- data/spec/builder/fixtures/build_source/bar/a.rb +0 -0
- data/spec/builder/fixtures/build_source/bar/wow/b.rb +0 -0
- data/spec/builder/fixtures/build_source/bar/wow/cow/c.rb +0 -0
- data/spec/builder/fixtures/build_source/beynon.rb +0 -0
- data/spec/builder/fixtures/build_source/charles.js +0 -0
- data/spec/builder/fixtures/build_source/foo/a.rb +0 -0
- data/spec/builder/fixtures/build_source/foo/b.rb +0 -0
- data/spec/builder/fixtures/build_source/foo/x.js +0 -0
- data/spec/builder/fixtures/build_source/foo/y.js +0 -0
- data/spec/builder/lib_name_for_spec.rb +0 -19
- data/test/index.min.html +0 -12
- data/test/spec_helper.rb +0 -4
data/docs/post.html
CHANGED
data/docs/pre.html
CHANGED
@@ -1,32 +1,35 @@
|
|
1
1
|
<!doctype html>
|
2
2
|
<html>
|
3
|
-
|
4
|
-
|
5
|
-
<meta http-equiv="X-UA-Compatible" content="chrome=1">
|
6
|
-
<title>Opal by adambeynon</title>
|
3
|
+
<head>
|
4
|
+
<title>Opal: Ruby to Javascript compiler</title>
|
7
5
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
<![endif]-->
|
15
|
-
</head>
|
16
|
-
<body>
|
17
|
-
<div class="wrapper">
|
18
|
-
<header>
|
19
|
-
<h1 class="header">Opal</h1>
|
20
|
-
<p class="header">Ruby runtime and library on top of Javascript</p>
|
6
|
+
<link href="/stylesheets/bootstrap.css" rel="stylesheet">
|
7
|
+
<link href="/stylesheets/pygment_trac.css" rel="stylesheet">
|
8
|
+
<style>
|
9
|
+
body {
|
10
|
+
padding-top: 92px;
|
11
|
+
}
|
21
12
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
13
|
+
.main-title {
|
14
|
+
padding-bottom: 32px;
|
15
|
+
}
|
16
|
+
</style>
|
17
|
+
</head>
|
18
|
+
<body>
|
19
|
+
<!-- nav -->
|
20
|
+
<div class="navbar navbar-fixed-top">
|
21
|
+
<div class="navbar-inner">
|
22
|
+
<div class="container">
|
23
|
+
<a class="brand" href="http://opalrb.org">
|
24
|
+
Opal
|
25
|
+
</a>
|
26
|
+
<ul class="nav">
|
27
|
+
<li><a href="/index.html">Home</a></li>
|
28
|
+
<li><a href="/try.html">Try Opal</a></li>
|
26
29
|
</ul>
|
30
|
+
</div>
|
31
|
+
</div>
|
32
|
+
</div>
|
27
33
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
</header>
|
32
|
-
<section>
|
34
|
+
<!-- body -->
|
35
|
+
<div class="container">
|
data/docs/try.html
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
<div class="row-fluid" id="wrapper">
|
2
|
+
<div id="editor_wrapper" class="span6">
|
3
|
+
<div id="editor"></div>
|
4
|
+
<br />
|
5
|
+
<a href="#" id="run_code" class="btn btn-primary">Compile</a>
|
6
|
+
</div>
|
7
|
+
|
8
|
+
<div id="viewer_wrapper" class="span6">
|
9
|
+
<div id="viewer"></div>
|
10
|
+
</div>
|
11
|
+
</div>
|
12
|
+
|
13
|
+
|
14
|
+
<script src="/javascripts/codemirror.js"></script>
|
15
|
+
<script src="/javascripts/ruby.js"></script>
|
16
|
+
<script src="/javascripts/javascript.js"></script>
|
17
|
+
<link href="/stylesheets/codemirror.css" rel="stylesheet">
|
18
|
+
<script src="/opal.js"></script>
|
19
|
+
<script src="/opal-parser.js"></script>
|
20
|
+
|
21
|
+
<script>
|
22
|
+
var viewer = CodeMirror(document.getElementById("viewer"), {
|
23
|
+
lineNumbers: true,
|
24
|
+
mode: "javascript",
|
25
|
+
readOnly: true
|
26
|
+
});
|
27
|
+
var editor = CodeMirror(document.getElementById("editor"), {
|
28
|
+
lineNumbers: true,
|
29
|
+
mode: "ruby",
|
30
|
+
tabMode: "shift"
|
31
|
+
});
|
32
|
+
|
33
|
+
var run = document.getElementById('run_code');
|
34
|
+
|
35
|
+
if (run.addEventListener) {
|
36
|
+
run.addEventListener('click', compile, false);
|
37
|
+
}
|
38
|
+
else {
|
39
|
+
run.attachEvent('onclick', compile);
|
40
|
+
}
|
41
|
+
// Initialize
|
42
|
+
editor.setValue("[1, 2, 3, 4].each do |a|\n puts a\nend\n\nclass Foo\n attr_reader :name\nend\n\nadam = Foo.new\nadam.name = 'Adam Beynon'\nputs adam.name");
|
43
|
+
// Functions to update editor and viewer content
|
44
|
+
function compile() {
|
45
|
+
try {
|
46
|
+
viewer.setValue(Opal.Opal.Parser.$new().$parse(editor.getValue()));
|
47
|
+
}
|
48
|
+
catch (err) {
|
49
|
+
}
|
50
|
+
return false;
|
51
|
+
}
|
52
|
+
</script>
|
data/lib/opal.rb
CHANGED
@@ -1,4 +1,15 @@
|
|
1
|
+
unless Symbol.instance_methods.include?(:[])
|
2
|
+
unless String == Symbol
|
3
|
+
class Symbol
|
4
|
+
def []key
|
5
|
+
to_s[key]
|
6
|
+
end
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
1
11
|
require 'opal/parser'
|
12
|
+
require 'opal/erb_parser'
|
2
13
|
require 'opal/builder'
|
3
14
|
require 'opal/version'
|
4
15
|
|
@@ -25,7 +36,26 @@ module Opal
|
|
25
36
|
#
|
26
37
|
# @return [String] returns opal runtime/corelib as a string
|
27
38
|
def self.runtime
|
28
|
-
|
39
|
+
core_dir = Opal.core_dir
|
40
|
+
load_order = File.join core_dir, 'load_order'
|
41
|
+
corelib = File.read(load_order).strip.split.map do |c|
|
42
|
+
File.read File.join(core_dir, "#{c}.rb")
|
43
|
+
end
|
44
|
+
|
45
|
+
runtime = File.read(File.join core_dir, 'runtime.js')
|
46
|
+
corelib = Opal.parse corelib.join("\n"), '(corelib)'
|
47
|
+
|
48
|
+
[
|
49
|
+
"// Opal v#{Opal::VERSION}",
|
50
|
+
"// http://opalrb.org",
|
51
|
+
"// Copyright 2012, Adam Beynon",
|
52
|
+
"// Released under the MIT License",
|
53
|
+
"(function(undefined) {",
|
54
|
+
runtime,
|
55
|
+
"Opal.version = #{ Opal::VERSION.inspect };",
|
56
|
+
corelib,
|
57
|
+
"}).call(this);"
|
58
|
+
].join("\n")
|
29
59
|
end
|
30
60
|
|
31
61
|
# Build gem with given name to a string.
|
@@ -40,7 +70,7 @@ module Opal
|
|
40
70
|
# @return [String] returns built gem
|
41
71
|
def self.build_gem(name)
|
42
72
|
spec = Gem::Specification.find_by_name name
|
43
|
-
Builder.
|
73
|
+
Builder.new(:files => spec.require_paths, :dir => spec.full_gem_path).build
|
44
74
|
end
|
45
75
|
|
46
76
|
# Build the given files. Files should be a string of either a full
|
@@ -52,7 +82,7 @@ module Opal
|
|
52
82
|
# @param [String] files files to build
|
53
83
|
# @return [String]
|
54
84
|
def self.build_files(files)
|
55
|
-
Builder.
|
85
|
+
Builder.new(:files => files).build
|
56
86
|
end
|
57
87
|
|
58
88
|
def self.opal_dir
|
data/lib/opal/builder.rb
CHANGED
@@ -1,33 +1,9 @@
|
|
1
|
-
require '
|
1
|
+
require 'opal/parser'
|
2
2
|
|
3
3
|
module Opal
|
4
|
-
class Builder
|
5
|
-
def self.runtime
|
6
|
-
core_dir = Opal.core_dir
|
7
|
-
load_order = File.join core_dir, 'load_order'
|
8
|
-
corelib = File.read(load_order).strip.split.map do |c|
|
9
|
-
File.read File.join(core_dir, "#{c}.rb")
|
10
|
-
end
|
11
|
-
|
12
|
-
runtime = File.read(File.join core_dir, 'runtime.js')
|
13
|
-
corelib = Opal.parse corelib.join("\n"), '(corelib)'
|
14
|
-
|
15
|
-
[
|
16
|
-
"// Opal v#{Opal::VERSION}",
|
17
|
-
"// http://opalrb.org",
|
18
|
-
"// Copyright 2012, Adam Beynon",
|
19
|
-
"// Released under the MIT License",
|
20
|
-
"(function(undefined) {",
|
21
|
-
runtime,
|
22
|
-
"Opal.version = #{ Opal::VERSION.inspect };",
|
23
|
-
corelib,
|
24
|
-
"}).call(this);"
|
25
|
-
].join("\n")
|
26
|
-
end
|
27
4
|
|
28
|
-
|
29
|
-
|
30
|
-
end
|
5
|
+
# Used to build gems/libs/directories of opal code
|
6
|
+
class Builder
|
31
7
|
|
32
8
|
def initialize(options = {})
|
33
9
|
@sources = Array(options[:files])
|
@@ -54,8 +30,8 @@ module Opal
|
|
54
30
|
sources.each do |s|
|
55
31
|
s = File.join @dir, s
|
56
32
|
if File.directory? s
|
57
|
-
files.push *Dir[File.join
|
58
|
-
elsif
|
33
|
+
files.push *Dir[File.join(s, '**/*.{rb,js,erb}')]
|
34
|
+
elsif %w(.rb .js .erb).include? File.extname(s)
|
59
35
|
files << s
|
60
36
|
end
|
61
37
|
end
|
@@ -92,9 +68,13 @@ module Opal
|
|
92
68
|
parser_name = parser_name_for file
|
93
69
|
|
94
70
|
if File.extname(file) == '.rb'
|
95
|
-
code = @parser.parse File.read(file),
|
71
|
+
code = @parser.parse File.read(file), lib_name
|
96
72
|
@requires[lib_name] = @parser.requires
|
97
|
-
|
73
|
+
elsif File.extname(file) == '.erb'
|
74
|
+
template_name = File.basename(file).chomp(File.extname(file))
|
75
|
+
code = Opal::ERBParser.new.parse File.read(file), template_name
|
76
|
+
@requires[lib_name] = []
|
77
|
+
else # javascript
|
98
78
|
code = "function() {\n #{ File.read file }\n}"
|
99
79
|
@requires[lib_name] = []
|
100
80
|
end
|
@@ -103,13 +83,13 @@ module Opal
|
|
103
83
|
end
|
104
84
|
|
105
85
|
def parser_name_for(file)
|
106
|
-
file.sub
|
86
|
+
file.sub(/^#{@dir}\//, '')
|
107
87
|
end
|
108
88
|
|
109
89
|
def lib_name_for(file)
|
110
|
-
file = file.sub
|
90
|
+
file = file.sub(/^#{@dir}\//, '')
|
111
91
|
file = file.chomp File.extname(file)
|
112
|
-
file.sub
|
92
|
+
file.sub(/^(lib|spec)\//, '')
|
113
93
|
end
|
114
94
|
end
|
115
95
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'opal/parser'
|
2
|
+
|
3
|
+
module Opal
|
4
|
+
class ERBParser
|
5
|
+
|
6
|
+
def parse(str, name = 'erb')
|
7
|
+
Parser.new.parse compile(str, name)
|
8
|
+
end
|
9
|
+
|
10
|
+
def compile(str, name)
|
11
|
+
res = "ERB.new('#{name}') do\nout = []\nout.<<(\"" +
|
12
|
+
str.gsub(/<%=([\s\S]+?)%>/) do
|
13
|
+
"\")\nout.<<(" + $1.gsub(/\\'/, "'") + ")\nout.<<(\""
|
14
|
+
end.gsub(/<%([\s\S]+?)%>/) do
|
15
|
+
"\")\n" + $1 + "\nout.<<(\""
|
16
|
+
end + "\")\nout.join\nend"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/opal/grammar.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
#
|
2
2
|
# DO NOT MODIFY!!!!
|
3
|
-
# This file is automatically generated by Racc 1.4.
|
3
|
+
# This file is automatically generated by Racc 1.4.9
|
4
4
|
# from Racc grammer file "".
|
5
5
|
#
|
6
6
|
|
@@ -2045,7 +2045,7 @@ racc_reduce_table = [
|
|
2045
2045
|
3, 163, :_reduce_206,
|
2046
2046
|
3, 163, :_reduce_207,
|
2047
2047
|
3, 163, :_reduce_208,
|
2048
|
-
3, 163, :
|
2048
|
+
3, 163, :_reduce_209,
|
2049
2049
|
5, 163, :_reduce_210,
|
2050
2050
|
1, 163, :_reduce_none,
|
2051
2051
|
1, 160, :_reduce_none,
|
@@ -3609,7 +3609,11 @@ def _reduce_208(val, _values, result)
|
|
3609
3609
|
result
|
3610
3610
|
end
|
3611
3611
|
|
3612
|
-
|
3612
|
+
def _reduce_209(val, _values, result)
|
3613
|
+
result = s(:defined, val[2])
|
3614
|
+
|
3615
|
+
result
|
3616
|
+
end
|
3613
3617
|
|
3614
3618
|
def _reduce_210(val, _values, result)
|
3615
3619
|
result = s(:if, val[0], val[2], val[4])
|
data/lib/opal/grammar.y
CHANGED
data/lib/opal/lexer.rb
CHANGED
@@ -1,10 +1,18 @@
|
|
1
1
|
require 'opal/grammar'
|
2
2
|
require 'strscan'
|
3
3
|
|
4
|
+
class Array
|
5
|
+
attr_accessor :line
|
6
|
+
attr_accessor :end_line
|
7
|
+
end
|
8
|
+
|
4
9
|
module Opal
|
5
|
-
|
10
|
+
Sexp = ::Array
|
6
11
|
|
7
|
-
|
12
|
+
# Any exceptions with parsing of file will raise this error
|
13
|
+
class OpalParseError < Exception; end
|
14
|
+
|
15
|
+
class Grammar < Racc::Parser
|
8
16
|
|
9
17
|
attr_reader :line
|
10
18
|
|
@@ -18,14 +26,13 @@ module Opal
|
|
18
26
|
@string_parse_stack = []
|
19
27
|
end
|
20
28
|
|
21
|
-
def s
|
22
|
-
sexp = parts
|
29
|
+
def s(*parts)
|
30
|
+
sexp = Sexp.new(parts)
|
23
31
|
sexp.line = @line
|
24
32
|
sexp
|
25
33
|
end
|
26
34
|
|
27
|
-
def parse
|
28
|
-
#puts "============"
|
35
|
+
def parse(source, file = '(string)')
|
29
36
|
@file = file
|
30
37
|
@scanner = StringScanner.new source
|
31
38
|
push_scope
|
@@ -90,7 +97,7 @@ module Opal
|
|
90
97
|
end
|
91
98
|
end
|
92
99
|
|
93
|
-
def new_body
|
100
|
+
def new_body(compstmt, res, els, ens)
|
94
101
|
s = compstmt || s(:block)
|
95
102
|
|
96
103
|
if compstmt
|
@@ -444,7 +451,6 @@ module Opal
|
|
444
451
|
def next_token
|
445
452
|
t = get_next_token
|
446
453
|
# puts "returning token #{t.inspect}"
|
447
|
-
# t[1] = { :value => t[1], :line => @line }
|
448
454
|
t
|
449
455
|
end
|
450
456
|
|
@@ -625,6 +631,8 @@ module Opal
|
|
625
631
|
"\n"
|
626
632
|
elsif scanner.scan(/r/)
|
627
633
|
"\r"
|
634
|
+
elsif scanner.scan(/\n/)
|
635
|
+
"\n"
|
628
636
|
else
|
629
637
|
# escaped char doesnt need escaping, so just return it
|
630
638
|
scanner.scan(/./)
|
data/lib/opal/parser.rb
CHANGED
@@ -2,13 +2,7 @@ require 'opal/lexer'
|
|
2
2
|
require 'opal/grammar'
|
3
3
|
require 'opal/scope'
|
4
4
|
|
5
|
-
class Array
|
6
|
-
attr_accessor :line
|
7
|
-
attr_accessor :end_line
|
8
|
-
end
|
9
|
-
|
10
5
|
module Opal
|
11
|
-
class OpalParseError < Exception; end
|
12
6
|
|
13
7
|
class Parser
|
14
8
|
INDENT = ' '
|
@@ -32,25 +26,20 @@ module Opal
|
|
32
26
|
|
33
27
|
attr_reader :requires
|
34
28
|
|
35
|
-
def self.parse(str)
|
36
|
-
self.new.parse str
|
37
|
-
end
|
38
|
-
|
39
|
-
def initialize(opts = {})
|
40
|
-
@debug = true if opts[:debug]
|
41
|
-
end
|
42
|
-
|
43
29
|
def parse(source, file = '(file)')
|
44
|
-
@
|
30
|
+
@grammar = Grammar.new
|
45
31
|
@requires = []
|
32
|
+
@file = file
|
33
|
+
@line = 1
|
34
|
+
@indent = ''
|
35
|
+
@unique = 0
|
36
|
+
|
46
37
|
@helpers = {
|
47
|
-
:breaker
|
48
|
-
:slice
|
49
|
-
:mm
|
38
|
+
:breaker => true,
|
39
|
+
:slice => true,
|
40
|
+
:mm => true
|
50
41
|
}
|
51
42
|
|
52
|
-
@grammar = Grammar.new
|
53
|
-
reset
|
54
43
|
top @grammar.parse(source, file)
|
55
44
|
end
|
56
45
|
|
@@ -67,22 +56,16 @@ module Opal
|
|
67
56
|
end
|
68
57
|
|
69
58
|
def s(*parts)
|
70
|
-
sexp = parts
|
59
|
+
sexp = Sexp.new(parts)
|
71
60
|
sexp.line = @line
|
72
61
|
sexp
|
73
62
|
end
|
74
63
|
|
75
|
-
def reset
|
76
|
-
@line = 1
|
77
|
-
@indent = ''
|
78
|
-
@unique = 0
|
79
|
-
end
|
80
|
-
|
81
64
|
def mid_to_jsid(mid)
|
82
65
|
if RESERVED.include?(mid) or /\=|\+|\-|\*|\/|\!|\?|\<|\>|\&|\||\^|\%|\~|\[/ =~ mid.to_s
|
83
|
-
"['
|
66
|
+
"['$#{mid}']"
|
84
67
|
else
|
85
|
-
'
|
68
|
+
'.$' + mid
|
86
69
|
end
|
87
70
|
end
|
88
71
|
|
@@ -104,7 +87,7 @@ module Opal
|
|
104
87
|
vars << "self = __opal.top"
|
105
88
|
vars << "__scope = __opal"
|
106
89
|
vars << "nil = __opal.nil"
|
107
|
-
vars << "def = #{current_self}
|
90
|
+
vars << "def = #{current_self}._klass.prototype" if @scope.defines_defn
|
108
91
|
vars.concat @helpers.keys.map { |h| "__#{h} = __opal.#{h}" }
|
109
92
|
|
110
93
|
code = "#{INDENT}var #{vars.join ', '};\n" + INDENT + @scope.to_vars + "\n" + code
|
@@ -140,6 +123,12 @@ module Opal
|
|
140
123
|
res
|
141
124
|
end
|
142
125
|
|
126
|
+
# Should be overriden in custom parsers to handle a require
|
127
|
+
# statement.
|
128
|
+
def handle_require(arglist)
|
129
|
+
"/* require statement removed */"
|
130
|
+
end
|
131
|
+
|
143
132
|
# Used when we enter a while statement. This pushes onto the current
|
144
133
|
# scope's while stack so we know how to handle break, next etc.
|
145
134
|
#
|
@@ -227,14 +216,49 @@ module Opal
|
|
227
216
|
|
228
217
|
until sexp.empty?
|
229
218
|
stmt = sexp.shift
|
219
|
+
type = stmt.first
|
220
|
+
|
221
|
+
# find any inline yield statements
|
222
|
+
if yasgn = find_inline_yield(stmt)
|
223
|
+
result << "#{process(yasgn, level)};"
|
224
|
+
end
|
225
|
+
|
230
226
|
expr = expression?(stmt) and LEVEL.index(level) < LEVEL.index(:list)
|
231
227
|
code = process(stmt, level)
|
232
|
-
result << (expr ? "#{code};" : code)
|
228
|
+
result << (expr ? "#{code};" : code) unless code == ""
|
233
229
|
end
|
234
230
|
|
235
231
|
result.join(@scope.class_scope? ? "\n\n#@indent" : "\n#@indent")
|
236
232
|
end
|
237
233
|
|
234
|
+
def find_inline_yield(stmt)
|
235
|
+
found = nil
|
236
|
+
case stmt.first
|
237
|
+
when :js_return
|
238
|
+
found = find_inline_yield stmt[1]
|
239
|
+
when :array
|
240
|
+
stmt[1..-1].each_with_index do |el, idx|
|
241
|
+
if el.first == :yield
|
242
|
+
found = el
|
243
|
+
stmt[idx+1] = s(:js_tmp, '__yielded')
|
244
|
+
end
|
245
|
+
end
|
246
|
+
when :call
|
247
|
+
arglist = stmt[3]
|
248
|
+
arglist[1..-1].each_with_index do |el, idx|
|
249
|
+
if el.first == :yield
|
250
|
+
found = el
|
251
|
+
arglist[idx+1] = s(:js_tmp, '__yielded')
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
if found
|
257
|
+
@scope.add_temp '__yielded' unless @scope.has_temp? '__yielded'
|
258
|
+
s(:yasgn, '__yielded', found)
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
238
262
|
def process_scope(sexp, level)
|
239
263
|
stmt = sexp.shift
|
240
264
|
if stmt
|
@@ -266,8 +290,8 @@ module Opal
|
|
266
290
|
l = process recv, :expr
|
267
291
|
r = process arg, :expr
|
268
292
|
|
269
|
-
"(%s = %s, %s = %s, typeof(%s) === 'number' ? %s %s %s : %s
|
270
|
-
[a, l, b, r, a, a, meth.to_s, b, a, mid,
|
293
|
+
"(%s = %s, %s = %s, typeof(%s) === 'number' ? %s %s %s : %s%s(%s))" %
|
294
|
+
[a, l, b, r, a, a, meth.to_s, b, a, mid, b]
|
271
295
|
end
|
272
296
|
end
|
273
297
|
end
|
@@ -336,7 +360,8 @@ module Opal
|
|
336
360
|
str = sexp.shift
|
337
361
|
if str == @file
|
338
362
|
@uses_file = true
|
339
|
-
"'FILE'"
|
363
|
+
# "'FILE'"
|
364
|
+
@file.inspect
|
340
365
|
else
|
341
366
|
str.inspect
|
342
367
|
end
|
@@ -356,9 +381,11 @@ module Opal
|
|
356
381
|
when :call
|
357
382
|
mid = mid_to_jsid part[2].to_s
|
358
383
|
recv = part[1] ? process(part[1], :expr) : current_self
|
359
|
-
"(#{recv}
|
384
|
+
"(#{recv}#{mid} ? 'method' : nil)"
|
360
385
|
when :xstr
|
361
386
|
"(typeof(#{process part, :expression}) !== 'undefined')"
|
387
|
+
when :colon2
|
388
|
+
"false"
|
362
389
|
else
|
363
390
|
raise "bad defined? part: #{part[0]}"
|
364
391
|
end
|
@@ -412,7 +439,7 @@ module Opal
|
|
412
439
|
|
413
440
|
if splat
|
414
441
|
params << splat
|
415
|
-
code += "#{splat} = __slice.call(arguments, #{len});"
|
442
|
+
code += "#{splat} = __slice.call(arguments, #{len - 1});"
|
416
443
|
end
|
417
444
|
|
418
445
|
if block_arg
|
@@ -431,7 +458,7 @@ module Opal
|
|
431
458
|
code += "\n#@indent" + process(body, :stmt)
|
432
459
|
|
433
460
|
if @scope.defines_defn
|
434
|
-
@scope.add_temp
|
461
|
+
@scope.add_temp "def = (#{current_self}._isObject ? #{current_self} : #{current_self}.prototype)"
|
435
462
|
end
|
436
463
|
|
437
464
|
code = "\n#@indent#{@scope.to_vars}\n#@indent#{code}"
|
@@ -451,7 +478,7 @@ module Opal
|
|
451
478
|
end
|
452
479
|
|
453
480
|
def js_block_args(sexp)
|
454
|
-
|
481
|
+
sexp.map do |arg|
|
455
482
|
a = arg[1].to_sym
|
456
483
|
a = "#{a}$".to_sym if RESERVED.include? a.to_s
|
457
484
|
@scope.add_arg a
|
@@ -530,60 +557,56 @@ module Opal
|
|
530
557
|
when :alias_native
|
531
558
|
return handle_alias_native(sexp) if @scope.class_scope?
|
532
559
|
when :require
|
560
|
+
# return handle_require(arglist)
|
533
561
|
path = arglist[1]
|
534
562
|
|
535
563
|
if path and path[0] == :str
|
536
|
-
|
537
|
-
@requires << path_name
|
538
|
-
return ""
|
539
|
-
else
|
540
|
-
# warn "Opal cannot do dynamic requires"
|
541
|
-
return ""
|
564
|
+
@requires << path[1]
|
542
565
|
end
|
566
|
+
|
567
|
+
return "//= require #{path[1]}"
|
543
568
|
end
|
544
569
|
|
545
570
|
splat = arglist[1..-1].any? { |a| a.first == :splat }
|
546
571
|
|
547
|
-
if
|
572
|
+
if Sexp === arglist.last and arglist.last.first == :block_pass
|
548
573
|
block = process s(:js_tmp, process(arglist.pop, :expr)), :expr
|
549
574
|
elsif iter
|
550
575
|
block = iter
|
551
576
|
end
|
552
577
|
|
553
|
-
recv ||=
|
578
|
+
recv ||= s(:self)
|
554
579
|
|
555
580
|
if block
|
556
|
-
|
581
|
+
tmprecv = @scope.new_temp
|
557
582
|
elsif splat and recv != [:self] and recv[0] != :lvar
|
558
|
-
|
583
|
+
tmprecv = @scope.new_temp
|
559
584
|
end
|
560
585
|
|
561
586
|
args = ""
|
562
587
|
|
563
|
-
|
564
|
-
recv_code = process recv, :recv
|
588
|
+
recv_code = process recv, :recv
|
565
589
|
|
566
|
-
|
567
|
-
args = process arglist, :expr
|
590
|
+
args = process arglist, :expr
|
568
591
|
|
569
|
-
|
570
|
-
|
571
|
-
|
592
|
+
result = if block
|
593
|
+
dispatch = "(%s = %s, %s%s._p = %s, %s%s" %
|
594
|
+
[tmprecv, recv_code, tmprecv, mid, block, tmprecv, mid]
|
572
595
|
|
573
|
-
|
574
|
-
|
575
|
-
else
|
576
|
-
"%s(%s))" % [dispatch, args]
|
577
|
-
end
|
596
|
+
if splat
|
597
|
+
"%s.apply(null, %s))" % [dispatch, args]
|
578
598
|
else
|
579
|
-
|
580
|
-
dispatch = "((#{tmprecv} = #{recv_code}).$m#{mid}#{ m_missing })"
|
581
|
-
splat ? "#{dispatch}.apply(null, #{args})" : "#{dispatch}(#{args})"
|
599
|
+
"%s(%s))" % [dispatch, args]
|
582
600
|
end
|
583
|
-
|
584
|
-
|
585
|
-
|
601
|
+
else
|
602
|
+
# m_missing = " || __mm(#{meth.to_s.inspect})"
|
603
|
+
# dispatch = "((#{tmprecv} = #{recv_code}).$m#{mid}#{ m_missing })"
|
604
|
+
# splat ? "#{dispatch}.apply(null, #{args})" : "#{dispatch}(#{args})"
|
605
|
+
dispatch = tmprecv ? "(#{tmprecv} = #{recv_code})#{mid}" : "#{recv_code}#{mid}"
|
606
|
+
splat ? "#{dispatch}.apply(#{tmprecv || recv_code}, #{args})" : "#{dispatch}(#{args})"
|
586
607
|
end
|
608
|
+
|
609
|
+
result
|
587
610
|
end
|
588
611
|
|
589
612
|
# s(:arglist, [arg [, arg ..]])
|
@@ -656,7 +679,7 @@ module Opal
|
|
656
679
|
indent do
|
657
680
|
in_scope(:class) do
|
658
681
|
@scope.name = name
|
659
|
-
@scope.add_temp "#{ @scope.proto } = #{name}.prototype", "
|
682
|
+
@scope.add_temp "#{ @scope.proto } = #{name}.prototype", "__scope = #{name}._scope"
|
660
683
|
@scope.donates_methods = true
|
661
684
|
body = process body, :stmt
|
662
685
|
code = @indent + @scope.to_vars + "\n\n#@indent" + body
|
@@ -685,7 +708,7 @@ module Opal
|
|
685
708
|
|
686
709
|
call = s(:call, recv, :singleton_class, s(:arglist))
|
687
710
|
|
688
|
-
"(function(
|
711
|
+
"(function(){#{ code }}).call(#{ process call, :expr })"
|
689
712
|
end
|
690
713
|
|
691
714
|
# s(:module, cid, body)
|
@@ -711,7 +734,7 @@ module Opal
|
|
711
734
|
indent do
|
712
735
|
in_scope(:module) do
|
713
736
|
@scope.name = name
|
714
|
-
@scope.add_temp "#{ @scope.
|
737
|
+
@scope.add_temp "#{ @scope.proto } = #{name}.prototype", "__scope = #{name}._scope"
|
715
738
|
@scope.donates_methods = true
|
716
739
|
body = process body, :stmt
|
717
740
|
code = @indent + @scope.to_vars + "\n\n#@indent" + body + "\n#@indent" + @scope.to_donate_methods
|
@@ -734,7 +757,7 @@ module Opal
|
|
734
757
|
# FIXME: maybe add this to donate(). it will be undefined, so
|
735
758
|
# when added to includees it will actually undefine methods there
|
736
759
|
# too.
|
737
|
-
"delete #{ @scope.
|
760
|
+
"delete #{ @scope.proto }#{jsid}"
|
738
761
|
end
|
739
762
|
|
740
763
|
# s(:defn, mid, s(:args), s(:scope))
|
@@ -772,21 +795,21 @@ module Opal
|
|
772
795
|
uses_super = nil
|
773
796
|
|
774
797
|
# opt args if last arg is sexp
|
775
|
-
opt = args.pop if
|
798
|
+
opt = args.pop if Sexp === args.last
|
776
799
|
|
777
800
|
# block name &block
|
778
|
-
if args.last.to_s
|
801
|
+
if args.last.to_s.start_with? '&'
|
779
802
|
block_name = args.pop[1..-1].to_sym
|
780
803
|
end
|
781
804
|
|
782
805
|
# splat args *splat
|
783
|
-
if args.last.to_s
|
806
|
+
if args.last.to_s.start_with? '*'
|
784
807
|
if args.last == :*
|
785
808
|
args.pop
|
786
809
|
else
|
787
810
|
splat = args[-1].to_s[1..-1].to_sym
|
788
811
|
args[-1] = splat
|
789
|
-
len = args.length -
|
812
|
+
len = args.length - 2
|
790
813
|
end
|
791
814
|
end
|
792
815
|
|
@@ -845,28 +868,24 @@ module Opal
|
|
845
868
|
|
846
869
|
if recvr
|
847
870
|
if smethod
|
848
|
-
@scope.smethods << mid
|
849
|
-
"#{ comment }#{ @scope.name }
|
871
|
+
@scope.smethods << "$#{mid}"
|
872
|
+
"#{ comment }#{ @scope.name }#{jsid} = #{defcode}"
|
850
873
|
else
|
851
|
-
|
852
|
-
@helpers[:defs] = true
|
853
|
-
"__defs(#{recv}, #{mid.to_s.inspect}, #{defcode})"
|
874
|
+
"#{ recv }#{ jsid } = #{ defcode }"
|
854
875
|
end
|
855
876
|
elsif @scope.class_scope?
|
856
|
-
@scope.methods << mid
|
877
|
+
@scope.methods << "$#{mid}"
|
857
878
|
if uses_super
|
858
879
|
@scope.add_temp uses_super
|
859
|
-
uses_super = "#{uses_super} = #{@scope.
|
880
|
+
uses_super = "#{uses_super} = #{@scope.proto}#{jsid};\n#@indent"
|
860
881
|
end
|
861
|
-
"#{ comment }#{uses_super}#{ @scope.
|
882
|
+
"#{ comment }#{uses_super}#{ @scope.proto }#{jsid} = #{defcode}"
|
862
883
|
elsif @scope.type == :iter
|
863
884
|
"def#{jsid} = #{defcode}"
|
864
885
|
elsif @scope.type == :top
|
865
|
-
|
866
|
-
"__defs(#{current_self}, #{mid.to_s.inspect}, #{defcode})"
|
886
|
+
"#{ current_self }#{ jsid } = #{ defcode }"
|
867
887
|
else
|
868
|
-
|
869
|
-
"__defs(#{current_self}, #{mid.to_s.inspect}, #{defcode})"
|
888
|
+
"def#{jsid} = #{defcode}"
|
870
889
|
end
|
871
890
|
end
|
872
891
|
|
@@ -887,7 +906,7 @@ module Opal
|
|
887
906
|
end
|
888
907
|
|
889
908
|
def process_args(exp, level)
|
890
|
-
args = [
|
909
|
+
args = []
|
891
910
|
|
892
911
|
until exp.empty?
|
893
912
|
a = exp.shift.to_sym
|
@@ -912,8 +931,10 @@ module Opal
|
|
912
931
|
@scope.name
|
913
932
|
elsif @scope.top?
|
914
933
|
'self'
|
915
|
-
|
934
|
+
elsif @scope.top?
|
916
935
|
'self'
|
936
|
+
else # def, iter
|
937
|
+
'this'
|
917
938
|
end
|
918
939
|
end
|
919
940
|
|
@@ -1046,11 +1067,11 @@ module Opal
|
|
1046
1067
|
old = mid_to_jsid exp[1][1].to_s
|
1047
1068
|
|
1048
1069
|
if [:class, :module].include? @scope.type
|
1049
|
-
@scope.methods <<
|
1050
|
-
"%s%s = %s%s" % [@scope.
|
1070
|
+
@scope.methods << "$#{exp[0][1].to_s}"
|
1071
|
+
"%s%s = %s%s" % [@scope.proto, new, @scope.proto, old]
|
1051
1072
|
else
|
1052
1073
|
current = current_self
|
1053
|
-
"%s
|
1074
|
+
"%s.prototype%s = %s.prototype%s" % [current, new, current, old]
|
1054
1075
|
end
|
1055
1076
|
end
|
1056
1077
|
|
@@ -1066,7 +1087,7 @@ module Opal
|
|
1066
1087
|
len = rhs.length - 1 # we are guaranteed an array of this length
|
1067
1088
|
code = ["#{tmp} = #{process rhs, :expr}"]
|
1068
1089
|
elsif rhs[0] == :to_ary
|
1069
|
-
code = ["#{tmp} =
|
1090
|
+
code = ["((#{tmp} = #{process rhs[1], :expr})._isArray ? #{tmp} : (#{tmp} = [#{tmp}]))"]
|
1070
1091
|
elsif rhs[0] == :splat
|
1071
1092
|
code = ["#{tmp} = #{process rhs[1], :expr}"]
|
1072
1093
|
else
|
@@ -1302,7 +1323,7 @@ module Opal
|
|
1302
1323
|
tmp = @scope.new_temp
|
1303
1324
|
|
1304
1325
|
if t = js_truthy_optimize(lhs)
|
1305
|
-
return "(#{tmp} = #{t} ? #{process rhs, :expr} : #{tmp})".tap {
|
1326
|
+
return "((#{tmp} = #{t}) ? #{process rhs, :expr} : #{tmp})".tap {
|
1306
1327
|
@scope.queue_temp tmp
|
1307
1328
|
}
|
1308
1329
|
end
|
@@ -1310,7 +1331,7 @@ module Opal
|
|
1310
1331
|
@scope.queue_temp tmp
|
1311
1332
|
|
1312
1333
|
"(%s = %s, %s !== false && %s !== nil ? %s : %s)" %
|
1313
|
-
|
1334
|
+
[tmp, process(lhs, :expr), tmp, tmp, process(rhs, :expr), tmp]
|
1314
1335
|
end
|
1315
1336
|
|
1316
1337
|
# s(:or, lhs, rhs)
|
@@ -1318,18 +1339,15 @@ module Opal
|
|
1318
1339
|
lhs = sexp[0]
|
1319
1340
|
rhs = sexp[1]
|
1320
1341
|
t = nil
|
1321
|
-
tmp = @scope.new_temp
|
1322
1342
|
|
1323
|
-
|
1324
|
-
|
1325
|
-
|
1326
|
-
|
1343
|
+
with_temp do |tmp|
|
1344
|
+
# if t = js_truthy_optimize(lhs)
|
1345
|
+
# "((%s = %s) ? %s : %s)" % [tmp, t, tmp, process(rhs, :expr)]
|
1346
|
+
# else
|
1347
|
+
"((%s = %s), %s !== false && %s !== nil ? %s : %s)" %
|
1348
|
+
[tmp, process(lhs, :expr), tmp, tmp, tmp, process(rhs, :expr)]
|
1349
|
+
# end
|
1327
1350
|
end
|
1328
|
-
|
1329
|
-
@scope.queue_temp tmp
|
1330
|
-
|
1331
|
-
"(%s = %s, %s !== false && %s !== nil ? %s : %s)" %
|
1332
|
-
[tmp, process(lhs, :expr), tmp, tmp, tmp, process(rhs, :expr)]
|
1333
1351
|
end
|
1334
1352
|
|
1335
1353
|
# s(:yield, arg1, arg2)
|
@@ -1339,18 +1357,31 @@ module Opal
|
|
1339
1357
|
if level == :stmt
|
1340
1358
|
"if (#{call} === __breaker) return __breaker.$v"
|
1341
1359
|
else
|
1342
|
-
|
1360
|
+
with_temp do |tmp|
|
1361
|
+
"(((#{tmp} = #{call}) === __breaker) ? __breaker.$v : #{tmp})"
|
1362
|
+
end
|
1343
1363
|
end
|
1344
1364
|
end
|
1345
1365
|
|
1366
|
+
# special opal yield assign, for `a = yield(arg1, arg2)` to assign
|
1367
|
+
# to a temp value to make yield expr into stmt.
|
1368
|
+
#
|
1369
|
+
# level will always be stmt as its the reason for this to exist
|
1370
|
+
#
|
1371
|
+
# s(:yasgn, :a, s(:yield, arg1, arg2))
|
1372
|
+
def process_yasgn(sexp, level)
|
1373
|
+
call = handle_yield_call s(*sexp[1][1..-1]), :stmt
|
1374
|
+
"if ((%s = %s) === __breaker) return __breaker.$v" % [sexp[0], call]
|
1375
|
+
end
|
1376
|
+
|
1346
1377
|
# Created by `#returns()` for when a yield statement should return
|
1347
1378
|
# it's value (its last in a block etc).
|
1348
1379
|
def process_returnable_yield(sexp, level)
|
1349
1380
|
call = handle_yield_call sexp, level
|
1350
1381
|
|
1351
1382
|
with_temp do |tmp|
|
1352
|
-
"return %s =
|
1353
|
-
[tmp, tmp, tmp, tmp]
|
1383
|
+
"return %s = %s, %s === __breaker ? %s : %s" %
|
1384
|
+
[tmp, call, tmp, tmp, tmp]
|
1354
1385
|
end
|
1355
1386
|
end
|
1356
1387
|
|
@@ -1358,12 +1389,12 @@ module Opal
|
|
1358
1389
|
@scope.uses_block!
|
1359
1390
|
|
1360
1391
|
splat = sexp.any? { |s| s.first == :splat }
|
1361
|
-
sexp.unshift s(:js_tmp, '__context') # self
|
1392
|
+
sexp.unshift s(:js_tmp, '__context') unless splat # self
|
1362
1393
|
args = process_arglist sexp, level
|
1363
1394
|
|
1364
1395
|
y = @scope.block_name || '__yield'
|
1365
1396
|
|
1366
|
-
splat ? "#{y}.apply(
|
1397
|
+
splat ? "#{y}.apply(__context, #{args})" : "#{y}.call(#{args})"
|
1367
1398
|
end
|
1368
1399
|
|
1369
1400
|
def process_break(exp, level)
|
@@ -1421,7 +1452,7 @@ module Opal
|
|
1421
1452
|
until arg.empty?
|
1422
1453
|
a = arg.shift
|
1423
1454
|
|
1424
|
-
if a.first == :
|
1455
|
+
if a.first == :splat # when inside another when means a splat of values
|
1425
1456
|
call = s(:call, s(:js_tmp, "$splt[i]"), :===, s(:arglist, s(:js_tmp, "$case")))
|
1426
1457
|
splt = "(function($splt) {for(var i = 0; i < $splt.length; i++) {"
|
1427
1458
|
splt += "if (#{process call, :expr}) { return true; }"
|
@@ -1488,7 +1519,7 @@ module Opal
|
|
1488
1519
|
#
|
1489
1520
|
# s(:super, arg1, arg2, ...)
|
1490
1521
|
def process_super(sexp, level)
|
1491
|
-
args = [
|
1522
|
+
args = []
|
1492
1523
|
until sexp.empty?
|
1493
1524
|
args << process(sexp.shift, :expr)
|
1494
1525
|
end
|
@@ -1506,23 +1537,28 @@ module Opal
|
|
1506
1537
|
def js_super args
|
1507
1538
|
if @scope.def_in_class?
|
1508
1539
|
mid = @scope.mid.to_s
|
1509
|
-
|
1510
|
-
|
1511
|
-
|
1540
|
+
sid = "super_#{unique_temp}"
|
1541
|
+
|
1542
|
+
@scope.uses_super = sid
|
1543
|
+
"#{sid}.apply(#{current_self}, #{ args })"
|
1512
1544
|
|
1513
1545
|
elsif @scope.type == :def
|
1514
1546
|
identity = @scope.identify!
|
1515
1547
|
cls_name = @scope.parent.name
|
1516
1548
|
jsid = mid_to_jsid @scope.mid.to_s
|
1517
|
-
base = @scope.defs ? '' : "
|
1549
|
+
# base = @scope.defs ? '' : ".prototype"
|
1518
1550
|
|
1519
|
-
"%s
|
1551
|
+
# "%s._super%s%s.apply(this, %s)" % [cls_name, base, jsid, args]
|
1552
|
+
if @scope.defs
|
1553
|
+
"%s._super%s.apply(this, %s)" % [cls_name, jsid, args]
|
1554
|
+
else
|
1555
|
+
"#{current_self}._klass._super.prototype%s.apply(#{current_self}, %s)" % [jsid, args]
|
1556
|
+
end
|
1520
1557
|
|
1521
1558
|
elsif @scope.type == :iter
|
1522
1559
|
chain, defn, mid = @scope.get_super_chain
|
1523
1560
|
trys = chain.map { |c| "#{c}._sup" }.join ' || '
|
1524
|
-
"(#{trys} || this
|
1525
|
-
|
1561
|
+
"(#{trys} || this._klass._super.prototype[#{mid}]).apply(this, #{args})"
|
1526
1562
|
else
|
1527
1563
|
raise "Cannot call super() from outside a method block"
|
1528
1564
|
end
|
@@ -1601,6 +1637,7 @@ module Opal
|
|
1601
1637
|
def process_resbody(exp, level)
|
1602
1638
|
args = exp[0]
|
1603
1639
|
body = exp[1]
|
1640
|
+
|
1604
1641
|
body = process(body || s(:nil), level)
|
1605
1642
|
types = args[1..-2]
|
1606
1643
|
|
@@ -1612,7 +1649,7 @@ module Opal
|
|
1612
1649
|
}.join ', '
|
1613
1650
|
err = "true" if err.empty?
|
1614
1651
|
|
1615
|
-
if
|
1652
|
+
if Sexp === args.last and [:lasgn, :iasgn].include? args.last.first
|
1616
1653
|
val = args.last
|
1617
1654
|
val[2] = s(:js_tmp, "$err")
|
1618
1655
|
val = process(val, :expr) + ";"
|