goodguide-gibbon 0.4.2 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
  };