red 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
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