opal 0.3.29 → 0.3.30

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/core/json.rb CHANGED
@@ -38,12 +38,11 @@ module JSON
38
38
  return arr;
39
39
  }
40
40
  else {
41
- var hash = #{ {} }, v, map = hash.map, keys = hash.keys;
41
+ var hash = #{ {} }, v, map = hash.map;
42
42
 
43
43
  for (var k in value) {
44
44
  if (__hasOwn.call(value, k)) {
45
45
  v = to_opal(value[k]);
46
- keys.push(k);
47
46
  map[k] = v;
48
47
  }
49
48
  }
data/core/kernel.rb CHANGED
@@ -11,6 +11,23 @@ module Kernel
11
11
  `#{self} == other`
12
12
  end
13
13
 
14
+ def method(name)
15
+ %x{
16
+ var recv = #{self},
17
+ meth = recv['$' + name],
18
+ func = function() {
19
+ return meth.apply(recv, __slice.call(arguments, 0));
20
+ };
21
+
22
+ if (!meth) {
23
+ #{ raise NameError };
24
+ }
25
+
26
+ func._klass = #{Method};
27
+ return func;
28
+ }
29
+ end
30
+
14
31
  def methods(all = true)
15
32
  %x{
16
33
  var methods = [];
@@ -83,6 +100,135 @@ module Kernel
83
100
  }
84
101
  end
85
102
 
103
+ def format(format, *args)
104
+ %x{
105
+ var idx = 0;
106
+ return format.replace(/%(\\d+\\$)?([-+ 0]*)(\\d*|\\*(\\d+\\$)?)(?:\\.(\\d*|\\*(\\d+\\$)?))?([cspdiubBoxXfgeEG])|(%%)/g, function(str, idx_str, flags, width_str, w_idx_str, prec_str, p_idx_str, spec, escaped) {
107
+ if (escaped) {
108
+ return '%';
109
+ }
110
+
111
+ var width,
112
+ prec,
113
+ is_integer_spec = ("diubBoxX".indexOf(spec) != -1),
114
+ is_float_spec = ("eEfgG".indexOf(spec) != -1),
115
+ prefix = '',
116
+ obj;
117
+
118
+ if (width_str === undefined) {
119
+ width = undefined;
120
+ } else if (width_str.charAt(0) == '*') {
121
+ var w_idx = idx++;
122
+ if (w_idx_str) {
123
+ w_idx = parseInt(w_idx_str, 10) - 1;
124
+ }
125
+ width = #{`args[w_idx]`.to_i};
126
+ } else {
127
+ width = parseInt(width_str, 10);
128
+ }
129
+ if (prec_str === undefined) {
130
+ prec = is_float_spec ? 6 : undefined;
131
+ } else if (prec_str.charAt(0) == '*') {
132
+ var p_idx = idx++;
133
+ if (p_idx_str) {
134
+ p_idx = parseInt(p_idx_str, 10) - 1;
135
+ }
136
+ prec = #{`args[p_idx]`.to_i};
137
+ } else {
138
+ prec = parseInt(prec_str, 10);
139
+ }
140
+ if (idx_str) {
141
+ idx = parseInt(idx_str, 10) - 1;
142
+ }
143
+ switch (spec) {
144
+ case 'c':
145
+ obj = args[idx];
146
+ if (obj._isString) {
147
+ str = obj.charAt(0);
148
+ } else {
149
+ str = String.fromCharCode(#{`obj`.to_i});
150
+ }
151
+ break;
152
+ case 's':
153
+ str = #{`args[idx]`.to_s};
154
+ if (prec !== undefined) {
155
+ str = str.substr(0, prec);
156
+ }
157
+ break;
158
+ case 'p':
159
+ str = #{`args[idx]`.inspect};
160
+ if (prec !== undefined) {
161
+ str = str.substr(0, prec);
162
+ }
163
+ break;
164
+ case 'd':
165
+ case 'i':
166
+ case 'u':
167
+ str = #{`args[idx]`.to_i}.toString();
168
+ break;
169
+ case 'b':
170
+ case 'B':
171
+ str = #{`args[idx]`.to_i}.toString(2);
172
+ break;
173
+ case 'o':
174
+ str = #{`args[idx]`.to_i}.toString(8);
175
+ break;
176
+ case 'x':
177
+ case 'X':
178
+ str = #{`args[idx]`.to_i}.toString(16);
179
+ break;
180
+ case 'e':
181
+ case 'E':
182
+ str = #{`args[idx]`.to_f}.toExponential(prec);
183
+ break;
184
+ case 'f':
185
+ str = #{`args[idx]`.to_f}.toFixed(prec);
186
+ break;
187
+ case 'g':
188
+ case 'G':
189
+ str = #{`args[idx]`.to_f}.toPrecision(prec);
190
+ break;
191
+ }
192
+ idx++;
193
+ if (is_integer_spec || is_float_spec) {
194
+ if (str.charAt(0) == '-') {
195
+ prefix = '-';
196
+ str = str.substr(1);
197
+ } else {
198
+ if (flags.indexOf('+') != -1) {
199
+ prefix = '+';
200
+ } else if (flags.indexOf(' ') != -1) {
201
+ prefix = ' ';
202
+ }
203
+ }
204
+ }
205
+ if (is_integer_spec && prec !== undefined) {
206
+ if (str.length < prec) {
207
+ str = #{'0' * `prec - str.length`} + str;
208
+ }
209
+ }
210
+ var total_len = prefix.length + str.length;
211
+ if (width !== undefined && total_len < width) {
212
+ if (flags.indexOf('-') != -1) {
213
+ str = str + #{' ' * `width - total_len`};
214
+ } else {
215
+ var pad_char = ' ';
216
+ if (flags.indexOf('0') != -1) {
217
+ str = #{'0' * `width - total_len`} + str;
218
+ } else {
219
+ prefix = #{' ' * `width - total_len`} + prefix;
220
+ }
221
+ }
222
+ }
223
+ var result = prefix + str;
224
+ if ('XEG'.indexOf(spec) != -1) {
225
+ result = result.toUpperCase();
226
+ }
227
+ return result;
228
+ });
229
+ }
230
+ end
231
+
86
232
  def hash
87
233
  `#{self}._id`
88
234
  end
@@ -184,6 +330,14 @@ module Kernel
184
330
  `#{self}._id || (#{self}._id = unique_id++)`
185
331
  end
186
332
 
333
+ def printf(*args)
334
+ if args.length > 0
335
+ fmt = args.shift
336
+ print format(fmt, *args)
337
+ end
338
+ nil
339
+ end
340
+
187
341
  def proc(&block)
188
342
  %x{
189
343
  if (block === nil) {
@@ -277,6 +431,8 @@ module Kernel
277
431
  }
278
432
  end
279
433
 
434
+ alias sprintf format
435
+
280
436
  def tap(&block)
281
437
  yield self
282
438
  self
@@ -293,4 +449,4 @@ module Kernel
293
449
  def to_s
294
450
  `return "#<" + #{self}._klass._name + ":" + #{self}._id + ">";`
295
451
  end
296
- end
452
+ end
data/core/load_order CHANGED
@@ -14,5 +14,6 @@ numeric
14
14
  proc
15
15
  range
16
16
  time
17
+ date
17
18
  json
18
- template
19
+ template
data/core/proc.rb CHANGED
@@ -27,4 +27,6 @@ class Proc < `Function`
27
27
  def arity
28
28
  `this.length - 1`
29
29
  end
30
- end
30
+ end
31
+
32
+ class Method < Proc; end
data/core/string.rb CHANGED
@@ -16,12 +16,11 @@ class String < `String`
16
16
  end
17
17
 
18
18
  def %(data)
19
- %x{
20
- var idx = 0;
21
- return #{self}.replace(/%((%)|s)/g, function (match) {
22
- return match[2] || data[idx++] || '';
23
- });
24
- }
19
+ if data.is_a?(Array)
20
+ format(self, *data)
21
+ else
22
+ format(self, data)
23
+ end
25
24
  end
26
25
 
27
26
  def *(count)
@@ -517,4 +516,4 @@ class String < `String`
517
516
  alias_native :upcase, :toUpperCase
518
517
  end
519
518
 
520
- Symbol = String
519
+ Symbol = String
data/core/time.rb CHANGED
@@ -56,6 +56,8 @@ class Time < `Date`
56
56
 
57
57
  alias_native :hour, :getHours
58
58
 
59
+ alias_native :inspect, :toString
60
+
59
61
  alias mday day
60
62
 
61
63
  alias_native :min, :getMinutes
@@ -92,6 +94,8 @@ class Time < `Date`
92
94
  `parseInt(#{self}.getTime() / 1000)`
93
95
  end
94
96
 
97
+ alias to_s inspect
98
+
95
99
  def tuesday?
96
100
  `#{self}.getDay() === 2`
97
101
  end
data/lib/opal.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'opal/parser'
2
+ require 'opal/erb'
2
3
  require 'opal/builder'
3
4
  require 'opal/version'
4
5
 
data/lib/opal/erb.rb ADDED
@@ -0,0 +1,13 @@
1
+ module Opal
2
+ def self.parse_erb(str, name = '(erb)')
3
+ body = str.gsub('"', '\\"').gsub(/<%=([\s\S]+?)%>/) do
4
+ inner = $1.gsub(/\\'/, "'").gsub(/\\"/, '"')
5
+ "\")\nout.<<(#{ inner })\nout.<<(\""
6
+ end.gsub(/<%([\s\S]+?)%>/) do
7
+ "\")\n#{ $1 }\nout.<<(\""
8
+ end
9
+
10
+ code = "Template.new('#{name}') do\nout = []\nout.<<(\"#{ body }\")\nout.join\nend\n"
11
+ "// #{ name } (erb)\n#{ Opal.parse(code) }\n"
12
+ end
13
+ end
data/lib/opal/lexer.rb CHANGED
@@ -183,13 +183,8 @@ module Opal
183
183
 
184
184
  if rest
185
185
  res << rest
186
- @scope.add_local begin
187
- rest.to_s[1..-1].to_sym
188
- rescue ArgumentError => e
189
- # Rescue from empty symbol error on Ruby 1.8
190
- raise unless e.message =~ /empty/
191
- ''
192
- end
186
+ rest_str = rest.to_s[1..-1]
187
+ @scope.add_local rest_str.to_sym unless rest_str.empty?
193
188
  end
194
189
 
195
190
  if block
@@ -732,6 +727,8 @@ module Opal
732
727
  @string_parse = { :beg => '/', :end => '/', :interpolate => true, :regexp => true }
733
728
  return :REGEXP_BEG, scanner.matched
734
729
  end
730
+ else
731
+ @lex_state = :expr_beg
735
732
  end
736
733
 
737
734
  return '/', '/'
@@ -1151,7 +1148,7 @@ module Opal
1151
1148
 
1152
1149
  elsif scanner.check(/[0-9]/)
1153
1150
  @lex_state = :expr_end
1154
- if scanner.scan(/[\d_]+\.[\d_]+\b/)
1151
+ if scanner.scan(/[\d_]+\.[\d_]+\b|[\d_]+(\.[\d_]+)?[eE][-+]?[\d_]+\b/)
1155
1152
  return [:FLOAT, scanner.matched.gsub(/_/, '').to_f]
1156
1153
  elsif scanner.scan(/[\d_]+\b/)
1157
1154
  return [:INTEGER, scanner.matched.gsub(/_/, '').to_i]
@@ -1276,7 +1273,10 @@ module Opal
1276
1273
 
1277
1274
  when 'rescue'
1278
1275
  return :IDENTIFIER, matched if [:expr_dot, :expr_fname].include? @lex_state
1279
- return :RESCUE, matched if @lex_state == :expr_beg
1276
+ if @lex_state == :expr_beg
1277
+ @lex_state = :expr_mid
1278
+ return :RESCUE, matched
1279
+ end
1280
1280
  @lex_state = :expr_beg
1281
1281
  return :RESCUE_MOD, matched
1282
1282
 
data/lib/opal/parser.rb CHANGED
@@ -179,14 +179,14 @@ module Opal
179
179
  code = @indent + process(s(:scope, sexp), :stmt)
180
180
  }
181
181
 
182
- vars << "__opal = Opal"
183
- vars << "self = __opal.top"
184
- vars << "__scope = __opal"
185
- vars << "nil = __opal.nil"
186
- vars << "def = #{current_self}._klass.prototype" if @scope.defines_defn
187
- vars.concat @helpers.keys.map { |h| "__#{h} = __opal.#{h}" }
182
+ @scope.add_temp "__opal = Opal"
183
+ @scope.add_temp "self = __opal.top"
184
+ @scope.add_temp "__scope = __opal"
185
+ @scope.add_temp "nil = __opal.nil"
186
+ @scope.add_temp "def = #{current_self}._klass.prototype" if @scope.defines_defn
187
+ @helpers.keys.each { |h| @scope.add_temp "__#{h} = __opal.#{h}" }
188
188
 
189
- code = "#{INDENT}var #{vars.join ', '};\n" + INDENT + @scope.to_vars + "\n" + code
189
+ code = INDENT + @scope.to_vars + "\n" + code
190
190
  end
191
191
 
192
192
  "(function() {\n#{ code }\n})();"
@@ -497,15 +497,19 @@ module Opal
497
497
  meth, recv, arg = sexp
498
498
  mid = mid_to_jsid meth.to_s
499
499
 
500
- with_temp do |a|
501
- with_temp do |b|
502
- l = process recv, :expr
503
- r = process arg, :expr
500
+ if @parser_uses_optimized_operators
501
+ with_temp do |a|
502
+ with_temp do |b|
503
+ l = process recv, :expr
504
+ r = process arg, :expr
504
505
 
505
- "(%s = %s, %s = %s, typeof(%s) === 'number' ? %s %s %s : %s%s(%s))" %
506
- [a, l, b, r, a, a, meth.to_s, b, a, mid, b]
506
+ "(%s = %s, %s = %s, typeof(%s) === 'number' ? %s %s %s : %s%s(%s))" %
507
+ [a, l, b, r, a, a, meth.to_s, b, a, mid, b]
508
+ end
507
509
  end
508
510
  end
511
+
512
+ "#{process recv, :recv}#{mid}(#{process arg, :expr})"
509
513
  end
510
514
 
511
515
  def js_block_given(sexp, level)
@@ -1233,7 +1237,7 @@ module Opal
1233
1237
  map = hash_keys.map { |k| "#{k}: #{hash_obj[k]}"}
1234
1238
 
1235
1239
  @helpers[:hash2] = true
1236
- "__hash2([#{hash_keys.join ', '}], {#{map.join(', ')}})"
1240
+ "__hash2({#{map.join(', ')}})"
1237
1241
  else
1238
1242
  @helpers[:hash] = true
1239
1243
  "__hash(#{sexp.map { |p| process p, :expr }.join ', '})"
@@ -1871,18 +1875,18 @@ module Opal
1871
1875
 
1872
1876
  def process_rescue(exp, level)
1873
1877
  body = exp.first.first == :resbody ? s(:nil) : exp.shift
1874
- body = process body, level
1878
+ body = indent { process body, level }
1875
1879
 
1876
1880
  parts = []
1877
1881
  until exp.empty?
1878
- part = process exp.shift, level
1882
+ part = indent { process exp.shift, level }
1879
1883
  part = "else " + part unless parts.empty?
1880
1884
  parts << part
1881
1885
  end
1882
1886
  # if no rescue statement captures our error, we should rethrow
1883
- parts << "else { throw $err; }"
1887
+ parts << indent { "else { throw $err; }" }
1884
1888
 
1885
- code = "try {#@space#{body}#@space} catch ($err) {#@space#{parts.join @space}#{@space}}"
1889
+ code = "try {#@space#{INDENT}#{body}#@space} catch ($err) {#@space#{parts.join @space}#{@space}}"
1886
1890
  code = "(function() { #{code} }).call(#{current_self})" if level == :expr
1887
1891
 
1888
1892
  code
data/lib/opal/scope.rb CHANGED
@@ -173,7 +173,7 @@ module Opal
173
173
  def new_temp
174
174
  return @queue.pop unless @queue.empty?
175
175
 
176
- tmp = "__#{@unique}"
176
+ tmp = "_#{@unique}"
177
177
  @unique = @unique.succ
178
178
  @temps << tmp
179
179
  tmp
data/lib/opal/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Opal
2
- VERSION = '0.3.29'
2
+ VERSION = '0.3.30'
3
3
  end
@@ -0,0 +1,8 @@
1
+ describe "Date.new" do
2
+ it "creates a date with arguments" do
3
+ d = Date.new(2000, 3, 5)
4
+ d.year.should == 2000
5
+ d.month.should == 3
6
+ d.day.should == 5
7
+ end
8
+ end
@@ -0,0 +1,5 @@
1
+ describe "Date#to_s" do
2
+ it "returns a string representation of date (YYYY-MM-DD)" do
3
+ Date.new(2012, 10, 26).to_s.should == "2012-10-26"
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ describe "Date.today" do
2
+ it "creates a new instance for current date" do
3
+ Date.today.should be_kind_of(Date)
4
+ end
5
+ end