goodguide-gibbon 0.4.2 → 0.5.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.
@@ -9,22 +9,46 @@ module GoodGuide
9
9
  def hash_to_ruby(js_hash)
10
10
  return nil unless js_hash
11
11
 
12
- ruby_hash = {}
13
- iterator = lambda { |this, k, v|
14
- ruby_hash[k] = obj_to_ruby(v)
15
- }
12
+ ruby_hash = { '__isHash__' => true }
16
13
 
17
- js_hash[:each].methodcall js_hash, iterator
14
+ js_hash[:each].methodcall(js_hash, lambda { |this, k, v|
15
+ ruby_hash[k] = obj_to_ruby(v)
16
+ })
18
17
 
19
18
  ruby_hash
20
19
  end
21
20
 
22
- def hash_to_js(ruby_hash)
23
- js_hash = gibbon[:Hash].new
24
- ruby_hash.each do |k, v|
25
- js_hash.set(k, v)
21
+ def obj_to_js(o)
22
+ case o
23
+ when Array
24
+ o.map { |x| obj_to_js(x) }
25
+ when Hash
26
+ if o['__isHash__'] or o[:__isHash__]
27
+ js_hash = gibbon[:Hash].new
28
+ o.each do |k, v|
29
+ next if k.to_s == '__isHash__'
30
+ js_hash.set(k, obj_to_js(v))
31
+ end
32
+ js_hash
33
+ elsif o['_union'] or o[:_union]
34
+ union = o['_union'] or o[:_union]
35
+ tag = o['_tag'] or o[:_tag]
36
+ constructor = gibbon[union]
37
+ raise "unknown union #{union}" unless constructor && constructor.tags
38
+ names = constructor.tags[tag]
39
+ raise "unknown tag #{tag}" unless names.is_a? V8::Array
40
+
41
+ vals = names.map do |name|
42
+ obj_to_js(o[name])
43
+ end
44
+
45
+ constructor[tag].methodcall(constructor, *vals)
46
+ else
47
+ o
48
+ end
49
+ else
50
+ o
26
51
  end
27
- js_hash
28
52
  end
29
53
 
30
54
  def obj_to_ruby(o)
@@ -32,13 +56,17 @@ module GoodGuide
32
56
  when V8::Array
33
57
  o.map { |x| obj_to_ruby(x) }
34
58
  when V8::Object
35
- o = o.asJSON if o.respond_to? :asJSON
36
-
37
- out = {}
38
- o.each do |k, v|
39
- out[k] = obj_to_ruby(v)
59
+ if o[:__isHash__]
60
+ hash_to_ruby(o)
61
+ else
62
+ o = o.asJSON if o.respond_to? :asJSON
63
+
64
+ out = {}
65
+ o.each do |k, v|
66
+ out[k] = obj_to_ruby(v)
67
+ end
68
+ out
40
69
  end
41
- out
42
70
  else
43
71
  o
44
72
  end
@@ -160,10 +188,7 @@ module GoodGuide
160
188
  end
161
189
 
162
190
  def call(runtime_client, entity_id)
163
- # TODO
164
- context = Context.new
165
-
166
- values, error = context.eval_gibbon(
191
+ values, error = @context.eval_gibbon(
167
192
  self.semantics, entity_id, runtime_client.to_js
168
193
  )
169
194
 
@@ -273,6 +298,7 @@ module GoodGuide
273
298
  js = JS.new(js)
274
299
  end
275
300
 
301
+ @defer = js[:setTimeout]
276
302
  @gibbon = js.gibbon
277
303
  end
278
304
 
@@ -281,6 +307,8 @@ module GoodGuide
281
307
  end
282
308
 
283
309
  def analyze(syntax, global_table, static_client)
310
+ syntax = obj_to_js(syntax)
311
+
284
312
  semantics, error = capture do |&callback|
285
313
  gibbon.analyze(syntax, global_table, static_client, callback)
286
314
  end
@@ -289,7 +317,7 @@ module GoodGuide
289
317
  end
290
318
 
291
319
  def eval_gibbon(semantics, id, runtime_client)
292
- semantics = hash_to_js(semantics)
320
+ semantics = obj_to_js(semantics)
293
321
  values, error = capture do |&callback|
294
322
  gibbon.eval(semantics, 0, id, runtime_client, callback)
295
323
  end
@@ -307,7 +335,6 @@ module GoodGuide
307
335
 
308
336
  [output, error]
309
337
  end
310
-
311
338
  end
312
339
 
313
340
  class JS < V8::Context
@@ -1,7 +1,7 @@
1
1
  module GoodGuide
2
2
  module Gibbon
3
3
  def self.version
4
- '0.4.2'
4
+ '0.5.0'
5
5
  end
6
6
  end
7
7
  end
@@ -388,6 +388,10 @@ DEBUG.assert = function(msg, cond) {
388
388
  }
389
389
  };
390
390
 
391
+ DEBUG.getStackSize = function() {
392
+ return (new Error).stack.match(/\n/g).length;
393
+ };
394
+
391
395
  isArray = Array.isArray || function(arg) {
392
396
  return Object.prototype.toString.call(arg) === '[object Array]';
393
397
  };
@@ -448,8 +452,9 @@ asyncMap = function(list, mapper, cb) {
448
452
  seen += 1;
449
453
  output[i] = el;
450
454
  if (seen >= list.length) {
451
- return cb(output);
455
+ cb(output);
452
456
  }
457
+ return null;
453
458
  };
454
459
  };
455
460
  _results = [];
@@ -705,6 +710,8 @@ Gibbon.Hash = Hash = (function(_super) {
705
710
  return _ref;
706
711
  }
707
712
 
713
+ Hash.prototype.__isHash__ = true;
714
+
708
715
  salt = '<key>';
709
716
 
710
717
  Hash.prototype.loadKey = function(k) {
@@ -1287,7 +1294,7 @@ Gibbon.Semantic = Semantic = (function(_super) {
1287
1294
  block: ['body'],
1288
1295
  list: ['elements', 'squish'],
1289
1296
  flow: ['type', 'head', 'tail'],
1290
- func: ['name', 'args'],
1297
+ func: ['name', 'args', 'scope'],
1291
1298
  subst: ['flow'],
1292
1299
  defaulted: ['body', 'alternative']
1293
1300
  });
@@ -1722,6 +1729,7 @@ analyze = Gibbon.analyze = (function() {
1722
1729
  func = stdlib[name];
1723
1730
  ast = func.type;
1724
1731
  scope = new Hash;
1732
+ flow.head.__scope__ = scope;
1725
1733
  input = TypeExpr.fromAST(ast.input, scope);
1726
1734
  if (flow.tail) {
1727
1735
  push(TypeExpr.expr(flow.tail), input);
@@ -1961,13 +1969,13 @@ analyze = Gibbon.analyze = (function() {
1961
1969
  done = function() {
1962
1970
  var flowType, toSemanticTree;
1963
1971
  flowType = function(expr) {
1964
- if (!solutions.has(TypeExpr.expr(expr))) {
1972
+ if (!solutions.has(expr)) {
1965
1973
  if (errors.length === 0) {
1966
1974
  throw new Error('unsolved!');
1967
1975
  }
1968
1976
  return Type.abstract(TypeExpr.expr(expr));
1969
1977
  }
1970
- return solutions.get(TypeExpr.expr(expr)).realize();
1978
+ return solutions.get(expr).realize();
1971
1979
  };
1972
1980
  toSemanticTree = function(expr) {
1973
1981
  return expr.cases({
@@ -1975,7 +1983,7 @@ analyze = Gibbon.analyze = (function() {
1975
1983
  return Semantic.definition(dependencies, toSemanticTree(flow));
1976
1984
  },
1977
1985
  flow: function(head, tail) {
1978
- return Semantic.flow(flowType(this), toSemanticTree(head), tail && toSemanticTree(tail));
1986
+ return Semantic.flow(flowType(TypeExpr.expr(this)), toSemanticTree(head), tail && toSemanticTree(tail));
1979
1987
  },
1980
1988
  query: function(type, name) {
1981
1989
  var _this = this;
@@ -1987,8 +1995,13 @@ analyze = Gibbon.analyze = (function() {
1987
1995
  return semanticAccessors.get(this);
1988
1996
  },
1989
1997
  func: function(name, args) {
1990
- var a;
1991
- return Semantic.func(name, (function() {
1998
+ var a, scope, semArgs, solvedScope;
1999
+ scope = this.__scope__;
2000
+ solvedScope = new Hash;
2001
+ scope && scope.each(function(name, texpr) {
2002
+ return solvedScope.set(name, flowType(texpr));
2003
+ });
2004
+ semArgs = (function() {
1992
2005
  var _i, _len, _results;
1993
2006
  _results = [];
1994
2007
  for (_i = 0, _len = args.length; _i < _len; _i++) {
@@ -1996,7 +2009,8 @@ analyze = Gibbon.analyze = (function() {
1996
2009
  _results.push(toSemanticTree(a));
1997
2010
  }
1998
2011
  return _results;
1999
- })());
2012
+ })();
2013
+ return Semantic.func(name, semArgs, solvedScope);
2000
2014
  },
2001
2015
  pair: function(first, second) {
2002
2016
  return Semantic.pair(toSemanticTree(first), toSemanticTree(second));
@@ -2173,9 +2187,6 @@ analyze = Gibbon.analyze = (function() {
2173
2187
  })();
2174
2188
  return function(program, globalID, external, cb) {
2175
2189
  var constraints;
2176
- if (!(program instanceof AST)) {
2177
- program = AST.fromJSON(program);
2178
- }
2179
2190
  DEBUG.log();
2180
2191
  DEBUG.log(program.inspect());
2181
2192
  constraints = generate(globalID, external.analyzeQuery, program);
@@ -2183,14 +2194,11 @@ analyze = Gibbon.analyze = (function() {
2183
2194
  };
2184
2195
  })();
2185
2196
  // Generated by CoffeeScript 1.6.3
2186
- var Dependency, Failure, Promise, Value, eval_, _ref, _ref1, _ref2,
2197
+ var CachingPromise, Dependency, Failure, Promise, Thunk, UnitPromise, Value, eval_, _ref, _ref1, _ref2, _ref3,
2187
2198
  __hasProp = {}.hasOwnProperty,
2188
- __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
2189
- __slice = [].slice;
2199
+ __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
2190
2200
 
2191
2201
  Value = Gibbon.Value = Value = (function(_super) {
2192
- var thunksAreEqual;
2193
-
2194
2202
  __extends(Value, _super);
2195
2203
 
2196
2204
  function Value() {
@@ -2245,37 +2253,6 @@ Value = Gibbon.Value = Value = (function(_super) {
2245
2253
  }));
2246
2254
  };
2247
2255
 
2248
- thunksAreEqual = function(list1, list2) {
2249
- var i, out, step, x, zipped;
2250
- if (list1.length !== list2.length) {
2251
- return Promise.unit(Value.boolean(false));
2252
- }
2253
- zipped = (function() {
2254
- var _i, _len, _results;
2255
- _results = [];
2256
- for (i = _i = 0, _len = list1.length; _i < _len; i = ++_i) {
2257
- x = list1[i];
2258
- _results.push(Promise.combine(x, list2[i]));
2259
- }
2260
- return _results;
2261
- })();
2262
- step = function(_arg, next) {
2263
- var x, y;
2264
- x = _arg[0], y = _arg[1];
2265
- return x.equals(y).then(function(isEqual) {
2266
- if (isEqual.value) {
2267
- return next();
2268
- } else {
2269
- return Promise.unit(Value.boolean(false));
2270
- }
2271
- });
2272
- };
2273
- out = function() {
2274
- return Promise.unit(Value.boolean(true));
2275
- };
2276
- return Promise.iter(zipped, step, out);
2277
- };
2278
-
2279
2256
  Value.prototype.equals = function(other) {
2280
2257
  var wrap;
2281
2258
  wrap = function(b) {
@@ -2326,26 +2303,6 @@ Value = Gibbon.Value = Value = (function(_super) {
2326
2303
  });
2327
2304
  };
2328
2305
 
2329
- Value.prototype.mapAsync = function(f, cb) {
2330
- return this.cases({
2331
- list: function(els) {
2332
- return asyncMap(els, f, function(mapped) {
2333
- return Value.list(mapped);
2334
- });
2335
- },
2336
- pair: function(first, second) {
2337
- return asyncMap([first, second], f, function(_arg) {
2338
- var first, second;
2339
- first = _arg[0], second = _arg[1];
2340
- return Value.pair(first, second);
2341
- });
2342
- },
2343
- other: function() {
2344
- return cb(this);
2345
- }
2346
- });
2347
- };
2348
-
2349
2306
  Value.prototype.mapPromise = function(f) {
2350
2307
  return this.cases({
2351
2308
  list: function(promises) {
@@ -2391,16 +2348,47 @@ Value = Gibbon.Value = Value = (function(_super) {
2391
2348
 
2392
2349
  })(Union);
2393
2350
 
2351
+ Thunk = (function() {
2352
+ Thunk.trampoline = function(t) {
2353
+ while (t instanceof Thunk) {
2354
+ t = t.run();
2355
+ }
2356
+ return t;
2357
+ };
2358
+
2359
+ function Thunk(run) {
2360
+ this.run = run;
2361
+ }
2362
+
2363
+ return Thunk;
2364
+
2365
+ })();
2366
+
2394
2367
  Promise = (function() {
2395
- function Promise(force) {
2396
- this.force = force;
2368
+ function Promise(forceRaw) {
2369
+ this.forceRaw = forceRaw;
2397
2370
  }
2398
2371
 
2372
+ Promise.prototype.force = function(fail, cc) {
2373
+ return Thunk.trampoline(this.forceRaw(fail, cc));
2374
+ };
2375
+
2376
+ Promise.prototype.step = function(fail, cc) {
2377
+ var _this = this;
2378
+ return new Thunk(function() {
2379
+ return _this.forceRaw(fail, cc);
2380
+ });
2381
+ };
2382
+
2399
2383
  Promise.prototype.then = function(fn) {
2400
2384
  var _this = this;
2401
2385
  return new Promise(function(fail, cb) {
2402
- return _this.force(fail, function(val, deps) {
2403
- return fn(val, deps).depends(deps).force(fail, cb);
2386
+ return _this.step(fail, function(val, deps) {
2387
+ var next;
2388
+ next = fn(val, deps).depends(deps);
2389
+ return new Thunk(function() {
2390
+ return next.forceRaw(fail, cb);
2391
+ });
2404
2392
  });
2405
2393
  });
2406
2394
  };
@@ -2410,9 +2398,11 @@ Promise = (function() {
2410
2398
  return new Promise(function(fail, cb) {
2411
2399
  var rescue;
2412
2400
  rescue = function(failure) {
2413
- return fn(failure).depends([Dependency.failure(failure)]).force(fail, cb);
2401
+ var rescuer;
2402
+ rescuer = fn(failure).depends([Dependency.failure(failure)]);
2403
+ return rescuer.step(fail, cb);
2414
2404
  };
2415
- return _this.force(rescue, cb);
2405
+ return _this.step(rescue, cb);
2416
2406
  });
2417
2407
  };
2418
2408
 
@@ -2422,67 +2412,95 @@ Promise = (function() {
2422
2412
  });
2423
2413
  };
2424
2414
 
2425
- Promise.prototype.depends = function(deps) {
2415
+ Promise.prototype.mapDeps = function(f) {
2426
2416
  var _this = this;
2427
2417
  return new Promise(function(fail, cc) {
2428
- return _this.force(fail, function(val, prevDeps) {
2429
- return cc(val, prevDeps.concat(deps));
2418
+ return _this.step(fail, function(val, deps) {
2419
+ return new Thunk(function() {
2420
+ return cc(val, f(deps));
2421
+ });
2430
2422
  });
2431
2423
  });
2432
2424
  };
2433
2425
 
2434
- Promise.prototype.map = function(f) {
2435
- return this.then(function(v, d) {
2436
- return Promise.unit(f(v, d));
2426
+ Promise.prototype.depends = function(deps) {
2427
+ if (deps.length === 0) {
2428
+ return this;
2429
+ }
2430
+ return this.mapDeps(function(prevDeps) {
2431
+ return prevDeps.concat(deps);
2437
2432
  });
2438
2433
  };
2439
2434
 
2440
- Promise.prototype.mapDependencies = function(f) {
2441
- var _this = this;
2442
- return new Promise(function(fail, cc) {
2443
- return _this.force(fail, function(val, deps) {
2444
- return cc(val, f(deps));
2445
- });
2435
+ Promise.prototype.dependsOnly = function(deps) {
2436
+ return this.mapDeps(function() {
2437
+ return deps;
2438
+ });
2439
+ };
2440
+
2441
+ Promise.prototype.map = function(f) {
2442
+ return this.then(function(v, d) {
2443
+ return Promise.unit(f(v, d));
2446
2444
  });
2447
2445
  };
2448
2446
 
2449
2447
  Promise.prototype.after = function(f) {
2450
2448
  var _this = this;
2451
2449
  return new Promise(function(fail, cc) {
2452
- return _this.force(fail, function(val, deps) {
2450
+ return _this.step(fail, function(val, deps) {
2453
2451
  f(val, deps);
2454
- return cc(val, deps);
2452
+ return new Thunk(function() {
2453
+ return cc(val, deps);
2454
+ });
2455
2455
  });
2456
2456
  });
2457
2457
  };
2458
2458
 
2459
2459
  Promise.unit = function(e) {
2460
- return new Promise(function(_, f) {
2461
- return f(e, []);
2460
+ return new UnitPromise(function(_, cc) {
2461
+ return new Thunk(function() {
2462
+ return cc(e, []);
2463
+ });
2462
2464
  });
2463
2465
  };
2464
2466
 
2465
2467
  Promise.fail = function(fail) {
2466
2468
  return new Promise(function(f, _) {
2467
- return f(fail);
2469
+ return new Thunk(function() {
2470
+ return f(fail);
2471
+ });
2468
2472
  });
2469
2473
  };
2470
2474
 
2471
2475
  Promise.lazy = function(f) {
2472
2476
  return new Promise(function(fail, cc) {
2473
- return f().force(fail, cc);
2477
+ return f().step(fail, cc);
2474
2478
  });
2475
2479
  };
2476
2480
 
2477
- Promise.combine = function(thunks) {
2478
- return new Promise(function(fail, cb) {
2479
- var mapper;
2480
- mapper = function(thunk, push) {
2481
- return thunk.force(fail, function(val, deps) {
2481
+ Promise.prototype.cache = function() {
2482
+ return new CachingPromise(this.forceRaw);
2483
+ };
2484
+
2485
+ Promise.combine = function(promises) {
2486
+ if (promises.length === 0) {
2487
+ return Promise.unit([]);
2488
+ }
2489
+ if (promises.length === 1) {
2490
+ return promises[0].map(function(t) {
2491
+ return [t];
2492
+ });
2493
+ }
2494
+ return new Promise(function(fail, cc) {
2495
+ var isSynchronous, mapper, outThunk;
2496
+ isSynchronous = true;
2497
+ outThunk = null;
2498
+ mapper = function(promise, push) {
2499
+ return promise.force(fail, function(val, deps) {
2482
2500
  return push([val, deps]);
2483
2501
  });
2484
2502
  };
2485
- return asyncMap(thunks, mapper, function(vals) {
2503
+ asyncMap(promises, mapper, function(vals) {
2486
2504
  var outDeps, outVal, v;
2487
2505
  outVal = (function() {
2488
2506
  var _i, _len, _results;
@@ -2502,41 +2520,86 @@ Promise = (function() {
2502
2520
  }
2503
2521
  return _results;
2504
2522
  })());
2505
- return cb(outVal, outDeps);
2523
+ if (isSynchronous) {
2524
+ return outThunk = new Thunk(function() {
2525
+ return cc(outVal, outDeps);
2526
+ });
2527
+ } else {
2528
+ return Thunk.trampoline(cc(outVal, outDeps));
2529
+ }
2506
2530
  });
2531
+ isSynchronous = false;
2532
+ return outThunk;
2507
2533
  });
2508
2534
  };
2509
2535
 
2510
- Promise.iter = function(list, step, out) {
2511
- var _loop;
2512
- _loop = function(i) {
2513
- if (i >= list.length) {
2514
- return out();
2515
- }
2516
- return list[i].then(function(val) {
2517
- return step(val, function() {
2518
- return _loop(i + 1);
2519
- });
2536
+ return Promise;
2537
+
2538
+ })();
2539
+
2540
+ UnitPromise = (function(_super) {
2541
+ __extends(UnitPromise, _super);
2542
+
2543
+ function UnitPromise() {
2544
+ _ref1 = UnitPromise.__super__.constructor.apply(this, arguments);
2545
+ return _ref1;
2546
+ }
2547
+
2548
+ UnitPromise.prototype.cache = function() {
2549
+ return this;
2550
+ };
2551
+
2552
+ return UnitPromise;
2553
+
2554
+ })(Promise);
2555
+
2556
+ CachingPromise = (function(_super) {
2557
+ __extends(CachingPromise, _super);
2558
+
2559
+ function CachingPromise(uncached) {
2560
+ var _this = this;
2561
+ this.forceRaw = function(fail, cc) {
2562
+ var cacheCC, cacheFail;
2563
+ cacheFail = function(failure) {
2564
+ return (_this.forceRaw = function(f, _) {
2565
+ return new Thunk(function() {
2566
+ return f(failure);
2567
+ });
2568
+ })(fail, cc);
2569
+ };
2570
+ cacheCC = function(val, deps) {
2571
+ return (_this.forceRaw = function(_, s) {
2572
+ return new Thunk(function() {
2573
+ return s(val, deps);
2574
+ });
2575
+ })(fail, cc);
2576
+ };
2577
+ return new Thunk(function() {
2578
+ return uncached(cacheFail, cacheCC);
2520
2579
  });
2521
2580
  };
2522
- return _loop(0);
2581
+ }
2582
+
2583
+ CachingPromise.prototype.cache = function() {
2584
+ return this;
2523
2585
  };
2524
2586
 
2525
- return Promise;
2587
+ return CachingPromise;
2526
2588
 
2527
- })();
2589
+ })(Promise);
2528
2590
 
2529
2591
  Gibbon.Failure = Failure = (function(_super) {
2530
2592
  __extends(Failure, _super);
2531
2593
 
2532
2594
  function Failure() {
2533
- _ref1 = Failure.__super__.constructor.apply(this, arguments);
2534
- return _ref1;
2595
+ _ref2 = Failure.__super__.constructor.apply(this, arguments);
2596
+ return _ref2;
2535
2597
  }
2536
2598
 
2537
2599
  Failure.types({
2538
2600
  query: ['id', 'annotations'],
2539
- composite: ['failures']
2601
+ composite: ['failures'],
2602
+ message: ['message']
2540
2603
  });
2541
2604
 
2542
2605
  Failure.prototype.equals = function(other) {
@@ -2552,6 +2615,9 @@ Gibbon.Failure = Failure = (function(_super) {
2552
2615
  return false;
2553
2616
  }
2554
2617
  },
2618
+ message: function(m) {
2619
+ return m === other.message;
2620
+ },
2555
2621
  composite: function(failures) {
2556
2622
  var failure, i, _i, _len;
2557
2623
  for (i = _i = 0, _len = failures.length; _i < _len; i = ++_i) {
@@ -2573,8 +2639,8 @@ Gibbon.Dependency = Dependency = (function(_super) {
2573
2639
  __extends(Dependency, _super);
2574
2640
 
2575
2641
  function Dependency() {
2576
- _ref2 = Dependency.__super__.constructor.apply(this, arguments);
2577
- return _ref2;
2642
+ _ref3 = Dependency.__super__.constructor.apply(this, arguments);
2643
+ return _ref3;
2578
2644
  }
2579
2645
 
2580
2646
  Dependency.types({
@@ -2625,148 +2691,386 @@ Gibbon.Dependency = Dependency = (function(_super) {
2625
2691
  })(Union);
2626
2692
 
2627
2693
  eval_ = Gibbon["eval"] = (function() {
2628
- var evalAll;
2629
- evalAll = function(semantics, entity, client) {
2630
- var evalFlow, globalPromise, resultThunks, results, toForce;
2631
- results = new Hash;
2632
- globalPromise = Promise.unit(entity);
2633
- resultThunks = new Hash;
2634
- semantics.each(function(key, definition) {
2635
- return resultThunks.set(key, Promise.lazy(function() {
2636
- return evalFlow(definition.flow, globalPromise).then(function(val) {
2637
- return val.resolve();
2694
+ var Context, Scope, combine, unit, vFalse, vTrue;
2695
+ unit = Promise.unit, combine = Promise.combine;
2696
+ vTrue = Value.boolean(true);
2697
+ vFalse = Value.boolean(false);
2698
+ Context = (function() {
2699
+ function Context(client, entity, definitions) {
2700
+ this.client = client;
2701
+ this.entity = entity;
2702
+ this.definitions = definitions;
2703
+ this.rootScope = Scope.global(entity, this);
2704
+ this.definitionBindings = new Hash;
2705
+ }
2706
+
2707
+ Context.prototype.evalAll = function() {
2708
+ var results, toForce,
2709
+ _this = this;
2710
+ this.definitions.each(function(key, ir) {
2711
+ var lazy;
2712
+ lazy = Promise.lazy(function() {
2713
+ return _this.rootScope["eval"](ir).then(function(x) {
2714
+ return x.resolve();
2715
+ });
2638
2716
  });
2639
- }));
2640
- });
2641
- evalFlow = function(flow, global) {
2642
- var input;
2643
- input = flow.tail ? evalFlow(flow.tail, global) : global;
2644
- return flow.head.cases({
2645
- query: function(annotations) {
2646
- return input.then(function(entity) {
2647
- var _this = this;
2648
- return new Promise(function(fail, cc) {
2649
- return client.performQuery(entity.id, annotations, Gibbon.Value, function(err, val) {
2650
- var dependency;
2651
- if (err) {
2652
- return fail(err);
2653
- }
2654
- dependency = Dependency.query(entity, flow.head);
2655
- return val.promise().depends([dependency]).force(fail, cc);
2656
- });
2657
- });
2717
+ return _this.definitionBindings.set(key, lazy.cache());
2718
+ });
2719
+ toForce = [];
2720
+ results = new Hash;
2721
+ this.definitionBindings.each(function(key, promise) {
2722
+ return toForce.push(promise.after(function(val, deps) {
2723
+ deps = uniq(deps, function(x, y) {
2724
+ return x.equals(y);
2658
2725
  });
2726
+ return results.set(key, [val, deps]);
2727
+ }).rescue(function(failure) {
2728
+ results.set(key, [null, [Dependency.failure(failure)]]);
2729
+ return Promise.unit(null);
2730
+ }));
2731
+ });
2732
+ return combine(toForce).then(function() {
2733
+ var deps, val, _ref4;
2734
+ _ref4 = results.get('/'), val = _ref4[0], deps = _ref4[1];
2735
+ if (val) {
2736
+ return Promise.unit(results);
2737
+ } else {
2738
+ return Promise.fail(deps[0].failure);
2739
+ }
2740
+ });
2741
+ };
2742
+
2743
+ Context.prototype.lookup = function(key) {
2744
+ return this.definitionBindings.get(key).dependsOnly([Dependency.lexical(key)]);
2745
+ };
2746
+
2747
+ Context.prototype.performQuery = function(id, annotations) {
2748
+ var _this = this;
2749
+ return new Promise(function(fail, cc) {
2750
+ var isSynchronous, out;
2751
+ isSynchronous = true;
2752
+ out = null;
2753
+ _this.client.performQuery(id, annotations, Value, function(err, data) {
2754
+ var result;
2755
+ if (err) {
2756
+ return (out = fail(err));
2757
+ }
2758
+ result = data.promise().depends([Dependency.query(id, annotations)]);
2759
+ if (isSynchronous) {
2760
+ return out = result.step(fail, cc);
2761
+ } else {
2762
+ return result.force(fail, cc);
2763
+ }
2764
+ });
2765
+ isSynchronous = false;
2766
+ return out;
2767
+ });
2768
+ };
2769
+
2770
+ return Context;
2771
+
2772
+ })();
2773
+ Scope = (function() {
2774
+ var EXTERN, OPERATORS;
2775
+
2776
+ function Scope(bindings, context, parent) {
2777
+ this.bindings = bindings;
2778
+ this.context = context;
2779
+ this.parent = parent;
2780
+ }
2781
+
2782
+ Scope.global = function(entity, context) {
2783
+ return new Scope(new Hash, context, null)["let"]([['@', unit(entity)]]);
2784
+ };
2785
+
2786
+ Scope.prototype.extend = function(b) {
2787
+ if (b == null) {
2788
+ b = new Hash;
2789
+ }
2790
+ return new Scope(b, this.context, this);
2791
+ };
2792
+
2793
+ Scope.prototype["let"] = function(bindings) {
2794
+ var ext, k, v, _i, _len, _ref4;
2795
+ ext = new Hash;
2796
+ for (_i = 0, _len = bindings.length; _i < _len; _i++) {
2797
+ _ref4 = bindings[_i], k = _ref4[0], v = _ref4[1];
2798
+ ext.set(k, v.cache());
2799
+ }
2800
+ return this.extend(ext);
2801
+ };
2802
+
2803
+ OPERATORS = {
2804
+ '+': function(x, y) {
2805
+ return Value.number(x + y);
2806
+ },
2807
+ '*': function(x, y) {
2808
+ return Value.number(x * y);
2809
+ },
2810
+ '/': function(x, y) {
2811
+ return Value.number(x / y);
2812
+ },
2813
+ '<': function(x, y) {
2814
+ return Value.boolean(x < y);
2815
+ },
2816
+ '>': function(x, y) {
2817
+ return Value.boolean(x > y);
2818
+ },
2819
+ '<=': function(x, y) {
2820
+ return Value.boolean(x <= y);
2821
+ },
2822
+ '>=': function(x, y) {
2823
+ return Value.boolean(x >= y);
2824
+ },
2825
+ '===': function(x, y) {
2826
+ return Value.boolean(x === y);
2827
+ }
2828
+ };
2829
+
2830
+ EXTERN = {
2831
+ '-': function(x) {
2832
+ return Value.number(-x);
2833
+ },
2834
+ '!': function(x) {
2835
+ return Value.boolean(!x);
2836
+ }
2837
+ };
2838
+
2839
+ Scope.prototype.get = function(v) {
2840
+ if (this.bindings.has(v)) {
2841
+ return this.bindings.get(v);
2842
+ } else if (this.parent) {
2843
+ return this.parent.get(v);
2844
+ } else {
2845
+ throw "no such variable: " + v;
2846
+ }
2847
+ };
2848
+
2849
+ Scope.prototype.force = function(varName) {
2850
+ return this.get(varName);
2851
+ };
2852
+
2853
+ Scope.prototype["eval"] = function(ir) {
2854
+ var _this = this;
2855
+ return ir.cases({
2856
+ global: function() {
2857
+ return _this.get('@');
2659
2858
  },
2660
- localAccessor: function(key) {
2661
- return new Promise(function(fail, cc) {
2662
- return resultThunks.get(key).force(fail, function(val, otherDeps) {
2663
- return cc(val, [Dependency.lexical(key)]);
2664
- });
2665
- });
2859
+ constant: function(value) {
2860
+ return unit(Value.fromJSON(value));
2666
2861
  },
2667
- func: function(name, args) {
2668
- var a, func;
2669
- func = stdlib[name].impl;
2670
- args = (function() {
2671
- var _i, _len, _results;
2672
- _results = [];
2673
- for (_i = 0, _len = args.length; _i < _len; _i++) {
2674
- a = args[_i];
2675
- _results.push(evalFlow(a, global));
2676
- }
2677
- return _results;
2678
- })();
2679
- return func.apply(null, [input].concat(__slice.call(args)));
2862
+ variable: function(name) {
2863
+ return _this.get(name);
2680
2864
  },
2681
- literal: function(syntax) {
2682
- return syntax.cases({
2683
- integer: function(value) {
2684
- return Promise.unit(Value.number(value));
2685
- },
2686
- decimal: function(value) {
2687
- return Promise.unit(Value.number(value));
2688
- },
2689
- string: function(value) {
2690
- return Promise.unit(Value.string(value));
2865
+ branch: function(cond, ifTrue, ifFalse) {
2866
+ return _this["eval"](cond).then(function(c) {
2867
+ if (c.value) {
2868
+ return _this["eval"](ifTrue);
2869
+ } else {
2870
+ return _this["eval"](ifFalse);
2691
2871
  }
2692
2872
  });
2693
2873
  },
2694
- pair: function(first, second) {
2695
- var eFirst, eSecond;
2696
- eFirst = evalFlow(first, global);
2697
- eSecond = evalFlow(second, global);
2698
- return Promise.unit(Value.pair(eFirst, eSecond));
2874
+ bind: function(name, val, expr) {
2875
+ return _this["eval"](val).then(function(v) {
2876
+ return _this["let"]([[name, v]])["eval"](expr);
2877
+ });
2878
+ },
2879
+ delist: function(expr, index) {
2880
+ var evaled;
2881
+ evaled = [_this["eval"](expr), _this["eval"](index)];
2882
+ return combine(evaled).then(function(_arg) {
2883
+ var elements, value, _ref4, _ref5;
2884
+ (_ref4 = _arg[0], elements = _ref4.elements), (_ref5 = _arg[1], value = _ref5.value);
2885
+ return elements[value];
2886
+ });
2887
+ },
2888
+ depair: function(expr, key) {
2889
+ return _this["eval"](expr).then(function(v) {
2890
+ return v[key];
2891
+ });
2699
2892
  },
2700
- list: function(elements, squished) {
2701
- var e, list;
2702
- list = Promise.unit(Value.list((function() {
2893
+ list: function(elements) {
2894
+ var e;
2895
+ return unit(Value.list((function() {
2703
2896
  var _i, _len, _results;
2704
2897
  _results = [];
2705
2898
  for (_i = 0, _len = elements.length; _i < _len; _i++) {
2706
2899
  e = elements[_i];
2707
- _results.push(evalFlow(e, global));
2900
+ _results.push(this["eval"](e));
2708
2901
  }
2709
2902
  return _results;
2710
- })()));
2711
- if (squished) {
2712
- return stdlib.squish.impl(list);
2713
- } else {
2714
- return list;
2715
- }
2903
+ }).call(_this)));
2904
+ },
2905
+ foldList: function(list, out, arg, accumArg, idxArg, body) {
2906
+ return _this["eval"](list).then(function(_arg) {
2907
+ var elements, _loop;
2908
+ elements = _arg.elements;
2909
+ _loop = function(i) {
2910
+ if (i >= elements.length) {
2911
+ return _this["eval"](out);
2912
+ }
2913
+ return _this["let"]([[idxArg, unit(Value.number(i))], [arg, elements[i]], [accumArg, _loop(i + 1)]])["eval"](body);
2914
+ };
2915
+ return _loop(0);
2916
+ });
2917
+ },
2918
+ mapList: function(list, arg, idxArg, body) {
2919
+ return _this["eval"](list).then(function(_arg) {
2920
+ var el, elements, i, mapped;
2921
+ elements = _arg.elements;
2922
+ mapped = (function() {
2923
+ var _i, _len, _results;
2924
+ _results = [];
2925
+ for (i = _i = 0, _len = elements.length; _i < _len; i = ++_i) {
2926
+ el = elements[i];
2927
+ _results.push(this["let"]([[arg, el], [idxArg, unit(Value.number(i))]])["eval"](body));
2928
+ }
2929
+ return _results;
2930
+ }).call(_this);
2931
+ return unit(Value.list(mapped));
2932
+ });
2933
+ },
2934
+ zipLists: function(firstExpr, secondExpr) {
2935
+ var evaled;
2936
+ evaled = [_this["eval"](firstExpr), _this["eval"](secondExpr)];
2937
+ return combine(evaled).then(function(_arg) {
2938
+ var el, first, i, pairs, second;
2939
+ first = _arg[0], second = _arg[1];
2940
+ pairs = (function() {
2941
+ var _i, _len, _ref4, _results;
2942
+ _ref4 = first.elements;
2943
+ _results = [];
2944
+ for (i = _i = 0, _len = _ref4.length; _i < _len; i = ++_i) {
2945
+ el = _ref4[i];
2946
+ _results.push(Value.pair(el, second.elements[i]));
2947
+ }
2948
+ return _results;
2949
+ })();
2950
+ return unit(Value.list(pairs));
2951
+ });
2952
+ },
2953
+ filterList: function(listExpr, arg, body) {
2954
+ return _this["eval"](listExpr).then(function(_arg) {
2955
+ var el, elements, mapped;
2956
+ elements = _arg.elements;
2957
+ mapped = (function() {
2958
+ var _i, _len, _results,
2959
+ _this = this;
2960
+ _results = [];
2961
+ for (_i = 0, _len = elements.length; _i < _len; _i++) {
2962
+ el = elements[_i];
2963
+ _results.push((function(el) {
2964
+ return _this["let"]([[arg, el]])["eval"](body).map(function(v) {
2965
+ if (v.value) {
2966
+ return [el];
2967
+ } else {
2968
+ return [];
2969
+ }
2970
+ });
2971
+ })(el));
2972
+ }
2973
+ return _results;
2974
+ }).call(_this);
2975
+ return combine(mapped).map(function(mappedEls) {
2976
+ return Value.list(catLists(mappedEls));
2977
+ });
2978
+ });
2979
+ },
2980
+ squishList: function(listExpr) {
2981
+ return _this["eval"](listExpr).then(function(_arg) {
2982
+ var elements, promise, wrapped;
2983
+ elements = _arg.elements;
2984
+ wrapped = (function() {
2985
+ var _i, _len, _results,
2986
+ _this = this;
2987
+ _results = [];
2988
+ for (_i = 0, _len = elements.length; _i < _len; _i++) {
2989
+ promise = elements[_i];
2990
+ _results.push(promise.then(function(e) {
2991
+ return e.resolve().map(function(e) {
2992
+ return [e.promise()];
2993
+ });
2994
+ }).or(unit([])));
2995
+ }
2996
+ return _results;
2997
+ }).call(_this);
2998
+ return combine(wrapped).map(function(lists) {
2999
+ return Value.list(catLists(lists));
3000
+ });
3001
+ });
3002
+ },
3003
+ len: function(list) {
3004
+ return _this["eval"](list).map(function(_arg) {
3005
+ var elements;
3006
+ elements = _arg.elements;
3007
+ return Value.number(elements.length);
3008
+ });
3009
+ },
3010
+ pair: function(first, second) {
3011
+ return unit(Value.pair(_this["eval"](first), _this["eval"](second)));
2716
3012
  },
2717
- block: function(body) {
2718
- return Promise.unit(Value.block(function(inputPromise) {
2719
- return evalFlow(body, inputPromise);
3013
+ block: function(name, body) {
3014
+ return unit(Value.block(function(input) {
3015
+ return _this["let"]([['@', input], [name, input]])["eval"](body);
2720
3016
  }));
2721
3017
  },
2722
- defaulted: function(body, alt) {
2723
- return evalFlow(body, global).or(evalFlow(alt, global));
3018
+ app: function(block, arg) {
3019
+ arg = _this["eval"](arg);
3020
+ return _this["eval"](block).then(function(b) {
3021
+ return b.fn(arg);
3022
+ });
3023
+ },
3024
+ query: function(expr, annotations) {
3025
+ return _this["eval"](expr).then(function(entity) {
3026
+ return _this.context.performQuery(entity.id, annotations);
3027
+ });
3028
+ },
3029
+ localQuery: function(key) {
3030
+ return _this.context.lookup(key);
3031
+ },
3032
+ fail: function(message) {
3033
+ return Promise.fail(Failure.message(message));
3034
+ },
3035
+ binop: function(op, lhs, rhs) {
3036
+ return combine([_this["eval"](lhs), _this["eval"](rhs)]).map(function(_arg) {
3037
+ var l, r;
3038
+ l = _arg[0], r = _arg[1];
3039
+ return OPERATORS[op](l.value, r.value);
3040
+ });
3041
+ },
3042
+ extern: function(name, value) {
3043
+ return _this["eval"](value).map(function(v) {
3044
+ return EXTERN[name](v.value);
3045
+ });
3046
+ },
3047
+ rescue: function(expr, default_) {
3048
+ return _this["eval"](expr).or(_this["eval"](default_));
2724
3049
  }
2725
3050
  });
2726
3051
  };
2727
- toForce = [];
2728
- resultThunks.each(function(key, thunk) {
2729
- return toForce.push(thunk.rescue(function(failure) {
2730
- results.set(key, [null, [Dependency.failure(failure)]]);
2731
- resultThunks.set(key, Promise.fail(failure));
2732
- return Promise.unit(null);
2733
- }).after(function(val, deps) {
2734
- deps = uniq(deps, function(x, y) {
2735
- return x.equals(y);
2736
- });
2737
- return results.set(key, [val, deps]);
2738
- }));
2739
- });
2740
- return Promise.combine(toForce).map(function() {
2741
- return results;
2742
- });
2743
- };
3052
+
3053
+ return Scope;
3054
+
3055
+ })();
2744
3056
  return function(semantics, table, id, client, finish) {
2745
- var entity, key, onFailure, onSuccess, _i, _len, _ref3;
2746
- _ref3 = semantics.keys();
2747
- for (_i = 0, _len = _ref3.length; _i < _len; _i++) {
2748
- key = _ref3[_i];
2749
- semantics.modify(key, function(val) {
2750
- if (val instanceof Semantic) {
2751
- return val;
2752
- }
2753
- return Semantic.fromJSON(val);
2754
- });
2755
- }
3057
+ var allCompiled, compile, entity, onFailure, onSuccess, optimize;
3058
+ optimize = Gibbon.optimize, compile = Gibbon.compile;
3059
+ allCompiled = new Hash;
3060
+ semantics.each(function(key, semantic) {
3061
+ var compiled;
3062
+ compiled = optimize(compile(semantic));
3063
+ return allCompiled.set(key, compiled);
3064
+ });
2756
3065
  entity = Value.entity(table, id);
2757
3066
  onFailure = function(fail) {
2758
3067
  return finish(fail);
2759
3068
  };
2760
3069
  onSuccess = function(vals) {
2761
- var deps, val, _ref4;
2762
- _ref4 = vals.get('/'), val = _ref4[0], deps = _ref4[1];
2763
- if (val) {
2764
- return finish(null, vals);
2765
- } else {
2766
- return finish(deps[0].failure);
2767
- }
3070
+ DEBUG.log("final stack size: " + (DEBUG.getStackSize()));
3071
+ return finish(null, vals);
2768
3072
  };
2769
- return evalAll(semantics, entity, client).force(onFailure, onSuccess);
3073
+ return new Context(client, entity, allCompiled).evalAll().force(onFailure, onSuccess);
2770
3074
  };
2771
3075
  })();
2772
3076
  // Generated by CoffeeScript 1.6.3
@@ -2803,7 +3107,7 @@ Gibbon.IR = IR = (function(_super) {
2803
3107
  block: ['name', 'body'],
2804
3108
  app: ['block', 'arg'],
2805
3109
  query: ['expr', 'annotations'],
2806
- localQuery: ['expr', 'key'],
3110
+ localQuery: ['key'],
2807
3111
  fail: ['message'],
2808
3112
  binop: ['op', 'lhs', 'rhs'],
2809
3113
  extern: ['name', 'value'],
@@ -2830,10 +3134,6 @@ Gibbon.IR = IR = (function(_super) {
2830
3134
  return IR.query(this, annotations);
2831
3135
  };
2832
3136
 
2833
- IR.prototype.localQuery = function(key) {
2834
- return IR.localQuery(this, key);
2835
- };
2836
-
2837
3137
  IR.prototype.binop = function(op, other) {
2838
3138
  return IR.binop(op, this, other);
2839
3139
  };
@@ -2854,12 +3154,57 @@ Gibbon.IR = IR = (function(_super) {
2854
3154
  return IR.len(this);
2855
3155
  };
2856
3156
 
2857
- IR.prototype.seq = function(name, f) {
2858
- name = nameGen(name);
2859
- return IR.bind(name, this, f(IR.variable(name)));
2860
- };
2861
-
2862
- IR.prototype.mapList = function(f) {
3157
+ IR.prototype.isAsync = function() {
3158
+ return this.cases({
3159
+ query: function() {
3160
+ return true;
3161
+ },
3162
+ localQuery: function() {
3163
+ return true;
3164
+ },
3165
+ other: function() {
3166
+ var sub, _i, _len, _ref1;
3167
+ _ref1 = this.subtrees();
3168
+ for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
3169
+ sub = _ref1[_i];
3170
+ if (sub.isAsync()) {
3171
+ return true;
3172
+ }
3173
+ }
3174
+ return false;
3175
+ }
3176
+ });
3177
+ };
3178
+
3179
+ IR.prototype.isSimple = function() {
3180
+ return this.cases({
3181
+ variable: function() {
3182
+ return true;
3183
+ },
3184
+ constant: function() {
3185
+ return true;
3186
+ },
3187
+ global: function() {
3188
+ return true;
3189
+ },
3190
+ binop: function(op, l, r) {
3191
+ return l.isSimple() && r.isSimple();
3192
+ },
3193
+ extern: function(n, v) {
3194
+ return v.isSimple();
3195
+ },
3196
+ other: function() {
3197
+ return false;
3198
+ }
3199
+ });
3200
+ };
3201
+
3202
+ IR.prototype.seq = function(name, f) {
3203
+ name = nameGen(name);
3204
+ return IR.bind(name, this, f(IR.variable(name)));
3205
+ };
3206
+
3207
+ IR.prototype.mapList = function(f) {
2863
3208
  var elName, ixName;
2864
3209
  elName = nameGen('el');
2865
3210
  ixName = nameGen('i');
@@ -2919,7 +3264,6 @@ Gibbon.IR = IR = (function(_super) {
2919
3264
  },
2920
3265
  app: double,
2921
3266
  query: single,
2922
- localQuery: single,
2923
3267
  binop: function(op, l, r) {
2924
3268
  return [l, r];
2925
3269
  },
@@ -2983,9 +3327,6 @@ Gibbon.IR = IR = (function(_super) {
2983
3327
  query: function(e, a) {
2984
3328
  return IR.query(f(e), a);
2985
3329
  },
2986
- localQuery: function(e, k) {
2987
- return IR.localQuery(f(e), k);
2988
- },
2989
3330
  binop: function(o, l, r) {
2990
3331
  return IR.binop(o, f(l), f(r));
2991
3332
  },
@@ -3021,17 +3362,25 @@ Gibbon.IR = IR = (function(_super) {
3021
3362
  return false;
3022
3363
  }
3023
3364
  return this.cases({
3365
+ global: function() {
3366
+ return true;
3367
+ },
3368
+ constant: function(v) {
3369
+ return v === other.value;
3370
+ },
3371
+ variable: function(name) {
3372
+ return name === other.name;
3373
+ },
3024
3374
  branch: function(cond, ifTrue, ifFalse) {
3025
3375
  return cond.equals(other.cond) && ifTrue.equals(other.ifTrue) && ifFalse.equals(other.ifFalse);
3026
3376
  },
3027
3377
  bind: function(name, val, expr) {
3378
+ var subst;
3028
3379
  if (!val.equals(other.value)) {
3029
3380
  return false;
3030
3381
  }
3031
- return expr.equals(other.replace(IR.variable(other.name), IR.variable(name)));
3032
- },
3033
- variable: function(name) {
3034
- return name === other.name;
3382
+ subst = other.expr.subst(other.name, IR.variable(name));
3383
+ return expr.equals(subst);
3035
3384
  },
3036
3385
  delist: function(expr, index) {
3037
3386
  return expr.equals(other.expr) && index.equals(other.index);
@@ -3049,14 +3398,66 @@ Gibbon.IR = IR = (function(_super) {
3049
3398
  }
3050
3399
  return true;
3051
3400
  },
3401
+ foldList: function(list, out, arg, accumArg, idxArg, body) {
3402
+ var subst;
3403
+ if (!list.equals(other.list)) {
3404
+ return false;
3405
+ }
3406
+ if (!out.equals(other.out)) {
3407
+ return false;
3408
+ }
3409
+ subst = other.body.subst(other.arg, IR.variable(arg)).subst(other.accumArg, IR.variable(accumArg)).subst(other.idxArg, IR.variable(idxArg));
3410
+ return body.equals(subst);
3411
+ },
3412
+ mapList: function(list, arg, idxArg, body) {
3413
+ var subst;
3414
+ if (!list.equals(other.list)) {
3415
+ return false;
3416
+ }
3417
+ subst = other.body.subst(other.arg, IR.variable(arg)).subst(other.idxArg, IR.variable(idxArg));
3418
+ return body.equals(subst);
3419
+ },
3420
+ zipLists: function(first, second) {
3421
+ return first.equals(other.first) && second.equals(other.second);
3422
+ },
3423
+ filterList: function(list, arg, body) {
3424
+ if (!list.equals(other.list)) {
3425
+ return false;
3426
+ }
3427
+ return body.equals(other.body.subst(other.arg, IR.variable(arg)));
3428
+ },
3429
+ squishList: function(list) {
3430
+ return list.equals(other.list);
3431
+ },
3432
+ len: function(list) {
3433
+ return list.equals(other.list);
3434
+ },
3052
3435
  pair: function(x, y) {
3053
3436
  return x.equals(other.first) && y.equals(other.second);
3054
3437
  },
3438
+ block: function(name, body) {
3439
+ return false;
3440
+ },
3441
+ app: function(block, arg) {
3442
+ return block.equals(other.block) && arg.equals(other.arg);
3443
+ },
3055
3444
  query: function(expr, annotations) {
3056
3445
  return JSON.stringify(annotations) === JSON.stringify(other.annotations) && expr.equals(other.expr);
3057
3446
  },
3058
- localQuery: function(expr, key) {
3059
- return key === other.key && expr.equals(other.expr);
3447
+ localQuery: function(key) {
3448
+ return key === other.key;
3449
+ },
3450
+ fail: function() {
3451
+ return false;
3452
+ },
3453
+ binop: function(op, lhs, rhs) {
3454
+ return op === other.op && lhs.equals(other.lhs) && rhs.equals(other.rhs);
3455
+ },
3456
+ extern: function(name, value) {
3457
+ return name === other.name && value.equals(other.value);
3458
+ },
3459
+ rescue: function(expr, default_) {
3460
+ return expr.equals(other.expr) && default_.equals(other["default"]);
3060
3461
  }
3061
3462
  });
3062
3463
  };
@@ -3087,7 +3488,7 @@ Gibbon.IR = IR = (function(_super) {
3087
3488
  return name;
3088
3489
  },
3089
3490
  delist: function(e, i) {
3090
- return "([" + i + "] " + (e.inspect()) + ")";
3491
+ return "([" + (i.inspect()) + "] " + (e.inspect()) + ")";
3091
3492
  },
3092
3493
  depair: function(e, k) {
3093
3494
  return "([" + k + "] " + (e.inspect()) + ")";
@@ -3113,9 +3514,15 @@ Gibbon.IR = IR = (function(_super) {
3113
3514
  foldList: function(list, out, arg, next, i, body) {
3114
3515
  return "(FOLDR " + (list.inspect()) + " " + (out.inspect()) + " " + arg + " " + next + " " + i + " " + (body.inspect()) + ")";
3115
3516
  },
3517
+ filterList: function(list, arg, body) {
3518
+ return "(FILTER " + (list.inspect()) + " " + arg + " " + (body.inspect()) + ")";
3519
+ },
3116
3520
  zipLists: function(x, y) {
3117
3521
  return "(ZIP " + (x.inspect()) + " " + (y.inspect()) + ")";
3118
3522
  },
3523
+ squishList: function(l) {
3524
+ return "(SQUISH " + (l.inspect()) + ")";
3525
+ },
3119
3526
  pair: function(x, y) {
3120
3527
  return "(PAIR " + (x.inspect()) + " " + (y.inspect()) + ")";
3121
3528
  },
@@ -3129,7 +3536,7 @@ Gibbon.IR = IR = (function(_super) {
3129
3536
  return "(APPLY " + (b.inspect()) + " " + (a.inspect()) + ")";
3130
3537
  },
3131
3538
  localQuery: function(k) {
3132
- return "(@" + k + " " + (e.inspect()) + ")";
3539
+ return "@" + k;
3133
3540
  },
3134
3541
  fail: function(m) {
3135
3542
  return "(FAIL " + m + ")";
@@ -3177,10 +3584,10 @@ Gibbon.compile = (function() {
3177
3584
  return input.query(annotations);
3178
3585
  },
3179
3586
  localAccessor: function(key) {
3180
- return input.localQuery(key);
3587
+ return IR.localQuery(key);
3181
3588
  },
3182
- func: function(name, args) {
3183
- var arg, argTypes, compArgs;
3589
+ func: function(name, args, tvars) {
3590
+ var arg, compArgs;
3184
3591
  compArgs = (function() {
3185
3592
  var _i, _len, _results;
3186
3593
  _results = [];
@@ -3190,23 +3597,14 @@ Gibbon.compile = (function() {
3190
3597
  }
3191
3598
  return _results;
3192
3599
  })();
3193
- argTypes = (function() {
3194
- var _i, _len, _results;
3195
- _results = [];
3196
- for (_i = 0, _len = args.length; _i < _len; _i++) {
3197
- arg = args[_i];
3198
- _results.push(arg.type);
3199
- }
3200
- return _results;
3201
- })();
3202
- return stdlib[name].compile(input, compArgs, this.type, argTypes);
3600
+ return stdlib[name].compile(input, compArgs, tvars);
3203
3601
  },
3204
3602
  literal: function(syntax) {
3205
3603
  return IR.constant(syntax.value);
3206
3604
  },
3207
- list: function(elements) {
3208
- var e;
3209
- return IR.list((function() {
3605
+ list: function(elements, squish) {
3606
+ var e, list;
3607
+ list = IR.list((function() {
3210
3608
  var _i, _len, _results;
3211
3609
  _results = [];
3212
3610
  for (_i = 0, _len = elements.length; _i < _len; _i++) {
@@ -3215,6 +3613,11 @@ Gibbon.compile = (function() {
3215
3613
  }
3216
3614
  return _results;
3217
3615
  })());
3616
+ if (squish) {
3617
+ return list.squish();
3618
+ } else {
3619
+ return list;
3620
+ }
3218
3621
  },
3219
3622
  pair: function(x, y) {
3220
3623
  return IR.pair(compile(x, context), compile(y, context));
@@ -3229,12 +3632,315 @@ Gibbon.compile = (function() {
3229
3632
  }
3230
3633
  });
3231
3634
  };
3232
- return function(semantics) {
3233
- var out;
3234
- out = new Hash;
3235
- semantics.each(function(k, v) {
3236
- return out.set(k, compile(v));
3635
+ return function(semantic) {
3636
+ return compile(semantic);
3637
+ };
3638
+ })();
3639
+ // Generated by CoffeeScript 1.6.3
3640
+ Gibbon.optimize = (function() {
3641
+ var insertBindings, partialEval;
3642
+ insertBindings = function(expr) {
3643
+ return expr;
3644
+ };
3645
+ partialEval = function(expr) {
3646
+ return expr.cases({
3647
+ depair: function(expr, key) {
3648
+ return partialEval(expr).cases({
3649
+ pair: function() {
3650
+ DEBUG.log("inlining lookup " + key + " of " + (this.inspect()));
3651
+ return this[key];
3652
+ },
3653
+ other: function() {
3654
+ return this.depair(key);
3655
+ }
3656
+ });
3657
+ },
3658
+ delist: function(expr, index) {
3659
+ return partialEval(expr).cases({
3660
+ list: function(els) {
3661
+ DEBUG.log("inlining lookup " + index + " of " + (this.inspect()));
3662
+ return els[index];
3663
+ },
3664
+ other: function() {
3665
+ return this.delist(index);
3666
+ }
3667
+ });
3668
+ },
3669
+ branch: function(cond, ifTrue, ifFalse) {
3670
+ ifTrue = partialEval(ifTrue);
3671
+ ifFalse = partialEval(ifFalse);
3672
+ if (ifTrue.equals(ifFalse)) {
3673
+ DEBUG.log("eliminating condition in equivalent branches: " + (this.inspect()));
3674
+ return ifTrue;
3675
+ }
3676
+ return partialEval(cond).cases({
3677
+ constant: function(value) {
3678
+ if (value) {
3679
+ DEBUG.log("eliminating dead false branch " + (ifFalse.inspect()));
3680
+ return ifTrue;
3681
+ } else {
3682
+ DEBUG.log("eliminating dead true branch " + (ifTrue.inspect()));
3683
+ return ifFalse;
3684
+ }
3685
+ },
3686
+ branch: function(innerCond, innerTrue, innerFalse) {
3687
+ if (innerTrue._tag === 'constant' && innerFalse._tag === 'constant') {
3688
+ DEBUG.log("eliminating nested if " + (this.inspect()));
3689
+ if (innerTrue.value) {
3690
+ return partialEval(innerCond.branch(ifTrue, ifFalse));
3691
+ } else {
3692
+ return partialEval(innerCond.branch(ifFalse, ifTrue));
3693
+ }
3694
+ } else {
3695
+ return this.branch(ifTrue, ifFalse);
3696
+ }
3697
+ },
3698
+ extern: function(name, arg) {
3699
+ if (name === '!') {
3700
+ DEBUG.log("eliminating if negation in condition " + (this.inspect()));
3701
+ return partialEval(arg.branch(ifFalse, ifTrue));
3702
+ } else {
3703
+ return this.branch(ifTrue, ifFalse);
3704
+ }
3705
+ },
3706
+ other: function() {
3707
+ return this.branch(ifTrue, ifFalse);
3708
+ }
3709
+ });
3710
+ },
3711
+ app: function(block, arg) {
3712
+ return partialEval(block).cases({
3713
+ block: function(argName, body) {
3714
+ return partialEval(body.subst(argName, arg));
3715
+ },
3716
+ other: function() {
3717
+ return this.app(partialEval(arg));
3718
+ }
3719
+ });
3720
+ },
3721
+ mapList: function(list, arg, ixName, body) {
3722
+ return list.cases({
3723
+ list: function(elements) {
3724
+ var el, i, mapped, _i, _len;
3725
+ DEBUG.log("inlining MAP");
3726
+ for (i = _i = 0, _len = elements.length; _i < _len; i = ++_i) {
3727
+ el = elements[i];
3728
+ DEBUG.log(("subst " + arg + "=" + (el.inspect()) + " ") + ("" + ixName + "=" + i + " " + (body.inspect())));
3729
+ partialEval(body.subst(arg, el).subst(ixName, IR.constant(i)));
3730
+ }
3731
+ mapped = (function() {
3732
+ var _j, _len1, _results;
3733
+ _results = [];
3734
+ for (_j = 0, _len1 = elements.length; _j < _len1; _j++) {
3735
+ el = elements[_j];
3736
+ _results.push(body.subst(arg, el));
3737
+ }
3738
+ return _results;
3739
+ })();
3740
+ return partialEval(IR.list(mapped));
3741
+ },
3742
+ other: function() {
3743
+ return IR.mapList(this, arg, ixName, partialEval(body));
3744
+ }
3745
+ });
3746
+ },
3747
+ foldList: function(list, out, arg, accum, ixName, body) {
3748
+ return partialEval(list).cases({
3749
+ list: function(elements) {
3750
+ var _loop;
3751
+ DEBUG.log("inlining FOLDR");
3752
+ _loop = function(i) {
3753
+ var next;
3754
+ if (i >= elements.length) {
3755
+ return partialEval(out);
3756
+ }
3757
+ next = _loop(i + 1);
3758
+ DEBUG.log(("subst " + arg + "=" + (elements[i].inspect()) + " ") + ("" + accum + "=" + (next.inspect()) + " ") + ("" + ixName + "=i " + (body.inspect())));
3759
+ return body.subst(arg, elements[i]).subst(accum, next).subst(ixName, IR.constant(i));
3760
+ };
3761
+ return partialEval(_loop(0));
3762
+ },
3763
+ other: function() {
3764
+ return IR.foldList(this, partialEval(out), arg, accum, ixName, partialEval(body));
3765
+ }
3766
+ });
3767
+ },
3768
+ len: function(list) {
3769
+ return partialEval(list).cases({
3770
+ list: function(elements) {
3771
+ DEBUG.log("optimizing out len from " + (this.inspect()));
3772
+ return IR.constant(elements.length);
3773
+ },
3774
+ mapList: function(list) {
3775
+ DEBUG.log("optimizing MAP out of len");
3776
+ return partialEval(list.len());
3777
+ },
3778
+ zipLists: function(l, r) {
3779
+ DEBUG.log("optimizing ZIP out of len");
3780
+ return partialEval(l.len());
3781
+ },
3782
+ other: function() {
3783
+ return this.len();
3784
+ }
3785
+ });
3786
+ },
3787
+ zipLists: function(l, r) {
3788
+ var e, elements, i;
3789
+ l = partialEval(l);
3790
+ r = partialEval(r);
3791
+ if (!(l._tag === 'list' && r._tag === 'list')) {
3792
+ return IR.zipLists(l, r);
3793
+ }
3794
+ elements = (function() {
3795
+ var _i, _len, _results;
3796
+ _results = [];
3797
+ for (i = _i = 0, _len = l.length; _i < _len; i = ++_i) {
3798
+ e = l[i];
3799
+ _results.push(IR.pair(e, r[i]));
3800
+ }
3801
+ return _results;
3802
+ })();
3803
+ return partialEval(IR.list(elements));
3804
+ },
3805
+ extern: function(op, arg) {
3806
+ return partialEval(arg).cases({
3807
+ constant: function(value) {
3808
+ if (/Math\.(\w+)/.test(op)) {
3809
+ return IR.constant(Math[RegExp.$1](value));
3810
+ }
3811
+ return IR.constant((function() {
3812
+ switch (op) {
3813
+ case '!':
3814
+ return !value;
3815
+ case '-':
3816
+ return -value;
3817
+ default:
3818
+ throw "unknown operator " + op;
3819
+ }
3820
+ })());
3821
+ },
3822
+ other: function() {
3823
+ return IR.extern(op, this);
3824
+ }
3825
+ });
3826
+ },
3827
+ binop: function(op, left, right) {
3828
+ var l, r, _ref;
3829
+ left = partialEval(left);
3830
+ right = partialEval(right);
3831
+ if (!(left._tag === 'constant' && right._tag === 'constant')) {
3832
+ return IR.binop(op, left, right);
3833
+ }
3834
+ DEBUG.log("constant-folding " + (left.binop(op, right).inspect()));
3835
+ _ref = [left.value, right.value], l = _ref[0], r = _ref[1];
3836
+ return IR.constant((function() {
3837
+ switch (op) {
3838
+ case '+':
3839
+ return l + r;
3840
+ case '*':
3841
+ return l * r;
3842
+ case '/':
3843
+ return l / r;
3844
+ case '%':
3845
+ return l % r;
3846
+ case '===':
3847
+ return l === r;
3848
+ case '<':
3849
+ return l < r;
3850
+ case '>':
3851
+ return l > r;
3852
+ case '<=':
3853
+ return l <= r;
3854
+ case '>=':
3855
+ return l >= r;
3856
+ }
3857
+ })());
3858
+ },
3859
+ rescue: function(expr, default_) {
3860
+ var alwaysFails, alwaysSucceeds;
3861
+ expr = partialEval(expr);
3862
+ alwaysSucceeds = function(e) {
3863
+ return e.cases({
3864
+ query: function() {
3865
+ return false;
3866
+ },
3867
+ localQuery: function() {
3868
+ return false;
3869
+ },
3870
+ fail: function() {
3871
+ return false;
3872
+ },
3873
+ rescue: function() {
3874
+ return true;
3875
+ },
3876
+ squishList: function() {
3877
+ return true;
3878
+ },
3879
+ other: function() {
3880
+ var subtree, _i, _len, _ref;
3881
+ _ref = this.subtrees();
3882
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
3883
+ subtree = _ref[_i];
3884
+ console.log("checking alwaysSucceeds " + (subtree.inspect()));
3885
+ if (!alwaysSucceeds(subtree)) {
3886
+ return false;
3887
+ }
3888
+ }
3889
+ return true;
3890
+ }
3891
+ });
3892
+ };
3893
+ alwaysFails = function(e) {
3894
+ return e.cases({
3895
+ query: function() {
3896
+ return false;
3897
+ },
3898
+ localQuery: function() {
3899
+ return false;
3900
+ },
3901
+ fail: function() {
3902
+ return true;
3903
+ },
3904
+ rescue: function() {
3905
+ return false;
3906
+ },
3907
+ squishList: function() {
3908
+ return false;
3909
+ },
3910
+ other: function() {
3911
+ var subtree, _i, _len, _ref;
3912
+ _ref = this.subtrees();
3913
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
3914
+ subtree = _ref[_i];
3915
+ console.log("checking alwaysFails " + (subtree.inspect()));
3916
+ if (alwaysFails(subtree)) {
3917
+ return true;
3918
+ }
3919
+ }
3920
+ return false;
3921
+ }
3922
+ });
3923
+ };
3924
+ if (alwaysSucceeds(expr)) {
3925
+ DEBUG.log("eliminating dead default branch of " + (this.inspect()));
3926
+ return expr;
3927
+ } else if (alwaysFails(expr)) {
3928
+ DEBUG.log("eliminating dead main branch of " + (this.inspect()));
3929
+ return partialEval(default_);
3930
+ } else {
3931
+ return IR.rescue(expr, partialEval(default_));
3932
+ }
3933
+ },
3934
+ other: function() {
3935
+ return this.map(partialEval);
3936
+ }
3237
3937
  });
3938
+ };
3939
+ return function(expr) {
3940
+ var out;
3941
+ DEBUG.log("=== OPTIMIZING " + (expr.inspect()));
3942
+ out = insertBindings(partialEval(expr));
3943
+ DEBUG.log("==> " + (out.inspect()));
3238
3944
  return out;
3239
3945
  };
3240
3946
  })();
@@ -3242,42 +3948,11 @@ Gibbon.compile = (function() {
3242
3948
  var stdlib;
3243
3949
 
3244
3950
  stdlib = Gibbon.stdlib = (function() {
3245
- var allBooleans, anyBooleans, combine, compEquals, iFalse, iTrue, iter, unit, vFalse, vTrue;
3246
- unit = Promise.unit;
3247
- iter = Promise.iter;
3248
- combine = Promise.combine;
3951
+ var compEquals, iFalse, iTrue, vFalse, vTrue;
3249
3952
  vTrue = Value.boolean(true);
3250
3953
  vFalse = Value.boolean(false);
3251
3954
  iTrue = IR.constant(true);
3252
3955
  iFalse = IR.constant(false);
3253
- anyBooleans = function(promises) {
3254
- var out, step;
3255
- step = function(cond, next) {
3256
- if (cond.value) {
3257
- return unit(vTrue);
3258
- } else {
3259
- return next();
3260
- }
3261
- };
3262
- out = function() {
3263
- return unit(vFalse);
3264
- };
3265
- return iter(promises, step, out);
3266
- };
3267
- allBooleans = function(promises) {
3268
- var out, step;
3269
- step = function(cond, next) {
3270
- if (cond.value) {
3271
- return next();
3272
- } else {
3273
- return unit(vFalse);
3274
- }
3275
- };
3276
- out = function() {
3277
- return unit(vTrue);
3278
- };
3279
- return iter(promises, step, out);
3280
- };
3281
3956
  compEquals = function(x, y, type) {
3282
3957
  var direct;
3283
3958
  direct = function() {
@@ -3310,24 +3985,6 @@ stdlib = Gibbon.stdlib = (function() {
3310
3985
  return {
3311
3986
  "case": {
3312
3987
  type: parse.type('case [bool : %b] = % -> %b'),
3313
- impl: function(_, evalList) {
3314
- return evalList.then(function(list) {
3315
- var out, step;
3316
- step = function(pair, next) {
3317
- return pair.first.then(function(cond) {
3318
- if (cond.value) {
3319
- return pair.second;
3320
- } else {
3321
- return next();
3322
- }
3323
- });
3324
- };
3325
- out = function() {
3326
- return Promise.fail('non-exhaustive cases');
3327
- };
3328
- return iter(list.elements, step, out);
3329
- });
3330
- },
3331
3988
  compile: function(_, _arg) {
3332
3989
  var alts;
3333
3990
  alts = _arg[0];
@@ -3338,32 +3995,10 @@ stdlib = Gibbon.stdlib = (function() {
3338
3995
  },
3339
3996
  "case-eq": {
3340
3997
  type: parse.type('case-eq [%a : %b] = %a -> %b'),
3341
- impl: function(evalInput, evalList) {
3342
- return combine([evalInput, evalList]).then(function(_arg) {
3343
- var input, list, out, step;
3344
- input = _arg[0], list = _arg[1];
3345
- step = function(pair, next) {
3346
- return pair.first.then(function(test) {
3347
- return input.equals(test).then(function(vBool) {
3348
- if (vBool.value) {
3349
- return pair.second;
3350
- } else {
3351
- return next();
3352
- }
3353
- });
3354
- });
3355
- };
3356
- out = function() {
3357
- return Promise.fail('non-exhaustive cases');
3358
- };
3359
- return iter(list.elements, step, out);
3360
- });
3361
- },
3362
- compile: function(input, _arg, _, _arg1) {
3363
- var alts, argType, eqType;
3998
+ compile: function(input, _arg, tvars) {
3999
+ var alts, eqType;
3364
4000
  alts = _arg[0];
3365
- argType = _arg1[0];
3366
- eqType = argType.of.first;
4001
+ eqType = tvars.get('a');
3367
4002
  return alts.foldList(IR.fail('non-exhaustive cases'), function(el, next) {
3368
4003
  var first, second;
3369
4004
  first = el.depair('first');
@@ -3374,14 +4009,10 @@ stdlib = Gibbon.stdlib = (function() {
3374
4009
  },
3375
4010
  "case-eq-default": {
3376
4011
  type: parse.type('case-eq-default %b [%a : %b] = %a -> %b'),
3377
- impl: function(evalInput, evalDefault, evalList) {
3378
- return stdlib['case-eq'].impl(evalInput, evalList).or(evalDefault);
3379
- },
3380
- compile: function(input, _arg, _, _arg1) {
3381
- var alts, argType, default_, eqType;
4012
+ compile: function(input, _arg, tvars) {
4013
+ var alts, default_, eqType;
3382
4014
  default_ = _arg[0], alts = _arg[1];
3383
- argType = _arg1[0];
3384
- eqType = argType.of.first;
4015
+ eqType = tvars.get('a');
3385
4016
  return alts.foldList(default_, function(el, next) {
3386
4017
  var first, second;
3387
4018
  first = el.depair('first');
@@ -3392,11 +4023,6 @@ stdlib = Gibbon.stdlib = (function() {
3392
4023
  },
3393
4024
  "any-true?": {
3394
4025
  type: parse.type('any-true? = [bool] -> bool'),
3395
- impl: function(evalList) {
3396
- return evalList.then(function(list) {
3397
- return anyBooleans(list.elements);
3398
- });
3399
- },
3400
4026
  compile: function(list) {
3401
4027
  return list.foldList(iFalse, function(el, next) {
3402
4028
  return el.branch(iTrue, next);
@@ -3405,11 +4031,6 @@ stdlib = Gibbon.stdlib = (function() {
3405
4031
  },
3406
4032
  "all-true?": {
3407
4033
  type: parse.type('all-true? = [bool] -> bool'),
3408
- impl: function(evalList) {
3409
- return evalList.then(function(list) {
3410
- return allBooleans(list.elements);
3411
- });
3412
- },
3413
4034
  compile: function(list) {
3414
4035
  return list.foldList(iTrue, function(el, next) {
3415
4036
  return el.branch(next, iFalse);
@@ -3418,24 +4039,9 @@ stdlib = Gibbon.stdlib = (function() {
3418
4039
  },
3419
4040
  "any?": {
3420
4041
  type: parse.type('any? { %a -> bool } = [%a] -> bool'),
3421
- impl: function(evalList, evalBlock) {
3422
- return combine([evalList, evalBlock]).then(function(_arg) {
3423
- var block, e, fn, list;
3424
- list = _arg[0], block = _arg[1];
3425
- fn = block.fn;
3426
- return anyBooleans((function() {
3427
- var _i, _len, _ref, _results;
3428
- _ref = list.elements;
3429
- _results = [];
3430
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
3431
- e = _ref[_i];
3432
- _results.push(fn(e));
3433
- }
3434
- return _results;
3435
- })());
3436
- });
3437
- },
3438
- compile: function(list, block) {
4042
+ compile: function(list, _arg) {
4043
+ var block;
4044
+ block = _arg[0];
3439
4045
  return list.foldList(iFalse, function(el, next) {
3440
4046
  return block.app(el).branch(iTrue, next);
3441
4047
  });
@@ -3443,24 +4049,9 @@ stdlib = Gibbon.stdlib = (function() {
3443
4049
  },
3444
4050
  "all?": {
3445
4051
  type: parse.type('all? { %a -> bool } = [%a] -> bool'),
3446
- impl: function(evalList, evalBlock) {
3447
- return combine([evalList, evalBlock]).then(function(_arg) {
3448
- var block, e, fn, list;
3449
- list = _arg[0], block = _arg[1];
3450
- fn = block.fn;
3451
- return allBooleans((function() {
3452
- var _i, _len, _ref, _results;
3453
- _ref = list.elements;
3454
- _results = [];
3455
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
3456
- e = _ref[_i];
3457
- _results.push(fn(e));
3458
- }
3459
- return _results;
3460
- })());
3461
- });
3462
- },
3463
- compile: function(list, block) {
4052
+ compile: function(list, _arg) {
4053
+ var block;
4054
+ block = _arg[0];
3464
4055
  return list.foldList(iTrue, function(el, next) {
3465
4056
  return block.app(el).branch(next, iFalse);
3466
4057
  });
@@ -3468,40 +4059,17 @@ stdlib = Gibbon.stdlib = (function() {
3468
4059
  },
3469
4060
  "include?": {
3470
4061
  type: parse.type('include? %a = [%a] -> bool'),
3471
- impl: function(evalList, evalElement) {
3472
- return combine([evalElement, evalList]).then(function(_arg) {
3473
- var booleans, el, list, p;
3474
- el = _arg[0], list = _arg[1];
3475
- booleans = (function() {
3476
- var _i, _len, _ref, _results;
3477
- _ref = list.elements;
3478
- _results = [];
3479
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
3480
- p = _ref[_i];
3481
- _results.push(p.then(function(x) {
3482
- return el.equals(x);
3483
- }));
3484
- }
3485
- return _results;
3486
- })();
3487
- return anyBooleans(booleans);
3488
- });
3489
- },
3490
- compile: function(list, needle, _, _arg) {
3491
- var listType;
3492
- listType = _arg[0];
4062
+ compile: function(list, _arg, tvars) {
4063
+ var elType, needle;
4064
+ needle = _arg[0];
4065
+ elType = tvars.get('a');
3493
4066
  return list.foldList(iFalse, function(el, next) {
3494
- return compEquals(el, needle, listType.of).branch(iTrue, next);
4067
+ return compEquals(el, needle, elType).branch(iTrue, next);
3495
4068
  });
3496
4069
  }
3497
4070
  },
3498
4071
  "empty?": {
3499
4072
  type: parse.type('empty? = [%] -> bool'),
3500
- impl: function(evalList) {
3501
- return evalList.map(function(list) {
3502
- return Value.boolean(list.length === 0);
3503
- });
3504
- },
3505
4073
  compile: function(list) {
3506
4074
  return list.foldList(iTrue, function() {
3507
4075
  return iFalse;
@@ -3510,40 +4078,10 @@ stdlib = Gibbon.stdlib = (function() {
3510
4078
  },
3511
4079
  weight: {
3512
4080
  type: parse.type('weight [numeric : numeric] = % -> numeric'),
3513
- impl: function(_, eWeights) {
3514
- return eWeights.then(function(weights) {
3515
- return combine(weights.elements).then(function(pairs) {
3516
- var denominator, numerator, p, process;
3517
- numerator = 0;
3518
- denominator = 0;
3519
- process = function(pair) {
3520
- return combine([pair.first, pair.second]).after(function(_arg) {
3521
- var first, second;
3522
- first = _arg[0], second = _arg[1];
3523
- numerator += first.value * second.value;
3524
- return denominator += second.value;
3525
- });
3526
- };
3527
- return combine((function() {
3528
- var _i, _len, _results;
3529
- _results = [];
3530
- for (_i = 0, _len = pairs.length; _i < _len; _i++) {
3531
- p = pairs[_i];
3532
- _results.push(process(p));
3533
- }
3534
- return _results;
3535
- })()).then(function() {
3536
- if (denominator === 0) {
3537
- return Promise.fail('cannot divide by zero');
3538
- }
3539
- return unit(Value.number(numerator / denominator));
3540
- });
3541
- });
3542
- });
3543
- },
3544
- compile: function(_, weights) {
3545
- var ratio;
3546
- return ratio = weights.foldList(IR.pair(IR.constant(0), IR.constant(0)), function(el, next) {
4081
+ compile: function(_, _arg) {
4082
+ var ratio, weights;
4083
+ weights = _arg[0];
4084
+ ratio = weights.foldList(IR.pair(IR.constant(0), IR.constant(0)), function(el, next) {
3547
4085
  var denominator, numerator, value, weight, weighted;
3548
4086
  value = el.depair('first');
3549
4087
  weight = el.depair('second');
@@ -3552,40 +4090,14 @@ stdlib = Gibbon.stdlib = (function() {
3552
4090
  weighted = value.binop('*', weight);
3553
4091
  return IR.pair(numerator.binop('+', weighted), denominator.binop('+', weight));
3554
4092
  });
4093
+ return ratio.depair('first').binop('/', ratio.depair('second'));
3555
4094
  }
3556
4095
  },
3557
4096
  filter: {
3558
4097
  type: parse.type('filter { %a -> bool } = [%a] -> [%a]'),
3559
- impl: function(evalInput, evalBlock) {
3560
- return evalBlock.then(function(block) {
3561
- var fn;
3562
- fn = block.fn;
3563
- return evalInput.then(function(list) {
3564
- var check, e, out;
3565
- out = [];
3566
- check = function(thunk) {
3567
- return fn(thunk).after(function(bool) {
3568
- if (bool.value) {
3569
- return out.push(thunk);
3570
- }
3571
- });
3572
- };
3573
- return combine((function() {
3574
- var _i, _len, _ref, _results;
3575
- _ref = list.elements;
3576
- _results = [];
3577
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
3578
- e = _ref[_i];
3579
- _results.push(check(e));
3580
- }
3581
- return _results;
3582
- })()).map(function() {
3583
- return Value.list(out);
3584
- });
3585
- });
3586
- });
3587
- },
3588
- compile: function(input, block) {
4098
+ compile: function(input, _arg) {
4099
+ var block;
4100
+ block = _arg[0];
3589
4101
  return input.filterList(function(el) {
3590
4102
  return block.app(el);
3591
4103
  });
@@ -3593,49 +4105,25 @@ stdlib = Gibbon.stdlib = (function() {
3593
4105
  },
3594
4106
  scale: {
3595
4107
  type: parse.type('scale (numeric:numeric) (numeric:numeric) = numeric -> numeric'),
3596
- impl: function(eInput, eDomain, eRange) {
3597
- return combine([eInput, eDomain, eRange]).then(function(_arg) {
3598
- var bounds, dom, input, range;
3599
- input = _arg[0], dom = _arg[1], range = _arg[2];
3600
- bounds = combine([dom.first, dom.second, range.first, range.second]);
3601
- return bounds.map(function(_arg1) {
3602
- var domHigh, domLow, domSize, rangeHigh, rangeLow, rangeSize, retranslated, scaled, translated;
3603
- domLow = _arg1[0], domHigh = _arg1[1], rangeLow = _arg1[2], rangeHigh = _arg1[3];
3604
- if (input.value < domLow.value) {
3605
- input = domLow;
3606
- } else if (input.value > domHigh.value) {
3607
- input = domHigh;
3608
- }
3609
- domSize = domHigh.value - domLow.value;
3610
- rangeSize = rangeHigh.value - rangeLow.value;
3611
- translated = input.value - domLow.value;
3612
- scaled = translated * rangeSize / domSize;
3613
- retranslated = scaled + rangeLow.value;
3614
- return Value.number(retranslated);
3615
- });
3616
- });
4108
+ compile: function(input, _arg) {
4109
+ var dom, domHigh, domLow, domSize, range, rangeHigh, rangeLow, rangeSize, retranslated, scaled, translated;
4110
+ dom = _arg[0], range = _arg[1];
4111
+ domLow = dom.depair('first');
4112
+ domHigh = dom.depair('second');
4113
+ rangeLow = range.depair('first');
4114
+ rangeHigh = range.depair('second');
4115
+ input = input.binop('<', domLow).branch(domLow, input);
4116
+ input = input.binop('>', domHigh).branch(domHigh, input);
4117
+ domSize = domHigh.binop('+', domLow.extern('-'));
4118
+ rangeSize = rangeHigh.binop('+', rangeLow.extern('-'));
4119
+ translated = input.binop('+', domLow.extern('-'));
4120
+ scaled = translated.binop('*', rangeSize.binop('/', domSize));
4121
+ retranslated = scaled.binop('+', rangeLow);
4122
+ return retranslated;
3617
4123
  }
3618
4124
  },
3619
4125
  map: {
3620
4126
  type: parse.type('map { %a -> %b } = [%a] -> [%b]'),
3621
- impl: function(evalList, evalBlock) {
3622
- return evalList.then(function(list) {
3623
- return evalBlock.map(function(block) {
3624
- var e, fn;
3625
- fn = block.fn;
3626
- return Value.list((function() {
3627
- var _i, _len, _ref, _results;
3628
- _ref = list.elements;
3629
- _results = [];
3630
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
3631
- e = _ref[_i];
3632
- _results.push(fn(e));
3633
- }
3634
- return _results;
3635
- })());
3636
- });
3637
- });
3638
- },
3639
4127
  compile: function(list, _arg) {
3640
4128
  var block;
3641
4129
  block = _arg[0];
@@ -3646,27 +4134,12 @@ stdlib = Gibbon.stdlib = (function() {
3646
4134
  },
3647
4135
  count: {
3648
4136
  type: parse.type('count = [%a] -> numeric'),
3649
- impl: function(evalList) {
3650
- return evalList.map(function(list) {
3651
- return Value.number(list.elements.length);
3652
- });
4137
+ compile: function(list) {
4138
+ return list.len();
3653
4139
  }
3654
4140
  },
3655
4141
  sum: {
3656
4142
  type: parse.type('sum = [numeric] -> numeric'),
3657
- impl: function(list) {
3658
- return list.then(function(val) {
3659
- return combine(val.elements).then(function(vals) {
3660
- var e, out, _i, _len;
3661
- out = 0;
3662
- for (_i = 0, _len = vals.length; _i < _len; _i++) {
3663
- e = vals[_i];
3664
- out += e.value;
3665
- }
3666
- return unit(Value.number(out));
3667
- });
3668
- });
3669
- },
3670
4143
  compile: function(list) {
3671
4144
  return list.foldList(IR.constant(0), function(el, next) {
3672
4145
  return el.binop('+', next);
@@ -3675,40 +4148,6 @@ stdlib = Gibbon.stdlib = (function() {
3675
4148
  },
3676
4149
  "case-sum": {
3677
4150
  type: parse.type('case-sum [bool : numeric] = % -> numeric'),
3678
- impl: function(_, evalList) {
3679
- return evalList.then(function(list) {
3680
- return combine(list.elements).then(function(elements) {
3681
- var first, numbers, second;
3682
- numbers = (function() {
3683
- var _i, _len, _ref, _results;
3684
- _results = [];
3685
- for (_i = 0, _len = elements.length; _i < _len; _i++) {
3686
- _ref = elements[_i], first = _ref.first, second = _ref.second;
3687
- _results.push((function(first, second) {
3688
- return first.then(function(cond) {
3689
- if (!cond.value) {
3690
- return unit(0);
3691
- }
3692
- return second.map(function(v) {
3693
- return v.value;
3694
- });
3695
- });
3696
- })(first, second));
3697
- }
3698
- return _results;
3699
- })();
3700
- return combine(numbers).then(function(nums) {
3701
- var num, out, _i, _len;
3702
- out = 0;
3703
- for (_i = 0, _len = nums.length; _i < _len; _i++) {
3704
- num = nums[_i];
3705
- out += num;
3706
- }
3707
- return unit(Value.number(out));
3708
- });
3709
- });
3710
- });
3711
- },
3712
4151
  compile: function(_, _arg) {
3713
4152
  var list;
3714
4153
  list = _arg[0];
@@ -3722,56 +4161,18 @@ stdlib = Gibbon.stdlib = (function() {
3722
4161
  },
3723
4162
  first: {
3724
4163
  type: parse.type('first = [%a] -> %a'),
3725
- impl: function(list) {
3726
- return list.then(function(val) {
3727
- return val.elements[0];
3728
- });
3729
- },
3730
4164
  compile: function(list) {
3731
- return list.delist(0);
4165
+ return list.delist(IR.constant(0));
3732
4166
  }
3733
4167
  },
3734
4168
  squish: {
3735
4169
  type: parse.type('squish = [%a] -> [%a]'),
3736
- impl: function(list) {
3737
- return list.then(function(_arg) {
3738
- var elements, promise, wrapped;
3739
- elements = _arg.elements;
3740
- wrapped = (function() {
3741
- var _i, _len, _results;
3742
- _results = [];
3743
- for (_i = 0, _len = elements.length; _i < _len; _i++) {
3744
- promise = elements[_i];
3745
- _results.push(promise.then(function(e) {
3746
- return e.resolve().map(function(e) {
3747
- return [e.promise()];
3748
- });
3749
- }).or(unit([])));
3750
- }
3751
- return _results;
3752
- })();
3753
- return combine(wrapped).map(function(lists) {
3754
- return Value.list(catLists(lists));
3755
- });
3756
- });
3757
- },
3758
4170
  compile: function(list) {
3759
- return list.filterList(function(el) {
3760
- return IR.rescue(el.seq('v', function(_) {
3761
- return iTrue;
3762
- }), iFalse);
3763
- });
4171
+ return list.squishList();
3764
4172
  }
3765
4173
  },
3766
4174
  add: {
3767
4175
  type: parse.type('add numeric = numeric -> numeric'),
3768
- impl: function(input, num) {
3769
- return combine([input, num]).map(function(_arg) {
3770
- var lhs, rhs;
3771
- lhs = _arg[0], rhs = _arg[1];
3772
- return Value.number(lhs.value + rhs.value);
3773
- });
3774
- },
3775
4176
  compile: function(input, _arg) {
3776
4177
  var num;
3777
4178
  num = _arg[0];
@@ -3780,13 +4181,6 @@ stdlib = Gibbon.stdlib = (function() {
3780
4181
  },
3781
4182
  sub: {
3782
4183
  type: parse.type('sub numeric = numeric -> numeric'),
3783
- impl: function(input, num) {
3784
- return combine([input, num]).map(function(_arg) {
3785
- var lhs, rhs;
3786
- lhs = _arg[0], rhs = _arg[1];
3787
- return Value.number(lhs.value - rhs.value);
3788
- });
3789
- },
3790
4184
  compile: function(input, _arg) {
3791
4185
  var num;
3792
4186
  num = _arg[0];
@@ -3795,42 +4189,24 @@ stdlib = Gibbon.stdlib = (function() {
3795
4189
  },
3796
4190
  id: {
3797
4191
  type: parse.type('id = %a -> %a'),
3798
- impl: function(x) {
3799
- return x;
3800
- },
3801
4192
  compile: function(input) {
3802
4193
  return input;
3803
4194
  }
3804
4195
  },
3805
4196
  "else": {
3806
4197
  type: parse.type('else = % -> bool'),
3807
- impl: function(_) {
3808
- return unit(vTrue);
3809
- },
3810
4198
  compile: function(_) {
3811
4199
  return iTrue;
3812
4200
  }
3813
4201
  },
3814
4202
  not: {
3815
4203
  type: parse.type('not = bool -> bool'),
3816
- impl: function(evalBool) {
3817
- return evalBool.map(function(bool) {
3818
- return Value.boolean(!bool.value);
3819
- });
3820
- },
3821
4204
  compile: function(input) {
3822
4205
  return input.extern('!');
3823
4206
  }
3824
4207
  },
3825
4208
  gt: {
3826
4209
  type: parse.type('gt numeric = numeric -> bool'),
3827
- impl: function(input, num) {
3828
- return combine([input, num]).map(function(_arg) {
3829
- var lhs, rhs;
3830
- lhs = _arg[0], rhs = _arg[1];
3831
- return Value.boolean(lhs.value > rhs.value);
3832
- });
3833
- },
3834
4210
  compile: function(input, _arg) {
3835
4211
  var num;
3836
4212
  num = _arg[0];
@@ -3839,13 +4215,6 @@ stdlib = Gibbon.stdlib = (function() {
3839
4215
  },
3840
4216
  lt: {
3841
4217
  type: parse.type('lt numeric = numeric -> bool'),
3842
- impl: function(input, num) {
3843
- return combine([input, num]).map(function(_arg) {
3844
- var lhs, rhs;
3845
- lhs = _arg[0], rhs = _arg[1];
3846
- return Value.boolean(lhs.value < rhs.value);
3847
- });
3848
- },
3849
4218
  compile: function(input, _arg) {
3850
4219
  var num;
3851
4220
  num = _arg[0];
@@ -3854,18 +4223,10 @@ stdlib = Gibbon.stdlib = (function() {
3854
4223
  },
3855
4224
  eq: {
3856
4225
  type: parse.type('eq %a = %a -> bool'),
3857
- impl: function(input, obj) {
3858
- return combine([input, obj]).then(function(_arg) {
3859
- var lhs, rhs;
3860
- lhs = _arg[0], rhs = _arg[1];
3861
- return lhs.equals(rhs);
3862
- });
3863
- },
3864
- compile: function(input, _arg, _, _arg1) {
3865
- var obj, objType;
4226
+ compile: function(input, _arg, tvars) {
4227
+ var obj;
3866
4228
  obj = _arg[0];
3867
- objType = _arg1[0];
3868
- return compEquals(input, obj, objType);
4229
+ return compEquals(input, obj, tvars.get('a'));
3869
4230
  }
3870
4231
  }
3871
4232
  };
@@ -3873,7 +4234,7 @@ stdlib = Gibbon.stdlib = (function() {
3873
4234
  // Generated by CoffeeScript 1.6.3
3874
4235
  Gibbon.jsonConsumer = (function() {
3875
4236
  return function(tables) {
3876
- var analyzeList, getType, getValue, lists;
4237
+ var analyzeList, getType, getValue, listLookup, lists;
3877
4238
  getType = function(id, accessorName, t, callback) {
3878
4239
  var fields;
3879
4240
  if (!tables.hasOwnProperty(id)) {
@@ -3923,6 +4284,15 @@ Gibbon.jsonConsumer = (function() {
3923
4284
  }
3924
4285
  });
3925
4286
  };
4287
+ listLookup = function(id, listName, v, callback) {
4288
+ var list;
4289
+ list = lists[listName].values;
4290
+ if (list.indexOf(id) >= 0) {
4291
+ return callback(null, v.boolean(true));
4292
+ } else {
4293
+ return callback(null, v.boolean(false));
4294
+ }
4295
+ };
3926
4296
  return {
3927
4297
  analyzeQuery: function(id, query, t, callback) {
3928
4298
  switch (query.type) {
@@ -3935,7 +4305,11 @@ Gibbon.jsonConsumer = (function() {
3935
4305
  }
3936
4306
  },
3937
4307
  performQuery: function(id, annotations, v, callback) {
3938
- return getValue(id, annotations, v, callback);
4308
+ if ('list' in annotations) {
4309
+ return listLookup(id, annotations.list, v, callback);
4310
+ } else {
4311
+ return getValue(id, annotations, v, callback);
4312
+ }
3939
4313
  }
3940
4314
  };
3941
4315
  };