goodguide-gibbon 0.6.1 → 0.6.2

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -3,7 +3,11 @@ gemspec
3
3
 
4
4
  gem 'minitest', '~> 4.0'
5
5
  gem 'wrong'
6
+
6
7
  gem 'pry'
7
- gem 'pry-debugger'
8
+
9
+ platforms :ruby do
10
+ gem 'pry-debugger'
11
+ end
8
12
 
9
13
  gem 'rake'
@@ -21,5 +21,9 @@ Gem::Specification.new do |s|
21
21
  'vendor/gibbon/lib/gibbon.browser.dev.js',
22
22
  ]
23
23
 
24
- s.add_dependency 'therubyracer'
24
+ if defined?(JRUBY_VERSION)
25
+ s.add_dependency 'therubyrhino'
26
+ else
27
+ s.add_dependency 'therubyracer'
28
+ end
25
29
  end
@@ -1,4 +1,18 @@
1
- require 'v8' # therubyracer
1
+ if defined?(JRUBY_VERSION)
2
+ require 'rhino' # therubyrhino
3
+ JSError = org.mozilla.javascript.RhinoException
4
+ JSContext = Rhino::Context
5
+ JSArray = Rhino::JS::NativeArray
6
+ JSObject = Rhino::JS::NativeObject
7
+ JSString = Java::OrgMozillaJavascript::ConsString
8
+ else
9
+ require 'v8' # therubyracer
10
+ JSError = V8::Error
11
+ JSContext = V8::Context
12
+ JSArray = V8::Array
13
+ JSObject = V8::Object
14
+ JSString = String
15
+ end
2
16
 
3
17
  require 'pathname'
4
18
 
@@ -11,7 +25,8 @@ module GoodGuide
11
25
 
12
26
  ruby_hash = { '__isHash__' => true }
13
27
 
14
- js_hash[:each].methodcall(js_hash, lambda { |this, k, v|
28
+ js_hash[:each].methodcall(js_hash, lambda { |a, b, c|
29
+ k, v = defined?(JRUBY_VERSION) ? [a, b] : [b, c]
15
30
  ruby_hash[k] = obj_to_ruby(v)
16
31
  })
17
32
 
@@ -36,7 +51,7 @@ module GoodGuide
36
51
  constructor = gibbon[type]
37
52
  raise "unknown union #{type}" unless constructor && constructor.tags
38
53
  names = constructor.tags[tag]
39
- raise "unknown tag #{tag}" unless names.is_a? V8::Array
54
+ raise "unknown tag #{tag}" unless names.is_a?(JSArray) or names.is_a?(Array)
40
55
 
41
56
  vals = names.map do |name|
42
57
  obj_to_js(o[name])
@@ -53,9 +68,11 @@ module GoodGuide
53
68
 
54
69
  def obj_to_ruby(o)
55
70
  case o
56
- when V8::Array
71
+ when JSArray, Array
57
72
  o.map { |x| obj_to_ruby(x) }
58
- when V8::Object
73
+ when JSString
74
+ o.to_s
75
+ when JSObject
59
76
  if o[:__isHash__]
60
77
  hash_to_ruby(o)
61
78
  elsif o[:__isVariant__]
@@ -247,6 +264,8 @@ module GoodGuide
247
264
 
248
265
  def proc_for(method)
249
266
  lambda do |this, *args|
267
+ args = ([this] + args).compact if defined?(JRUBY_VERSION)
268
+
250
269
  cb = args.pop
251
270
  err, val = begin
252
271
  [nil, send(method, *args)]
@@ -332,7 +351,7 @@ module GoodGuide
332
351
 
333
352
  def parse(str)
334
353
  obj_to_ruby self.gibbon.parse(str)
335
- rescue V8::Error => e
354
+ rescue JSError => e
336
355
  raise SemanticError.new([{'_tag' => 'parse', 'message' => e.value}])
337
356
  end
338
357
 
@@ -360,22 +379,28 @@ module GoodGuide
360
379
  def capture(&b)
361
380
  output = nil
362
381
  error = nil
363
- b.call do |this, error_, output_|
364
- output, error = output_, error_
382
+ b.call do |*args|
383
+ # Rhino doesn't get "this", but V8 does.
384
+ args.shift unless defined?(JRUBY_VERSION)
385
+ error, output = args[0..1]
365
386
  end
366
387
 
367
388
  [output, error]
368
389
  end
369
390
  end
370
391
 
371
- class JS < V8::Context
392
+ class JS < JSContext
372
393
  def self.default
373
394
  @default ||= new
374
395
  end
375
396
 
376
397
  class Console
377
398
  def log
378
- @log ||= proc { |_, *a| puts a.map(&:to_s).join(' ') }
399
+ @log ||= if defined?(JRUBY_VERSION)
400
+ proc { |*a| puts a.map(&:to_s).join(' ') }
401
+ else
402
+ proc { |_, *a| puts a.map(&:to_s).join(' ') }
403
+ end
379
404
  end
380
405
  end
381
406
 
@@ -387,9 +412,9 @@ module GoodGuide
387
412
  self[:console] = Console.new
388
413
 
389
414
  if @debug
390
- load GoodGuide::Gibbon.dev_js_lib
415
+ load GoodGuide::Gibbon.dev_js_lib.to_s
391
416
  else
392
- load GoodGuide::Gibbon.js_lib
417
+ load GoodGuide::Gibbon.js_lib.to_s
393
418
  end
394
419
  end
395
420
 
@@ -1,7 +1,7 @@
1
1
  module GoodGuide
2
2
  module Gibbon
3
3
  def self.version
4
- '0.6.1'
4
+ '0.6.2'
5
5
  end
6
6
  end
7
7
  end
@@ -1233,7 +1233,7 @@ parse = Gibbon.parse = (function() {
1233
1233
  lsplat = multiline(string('[*'));
1234
1234
  rsplat = lexeme(string('*]'));
1235
1235
  query = lexeme(string('.').then(identifier));
1236
- queryArg = lexeme(regex(/^[\w-]+/));
1236
+ queryArg = lexeme(regex(/^\w[\w-]*/));
1237
1237
  accessor = lexeme(string('@').then(identifier));
1238
1238
  name = lexeme(identifier);
1239
1239
  str = lexeme(string("'").then(regex(/^[^']*/)).skip(string("'")));
@@ -3046,8 +3046,8 @@ Gibbon.Dependency = Dependency = (function(_super) {
3046
3046
  query: function(entity, query) {
3047
3047
  return "" + (JSON.stringify(query)) + "<" + entity + ">";
3048
3048
  },
3049
- lexical: function(definition) {
3050
- return "@" + definition.name;
3049
+ lexical: function(key) {
3050
+ return "@" + key;
3051
3051
  },
3052
3052
  failure: function(failure) {
3053
3053
  return "!";
@@ -3594,6 +3594,10 @@ Gibbon.Core = Core = (function(_super) {
3594
3594
  });
3595
3595
  };
3596
3596
 
3597
+ Core.prototype.failIf = function(message, f) {
3598
+ return f(this).branch(Core.fail(message), this);
3599
+ };
3600
+
3597
3601
  Core.prototype.alwaysFails = function() {
3598
3602
  return this.cases({
3599
3603
  query: function() {
@@ -6404,9 +6408,12 @@ Gibbon.codegen = (function() {
6404
6408
  })();
6405
6409
 
6406
6410
  stdlib = Gibbon.stdlib = (function() {
6407
- var FALSE, TRUE, equals;
6411
+ var FALSE, TRUE, equals, isEmpty;
6408
6412
  TRUE = Core.constant(true);
6409
6413
  FALSE = Core.constant(false);
6414
+ isEmpty = function(list) {
6415
+ return list.len().op2('===', Core.constant(0));
6416
+ };
6410
6417
  equals = function(x, y, type) {
6411
6418
  var direct;
6412
6419
  direct = function() {
@@ -6526,9 +6533,7 @@ stdlib = Gibbon.stdlib = (function() {
6526
6533
  },
6527
6534
  "empty?": {
6528
6535
  type: parse.type('empty? = [%] -> bool'),
6529
- compile: function(list) {
6530
- return list.len().op2('===', Core.constant(0));
6531
- }
6536
+ compile: isEmpty
6532
6537
  },
6533
6538
  weight: {
6534
6539
  type: parse.type('weight [numeric : numeric] = % -> numeric'),
@@ -6600,6 +6605,24 @@ stdlib = Gibbon.stdlib = (function() {
6600
6605
  });
6601
6606
  }
6602
6607
  },
6608
+ max: {
6609
+ type: parse.type('max = [numeric] -> numeric'),
6610
+ compile: function(list) {
6611
+ list = list.failIf('max: empty list', isEmpty);
6612
+ return list.foldList(Core.constant(-Infinity), function(el, next) {
6613
+ return el.op2('>', next).branch(el, next);
6614
+ });
6615
+ }
6616
+ },
6617
+ min: {
6618
+ type: parse.type('min = [numeric] -> numeric'),
6619
+ compile: function(list) {
6620
+ list = list.failIf('min: empty list', isEmpty);
6621
+ return list.foldList(Core.constant(Infinity), function(el, next) {
6622
+ return el.op2('<', next).branch(el, next);
6623
+ });
6624
+ }
6625
+ },
6603
6626
  "case-sum": {
6604
6627
  type: parse.type('case-sum [bool : numeric] = % -> numeric'),
6605
6628
  compile: function(_, _arg) {
@@ -6635,6 +6658,25 @@ stdlib = Gibbon.stdlib = (function() {
6635
6658
  return input.op2('+', num.op1('-'));
6636
6659
  }
6637
6660
  },
6661
+ mul: {
6662
+ type: parse.type('mul numeric = numeric -> numeric'),
6663
+ compile: function(input, _arg) {
6664
+ var num;
6665
+ num = _arg[0];
6666
+ return input.op2('*', num);
6667
+ }
6668
+ },
6669
+ div: {
6670
+ type: parse.type('div numeric = numeric -> numeric'),
6671
+ compile: function(input, _arg) {
6672
+ var num;
6673
+ num = _arg[0];
6674
+ num = num.failIf('division by zero', function(n) {
6675
+ return n.op2('===', Core.constant(0));
6676
+ });
6677
+ return input.op2('/', num);
6678
+ }
6679
+ },
6638
6680
  id: {
6639
6681
  type: parse.type('id = %a -> %a'),
6640
6682
  compile: function(input) {
@@ -1223,7 +1223,7 @@ parse = Gibbon.parse = (function() {
1223
1223
  lsplat = multiline(string('[*'));
1224
1224
  rsplat = lexeme(string('*]'));
1225
1225
  query = lexeme(string('.').then(identifier));
1226
- queryArg = lexeme(regex(/^[\w-]+/));
1226
+ queryArg = lexeme(regex(/^\w[\w-]*/));
1227
1227
  accessor = lexeme(string('@').then(identifier));
1228
1228
  name = lexeme(identifier);
1229
1229
  str = lexeme(string("'").then(regex(/^[^']*/)).skip(string("'")));
@@ -3018,8 +3018,8 @@ Gibbon.Dependency = Dependency = (function(_super) {
3018
3018
  query: function(entity, query) {
3019
3019
  return "" + (JSON.stringify(query)) + "<" + entity + ">";
3020
3020
  },
3021
- lexical: function(definition) {
3022
- return "@" + definition.name;
3021
+ lexical: function(key) {
3022
+ return "@" + key;
3023
3023
  },
3024
3024
  failure: function(failure) {
3025
3025
  return "!";
@@ -3566,6 +3566,10 @@ Gibbon.Core = Core = (function(_super) {
3566
3566
  });
3567
3567
  };
3568
3568
 
3569
+ Core.prototype.failIf = function(message, f) {
3570
+ return f(this).branch(Core.fail(message), this);
3571
+ };
3572
+
3569
3573
  Core.prototype.alwaysFails = function() {
3570
3574
  return this.cases({
3571
3575
  query: function() {
@@ -6376,9 +6380,12 @@ Gibbon.codegen = (function() {
6376
6380
  })();
6377
6381
 
6378
6382
  stdlib = Gibbon.stdlib = (function() {
6379
- var FALSE, TRUE, equals;
6383
+ var FALSE, TRUE, equals, isEmpty;
6380
6384
  TRUE = Core.constant(true);
6381
6385
  FALSE = Core.constant(false);
6386
+ isEmpty = function(list) {
6387
+ return list.len().op2('===', Core.constant(0));
6388
+ };
6382
6389
  equals = function(x, y, type) {
6383
6390
  var direct;
6384
6391
  direct = function() {
@@ -6498,9 +6505,7 @@ stdlib = Gibbon.stdlib = (function() {
6498
6505
  },
6499
6506
  "empty?": {
6500
6507
  type: parse.type('empty? = [%] -> bool'),
6501
- compile: function(list) {
6502
- return list.len().op2('===', Core.constant(0));
6503
- }
6508
+ compile: isEmpty
6504
6509
  },
6505
6510
  weight: {
6506
6511
  type: parse.type('weight [numeric : numeric] = % -> numeric'),
@@ -6572,6 +6577,24 @@ stdlib = Gibbon.stdlib = (function() {
6572
6577
  });
6573
6578
  }
6574
6579
  },
6580
+ max: {
6581
+ type: parse.type('max = [numeric] -> numeric'),
6582
+ compile: function(list) {
6583
+ list = list.failIf('max: empty list', isEmpty);
6584
+ return list.foldList(Core.constant(-Infinity), function(el, next) {
6585
+ return el.op2('>', next).branch(el, next);
6586
+ });
6587
+ }
6588
+ },
6589
+ min: {
6590
+ type: parse.type('min = [numeric] -> numeric'),
6591
+ compile: function(list) {
6592
+ list = list.failIf('min: empty list', isEmpty);
6593
+ return list.foldList(Core.constant(Infinity), function(el, next) {
6594
+ return el.op2('<', next).branch(el, next);
6595
+ });
6596
+ }
6597
+ },
6575
6598
  "case-sum": {
6576
6599
  type: parse.type('case-sum [bool : numeric] = % -> numeric'),
6577
6600
  compile: function(_, _arg) {
@@ -6607,6 +6630,25 @@ stdlib = Gibbon.stdlib = (function() {
6607
6630
  return input.op2('+', num.op1('-'));
6608
6631
  }
6609
6632
  },
6633
+ mul: {
6634
+ type: parse.type('mul numeric = numeric -> numeric'),
6635
+ compile: function(input, _arg) {
6636
+ var num;
6637
+ num = _arg[0];
6638
+ return input.op2('*', num);
6639
+ }
6640
+ },
6641
+ div: {
6642
+ type: parse.type('div numeric = numeric -> numeric'),
6643
+ compile: function(input, _arg) {
6644
+ var num;
6645
+ num = _arg[0];
6646
+ num = num.failIf('division by zero', function(n) {
6647
+ return n.op2('===', Core.constant(0));
6648
+ });
6649
+ return input.op2('/', num);
6650
+ }
6651
+ },
6610
6652
  id: {
6611
6653
  type: parse.type('id = %a -> %a'),
6612
6654
  compile: function(input) {
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: goodguide-gibbon
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.1
4
+ version: 0.6.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-01-28 00:00:00.000000000 Z
12
+ date: 2014-01-29 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: therubyracer