red 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +4 -0
- data/License.txt +20 -0
- data/Manifest.txt +41 -0
- data/PostInstall.txt +7 -0
- data/README.txt +28 -0
- data/Rakefile +4 -0
- data/config/hoe.rb +74 -0
- data/config/requirements.rb +15 -0
- data/lib/red/assignment_nodes.rb +126 -0
- data/lib/red/call_nodes.rb +85 -0
- data/lib/red/conditional_nodes.rb +63 -0
- data/lib/red/conjunction_nodes.rb +23 -0
- data/lib/red/constant_nodes.rb +47 -0
- data/lib/red/control_nodes.rb +127 -0
- data/lib/red/data_nodes.rb +92 -0
- data/lib/red/definition_nodes.rb +142 -0
- data/lib/red/errors.rb +95 -0
- data/lib/red/illegal_nodes.rb +63 -0
- data/lib/red/literal_nodes.rb +119 -0
- data/lib/red/variable_nodes.rb +37 -0
- data/lib/red/version.rb +9 -0
- data/lib/red/wrap_nodes.rb +51 -0
- data/lib/red.rb +161 -0
- data/script/console +10 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/script/txt2html +82 -0
- data/setup.rb +1585 -0
- data/spec/red_spec.rb +11 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +10 -0
- data/tasks/deployment.rake +34 -0
- data/tasks/environment.rake +7 -0
- data/tasks/red.rake +49 -0
- data/tasks/rspec.rake +21 -0
- data/tasks/website.rake +17 -0
- data/website/index.html +86 -0
- data/website/index.txt +83 -0
- data/website/javascripts/rounded_corners_lite.inc.js +285 -0
- data/website/stylesheets/screen.css +138 -0
- data/website/template.html.erb +48 -0
- metadata +116 -0
data/History.txt
ADDED
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
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
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
|