red 3.0.0

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/History.txt ADDED
@@ -0,0 +1,4 @@
1
+ == 3.0.0 2008-08-06
2
+
3
+ * 1 major enhancement:
4
+ * Initial Rubyforge release
data/License.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 Jesse Sielaff
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Manifest.txt ADDED
@@ -0,0 +1,41 @@
1
+ History.txt
2
+ License.txt
3
+ Manifest.txt
4
+ PostInstall.txt
5
+ README.txt
6
+ Rakefile
7
+ config/hoe.rb
8
+ config/requirements.rb
9
+ lib/red.rb
10
+ lib/red/assignment_nodes.rb
11
+ lib/red/call_nodes.rb
12
+ lib/red/conditional_nodes.rb
13
+ lib/red/conjunction_nodes.rb
14
+ lib/red/constant_nodes.rb
15
+ lib/red/control_nodes.rb
16
+ lib/red/data_nodes.rb
17
+ lib/red/definition_nodes.rb
18
+ lib/red/errors.rb
19
+ lib/red/illegal_nodes.rb
20
+ lib/red/literal_nodes.rb
21
+ lib/red/variable_nodes.rb
22
+ lib/red/version.rb
23
+ lib/red/wrap_nodes.rb
24
+ script/console
25
+ script/destroy
26
+ script/generate
27
+ script/txt2html
28
+ setup.rb
29
+ spec/red_spec.rb
30
+ spec/spec.opts
31
+ spec/spec_helper.rb
32
+ tasks/deployment.rake
33
+ tasks/environment.rake
34
+ tasks/red.rake
35
+ tasks/rspec.rake
36
+ tasks/website.rake
37
+ website/index.html
38
+ website/index.txt
39
+ website/javascripts/rounded_corners_lite.inc.js
40
+ website/stylesheets/screen.css
41
+ website/template.html.erb
data/PostInstall.txt ADDED
@@ -0,0 +1,7 @@
1
+
2
+ For more information on red, see http://red.rubyforge.org
3
+
4
+ NOTE: Change this information in PostInstall.txt
5
+ You can also delete it if you don't want it.
6
+
7
+
data/README.txt ADDED
@@ -0,0 +1,28 @@
1
+ = Turn your JavaScript Red.
2
+
3
+ Red is a Ruby-to-JavaScript transliterator using ParseTree.
4
+
5
+ === License:
6
+
7
+ (The MIT License)
8
+
9
+ Copyright (c) 2008 FIXME full name
10
+
11
+ Permission is hereby granted, free of charge, to any person obtaining
12
+ a copy of this software and associated documentation files (the
13
+ 'Software'), to deal in the Software without restriction, including
14
+ without limitation the rights to use, copy, modify, merge, publish,
15
+ distribute, sublicense, and/or sell copies of the Software, and to
16
+ permit persons to whom the Software is furnished to do so, subject to
17
+ the following conditions:
18
+
19
+ The above copyright notice and this permission notice shall be
20
+ included in all copies or substantial portions of the Software.
21
+
22
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
23
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
25
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
26
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
27
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
28
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,4 @@
1
+ require 'config/requirements'
2
+ require 'config/hoe' # setup Hoe + all gem configuration
3
+
4
+ Dir['tasks/**/*.rake'].each { |rake| load rake }
data/config/hoe.rb ADDED
@@ -0,0 +1,74 @@
1
+ require 'red/version'
2
+
3
+ AUTHOR = 'Jesse Sielaff'
4
+ EMAIL = "jesse.sielaff@gmail.com"
5
+ DESCRIPTION = "A Ruby-to-JavaScript transliterator using ParseTree."
6
+ GEM_NAME = 'red'
7
+ RUBYFORGE_PROJECT = 'red-js'
8
+ HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org"
9
+ DOWNLOAD_PATH = "http://rubyforge.org/projects/#{RUBYFORGE_PROJECT}"
10
+ EXTRA_DEPENDENCIES = [
11
+ ['parse_tree', '>= 2.2.0'],
12
+ ['rake', '>= 0.8.1']
13
+ ]
14
+
15
+ @config_file = "~/.rubyforge/user-config.yml"
16
+ @config = nil
17
+ RUBYFORGE_USERNAME = "unknown"
18
+ def rubyforge_username
19
+ unless @config
20
+ begin
21
+ @config = YAML.load(File.read(File.expand_path(@config_file)))
22
+ rescue
23
+ puts <<-EOS
24
+ ERROR: No rubyforge config file found: #{@config_file}
25
+ Run 'rubyforge setup' to prepare your env for access to Rubyforge
26
+ - See http://newgem.rubyforge.org/rubyforge.html for more details
27
+ EOS
28
+ exit
29
+ end
30
+ end
31
+ RUBYFORGE_USERNAME.replace @config["username"]
32
+ end
33
+
34
+
35
+ REV = nil
36
+ # UNCOMMENT IF REQUIRED:
37
+ # REV = YAML.load(`svn info`)['Revision']
38
+ VERS = Red::VERSION::STRING + (REV ? ".#{REV}" : "")
39
+ RDOC_OPTS = ['--quiet', '--title', 'red documentation',
40
+ "--opname", "index.html",
41
+ "--line-numbers",
42
+ "--main", "README",
43
+ "--inline-source"]
44
+
45
+ class Hoe
46
+ def extra_deps
47
+ @extra_deps.reject! { |x| Array(x).first == 'hoe' }
48
+ @extra_deps
49
+ end
50
+ end
51
+
52
+ # Generate all the Rake tasks
53
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
54
+ $hoe = Hoe.new(GEM_NAME, VERS) do |p|
55
+ p.developer(AUTHOR, EMAIL)
56
+ p.description = DESCRIPTION
57
+ p.summary = DESCRIPTION
58
+ p.url = HOMEPATH
59
+ p.rubyforge_name = RUBYFORGE_PROJECT if RUBYFORGE_PROJECT
60
+ p.test_globs = ["test/**/test_*.rb"]
61
+ p.clean_globs |= ['**/.*.sw?', '*.gem', '.config', '**/.DS_Store'] #An array of file patterns to delete on clean.
62
+
63
+ # == Optional
64
+ p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
65
+ #p.extra_deps = EXTRA_DEPENDENCIES
66
+
67
+ #p.spec_extras = {} # A hash of extra values to set in the gemspec.
68
+ end
69
+
70
+ CHANGES = $hoe.paragraphs_of('History.txt', 0..1).join("\\n\\n")
71
+ PATH = (RUBYFORGE_PROJECT == GEM_NAME) ? RUBYFORGE_PROJECT : "#{RUBYFORGE_PROJECT}/#{GEM_NAME}"
72
+ $hoe.remote_rdoc_dir = File.join(PATH.gsub(/^#{RUBYFORGE_PROJECT}\/?/,''), 'rdoc')
73
+ $hoe.rsync_args = '-av --delete --ignore-errors'
74
+ $hoe.spec.post_install_message = File.open(File.dirname(__FILE__) + "/../PostInstall.txt").read rescue ""
@@ -0,0 +1,15 @@
1
+ require 'fileutils'
2
+ include FileUtils
3
+
4
+ require 'rubygems'
5
+ %w[rake hoe newgem rubigen].each do |req_gem|
6
+ begin
7
+ require req_gem
8
+ rescue LoadError
9
+ puts "This Rakefile requires the '#{req_gem}' RubyGem."
10
+ puts "Installation: gem install #{req_gem} -y"
11
+ exit
12
+ end
13
+ end
14
+
15
+ $:.unshift(File.join(File.dirname(__FILE__), %w[.. lib]))
@@ -0,0 +1,126 @@
1
+ module Red
2
+ class AssignmentNode # :nodoc:
3
+ def initialize(variable_name, expression)
4
+ raise(BuildError::NoMultilineAssignment, "Multiline assignment (e.g. foo = begin; line1; line2; end) is not supported") if expression.first == :block
5
+ @variable_name, @expression = [variable_name, expression].build_nodes
6
+ end
7
+
8
+ def compile_internals(options = {})
9
+ return [@variable_name, @expression].compile_nodes(:as_argument => true)
10
+ end
11
+
12
+ class ClassVariableNode < AssignmentNode # :nodoc:
13
+ def compile_node(options = {})
14
+ if options[:as_prototype]
15
+ receiver = @variable_name.compile_node
16
+ "%s: %s"
17
+ else
18
+ receiver = "%s.%s" % [@@red_class, @variable_name.compile_node]
19
+ "%s = %s"
20
+ end % [receiver, @expression.compile_node(:as_argument => true)]
21
+ end
22
+ end
23
+
24
+ class GlobalVariableNode < AssignmentNode # :nodoc:
25
+ def compile_node(options = {})
26
+ return "%s = %s" % self.compile_internals
27
+ end
28
+ end
29
+
30
+ class InstanceVariableNode < AssignmentNode # :nodoc:
31
+ def compile_node(options = {})
32
+ return "this.%s = %s" % self.compile_internals
33
+ end
34
+ end
35
+
36
+ class LocalVariableNode < AssignmentNode # :nodoc:
37
+ def compile_node(options = {})
38
+ return (@variable_name.is_a?(LiteralNode::NamespaceNode) ? "%s = %s" : "var %s = %s") % self.compile_internals
39
+ end
40
+ end
41
+
42
+ class AttributeNode # :nodoc:
43
+ def initialize(variable_name, slot_equals, arguments)
44
+ @variable_name, @expression = [variable_name, arguments.last].build_nodes
45
+ @slot = (slot_equals == :[]= ? arguments[1] : slot_equals.to_s.gsub(/=/,'').to_sym).build_node
46
+ end
47
+
48
+ def compile_node(options = {})
49
+ return "%s = %s" % compile_internals
50
+ end
51
+
52
+ def compile_internals(options = {})
53
+ variable_name, slot, expression = [@variable_name, @slot, @expression].compile_nodes(:quotes => '', :as_argument => true)
54
+ receiver = self.compile_receiver(variable_name, slot)
55
+ return [receiver, expression]
56
+ end
57
+
58
+ def compile_receiver(variable_name, slot)
59
+ return ([:symbol, :string].include?((@slot.data_type rescue :node)) ? "%s.%s" : "%s[%s]") % [variable_name, slot]
60
+ end
61
+ end
62
+
63
+ class OperatorNode # :nodoc:
64
+ def compile_node(options = {})
65
+ return "%s%s = %s %s %s" % self.compile_internals
66
+ end
67
+
68
+ def compile_internals(options = {})
69
+ receiver, operation = [@receiver, @operation].compile_nodes
70
+ expression = @expression.compile_node(:as_argument => true)
71
+ slot = @slot.compile_node(:quotes => '')
72
+ original = self.compile_receiver(receiver, slot)
73
+ var = (self.var? rescue nil)
74
+ return [var, original, original, operation, expression]
75
+ end
76
+
77
+ class BracketNode < OperatorNode # :nodoc:
78
+ def initialize(receiver, bracket_contents, operation, expression)
79
+ @receiver, @slot, @operation, @expression = [receiver, bracket_contents.last, operation, expression].build_nodes
80
+ end
81
+
82
+ def compile_receiver(receiver, slot)
83
+ return ([:symbol, :string].include?((@slot.data_type rescue :node)) ? "%s.%s" : "%s[%s]") % [receiver, slot]
84
+ end
85
+ end
86
+
87
+ class DotNode < OperatorNode # :nodoc:
88
+ def initialize(receiver, slot_equals, operation, expression)
89
+ @receiver, @slot, @operation, @expression = [receiver, slot_equals.to_s.gsub(/=/,''), operation, expression].build_nodes
90
+ end
91
+
92
+ def compile_receiver(receiver, slot)
93
+ return "%s.%s" % [receiver, slot]
94
+ end
95
+ end
96
+
97
+ class OrNode < OperatorNode # :nodoc:
98
+ def initialize(receiver, assignment_node_array)
99
+ @receiver, @slot, @operation, @expression = [receiver, nil, %s(||), assignment_node_array.last].build_nodes
100
+ end
101
+
102
+ def compile_receiver(receiver, slot)
103
+ return "%s" % [receiver]
104
+ end
105
+
106
+ def var?
107
+ return "var " unless [VariableNode::GlobalVariableNode, VariableNode::InstanceVariableNode].include?(@receiver.class)
108
+ end
109
+ end
110
+
111
+ class AndNode < OperatorNode # :nodoc:
112
+ def initialize(receiver, assignment_node_array)
113
+ @receiver, @slot, @operation, @expression = [receiver, nil, %s(&&), assignment_node_array.last].build_nodes
114
+ end
115
+
116
+ def compile_receiver(receiver, slot)
117
+ return "%s" % [receiver]
118
+ end
119
+
120
+ def var?
121
+ return "var " unless [VariableNode::GlobalVariableNode, VariableNode::InstanceVariableNode].include?(@receiver.class)
122
+ end
123
+ end
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,85 @@
1
+ module Red
2
+ class CallNode # :nodoc:
3
+ class BlockNode # :nodoc:
4
+ def initialize(receiver, arguments_array, expression = nil)
5
+ @receiver, @expression = [receiver, expression].build_nodes
6
+ @arguments = (((arguments_array ||= []).first == :masgn) ? arguments_array.assoc(:array)[1..-1].map {|node| node.last} : [arguments_array.last]).build_nodes
7
+ end
8
+
9
+ def compile_node(options = {})
10
+ receiver = @receiver.compile_node.gsub(/\(\)$/,'')
11
+ arguments = @arguments.compile_nodes.join(', ')
12
+ expression = @expression.compile_node
13
+ case receiver.to_sym
14
+ when :lambda, :function, :proc
15
+ "function(%s) { %s }" % [arguments, expression]
16
+ else
17
+ "%s(function(%s) { %s })" % [receiver, arguments, expression]
18
+ end
19
+ end
20
+ end
21
+
22
+ class MatchNode # :nodoc:
23
+ def initialize(regex, expression)
24
+ @regex, @expression = [regex, expression].build_nodes
25
+ end
26
+
27
+ def compile_node(options = {}) # :nodoc:
28
+ regex = @regex.compile_node
29
+ expression = @expression.compile_node(:as_argument => true)
30
+ "%s.match(%s)" % [regex, expression]
31
+ end
32
+
33
+ class ReverseNode < MatchNode # :nodoc:
34
+ def initialize(expression, regex)
35
+ @regex, @expression = [regex, expression].build_nodes
36
+ end
37
+ end
38
+ end
39
+
40
+ class MethodNode # :nodoc:
41
+ def compile_node(options = {})
42
+ call_to_returned_function = [DefinitionNode::InstanceMethodNode, CallNode::BlockNode].include?(@receiver.class) ? :call : false
43
+ receiver = @receiver.compile_node
44
+ function = @function.compile_node
45
+ arguments = @arguments.compile_nodes(:as_argument => true, :quotes => "'")
46
+ return ("$%s(%s)" % [receiver = ((receiver == '$-') || (receiver == 'id' && @@red_library == :Prototype) ? nil : receiver), arguments.first]).gsub('$$','$').gsub('$class','$$') if @receiver.is_a?(VariableNode::GlobalVariableNode) && function == '-'
47
+ case function.to_sym
48
+ when :-, :+, :<, :>, :%, :*, :/, :^, :==, :===, :instanceof
49
+ "%s %s %s" % [receiver, function, arguments.first]
50
+ when :raise
51
+ "throw(%s)" % [arguments.first]
52
+ when :new
53
+ "new %s(%s)" % [receiver, arguments.join(', ')]
54
+ when :[]
55
+ if ([:symbol, :string].include?(@arguments.first.data_type) rescue false)
56
+ arguments = @arguments.compile_nodes(:quotes => "", :as_argument => true)
57
+ "%s.%s"
58
+ else
59
+ "%s[%s]"
60
+ end % [receiver, arguments.first]
61
+ when call_to_returned_function
62
+ "(%s)(%s)" % [receiver, arguments]
63
+ else
64
+ receiver += '.' unless receiver.empty?
65
+ "%s%s(%s)" % [receiver, function, arguments.join(', ')]
66
+ end
67
+ end
68
+
69
+ class ExplicitNode < MethodNode # :nodoc:
70
+ def initialize(receiver, function, arguments = [nil])
71
+ @receiver, @function = [receiver, function].build_nodes
72
+ @arguments = arguments[1..-1].build_nodes
73
+ end
74
+ end
75
+
76
+ class ImplicitNode < MethodNode # :nodoc:
77
+ def initialize(function, arguments = [nil])
78
+ @function = function.build_node
79
+ @receiver = (:self if @function.compile_node == '[]').build_node
80
+ @arguments = arguments[1..-1].build_nodes
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,63 @@
1
+ module Red
2
+ class ConditionalNode # :nodoc:
3
+ class IfNode # :nodoc:
4
+ def initialize(condition, true_case, else_case)
5
+ @condition, @true_case, @else_case = [condition, true_case, else_case].build_nodes
6
+ end
7
+
8
+ def compile_node(options = {})
9
+ unless options[:as_argument]
10
+ "if (%s) %s%s%s"
11
+ else
12
+ "(%s ? %s : %s)"
13
+ end % self.compile_internals(options)
14
+ end
15
+
16
+ def compile_internals(options = {})
17
+ true_case, else_case, condition = [@true_case, @else_case, @condition].compile_nodes
18
+ return [condition, (true_case.empty? ? 'null' : true_case), (else_case.empty? ? 'null' : else_case)] if options[:as_argument]
19
+ condition = (true_case.empty? ? "!(%s)" : "%s") % [condition]
20
+ true_case = "{ %s; }" % [true_case] unless true_case.empty?
21
+ join = " else " unless true_case.empty? || else_case.empty?
22
+ else_case = "{ %s; }" % [else_case] unless else_case.empty?
23
+ return [condition, true_case, join, else_case]
24
+ end
25
+ end
26
+
27
+ class CaseNode # :nodoc:
28
+ def initialize(switch, *cases)
29
+ @switch, @else_case = [switch, cases.pop].build_nodes
30
+ @when_cases = cases.build_nodes
31
+ end
32
+
33
+ def compile_node(options = {})
34
+ return "switch (%s) { %s%s }" % self.compile_internals
35
+ end
36
+
37
+ def compile_internals(options = {})
38
+ switch, else_case = [@switch, @else_case].compile_nodes
39
+ when_cases = @when_cases.compile_nodes.join
40
+ default = "default:%s;" % [else_case] unless else_case.empty?
41
+ return [switch, when_cases, default]
42
+ end
43
+ end
44
+
45
+ class WhenNode # :nodoc:
46
+ def initialize(conditions, expression)
47
+ @conditions = conditions[1..-1].build_nodes
48
+ @expression = expression.build_node
49
+ end
50
+
51
+ def compile_node(options = {})
52
+ return "case %s:%s;%s" % self.compile_internals
53
+ end
54
+
55
+ def compile_internals(options = {})
56
+ condition = @conditions.first.compile_node(:quotes => "'")
57
+ expression = @expression.compile_node
58
+ final = "break;"
59
+ return [condition, expression, final]
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,23 @@
1
+ module Red
2
+ class ConjunctionNode # :nodoc:
3
+ def initialize(a, b)
4
+ @a, @b = [a, b].build_nodes
5
+ end
6
+
7
+ def compile_internals(options = {})
8
+ [@a, @b].compile_nodes(:as_argument => true)
9
+ end
10
+
11
+ class AndNode < ConjunctionNode # :nodoc:
12
+ def compile_node(options = {})
13
+ return "%s && %s" % self.compile_internals
14
+ end
15
+ end
16
+
17
+ class OrNode < ConjunctionNode # :nodoc:
18
+ def compile_node(options = {})
19
+ return "%s || %s" % self.compile_internals
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,47 @@
1
+ module Red
2
+ class ConstantNode # :nodoc:
3
+ class BreakNode < ConstantNode # :nodoc:
4
+ def initialize(*args)
5
+ raise(BuildError::NoBreakArguments, "Break can't take an argument in JavaScript") unless args.empty?
6
+ end
7
+
8
+ def compile_node(options = {})
9
+ return "break"
10
+ end
11
+ end
12
+
13
+ class FalseNode < ConstantNode # :nodoc:
14
+ def compile_node(options = {})
15
+ return "false"
16
+ end
17
+ end
18
+
19
+ class NextNode < ConstantNode # :nodoc:
20
+ def initialize(*args)
21
+ raise(BuildError::NoNextArguments, "Next/continue can't take an argument in JavaScript") unless args.empty?
22
+ end
23
+
24
+ def compile_node(options = {})
25
+ return "continue"
26
+ end
27
+ end
28
+
29
+ class NilNode < ConstantNode # :nodoc:
30
+ def compile_node(options = {})
31
+ return "null"
32
+ end
33
+ end
34
+
35
+ class SelfNode < ConstantNode # :nodoc:
36
+ def compile_node(options = {})
37
+ return "this"
38
+ end
39
+ end
40
+
41
+ class TrueNode < ConstantNode # :nodoc:
42
+ def compile_node(options = {})
43
+ return "true"
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,127 @@
1
+ module Red
2
+ class ControlNode # :nodoc:
3
+ class BeginNode # :nodoc:
4
+ def initialize(body)
5
+ @@rescue_is_safe = (body.first == :rescue)
6
+ @body = body.build_node
7
+ end
8
+
9
+ def compile_node(options = {})
10
+ "%s" % [@body.compile_node]
11
+ end
12
+ end
13
+
14
+ class EnsureNode # :nodoc:
15
+ def initialize(attempted, ensure_body)
16
+ @@rescue_is_safe = @ensure_from_rescue = attempted.first == :rescue
17
+ @attempted, @ensured = [attempted, ensure_body].build_nodes
18
+ end
19
+
20
+ def compile_node(options = {})
21
+ if @ensure_from_rescue
22
+ "%s finally { %s; }"
23
+ else
24
+ "try { %s; } finally { %s; }"
25
+ end % self.compile_internals
26
+ end
27
+
28
+ def compile_internals(options = {})
29
+ return [@attempted, @ensured].compile_nodes
30
+ end
31
+ end
32
+
33
+ class ForNode # :nodoc:
34
+ def initialize(source, iterator, body)
35
+ @properties_loop = (iterator.last == :property)
36
+ @source, @iterator, @body = [source, iterator.last, body].build_nodes
37
+ end
38
+
39
+ def compile_node(options = {})
40
+ source = @source.compile_node(:as_argument => true)
41
+ iterator = @iterator.compile_node
42
+ body = @body.compile_node
43
+ if @properties_loop
44
+ "for (var property in %s) { %s; }" % [source, body]
45
+ else
46
+ "for (var %s = 0; %s < %s.length; %s++) { %s; }" % [iterator, iterator, source, iterator, body]
47
+ end
48
+ end
49
+ end
50
+
51
+ class RescueNode # :nodoc:
52
+ def initialize(attempted, rescue_body)
53
+ raise(BuildError::NoArbitraryRescue, "JavaScript does not support arbitrary placement of rescue/try blocks") unless @@rescue_is_safe
54
+ raise(BuildError::NoSpecificRescue, "JavaScript does not support rescuing of specific exception classes") unless !rescue_body[1]
55
+ @@rescue_is_safe == false
56
+ @attempted = attempted.build_node
57
+ if (block = (rescue_body.assoc(:block) || [])[1..-1]) && block.first.last == [:gvar, %s($!)]
58
+ exception_node = block.shift
59
+ @exception_variable = exception_node[1].build_node
60
+ @rescued = block.unshift(:block).build_node
61
+ else
62
+ @exception_variable = :e.build_node
63
+ @rescued = rescue_body[2].build_node
64
+ end
65
+ end
66
+
67
+ def compile_node(options = {})
68
+ return "try { %s; } catch(%s) { %s; }" % self.compile_internals
69
+ end
70
+
71
+ def compile_internals(options = {})
72
+ return [@attempted, @exception_variable, @rescued].compile_nodes
73
+ end
74
+ end
75
+
76
+ class UntilNode # :nodoc:
77
+ def initialize(condition, body, run_only_if_condition_met)
78
+ @condition, @body = [condition, body].build_nodes
79
+ @do_while_loop = !run_only_if_condition_met
80
+ end
81
+
82
+ def compile_node(options = {})
83
+ if @do_while_loop
84
+ return "do { %s; } while (!(%s))" % self.compile_internals.reverse
85
+ else
86
+ return "while (!(%s)) { %s; }" % self.compile_internals
87
+ end
88
+ end
89
+
90
+ def compile_internals(options = {})
91
+ condition, body = [@condition, @body].compile_nodes
92
+ return [condition, body]
93
+ end
94
+ end
95
+
96
+ class WhileNode # :nodoc:
97
+ def initialize(condition, body, run_only_if_condition_met)
98
+ @condition, @body = [condition, body].build_nodes
99
+ @do_while_loop = !run_only_if_condition_met
100
+ end
101
+
102
+ def compile_node(options = {})
103
+ if @do_while_loop
104
+ return "do { %s; } while (%s)" % self.compile_internals.reverse
105
+ else
106
+ return "while (%s) { %s; }" % self.compile_internals
107
+ end
108
+ end
109
+
110
+ def compile_internals(options = {})
111
+ condition, body = [@condition, @body].compile_nodes
112
+ return [condition, body]
113
+ end
114
+ end
115
+
116
+ class LibraryNode # :nodoc:
117
+ def initialize(library)
118
+ @@red_library = @library = library
119
+ end
120
+
121
+ def compile_node(options = {})
122
+ @@red_library = @library
123
+ nil
124
+ end
125
+ end
126
+ end
127
+ end