goodguide-gibbon 0.13.1 → 0.14.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.
@@ -1,87 +1,22 @@
1
1
  var Gibbon = (function(undefined) {
2
- var Parsimmon = (function(undefined) {
3
- var P = (function(prototype, ownProperty, undefined) {
4
- return function P(_superclass /* = Object */, definition) {
5
- // handle the case where no superclass is given
6
- if (definition === undefined) {
7
- definition = _superclass;
8
- _superclass = Object;
9
- }
10
-
11
- // C is the class to be returned.
12
- //
13
- // When called, creates and initializes an instance of C, unless
14
- // `this` is already an instance of C, then just initializes `this`;
15
- // either way, returns the instance of C that was initialized.
16
- //
17
- // TODO: the Chrome inspector shows all created objects as `C`
18
- // rather than `Object`. Setting the .name property seems to
19
- // have no effect. Is there a way to override this behavior?
20
- function C() {
21
- var self = this instanceof C ? this : new Bare;
22
- self.init.apply(self, arguments);
23
- return self;
24
- }
25
-
26
- // C.Bare is a class with a noop constructor. Its prototype will be
27
- // the same as C, so that instances of C.Bare are instances of C.
28
- // `new MyClass.Bare` then creates new instances of C without
29
- // calling .init().
30
- function Bare() {}
31
- C.Bare = Bare;
32
-
33
- // Extend the prototype chain: first use Bare to create an
34
- // uninitialized instance of the superclass, then set up Bare
35
- // to create instances of this class.
36
- var _super = Bare[prototype] = _superclass[prototype];
37
- var proto = Bare[prototype] = C[prototype] = C.p = new Bare;
38
-
39
- // pre-declaring the iteration variable for the loop below to save
40
- // a `var` keyword after minification
41
- var key;
42
-
43
- // set the constructor property on the prototype, for convenience
44
- proto.constructor = C;
45
-
46
- C.extend = function(def) { return P(C, def); }
47
-
48
- return (C.open = function(def) {
49
- if (typeof def === 'function') {
50
- // call the defining function with all the arguments you need
51
- // extensions captures the return value.
52
- def = def.call(C, proto, _super, C, _superclass);
53
- }
54
-
55
- // ...and extend it
56
- if (typeof def === 'object') {
57
- for (key in def) {
58
- if (ownProperty.call(def, key)) {
59
- proto[key] = def[key];
60
- }
61
- }
62
- }
63
-
64
- // if no init, assume we're inheriting from a non-Pjs class, so
65
- // default to using the superclass constructor.
66
- if (!('init' in proto)) proto.init = _superclass;
67
-
68
- return C;
69
- })(definition);
70
- }
71
-
72
- // as a minifier optimization, we've closured in a few helper functions
73
- // and the string 'prototype' (C[p] is much shorter than C.prototype)
74
- })('prototype', ({}).hasOwnProperty);
2
+ // pass
75
3
  var Parsimmon = {};
76
4
 
77
- Parsimmon.Parser = P(function(_, _super, Parser) {
5
+ Parsimmon.Parser = (function() {
78
6
  "use strict";
7
+
79
8
  // The Parser object is a wrapper for a parser function.
80
9
  // Externally, you use one to parse a string by calling
81
10
  // var result = SomeParser.parse('Me Me Me! Parse Me!');
82
11
  // You should never call the constructor, rather you should
83
12
  // construct your Parser from the base parsers and the
84
13
  // parser combinator methods.
14
+ function Parser(action) {
15
+ if (!(this instanceof Parser)) return new Parser(action);
16
+ this._ = action;
17
+ };
18
+
19
+ var _ = Parser.prototype;
85
20
 
86
21
  function makeSuccess(index, value) {
87
22
  return {
@@ -89,7 +24,7 @@ Parsimmon.Parser = P(function(_, _super, Parser) {
89
24
  index: index,
90
25
  value: value,
91
26
  furthest: -1,
92
- expected: ''
27
+ expected: []
93
28
  };
94
29
  }
95
30
 
@@ -99,20 +34,24 @@ Parsimmon.Parser = P(function(_, _super, Parser) {
99
34
  index: -1,
100
35
  value: null,
101
36
  furthest: index,
102
- expected: expected
37
+ expected: [expected]
103
38
  };
104
39
  }
105
40
 
106
- function furthestBacktrackFor(result, last) {
41
+ function mergeReplies(result, last) {
107
42
  if (!last) return result;
108
- if (result.furthest >= last.furthest) return result;
43
+ if (result.furthest > last.furthest) return result;
44
+
45
+ var expected = (result.furthest === last.furthest)
46
+ ? result.expected.concat(last.expected)
47
+ : last.expected;
109
48
 
110
49
  return {
111
50
  status: result.status,
112
51
  index: result.index,
113
52
  value: result.value,
114
53
  furthest: last.furthest,
115
- expected: last.expected
54
+ expected: expected
116
55
  }
117
56
  }
118
57
 
@@ -120,23 +59,28 @@ Parsimmon.Parser = P(function(_, _super, Parser) {
120
59
  if (!(p instanceof Parser)) throw new Error('not a parser: '+p);
121
60
  }
122
61
 
123
- var formatError = Parsimmon.formatError = function(stream, error) {
124
- var expected = error.expected;
62
+ function formatExpected(expected) {
63
+ if (expected.length === 1) return expected[0];
64
+
65
+ return 'one of ' + expected.join(', ')
66
+ }
67
+
68
+ function formatGot(stream, error) {
125
69
  var i = error.index;
126
70
 
127
- if (i === stream.length) {
128
- return 'expected ' + expected + ', got the end of the string';
129
- }
71
+ if (i === stream.length) return ', got the end of the stream'
72
+
130
73
 
131
74
  var prefix = (i > 0 ? "'..." : "'");
132
75
  var suffix = (stream.length - i > 12 ? "...'" : "'");
133
- return (
134
- 'expected ' + expected + ' at character ' + i + ', got ' +
135
- prefix + stream.slice(i, i+12) + suffix
136
- );
137
- };
138
76
 
139
- _.init = function(body) { this._ = body; };
77
+ return ' at character ' + i + ', got ' + prefix + stream.slice(i, i+12) + suffix
78
+ }
79
+
80
+ var formatError = Parsimmon.formatError = function(stream, error) {
81
+ console.log('formatError', stream, error);
82
+ return 'expected ' + formatExpected(error.expected) + formatGot(stream, error)
83
+ };
140
84
 
141
85
  _.parse = function(stream) {
142
86
  var result = this.skip(eof)._(stream, 0);
@@ -161,13 +105,22 @@ Parsimmon.Parser = P(function(_, _super, Parser) {
161
105
  var accum = new Array(numParsers);
162
106
 
163
107
  for (var j = 0; j < numParsers; j += 1) {
164
- result = furthestBacktrackFor(parsers[j]._(stream, i), result);
108
+ result = mergeReplies(parsers[j]._(stream, i), result);
165
109
  if (!result.status) return result;
166
110
  accum[j] = result.value
167
111
  i = result.index;
168
112
  }
169
113
 
170
- return furthestBacktrackFor(makeSuccess(i, accum), result);
114
+ return mergeReplies(makeSuccess(i, accum), result);
115
+ });
116
+ };
117
+
118
+
119
+ var seqMap = Parsimmon.seqMap = function() {
120
+ var args = [].slice.call(arguments);
121
+ var mapper = args.pop();
122
+ return seq.apply(null, args).map(function(results) {
123
+ return mapper.apply(null, results);
171
124
  });
172
125
  };
173
126
 
@@ -186,7 +139,7 @@ Parsimmon.Parser = P(function(_, _super, Parser) {
186
139
  return Parser(function(stream, i) {
187
140
  var result;
188
141
  for (var j = 0; j < parsers.length; j += 1) {
189
- result = furthestBacktrackFor(parsers[j]._(stream, i), result);
142
+ result = mergeReplies(parsers[j]._(stream, i), result);
190
143
  if (result.status) return result;
191
144
  }
192
145
  return result;
@@ -200,7 +153,7 @@ Parsimmon.Parser = P(function(_, _super, Parser) {
200
153
 
201
154
  _.then = function(next) {
202
155
  if (typeof next === 'function') {
203
- throw new Error('chaining features of .then are no longer supported');
156
+ throw new Error('chaining features of .then are no longer supported, use .chain instead');
204
157
  }
205
158
 
206
159
  assertParser(next);
@@ -230,14 +183,14 @@ Parsimmon.Parser = P(function(_, _super, Parser) {
230
183
  var prevResult;
231
184
 
232
185
  for (;;) {
233
- result = furthestBacktrackFor(self._(stream, i), result);
186
+ result = mergeReplies(self._(stream, i), result);
234
187
 
235
188
  if (result.status) {
236
189
  i = result.index;
237
190
  accum.push(result.value);
238
191
  }
239
192
  else {
240
- return furthestBacktrackFor(makeSuccess(i, accum), result);
193
+ return mergeReplies(makeSuccess(i, accum), result);
241
194
  }
242
195
  }
243
196
  });
@@ -275,39 +228,35 @@ Parsimmon.Parser = P(function(_, _super, Parser) {
275
228
 
276
229
  for (var times = 0; times < min; times += 1) {
277
230
  result = self._(stream, i);
278
- prevResult = furthestBacktrackFor(result, prevResult);
231
+ prevResult = mergeReplies(result, prevResult);
279
232
  if (result.status) {
280
233
  i = result.index;
281
234
  accum.push(result.value);
282
235
  }
283
- else {
284
- return prevResult;
285
- }
236
+ else return prevResult;
286
237
  }
287
238
 
288
239
  for (; times < max; times += 1) {
289
240
  result = self._(stream, i);
290
- prevResult = furthestBacktrackFor(result, prevResult);
241
+ prevResult = mergeReplies(result, prevResult);
291
242
  if (result.status) {
292
243
  i = result.index;
293
244
  accum.push(result.value);
294
245
  }
295
- else {
296
- break;
297
- }
246
+ else break;
298
247
  }
299
248
 
300
- return furthestBacktrackFor(makeSuccess(i, accum), prevResult);
249
+ return mergeReplies(makeSuccess(i, accum), prevResult);
301
250
  });
302
251
  };
303
252
 
304
253
  // -*- higher-level combinators -*- //
305
- _.result = function(res) { return this.then(succeed(res)); };
254
+ _.result = function(res) { return this.map(function(_) { return res; }); };
306
255
  _.atMost = function(n) { return this.times(0, n); };
307
256
  _.atLeast = function(n) {
308
257
  var self = this;
309
- return seq(this.times(n), this.many()).map(function(results) {
310
- return results[0].concat(results[1]);
258
+ return seqMap(this.times(n), this.many(), function(init, rest) {
259
+ return init.concat(rest);
311
260
  });
312
261
  };
313
262
 
@@ -316,7 +265,7 @@ Parsimmon.Parser = P(function(_, _super, Parser) {
316
265
  return Parser(function(stream, i) {
317
266
  var result = self._(stream, i);
318
267
  if (!result.status) return result;
319
- return furthestBacktrackFor(makeSuccess(result.index, fn(result.value)), result);
268
+ return mergeReplies(makeSuccess(result.index, fn(result.value)), result);
320
269
  });
321
270
  };
322
271
 
@@ -325,13 +274,18 @@ Parsimmon.Parser = P(function(_, _super, Parser) {
325
274
  };
326
275
 
327
276
  _.mark = function() {
328
- return seq(index, this, index).map(function(results) {
329
- return { start: results[0], value: results[1], end: results[2] };
277
+ return seqMap(index, this, index, function(start, value, end) {
278
+ return { start: start, value: value, end: end };
330
279
  });
331
280
  };
332
281
 
333
282
  _.desc = function(expected) {
334
- return this.or(fail(expected))
283
+ var self = this;
284
+ return Parser(function(stream, i) {
285
+ var reply = self._(stream, i);
286
+ if (!reply.status) reply.expected = [expected];
287
+ return reply;
288
+ });
335
289
  };
336
290
 
337
291
  // -*- primitive parsers -*- //
@@ -351,19 +305,21 @@ Parsimmon.Parser = P(function(_, _super, Parser) {
351
305
  });
352
306
  };
353
307
 
354
- var regex = Parsimmon.regex = function(re) {
308
+ var regex = Parsimmon.regex = function(re, group) {
355
309
  var anchored = RegExp('^(?:'+re.source+')', (''+re).slice((''+re).lastIndexOf('/')+1));
310
+ var expected = '' + re;
311
+ if (group == null) group = 0;
356
312
 
357
313
  return Parser(function(stream, i) {
358
314
  var match = anchored.exec(stream.slice(i));
359
315
 
360
316
  if (match) {
361
- var result = match[0];
362
- return makeSuccess(i+result.length, result);
363
- }
364
- else {
365
- return makeFailure(i, re);
317
+ var fullMatch = match[0];
318
+ var groupMatch = match[group];
319
+ if (groupMatch != null) return makeSuccess(i+fullMatch.length, groupMatch);
366
320
  }
321
+
322
+ return makeFailure(i, expected);
367
323
  });
368
324
  };
369
325
 
@@ -412,6 +368,14 @@ Parsimmon.Parser = P(function(_, _super, Parser) {
412
368
  });
413
369
  };
414
370
 
371
+ var oneOf = Parsimmon.oneOf = function(str) {
372
+ return test(function(ch) { return str.indexOf(ch) >= 0; });
373
+ };
374
+
375
+ var noneOf = Parsimmon.noneOf = function(str) {
376
+ return test(function(ch) { return str.indexOf(ch) < 0; });
377
+ };
378
+
415
379
  var takeWhile = Parsimmon.takeWhile = function(predicate) {
416
380
  return Parser(function(stream, i) {
417
381
  var j = i;
@@ -450,9 +414,7 @@ Parsimmon.Parser = P(function(_, _super, Parser) {
450
414
  _.of = Parser.of = Parsimmon.of = succeed
451
415
 
452
416
  _.ap = function(other) {
453
- return seq(this, other).map(function(results) {
454
- return results[0](results[1]);
455
- });
417
+ return seqMap(this, other, function(f, x) { return f(x); })
456
418
  };
457
419
 
458
420
  //- Monad
@@ -462,12 +424,13 @@ Parsimmon.Parser = P(function(_, _super, Parser) {
462
424
  var result = self._(stream, i);
463
425
  if (!result.status) return result;
464
426
  var nextParser = f(result.value);
465
- return furthestBacktrackFor(nextParser._(stream, result.index), result);
427
+ return mergeReplies(nextParser._(stream, result.index), result);
466
428
  });
467
429
  };
468
- });
469
- return Parsimmon;
470
- })()
430
+
431
+ return Parser;
432
+ })();
433
+ // pass
471
434
  // Generated by CoffeeScript 1.6.3
472
435
  var AST, CompiledCode, Core, DEBUG, Dependency, Failure, Gibbon, Hash, JS, List, Map, ObjHash, RVal, Result, Ruby, Semantic, Step, Thunk, Trace, Type, TypeAST, TypeExpr, TypeLookup, Value, VarTrace, Variant, analyze, applyOp1, applyOp2, asyncMap, contIter, contMap, equalArrays, eval_, inspectNative, isArray, nameGen, parse, stdlib, uniq, _ref, _ref1, _ref10, _ref11, _ref12, _ref13, _ref14, _ref15, _ref16, _ref17, _ref18, _ref19, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7, _ref8, _ref9,
473
436
  __slice = [].slice,
@@ -1060,7 +1023,8 @@ Gibbon.AST = AST = (function(_super) {
1060
1023
  flow: ['loc', 'head', 'tail'],
1061
1024
  metadata: ['loc', 'key', 'text'],
1062
1025
  definition: ['loc', 'metadata', 'name', 'frame'],
1063
- frame: ['loc', 'definitions', 'flow']
1026
+ frame: ['loc', 'definitions', 'flow'],
1027
+ program: ['definitions']
1064
1028
  });
1065
1029
 
1066
1030
  inspectDefinitions = function(defs) {
@@ -1179,6 +1143,9 @@ Gibbon.AST = AST = (function(_super) {
1179
1143
  out.push(flow.inspect());
1180
1144
  out.push(")");
1181
1145
  return out.join('');
1146
+ },
1147
+ program: function(definitions) {
1148
+ return inspectDefinitions(definitions);
1182
1149
  }
1183
1150
  });
1184
1151
  };
@@ -1215,17 +1182,10 @@ Gibbon.TypeAST = TypeAST = (function(_super) {
1215
1182
  })(Variant);
1216
1183
 
1217
1184
  parse = Gibbon.parse = (function() {
1218
- var accessor, accessorExpr, arrow, arrowType, assertString, blankLines, blockExpr, blockType, comma, commaSepFlows, comment, component, concrete, decimal, decimalExpr, defaulted, define, definition, expr, fail, flow, fraction, fractionExpr, frame, freeFrame, fullSignature, func, funcPlaceholder, handleResult, identifier, innerFrame, integer, integerExpr, isString, label, labelVal, lazy, lbrace, lbrack, lexeme, lexical, lexicalExpr, lines, listExpr, listType, lparen, lsplat, metadata, multiline, name, nonDefaultedFlow, nonPairedFlow, numericExpr, opt, pair, parenFlow, parenFrame, parenType, percent, percentExpr, program, query, queryArg, queryExpr, rbrace, rbrack, regex, rparen, rsplat, seq, signature, simpleType, singletonFlow, spanLoc, squishListExpr, str, string, stringExpr, substExpr, succeed, tag, tassign, type, typeVar, variable, whitespace, wildType, wildcard, withLoc,
1185
+ var accessor, accessorExpr, arrow, arrowType, assertString, blankLines, blockExpr, blockType, comma, commaSepFlows, comment, component, concrete, decimal, decimalExpr, defaulted, define, definition, expr, fail, flow, fraction, fractionExpr, frame, freeFrame, fullFrame, fullSignature, func, funcPlaceholder, handleResult, identifier, innerFrame, integer, integerExpr, isString, label, labelVal, lazy, lbrace, lbrack, lexeme, lexical, lexicalExpr, lines, listExpr, listType, lparen, lsplat, metadata, multiline, name, nonDefaultedFlow, nonPairedFlow, numericExpr, opt, pair, parenFlow, parenFrame, parenType, percent, percentExpr, program, query, queryArg, queryExpr, rbrace, rbrack, regex, rparen, rsplat, seq, signature, simpleType, singletonFlow, spanLoc, squishListExpr, str, string, stringExpr, substExpr, succeed, tag, tassign, type, typeVar, variable, whitespace, wildType, wildcard, withLoc,
1219
1186
  _this = this;
1220
1187
  tag = function(name, parser) {
1221
- return Parsimmon.Parser(function(stream, i) {
1222
- var result;
1223
- result = parser._(stream, i);
1224
- if (!result.status) {
1225
- result.expected = name;
1226
- }
1227
- return result;
1228
- });
1188
+ return parser.desc(name);
1229
1189
  };
1230
1190
  Parsimmon.Parser.prototype.tryChain = function(f) {
1231
1191
  return this.chain(function(res) {
@@ -1234,10 +1194,10 @@ parse = Gibbon.parse = (function() {
1234
1194
  };
1235
1195
  string = Parsimmon.string, regex = Parsimmon.regex, succeed = Parsimmon.succeed, fail = Parsimmon.fail;
1236
1196
  seq = Parsimmon.seq, lazy = Parsimmon.lazy;
1237
- whitespace = regex(/^[ \t]*/);
1238
- blankLines = regex(/^[\n;\s]+/);
1239
- comment = regex(/^#.*?(\n|$)/);
1240
- lines = (blankLines.or(comment)).many();
1197
+ whitespace = tag('inline whitespace', regex(/^[ \t]*/));
1198
+ blankLines = regex(/[\n;\s]+/).desc('blank lines');
1199
+ comment = regex(/#.*?(\n|$)/).desc('a comment');
1200
+ lines = tag('whitespace', (blankLines.or(comment)).many());
1241
1201
  lexeme = function(p) {
1242
1202
  return p.mark().skip(whitespace);
1243
1203
  };
@@ -1277,9 +1237,9 @@ parse = Gibbon.parse = (function() {
1277
1237
  defaulted = multiline(string('|'));
1278
1238
  lsplat = multiline(string('[*'));
1279
1239
  rsplat = lexeme(string('*]'));
1280
- query = lexeme(string('@:').then(identifier));
1240
+ query = lexeme(string('@:').then(identifier).desc('a query'));
1281
1241
  queryArg = lexeme(regex(/^\w[\w-]*/));
1282
- accessor = lexeme(string('@').then(identifier));
1242
+ accessor = lexeme(string('@').then(identifier).desc('an accessor'));
1283
1243
  lexical = lexeme(string('.').then(identifier));
1284
1244
  name = lexeme(identifier);
1285
1245
  str = lexeme(string("'").then(regex(/^[^']*/)).skip(string("'")));
@@ -1414,7 +1374,7 @@ parse = Gibbon.parse = (function() {
1414
1374
  }
1415
1375
  return els;
1416
1376
  });
1417
- metadata = seq(label, labelVal).map(function(_arg) {
1377
+ metadata = seq(label, labelVal).desc('metadata').map(function(_arg) {
1418
1378
  var key, text;
1419
1379
  key = _arg[0], text = _arg[1];
1420
1380
  return AST.metadata(spanLoc(key, text), key.value, text.value);
@@ -1427,10 +1387,11 @@ parse = Gibbon.parse = (function() {
1427
1387
  return AST.definition(loc, md, n.value, fl);
1428
1388
  });
1429
1389
  });
1430
- frame = seq(definition.many(), flow).map(function(_arg) {
1431
- var defs, flow, loc;
1432
- defs = _arg[0], flow = _arg[1];
1433
- loc = spanLoc((defs[0] || flow).loc, flow.loc);
1390
+ frame = seq(definition, definition.many(), flow).map(function(_arg) {
1391
+ var defs, first, flow, loc, rest;
1392
+ first = _arg[0], rest = _arg[1], flow = _arg[2];
1393
+ defs = [first].concat(rest);
1394
+ loc = spanLoc(first.loc, flow.loc);
1434
1395
  return AST.frame(loc, defs, flow);
1435
1396
  });
1436
1397
  parenFrame = seq(lparen, frame, rparen, lines).map(function(_arg) {
@@ -1443,7 +1404,10 @@ parse = Gibbon.parse = (function() {
1443
1404
  return AST.frame(fl.loc, [], fl);
1444
1405
  });
1445
1406
  innerFrame = parenFrame.or(freeFrame);
1446
- program = lines.then(frame);
1407
+ program = lines.then(definition.many()).map(function(ds) {
1408
+ return AST.program(ds);
1409
+ });
1410
+ fullFrame = lines.then(frame.or(flow));
1447
1411
  tassign = lexeme(string('='));
1448
1412
  concrete = name.map(function(n) {
1449
1413
  return TypeAST.concrete(n.value);
@@ -1503,6 +1467,9 @@ parse = Gibbon.parse = (function() {
1503
1467
  assertString(str);
1504
1468
  return handleResult(str, program.parse(str));
1505
1469
  };
1470
+ parse.frame = function(str) {
1471
+ return handleResult(str, fullFrame.parse(str));
1472
+ };
1506
1473
  parse.type = function(str) {
1507
1474
  assertString(str);
1508
1475
  return handleResult(str, fullSignature.parse(str));
@@ -1742,9 +1709,9 @@ Gibbon.TypeExpr = TypeExpr = (function(_super) {
1742
1709
  variable: ['name', 'uniq'],
1743
1710
  query: ['input', 'scope', 'query'],
1744
1711
  lexical: ['syntax', 'scope'],
1745
- destructure: ['constraint', 'name', 'argnum'],
1746
1712
  "native": ['id'],
1747
1713
  param: ['name', 'constraints'],
1714
+ destructure: ['constraint', 'name', 'argnum'],
1748
1715
  error: ['type', 'args'],
1749
1716
  any: []
1750
1717
  });
@@ -1972,29 +1939,6 @@ Gibbon.TypeExpr = TypeExpr = (function(_super) {
1972
1939
  });
1973
1940
  };
1974
1941
 
1975
- TypeExpr.prototype.mapAsync = function(f, cb) {
1976
- return this.cases({
1977
- param: function(name, params) {
1978
- return asyncMap(params, f, function(ps) {
1979
- return cb(TypeExpr.param(name, ps));
1980
- });
1981
- },
1982
- query: function(input, scope, query) {
1983
- return f(input, function(i) {
1984
- return cb(TypeExpr.query(i, scope, query));
1985
- });
1986
- },
1987
- destructure: function(param, name, argnum) {
1988
- return f(param, function(p) {
1989
- return cb(TypeExpr.destructure(p, name, argnum));
1990
- });
1991
- },
1992
- other: function() {
1993
- return cb(this);
1994
- }
1995
- });
1996
- };
1997
-
1998
1942
  return TypeExpr;
1999
1943
 
2000
1944
  })(Variant);
@@ -2017,19 +1961,18 @@ analyze = Gibbon.analyze = (function() {
2017
1961
  })();
2018
1962
  }
2019
1963
 
2020
- NativeContext.prototype.query = function(id, query, cb) {
2021
- var cacheKey, lookupFn,
2022
- _this = this;
1964
+ NativeContext.prototype.query = function(id, query) {
1965
+ var cacheKey, lookupFn;
2023
1966
  cacheKey = "" + id + "/" + query.type + " " + (query.args.join(' '));
2024
- if (this.queryCache.has(cacheKey)) {
2025
- return Thunk.trampoline(cb(this.queryCache.get(cacheKey)));
2026
- }
2027
1967
  lookupFn = this.externalLookup;
2028
- return lookupFn(id, query, Type, function(err, analysis) {
1968
+ return this.queryCache.cache(cacheKey, function() {
2029
1969
  var result;
2030
- result = err ? TypeLookup.error(err) : TypeLookup.response(query, analysis);
2031
- _this.queryCache.set(cacheKey, result);
2032
- return Thunk.trampoline(cb(result));
1970
+ result = lookupFn(id, query, Type);
1971
+ if (result.success) {
1972
+ return TypeLookup.response(query, result.analysis);
1973
+ } else {
1974
+ return TypeLookup.error(result.error);
1975
+ }
2033
1976
  });
2034
1977
  };
2035
1978
 
@@ -2039,14 +1982,14 @@ analyze = Gibbon.analyze = (function() {
2039
1982
  Scope = (function() {
2040
1983
  var makeKey;
2041
1984
 
2042
- Scope.global = function(context, frame) {
2043
- return new Scope(null, [], frame, context, new Hash);
1985
+ Scope.global = function(context, defs) {
1986
+ return new Scope(null, [], defs, context, new Hash);
2044
1987
  };
2045
1988
 
2046
- function Scope(parent, breadcrumbs, frame, context, metadata) {
1989
+ function Scope(parent, breadcrumbs, definitions, context, metadata) {
2047
1990
  this.parent = parent;
2048
1991
  this.breadcrumbs = breadcrumbs;
2049
- this.frame = frame;
1992
+ this.definitions = definitions;
2050
1993
  this.context = context;
2051
1994
  this.metadata = metadata;
2052
1995
  this.bindings = new Hash;
@@ -2054,20 +1997,20 @@ analyze = Gibbon.analyze = (function() {
2054
1997
  }
2055
1998
 
2056
1999
  Scope.prototype.extend = function(definition) {
2057
- var breadcrumbs, frame, key, metadata, text, _i, _len, _ref10, _ref9;
2000
+ var breadcrumbs, definitions, key, metadata, text, _i, _len, _ref10, _ref9;
2058
2001
  breadcrumbs = this.breadcrumbs.concat(definition.name);
2059
- frame = definition.frame;
2002
+ definitions = definition.frame.definitions;
2060
2003
  metadata = new Hash;
2061
2004
  _ref9 = definition.metadata;
2062
2005
  for (_i = 0, _len = _ref9.length; _i < _len; _i++) {
2063
2006
  _ref10 = _ref9[_i], key = _ref10.key, text = _ref10.text;
2064
2007
  metadata.set(key, text);
2065
2008
  }
2066
- return new Scope(this, breadcrumbs, frame, this.context, metadata);
2009
+ return new Scope(this, breadcrumbs, definitions, this.context, metadata);
2067
2010
  };
2068
2011
 
2069
- Scope.prototype.lookup = function(nativeId, query, cb) {
2070
- return this.context.query(nativeId, query, cb);
2012
+ Scope.prototype.lookup = function(nativeId, query) {
2013
+ return this.context.query(nativeId, query);
2071
2014
  };
2072
2015
 
2073
2016
  Scope.prototype.lexicalLookup = function(name) {
@@ -2093,20 +2036,21 @@ analyze = Gibbon.analyze = (function() {
2093
2036
  };
2094
2037
 
2095
2038
  Scope.prototype.analyze = function(push) {
2096
- var def, frame, frameScope, global, _i, _len, _ref9,
2039
+ var def, framePush, frameScope, global, _i, _len, _ref9, _results,
2097
2040
  _this = this;
2098
- _ref9 = this.frame.definitions;
2041
+ global = TypeExpr["native"](this.context.globalID);
2042
+ _ref9 = this.definitions;
2043
+ _results = [];
2099
2044
  for (_i = 0, _len = _ref9.length; _i < _len; _i++) {
2100
2045
  def = _ref9[_i];
2101
- frameScope = this.extend(def);
2046
+ frameScope = this.bindings.set(def.name, this.extend(def));
2102
2047
  frameScope.analyze(push);
2103
- this.bindings.set(def.name, frameScope);
2048
+ framePush = function(lhs, rhs) {
2049
+ return push(frameScope, def.frame, [lhs, rhs]);
2050
+ };
2051
+ _results.push(frameScope.analyzeFlow(def.frame.flow, global, framePush));
2104
2052
  }
2105
- global = TypeExpr["native"](this.context.globalID);
2106
- frame = this.frame;
2107
- return this.analyzeFlow(this.frame.flow, global, function(lhs, rhs) {
2108
- return push(_this, [lhs, rhs]);
2109
- });
2053
+ return _results;
2110
2054
  };
2111
2055
 
2112
2056
  Scope.prototype.analyzeFlow = function(flow, global, push) {
@@ -2200,13 +2144,14 @@ analyze = Gibbon.analyze = (function() {
2200
2144
  return function(globalID, externalLookup, program) {
2201
2145
  var constraintMap, context, scope;
2202
2146
  context = new NativeContext(globalID, externalLookup);
2203
- scope = Scope.global(context, program);
2147
+ scope = Scope.global(context, program.definitions);
2204
2148
  constraintMap = new Hash;
2205
- scope.analyze(function(scope, constraint) {
2149
+ scope.analyze(function(scope, frame, constraint) {
2206
2150
  var entry;
2207
2151
  entry = constraintMap.cache(scope.key(), function() {
2208
2152
  return {
2209
2153
  scope: scope,
2154
+ frame: frame,
2210
2155
  constraints: []
2211
2156
  };
2212
2157
  });
@@ -2216,7 +2161,10 @@ analyze = Gibbon.analyze = (function() {
2216
2161
  };
2217
2162
  })();
2218
2163
  solve = (function() {
2219
- var TypeError, consume, _ref9;
2164
+ var SolveState, Solver, TypeError, _ref9;
2165
+ DEBUG.logConstraint = function(prefix, lhs, rhs) {
2166
+ return DEBUG.log(prefix, lhs.inspect(), '=', rhs.inspect());
2167
+ };
2220
2168
  TypeError = (function(_super) {
2221
2169
  __extends(TypeError, _super);
2222
2170
 
@@ -2260,382 +2208,446 @@ analyze = Gibbon.analyze = (function() {
2260
2208
  return TypeError;
2261
2209
 
2262
2210
  })(Variant);
2263
- DEBUG.logConstraint = function(prefix, lhs, rhs) {
2264
- return DEBUG.log(prefix, lhs.inspect(), '=', rhs.inspect());
2265
- };
2266
- consume = function(array, next, body) {
2267
- var loop_, push;
2268
- push = function(x, y) {
2269
- return array.push([x, y]);
2211
+ SolveState = (function() {
2212
+ function SolveState(constraintMap) {
2213
+ this.constraintMap = constraintMap;
2214
+ this.locks = new Hash;
2215
+ this.crumbs = [];
2216
+ this.errors = [];
2217
+ this.semantics = new Hash;
2218
+ }
2219
+
2220
+ SolveState.prototype.solved = function(key, semantic) {
2221
+ return this.semantics.set(key, semantic);
2222
+ };
2223
+
2224
+ SolveState.prototype.solverFor = function(key) {
2225
+ return new Solver(this, key);
2226
+ };
2227
+
2228
+ SolveState.prototype.solveKey = function(key) {
2229
+ if (this.semantics.has(key)) {
2230
+ return TypeExpr.fromType(this.semantics.get(key).flow.type);
2231
+ }
2232
+ return this.solverFor(key).solve();
2233
+ };
2234
+
2235
+ SolveState.prototype.solveAll = function() {
2236
+ var key, _i, _len, _ref10;
2237
+ DEBUG.log('keys to solve: ', this.constraintMap.keys());
2238
+ _ref10 = this.constraintMap.keys();
2239
+ for (_i = 0, _len = _ref10.length; _i < _len; _i++) {
2240
+ key = _ref10[_i];
2241
+ this.solveKey(key);
2242
+ }
2243
+ if (this.errors.length === 0) {
2244
+ return {
2245
+ success: true,
2246
+ semantics: this.semantics
2247
+ };
2248
+ } else {
2249
+ return {
2250
+ success: false,
2251
+ errors: this.errors
2252
+ };
2253
+ }
2254
+ };
2255
+
2256
+ return SolveState;
2257
+
2258
+ })();
2259
+ Solver = (function() {
2260
+ function Solver(state, key) {
2261
+ var entry;
2262
+ this.state = state;
2263
+ this.key = key;
2264
+ entry = this.state.constraintMap.get(this.key);
2265
+ this.scope = entry.scope;
2266
+ this.frame = entry.frame;
2267
+ this.constraints = entry.constraints.reverse();
2268
+ this.dependencies = [];
2269
+ this.solutions = new ObjHash;
2270
+ this.queryResults = new ObjHash;
2271
+ }
2272
+
2273
+ Solver.prototype.error = function() {
2274
+ var args, type;
2275
+ type = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
2276
+ this.state.errors.push(TypeError[type].apply(TypeError, args));
2277
+ return TypeExpr.any();
2278
+ };
2279
+
2280
+ Solver.prototype.hasErrors = function() {
2281
+ return this.state.errors.length > 0;
2270
2282
  };
2271
- loop_ = function() {
2272
- var lhs, rhs, _ref10;
2273
- if (!(array.length > 0)) {
2274
- return next();
2283
+
2284
+ Solver.prototype.typeOf = function(expr) {
2285
+ if (this.solutions.has(expr)) {
2286
+ return this.solutions.get(expr).realize();
2275
2287
  }
2276
- _ref10 = array.pop(), lhs = _ref10[0], rhs = _ref10[1];
2277
- return body(lhs, rhs, push, function() {
2278
- return new Thunk(loop_);
2288
+ return expr.cases({
2289
+ expr: function() {
2290
+ throw new Error('unsolved!');
2291
+ },
2292
+ other: function() {
2293
+ return Type.abstract(TypeExpr.expr(expr));
2294
+ }
2279
2295
  });
2280
2296
  };
2281
- return Thunk.trampoline(loop_());
2282
- };
2283
- return function(constraintMap, finish) {
2284
- var errors, frameTypes, initialCrumbs, k, locks, semantics, solutions, solveEntry;
2285
- errors = [];
2286
- solutions = new ObjHash;
2287
- semantics = new Hash;
2288
- frameTypes = new Hash;
2289
- locks = new Hash;
2290
- solveEntry = function(crumbs, solved) {
2291
- var constraints, dependencies, done, error, frame, fullSubstitute, key, nextCrumbs, scope, semanticAccessors, simplify, substitute, _ref10;
2292
- key = crumbs[crumbs.length - 1];
2293
- if (semantics.has(key)) {
2294
- return solved();
2297
+
2298
+ Solver.prototype.makeSemantic = function(expr) {
2299
+ var _this = this;
2300
+ return expr.cases({
2301
+ frame: function(_, __, flow) {
2302
+ return Semantic.definition(_this.dependencies, _this.makeSemantic(flow), _this.scope.metadata);
2303
+ },
2304
+ flow: function(_, head, tail) {
2305
+ return Semantic.flow(_this.typeOf(TypeExpr.expr(expr)), _this.makeSemantic(head), tail && _this.makeSemantic(tail));
2306
+ },
2307
+ query: function(_, type, name) {
2308
+ if (!(_this.hasErrors() || _this.queryResults.has(expr))) {
2309
+ throw "panic: unsolved query with no errors!";
2310
+ }
2311
+ return _this.queryResults.get(expr);
2312
+ },
2313
+ lexical: function(_, name) {
2314
+ return _this.queryResults.get(expr);
2315
+ },
2316
+ func: function(_, name, args) {
2317
+ var a, semArgs, solvedScope, typeScope;
2318
+ typeScope = expr.__scope__;
2319
+ solvedScope = new Hash;
2320
+ typeScope && typeScope.each(function(name, texpr) {
2321
+ return solvedScope.set(name, _this.typeOf(texpr));
2322
+ });
2323
+ semArgs = (function() {
2324
+ var _i, _len, _results;
2325
+ _results = [];
2326
+ for (_i = 0, _len = args.length; _i < _len; _i++) {
2327
+ a = args[_i];
2328
+ _results.push(this.makeSemantic(a));
2329
+ }
2330
+ return _results;
2331
+ }).call(_this);
2332
+ return Semantic.func(name, semArgs, solvedScope);
2333
+ },
2334
+ pair: function(_, first, second) {
2335
+ return Semantic.pair(_this.makeSemantic(first), _this.makeSemantic(second));
2336
+ },
2337
+ block: function(_, flow) {
2338
+ return Semantic.block(_this.makeSemantic(flow));
2339
+ },
2340
+ subst: function(_, subFlow) {
2341
+ return _this.makeSemantic(subFlow);
2342
+ },
2343
+ list: function(_, elements, squish) {
2344
+ var e;
2345
+ return Semantic.list((function() {
2346
+ var _i, _len, _results;
2347
+ _results = [];
2348
+ for (_i = 0, _len = elements.length; _i < _len; _i++) {
2349
+ e = elements[_i];
2350
+ _results.push(this.makeSemantic(e));
2351
+ }
2352
+ return _results;
2353
+ }).call(_this), squish);
2354
+ },
2355
+ defaulted: function(_, body, alt) {
2356
+ return Semantic.defaulted(_this.makeSemantic(body), _this.makeSemantic(alt));
2357
+ },
2358
+ integer: function() {
2359
+ return Semantic.literal(this);
2360
+ },
2361
+ decimal: function() {
2362
+ return Semantic.literal(this);
2363
+ },
2364
+ percent: function() {
2365
+ return Semantic.literal(this);
2366
+ },
2367
+ fraction: function() {
2368
+ return Semantic.literal(this);
2369
+ },
2370
+ string: function() {
2371
+ return Semantic.literal(this);
2372
+ }
2373
+ });
2374
+ };
2375
+
2376
+ Solver.prototype.lookup = function(scope, id, query) {
2377
+ var lookup,
2378
+ _this = this;
2379
+ lookup = scope.lookup(id, query);
2380
+ this.dependencies.push(lookup);
2381
+ return lookup.cases({
2382
+ error: function(e) {
2383
+ return _this.error('lookup', query, id, e);
2384
+ },
2385
+ response: function(_, analysis) {
2386
+ _this.queryResults.set(query, Semantic.query({
2387
+ annotations: analysis.annotations,
2388
+ type: analysis.type.toSexpr()
2389
+ }));
2390
+ return TypeExpr.fromType(analysis.type);
2391
+ }
2392
+ });
2393
+ };
2394
+
2395
+ Solver.prototype.lexicalLookup = function(syntax, scope) {
2396
+ var lookupKey;
2397
+ lookupKey = scope.lexicalLookup(syntax.name);
2398
+ if (!lookupKey) {
2399
+ return this.error('lexical', name, scope);
2295
2400
  }
2296
- nextCrumbs = crumbs.concat([key]);
2297
- _ref10 = constraintMap.get(key), scope = _ref10.scope, constraints = _ref10.constraints;
2298
- frame = scope.frame;
2299
- DEBUG.log('locking', key);
2300
- locks.set(key, true);
2301
- semanticAccessors = new ObjHash;
2302
- dependencies = [];
2401
+ this.queryResults.set(syntax, Semantic.localAccessor(lookupKey));
2402
+ this.dependencies.push(TypeLookup.local(lookupKey));
2403
+ return this.state.solveKey(lookupKey);
2404
+ };
2405
+
2406
+ Solver.prototype.resolve = function(expr) {
2407
+ var _this = this;
2408
+ return expr.cases({
2409
+ error: function(type, args) {
2410
+ return _this.error.apply(_this, [type].concat(__slice.call(args)));
2411
+ },
2412
+ destructure: function(constraint, name, argnum) {
2413
+ return _this.resolve(constraint).cases({
2414
+ param: function(paramName, paramArgs) {
2415
+ if (paramName === name) {
2416
+ return paramArgs[argnum];
2417
+ } else {
2418
+ return _this.error('destructure', expr);
2419
+ }
2420
+ },
2421
+ other: function() {
2422
+ return _this.error('destructure', expr);
2423
+ }
2424
+ });
2425
+ },
2426
+ lexical: function(syntax, scope) {
2427
+ return _this.lexicalLookup(syntax, scope);
2428
+ },
2429
+ query: function(input, scope, query) {
2430
+ return _this.resolve(input).cases({
2431
+ "native": function(id) {
2432
+ return _this.lookup(scope, id, query);
2433
+ },
2434
+ other: function() {
2435
+ return expr;
2436
+ }
2437
+ });
2438
+ },
2439
+ other: function() {
2440
+ return expr.map(function(e) {
2441
+ return _this.resolve(e);
2442
+ });
2443
+ }
2444
+ });
2445
+ };
2446
+
2447
+ Solver.prototype.substitute = function(texpr) {
2448
+ var _this = this;
2449
+ return this.solutions.fetch(texpr, function() {
2450
+ return texpr.map(function(e) {
2451
+ return _this.substitute(e);
2452
+ });
2453
+ });
2454
+ };
2455
+
2456
+ Solver.prototype.fullSubstitute = function(texpr) {
2457
+ var resolved, substituted;
2458
+ substituted = this.substitute(texpr);
2459
+ resolved = this.resolve(substituted);
2303
2460
  DEBUG(function() {
2304
- var lhs, rhs, _i, _len, _ref11, _results;
2305
- _results = [];
2306
- for (_i = 0, _len = constraints.length; _i < _len; _i++) {
2307
- _ref11 = constraints[_i], lhs = _ref11[0], rhs = _ref11[1];
2308
- _results.push(DEBUG.logConstraint('-> ', lhs, rhs));
2461
+ if (!texpr.equals(resolved)) {
2462
+ return DEBUG.logConstraint('%> ', texpr, resolved);
2309
2463
  }
2310
- return _results;
2311
2464
  });
2312
- substitute = function(texpr, cb) {
2313
- if (solutions.has(texpr)) {
2314
- return cb(solutions.get(texpr));
2465
+ return resolved;
2466
+ };
2467
+
2468
+ Solver.prototype.addSolution = function(lhs, rhs) {
2469
+ var _this = this;
2470
+ DEBUG.logConstraint('>> ', lhs, rhs);
2471
+ this.solutions.set(lhs, rhs);
2472
+ return this.solutions.each(function(k, texpr) {
2473
+ return _this.solutions.set(k, _this.fullSubstitute(texpr));
2474
+ });
2475
+ };
2476
+
2477
+ Solver.prototype.processPair = function(lhs, rhs) {
2478
+ var log, matchError, push, solveFor, swap,
2479
+ _this = this;
2480
+ DEBUG.logConstraint(':> ', lhs, rhs);
2481
+ push = function(newLhs, newRhs) {
2482
+ return _this.constraints.push([newLhs, newRhs]);
2483
+ };
2484
+ solveFor = function() {
2485
+ rhs = _this.fullSubstitute(rhs);
2486
+ if (_this.solutions.has(lhs)) {
2487
+ return push(_this.solutions.get(lhs), rhs);
2315
2488
  } else {
2316
- return texpr.mapAsync(substitute, cb);
2489
+ return _this.addSolution(lhs, rhs);
2317
2490
  }
2318
2491
  };
2319
- fullSubstitute = function(texpr, cb) {
2320
- return substitute(texpr, function(substituted) {
2321
- return simplify(substituted, function(result) {
2322
- DEBUG(function() {
2323
- if (!texpr.equals(result)) {
2324
- return DEBUG.logConstraint('%> ', texpr, result);
2325
- }
2326
- });
2327
- return cb(result);
2328
- });
2329
- });
2492
+ log = function() {
2493
+ return DEBUG.logConstraint('?> ', lhs, rhs);
2330
2494
  };
2331
- error = function() {
2332
- var args, type;
2333
- type = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
2334
- errors.push(TypeError[type].apply(TypeError, args));
2335
- return TypeExpr.any();
2495
+ swap = function() {
2496
+ return push(rhs, lhs);
2336
2497
  };
2337
- simplify = function(expr, cb) {
2338
- return expr.cases({
2339
- error: function(type, args) {
2340
- return cb(error.apply(null, [type].concat(__slice.call(args))));
2341
- },
2342
- destructure: function(constraint, name, argnum) {
2343
- var destructured;
2344
- destructured = this;
2345
- return simplify(constraint, function(x) {
2346
- return cb(x.cases({
2347
- param: function(paramName, paramArgs) {
2348
- if (paramName === name) {
2349
- return paramArgs[argnum];
2350
- } else {
2351
- return error('destructure', this);
2352
- }
2353
- },
2354
- other: function() {
2355
- return error('destructure', this);
2356
- }
2357
- }));
2358
- });
2359
- },
2360
- lexical: function(syntax, scope) {
2361
- var lookupKey;
2362
- lookupKey = scope.lexicalLookup(syntax.name);
2363
- if (!lookupKey) {
2364
- return cb(error('lexical', name, scope));
2365
- }
2366
- semanticAccessors.set(syntax, Semantic.localAccessor(lookupKey));
2367
- dependencies.push(TypeLookup.local(lookupKey));
2368
- nextCrumbs = crumbs.concat([lookupKey]);
2369
- if (locks.get(lookupKey)) {
2370
- return cb(error('circular', nextCrumbs));
2371
- }
2372
- return new Thunk(function() {
2373
- return solveEntry(nextCrumbs, function() {
2374
- return new Thunk(function() {
2375
- return cb(frameTypes.get(lookupKey));
2376
- });
2377
- });
2378
- });
2379
- },
2380
- query: function(input, scope, query) {
2381
- return simplify(input, function(x) {
2382
- return x.cases({
2383
- "native": function(id) {
2384
- return scope.lookup(id, query, function(lookup) {
2385
- dependencies.push(lookup);
2386
- return lookup.cases({
2387
- error: function(e) {
2388
- return cb(error('lookup', query, id, e));
2389
- },
2390
- response: function(_, analysis) {
2391
- semanticAccessors.set(query, Semantic.query({
2392
- annotations: analysis.annotations,
2393
- type: analysis.type.toSexpr()
2394
- }));
2395
- return cb(TypeExpr.fromType(analysis.type));
2396
- }
2397
- });
2398
- });
2399
- },
2400
- other: function() {
2401
- return cb(expr);
2402
- }
2403
- });
2404
- });
2405
- },
2406
- other: function() {
2407
- return this.mapAsync(simplify, cb);
2408
- }
2409
- });
2498
+ matchError = function() {
2499
+ DEBUG.logConstraint('!> ', lhs, rhs);
2500
+ return _this.error('match', lhs, rhs);
2410
2501
  };
2411
- done = function() {
2412
- var flowType, toSemanticTree;
2413
- flowType = function(expr) {
2414
- if (!solutions.has(expr)) {
2415
- if (errors.length === 0 && expr._tag === 'expr') {
2416
- throw new Error('unsolved!');
2417
- }
2418
- return Type.abstract(TypeExpr.expr(expr));
2419
- }
2420
- return solutions.get(expr).realize();
2421
- };
2422
- toSemanticTree = function(expr) {
2423
- return expr.cases({
2424
- frame: function(_, __, flow) {
2425
- return Semantic.definition(dependencies, toSemanticTree(flow), scope.metadata);
2426
- },
2427
- flow: function(_, head, tail) {
2428
- return Semantic.flow(flowType(TypeExpr.expr(this)), toSemanticTree(head), tail && toSemanticTree(tail));
2429
- },
2430
- query: function(_, type, name) {
2431
- if (!(errors.length || semanticAccessors.has(this))) {
2432
- throw "unsolved with no errors!";
2502
+ if ('any' === rhs._tag || 'any' === lhs._tag) {
2503
+ return;
2504
+ }
2505
+ if (lhs.equals(rhs)) {
2506
+ return;
2507
+ }
2508
+ return lhs.cases({
2509
+ expr: solveFor,
2510
+ variable: solveFor,
2511
+ query: function() {
2512
+ return rhs.cases({
2513
+ expr: swap,
2514
+ variable: swap,
2515
+ param: swap,
2516
+ other: log
2517
+ });
2518
+ },
2519
+ "native": function(id) {
2520
+ return rhs.cases({
2521
+ variable: swap,
2522
+ expr: swap,
2523
+ "native": function(otherId) {
2524
+ if (id !== otherId) {
2525
+ return matchError();
2433
2526
  }
2434
- return semanticAccessors.get(this);
2435
- },
2436
- lexical: function(_, name) {
2437
- return semanticAccessors.get(this);
2438
- },
2439
- func: function(_, name, args) {
2440
- var a, semArgs, solvedScope, typeScope;
2441
- typeScope = this.__scope__;
2442
- solvedScope = new Hash;
2443
- typeScope && typeScope.each(function(name, texpr) {
2444
- return solvedScope.set(name, flowType(texpr));
2445
- });
2446
- semArgs = (function() {
2447
- var _i, _len, _results;
2448
- _results = [];
2449
- for (_i = 0, _len = args.length; _i < _len; _i++) {
2450
- a = args[_i];
2451
- _results.push(toSemanticTree(a));
2452
- }
2453
- return _results;
2454
- })();
2455
- return Semantic.func(name, semArgs, solvedScope);
2456
- },
2457
- pair: function(_, first, second) {
2458
- return Semantic.pair(toSemanticTree(first), toSemanticTree(second));
2459
- },
2460
- block: function(_, flow) {
2461
- return Semantic.block(toSemanticTree(flow));
2462
- },
2463
- subst: function(_, subFlow) {
2464
- return toSemanticTree(subFlow);
2465
- },
2466
- list: function(_, elements, squish) {
2467
- var e;
2468
- return Semantic.list((function() {
2469
- var _i, _len, _results;
2470
- _results = [];
2471
- for (_i = 0, _len = elements.length; _i < _len; _i++) {
2472
- e = elements[_i];
2473
- _results.push(toSemanticTree(e));
2474
- }
2475
- return _results;
2476
- })(), squish);
2477
2527
  },
2478
- defaulted: function(_, body, alt) {
2479
- return Semantic.defaulted(toSemanticTree(body), toSemanticTree(alt));
2480
- },
2481
- integer: function() {
2482
- return Semantic.literal(this);
2483
- },
2484
- decimal: function() {
2485
- return Semantic.literal(this);
2486
- },
2487
- percent: function() {
2488
- return Semantic.literal(this);
2528
+ query: swap,
2529
+ other: matchError
2530
+ });
2531
+ },
2532
+ param: function() {
2533
+ return rhs.cases({
2534
+ param: function() {
2535
+ var constraint, i, _i, _len, _ref10, _results;
2536
+ if (lhs.name !== rhs.name) {
2537
+ return matchError();
2538
+ }
2539
+ _ref10 = lhs.constraints;
2540
+ _results = [];
2541
+ for (i = _i = 0, _len = _ref10.length; _i < _len; i = ++_i) {
2542
+ constraint = _ref10[i];
2543
+ _results.push(push(constraint, rhs.constraints[i]));
2544
+ }
2545
+ return _results;
2489
2546
  },
2490
- fraction: function() {
2491
- return Semantic.literal(this);
2547
+ query: function() {
2548
+ var c, i, _i, _len, _ref10, _results;
2549
+ _ref10 = lhs.constraints;
2550
+ _results = [];
2551
+ for (i = _i = 0, _len = _ref10.length; _i < _len; i = ++_i) {
2552
+ c = _ref10[i];
2553
+ _results.push(push(c, TypeExpr.destructure(rhs, lhs.type, i)));
2554
+ }
2555
+ return _results;
2492
2556
  },
2493
- string: function() {
2494
- return Semantic.literal(this);
2495
- }
2557
+ expr: swap,
2558
+ variable: swap,
2559
+ other: matchError
2496
2560
  });
2497
- };
2561
+ },
2562
+ other: log
2563
+ });
2564
+ };
2565
+
2566
+ Solver.prototype.registeredType = function() {
2567
+ if (!this.state.semantics.has(this.key)) {
2568
+ return null;
2569
+ }
2570
+ return TypeExpr.fromType(this.state.semantics.get(this.key).flow.type);
2571
+ };
2572
+
2573
+ Solver.prototype.register = function() {
2574
+ DEBUG.log('registering solution: ', this.key);
2575
+ return this.state.semantics.set(this.key, this.makeSemantic(this.frame));
2576
+ };
2577
+
2578
+ Solver.prototype.setLock = function() {
2579
+ DEBUG.log('locking key', this.key);
2580
+ return this.state.locks.set(this.key, true);
2581
+ };
2582
+
2583
+ Solver.prototype.clearLock = function() {
2584
+ DEBUG.log('unlocking key', this.key);
2585
+ return this.state.locks.set(this.key, false);
2586
+ };
2587
+
2588
+ Solver.prototype.isLocked = function() {
2589
+ return this.state.locks.get(this.key);
2590
+ };
2591
+
2592
+ Solver.prototype.withLock = function(fn) {
2593
+ var result;
2594
+ this.state.crumbs.push(this.key);
2595
+ if (this.isLocked()) {
2596
+ result = this.error('circular', this.state.crumbs.slice());
2597
+ } else {
2598
+ this.setLock();
2599
+ result = fn(this);
2600
+ this.clearLock();
2601
+ }
2602
+ this.state.crumbs.pop();
2603
+ return result;
2604
+ };
2605
+
2606
+ Solver.prototype.solve = function() {
2607
+ var _this = this;
2608
+ return this.withLock(function() {
2609
+ var lhs, rhs, _ref10;
2498
2610
  DEBUG(function() {
2499
- return solutions.each(function(k, v) {
2500
- return DEBUG.logConstraint('=> ', k, v);
2501
- });
2611
+ var lhs, rhs, _i, _len, _ref10, _ref11, _results;
2612
+ _ref10 = _this.constraints;
2613
+ _results = [];
2614
+ for (_i = 0, _len = _ref10.length; _i < _len; _i++) {
2615
+ _ref11 = _ref10[_i], lhs = _ref11[0], rhs = _ref11[1];
2616
+ _results.push(DEBUG.logConstraint('-> ', lhs, rhs));
2617
+ }
2618
+ return _results;
2502
2619
  });
2503
- DEBUG.log('setting key: ' + key);
2504
- if (!errors.length) {
2505
- semantics.set(key, toSemanticTree(frame));
2506
- }
2507
- frameTypes.set(key, solutions.get(TypeExpr.expr(frame.flow)));
2508
- DEBUG.log('unlocking', key);
2509
- locks.set(key, false);
2510
- return solved();
2511
- };
2512
- return consume(constraints.reverse(), done, function(lhs, rhs, push, next) {
2513
- var log, matchError, skip, solveFor, swap;
2514
- DEBUG.logConstraint(':> ', lhs, rhs);
2515
- if (lhs.equals(rhs)) {
2516
- return next();
2620
+ while (_this.constraints.length > 0) {
2621
+ _ref10 = _this.constraints.pop(), lhs = _ref10[0], rhs = _ref10[1];
2622
+ _this.processPair(lhs, rhs);
2517
2623
  }
2518
- solveFor = function() {
2519
- return fullSubstitute(rhs, function(rhs) {
2520
- var mapper;
2521
- if (solutions.has(lhs)) {
2522
- push(solutions.get(lhs), rhs);
2523
- return next();
2524
- } else {
2525
- DEBUG.logConstraint('>> ', lhs, rhs);
2526
- solutions.set(lhs, rhs);
2527
- mapper = function(k, texpr, cb) {
2528
- return fullSubstitute(texpr, (function(s) {
2529
- solutions.set(k, s);
2530
- return cb();
2531
- }));
2532
- };
2533
- return solutions.eachAsync(mapper, next);
2534
- }
2624
+ DEBUG(function() {
2625
+ return _this.solutions.each(function(k, v) {
2626
+ return DEBUG.logConstraint('=> ', k, v);
2535
2627
  });
2536
- };
2537
- log = function() {
2538
- DEBUG.logConstraint('?> ', lhs, rhs);
2539
- return next();
2540
- };
2541
- skip = function() {
2542
- return next();
2543
- };
2544
- swap = function() {
2545
- push(rhs, lhs);
2546
- return next();
2547
- };
2548
- matchError = function() {
2549
- DEBUG.logConstraint('!> ', lhs, rhs);
2550
- error('match', lhs, rhs);
2551
- return next();
2552
- };
2553
- if ('any' === rhs._tag || 'any' === lhs._tag) {
2554
- return next();
2628
+ });
2629
+ if (!_this.hasErrors()) {
2630
+ _this.register();
2555
2631
  }
2556
- return lhs.cases({
2557
- expr: solveFor,
2558
- variable: solveFor,
2559
- query: function() {
2560
- return rhs.cases({
2561
- expr: swap,
2562
- variable: swap,
2563
- param: swap,
2564
- other: log
2565
- });
2566
- },
2567
- "native": function(id) {
2568
- return rhs.cases({
2569
- variable: swap,
2570
- expr: swap,
2571
- "native": function(otherId) {
2572
- if (id === otherId) {
2573
- return skip();
2574
- } else {
2575
- return matchError();
2576
- }
2577
- },
2578
- other: matchError
2579
- });
2580
- },
2581
- param: function() {
2582
- return rhs.cases({
2583
- param: function() {
2584
- var constraint, i, _i, _len, _ref11;
2585
- if (lhs.name !== rhs.name) {
2586
- return matchError();
2587
- }
2588
- _ref11 = lhs.constraints;
2589
- for (i = _i = 0, _len = _ref11.length; _i < _len; i = ++_i) {
2590
- constraint = _ref11[i];
2591
- push(constraint, rhs.constraints[i]);
2592
- }
2593
- return next();
2594
- },
2595
- query: function() {
2596
- var c, i, _i, _len, _ref11;
2597
- _ref11 = lhs.constraints;
2598
- for (i = _i = 0, _len = _ref11.length; _i < _len; i = ++_i) {
2599
- c = _ref11[i];
2600
- push(c, TypeExpr.destructure(rhs, lhs.type, i));
2601
- }
2602
- return next();
2603
- },
2604
- expr: swap,
2605
- variable: swap,
2606
- other: matchError
2607
- });
2608
- },
2609
- other: log
2632
+ return _this.solutions.fetch(TypeExpr.expr(_this.frame.flow), function() {
2633
+ return TypeExpr.any();
2610
2634
  });
2611
2635
  });
2612
2636
  };
2613
- initialCrumbs = (function() {
2614
- var _i, _len, _ref10, _results;
2615
- _ref10 = constraintMap.keys();
2616
- _results = [];
2617
- for (_i = 0, _len = _ref10.length; _i < _len; _i++) {
2618
- k = _ref10[_i];
2619
- _results.push([k]);
2620
- }
2621
- return _results;
2622
- })();
2623
- DEBUG.log('initial crumbs', initialCrumbs);
2624
- return contMap(initialCrumbs, solveEntry, function() {
2625
- if (errors.length === 0) {
2626
- return finish(null, semantics);
2627
- } else {
2628
- return finish(errors);
2629
- }
2630
- });
2637
+
2638
+ return Solver;
2639
+
2640
+ })();
2641
+ return function(constraintMap) {
2642
+ return new SolveState(constraintMap).solveAll();
2631
2643
  };
2632
2644
  })();
2633
- return function(program, globalID, external, cb) {
2645
+ return function(program, globalID, external) {
2634
2646
  var constraints;
2635
2647
  DEBUG.log();
2636
2648
  DEBUG.log(program.inspect());
2637
2649
  constraints = generate(globalID, external.analyzeQuery, program);
2638
- return solve(constraints, cb);
2650
+ return solve(constraints);
2639
2651
  };
2640
2652
  })();
2641
2653
 
@@ -3297,8 +3309,8 @@ Gibbon.Core = Core = (function(_super) {
3297
3309
 
3298
3310
  })(Variant);
3299
3311
 
3300
- Gibbon.translate = (function() {
3301
- var translate;
3312
+ Gibbon.translate = function(semantics) {
3313
+ var translate, translated;
3302
3314
  translate = function(semantic, input, context) {
3303
3315
  if (input == null) {
3304
3316
  input = Core.global();
@@ -3321,7 +3333,15 @@ Gibbon.translate = (function() {
3321
3333
  return input.query(annotations);
3322
3334
  },
3323
3335
  localAccessor: function(key) {
3324
- return Core.localQuery(key);
3336
+ var definition;
3337
+ definition = semantics.get(key) || (function() {
3338
+ throw "panic: invalid reference";
3339
+ })();
3340
+ if (definition.metadata.has('export')) {
3341
+ return translate(definition, Core.global());
3342
+ } else {
3343
+ return Core.localQuery(key);
3344
+ }
3325
3345
  },
3326
3346
  func: function(name, args, tvars) {
3327
3347
  var arg, compArgs;
@@ -3369,10 +3389,12 @@ Gibbon.translate = (function() {
3369
3389
  }
3370
3390
  });
3371
3391
  };
3372
- return function(semantic) {
3373
- return translate(semantic);
3374
- };
3375
- })();
3392
+ translated = new Hash;
3393
+ semantics.each(function(key, semantic) {
3394
+ return translated.set(key, translate(semantic));
3395
+ });
3396
+ return translated;
3397
+ };
3376
3398
 
3377
3399
  Gibbon.optimize = (function() {
3378
3400
  var insertBindings, partialEval, uncachedPartialEval;
@@ -3412,15 +3434,21 @@ Gibbon.optimize = (function() {
3412
3434
  });
3413
3435
  },
3414
3436
  branch: function(cond, ifTrue, ifFalse) {
3415
- var abort;
3437
+ var abort,
3438
+ _this = this;
3416
3439
  cond = recurse(cond);
3417
3440
  abort = function() {
3441
+ var _ref10;
3418
3442
  ifTrue = recurse(ifTrue);
3419
3443
  ifFalse = recurse(ifFalse);
3420
3444
  if (ifTrue.equals(ifFalse)) {
3421
- DEBUG.log("> eliminating condition in equivalent branches: " + (this.inspect()));
3445
+ DEBUG.log("> eliminating condition in equivalent branches: " + (_this.inspect()));
3422
3446
  return ifTrue;
3423
3447
  }
3448
+ if (ifTrue._tag === 'constant' && ifFalse._tag === 'constant' && ((_ref10 = ifTrue.value) === true || _ref10 === false)) {
3449
+ DEBUG.log("> eliminating conditional with constant branches: " + (_this.inspect()));
3450
+ return (ifTrue.value ? cond : recurse(cond.op1('!')));
3451
+ }
3424
3452
  return cond.branch(ifTrue, ifFalse);
3425
3453
  };
3426
3454
  return cond.cases({
@@ -6066,6 +6094,18 @@ stdlib = Gibbon.stdlib = (function() {
6066
6094
  obj = _arg[0];
6067
6095
  return equals(input, obj, tvars.get('a')).op1('!');
6068
6096
  }
6097
+ },
6098
+ t: {
6099
+ type: parse.type('t = % -> bool'),
6100
+ compile: function() {
6101
+ return TRUE;
6102
+ }
6103
+ },
6104
+ f: {
6105
+ type: parse.type('f = % -> bool'),
6106
+ compile: function() {
6107
+ return FALSE;
6108
+ }
6069
6109
  }
6070
6110
  };
6071
6111
  })();
@@ -6497,9 +6537,6 @@ Gibbon.CompiledCode = CompiledCode = (function() {
6497
6537
 
6498
6538
  CompiledCode.prototype.outputType = function(key) {
6499
6539
  var e, type;
6500
- if (key == null) {
6501
- key = '/';
6502
- }
6503
6540
  try {
6504
6541
  type = this.semantics.get(key).flow.type;
6505
6542
  if (type == null) {
@@ -6520,11 +6557,12 @@ Gibbon.CompiledCode = CompiledCode = (function() {
6520
6557
  })();
6521
6558
 
6522
6559
  Gibbon.compile = function(semantics) {
6523
- var codegen, compiled, optimize, reduce, sequence, translate;
6560
+ var codegen, compiled, optimize, reduce, sequence, translate, translated;
6524
6561
  codegen = Gibbon.codegen, reduce = Gibbon.reduce, sequence = Gibbon.sequence, optimize = Gibbon.optimize, translate = Gibbon.translate;
6525
6562
  compiled = new Hash;
6526
- semantics.each(function(k, v) {
6527
- return compiled.set(k, codegen(reduce(sequence(optimize(translate(v))))).block.toJS());
6563
+ translated = translate(semantics);
6564
+ translated.each(function(k, v) {
6565
+ return compiled.set(k, codegen(reduce(sequence(optimize(v)))).block.toJS());
6528
6566
  });
6529
6567
  return new CompiledCode(semantics, compiled);
6530
6568
  };
@@ -6956,11 +6994,12 @@ Gibbon.compileRuby = (function() {
6956
6994
  });
6957
6995
  };
6958
6996
  return function(semantics) {
6959
- var key, keys, optimize, out, processKey, seen, translate, _i, _len;
6997
+ var key, keys, optimize, out, processKey, seen, translate, translated, _i, _len;
6960
6998
  optimize = Gibbon.optimize, translate = Gibbon.translate;
6961
6999
  keys = semantics.keys();
6962
7000
  seen = new Hash;
6963
7001
  out = [];
7002
+ translated = translate(semantics);
6964
7003
  processKey = function(key) {
6965
7004
  var compiledRuby, dep, _i, _len, _ref20;
6966
7005
  if (seen.has(key)) {
@@ -6974,7 +7013,7 @@ Gibbon.compileRuby = (function() {
6974
7013
  processKey(dep.name);
6975
7014
  }
6976
7015
  }
6977
- compiledRuby = compileCore(optimize(translate(semantics.get(key))), null, key).toRuby();
7016
+ compiledRuby = compileCore(optimize(translated.get(key)), null, key).toRuby();
6978
7017
  return out.push("" + (idForLocal(key)) + " = begin\n {:status=>:success,:value=>(" + compiledRuby + ")}\nrescue E => e\n {:status=>:failure,:error=>e}\nend");
6979
7018
  };
6980
7019
  for (_i = 0, _len = keys.length; _i < _len; _i++) {
@@ -6992,6 +7031,7 @@ Gibbon.compileRuby = (function() {
6992
7031
  return _results;
6993
7032
  })()).join(','));
6994
7033
  out.push('}');
7034
+ DEBUG.log("compiled ruby!\n" + (out.join("\n")));
6995
7035
  return out.join("\n");
6996
7036
  };
6997
7037
  })();
@@ -7002,19 +7042,28 @@ Gibbon.jsonConsumer = (function() {
7002
7042
  getType = function(id, accessorName, t, callback) {
7003
7043
  var fields;
7004
7044
  if (!tables.hasOwnProperty(id)) {
7005
- return callback(new Error("no such type " + id));
7045
+ return {
7046
+ success: false,
7047
+ error: new Error("no such type " + id)
7048
+ };
7006
7049
  }
7007
7050
  fields = tables[id].fields;
7008
7051
  if (!fields.hasOwnProperty(accessorName)) {
7009
- return callback(new Error("" + id + " has no field " + accessorName));
7052
+ return {
7053
+ success: false,
7054
+ error: new Error("" + id + " has no field " + accessorName)
7055
+ };
7010
7056
  }
7011
- return callback(null, {
7012
- type: fields[accessorName],
7013
- annotations: {
7014
- name: accessorName,
7015
- table: id
7057
+ return {
7058
+ success: true,
7059
+ analysis: {
7060
+ type: fields[accessorName],
7061
+ annotations: {
7062
+ name: accessorName,
7063
+ table: id
7064
+ }
7016
7065
  }
7017
- });
7066
+ };
7018
7067
  };
7019
7068
  getValue = function(id, annotations, callback) {
7020
7069
  var entity, values;
@@ -7035,18 +7084,27 @@ Gibbon.jsonConsumer = (function() {
7035
7084
  analyzeList = function(id, listName, t, callback) {
7036
7085
  var list;
7037
7086
  if (!lists.hasOwnProperty(listName)) {
7038
- callback(new Error("unkown list `" + listName + "'"));
7087
+ ({
7088
+ success: false,
7089
+ error: new Error("unkown list `" + listName + "'")
7090
+ });
7039
7091
  }
7040
7092
  list = lists[listName];
7041
7093
  if (id !== list.type) {
7042
- callback(new Error("wrong type " + id + " for list `" + listName + "'"));
7094
+ ({
7095
+ success: false,
7096
+ error: new Error("wrong type " + id + " for list `" + listName + "'")
7097
+ });
7043
7098
  }
7044
- return callback(null, {
7045
- type: t.bool(),
7046
- annotations: {
7047
- list: listName
7099
+ return {
7100
+ success: true,
7101
+ analysis: {
7102
+ type: t.bool(),
7103
+ annotations: {
7104
+ list: listName
7105
+ }
7048
7106
  }
7049
- });
7107
+ };
7050
7108
  };
7051
7109
  listLookup = function(id, listName, callback) {
7052
7110
  var list;
@@ -7061,11 +7119,14 @@ Gibbon.jsonConsumer = (function() {
7061
7119
  analyzeQuery: function(id, query, t, callback) {
7062
7120
  switch (query.type) {
7063
7121
  case 'access':
7064
- return getType(id, query.args[0], t, callback);
7122
+ return getType(id, query.args[0], t);
7065
7123
  case 'on':
7066
- return analyzeList(id, query.args[0], t, callback);
7124
+ return analyzeList(id, query.args[0], t);
7067
7125
  default:
7068
- return callback(new Error("unknown query `" + query.type + "'"));
7126
+ return {
7127
+ success: false,
7128
+ error: new Error("unknown query `" + query.type + "'")
7129
+ };
7069
7130
  }
7070
7131
  },
7071
7132
  performQuery: function(id, annotations, callback) {