goodguide-gibbon 0.2.1 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/goodguide-gibbon.gemspec +2 -1
- data/lib/goodguide/gibbon.rb +95 -43
- data/lib/goodguide/gibbon/version.rb +1 -1
- data/vendor/gibbon/lib/gibbon.browser.dev.js +2906 -0
- data/vendor/gibbon/lib/gibbon.browser.js +206 -199
- data/vendor/gibbon/package.json +2 -1
- metadata +3 -2
data/goodguide-gibbon.gemspec
CHANGED
@@ -17,7 +17,8 @@ Gem::Specification.new do |s|
|
|
17
17
|
'goodguide-gibbon.gemspec',
|
18
18
|
'lib/**/*.rb',
|
19
19
|
'vendor/gibbon/package.json',
|
20
|
-
'vendor/gibbon/lib/gibbon.browser.js'
|
20
|
+
'vendor/gibbon/lib/gibbon.browser.js',
|
21
|
+
'vendor/gibbon/lib/gibbon.browser.dev.js',
|
21
22
|
]
|
22
23
|
|
23
24
|
s.add_dependency 'therubyracer'
|
data/lib/goodguide/gibbon.rb
CHANGED
@@ -12,6 +12,10 @@ module GoodGuide
|
|
12
12
|
root.join('vendor/gibbon/lib/gibbon.browser.js')
|
13
13
|
end
|
14
14
|
|
15
|
+
def self.dev_js_lib
|
16
|
+
root.join('vendor/gibbon/lib/gibbon.browser.dev.js')
|
17
|
+
end
|
18
|
+
|
15
19
|
def self.js_source
|
16
20
|
@js_source ||= File.read(js_lib)
|
17
21
|
end
|
@@ -25,37 +29,44 @@ module GoodGuide
|
|
25
29
|
class RuntimeError < StandardError; end
|
26
30
|
|
27
31
|
class Program
|
28
|
-
def self.
|
32
|
+
def self.compile(source, info={})
|
33
|
+
client = info[:client] || raise('please pass a static client')
|
34
|
+
global = info[:global] || raise('please pass a global table id')
|
35
|
+
|
36
|
+
context = info[:context] || Context.new
|
37
|
+
|
29
38
|
syntax = context.parse(source)
|
30
|
-
semantics, errors = context.analyze(syntax, global)
|
39
|
+
semantics, errors = context.analyze(syntax, global, client.to_js)
|
40
|
+
|
31
41
|
raise SemanticError.new(errors) if errors
|
32
42
|
|
33
|
-
Program.new(
|
34
|
-
:global => global,
|
43
|
+
Program.new(
|
35
44
|
:syntax => syntax,
|
36
45
|
:semantics => semantics,
|
46
|
+
:context => context,
|
37
47
|
)
|
38
48
|
end
|
39
49
|
|
40
50
|
attr_reader :syntax, :semantics
|
41
|
-
def initialize(
|
42
|
-
@context = context
|
43
|
-
@global = info[:global]
|
51
|
+
def initialize(info={})
|
44
52
|
@syntax = info[:syntax]
|
45
53
|
@semantics = info[:semantics]
|
54
|
+
@context = info[:context] || Context.new
|
46
55
|
end
|
47
56
|
|
48
57
|
def as_json
|
49
58
|
{
|
50
|
-
global: @global,
|
51
59
|
syntax: @syntax,
|
52
60
|
semantics: @semantics,
|
53
61
|
}
|
54
62
|
end
|
55
63
|
|
56
|
-
def call(entity_id)
|
57
|
-
|
58
|
-
|
64
|
+
def call(runtime_client, entity_id)
|
65
|
+
# TODO
|
66
|
+
context = Context.new
|
67
|
+
|
68
|
+
values, error = context.eval_gibbon(
|
69
|
+
self.semantics, entity_id, runtime_client.to_js
|
59
70
|
)
|
60
71
|
|
61
72
|
raise RuntimeError.new(error) if error
|
@@ -63,21 +74,24 @@ module GoodGuide
|
|
63
74
|
end
|
64
75
|
end
|
65
76
|
|
66
|
-
class
|
67
|
-
def self.
|
68
|
-
|
77
|
+
class AbstractClient
|
78
|
+
def self.queries
|
79
|
+
@queries ||= {}
|
69
80
|
end
|
70
81
|
|
71
|
-
def
|
72
|
-
|
82
|
+
def self.query(name, &impl)
|
83
|
+
queries[name.to_s] = impl
|
73
84
|
end
|
74
85
|
|
75
|
-
def
|
86
|
+
def to_js
|
76
87
|
raise 'abstract'
|
77
88
|
end
|
78
89
|
|
79
|
-
|
80
|
-
|
90
|
+
private
|
91
|
+
def get_query(type)
|
92
|
+
query = self.class.queries[type]
|
93
|
+
raise "no such query #{type}" if query.nil?
|
94
|
+
query
|
81
95
|
end
|
82
96
|
|
83
97
|
def proc_for(method)
|
@@ -85,57 +99,65 @@ module GoodGuide
|
|
85
99
|
cb = args.pop
|
86
100
|
err, val = begin
|
87
101
|
[nil, send(method, *args)]
|
88
|
-
rescue => e
|
89
|
-
|
102
|
+
# rescue => e
|
103
|
+
# [e.to_s, nil]
|
90
104
|
end
|
91
105
|
|
92
106
|
cb.call(err, val)
|
93
107
|
end
|
94
108
|
end
|
109
|
+
end
|
110
|
+
|
111
|
+
class StaticClient < AbstractClient
|
112
|
+
def analyze_query(input_id, query, t)
|
113
|
+
query_impl = get_query(query.type)
|
114
|
+
analysis = instance_exec(input_id, query.name, t, &query_impl)
|
115
|
+
analysis[:annotations][:_query_type] = query.type
|
116
|
+
analysis
|
117
|
+
end
|
95
118
|
|
96
119
|
def to_js
|
97
|
-
{
|
98
|
-
getType: proc_for(:lookup_type),
|
99
|
-
getValue: proc_for(:lookup_value),
|
100
|
-
}
|
120
|
+
{ :analyzeQuery => proc_for(:analyze_query) }
|
101
121
|
end
|
102
122
|
end
|
103
123
|
|
104
|
-
class
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
end
|
124
|
+
class RuntimeClient < AbstractClient
|
125
|
+
def perform_query(id, annotations)
|
126
|
+
query = get_query(annotations[:_query_type])
|
127
|
+
instance_exec(id, annotations, &query)
|
109
128
|
end
|
110
129
|
|
111
|
-
|
112
|
-
|
113
|
-
super()
|
114
|
-
@client = client.to_js
|
115
|
-
self[:console] = Console.new
|
116
|
-
load GoodGuide::Gibbon.js_lib
|
130
|
+
def to_js
|
131
|
+
{ :performQuery => proc_for(:perform_query) }
|
117
132
|
end
|
133
|
+
end
|
118
134
|
|
119
|
-
|
120
|
-
|
135
|
+
class Context
|
136
|
+
attr_reader :gibbon
|
137
|
+
def initialize(js={})
|
138
|
+
if js.is_a? Hash
|
139
|
+
js = JS.new(js)
|
140
|
+
end
|
141
|
+
|
142
|
+
@gibbon = js.gibbon
|
121
143
|
end
|
122
144
|
|
123
145
|
def parse(str)
|
124
|
-
obj_to_ruby gibbon.parse(str).asJSON
|
146
|
+
obj_to_ruby self.gibbon.parse(str).asJSON
|
125
147
|
end
|
126
148
|
|
127
|
-
def analyze(syntax, global_table)
|
149
|
+
def analyze(syntax, global_table, static_client)
|
128
150
|
semantics, error = capture do |&callback|
|
129
|
-
gibbon.analyze(syntax, global_table,
|
151
|
+
gibbon.analyze(syntax, global_table, static_client, callback)
|
130
152
|
end
|
131
153
|
|
132
154
|
[hash_to_ruby(semantics), obj_to_ruby(error)]
|
133
155
|
end
|
134
156
|
|
135
|
-
def eval_gibbon(semantics,
|
157
|
+
def eval_gibbon(semantics, id, runtime_client)
|
136
158
|
semantics = hash_to_js(semantics)
|
137
159
|
values, error = capture do |&callback|
|
138
|
-
gibbon.eval(semantics,
|
160
|
+
gibbon.eval(semantics, 0, id, runtime_client, callback)
|
139
161
|
end
|
140
162
|
|
141
163
|
[hash_to_ruby(values), obj_to_ruby(error)]
|
@@ -190,5 +212,35 @@ module GoodGuide
|
|
190
212
|
end
|
191
213
|
end
|
192
214
|
end
|
215
|
+
|
216
|
+
class JS < V8::Context
|
217
|
+
def self.default
|
218
|
+
@default ||= new
|
219
|
+
end
|
220
|
+
|
221
|
+
class Console
|
222
|
+
def log
|
223
|
+
@log ||= proc { |_, *a| puts a.map(&:to_s).join(' ') }
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
attr_reader :client
|
228
|
+
def initialize(opts={})
|
229
|
+
super()
|
230
|
+
@debug = opts[:debug]
|
231
|
+
|
232
|
+
self[:console] = Console.new
|
233
|
+
|
234
|
+
if @debug
|
235
|
+
load GoodGuide::Gibbon.dev_js_lib
|
236
|
+
else
|
237
|
+
load GoodGuide::Gibbon.js_lib
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
def gibbon
|
242
|
+
self[:Gibbon]
|
243
|
+
end
|
244
|
+
end
|
193
245
|
end
|
194
246
|
end
|
@@ -0,0 +1,2906 @@
|
|
1
|
+
var Gibbon = (function(undefined) {
|
2
|
+
var Parsimmon = (function(undefined) {
|
3
|
+
var P = (function(prototype, ownProperty, undefined) {
|
4
|
+
// helper functions that also help minification
|
5
|
+
function isObject(o) { return typeof o === 'object'; }
|
6
|
+
function isFunction(f) { return typeof f === 'function'; }
|
7
|
+
|
8
|
+
// used to extend the prototypes of superclasses (which might not
|
9
|
+
// have `.Bare`s)
|
10
|
+
function SuperclassBare() {}
|
11
|
+
|
12
|
+
function P(_superclass /* = Object */, definition) {
|
13
|
+
// handle the case where no superclass is given
|
14
|
+
if (definition === undefined) {
|
15
|
+
definition = _superclass;
|
16
|
+
_superclass = Object;
|
17
|
+
}
|
18
|
+
|
19
|
+
// C is the class to be returned.
|
20
|
+
//
|
21
|
+
// It delegates to instantiating an instance of `Bare`, so that it
|
22
|
+
// will always return a new instance regardless of the calling
|
23
|
+
// context.
|
24
|
+
//
|
25
|
+
// TODO: the Chrome inspector shows all created objects as `C`
|
26
|
+
// rather than `Object`. Setting the .name property seems to
|
27
|
+
// have no effect. Is there a way to override this behavior?
|
28
|
+
function C() {
|
29
|
+
var self = new Bare;
|
30
|
+
if (isFunction(self.init)) self.init.apply(self, arguments);
|
31
|
+
return self;
|
32
|
+
}
|
33
|
+
|
34
|
+
// C.Bare is a class with a noop constructor. Its prototype is the
|
35
|
+
// same as C, so that instances of C.Bare are also instances of C.
|
36
|
+
// New objects can be allocated without initialization by calling
|
37
|
+
// `new MyClass.Bare`.
|
38
|
+
function Bare() {}
|
39
|
+
C.Bare = Bare;
|
40
|
+
|
41
|
+
// Set up the prototype of the new class.
|
42
|
+
var _super = SuperclassBare[prototype] = _superclass[prototype];
|
43
|
+
var proto = Bare[prototype] = C[prototype] = new SuperclassBare;
|
44
|
+
|
45
|
+
// other variables, as a minifier optimization
|
46
|
+
var extensions;
|
47
|
+
|
48
|
+
|
49
|
+
// set the constructor property on the prototype, for convenience
|
50
|
+
proto.constructor = C;
|
51
|
+
|
52
|
+
C.mixin = function(def) {
|
53
|
+
Bare[prototype] = C[prototype] = P(C, def)[prototype];
|
54
|
+
return C;
|
55
|
+
}
|
56
|
+
|
57
|
+
return (C.open = function(def) {
|
58
|
+
extensions = {};
|
59
|
+
|
60
|
+
if (isFunction(def)) {
|
61
|
+
// call the defining function with all the arguments you need
|
62
|
+
// extensions captures the return value.
|
63
|
+
extensions = def.call(C, proto, _super, C, _superclass);
|
64
|
+
}
|
65
|
+
else if (isObject(def)) {
|
66
|
+
// if you passed an object instead, we'll take it
|
67
|
+
extensions = def;
|
68
|
+
}
|
69
|
+
|
70
|
+
// ...and extend it
|
71
|
+
if (isObject(extensions)) {
|
72
|
+
for (var ext in extensions) {
|
73
|
+
if (ownProperty.call(extensions, ext)) {
|
74
|
+
proto[ext] = extensions[ext];
|
75
|
+
}
|
76
|
+
}
|
77
|
+
}
|
78
|
+
|
79
|
+
// if there's no init, we assume we're inheriting a non-pjs class, so
|
80
|
+
// we default to applying the superclass's constructor.
|
81
|
+
if (!isFunction(proto.init)) {
|
82
|
+
proto.init = _superclass;
|
83
|
+
}
|
84
|
+
|
85
|
+
return C;
|
86
|
+
})(definition);
|
87
|
+
}
|
88
|
+
|
89
|
+
// ship it
|
90
|
+
return P;
|
91
|
+
|
92
|
+
// as a minifier optimization, we've closured in a few helper functions
|
93
|
+
// and the string 'prototype' (C[p] is much shorter than C.prototype)
|
94
|
+
})('prototype', ({}).hasOwnProperty);
|
95
|
+
var Parsimmon = {};
|
96
|
+
|
97
|
+
Parsimmon.Parser = P(function(_, _super, Parser) {
|
98
|
+
"use strict";
|
99
|
+
// The Parser object is a wrapper for a parser function.
|
100
|
+
// Externally, you use one to parse a string by calling
|
101
|
+
// var result = SomeParser.parse('Me Me Me! Parse Me!');
|
102
|
+
// You should never call the constructor, rather you should
|
103
|
+
// construct your Parser from the base parsers and the
|
104
|
+
// parser combinator methods.
|
105
|
+
|
106
|
+
function parseError(stream, i, expected) {
|
107
|
+
if (i === stream.length) {
|
108
|
+
var message = 'expected ' + expected + ', got the end of the string';
|
109
|
+
}
|
110
|
+
else {
|
111
|
+
var prefix = (i > 0 ? "'..." : "'");
|
112
|
+
var suffix = (stream.length - i > 12 ? "...'" : "'");
|
113
|
+
var message = 'expected ' + expected + ' at character ' + i + ', got '
|
114
|
+
+ prefix + stream.slice(i, i+12) + suffix;
|
115
|
+
}
|
116
|
+
throw 'Parse Error: ' + message + "\n parsing: '" + stream + "'";
|
117
|
+
}
|
118
|
+
|
119
|
+
_.init = function(body) { this._ = body; };
|
120
|
+
|
121
|
+
_.parse = function(stream) {
|
122
|
+
return this.skip(eof)._(stream, 0, success, parseError);
|
123
|
+
|
124
|
+
function success(stream, i, result) { return result; }
|
125
|
+
};
|
126
|
+
|
127
|
+
// -*- primitive combinators -*- //
|
128
|
+
_.or = function(alternative) {
|
129
|
+
var self = this;
|
130
|
+
|
131
|
+
return Parser(function(stream, i, onSuccess, onFailure) {
|
132
|
+
return self._(stream, i, onSuccess, failure);
|
133
|
+
|
134
|
+
function failure(stream, newI) {
|
135
|
+
return alternative._(stream, i, onSuccess, onFailure);
|
136
|
+
}
|
137
|
+
});
|
138
|
+
};
|
139
|
+
|
140
|
+
_.then = function(next) {
|
141
|
+
var self = this;
|
142
|
+
|
143
|
+
return Parser(function(stream, i, onSuccess, onFailure) {
|
144
|
+
return self._(stream, i, success, onFailure);
|
145
|
+
|
146
|
+
function success(stream, newI, result) {
|
147
|
+
var nextParser = (next instanceof Parser ? next : next(result));
|
148
|
+
return nextParser._(stream, newI, onSuccess, onFailure);
|
149
|
+
}
|
150
|
+
});
|
151
|
+
};
|
152
|
+
|
153
|
+
// -*- optimized iterative combinators -*- //
|
154
|
+
// equivalent to:
|
155
|
+
// _.many = function() {
|
156
|
+
// return this.times(0, Infinity);
|
157
|
+
// };
|
158
|
+
// or, more explicitly:
|
159
|
+
// _.many = function() {
|
160
|
+
// var self = this;
|
161
|
+
// return self.then(function(x) {
|
162
|
+
// return self.many().then(function(xs) {
|
163
|
+
// return [x].concat(xs);
|
164
|
+
// });
|
165
|
+
// }).or(succeed([]));
|
166
|
+
// };
|
167
|
+
_.many = function() {
|
168
|
+
var self = this;
|
169
|
+
|
170
|
+
return Parser(function(stream, i, onSuccess, onFailure) {
|
171
|
+
var xs = [];
|
172
|
+
while (self._(stream, i, success, failure));
|
173
|
+
return onSuccess(stream, i, xs);
|
174
|
+
|
175
|
+
function success(stream, newI, x) {
|
176
|
+
i = newI;
|
177
|
+
xs.push(x);
|
178
|
+
return true;
|
179
|
+
}
|
180
|
+
|
181
|
+
function failure() {
|
182
|
+
return false;
|
183
|
+
}
|
184
|
+
});
|
185
|
+
};
|
186
|
+
|
187
|
+
// equivalent to:
|
188
|
+
// _.times = function(min, max) {
|
189
|
+
// if (arguments.length < 2) max = min;
|
190
|
+
// var self = this;
|
191
|
+
// if (min > 0) {
|
192
|
+
// return self.then(function(x) {
|
193
|
+
// return self.times(min - 1, max - 1).then(function(xs) {
|
194
|
+
// return [x].concat(xs);
|
195
|
+
// });
|
196
|
+
// });
|
197
|
+
// }
|
198
|
+
// else if (max > 0) {
|
199
|
+
// return self.then(function(x) {
|
200
|
+
// return self.times(0, max - 1).then(function(xs) {
|
201
|
+
// return [x].concat(xs);
|
202
|
+
// });
|
203
|
+
// }).or(succeed([]));
|
204
|
+
// }
|
205
|
+
// else return succeed([]);
|
206
|
+
// };
|
207
|
+
_.times = function(min, max) {
|
208
|
+
if (arguments.length < 2) max = min;
|
209
|
+
var self = this;
|
210
|
+
|
211
|
+
return Parser(function(stream, i, onSuccess, onFailure) {
|
212
|
+
var xs = [];
|
213
|
+
var result = true;
|
214
|
+
var failure;
|
215
|
+
|
216
|
+
for (var times = 0; times < min; times += 1) {
|
217
|
+
result = self._(stream, i, success, firstFailure);
|
218
|
+
if (!result) return onFailure(stream, i, failure);
|
219
|
+
}
|
220
|
+
|
221
|
+
for (; times < max && result; times += 1) {
|
222
|
+
result = self._(stream, i, success, secondFailure);
|
223
|
+
}
|
224
|
+
|
225
|
+
return onSuccess(stream, i, xs);
|
226
|
+
|
227
|
+
function success(stream, newI, x) {
|
228
|
+
xs.push(x);
|
229
|
+
i = newI;
|
230
|
+
return true;
|
231
|
+
}
|
232
|
+
|
233
|
+
function firstFailure(stream, newI, msg) {
|
234
|
+
failure = msg;
|
235
|
+
i = newI;
|
236
|
+
return false;
|
237
|
+
}
|
238
|
+
|
239
|
+
function secondFailure(stream, newI, msg) {
|
240
|
+
return false;
|
241
|
+
}
|
242
|
+
});
|
243
|
+
};
|
244
|
+
|
245
|
+
// -*- higher-level combinators -*- //
|
246
|
+
_.result = function(res) { return this.then(succeed(res)); };
|
247
|
+
_.atMost = function(n) { return this.times(0, n); };
|
248
|
+
_.atLeast = function(n) {
|
249
|
+
var self = this;
|
250
|
+
return self.times(n).then(function(start) {
|
251
|
+
return self.many().map(function(end) {
|
252
|
+
return start.concat(end);
|
253
|
+
});
|
254
|
+
});
|
255
|
+
};
|
256
|
+
|
257
|
+
_.map = function(fn) {
|
258
|
+
return this.then(function(result) { return succeed(fn(result)); });
|
259
|
+
};
|
260
|
+
|
261
|
+
_.skip = function(two) {
|
262
|
+
return this.then(function(result) { return two.result(result); });
|
263
|
+
};
|
264
|
+
|
265
|
+
// -*- primitive parsers -*- //
|
266
|
+
var string = Parsimmon.string = function(str) {
|
267
|
+
var len = str.length;
|
268
|
+
var expected = "'"+str+"'";
|
269
|
+
|
270
|
+
return Parser(function(stream, i, onSuccess, onFailure) {
|
271
|
+
var head = stream.slice(i, i+len);
|
272
|
+
|
273
|
+
if (head === str) {
|
274
|
+
return onSuccess(stream, i+len, head);
|
275
|
+
}
|
276
|
+
else {
|
277
|
+
return onFailure(stream, i, expected);
|
278
|
+
}
|
279
|
+
});
|
280
|
+
};
|
281
|
+
|
282
|
+
var regex = Parsimmon.regex = function(re) {
|
283
|
+
if (re.source[0] !== '^') throw 'regex '+re+' must be anchored';
|
284
|
+
|
285
|
+
var expected = ''+re;
|
286
|
+
|
287
|
+
return Parser(function(stream, i, onSuccess, onFailure) {
|
288
|
+
var match = re.exec(stream.slice(i));
|
289
|
+
|
290
|
+
if (match) {
|
291
|
+
var result = match[0];
|
292
|
+
return onSuccess(stream, i+result.length, result);
|
293
|
+
}
|
294
|
+
else {
|
295
|
+
return onFailure(stream, i, expected);
|
296
|
+
}
|
297
|
+
});
|
298
|
+
};
|
299
|
+
|
300
|
+
var succeed = Parsimmon.succeed = function(result) {
|
301
|
+
return Parser(function(stream, i, onSuccess) {
|
302
|
+
return onSuccess(stream, i, result);
|
303
|
+
});
|
304
|
+
};
|
305
|
+
|
306
|
+
var fail = Parsimmon.fail = function(expected) {
|
307
|
+
return Parser(function(stream, i, _, onFailure) {
|
308
|
+
return onFailure(stream, i, expected);
|
309
|
+
});
|
310
|
+
};
|
311
|
+
|
312
|
+
var letter = Parsimmon.letter = regex(/^[a-z]/i);
|
313
|
+
var letters = Parsimmon.letters = regex(/^[a-z]*/i);
|
314
|
+
var digit = Parsimmon.digit = regex(/^[0-9]/);
|
315
|
+
var digits = Parsimmon.digits = regex(/^[0-9]*/);
|
316
|
+
var whitespace = Parsimmon.whitespace = regex(/^\s+/);
|
317
|
+
var optWhitespace = Parsimmon.optWhitespace = regex(/^\s*/);
|
318
|
+
|
319
|
+
var any = Parsimmon.any = Parser(function(stream, i, onSuccess, onFailure) {
|
320
|
+
if (i >= stream.length) return onFailure(stream, i, 'any character');
|
321
|
+
|
322
|
+
return onSuccess(stream, i+1, stream.charAt(i));
|
323
|
+
});
|
324
|
+
|
325
|
+
var all = Parsimmon.all = Parser(function(stream, i, onSuccess, onFailure) {
|
326
|
+
return onSuccess(stream, stream.length, stream.slice(i));
|
327
|
+
});
|
328
|
+
|
329
|
+
var eof = Parsimmon.eof = Parser(function(stream, i, onSuccess, onFailure) {
|
330
|
+
if (i < stream.length) return onFailure(stream, i, 'EOF');
|
331
|
+
|
332
|
+
return onSuccess(stream, i, '');
|
333
|
+
});
|
334
|
+
});
|
335
|
+
return Parsimmon;
|
336
|
+
})()
|
337
|
+
// Generated by CoffeeScript 1.6.3
|
338
|
+
var Gibbon;
|
339
|
+
|
340
|
+
Gibbon = {};
|
341
|
+
// Generated by CoffeeScript 1.6.3
|
342
|
+
var CompMap, DEBUG, Hash, Map, Union, allocate, asyncMap, catLists, contIter, contMap, genId, isArray, uniq, _ref,
|
343
|
+
__slice = [].slice,
|
344
|
+
__hasProp = {}.hasOwnProperty,
|
345
|
+
__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; };
|
346
|
+
|
347
|
+
genId = (function() {
|
348
|
+
var id;
|
349
|
+
id = 0;
|
350
|
+
return function() {
|
351
|
+
return id += 1;
|
352
|
+
};
|
353
|
+
})();
|
354
|
+
|
355
|
+
DEBUG = function(f) {
|
356
|
+
return f();
|
357
|
+
};
|
358
|
+
|
359
|
+
DEBUG.log = console.log;
|
360
|
+
|
361
|
+
DEBUG.assert = function(msg, cond) {
|
362
|
+
if (!cond) {
|
363
|
+
throw msg;
|
364
|
+
}
|
365
|
+
};
|
366
|
+
|
367
|
+
isArray = Array.isArray || function(arg) {
|
368
|
+
return Object.prototype.toString.call(arg) === '[object Array]';
|
369
|
+
};
|
370
|
+
|
371
|
+
catLists = function(lists) {
|
372
|
+
var l, out, _i, _len;
|
373
|
+
out = [];
|
374
|
+
for (_i = 0, _len = lists.length; _i < _len; _i++) {
|
375
|
+
l = lists[_i];
|
376
|
+
out = out.concat(l);
|
377
|
+
}
|
378
|
+
return out;
|
379
|
+
};
|
380
|
+
|
381
|
+
uniq = function(list, eq) {
|
382
|
+
var el, out, u, _i, _j, _len, _len1;
|
383
|
+
if (eq == null) {
|
384
|
+
eq = (function(x, y) {
|
385
|
+
return x === y;
|
386
|
+
});
|
387
|
+
}
|
388
|
+
if (list.length === 0) {
|
389
|
+
return list;
|
390
|
+
}
|
391
|
+
out = [];
|
392
|
+
for (_i = 0, _len = list.length; _i < _len; _i++) {
|
393
|
+
el = list[_i];
|
394
|
+
for (_j = 0, _len1 = out.length; _j < _len1; _j++) {
|
395
|
+
u = out[_j];
|
396
|
+
if (!eq(el, u)) {
|
397
|
+
out.push(el);
|
398
|
+
break;
|
399
|
+
}
|
400
|
+
}
|
401
|
+
if (out.length === 0) {
|
402
|
+
out.push(el);
|
403
|
+
}
|
404
|
+
}
|
405
|
+
return out;
|
406
|
+
};
|
407
|
+
|
408
|
+
allocate = Object.create || function(proto) {
|
409
|
+
var dummy;
|
410
|
+
dummy = function() {};
|
411
|
+
dummy.prototype = proto;
|
412
|
+
return new dummy;
|
413
|
+
};
|
414
|
+
|
415
|
+
asyncMap = function(list, mapper, cb) {
|
416
|
+
var el, i, output, response, seen, _i, _len, _results;
|
417
|
+
if (list.length === 0) {
|
418
|
+
return cb(list);
|
419
|
+
}
|
420
|
+
seen = 0;
|
421
|
+
output = [];
|
422
|
+
response = function(i) {
|
423
|
+
return function(el) {
|
424
|
+
seen += 1;
|
425
|
+
output[i] = el;
|
426
|
+
if (seen >= list.length) {
|
427
|
+
return cb(output);
|
428
|
+
}
|
429
|
+
};
|
430
|
+
};
|
431
|
+
_results = [];
|
432
|
+
for (i = _i = 0, _len = list.length; _i < _len; i = ++_i) {
|
433
|
+
el = list[i];
|
434
|
+
_results.push(mapper(el, response(i), i));
|
435
|
+
}
|
436
|
+
return _results;
|
437
|
+
};
|
438
|
+
|
439
|
+
contMap = function(list, mapper, cb) {
|
440
|
+
var accum, step;
|
441
|
+
accum = [];
|
442
|
+
step = function(el, i, next) {
|
443
|
+
return mapper(el, function(result) {
|
444
|
+
accum[i] = result;
|
445
|
+
return next();
|
446
|
+
});
|
447
|
+
};
|
448
|
+
return contIter(list, step, function() {
|
449
|
+
return cb(accum);
|
450
|
+
});
|
451
|
+
};
|
452
|
+
|
453
|
+
contIter = function(list, f, cb) {
|
454
|
+
var loop_;
|
455
|
+
loop_ = function(i) {
|
456
|
+
if (i >= list.length) {
|
457
|
+
return cb();
|
458
|
+
}
|
459
|
+
return f(list[i], i, function() {
|
460
|
+
return loop_(i + 1);
|
461
|
+
});
|
462
|
+
};
|
463
|
+
return loop_(0);
|
464
|
+
};
|
465
|
+
|
466
|
+
Union = (function() {
|
467
|
+
var castJSON;
|
468
|
+
|
469
|
+
Union.specialize = function(tag, names) {
|
470
|
+
var klass, name, subclass, _i, _len;
|
471
|
+
klass = this;
|
472
|
+
subclass = function(values) {
|
473
|
+
if (values.length !== names.length) {
|
474
|
+
throw new TypeError("wrong number of arguments: " + values.length + " for " + names.length);
|
475
|
+
}
|
476
|
+
return klass.call(this, names, values);
|
477
|
+
};
|
478
|
+
subclass.prototype = allocate(klass.prototype);
|
479
|
+
subclass.prototype._tag = tag;
|
480
|
+
for (_i = 0, _len = names.length; _i < _len; _i++) {
|
481
|
+
name = names[_i];
|
482
|
+
subclass.prototype[name] = null;
|
483
|
+
}
|
484
|
+
return function() {
|
485
|
+
var values;
|
486
|
+
values = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
|
487
|
+
return new subclass(values);
|
488
|
+
};
|
489
|
+
};
|
490
|
+
|
491
|
+
Union.types = function(tags) {
|
492
|
+
var names, tag, _results;
|
493
|
+
this.tags = tags;
|
494
|
+
_results = [];
|
495
|
+
for (tag in tags) {
|
496
|
+
if (!__hasProp.call(tags, tag)) continue;
|
497
|
+
names = tags[tag];
|
498
|
+
_results.push(this[tag] = this.specialize(tag, names));
|
499
|
+
}
|
500
|
+
return _results;
|
501
|
+
};
|
502
|
+
|
503
|
+
function Union(_names, _values) {
|
504
|
+
var i, name, _i, _len, _ref;
|
505
|
+
this._names = _names;
|
506
|
+
this._values = _values;
|
507
|
+
_ref = this._names;
|
508
|
+
for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
|
509
|
+
name = _ref[i];
|
510
|
+
this[name] = this._values[i];
|
511
|
+
}
|
512
|
+
}
|
513
|
+
|
514
|
+
Union.prototype.cases = function(cases) {
|
515
|
+
var fn;
|
516
|
+
fn = cases[this._tag] || cases.other;
|
517
|
+
if (!fn) {
|
518
|
+
throw new Error("non-exhaustive cases: missing " + this._tag);
|
519
|
+
}
|
520
|
+
return fn.apply(this, this._values);
|
521
|
+
};
|
522
|
+
|
523
|
+
castJSON = function(val) {
|
524
|
+
var v, _i, _len, _results;
|
525
|
+
if (typeof (val != null ? val.asJSON : void 0) === 'function') {
|
526
|
+
return val.asJSON();
|
527
|
+
} else if (isArray(val)) {
|
528
|
+
_results = [];
|
529
|
+
for (_i = 0, _len = val.length; _i < _len; _i++) {
|
530
|
+
v = val[_i];
|
531
|
+
_results.push(castJSON(v));
|
532
|
+
}
|
533
|
+
return _results;
|
534
|
+
} else {
|
535
|
+
return val;
|
536
|
+
}
|
537
|
+
};
|
538
|
+
|
539
|
+
Union.prototype.asJSON = function() {
|
540
|
+
var name, out, _i, _len, _ref;
|
541
|
+
out = {
|
542
|
+
_tag: this._tag,
|
543
|
+
_union: this.constructor.name
|
544
|
+
};
|
545
|
+
_ref = this._names;
|
546
|
+
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
547
|
+
name = _ref[_i];
|
548
|
+
out[name] = castJSON(this[name]);
|
549
|
+
}
|
550
|
+
return out;
|
551
|
+
};
|
552
|
+
|
553
|
+
Union.fromJSON = function(o) {
|
554
|
+
var constructor, e, name, names, vals;
|
555
|
+
if (isArray(o)) {
|
556
|
+
return (function() {
|
557
|
+
var _i, _len, _results;
|
558
|
+
_results = [];
|
559
|
+
for (_i = 0, _len = o.length; _i < _len; _i++) {
|
560
|
+
e = o[_i];
|
561
|
+
_results.push(this.fromJSON(e));
|
562
|
+
}
|
563
|
+
return _results;
|
564
|
+
}).call(this);
|
565
|
+
}
|
566
|
+
if (!(typeof o === 'object' && (o != null) && '_tag' in o)) {
|
567
|
+
return o;
|
568
|
+
}
|
569
|
+
constructor = Gibbon[o._union];
|
570
|
+
names = constructor.tags[o._tag];
|
571
|
+
vals = (function() {
|
572
|
+
var _i, _len, _results;
|
573
|
+
_results = [];
|
574
|
+
for (_i = 0, _len = names.length; _i < _len; _i++) {
|
575
|
+
name = names[_i];
|
576
|
+
_results.push(constructor.fromJSON(o[name]));
|
577
|
+
}
|
578
|
+
return _results;
|
579
|
+
})();
|
580
|
+
return constructor[o._tag].apply(constructor, vals);
|
581
|
+
};
|
582
|
+
|
583
|
+
Union.wrap = function(o) {
|
584
|
+
if (o instanceof this) {
|
585
|
+
return o;
|
586
|
+
}
|
587
|
+
return this.fromJSON(o);
|
588
|
+
};
|
589
|
+
|
590
|
+
return Union;
|
591
|
+
|
592
|
+
})();
|
593
|
+
|
594
|
+
Map = (function() {
|
595
|
+
function Map() {}
|
596
|
+
|
597
|
+
Map.prototype.has = function() {
|
598
|
+
throw 'abstract';
|
599
|
+
};
|
600
|
+
|
601
|
+
Map.prototype.get = function() {
|
602
|
+
throw 'abstract';
|
603
|
+
};
|
604
|
+
|
605
|
+
Map.prototype.set = function() {
|
606
|
+
throw 'abstract';
|
607
|
+
};
|
608
|
+
|
609
|
+
Map.prototype.each = function() {
|
610
|
+
throw 'abstract';
|
611
|
+
};
|
612
|
+
|
613
|
+
Map.prototype.fetch = function(k, f) {
|
614
|
+
if (this.has(k)) {
|
615
|
+
return this.get(k);
|
616
|
+
} else {
|
617
|
+
return f();
|
618
|
+
}
|
619
|
+
};
|
620
|
+
|
621
|
+
Map.prototype.merge = function() {
|
622
|
+
var k, obj, objs, v, _i, _len, _results;
|
623
|
+
objs = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
|
624
|
+
_results = [];
|
625
|
+
for (_i = 0, _len = objs.length; _i < _len; _i++) {
|
626
|
+
obj = objs[_i];
|
627
|
+
_results.push((function() {
|
628
|
+
var _results1;
|
629
|
+
_results1 = [];
|
630
|
+
for (k in obj) {
|
631
|
+
if (!__hasProp.call(obj, k)) continue;
|
632
|
+
v = obj[k];
|
633
|
+
_results1.push(this.set(k, v));
|
634
|
+
}
|
635
|
+
return _results1;
|
636
|
+
}).call(this));
|
637
|
+
}
|
638
|
+
return _results;
|
639
|
+
};
|
640
|
+
|
641
|
+
Map.prototype.modify = function(k, f) {
|
642
|
+
return this.set(k, f(this.get(k)));
|
643
|
+
};
|
644
|
+
|
645
|
+
Map.prototype.cache = function(k, f) {
|
646
|
+
var _this = this;
|
647
|
+
return this.fetch(k, function() {
|
648
|
+
return _this.modify(k, f);
|
649
|
+
});
|
650
|
+
};
|
651
|
+
|
652
|
+
Map.prototype.keys = function() {
|
653
|
+
var out;
|
654
|
+
out = [];
|
655
|
+
this.each(function(k, v) {
|
656
|
+
return out.push(k);
|
657
|
+
});
|
658
|
+
return out;
|
659
|
+
};
|
660
|
+
|
661
|
+
Map.prototype.values = function() {
|
662
|
+
var out;
|
663
|
+
out = [];
|
664
|
+
this.each(function(k, v) {
|
665
|
+
return out.push(v);
|
666
|
+
});
|
667
|
+
return out;
|
668
|
+
};
|
669
|
+
|
670
|
+
return Map;
|
671
|
+
|
672
|
+
})();
|
673
|
+
|
674
|
+
Gibbon.Hash = Hash = (function(_super) {
|
675
|
+
var salt;
|
676
|
+
|
677
|
+
__extends(Hash, _super);
|
678
|
+
|
679
|
+
function Hash() {
|
680
|
+
_ref = Hash.__super__.constructor.apply(this, arguments);
|
681
|
+
return _ref;
|
682
|
+
}
|
683
|
+
|
684
|
+
salt = '<key>';
|
685
|
+
|
686
|
+
Hash.prototype.loadKey = function(k) {
|
687
|
+
return salt + k;
|
688
|
+
};
|
689
|
+
|
690
|
+
Hash.prototype.dumpKey = function(k) {
|
691
|
+
if (k.indexOf(salt) === 0) {
|
692
|
+
return k.slice(salt.length);
|
693
|
+
}
|
694
|
+
};
|
695
|
+
|
696
|
+
Hash.prototype.get = function(k) {
|
697
|
+
return this[salt + k];
|
698
|
+
};
|
699
|
+
|
700
|
+
Hash.prototype.set = function(k, v) {
|
701
|
+
return this[salt + k] = v;
|
702
|
+
};
|
703
|
+
|
704
|
+
Hash.prototype.has = function(k) {
|
705
|
+
return this.hasOwnProperty(salt + k);
|
706
|
+
};
|
707
|
+
|
708
|
+
Hash.prototype.each = function(f) {
|
709
|
+
var k, v, _results;
|
710
|
+
_results = [];
|
711
|
+
for (k in this) {
|
712
|
+
if (!__hasProp.call(this, k)) continue;
|
713
|
+
v = this[k];
|
714
|
+
if (k.indexOf(salt) !== 0) {
|
715
|
+
continue;
|
716
|
+
}
|
717
|
+
_results.push(f(k.slice(salt.length), v));
|
718
|
+
}
|
719
|
+
return _results;
|
720
|
+
};
|
721
|
+
|
722
|
+
return Hash;
|
723
|
+
|
724
|
+
})(Map);
|
725
|
+
|
726
|
+
CompMap = (function(_super) {
|
727
|
+
__extends(CompMap, _super);
|
728
|
+
|
729
|
+
function CompMap(fn) {
|
730
|
+
if (fn == null) {
|
731
|
+
fn = (function(x, y) {
|
732
|
+
return x === y;
|
733
|
+
});
|
734
|
+
}
|
735
|
+
CompMap.__super__.constructor.apply(this, arguments);
|
736
|
+
this.compare = fn;
|
737
|
+
this.keys = [];
|
738
|
+
this.values = [];
|
739
|
+
}
|
740
|
+
|
741
|
+
CompMap.prototype.addBinding = function(k, v) {
|
742
|
+
this.keys.push(k);
|
743
|
+
this.values.push(v);
|
744
|
+
return v;
|
745
|
+
};
|
746
|
+
|
747
|
+
CompMap.prototype.keyIndex = function(k) {
|
748
|
+
var i, key, _i, _len, _ref1;
|
749
|
+
_ref1 = this.keys;
|
750
|
+
for (i = _i = 0, _len = _ref1.length; _i < _len; i = ++_i) {
|
751
|
+
key = _ref1[i];
|
752
|
+
if (this.compare(key, k)) {
|
753
|
+
return i;
|
754
|
+
}
|
755
|
+
}
|
756
|
+
return null;
|
757
|
+
};
|
758
|
+
|
759
|
+
CompMap.prototype.has = function(k) {
|
760
|
+
return this.keyIndex(k) != null;
|
761
|
+
};
|
762
|
+
|
763
|
+
CompMap.prototype.get = function(k) {
|
764
|
+
var index;
|
765
|
+
index = this.keyIndex(k);
|
766
|
+
return (index != null) && this.values[index];
|
767
|
+
};
|
768
|
+
|
769
|
+
CompMap.prototype.set = function(k, v) {
|
770
|
+
var index;
|
771
|
+
index = this.keyIndex(k);
|
772
|
+
if (index != null) {
|
773
|
+
return this.values[index] = v;
|
774
|
+
} else {
|
775
|
+
return this.addBinding(k, v);
|
776
|
+
}
|
777
|
+
};
|
778
|
+
|
779
|
+
CompMap.prototype.each = function(f) {
|
780
|
+
var i, k, _i, _len, _ref1, _results;
|
781
|
+
_ref1 = this.keys;
|
782
|
+
_results = [];
|
783
|
+
for (i = _i = 0, _len = _ref1.length; _i < _len; i = ++_i) {
|
784
|
+
k = _ref1[i];
|
785
|
+
_results.push(f(k, this.values[i]));
|
786
|
+
}
|
787
|
+
return _results;
|
788
|
+
};
|
789
|
+
|
790
|
+
CompMap.prototype.eachAsync = function(f, cb) {
|
791
|
+
var i, k, keys, responder, seen, _i, _len, _results;
|
792
|
+
keys = this.keys;
|
793
|
+
if (keys.length === 0) {
|
794
|
+
return;
|
795
|
+
}
|
796
|
+
seen = 0;
|
797
|
+
responder = function(i) {
|
798
|
+
return function() {
|
799
|
+
seen += 1;
|
800
|
+
if (seen >= keys.length) {
|
801
|
+
return cb();
|
802
|
+
}
|
803
|
+
};
|
804
|
+
};
|
805
|
+
_results = [];
|
806
|
+
for (i = _i = 0, _len = keys.length; _i < _len; i = ++_i) {
|
807
|
+
k = keys[i];
|
808
|
+
_results.push(f(k, this.values[i], responder(i)));
|
809
|
+
}
|
810
|
+
return _results;
|
811
|
+
};
|
812
|
+
|
813
|
+
CompMap.prototype.fetch = function(k, f) {
|
814
|
+
var index;
|
815
|
+
index = this.keyIndex(k);
|
816
|
+
if (index != null) {
|
817
|
+
return this.values[index];
|
818
|
+
} else {
|
819
|
+
return f();
|
820
|
+
}
|
821
|
+
};
|
822
|
+
|
823
|
+
CompMap.prototype.fetchAsync = function(k, f, cb) {
|
824
|
+
var index;
|
825
|
+
index = this.keyIndex(k);
|
826
|
+
if (index != null) {
|
827
|
+
return cb(this.values[index]);
|
828
|
+
} else {
|
829
|
+
return f(cb);
|
830
|
+
}
|
831
|
+
};
|
832
|
+
|
833
|
+
CompMap.prototype.cache = function(k, f) {
|
834
|
+
var _this = this;
|
835
|
+
return this.fetch(k, function() {
|
836
|
+
return _this.addBinding(k, f());
|
837
|
+
});
|
838
|
+
};
|
839
|
+
|
840
|
+
return CompMap;
|
841
|
+
|
842
|
+
})(Map);
|
843
|
+
// Generated by CoffeeScript 1.6.3
|
844
|
+
var AST, TypeAST, parse, _ref, _ref1,
|
845
|
+
__hasProp = {}.hasOwnProperty,
|
846
|
+
__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; };
|
847
|
+
|
848
|
+
Gibbon.AST = AST = (function(_super) {
|
849
|
+
var inspectDefinitions;
|
850
|
+
|
851
|
+
__extends(AST, _super);
|
852
|
+
|
853
|
+
function AST() {
|
854
|
+
_ref = AST.__super__.constructor.apply(this, arguments);
|
855
|
+
return _ref;
|
856
|
+
}
|
857
|
+
|
858
|
+
AST.types({
|
859
|
+
integer: ['value'],
|
860
|
+
decimal: ['value'],
|
861
|
+
percent: ['value'],
|
862
|
+
fraction: ['numerator', 'denominator'],
|
863
|
+
string: ['value'],
|
864
|
+
subst: ['flow'],
|
865
|
+
block: ['flow'],
|
866
|
+
list: ['elements'],
|
867
|
+
query: ['type', 'name'],
|
868
|
+
func: ['name', 'args'],
|
869
|
+
pair: ['first', 'second'],
|
870
|
+
flow: ['head', 'tail'],
|
871
|
+
metadata: ['key', 'text'],
|
872
|
+
definition: ['metadata', 'name', 'frame'],
|
873
|
+
frame: ['definitions', 'flow']
|
874
|
+
});
|
875
|
+
|
876
|
+
inspectDefinitions = function(defs) {
|
877
|
+
var def, out, _i, _len;
|
878
|
+
out = [];
|
879
|
+
for (_i = 0, _len = defs.length; _i < _len; _i++) {
|
880
|
+
def = defs[_i];
|
881
|
+
out.push(def.inspect());
|
882
|
+
out.push("\n");
|
883
|
+
}
|
884
|
+
return out.join('');
|
885
|
+
};
|
886
|
+
|
887
|
+
AST.prototype.inspect = function() {
|
888
|
+
var id;
|
889
|
+
id = function(x) {
|
890
|
+
return x;
|
891
|
+
};
|
892
|
+
return this.cases({
|
893
|
+
integer: id,
|
894
|
+
decimal: id,
|
895
|
+
percent: id,
|
896
|
+
fraction: function(num, denom) {
|
897
|
+
return "" + num + "/" + denom;
|
898
|
+
},
|
899
|
+
string: function(s) {
|
900
|
+
return "'" + s + "'";
|
901
|
+
},
|
902
|
+
query: function(query, name) {
|
903
|
+
if (query === 'access') {
|
904
|
+
query = '';
|
905
|
+
}
|
906
|
+
return "@" + query + "(" + name + ")";
|
907
|
+
},
|
908
|
+
subst: function(flow) {
|
909
|
+
return "(" + (flow.inspect()) + ")";
|
910
|
+
},
|
911
|
+
block: function(flow) {
|
912
|
+
return "{ " + (flow.inspect()) + " }";
|
913
|
+
},
|
914
|
+
list: function(els) {
|
915
|
+
var el;
|
916
|
+
return "[ " + (((function() {
|
917
|
+
var _i, _len, _results;
|
918
|
+
_results = [];
|
919
|
+
for (_i = 0, _len = els.length; _i < _len; _i++) {
|
920
|
+
el = els[_i];
|
921
|
+
_results.push(el.inspect());
|
922
|
+
}
|
923
|
+
return _results;
|
924
|
+
})()).join(', ')) + " ]";
|
925
|
+
},
|
926
|
+
func: function(name, args) {
|
927
|
+
var arg;
|
928
|
+
args = (function() {
|
929
|
+
var _i, _len, _results;
|
930
|
+
_results = [];
|
931
|
+
for (_i = 0, _len = args.length; _i < _len; _i++) {
|
932
|
+
arg = args[_i];
|
933
|
+
_results.push(arg.inspect());
|
934
|
+
}
|
935
|
+
return _results;
|
936
|
+
})();
|
937
|
+
return "" + name + " " + (args.join(' '));
|
938
|
+
},
|
939
|
+
pair: function(first, second) {
|
940
|
+
return "" + (first.inspect()) + " : " + (second.inspect());
|
941
|
+
},
|
942
|
+
flow: function(head, tail) {
|
943
|
+
if (tail) {
|
944
|
+
tail = "" + (tail.inspect()) + " -> ";
|
945
|
+
} else {
|
946
|
+
tail = '';
|
947
|
+
}
|
948
|
+
return "" + tail + (head.inspect());
|
949
|
+
},
|
950
|
+
metadata: function(key, text) {
|
951
|
+
return "" + key + ": " + text;
|
952
|
+
},
|
953
|
+
definition: function(metadata, name, frame) {
|
954
|
+
var m, out, _i, _len;
|
955
|
+
out = [];
|
956
|
+
for (_i = 0, _len = metadata.length; _i < _len; _i++) {
|
957
|
+
m = metadata[_i];
|
958
|
+
out.push(m.inspect());
|
959
|
+
out.push("\n");
|
960
|
+
}
|
961
|
+
out.push("" + name + " := ");
|
962
|
+
out.push(frame.inspect());
|
963
|
+
return out.join('');
|
964
|
+
},
|
965
|
+
frame: function(definitions, flow) {
|
966
|
+
var out;
|
967
|
+
out = [];
|
968
|
+
out.push("(");
|
969
|
+
out.push(inspectDefinitions(definitions));
|
970
|
+
out.push(flow.inspect());
|
971
|
+
out.push(")");
|
972
|
+
return out.join('');
|
973
|
+
}
|
974
|
+
});
|
975
|
+
};
|
976
|
+
|
977
|
+
return AST;
|
978
|
+
|
979
|
+
})(Union);
|
980
|
+
|
981
|
+
Gibbon.TypeAST = TypeAST = (function(_super) {
|
982
|
+
__extends(TypeAST, _super);
|
983
|
+
|
984
|
+
function TypeAST() {
|
985
|
+
_ref1 = TypeAST.__super__.constructor.apply(this, arguments);
|
986
|
+
return _ref1;
|
987
|
+
}
|
988
|
+
|
989
|
+
TypeAST.types({
|
990
|
+
concrete: ['name'],
|
991
|
+
variable: ['name'],
|
992
|
+
"native": ['id'],
|
993
|
+
wildcard: [],
|
994
|
+
list: ['of'],
|
995
|
+
func: ['input', 'args', 'output'],
|
996
|
+
block: ['of'],
|
997
|
+
pair: ['first', 'second'],
|
998
|
+
arrow: ['from', 'to']
|
999
|
+
});
|
1000
|
+
|
1001
|
+
TypeAST.parse = function(str) {
|
1002
|
+
return parse.type(str);
|
1003
|
+
};
|
1004
|
+
|
1005
|
+
TypeAST.parseUnit = function(str) {
|
1006
|
+
return parse.unitType(str);
|
1007
|
+
};
|
1008
|
+
|
1009
|
+
return TypeAST;
|
1010
|
+
|
1011
|
+
})(Union);
|
1012
|
+
|
1013
|
+
parse = Gibbon.parse = (function() {
|
1014
|
+
var arrow, arrowType, assertString, bang, blockExpr, blockType, comma, comment, component, concrete, decimal, decimalExpr, define, definition, expr, fail, flow, fraction, fractionExpr, frame, freeFrame, fullSignature, func, funcPlaceholder, identifier, ignore, innerFrame, integer, integerExpr, isString, label, labelVal, lbrace, lbrack, lexeme, listExpr, listType, lparen, metadata, name, nativeId, nativeType, nonPairedFlow, numericExpr, pair, parenFlow, parenFrame, parenType, percent, percentExpr, program, query, question, rbrace, rbrack, regex, rparen, signature, simpleType, singletonFlow, str, string, stringExpr, substExpr, succeed, tassign, type, typeVar, variable, whitespace, wildType, wildcard;
|
1015
|
+
string = Parsimmon.string, regex = Parsimmon.regex, succeed = Parsimmon.succeed, fail = Parsimmon.fail;
|
1016
|
+
Parsimmon.Parser.prototype.expected = function(message) {
|
1017
|
+
var _this = this;
|
1018
|
+
return Parsimmon.Parser(function(stream, i, onSuccess) {
|
1019
|
+
return _this._(stream, i, onSuccess, function(newStream, _, defMessage) {
|
1020
|
+
var at;
|
1021
|
+
at = stream.slice(0, 10) || 'EOF';
|
1022
|
+
throw new Error("Parse Error: expected " + (message || defMessage) + " (at '" + at + "')");
|
1023
|
+
});
|
1024
|
+
});
|
1025
|
+
};
|
1026
|
+
Parsimmon.Parser.prototype.named = function(name) {
|
1027
|
+
var _this = this;
|
1028
|
+
return Parsimmon.Parser(function(stream, i, onSuccess, onFailure) {
|
1029
|
+
return _this._(stream, i, onSuccess, function() {
|
1030
|
+
return onFailure(stream, i, name);
|
1031
|
+
});
|
1032
|
+
});
|
1033
|
+
};
|
1034
|
+
whitespace = regex(/^[\n\s]+/);
|
1035
|
+
comment = regex(/^#.*?(\n|$)/);
|
1036
|
+
ignore = (whitespace.or(comment)).many();
|
1037
|
+
lexeme = function(p) {
|
1038
|
+
return p.skip(ignore);
|
1039
|
+
};
|
1040
|
+
identifier = regex(/^[a-z][\w-]*/i);
|
1041
|
+
arrow = lexeme(string('->'));
|
1042
|
+
define = lexeme(string(':='));
|
1043
|
+
pair = lexeme(string(':'));
|
1044
|
+
lbrace = lexeme(string('{'));
|
1045
|
+
rbrace = lexeme(string('}'));
|
1046
|
+
lbrack = lexeme(string('['));
|
1047
|
+
rbrack = lexeme(string(']'));
|
1048
|
+
lparen = lexeme(string('('));
|
1049
|
+
rparen = lexeme(string(')'));
|
1050
|
+
comma = lexeme(string(','));
|
1051
|
+
question = lexeme(string('?'));
|
1052
|
+
name = lexeme(identifier);
|
1053
|
+
str = lexeme(string("'").then(regex(/^[^']*/)).skip(string("'").expected()));
|
1054
|
+
fraction = lexeme(regex(/^\d+\/\d+/));
|
1055
|
+
decimal = lexeme(regex(/^\d+\.\d+/));
|
1056
|
+
percent = lexeme(regex(/^\d+%/));
|
1057
|
+
integer = lexeme(regex(/^\d+/));
|
1058
|
+
label = lexeme(identifier.skip(string(':')));
|
1059
|
+
labelVal = lexeme(regex(/^[^\n]*/));
|
1060
|
+
variable = lexeme(string('%').then(identifier));
|
1061
|
+
wildcard = lexeme(string('%'));
|
1062
|
+
funcPlaceholder = lexeme(string('&'));
|
1063
|
+
integerExpr = integer.map(function(i) {
|
1064
|
+
return AST.integer(parseInt(i));
|
1065
|
+
});
|
1066
|
+
decimalExpr = decimal.map(function(d) {
|
1067
|
+
return AST.decimal(parseFloat(d));
|
1068
|
+
});
|
1069
|
+
percentExpr = percent.map(function(p) {
|
1070
|
+
return AST.percent(parseInt(p));
|
1071
|
+
});
|
1072
|
+
fractionExpr = fraction.map(function(f) {
|
1073
|
+
var denom, num, _ref2;
|
1074
|
+
_ref2 = f.split('/'), num = _ref2[0], denom = _ref2[1];
|
1075
|
+
return AST.fraction(num, denom);
|
1076
|
+
});
|
1077
|
+
stringExpr = str.map(function(s) {
|
1078
|
+
return AST.string(s);
|
1079
|
+
});
|
1080
|
+
query = string('@').then((function() {
|
1081
|
+
var accessor, fullQuery, parenName;
|
1082
|
+
parenName = lparen.then(lexeme(identifier).expected()).skip(rparen.expected());
|
1083
|
+
accessor = parenName.map(function(name) {
|
1084
|
+
return AST.query('access', name);
|
1085
|
+
});
|
1086
|
+
fullQuery = identifier.then(function(q) {
|
1087
|
+
return parenName.map(function(name) {
|
1088
|
+
return AST.query(q, name);
|
1089
|
+
});
|
1090
|
+
});
|
1091
|
+
return accessor.or(fullQuery);
|
1092
|
+
})());
|
1093
|
+
numericExpr = percentExpr.or(decimalExpr.or(fractionExpr.or(integerExpr)));
|
1094
|
+
parenFlow = lparen.then(function() {
|
1095
|
+
return flow.expected().skip(rparen.expected());
|
1096
|
+
});
|
1097
|
+
substExpr = parenFlow.map(function(fl) {
|
1098
|
+
return AST.subst(fl);
|
1099
|
+
});
|
1100
|
+
listExpr = lbrack.then(function() {
|
1101
|
+
return flow.skip(comma).many().then(function(els) {
|
1102
|
+
return flow.or(succeed(null)).then(function(final) {
|
1103
|
+
if (final) {
|
1104
|
+
els.push(final);
|
1105
|
+
}
|
1106
|
+
return rbrack.expected().result(AST.list(els));
|
1107
|
+
});
|
1108
|
+
});
|
1109
|
+
});
|
1110
|
+
blockExpr = lbrace.then(function() {
|
1111
|
+
return flow.skip(rbrace.expected());
|
1112
|
+
}).map(AST.block);
|
1113
|
+
expr = query.or(substExpr.or(listExpr.or(stringExpr.or(blockExpr.or(numericExpr)))));
|
1114
|
+
singletonFlow = expr.map(function(e) {
|
1115
|
+
return AST.flow(e, null);
|
1116
|
+
});
|
1117
|
+
func = name.then(function(funcName) {
|
1118
|
+
return parenFlow.or(singletonFlow).many().map(function(args) {
|
1119
|
+
return AST.func(funcName, args);
|
1120
|
+
});
|
1121
|
+
});
|
1122
|
+
component = expr.or(func);
|
1123
|
+
nonPairedFlow = component.then(function(first) {
|
1124
|
+
return arrow.then(component).many().map(function(rest) {
|
1125
|
+
var comp, cursor, _i, _len;
|
1126
|
+
cursor = AST.flow(first, null);
|
1127
|
+
for (_i = 0, _len = rest.length; _i < _len; _i++) {
|
1128
|
+
comp = rest[_i];
|
1129
|
+
cursor = AST.flow(comp, cursor);
|
1130
|
+
}
|
1131
|
+
return cursor;
|
1132
|
+
});
|
1133
|
+
});
|
1134
|
+
flow = nonPairedFlow.then(function(first) {
|
1135
|
+
return pair.then(flow).map(function(second) {
|
1136
|
+
return AST.flow(AST.pair(first, second), null);
|
1137
|
+
}).or(succeed(first));
|
1138
|
+
});
|
1139
|
+
metadata = label.then(function(key) {
|
1140
|
+
return labelVal.map(function(text) {
|
1141
|
+
return AST.metadata(key, text);
|
1142
|
+
});
|
1143
|
+
});
|
1144
|
+
definition = metadata.many().then(function(md) {
|
1145
|
+
return name.then(function(n) {
|
1146
|
+
return define.then(innerFrame.expected()).map(function(fl) {
|
1147
|
+
return AST.definition(md, n, fl);
|
1148
|
+
});
|
1149
|
+
});
|
1150
|
+
});
|
1151
|
+
frame = definition.many().then(function(defs) {
|
1152
|
+
return flow.expected().map(function(fl) {
|
1153
|
+
return AST.frame(defs, fl);
|
1154
|
+
});
|
1155
|
+
});
|
1156
|
+
parenFrame = lparen.then(frame).skip(rparen.expected());
|
1157
|
+
freeFrame = flow.map(function(fl) {
|
1158
|
+
return AST.frame([], fl);
|
1159
|
+
});
|
1160
|
+
innerFrame = parenFrame.or(freeFrame);
|
1161
|
+
program = ignore.then(frame);
|
1162
|
+
tassign = lexeme(string('='));
|
1163
|
+
bang = lexeme(string('!'));
|
1164
|
+
nativeId = lexeme(regex(/^\w+/));
|
1165
|
+
concrete = name.map(function(n) {
|
1166
|
+
return TypeAST.concrete(n);
|
1167
|
+
});
|
1168
|
+
typeVar = variable.map(function(v) {
|
1169
|
+
return TypeAST.variable(v);
|
1170
|
+
});
|
1171
|
+
wildType = wildcard.result(TypeAST.wildcard());
|
1172
|
+
listType = lbrack.then(function() {
|
1173
|
+
return type.skip(rbrack.expected()).map(function(t) {
|
1174
|
+
return TypeAST.list(t);
|
1175
|
+
});
|
1176
|
+
});
|
1177
|
+
parenType = lparen.then(function() {
|
1178
|
+
return type.skip(rparen.expected());
|
1179
|
+
});
|
1180
|
+
blockType = lbrace.then(function() {
|
1181
|
+
return arrowType.skip(rbrace.expected()).map(function(t) {
|
1182
|
+
return TypeAST.block(t);
|
1183
|
+
});
|
1184
|
+
});
|
1185
|
+
nativeType = bang.then(nativeId).map(TypeAST["native"]);
|
1186
|
+
simpleType = (typeVar.or(wildType.or(listType.or(parenType.or(blockType.or(concrete.or(nativeType))))))).named('a simple type');
|
1187
|
+
type = simpleType.then(function(first) {
|
1188
|
+
return pair.then(type.expected()).map(function(second) {
|
1189
|
+
return TypeAST.pair(first, second);
|
1190
|
+
}).or(succeed(first));
|
1191
|
+
});
|
1192
|
+
arrowType = type.then(function(first) {
|
1193
|
+
return arrow.then(type.expected()).map(function(second) {
|
1194
|
+
return TypeAST.arrow(first, second);
|
1195
|
+
});
|
1196
|
+
});
|
1197
|
+
signature = name.then(function(n) {
|
1198
|
+
return type.many().then(function(argTypes) {
|
1199
|
+
return tassign.then(arrowType).map(function(ftype) {
|
1200
|
+
return TypeAST.func(ftype.from, argTypes, ftype.to);
|
1201
|
+
});
|
1202
|
+
});
|
1203
|
+
});
|
1204
|
+
fullSignature = ignore.then(signature);
|
1205
|
+
isString = function(s) {
|
1206
|
+
return typeof s === 'string' || s instanceof String;
|
1207
|
+
};
|
1208
|
+
assertString = function(s) {
|
1209
|
+
if (!isString(s)) {
|
1210
|
+
throw 'can only parse strings';
|
1211
|
+
}
|
1212
|
+
};
|
1213
|
+
parse = function(str) {
|
1214
|
+
assertString(str);
|
1215
|
+
return program.parse(str);
|
1216
|
+
};
|
1217
|
+
parse.type = function(str) {
|
1218
|
+
assertString(str);
|
1219
|
+
return fullSignature.parse(str);
|
1220
|
+
};
|
1221
|
+
parse.unitType = function(str) {
|
1222
|
+
assertString(str);
|
1223
|
+
return type.parse(str);
|
1224
|
+
};
|
1225
|
+
return parse;
|
1226
|
+
})();
|
1227
|
+
// Generated by CoffeeScript 1.6.3
|
1228
|
+
var stdlib;
|
1229
|
+
|
1230
|
+
stdlib = Gibbon.stdlib = (function() {
|
1231
|
+
return {
|
1232
|
+
"case": {
|
1233
|
+
type: parse.type('case [bool : %b] = % -> %b'),
|
1234
|
+
impl: function(_, evalList) {
|
1235
|
+
return evalList.then(function(list) {
|
1236
|
+
var out, step;
|
1237
|
+
step = function(pair, next) {
|
1238
|
+
return pair.first.then(function(cond) {
|
1239
|
+
if (cond.value) {
|
1240
|
+
return pair.second;
|
1241
|
+
} else {
|
1242
|
+
return next();
|
1243
|
+
}
|
1244
|
+
});
|
1245
|
+
};
|
1246
|
+
out = function() {
|
1247
|
+
throw new Error('Runtime Error: non-exhaustive cases');
|
1248
|
+
};
|
1249
|
+
return Promise.iter(list.elements, step, out);
|
1250
|
+
});
|
1251
|
+
}
|
1252
|
+
},
|
1253
|
+
weight: {
|
1254
|
+
type: parse.type('weight [numeric : numeric] = % -> numeric'),
|
1255
|
+
impl: function(_, eWeights) {
|
1256
|
+
return eWeights.then(function(weights) {
|
1257
|
+
return Promise.combine(weights.elements).then(function(pairs) {
|
1258
|
+
var denominator, numerator, p, process;
|
1259
|
+
numerator = 0;
|
1260
|
+
denominator = 0;
|
1261
|
+
process = function(pair) {
|
1262
|
+
return Promise.combine([pair.first, pair.second]).after(function(_arg) {
|
1263
|
+
var first, second;
|
1264
|
+
first = _arg[0], second = _arg[1];
|
1265
|
+
numerator += first.value * second.value;
|
1266
|
+
return denominator += second.value;
|
1267
|
+
});
|
1268
|
+
};
|
1269
|
+
return Promise.combine((function() {
|
1270
|
+
var _i, _len, _results;
|
1271
|
+
_results = [];
|
1272
|
+
for (_i = 0, _len = pairs.length; _i < _len; _i++) {
|
1273
|
+
p = pairs[_i];
|
1274
|
+
_results.push(process(p));
|
1275
|
+
}
|
1276
|
+
return _results;
|
1277
|
+
})()).then(function() {
|
1278
|
+
if (denominator === 0) {
|
1279
|
+
return Promise.fail('cannot divide by zero');
|
1280
|
+
}
|
1281
|
+
debugger;
|
1282
|
+
return Promise.unit(Value.number(numerator / denominator));
|
1283
|
+
});
|
1284
|
+
});
|
1285
|
+
});
|
1286
|
+
}
|
1287
|
+
},
|
1288
|
+
filter: {
|
1289
|
+
type: parse.type('filter { %a -> bool } = [%a] -> [%a]'),
|
1290
|
+
impl: function(evalInput, evalBlock) {
|
1291
|
+
return evalBlock.then(function(block) {
|
1292
|
+
var fn;
|
1293
|
+
fn = block.fn;
|
1294
|
+
return evalInput.then(function(list) {
|
1295
|
+
var check, e, out;
|
1296
|
+
out = [];
|
1297
|
+
check = function(thunk) {
|
1298
|
+
return fn(thunk).after(function(bool) {
|
1299
|
+
if (bool.value) {
|
1300
|
+
return out.push(thunk);
|
1301
|
+
}
|
1302
|
+
});
|
1303
|
+
};
|
1304
|
+
return Promise.combine((function() {
|
1305
|
+
var _i, _len, _ref, _results;
|
1306
|
+
_ref = list.elements;
|
1307
|
+
_results = [];
|
1308
|
+
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
1309
|
+
e = _ref[_i];
|
1310
|
+
_results.push(check(e));
|
1311
|
+
}
|
1312
|
+
return _results;
|
1313
|
+
})()).map(function() {
|
1314
|
+
return Value.list(out);
|
1315
|
+
});
|
1316
|
+
});
|
1317
|
+
});
|
1318
|
+
}
|
1319
|
+
},
|
1320
|
+
scale: {
|
1321
|
+
type: parse.type('scale (numeric:numeric) (numeric:numeric) = numeric -> numeric'),
|
1322
|
+
impl: function(eInput, eDomain, eRange) {
|
1323
|
+
return Promise.combine([eInput, eDomain, eRange]).then(function(_arg) {
|
1324
|
+
var bounds, dom, input, range;
|
1325
|
+
input = _arg[0], dom = _arg[1], range = _arg[2];
|
1326
|
+
bounds = Promise.combine([dom.first, dom.second, range.first, range.second]);
|
1327
|
+
return bounds.map(function(_arg1) {
|
1328
|
+
var domHigh, domLow, domSize, rangeHigh, rangeLow, rangeSize, retranslated, scaled, translated;
|
1329
|
+
domLow = _arg1[0], domHigh = _arg1[1], rangeLow = _arg1[2], rangeHigh = _arg1[3];
|
1330
|
+
if (input.value < domLow.value) {
|
1331
|
+
input = domLow;
|
1332
|
+
} else if (input.value > domHigh.value) {
|
1333
|
+
input = domHigh;
|
1334
|
+
}
|
1335
|
+
domSize = domHigh.value - domLow.value;
|
1336
|
+
rangeSize = rangeHigh.value - rangeLow.value;
|
1337
|
+
translated = input.value - domLow.value;
|
1338
|
+
scaled = translated * rangeSize / domSize;
|
1339
|
+
retranslated = scaled + rangeLow.value;
|
1340
|
+
return Value.number(retranslated);
|
1341
|
+
});
|
1342
|
+
});
|
1343
|
+
}
|
1344
|
+
},
|
1345
|
+
map: {
|
1346
|
+
type: parse.type('map { %a -> %b } = [%a] -> [%b]'),
|
1347
|
+
impl: function(evalList, evalBlock) {
|
1348
|
+
return evalList.then(function(list) {
|
1349
|
+
return evalBlock.map(function(block) {
|
1350
|
+
var e, fn;
|
1351
|
+
fn = block.fn;
|
1352
|
+
return Value.list(Promise.combine((function() {
|
1353
|
+
var _i, _len, _ref, _results;
|
1354
|
+
_ref = list.elements;
|
1355
|
+
_results = [];
|
1356
|
+
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
1357
|
+
e = _ref[_i];
|
1358
|
+
_results.push(fn(e));
|
1359
|
+
}
|
1360
|
+
return _results;
|
1361
|
+
})()));
|
1362
|
+
});
|
1363
|
+
});
|
1364
|
+
}
|
1365
|
+
},
|
1366
|
+
count: {
|
1367
|
+
type: parse.type('count = [%a] -> numeric'),
|
1368
|
+
impl: function(evalList) {
|
1369
|
+
return evalList.map(function(list) {
|
1370
|
+
return Value.number(list.elements.length);
|
1371
|
+
});
|
1372
|
+
}
|
1373
|
+
},
|
1374
|
+
sum: {
|
1375
|
+
type: parse.type('sum = [numeric] -> numeric'),
|
1376
|
+
impl: function(list) {
|
1377
|
+
return list.then(function(val) {
|
1378
|
+
return Promise.combine(val.elements).then(function(vals) {
|
1379
|
+
var e, out, _i, _len;
|
1380
|
+
out = 0;
|
1381
|
+
for (_i = 0, _len = vals.length; _i < _len; _i++) {
|
1382
|
+
e = vals[_i];
|
1383
|
+
out += e.value;
|
1384
|
+
}
|
1385
|
+
return Promise.unit(Value.number(out));
|
1386
|
+
});
|
1387
|
+
});
|
1388
|
+
}
|
1389
|
+
},
|
1390
|
+
first: {
|
1391
|
+
type: parse.type('first = [%a] -> %a'),
|
1392
|
+
impl: function(list) {
|
1393
|
+
return list.then(function(val) {
|
1394
|
+
return val.elements[0];
|
1395
|
+
});
|
1396
|
+
}
|
1397
|
+
},
|
1398
|
+
add: {
|
1399
|
+
type: parse.type('add numeric = numeric -> numeric'),
|
1400
|
+
impl: function(input, num) {
|
1401
|
+
return Promise.combine([input, num]).map(function(_arg) {
|
1402
|
+
var lhs, rhs;
|
1403
|
+
lhs = _arg[0], rhs = _arg[1];
|
1404
|
+
return Value.number(lhs.value + rhs.value);
|
1405
|
+
});
|
1406
|
+
}
|
1407
|
+
},
|
1408
|
+
sub: {
|
1409
|
+
type: parse.type('sub numeric = numeric -> numeric'),
|
1410
|
+
impl: function(input, num) {
|
1411
|
+
return Promise.combine([input, num]).map(function(_arg) {
|
1412
|
+
var lhs, rhs;
|
1413
|
+
lhs = _arg[0], rhs = _arg[1];
|
1414
|
+
return Value.number(lhs.value - rhs.value);
|
1415
|
+
});
|
1416
|
+
}
|
1417
|
+
},
|
1418
|
+
id: {
|
1419
|
+
type: parse.type('id = %a -> %a'),
|
1420
|
+
impl: function(x) {
|
1421
|
+
return x;
|
1422
|
+
}
|
1423
|
+
},
|
1424
|
+
"else": {
|
1425
|
+
type: parse.type('else = % -> bool'),
|
1426
|
+
impl: function(_) {
|
1427
|
+
return Promise.unit(Value.boolean(true));
|
1428
|
+
}
|
1429
|
+
},
|
1430
|
+
gt: {
|
1431
|
+
type: parse.type('gt numeric = numeric -> bool'),
|
1432
|
+
impl: function(input, num) {
|
1433
|
+
return Promise.combine([input, num]).map(function(_arg) {
|
1434
|
+
var lhs, rhs;
|
1435
|
+
lhs = _arg[0], rhs = _arg[1];
|
1436
|
+
return Value.boolean(lhs.value > rhs.value);
|
1437
|
+
});
|
1438
|
+
}
|
1439
|
+
},
|
1440
|
+
lt: {
|
1441
|
+
type: parse.type('lt numeric = numeric -> bool'),
|
1442
|
+
impl: function(input, num) {
|
1443
|
+
return Promise.combine([input, num]).map(function(_arg) {
|
1444
|
+
var lhs, rhs;
|
1445
|
+
lhs = _arg[0], rhs = _arg[1];
|
1446
|
+
return Value.boolean(lhs.value < rhs.value);
|
1447
|
+
});
|
1448
|
+
}
|
1449
|
+
},
|
1450
|
+
eq: {
|
1451
|
+
type: parse.type('eq %a = %a -> bool'),
|
1452
|
+
impl: function(input, obj) {
|
1453
|
+
return Promise.combine([input, obj]).then(function(_arg) {
|
1454
|
+
var lhs, rhs;
|
1455
|
+
lhs = _arg[0], rhs = _arg[1];
|
1456
|
+
return lhs.equals(rhs);
|
1457
|
+
});
|
1458
|
+
}
|
1459
|
+
}
|
1460
|
+
};
|
1461
|
+
})();
|
1462
|
+
// Generated by CoffeeScript 1.6.3
|
1463
|
+
var Semantic, Type, TypeLookup, analyze, _ref, _ref1, _ref2,
|
1464
|
+
__hasProp = {}.hasOwnProperty,
|
1465
|
+
__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; },
|
1466
|
+
__slice = [].slice;
|
1467
|
+
|
1468
|
+
Gibbon.Semantic = Semantic = (function(_super) {
|
1469
|
+
__extends(Semantic, _super);
|
1470
|
+
|
1471
|
+
function Semantic() {
|
1472
|
+
_ref = Semantic.__super__.constructor.apply(this, arguments);
|
1473
|
+
return _ref;
|
1474
|
+
}
|
1475
|
+
|
1476
|
+
Semantic.types({
|
1477
|
+
definition: ['dependencies', 'flow'],
|
1478
|
+
literal: ['syntax'],
|
1479
|
+
query: ['annotations'],
|
1480
|
+
localAccessor: ['name'],
|
1481
|
+
pair: ['first', 'second'],
|
1482
|
+
block: ['body'],
|
1483
|
+
list: ['elements'],
|
1484
|
+
flow: ['type', 'head', 'tail'],
|
1485
|
+
func: ['name', 'args'],
|
1486
|
+
subst: ['flow']
|
1487
|
+
});
|
1488
|
+
|
1489
|
+
return Semantic;
|
1490
|
+
|
1491
|
+
})(Union);
|
1492
|
+
|
1493
|
+
Gibbon.TypeLookup = TypeLookup = (function(_super) {
|
1494
|
+
__extends(TypeLookup, _super);
|
1495
|
+
|
1496
|
+
function TypeLookup() {
|
1497
|
+
_ref1 = TypeLookup.__super__.constructor.apply(this, arguments);
|
1498
|
+
return _ref1;
|
1499
|
+
}
|
1500
|
+
|
1501
|
+
TypeLookup.types({
|
1502
|
+
response: ['analysis'],
|
1503
|
+
local: ['name']
|
1504
|
+
});
|
1505
|
+
|
1506
|
+
return TypeLookup;
|
1507
|
+
|
1508
|
+
})(Union);
|
1509
|
+
|
1510
|
+
Gibbon.Type = Type = (function(_super) {
|
1511
|
+
__extends(Type, _super);
|
1512
|
+
|
1513
|
+
function Type() {
|
1514
|
+
_ref2 = Type.__super__.constructor.apply(this, arguments);
|
1515
|
+
return _ref2;
|
1516
|
+
}
|
1517
|
+
|
1518
|
+
Type.types({
|
1519
|
+
block: ['from', 'to'],
|
1520
|
+
pair: ['first', 'second'],
|
1521
|
+
list: ['of'],
|
1522
|
+
entity: ['id'],
|
1523
|
+
numeric: [],
|
1524
|
+
string: [],
|
1525
|
+
bool: [],
|
1526
|
+
abstract: ['expr']
|
1527
|
+
});
|
1528
|
+
|
1529
|
+
Type.prototype.inspect = function() {
|
1530
|
+
var v, vals;
|
1531
|
+
if (this._tag === 'entity') {
|
1532
|
+
return "(entity " + this.id + ")";
|
1533
|
+
}
|
1534
|
+
vals = this._values;
|
1535
|
+
if (!vals.length) {
|
1536
|
+
return this._tag;
|
1537
|
+
}
|
1538
|
+
vals = (function() {
|
1539
|
+
var _i, _len, _results;
|
1540
|
+
_results = [];
|
1541
|
+
for (_i = 0, _len = vals.length; _i < _len; _i++) {
|
1542
|
+
v = vals[_i];
|
1543
|
+
_results.push(v.inspect());
|
1544
|
+
}
|
1545
|
+
return _results;
|
1546
|
+
})();
|
1547
|
+
return "(" + this._tag + " " + (vals.join(' ')) + ")";
|
1548
|
+
};
|
1549
|
+
|
1550
|
+
return Type;
|
1551
|
+
|
1552
|
+
})(Union);
|
1553
|
+
|
1554
|
+
analyze = Gibbon.analyze = (function() {
|
1555
|
+
var TypeExpr, generate, solve, _ref3;
|
1556
|
+
TypeExpr = (function(_super) {
|
1557
|
+
__extends(TypeExpr, _super);
|
1558
|
+
|
1559
|
+
function TypeExpr() {
|
1560
|
+
_ref3 = TypeExpr.__super__.constructor.apply(this, arguments);
|
1561
|
+
return _ref3;
|
1562
|
+
}
|
1563
|
+
|
1564
|
+
TypeExpr.types({
|
1565
|
+
expr: ['expr'],
|
1566
|
+
variable: ['name'],
|
1567
|
+
query: ['input', 'scope', 'query'],
|
1568
|
+
destructure: ['constraint', 'name', 'argnum'],
|
1569
|
+
"native": ['id'],
|
1570
|
+
param: ['name', 'constraints'],
|
1571
|
+
any: []
|
1572
|
+
});
|
1573
|
+
|
1574
|
+
TypeExpr.prototype.realize = function() {
|
1575
|
+
return this.cases({
|
1576
|
+
"native": function(id) {
|
1577
|
+
return Type.entity(id);
|
1578
|
+
},
|
1579
|
+
param: function(name, args) {
|
1580
|
+
var arg;
|
1581
|
+
return Type[name].apply(Type, (function() {
|
1582
|
+
var _i, _len, _results;
|
1583
|
+
_results = [];
|
1584
|
+
for (_i = 0, _len = args.length; _i < _len; _i++) {
|
1585
|
+
arg = args[_i];
|
1586
|
+
_results.push(arg.realize());
|
1587
|
+
}
|
1588
|
+
return _results;
|
1589
|
+
})());
|
1590
|
+
},
|
1591
|
+
other: function() {
|
1592
|
+
return Type.abstract(this);
|
1593
|
+
}
|
1594
|
+
});
|
1595
|
+
};
|
1596
|
+
|
1597
|
+
TypeExpr.prototype.inspect = function() {
|
1598
|
+
return this.cases({
|
1599
|
+
expr: function(e) {
|
1600
|
+
return "<" + (e.inspect()) + ">";
|
1601
|
+
},
|
1602
|
+
variable: function(name) {
|
1603
|
+
return "%" + name;
|
1604
|
+
},
|
1605
|
+
query: function(input, _, query) {
|
1606
|
+
return "@" + query.type + "(" + query.name + ")[" + (input.inspect()) + "]";
|
1607
|
+
},
|
1608
|
+
destructure: function(constraint, name, argnum) {
|
1609
|
+
return "" + (constraint.inspect()) + "/" + name + "[" + argnum + "]";
|
1610
|
+
},
|
1611
|
+
"native": function(id) {
|
1612
|
+
return "!" + id;
|
1613
|
+
},
|
1614
|
+
param: function(name, exprs) {
|
1615
|
+
var expr;
|
1616
|
+
if (!exprs.length) {
|
1617
|
+
return "(" + name + ")";
|
1618
|
+
}
|
1619
|
+
exprs = (function() {
|
1620
|
+
var _i, _len, _results;
|
1621
|
+
_results = [];
|
1622
|
+
for (_i = 0, _len = exprs.length; _i < _len; _i++) {
|
1623
|
+
expr = exprs[_i];
|
1624
|
+
_results.push(expr.inspect());
|
1625
|
+
}
|
1626
|
+
return _results;
|
1627
|
+
})();
|
1628
|
+
return "(" + name + " " + (exprs.join(' ')) + ")";
|
1629
|
+
},
|
1630
|
+
any: function() {
|
1631
|
+
return '*';
|
1632
|
+
}
|
1633
|
+
});
|
1634
|
+
};
|
1635
|
+
|
1636
|
+
TypeExpr.prototype.equals = function(other) {
|
1637
|
+
var _this = this;
|
1638
|
+
if (this._tag !== other._tag) {
|
1639
|
+
return false;
|
1640
|
+
}
|
1641
|
+
return this.cases({
|
1642
|
+
expr: function(e) {
|
1643
|
+
return e === other.expr;
|
1644
|
+
},
|
1645
|
+
query: function(input, scope, query) {
|
1646
|
+
if (scope !== other.scope) {
|
1647
|
+
return false;
|
1648
|
+
}
|
1649
|
+
if (query !== other.query) {
|
1650
|
+
return false;
|
1651
|
+
}
|
1652
|
+
return input.equals(other.input);
|
1653
|
+
},
|
1654
|
+
"native": function(id) {
|
1655
|
+
return id === other.id;
|
1656
|
+
},
|
1657
|
+
param: function(name, constraints) {
|
1658
|
+
var constraint, i, _i, _len;
|
1659
|
+
if (name !== other.type) {
|
1660
|
+
return false;
|
1661
|
+
}
|
1662
|
+
for (i = _i = 0, _len = constraints.length; _i < _len; i = ++_i) {
|
1663
|
+
constraint = constraints[i];
|
1664
|
+
if (!constraint.equals(other.constraints[i])) {
|
1665
|
+
return false;
|
1666
|
+
}
|
1667
|
+
}
|
1668
|
+
return true;
|
1669
|
+
},
|
1670
|
+
destructure: function(constraint, name, argnum) {
|
1671
|
+
if (name !== other.type) {
|
1672
|
+
return false;
|
1673
|
+
}
|
1674
|
+
if (argnum !== other.argnum) {
|
1675
|
+
return false;
|
1676
|
+
}
|
1677
|
+
return constraint.equals(other.constraint);
|
1678
|
+
},
|
1679
|
+
other: function() {
|
1680
|
+
return _this === other;
|
1681
|
+
}
|
1682
|
+
});
|
1683
|
+
};
|
1684
|
+
|
1685
|
+
TypeExpr.fromAST = function(typeAST, scope) {
|
1686
|
+
var e, r;
|
1687
|
+
r = function(ast) {
|
1688
|
+
return TypeExpr.fromAST(ast, scope);
|
1689
|
+
};
|
1690
|
+
e = TypeExpr;
|
1691
|
+
return typeAST.cases({
|
1692
|
+
concrete: function(name) {
|
1693
|
+
if (typeof Type[name] !== 'function') {
|
1694
|
+
throw new Error("unknown type " + name);
|
1695
|
+
}
|
1696
|
+
return e.param(name, []);
|
1697
|
+
},
|
1698
|
+
variable: function(name) {
|
1699
|
+
return scope.cache(name, function() {
|
1700
|
+
return e.variable(name);
|
1701
|
+
});
|
1702
|
+
},
|
1703
|
+
"native": function(id) {
|
1704
|
+
return e["native"](id);
|
1705
|
+
},
|
1706
|
+
wildcard: function() {
|
1707
|
+
return e.any();
|
1708
|
+
},
|
1709
|
+
list: function(el) {
|
1710
|
+
return e.param('list', [r(el)]);
|
1711
|
+
},
|
1712
|
+
block: function(el) {
|
1713
|
+
return e.param('block', [r(el.from), r(el.to)]);
|
1714
|
+
},
|
1715
|
+
pair: function(first, second) {
|
1716
|
+
return e.param('pair', [r(first), r(second)]);
|
1717
|
+
}
|
1718
|
+
});
|
1719
|
+
};
|
1720
|
+
|
1721
|
+
TypeExpr.prototype.map = function(f) {
|
1722
|
+
return this.cases({
|
1723
|
+
param: function(name, params) {
|
1724
|
+
var p;
|
1725
|
+
return TypeExpr.param(name, (function() {
|
1726
|
+
var _i, _len, _results;
|
1727
|
+
_results = [];
|
1728
|
+
for (_i = 0, _len = params.length; _i < _len; _i++) {
|
1729
|
+
p = params[_i];
|
1730
|
+
_results.push(f(p));
|
1731
|
+
}
|
1732
|
+
return _results;
|
1733
|
+
})());
|
1734
|
+
},
|
1735
|
+
query: function(input, scope, query) {
|
1736
|
+
return TypeExpr.query(f(input), scope, query);
|
1737
|
+
},
|
1738
|
+
destructure: function(constraint, name, argnum) {
|
1739
|
+
return TypeExpr.destructure(f(constraint), name, argnum);
|
1740
|
+
},
|
1741
|
+
other: function() {
|
1742
|
+
return this;
|
1743
|
+
}
|
1744
|
+
});
|
1745
|
+
};
|
1746
|
+
|
1747
|
+
TypeExpr.prototype.mapAsync = function(f, cb) {
|
1748
|
+
return this.cases({
|
1749
|
+
param: function(name, params) {
|
1750
|
+
return asyncMap(params, f, function(ps) {
|
1751
|
+
return cb(TypeExpr.param(name, ps));
|
1752
|
+
});
|
1753
|
+
},
|
1754
|
+
query: function(input, scope, query) {
|
1755
|
+
return f(input, function(i) {
|
1756
|
+
return cb(TypeExpr.query(i, scope, query));
|
1757
|
+
});
|
1758
|
+
},
|
1759
|
+
destructure: function(param, name, argnum) {
|
1760
|
+
return f(param, function(p) {
|
1761
|
+
return cb(TypeExpr.destructure(p, name, argnum));
|
1762
|
+
});
|
1763
|
+
},
|
1764
|
+
other: function() {
|
1765
|
+
return cb(this);
|
1766
|
+
}
|
1767
|
+
});
|
1768
|
+
};
|
1769
|
+
|
1770
|
+
return TypeExpr;
|
1771
|
+
|
1772
|
+
})(Union);
|
1773
|
+
generate = (function() {
|
1774
|
+
var NativeContext, Scope;
|
1775
|
+
NativeContext = (function() {
|
1776
|
+
function NativeContext(globalID, externalLookup) {
|
1777
|
+
this.globalID = globalID;
|
1778
|
+
this.externalLookup = externalLookup;
|
1779
|
+
}
|
1780
|
+
|
1781
|
+
NativeContext.prototype.query = function(id, query, cb) {
|
1782
|
+
return this.externalLookup.call(null, id, query, TypeAST, function(err, analysis) {
|
1783
|
+
if (err) {
|
1784
|
+
throw err;
|
1785
|
+
}
|
1786
|
+
return cb(TypeLookup.response(analysis));
|
1787
|
+
});
|
1788
|
+
};
|
1789
|
+
|
1790
|
+
return NativeContext;
|
1791
|
+
|
1792
|
+
})();
|
1793
|
+
Scope = (function() {
|
1794
|
+
var makeKey;
|
1795
|
+
|
1796
|
+
Scope.global = function(context, frame) {
|
1797
|
+
return new Scope(null, [], frame, context);
|
1798
|
+
};
|
1799
|
+
|
1800
|
+
function Scope(parent, breadcrumbs, frame, context) {
|
1801
|
+
this.parent = parent;
|
1802
|
+
this.breadcrumbs = breadcrumbs;
|
1803
|
+
this.frame = frame;
|
1804
|
+
this.context = context;
|
1805
|
+
this.bindings = new Hash;
|
1806
|
+
}
|
1807
|
+
|
1808
|
+
Scope.prototype.extend = function(name, frame) {
|
1809
|
+
return new Scope(this, this.breadcrumbs.concat([name]), frame, this.context);
|
1810
|
+
};
|
1811
|
+
|
1812
|
+
Scope.prototype.lookup = function(nativeId, query, cb) {
|
1813
|
+
var lexical;
|
1814
|
+
if (query.type === 'access' && nativeId === this.context.globalID) {
|
1815
|
+
lexical = this.lexicalLookup(query.name);
|
1816
|
+
if (lexical) {
|
1817
|
+
return cb(lexical);
|
1818
|
+
} else {
|
1819
|
+
return this.context.query(nativeId, query, cb);
|
1820
|
+
}
|
1821
|
+
} else {
|
1822
|
+
return this.context.query(nativeId, query, cb);
|
1823
|
+
}
|
1824
|
+
};
|
1825
|
+
|
1826
|
+
Scope.prototype.lexicalLookup = function(name) {
|
1827
|
+
var local;
|
1828
|
+
local = this.lookupLocal(name);
|
1829
|
+
if (local) {
|
1830
|
+
return local;
|
1831
|
+
}
|
1832
|
+
if (this.parent) {
|
1833
|
+
return this.parent.lexicalLookup(name);
|
1834
|
+
}
|
1835
|
+
};
|
1836
|
+
|
1837
|
+
Scope.prototype.lookupLocal = function(name) {
|
1838
|
+
if (!this.bindings.has(name)) {
|
1839
|
+
return null;
|
1840
|
+
}
|
1841
|
+
return TypeLookup.local(this.keyFor(name));
|
1842
|
+
};
|
1843
|
+
|
1844
|
+
makeKey = function(crumbs) {
|
1845
|
+
return '/' + crumbs.join('/');
|
1846
|
+
};
|
1847
|
+
|
1848
|
+
Scope.prototype.key = function() {
|
1849
|
+
return makeKey(this.breadcrumbs);
|
1850
|
+
};
|
1851
|
+
|
1852
|
+
Scope.prototype.keyFor = function(name) {
|
1853
|
+
return makeKey(this.breadcrumbs.concat([name]));
|
1854
|
+
};
|
1855
|
+
|
1856
|
+
Scope.prototype.analyze = function(push) {
|
1857
|
+
var def, frame, frameScope, global, key, _i, _len, _ref4;
|
1858
|
+
_ref4 = this.frame.definitions;
|
1859
|
+
for (_i = 0, _len = _ref4.length; _i < _len; _i++) {
|
1860
|
+
def = _ref4[_i];
|
1861
|
+
frameScope = this.extend(def.name, def.frame);
|
1862
|
+
frameScope.analyze(push);
|
1863
|
+
this.bindings.set(def.name, frameScope);
|
1864
|
+
}
|
1865
|
+
key = this.key();
|
1866
|
+
global = TypeExpr["native"](this.context.globalID);
|
1867
|
+
frame = this.frame;
|
1868
|
+
return this.analyzeFlow(this.frame.flow, global, function(lhs, rhs) {
|
1869
|
+
return push(key, frame, [lhs, rhs]);
|
1870
|
+
});
|
1871
|
+
};
|
1872
|
+
|
1873
|
+
Scope.prototype.analyzeFlow = function(flow, global, push) {
|
1874
|
+
var _this = this;
|
1875
|
+
if (flow.tail) {
|
1876
|
+
this.analyzeFlow(flow.tail, global, push);
|
1877
|
+
}
|
1878
|
+
return flow.head.cases({
|
1879
|
+
query: function() {
|
1880
|
+
var input;
|
1881
|
+
input = flow.tail ? TypeExpr.expr(flow.tail) : global;
|
1882
|
+
return push(TypeExpr.expr(flow), TypeExpr.query(input, _this, flow.head));
|
1883
|
+
},
|
1884
|
+
pair: function(first, second) {
|
1885
|
+
_this.analyzeFlow(first, global, push);
|
1886
|
+
_this.analyzeFlow(second, global, push);
|
1887
|
+
return push(TypeExpr.expr(flow), TypeExpr.param('pair', [TypeExpr.expr(first), TypeExpr.expr(second)]));
|
1888
|
+
},
|
1889
|
+
func: function(name, args) {
|
1890
|
+
var arg, ast, func, i, input, scope, _i, _len, _results;
|
1891
|
+
func = stdlib[name];
|
1892
|
+
ast = func.type;
|
1893
|
+
scope = new Hash;
|
1894
|
+
input = TypeExpr.fromAST(ast.input, scope);
|
1895
|
+
if (flow.tail) {
|
1896
|
+
push(TypeExpr.expr(flow.tail), input);
|
1897
|
+
} else {
|
1898
|
+
push(input, global);
|
1899
|
+
}
|
1900
|
+
push(TypeExpr.expr(flow), TypeExpr.fromAST(ast.output, scope));
|
1901
|
+
_results = [];
|
1902
|
+
for (i = _i = 0, _len = args.length; _i < _len; i = ++_i) {
|
1903
|
+
arg = args[i];
|
1904
|
+
push(TypeExpr.expr(arg), TypeExpr.fromAST(ast.args[i], scope));
|
1905
|
+
_results.push(_this.analyzeFlow(arg, global, push));
|
1906
|
+
}
|
1907
|
+
return _results;
|
1908
|
+
},
|
1909
|
+
integer: function() {
|
1910
|
+
return push(TypeExpr.expr(flow), TypeExpr.param('numeric', []));
|
1911
|
+
},
|
1912
|
+
decimal: function() {
|
1913
|
+
return push(TypeExpr.expr(flow), TypeExpr.param('numeric', []));
|
1914
|
+
},
|
1915
|
+
string: function() {
|
1916
|
+
return push(TypeExpr.expr(flow), TypeExpr.param('string', []));
|
1917
|
+
},
|
1918
|
+
subst: function(subFlow) {
|
1919
|
+
push(TypeExpr.expr(flow), TypeExpr.expr(subFlow));
|
1920
|
+
return _this.analyzeFlow(flow, global, push);
|
1921
|
+
},
|
1922
|
+
list: function(elements) {
|
1923
|
+
var el, expected, rest, _i, _len, _results;
|
1924
|
+
if (elements.length === 0) {
|
1925
|
+
push(TypeExpr.expr(flow), TypeExpr.param('list', [TypeExpr.variable('el')]));
|
1926
|
+
return;
|
1927
|
+
}
|
1928
|
+
expected = elements[0], rest = 2 <= elements.length ? __slice.call(elements, 1) : [];
|
1929
|
+
push(TypeExpr.expr(flow), TypeExpr.param('list', [TypeExpr.expr(expected)]));
|
1930
|
+
_this.analyzeFlow(expected, global, push);
|
1931
|
+
_results = [];
|
1932
|
+
for (_i = 0, _len = rest.length; _i < _len; _i++) {
|
1933
|
+
el = rest[_i];
|
1934
|
+
_this.analyzeFlow(el, global, push);
|
1935
|
+
_results.push(push(TypeExpr.expr(el), TypeExpr.expr(expected)));
|
1936
|
+
}
|
1937
|
+
return _results;
|
1938
|
+
},
|
1939
|
+
block: function(subFlow) {
|
1940
|
+
var input;
|
1941
|
+
input = TypeExpr.variable('.input');
|
1942
|
+
push(TypeExpr.expr(flow), TypeExpr.param('block', [input, TypeExpr.expr(subFlow)]));
|
1943
|
+
return _this.analyzeFlow(subFlow, input, push);
|
1944
|
+
}
|
1945
|
+
});
|
1946
|
+
};
|
1947
|
+
|
1948
|
+
return Scope;
|
1949
|
+
|
1950
|
+
})();
|
1951
|
+
return function(globalID, externalLookup, program) {
|
1952
|
+
var constraintMap, context, scope;
|
1953
|
+
context = new NativeContext(globalID, externalLookup);
|
1954
|
+
scope = Scope.global(context, program);
|
1955
|
+
constraintMap = new Hash;
|
1956
|
+
scope.analyze(function(key, frame, constraint) {
|
1957
|
+
var entry;
|
1958
|
+
entry = constraintMap.cache(key, function() {
|
1959
|
+
return {
|
1960
|
+
frame: frame,
|
1961
|
+
constraints: []
|
1962
|
+
};
|
1963
|
+
});
|
1964
|
+
return entry.constraints.push(constraint);
|
1965
|
+
});
|
1966
|
+
return constraintMap;
|
1967
|
+
};
|
1968
|
+
})();
|
1969
|
+
solve = (function() {
|
1970
|
+
var TypeError, consume, _ref4;
|
1971
|
+
TypeError = (function(_super) {
|
1972
|
+
__extends(TypeError, _super);
|
1973
|
+
|
1974
|
+
function TypeError() {
|
1975
|
+
_ref4 = TypeError.__super__.constructor.apply(this, arguments);
|
1976
|
+
return _ref4;
|
1977
|
+
}
|
1978
|
+
|
1979
|
+
TypeError.types({
|
1980
|
+
match: ['lhs', 'rhs'],
|
1981
|
+
infinite: ['type'],
|
1982
|
+
destructure: ['type'],
|
1983
|
+
access: ['type'],
|
1984
|
+
circular: ['crumbs']
|
1985
|
+
});
|
1986
|
+
|
1987
|
+
return TypeError;
|
1988
|
+
|
1989
|
+
})(Union);
|
1990
|
+
DEBUG.logConstraint = function(prefix, lhs, rhs) {
|
1991
|
+
return console.log(prefix, lhs.inspect(), '=', rhs.inspect());
|
1992
|
+
};
|
1993
|
+
consume = function(array, next, body) {
|
1994
|
+
var loop_, push;
|
1995
|
+
push = function(x, y) {
|
1996
|
+
return array.push([x, y]);
|
1997
|
+
};
|
1998
|
+
loop_ = function() {
|
1999
|
+
var lhs, rhs, _ref5;
|
2000
|
+
if (!(array.length > 0)) {
|
2001
|
+
return next();
|
2002
|
+
}
|
2003
|
+
_ref5 = array.pop(), lhs = _ref5[0], rhs = _ref5[1];
|
2004
|
+
return body(lhs, rhs, push, loop_);
|
2005
|
+
};
|
2006
|
+
return loop_();
|
2007
|
+
};
|
2008
|
+
return function(constraintMap, finish) {
|
2009
|
+
var errors, frameTypes, initialCrumbs, k, locks, semantics, solutions, solveEntry;
|
2010
|
+
errors = [];
|
2011
|
+
solutions = new CompMap(function(x, y) {
|
2012
|
+
return x.equals(y);
|
2013
|
+
});
|
2014
|
+
semantics = new Hash;
|
2015
|
+
frameTypes = new Hash;
|
2016
|
+
locks = new Hash;
|
2017
|
+
solveEntry = function(crumbs, solved) {
|
2018
|
+
var constraints, dependencies, done, error, frame, fullSubstitute, key, nextCrumbs, semanticAccessors, simplify, substitute, _ref5;
|
2019
|
+
key = crumbs[crumbs.length - 1];
|
2020
|
+
if (semantics.has(key)) {
|
2021
|
+
return solved();
|
2022
|
+
}
|
2023
|
+
nextCrumbs = crumbs.concat([key]);
|
2024
|
+
_ref5 = constraintMap.get(key), frame = _ref5.frame, constraints = _ref5.constraints;
|
2025
|
+
DEBUG.log('locking', key);
|
2026
|
+
locks.set(key, true);
|
2027
|
+
semanticAccessors = new CompMap;
|
2028
|
+
dependencies = [];
|
2029
|
+
DEBUG(function() {
|
2030
|
+
var lhs, rhs, _i, _len, _ref6, _results;
|
2031
|
+
_results = [];
|
2032
|
+
for (_i = 0, _len = constraints.length; _i < _len; _i++) {
|
2033
|
+
_ref6 = constraints[_i], lhs = _ref6[0], rhs = _ref6[1];
|
2034
|
+
_results.push(DEBUG.logConstraint('-> ', lhs, rhs));
|
2035
|
+
}
|
2036
|
+
return _results;
|
2037
|
+
});
|
2038
|
+
substitute = function(texpr, cb) {
|
2039
|
+
return solutions.fetchAsync(texpr, (function() {
|
2040
|
+
return texpr.mapAsync(substitute, cb);
|
2041
|
+
}), cb);
|
2042
|
+
};
|
2043
|
+
fullSubstitute = function(texpr, cb) {
|
2044
|
+
return substitute(texpr, function(substituted) {
|
2045
|
+
return simplify(substituted, function(result) {
|
2046
|
+
DEBUG(function() {
|
2047
|
+
if (!texpr.equals(result)) {
|
2048
|
+
return DEBUG.logConstraint('%> ', texpr, result);
|
2049
|
+
}
|
2050
|
+
});
|
2051
|
+
return cb(result);
|
2052
|
+
});
|
2053
|
+
});
|
2054
|
+
};
|
2055
|
+
error = function() {
|
2056
|
+
var args, type;
|
2057
|
+
type = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
|
2058
|
+
errors.push(TypeError[type].apply(TypeError, args));
|
2059
|
+
return TypeExpr.any();
|
2060
|
+
};
|
2061
|
+
simplify = function(expr, cb) {
|
2062
|
+
return expr.cases({
|
2063
|
+
destructure: function(constraint, name, argnum) {
|
2064
|
+
var destructured;
|
2065
|
+
destructured = this;
|
2066
|
+
return simplify(constraint, function(x) {
|
2067
|
+
return cb(x.cases({
|
2068
|
+
param: function(paramName, paramArgs) {
|
2069
|
+
if (paramName === name) {
|
2070
|
+
return paramArgs[argnum];
|
2071
|
+
} else {
|
2072
|
+
return error('destructure', this);
|
2073
|
+
}
|
2074
|
+
},
|
2075
|
+
other: function() {
|
2076
|
+
return error('destructure', this);
|
2077
|
+
}
|
2078
|
+
}));
|
2079
|
+
});
|
2080
|
+
},
|
2081
|
+
query: function(input, scope, query) {
|
2082
|
+
return simplify(input, function(x) {
|
2083
|
+
return x.cases({
|
2084
|
+
"native": function(id) {
|
2085
|
+
return scope.lookup(id, query, function(lookup) {
|
2086
|
+
dependencies.push(lookup);
|
2087
|
+
return lookup.cases({
|
2088
|
+
response: function(analysis) {
|
2089
|
+
semanticAccessors.set(query, Semantic.query(analysis.annotations));
|
2090
|
+
return cb(TypeExpr.fromAST(analysis.type));
|
2091
|
+
},
|
2092
|
+
local: function(key) {
|
2093
|
+
var localFrame;
|
2094
|
+
nextCrumbs = crumbs.concat([key]);
|
2095
|
+
semanticAccessors.set(query, Semantic.localAccessor(key));
|
2096
|
+
if (locks.get(key)) {
|
2097
|
+
return cb(error('circular', nextCrumbs));
|
2098
|
+
}
|
2099
|
+
localFrame = constraintMap.get(key).frame;
|
2100
|
+
return solveEntry(nextCrumbs, function() {
|
2101
|
+
return cb(frameTypes.get(key));
|
2102
|
+
});
|
2103
|
+
}
|
2104
|
+
});
|
2105
|
+
});
|
2106
|
+
},
|
2107
|
+
other: function() {
|
2108
|
+
return cb(expr);
|
2109
|
+
}
|
2110
|
+
});
|
2111
|
+
});
|
2112
|
+
},
|
2113
|
+
other: function() {
|
2114
|
+
return this.mapAsync(simplify, cb);
|
2115
|
+
}
|
2116
|
+
});
|
2117
|
+
};
|
2118
|
+
done = function() {
|
2119
|
+
var flowType, toSemanticTree;
|
2120
|
+
flowType = function(expr) {
|
2121
|
+
if (!solutions.has(TypeExpr.expr(expr))) {
|
2122
|
+
throw 'unsolved!';
|
2123
|
+
}
|
2124
|
+
return solutions.get(TypeExpr.expr(expr)).realize();
|
2125
|
+
};
|
2126
|
+
toSemanticTree = function(expr) {
|
2127
|
+
return expr.cases({
|
2128
|
+
frame: function(_, flow) {
|
2129
|
+
return Semantic.definition(dependencies, toSemanticTree(flow));
|
2130
|
+
},
|
2131
|
+
flow: function(head, tail) {
|
2132
|
+
return Semantic.flow(flowType(this), toSemanticTree(head), tail && toSemanticTree(tail));
|
2133
|
+
},
|
2134
|
+
query: function(type, name) {
|
2135
|
+
DEBUG(function() {
|
2136
|
+
if (!semanticAccessors.has(this)) {
|
2137
|
+
debugger;
|
2138
|
+
}
|
2139
|
+
});
|
2140
|
+
return semanticAccessors.get(this);
|
2141
|
+
},
|
2142
|
+
func: function(name, args) {
|
2143
|
+
var a;
|
2144
|
+
return Semantic.func(name, (function() {
|
2145
|
+
var _i, _len, _results;
|
2146
|
+
_results = [];
|
2147
|
+
for (_i = 0, _len = args.length; _i < _len; _i++) {
|
2148
|
+
a = args[_i];
|
2149
|
+
_results.push(toSemanticTree(a));
|
2150
|
+
}
|
2151
|
+
return _results;
|
2152
|
+
})());
|
2153
|
+
},
|
2154
|
+
pair: function(first, second) {
|
2155
|
+
return Semantic.pair(toSemanticTree(first), toSemanticTree(second));
|
2156
|
+
},
|
2157
|
+
block: function(flow) {
|
2158
|
+
return Semantic.block(toSemanticTree(flow));
|
2159
|
+
},
|
2160
|
+
list: function(elements) {
|
2161
|
+
var e;
|
2162
|
+
return Semantic.list((function() {
|
2163
|
+
var _i, _len, _results;
|
2164
|
+
_results = [];
|
2165
|
+
for (_i = 0, _len = elements.length; _i < _len; _i++) {
|
2166
|
+
e = elements[_i];
|
2167
|
+
_results.push(toSemanticTree(e));
|
2168
|
+
}
|
2169
|
+
return _results;
|
2170
|
+
})());
|
2171
|
+
},
|
2172
|
+
integer: function() {
|
2173
|
+
return Semantic.literal(this);
|
2174
|
+
},
|
2175
|
+
decimal: function() {
|
2176
|
+
return Semantic.literal(this);
|
2177
|
+
},
|
2178
|
+
percent: function() {
|
2179
|
+
return Semantic.literal(this);
|
2180
|
+
},
|
2181
|
+
fraction: function() {
|
2182
|
+
return Semantic.literal(this);
|
2183
|
+
},
|
2184
|
+
string: function() {
|
2185
|
+
return Semantic.literal(this);
|
2186
|
+
}
|
2187
|
+
});
|
2188
|
+
};
|
2189
|
+
DEBUG(function() {
|
2190
|
+
return solutions.each(function(k, v) {
|
2191
|
+
return DEBUG.logConstraint('=> ', k, v);
|
2192
|
+
});
|
2193
|
+
});
|
2194
|
+
DEBUG.log('setting key: ' + key);
|
2195
|
+
semantics.set(key, toSemanticTree(frame));
|
2196
|
+
frameTypes.set(key, solutions.get(TypeExpr.expr(frame.flow)));
|
2197
|
+
DEBUG.log('unlocking', key);
|
2198
|
+
locks.set(key, false);
|
2199
|
+
return solved();
|
2200
|
+
};
|
2201
|
+
return consume(constraints.reverse(), done, function(lhs, rhs, push, next) {
|
2202
|
+
var log, matchError, skip, solveFor, swap;
|
2203
|
+
DEBUG.logConstraint(':> ', lhs, rhs);
|
2204
|
+
if (lhs.equals(rhs)) {
|
2205
|
+
return next();
|
2206
|
+
}
|
2207
|
+
solveFor = function() {
|
2208
|
+
return fullSubstitute(rhs, function(rhs) {
|
2209
|
+
var mapper;
|
2210
|
+
if (solutions.has(lhs)) {
|
2211
|
+
push(solutions.get(lhs), rhs);
|
2212
|
+
return next();
|
2213
|
+
} else {
|
2214
|
+
DEBUG.logConstraint('>> ', lhs, rhs);
|
2215
|
+
solutions.set(lhs, rhs);
|
2216
|
+
mapper = function(k, texpr, cb) {
|
2217
|
+
return fullSubstitute(texpr, (function(s) {
|
2218
|
+
solutions.set(k, s);
|
2219
|
+
return cb();
|
2220
|
+
}));
|
2221
|
+
};
|
2222
|
+
return solutions.eachAsync(mapper, next);
|
2223
|
+
}
|
2224
|
+
});
|
2225
|
+
};
|
2226
|
+
log = function() {
|
2227
|
+
DEBUG.logConstraint('?> ', lhs, rhs);
|
2228
|
+
return next();
|
2229
|
+
};
|
2230
|
+
skip = function() {
|
2231
|
+
return next();
|
2232
|
+
};
|
2233
|
+
swap = function() {
|
2234
|
+
push(rhs, lhs);
|
2235
|
+
return next();
|
2236
|
+
};
|
2237
|
+
matchError = function() {
|
2238
|
+
error('match', lhs, rhs);
|
2239
|
+
return next();
|
2240
|
+
};
|
2241
|
+
return lhs.cases({
|
2242
|
+
expr: solveFor,
|
2243
|
+
variable: solveFor,
|
2244
|
+
any: skip,
|
2245
|
+
query: function() {
|
2246
|
+
return rhs.cases({
|
2247
|
+
expr: swap,
|
2248
|
+
variable: swap,
|
2249
|
+
param: swap,
|
2250
|
+
other: log
|
2251
|
+
});
|
2252
|
+
},
|
2253
|
+
"native": function(id) {
|
2254
|
+
return rhs.cases({
|
2255
|
+
variable: swap,
|
2256
|
+
expr: swap,
|
2257
|
+
"native": function(otherId) {
|
2258
|
+
if (id === otherId) {
|
2259
|
+
return skip();
|
2260
|
+
} else {
|
2261
|
+
return matchError();
|
2262
|
+
}
|
2263
|
+
},
|
2264
|
+
other: matchError
|
2265
|
+
});
|
2266
|
+
},
|
2267
|
+
param: function() {
|
2268
|
+
return rhs.cases({
|
2269
|
+
param: function() {
|
2270
|
+
var constraint, i, _i, _len, _ref6;
|
2271
|
+
if (lhs.name !== rhs.name) {
|
2272
|
+
return matchError();
|
2273
|
+
}
|
2274
|
+
_ref6 = lhs.constraints;
|
2275
|
+
for (i = _i = 0, _len = _ref6.length; _i < _len; i = ++_i) {
|
2276
|
+
constraint = _ref6[i];
|
2277
|
+
push(constraint, rhs.constraints[i]);
|
2278
|
+
}
|
2279
|
+
return next();
|
2280
|
+
},
|
2281
|
+
query: function() {
|
2282
|
+
var c, i, _i, _len, _ref6;
|
2283
|
+
_ref6 = lhs.constraints;
|
2284
|
+
for (i = _i = 0, _len = _ref6.length; _i < _len; i = ++_i) {
|
2285
|
+
c = _ref6[i];
|
2286
|
+
push(c, TypeExpr.destructure(rhs, lhs.type(i)));
|
2287
|
+
}
|
2288
|
+
return next();
|
2289
|
+
},
|
2290
|
+
expr: swap,
|
2291
|
+
variable: swap,
|
2292
|
+
other: matchError
|
2293
|
+
});
|
2294
|
+
},
|
2295
|
+
other: log
|
2296
|
+
});
|
2297
|
+
});
|
2298
|
+
};
|
2299
|
+
initialCrumbs = (function() {
|
2300
|
+
var _i, _len, _ref5, _results;
|
2301
|
+
_ref5 = constraintMap.keys();
|
2302
|
+
_results = [];
|
2303
|
+
for (_i = 0, _len = _ref5.length; _i < _len; _i++) {
|
2304
|
+
k = _ref5[_i];
|
2305
|
+
_results.push([k]);
|
2306
|
+
}
|
2307
|
+
return _results;
|
2308
|
+
})();
|
2309
|
+
DEBUG.log('initial crumbs', initialCrumbs);
|
2310
|
+
return contMap(initialCrumbs, solveEntry, function() {
|
2311
|
+
if (errors.length === 0) {
|
2312
|
+
errors = null;
|
2313
|
+
}
|
2314
|
+
return finish(errors, semantics);
|
2315
|
+
});
|
2316
|
+
};
|
2317
|
+
})();
|
2318
|
+
return function(program, globalID, external, cb) {
|
2319
|
+
var constraints;
|
2320
|
+
if (!(program instanceof AST)) {
|
2321
|
+
program = AST.fromJSON(program);
|
2322
|
+
}
|
2323
|
+
DEBUG.log();
|
2324
|
+
DEBUG.log(program.inspect());
|
2325
|
+
constraints = generate(globalID, external.analyzeQuery, program);
|
2326
|
+
return solve(constraints, cb);
|
2327
|
+
};
|
2328
|
+
})();
|
2329
|
+
// Generated by CoffeeScript 1.6.3
|
2330
|
+
var Dependency, Promise, Value, eval_, _ref, _ref1,
|
2331
|
+
__hasProp = {}.hasOwnProperty,
|
2332
|
+
__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; },
|
2333
|
+
__slice = [].slice;
|
2334
|
+
|
2335
|
+
Value = Gibbon.Value = Value = (function(_super) {
|
2336
|
+
var thunksAreEqual;
|
2337
|
+
|
2338
|
+
__extends(Value, _super);
|
2339
|
+
|
2340
|
+
function Value() {
|
2341
|
+
_ref = Value.__super__.constructor.apply(this, arguments);
|
2342
|
+
return _ref;
|
2343
|
+
}
|
2344
|
+
|
2345
|
+
Value.types({
|
2346
|
+
string: ['value'],
|
2347
|
+
number: ['value'],
|
2348
|
+
boolean: ['value'],
|
2349
|
+
block: ['fn'],
|
2350
|
+
list: ['elements'],
|
2351
|
+
pair: ['first', 'second'],
|
2352
|
+
entity: ['type', 'id']
|
2353
|
+
});
|
2354
|
+
|
2355
|
+
Value.fromJSON = function(o) {
|
2356
|
+
var e;
|
2357
|
+
if (typeof o === 'boolean') {
|
2358
|
+
return Value.boolean(o);
|
2359
|
+
}
|
2360
|
+
if (typeof o === 'number') {
|
2361
|
+
return Value.number(o);
|
2362
|
+
}
|
2363
|
+
if (typeof o === 'string') {
|
2364
|
+
return Value.string(o);
|
2365
|
+
}
|
2366
|
+
if (isArray(o)) {
|
2367
|
+
return Value.list((function() {
|
2368
|
+
var _i, _len, _results;
|
2369
|
+
_results = [];
|
2370
|
+
for (_i = 0, _len = o.length; _i < _len; _i++) {
|
2371
|
+
e = o[_i];
|
2372
|
+
_results.push(Value.fromJSON(e));
|
2373
|
+
}
|
2374
|
+
return _results;
|
2375
|
+
})());
|
2376
|
+
}
|
2377
|
+
switch (o._tag) {
|
2378
|
+
case 'entity':
|
2379
|
+
return Value.entity(o.type, o.id);
|
2380
|
+
case 'pair':
|
2381
|
+
return Value.pair(o.first, o.second);
|
2382
|
+
}
|
2383
|
+
throw new Error('invalid value: ' + o);
|
2384
|
+
};
|
2385
|
+
|
2386
|
+
Value.prototype.promise = function() {
|
2387
|
+
return Promise.unit(this.map(function(x) {
|
2388
|
+
return x.promise();
|
2389
|
+
}));
|
2390
|
+
};
|
2391
|
+
|
2392
|
+
thunksAreEqual = function(list1, list2) {
|
2393
|
+
var i, out, step, x, zipped;
|
2394
|
+
if (list1.length !== list2.length) {
|
2395
|
+
return Promise.unit(Value.boolean(false));
|
2396
|
+
}
|
2397
|
+
zipped = (function() {
|
2398
|
+
var _i, _len, _results;
|
2399
|
+
_results = [];
|
2400
|
+
for (i = _i = 0, _len = list1.length; _i < _len; i = ++_i) {
|
2401
|
+
x = list1[i];
|
2402
|
+
_results.push(Promise.combine(x, list2[i]));
|
2403
|
+
}
|
2404
|
+
return _results;
|
2405
|
+
})();
|
2406
|
+
step = function(_arg, next) {
|
2407
|
+
var x, y;
|
2408
|
+
x = _arg[0], y = _arg[1];
|
2409
|
+
return x.equals(y).then(function(isEqual) {
|
2410
|
+
if (isEqual.value) {
|
2411
|
+
return next();
|
2412
|
+
} else {
|
2413
|
+
return Promise.unit(Value.boolean(false));
|
2414
|
+
}
|
2415
|
+
});
|
2416
|
+
};
|
2417
|
+
out = function() {
|
2418
|
+
return Promise.unit(Value.boolean(true));
|
2419
|
+
};
|
2420
|
+
return Promise.iter(zipped, step, out);
|
2421
|
+
};
|
2422
|
+
|
2423
|
+
Value.prototype.equals = function(other) {
|
2424
|
+
var wrap;
|
2425
|
+
wrap = function(b) {
|
2426
|
+
return Promise.unit(Value.boolean(b));
|
2427
|
+
};
|
2428
|
+
return this.cases({
|
2429
|
+
string: function(val) {
|
2430
|
+
return wrap(val === other.value);
|
2431
|
+
},
|
2432
|
+
number: function(val) {
|
2433
|
+
return wrap(val === other.value);
|
2434
|
+
},
|
2435
|
+
boolean: function(val) {
|
2436
|
+
return wrap(val === other.value);
|
2437
|
+
},
|
2438
|
+
block: function() {
|
2439
|
+
return wrap(false);
|
2440
|
+
},
|
2441
|
+
list: function(els) {
|
2442
|
+
return thunksAreEqual(els, other.elements);
|
2443
|
+
},
|
2444
|
+
pair: function(evalFirst, evalSecond) {
|
2445
|
+
return thunksAreEqual([evalFirst, evalSecond], [other.first, other.second]);
|
2446
|
+
}
|
2447
|
+
});
|
2448
|
+
};
|
2449
|
+
|
2450
|
+
Value.prototype.map = function(f) {
|
2451
|
+
return this.cases({
|
2452
|
+
list: function(els) {
|
2453
|
+
var x;
|
2454
|
+
return Value.list((function() {
|
2455
|
+
var _i, _len, _results;
|
2456
|
+
_results = [];
|
2457
|
+
for (_i = 0, _len = els.length; _i < _len; _i++) {
|
2458
|
+
x = els[_i];
|
2459
|
+
_results.push(f(x));
|
2460
|
+
}
|
2461
|
+
return _results;
|
2462
|
+
})());
|
2463
|
+
},
|
2464
|
+
pair: function(first, second) {
|
2465
|
+
return Value.pair(f(first), f(second));
|
2466
|
+
},
|
2467
|
+
other: function() {
|
2468
|
+
return this;
|
2469
|
+
}
|
2470
|
+
});
|
2471
|
+
};
|
2472
|
+
|
2473
|
+
Value.prototype.mapAsync = function(f, cb) {
|
2474
|
+
return this.cases({
|
2475
|
+
list: function(els) {
|
2476
|
+
return asyncMap(els, f, function(mapped) {
|
2477
|
+
return Value.list(mapped);
|
2478
|
+
});
|
2479
|
+
},
|
2480
|
+
pair: function(first, second) {
|
2481
|
+
return asyncMap([first, second], f, function(_arg) {
|
2482
|
+
var first, second;
|
2483
|
+
first = _arg[0], second = _arg[1];
|
2484
|
+
return Value.pair(first, second);
|
2485
|
+
});
|
2486
|
+
},
|
2487
|
+
other: function() {
|
2488
|
+
return cb(this);
|
2489
|
+
}
|
2490
|
+
});
|
2491
|
+
};
|
2492
|
+
|
2493
|
+
Value.prototype.mapPromise = function(f) {
|
2494
|
+
return this.cases({
|
2495
|
+
list: function(promises) {
|
2496
|
+
return Promise.combine(promises).then(function(els) {
|
2497
|
+
var el;
|
2498
|
+
return Promise.combine((function() {
|
2499
|
+
var _i, _len, _results;
|
2500
|
+
_results = [];
|
2501
|
+
for (_i = 0, _len = els.length; _i < _len; _i++) {
|
2502
|
+
el = els[_i];
|
2503
|
+
_results.push(f(el));
|
2504
|
+
}
|
2505
|
+
return _results;
|
2506
|
+
})()).map(function(els) {
|
2507
|
+
return Value.list(els);
|
2508
|
+
});
|
2509
|
+
});
|
2510
|
+
},
|
2511
|
+
pair: function(eFirst, eSecond) {
|
2512
|
+
return Promise.combine([eFirst, eSecond]).then(function(first, second) {
|
2513
|
+
return Promise.combine([f(first), f(second)]).map(function(_arg) {
|
2514
|
+
var mFirst, mSecond;
|
2515
|
+
mFirst = _arg[0], mSecond = _arg[1];
|
2516
|
+
return Value.pair(mFirst, mSecond);
|
2517
|
+
});
|
2518
|
+
});
|
2519
|
+
},
|
2520
|
+
other: function() {
|
2521
|
+
return Promise.unit(this);
|
2522
|
+
}
|
2523
|
+
});
|
2524
|
+
};
|
2525
|
+
|
2526
|
+
Value.prototype.resolve = function() {
|
2527
|
+
return this.mapPromise(function(x) {
|
2528
|
+
return x.resolve();
|
2529
|
+
});
|
2530
|
+
};
|
2531
|
+
|
2532
|
+
return Value;
|
2533
|
+
|
2534
|
+
})(Union);
|
2535
|
+
|
2536
|
+
Promise = (function() {
|
2537
|
+
function Promise(fn) {
|
2538
|
+
this.fn = fn;
|
2539
|
+
}
|
2540
|
+
|
2541
|
+
Promise.prototype.force = function(failure, success) {
|
2542
|
+
var onFailure, onSuccess,
|
2543
|
+
_this = this;
|
2544
|
+
if (this.result === true) {
|
2545
|
+
return success(this.value, this.dependencies);
|
2546
|
+
}
|
2547
|
+
if (this.result === false) {
|
2548
|
+
return failure(this.value);
|
2549
|
+
}
|
2550
|
+
onSuccess = function(val, deps) {
|
2551
|
+
_this.result = true;
|
2552
|
+
_this.value = val;
|
2553
|
+
_this.dependencies = deps;
|
2554
|
+
return success(val, deps);
|
2555
|
+
};
|
2556
|
+
onFailure = function(fail) {
|
2557
|
+
_this.result = false;
|
2558
|
+
_this.value = fail;
|
2559
|
+
return failure(fail);
|
2560
|
+
};
|
2561
|
+
return this.fn.call(null, onFailure, onSuccess);
|
2562
|
+
};
|
2563
|
+
|
2564
|
+
Promise.prototype.then = function(fn) {
|
2565
|
+
var _this = this;
|
2566
|
+
return new Promise(function(fail, cb) {
|
2567
|
+
return _this.force(fail, function(val, deps) {
|
2568
|
+
return fn(val, deps).depends(deps).force(fail, cb);
|
2569
|
+
});
|
2570
|
+
});
|
2571
|
+
};
|
2572
|
+
|
2573
|
+
Promise.prototype.depends = function(deps) {
|
2574
|
+
var _this = this;
|
2575
|
+
return new Promise(function(fail, cc) {
|
2576
|
+
return _this.force(fail, function(val, prevDeps) {
|
2577
|
+
return cc(val, prevDeps.concat(deps));
|
2578
|
+
});
|
2579
|
+
});
|
2580
|
+
};
|
2581
|
+
|
2582
|
+
Promise.prototype.map = function(f) {
|
2583
|
+
return this.then(function(v, d) {
|
2584
|
+
return Promise.unit(f(v, d));
|
2585
|
+
});
|
2586
|
+
};
|
2587
|
+
|
2588
|
+
Promise.prototype.mapDependencies = function(f) {
|
2589
|
+
var _this = this;
|
2590
|
+
return new Promise(function(fail, cc) {
|
2591
|
+
return _this.force(fail, function(val, deps) {
|
2592
|
+
return cc(val, f(deps));
|
2593
|
+
});
|
2594
|
+
});
|
2595
|
+
};
|
2596
|
+
|
2597
|
+
Promise.prototype.after = function(f) {
|
2598
|
+
var _this = this;
|
2599
|
+
return new Promise(function(fail, cc) {
|
2600
|
+
return _this.force(fail, function(val, deps) {
|
2601
|
+
f(val, deps);
|
2602
|
+
return cc(val, deps);
|
2603
|
+
});
|
2604
|
+
});
|
2605
|
+
};
|
2606
|
+
|
2607
|
+
Promise.unit = function(e) {
|
2608
|
+
if (!(e instanceof Gibbon.Value)) {
|
2609
|
+
throw new Error('only make thunks of Value for now');
|
2610
|
+
}
|
2611
|
+
return new Promise(function(_, f) {
|
2612
|
+
return f(e, []);
|
2613
|
+
});
|
2614
|
+
};
|
2615
|
+
|
2616
|
+
Promise.fail = function(fail) {
|
2617
|
+
return new Promise(function(f, _) {
|
2618
|
+
return f(fail);
|
2619
|
+
});
|
2620
|
+
};
|
2621
|
+
|
2622
|
+
Promise.lazy = function(f) {
|
2623
|
+
return new Promise(function(fail, cc) {
|
2624
|
+
return f().force(fail, cc);
|
2625
|
+
});
|
2626
|
+
};
|
2627
|
+
|
2628
|
+
Promise.combine = function(thunks) {
|
2629
|
+
return new Promise(function(fail, cb) {
|
2630
|
+
var mapper;
|
2631
|
+
mapper = function(thunk, push) {
|
2632
|
+
return thunk.force(fail, function(val, deps) {
|
2633
|
+
return push([val, deps]);
|
2634
|
+
});
|
2635
|
+
};
|
2636
|
+
return asyncMap(thunks, mapper, function(vals) {
|
2637
|
+
var outDeps, outVal, v;
|
2638
|
+
outVal = (function() {
|
2639
|
+
var _i, _len, _results;
|
2640
|
+
_results = [];
|
2641
|
+
for (_i = 0, _len = vals.length; _i < _len; _i++) {
|
2642
|
+
v = vals[_i];
|
2643
|
+
_results.push(v[0]);
|
2644
|
+
}
|
2645
|
+
return _results;
|
2646
|
+
})();
|
2647
|
+
outDeps = catLists((function() {
|
2648
|
+
var _i, _len, _results;
|
2649
|
+
_results = [];
|
2650
|
+
for (_i = 0, _len = vals.length; _i < _len; _i++) {
|
2651
|
+
v = vals[_i];
|
2652
|
+
_results.push(v[1]);
|
2653
|
+
}
|
2654
|
+
return _results;
|
2655
|
+
})());
|
2656
|
+
return cb(outVal, outDeps);
|
2657
|
+
});
|
2658
|
+
});
|
2659
|
+
};
|
2660
|
+
|
2661
|
+
Promise.iter = function(list, step, out) {
|
2662
|
+
var _loop;
|
2663
|
+
_loop = function(i) {
|
2664
|
+
if (i >= list.length) {
|
2665
|
+
return out();
|
2666
|
+
}
|
2667
|
+
return list[i].then(function(val) {
|
2668
|
+
return step(val, function() {
|
2669
|
+
return _loop(i + 1);
|
2670
|
+
});
|
2671
|
+
});
|
2672
|
+
};
|
2673
|
+
return _loop(0);
|
2674
|
+
};
|
2675
|
+
|
2676
|
+
return Promise;
|
2677
|
+
|
2678
|
+
})();
|
2679
|
+
|
2680
|
+
Dependency = (function(_super) {
|
2681
|
+
__extends(Dependency, _super);
|
2682
|
+
|
2683
|
+
function Dependency() {
|
2684
|
+
_ref1 = Dependency.__super__.constructor.apply(this, arguments);
|
2685
|
+
return _ref1;
|
2686
|
+
}
|
2687
|
+
|
2688
|
+
Dependency.types({
|
2689
|
+
query: ['entity', 'query'],
|
2690
|
+
lexical: ['key']
|
2691
|
+
});
|
2692
|
+
|
2693
|
+
Dependency.prototype.equals = function(other) {
|
2694
|
+
if (this.tag !== other.tag) {
|
2695
|
+
return false;
|
2696
|
+
}
|
2697
|
+
return this.cases({
|
2698
|
+
query: function(entity, query) {
|
2699
|
+
if (entity.id !== other.entity.id) {
|
2700
|
+
return false;
|
2701
|
+
}
|
2702
|
+
if (query.annotations !== other.query.annotations) {
|
2703
|
+
return false;
|
2704
|
+
}
|
2705
|
+
return true;
|
2706
|
+
},
|
2707
|
+
lexical: function(key) {
|
2708
|
+
return key === other.key;
|
2709
|
+
}
|
2710
|
+
});
|
2711
|
+
};
|
2712
|
+
|
2713
|
+
Dependency.prototype.inspect = function() {
|
2714
|
+
return this.cases({
|
2715
|
+
lookup: function(entity, query) {
|
2716
|
+
return "" + (query.inspect()) + "<" + entity.id + ">";
|
2717
|
+
},
|
2718
|
+
lexical: function(definition) {
|
2719
|
+
return "@" + definition.name;
|
2720
|
+
}
|
2721
|
+
});
|
2722
|
+
};
|
2723
|
+
|
2724
|
+
return Dependency;
|
2725
|
+
|
2726
|
+
})(Union);
|
2727
|
+
|
2728
|
+
eval_ = Gibbon["eval"] = (function() {
|
2729
|
+
var evalAll;
|
2730
|
+
evalAll = function(semantics, entity, client) {
|
2731
|
+
var evalFlow, globalPromise, resultThunks, results;
|
2732
|
+
results = new Hash;
|
2733
|
+
globalPromise = Promise.unit(entity);
|
2734
|
+
resultThunks = new Hash;
|
2735
|
+
semantics.each(function(key, definition) {
|
2736
|
+
return resultThunks.set(key, Promise.lazy(function() {
|
2737
|
+
return evalFlow(definition.flow, globalPromise).then(function(val) {
|
2738
|
+
return val.resolve();
|
2739
|
+
}).after(function(val, deps) {
|
2740
|
+
deps = uniq(deps, function(x, y) {
|
2741
|
+
return x.equals(y);
|
2742
|
+
});
|
2743
|
+
return results.set(key, [val, deps]);
|
2744
|
+
});
|
2745
|
+
}));
|
2746
|
+
});
|
2747
|
+
evalFlow = function(flow, global) {
|
2748
|
+
var input;
|
2749
|
+
input = flow.tail ? evalFlow(flow.tail, global) : global;
|
2750
|
+
return flow.head.cases({
|
2751
|
+
query: function(annotations) {
|
2752
|
+
return input.then(function(entity) {
|
2753
|
+
var _this = this;
|
2754
|
+
return new Promise(function(fail, cc) {
|
2755
|
+
return client.performQuery(entity.id, annotations, function(err, val) {
|
2756
|
+
var dependency;
|
2757
|
+
if (err) {
|
2758
|
+
return fail(err);
|
2759
|
+
}
|
2760
|
+
dependency = Dependency.query(entity, flow.head);
|
2761
|
+
return Value.fromJSON(val).promise().depends([dependency]).force(fail, cc);
|
2762
|
+
});
|
2763
|
+
});
|
2764
|
+
});
|
2765
|
+
},
|
2766
|
+
localAccessor: function(key) {
|
2767
|
+
return new Promise(function(fail, cc) {
|
2768
|
+
return resultThunks.get(key).force(fail, function(val, otherDeps) {
|
2769
|
+
return cc(val, [Dependency.lexical(key)]);
|
2770
|
+
});
|
2771
|
+
});
|
2772
|
+
},
|
2773
|
+
func: function(name, args) {
|
2774
|
+
var a, func;
|
2775
|
+
func = stdlib[name].impl;
|
2776
|
+
args = (function() {
|
2777
|
+
var _i, _len, _results;
|
2778
|
+
_results = [];
|
2779
|
+
for (_i = 0, _len = args.length; _i < _len; _i++) {
|
2780
|
+
a = args[_i];
|
2781
|
+
_results.push(evalFlow(a, global));
|
2782
|
+
}
|
2783
|
+
return _results;
|
2784
|
+
})();
|
2785
|
+
return func.apply(null, [input].concat(__slice.call(args)));
|
2786
|
+
},
|
2787
|
+
literal: function(syntax) {
|
2788
|
+
return syntax.cases({
|
2789
|
+
integer: function(value) {
|
2790
|
+
return Promise.unit(Value.number(value));
|
2791
|
+
},
|
2792
|
+
decimal: function(value) {
|
2793
|
+
return Promise.unit(Value.number(value));
|
2794
|
+
},
|
2795
|
+
string: function(value) {
|
2796
|
+
return Promise.unit(Value.string(value));
|
2797
|
+
}
|
2798
|
+
});
|
2799
|
+
},
|
2800
|
+
pair: function(first, second) {
|
2801
|
+
var eFirst, eSecond;
|
2802
|
+
eFirst = evalFlow(first, global);
|
2803
|
+
eSecond = evalFlow(second, global);
|
2804
|
+
return Promise.unit(Value.pair(eFirst, eSecond));
|
2805
|
+
},
|
2806
|
+
list: function(elements) {
|
2807
|
+
var e;
|
2808
|
+
elements = (function() {
|
2809
|
+
var _i, _len, _results;
|
2810
|
+
_results = [];
|
2811
|
+
for (_i = 0, _len = elements.length; _i < _len; _i++) {
|
2812
|
+
e = elements[_i];
|
2813
|
+
_results.push(evalFlow(e, global));
|
2814
|
+
}
|
2815
|
+
return _results;
|
2816
|
+
})();
|
2817
|
+
return Promise.unit(Value.list(elements));
|
2818
|
+
},
|
2819
|
+
block: function(body) {
|
2820
|
+
return Promise.unit(Value.block(function(inputPromise) {
|
2821
|
+
return evalFlow(body, inputPromise);
|
2822
|
+
}));
|
2823
|
+
}
|
2824
|
+
});
|
2825
|
+
};
|
2826
|
+
return new Promise(function(fail, cc) {
|
2827
|
+
return Promise.combine(resultThunks.values()).force(fail, function(_, deps) {
|
2828
|
+
return cc(results, deps);
|
2829
|
+
});
|
2830
|
+
});
|
2831
|
+
};
|
2832
|
+
return function(semantics, table, id, client, finish) {
|
2833
|
+
var entity, key, onFailure, onSuccess, _i, _len, _ref2;
|
2834
|
+
_ref2 = semantics.keys();
|
2835
|
+
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
|
2836
|
+
key = _ref2[_i];
|
2837
|
+
semantics.modify(key, function(val) {
|
2838
|
+
if (val instanceof Semantic) {
|
2839
|
+
return val;
|
2840
|
+
}
|
2841
|
+
return Semantic.fromJSON(val);
|
2842
|
+
});
|
2843
|
+
}
|
2844
|
+
entity = Value.entity(table, id);
|
2845
|
+
onFailure = function(fail) {
|
2846
|
+
return finish(fail);
|
2847
|
+
};
|
2848
|
+
onSuccess = function(vals) {
|
2849
|
+
return finish(null, vals);
|
2850
|
+
};
|
2851
|
+
return evalAll(semantics, entity, client).force(onFailure, onSuccess);
|
2852
|
+
};
|
2853
|
+
})();
|
2854
|
+
// Generated by CoffeeScript 1.6.3
|
2855
|
+
Gibbon.jsonConsumer = (function() {
|
2856
|
+
return function(tables) {
|
2857
|
+
var getType, getValue;
|
2858
|
+
getType = function(id, accessorName, t, callback) {
|
2859
|
+
var fields;
|
2860
|
+
if (!tables.hasOwnProperty(id)) {
|
2861
|
+
return callback(new Error("no such type " + id));
|
2862
|
+
}
|
2863
|
+
fields = tables[id].fields;
|
2864
|
+
if (!fields.hasOwnProperty(accessorName)) {
|
2865
|
+
return callback(new Error("" + id + " has no field " + accessorName));
|
2866
|
+
}
|
2867
|
+
return callback(null, {
|
2868
|
+
type: t.parseUnit(fields[accessorName]),
|
2869
|
+
annotations: {
|
2870
|
+
name: accessorName,
|
2871
|
+
table: id
|
2872
|
+
}
|
2873
|
+
});
|
2874
|
+
};
|
2875
|
+
getValue = function(id, annotations, callback) {
|
2876
|
+
var entity, values;
|
2877
|
+
if (!tables.hasOwnProperty(annotations.table)) {
|
2878
|
+
return callback(new Error("no such type " + annotations.table));
|
2879
|
+
}
|
2880
|
+
values = tables[annotations.table].values;
|
2881
|
+
if (!values[id]) {
|
2882
|
+
return callback(new Error("no entity with id " + id));
|
2883
|
+
}
|
2884
|
+
entity = values[id];
|
2885
|
+
if (!entity.hasOwnProperty(annotations.name)) {
|
2886
|
+
return callback(null, null);
|
2887
|
+
}
|
2888
|
+
return callback(null, entity[annotations.name]);
|
2889
|
+
};
|
2890
|
+
return {
|
2891
|
+
analyzeQuery: function(id, query, t, callback) {
|
2892
|
+
switch (query.type) {
|
2893
|
+
case 'access':
|
2894
|
+
return getType(id, query.name, t, callback);
|
2895
|
+
default:
|
2896
|
+
return callback(new Error("unknown query `" + query.type + "'"));
|
2897
|
+
}
|
2898
|
+
},
|
2899
|
+
performQuery: function(id, annotations, callback) {
|
2900
|
+
return getValue(id, annotations, callback);
|
2901
|
+
}
|
2902
|
+
};
|
2903
|
+
};
|
2904
|
+
})();
|
2905
|
+
return Gibbon;
|
2906
|
+
})();
|