opal 0.3.21 → 0.3.22
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/.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) + ";"
|