red 4.0.6 → 4.1.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/Manifest.txt CHANGED
@@ -27,9 +27,10 @@ script/destroy
27
27
  script/generate
28
28
  script/txt2html
29
29
  setup.rb
30
- spec/red_spec.rb
31
- spec/spec.opts
32
- spec/spec_helper.rb
30
+ spec/array.red
31
+ spec/hash.red
32
+ spec/object.red
33
+ spec/string.red
33
34
  tasks/deployment.rake
34
35
  tasks/environment.rake
35
36
  tasks/rspec.rake
data/bin/red CHANGED
@@ -15,6 +15,7 @@ include Red
15
15
  parser = OptionParser.new do |opts|
16
16
  opts.banner = RED_MESSAGES[:banner]
17
17
  opts.separator ""
18
+ opts.on('-d',"--debug","Translate Red files to JavaScript in debug mode.") { Red.instance_eval "def debug;true;end" }
18
19
  opts.on('-h',"--help","Show this help message.") { puts opts; exit }
19
20
  opts.on('-r',"--rails","Add Red plugin to ./vendor/plugins.") { build_red_plugin_for_rails }
20
21
  opts.on('-s',"--string=RUBY_STRING","Translate a single string to JavaScript.") { |string| Red.init && direct_translate(string) }
@@ -72,9 +72,12 @@ module Red # :nodoc:
72
72
  puts "File #{filename}.red does not exist."
73
73
  exit
74
74
  end
75
+ @@red_filepath = File.dirname(File.expand_path(filename))
75
76
  js_output = hush_warnings { File.read(file).translate_to_sexp_array }.red!
76
77
  ruby_js = compile_ruby_js_source
77
- File.open("%s%s.js" % [dir, filename], 'w') {|f| f.write(ruby_js + js_output)} unless dry_run
78
+ pre = Red.debug ? "try{" : ""
79
+ post = Red.debug ? "}catch(e){if(e.__class__){m$raise(e);};$ee=e;var m=e.message.match(/([^\\$]+)\\.m\\$(\\w+)\\sis\\snot\\sa\\sfunction/);if(m){m$raise(c$NoMethodError,$q('undefined method \"'+m[2]+'\" for '+m[1]));};var c=e.message.match(/([\\s\\S]+)\\sis\\sundefined/);if(c){c=c[1].replace(/\\./g,'::').replace(/c\\$/g,'');m$raise(c$NameError,$q('uninitialized constant '+c));};}" : ""
80
+ File.open("%s%s.js" % [dir, filename], 'w') {|f| f.write(pre + ruby_js + js_output + post)} unless dry_run
78
81
  print_js(js_output, filename, dry_run)
79
82
  end
80
83
 
@@ -46,8 +46,9 @@ module Red
46
46
  def initialize(variable_name_sexp, expression_sexp, options)
47
47
  variable_name = variable_name_sexp.red!
48
48
  expression = expression_sexp.red!(:as_assignment => true)
49
+ a = @@red_boolean.succ!.dup
49
50
  if options[:as_argument_default]
50
- self << "%s=$T(_a=%s)?_a:%s" % [variable_name, variable_name, expression]
51
+ self << "%s=$T($.%s=%s)?$.%s:%s" % [variable_name, a, variable_name, a, expression]
51
52
  else
52
53
  self << "%s=%s" % [variable_name, expression]
53
54
  end
@@ -82,7 +83,7 @@ module Red
82
83
  method = (METHOD_ESCAPE[method_sexp] || method_sexp).red!
83
84
  expression = expression_sexp.red!(:as_argument => true)
84
85
  object = "%s.m$_brac(%s)" % [receiver, arguments]
85
- unless string = ((method == '||' && LogicNode::Conjunction::Or::STRING) || (method == '&&' && LogicNode::Conjunction::And::STRING))
86
+ unless string = ((method == '||' && LogicNode::Conjunction::Or.string) || (method == '&&' && LogicNode::Conjunction::And.string))
86
87
  operation = "%s.m$%s(%s)" % [object, method, expression]
87
88
  else
88
89
  operation = string % [object, expression]
@@ -100,7 +101,7 @@ module Red
100
101
  method = (METHOD_ESCAPE[method_sexp] || method_sexp).red!
101
102
  expression = expression_sexp.red!(:as_argument => true)
102
103
  object = "%s.m$%s()" % [receiver, reader]
103
- unless string = ((method == '||' && LogicNode::Conjunction::Or::STRING) || (method == '&&' && LogicNode::Conjunction::And::STRING))
104
+ unless string = ((method == '||' && LogicNode::Conjunction::Or.string) || (method == '&&' && LogicNode::Conjunction::And.string))
104
105
  operation = "%s.m$%s(%s)" % [object, method, expression]
105
106
  else
106
107
  operation = string % [object, expression]
@@ -114,7 +115,7 @@ module Red
114
115
  def initialize(variable_name_sexp, assignment_sexp, options)
115
116
  variable_name = variable_name_sexp.red!
116
117
  expression = assignment_sexp.last.red!(:as_argument => true)
117
- conjunction = LogicNode::Conjunction::Or::STRING % [variable_name, expression]
118
+ conjunction = LogicNode::Conjunction::Or.string % [variable_name, expression]
118
119
  self << "%s=%s" % [variable_name, conjunction]
119
120
  end
120
121
  end
@@ -124,7 +125,7 @@ module Red
124
125
  def initialize(variable_name_sexp, assignment_sexp, options)
125
126
  variable_name = variable_name_sexp.red!
126
127
  expression = assignment_sexp.last.red!(:as_argument => true)
127
- conjunction = LogicNode::Conjunction::And::STRING % [variable_name, expression]
128
+ conjunction = LogicNode::Conjunction::And.string % [variable_name, expression]
128
129
  self << "%s=%s" % [variable_name, conjunction]
129
130
  end
130
131
  end
@@ -3,7 +3,7 @@ module Red
3
3
  class Ampersand < CallNode # :nodoc:
4
4
  # [:block_pass, {expression}, {expression}]
5
5
  def initialize(block_pass_sexp, function_call_sexp, options)
6
- block_string = "%s.m$toProc()._block" % block_pass_sexp.red!(:as_receiver => true)
6
+ block_string = "%s.m$to_proc().__block__" % block_pass_sexp.red!(:as_receiver => true)
7
7
  function_call = function_call_sexp.red!(options.merge(:block_string => block_string))
8
8
  self << "%s" % [function_call]
9
9
  end
@@ -79,17 +79,32 @@ module Red
79
79
  arguments = args_array.join(",")
80
80
  case function_sexp
81
81
  when :require
82
- #cached_import_status = @@red_import
83
- #@@red_import = true
84
- self << hush_warnings { File.read((arguments_array_sexp.assoc(:array).assoc(:str).last rescue '')).translate_to_sexp_array }.red!
85
- #@@red_import = cached_import_status
82
+ basename = File.basename((arguments_array_sexp.assoc(:array).assoc(:str).last rescue ''))
83
+ dirname = File.dirname((arguments_array_sexp.assoc(:array).assoc(:str).last rescue ''))
84
+ short_filename = File.join(@@red_filepath, basename)
85
+ long_filename = File.join(@@red_filepath, dirname, basename)
86
+ unless @@red_required.include?(basename)
87
+ @@red_required |= [basename]
88
+ file = Dir.glob(short_filename)[0] || Dir.glob('%s.red' % short_filename)[0] || Dir.glob('%s.rb' % short_filename)[0] || Dir.glob(long_filename)[0] || Dir.glob('%s.red' % long_filename)[0] || Dir.glob('%s.rb' % long_filename)[0] || Dir.glob('%s/../../source/redshift/%s' % [File.dirname(__FILE__),basename])[0] || Dir.glob('%s/../../source/redshift/%s.red' % [File.dirname(__FILE__),basename])[0]
89
+ stored_filepath = @@red_filepath
90
+ @@red_filepath = File.dirname(file)
91
+ self << hush_warnings { File.read(file).translate_to_sexp_array }.red!
92
+ @@red_filepath = stored_filepath
93
+ else
94
+ self << "false";
95
+ end
86
96
  when :[]
87
97
  self << "this.m$%s(%s)" % [function, arguments]
88
98
  when :block_given?
89
- self << "m$blockGivenBool(%s._block)" % @@red_block_arg
99
+ self << "m$block_given_bool(%s.__block__)" % (@@red_block_arg || 'nil')
90
100
  else
91
- arguments = ','+arguments unless arguments.empty?
92
- self << "(this.m$%s||m$%s).call(this%s)" % [function, function, arguments]
101
+ if Red.debug
102
+ error_function = arguments.empty? ? 'n' : 'm'
103
+ self << "((this.m$%s&&this.m$%s(%s))||(window.m$%s&&window.m%s(%s))||$%s(this,'%s'))" % [function,function,arguments,function,function,arguments,error_function,function_sexp]
104
+ else
105
+ arguments = ','+arguments unless arguments.empty?
106
+ self << "(this.m$%s||window.m$%s).call(this%s)" % [function, function, arguments]
107
+ end
93
108
  @@red_methods |= [function_sexp] unless @@red_import
94
109
  end
95
110
  end
@@ -62,15 +62,10 @@ module Red
62
62
  class For < ControlNode # :nodoc:
63
63
  # [:for, {expression}, {expression}, {expression | :block}]
64
64
  def initialize(source_sexp, iterator_assignment_sexp, body_sexp, options)
65
- body = body_sexp.red!
66
- unless source_sexp.is_sexp?(:xstr, :dxstr)
67
- source = source_sexp.red!(:as_argument => true)
68
- iterator = iterator_assignment_sexp.last.red!
69
- self << "for(var %s in %s){%s;}" % [iterator, source, body]
70
- else
71
- loop_statement = source_sexp.red!
72
- self << "for(%s){%s;}" % [loop_statement, body]
73
- end
65
+ iterator = iterator_assignment_sexp.last.red!
66
+ source = source_sexp.red!(:as_receiver => true)
67
+ body = body_sexp.red!
68
+ self << "%s.m$each(function(%s){%s;}.m$(this))" % [source, iterator, body]
74
69
  end
75
70
  end
76
71
 
@@ -44,7 +44,8 @@ module Red
44
44
  class String < DataNode # :nodoc:
45
45
  # 'foo'
46
46
  def initialize(value_data, options)
47
- value = options[:no_escape] ? value_data : value_data.gsub(/'/, "\\\\'")
47
+ # value = options[:no_escape] ? value_data : value_data.gsub(/"/, '\\"')
48
+ value = value_data
48
49
  string = options[:unquoted] ? "%s" % [value] : "%s" % [value.inspect]
49
50
  self << string
50
51
  end
@@ -54,15 +55,16 @@ module Red
54
55
  # :foo
55
56
  def initialize(value_data, options)
56
57
  value = self.camelize(value_data.to_s, options[:not_camelized])
57
- string = options[:as_receiver] ? "$q('%s')" : options[:as_argument] ? "'%s'" : "%s"
58
+ string = options[:as_receiver] ? "$q(\"%s\")" : options[:as_argument] ? "\"%s\"" : "%s"
58
59
  self << string % [value]
59
60
  end
60
61
 
61
62
  def camelize(string, disabled = false)
62
- return string unless self.camelize?(string) && !disabled
63
- words = string.gsub(/@/,'').gsub('?','_bool').gsub('!','_bang').gsub('=','_eql').split(/_/)
64
- underscore = words.shift if words.first.empty?
65
- return (underscore ? '_' : '') + words[0] + words[1..-1].map {|word| word == word.upcase ? word : word.capitalize }.join
63
+ return string.gsub(/@/,'').gsub('?','_bool').gsub('!','_bang').gsub('=','_eql')
64
+ # return string unless self.camelize?(string) && !disabled
65
+ # words = string.gsub(/@/,'').gsub('?','_bool').gsub('!','_bang').gsub('=','_eql').split(/_/)
66
+ # underscore = words.shift if words.first.empty?
67
+ # return (underscore ? '_' : '') + words[0] + words[1..-1].map {|word| word == word.upcase ? word : word.capitalize }.join
66
68
  end
67
69
 
68
70
  def camelize?(string)
@@ -95,12 +95,16 @@ module Red
95
95
  splat_arg = argument_sexps.pop.to_s[1..-1] if argument_sexps.last && argument_sexps.last.to_s.include?('*')
96
96
  argument_sexps += [block_arg_sexp.last] if block_arg_sexp
97
97
  args_array = argument_sexps.map {|argument| argument.red! }
98
- splatten_args = "for(var bg=m$blockGivenBool(arguments[arguments.length-1]),l=bg?arguments.length-1:arguments.length,i=#{block_arg_sexp ? argument_sexps.size - 1 : argument_sexps.size},#{splat_arg}=[];i<l;++i){#{splat_arg}.push(arguments[i]);};var #{block_arg_sexp.last rescue :_block}=(bg?c$Proc.m$new(arguments[arguments.length-1]):nil)" if splat_arg
99
- block_arg = "var #{block_arg_sexp.last rescue :_block}=(m$blockGivenBool(arguments[arguments.length-1])?c$Proc.m$new(arguments[arguments.length-1]):nil)" if block_arg_sexp && !splat_arg
98
+ maximum_args = args_array.length - (block_arg_sexp ? 1 : 0)
99
+ minimum_args = maximum_args - (defaults_sexp ? defaults_sexp.flatten.select {|x| x == :lasgn}.length : 0)
100
+ splatten_args = "for(var l=arguments.length,i=#{argument_sexps.size},#{splat_arg}=[];i<l;++i){#{splat_arg}.push(arguments[i]);}" if splat_arg && !block_arg_sexp
101
+ splat_block = "for(var l=arguments.length,bg=m$block_given_bool(arguments[l-1]),l=bg?l-1:l,i=#{argument_sexps.size - 1},#{splat_arg}=[];i<l;++i){#{splat_arg}.push(arguments[i]);};var #{block_arg_sexp.last rescue :_block}=(bg?c$Proc.m$new(arguments[arguments.length-1]):nil)" if splat_arg && block_arg_sexp
102
+ block_arg = "var z=arguments[arguments.length-1],bg=m$block_given_bool(z),#{block_arg_sexp.last rescue :_block}=bg?c$Proc.m$new(z):nil" if block_arg_sexp && !splat_arg
103
+ args_checker = "$a(%s,%s,arguments,%s)" % [minimum_args, (splat_arg ? -1 : maximum_args), (splat_block || block_arg ? "bg?1:0" : "arguments[arguments.length-1]&&arguments[arguments.length-1].__block__?1:0")] if Red.debug && ![:new, :initialize].include?(function_name_sexp)
100
104
  defaults = defaults_sexp.red!(:as_argument_default => true) if defaults_sexp
101
105
  arguments = args_array.join(",")
102
106
  scope = scope_sexp.red!(:force_return => function != 'initialize')
103
- contents = [splatten_args, block_arg, defaults, scope].compact.join(";")
107
+ contents = [(splatten_args || splat_block || block_arg), args_checker, defaults, scope].compact.join(";")
104
108
  if options[:as_class_eval]
105
109
  string = "_.m$%s=function(%s){%s;}"
106
110
  else
@@ -130,12 +134,16 @@ module Red
130
134
  splat_arg = argument_sexps.pop.to_s[1..-1] if argument_sexps.last && argument_sexps.last.to_s.include?('*')
131
135
  argument_sexps += [block_arg_sexp.last] if block_arg_sexp
132
136
  args_array = argument_sexps.map {|argument| argument.red! }
133
- splatten_args = "for(var bg=m$blockGivenBool(arguments[arguments.length-1]),l=bg?arguments.length-1:arguments.length,i=#{block_arg_sexp ? argument_sexps.size - 1 : argument_sexps.size},#{splat_arg}=[];i<l;++i){#{splat_arg}.push(arguments[i]);};var #{block_arg_sexp.last rescue :_block}=(bg?c$Proc.m$new(arguments[arguments.length-1]):nil)" if splat_arg
134
- block_arg = "var #{block_arg_sexp.last rescue :_block}=(m$blockGivenBool(arguments[arguments.length-1])?c$Proc.m$new(arguments[arguments.length-1]):nil)" if block_arg_sexp && !splat_arg
137
+ maximum_args = args_array.length - (block_arg_sexp ? 1 : 0)
138
+ minimum_args = maximum_args - (defaults_sexp ? defaults_sexp.flatten.select {|x| x == :lasgn}.length : 0)
139
+ splatten_args = "for(var l=arguments.length,i=#{argument_sexps.size},#{splat_arg}=[];i<l;++i){#{splat_arg}.push(arguments[i]);}" if splat_arg && !block_arg_sexp
140
+ splat_block = "for(var l=arguments.length,bg=m$block_given_bool(arguments[l-1]),l=bg?l-1:l,i=#{argument_sexps.size - 1},#{splat_arg}=[];i<l;++i){#{splat_arg}.push(arguments[i]);};var #{block_arg_sexp.last rescue :_block}=(bg?c$Proc.m$new(arguments[arguments.length-1]):nil)" if splat_arg && block_arg_sexp
141
+ block_arg = "var z=arguments[arguments.length-1],bg=m$block_given_bool(z),#{block_arg_sexp.last rescue :_block}=bg?c$Proc.m$new(z):nil" if block_arg_sexp && !splat_arg
142
+ args_checker = "$a(%s,%s,arguments,%s)" % [minimum_args, (splat_arg ? -1 : maximum_args), (splat_block || block_arg ? "bg?1:0" : 0)]#{}"arguments[arguments.length-1]&&arguments[arguments.length-1].__block__?1:0")]
135
143
  defaults = defaults_sexp.red!(:as_argument_default => true) if defaults_sexp
136
144
  arguments = args_array.join(",")
137
145
  scope = scope_sexp.red!(:force_return => function != 'initialize')
138
- contents = [splatten_args, block_arg, defaults, scope].compact.join(";")
146
+ contents = [(splatten_args || splat_block || block_arg), args_checker, defaults, scope].compact.join(";")
139
147
  self << "%s=function(%s){%s;}" % [singleton, arguments, contents]
140
148
  @@red_block_arg = nil
141
149
  @@red_function = nil
@@ -28,7 +28,7 @@ module Red
28
28
  # as_argument: duplicates :force_return and adds "function() {
29
29
  # <multiline block>; }()" wrapper to the entire block.
30
30
  options = expression_sexps.pop
31
- if options[:as_argument] || options[:as_assignment] || options[:force_return] && expression_sexps.last.is_a?(::Array) && !expression_sexps.last.is_sexp?(:rescue, :ensure, :begin) && (expression_sexps.last.first == :iter ? true : !expression_sexps.last.flatten.include?(:return))
31
+ if options[:as_argument] || options[:as_assignment] || options.delete(:force_return) && expression_sexps.last.is_a?(::Array) && !expression_sexps.last.is_sexp?(:rescue, :ensure, :begin) && (expression_sexps.last.first == :iter ? true : !expression_sexps.last.flatten.include?(:return))
32
32
  returner = "return %s" % [expression_sexps.pop.red!(:as_argument => true)]
33
33
  end
34
34
  string = options[:as_argument] || options[:as_assignment] ? "function(){%s;}.m$(this)()" : "%s"
@@ -46,11 +46,14 @@ module Red
46
46
  def initialize(expression_a_sexp, expression_b_sexp, options)
47
47
  a = expression_a_sexp.red!(:as_argument => true)
48
48
  b = expression_b_sexp.red!(:as_argument => true)
49
- d = @@red_boolean.succ!.dup
50
- e = @@red_boolean.succ!.dup
51
- f = @@red_boolean.succ!.dup
52
- string = "($.%s=$T(%s)?($.%s=$T($.%s=%s)?$.%s:$.%s):$.%s)" % [d, '%s', f, e, '%s', e, f, d]
53
- self << string % [a,b]
49
+ self << self.class.string % [a, b]
50
+ end
51
+
52
+ def self.string # :nodoc:
53
+ a = @@red_boolean.succ!.dup
54
+ b = @@red_boolean.succ!.dup
55
+ c = @@red_boolean.succ!.dup
56
+ "(($.%s=$T(%s))?(($.%s=$T($.%s=%s))?$.%s:$.%s):$.%s)" % [a, '%s', c, b, '%s', b, c, a]
54
57
  end
55
58
  end
56
59
 
@@ -59,9 +62,12 @@ module Red
59
62
  def initialize(expression_a_sexp, expression_b_sexp, options)
60
63
  a = expression_a_sexp.red!(:as_argument => true)
61
64
  b = expression_b_sexp.red!(:as_argument => true)
62
- c = @@red_boolean.succ!.dup
63
- string = "($T($.%s=%s)?$.%s:%s)" % [c, '%s', c, '%s']
64
- self << string % [a,b]
65
+ self << self.class.string % [a, b]
66
+ end
67
+
68
+ def self.string
69
+ a = @@red_boolean.succ!.dup
70
+ "($T($.%s=%s)?$.%s:%s)" % [a, '%s', a, '%s']
65
71
  end
66
72
  end
67
73
  end
data/lib/red/version.rb CHANGED
@@ -1,8 +1,8 @@
1
1
  module Red
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 4
4
- MINOR = 0
5
- TINY = 6
4
+ MINOR = 1
5
+ TINY = 0
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
data/lib/red.rb CHANGED
@@ -193,6 +193,7 @@ module Red # :nodoc:
193
193
  block_given?
194
194
  call
195
195
  class
196
+ each
196
197
  extend_object
197
198
  extended
198
199
  hash
@@ -206,12 +207,14 @@ module Red # :nodoc:
206
207
  new
207
208
  raise
208
209
  sprintf
210
+ superclass
209
211
  to_proc
210
212
  to_s
211
213
  to_str
212
214
  }.map {|m| m.to_sym }
213
215
 
214
- def self.init
216
+ def self.init(file = '')
217
+ @@red_filepath = File.dirname(File.expand_path(file))
215
218
  @@namespace_stack = []
216
219
  @@red_constants = NATIVE_CONSTANTS
217
220
  @@red_methods = INTERNAL_METHODS
@@ -219,10 +222,15 @@ module Red # :nodoc:
219
222
  @@red_singleton = nil
220
223
  @@red_block_arg = nil
221
224
  @@red_import = false
222
- @@red_boolean = 'a'
225
+ @@red_boolean = '`'
226
+ @@red_required = []
223
227
  return true
224
228
  end
225
229
 
230
+ def self.debug
231
+ false
232
+ end
233
+
226
234
  def red!(options = {}, reset = false)
227
235
  case self
228
236
  when Array