goodguide-gibbon 0.5.1 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,7 +1,7 @@
1
1
  module GoodGuide
2
2
  module Gibbon
3
3
  def self.version
4
- '0.5.1'
4
+ '0.6.0'
5
5
  end
6
6
  end
7
7
  end
@@ -23,18 +23,18 @@ module GoodGuide
23
23
  when Array
24
24
  o.map { |x| obj_to_js(x) }
25
25
  when Hash
26
- if o['__isHash__'] or o[:__isHash__]
26
+ if o['__isHash__']
27
27
  js_hash = gibbon[:Hash].new
28
28
  o.each do |k, v|
29
29
  next if k.to_s == '__isHash__'
30
30
  js_hash.set(k, obj_to_js(v))
31
31
  end
32
32
  js_hash
33
- elsif o['_union'] or o[:_union]
34
- union = o['_union'] or o[:_union]
35
- tag = o['_tag'] or o[:_tag]
36
- constructor = gibbon[union]
37
- raise "unknown union #{union}" unless constructor && constructor.tags
33
+ elsif o['__isVariant__']
34
+ type = o['_type']
35
+ tag = o['_tag']
36
+ constructor = gibbon[type]
37
+ raise "unknown union #{type}" unless constructor && constructor.tags
38
38
  names = constructor.tags[tag]
39
39
  raise "unknown tag #{tag}" unless names.is_a? V8::Array
40
40
 
@@ -58,9 +58,20 @@ module GoodGuide
58
58
  when V8::Object
59
59
  if o[:__isHash__]
60
60
  hash_to_ruby(o)
61
- else
62
- o = o.asJSON if o.respond_to? :asJSON
61
+ elsif o[:__isVariant__]
62
+ out = {
63
+ '__isVariant__' => true,
64
+ '_names' => obj_to_ruby(o[:_names]),
65
+ '_type' => o[:_type],
66
+ '_tag' => o[:_tag]
67
+ }
68
+
69
+ o._names.each do |name|
70
+ out[name] = obj_to_ruby o[name]
71
+ end
63
72
 
73
+ out
74
+ else
64
75
  out = {}
65
76
  o.each do |k, v|
66
77
  out[k] = obj_to_ruby(v)
@@ -90,6 +101,8 @@ module GoodGuide
90
101
  end
91
102
 
92
103
  class SemanticError < StandardError
104
+ include Util
105
+
93
106
  def initialize(errors)
94
107
  @errors = errors
95
108
  end
@@ -99,14 +112,15 @@ module GoodGuide
99
112
  end
100
113
 
101
114
  private
102
- def inspect_js(type, js)
103
- obj = JS.default.gibbon[type].fromJSON(js)
104
- inspect = obj[:inspect]
105
- inspect.methodcall(obj)
115
+ # needed for obj_to_js
116
+ def gibbon
117
+ JS.default.gibbon
106
118
  end
107
119
 
108
120
  def inspect_expr(expr)
109
- inspect_js :TypeExpr, expr
121
+ obj = obj_to_js(expr)
122
+ inspect = obj[:inspect]
123
+ inspect.methodcall(obj)
110
124
  end
111
125
 
112
126
  def semantic_error_message(e)
@@ -121,7 +135,7 @@ module GoodGuide
121
135
  type = inspect_expr e['type']
122
136
  "could not destructure #{type}"
123
137
  when 'lookup'
124
- query = inspect_js :AST, e['query']
138
+ query = inspect_expr e['query']
125
139
  id = e['id']
126
140
  error = e['error']
127
141
  "error analyzing #{query} on #{id}: #{error}"
@@ -168,31 +182,43 @@ module GoodGuide
168
182
 
169
183
  raise SemanticError.new(errors) if errors
170
184
 
185
+ compiled = context.compile(semantics)
186
+
171
187
  Program.new(
172
188
  :syntax => syntax,
173
- :semantics => semantics,
189
+ :compiled => compiled,
174
190
  :context => context,
175
191
  )
176
192
  end
177
193
 
178
- attr_reader :syntax, :semantics
194
+ attr_reader :syntax, :compiled
195
+ def semantics
196
+ as_json['compiled']['semantics']
197
+ end
198
+
179
199
  def initialize(info={})
180
- @syntax = info[:syntax]
181
- @semantics = info[:semantics]
200
+ @syntax = info[:syntax] or raise 'please pass syntax'
201
+ @compiled = info[:compiled] or raise 'please pass a compiled program'
182
202
  @context = info[:context] || Context.new
183
203
  end
184
204
 
185
205
  def as_json
186
- {
187
- syntax: @syntax,
188
- semantics: @semantics,
206
+ @as_json ||= {
207
+ 'syntax' => @context.send(:obj_to_ruby, @syntax),
208
+ 'compiled' => @context.send(:obj_to_ruby, @compiled),
189
209
  }
190
210
  end
191
211
 
212
+ def self.from_json(hash, context)
213
+ syntax = context.send(:obj_to_js, hash['syntax'])
214
+ semantics = context.send(:obj_to_js, hash['compiled']['semantics'])
215
+ blocks = context.send(:obj_to_js, hash['compiled']['blocks'])
216
+ compiled = context.gibbon[:CompiledCode].new(semantics, blocks)
217
+ new(syntax: syntax, compiled: compiled, context: context)
218
+ end
219
+
192
220
  def call(runtime_client, entity_id)
193
- values, error = @context.eval_gibbon(
194
- self.semantics, entity_id, runtime_client.to_js
195
- )
221
+ values, error = @context.run_compiled(@compiled, entity_id, runtime_client.to_js)
196
222
 
197
223
  raise error if error
198
224
  values
@@ -268,7 +294,7 @@ module GoodGuide
268
294
 
269
295
  class RuntimeClient < AbstractClient
270
296
  include Util
271
- def perform_query(id, annotations, v)
297
+ def perform_query(id, annotations)
272
298
  annotations = obj_to_ruby(annotations)
273
299
 
274
300
  query_type = annotations.delete('_query_type')
@@ -279,7 +305,7 @@ module GoodGuide
279
305
  @last_id = id
280
306
 
281
307
  query = get_query(query_type)
282
- instance_exec(id, annotations, v, &query)
308
+ instance_exec(id, annotations, &query)
283
309
  end
284
310
 
285
311
  def missing_data!
@@ -305,25 +331,26 @@ module GoodGuide
305
331
  end
306
332
 
307
333
  def parse(str)
308
- obj_to_ruby self.gibbon.parse(str).asJSON
334
+ obj_to_ruby self.gibbon.parse(str)
309
335
  rescue V8::Error => e
310
336
  raise SemanticError.new([{'_tag' => 'parse', 'message' => e.value}])
311
337
  end
312
338
 
339
+ def compile(semantics)
340
+ gibbon.compile(obj_to_js(semantics))
341
+ end
342
+
313
343
  def analyze(syntax, global_table, static_client)
314
344
  syntax = obj_to_js(syntax)
315
345
 
316
- semantics, error = capture do |&callback|
346
+ capture do |&callback|
317
347
  gibbon.analyze(syntax, global_table, static_client, callback)
318
348
  end
319
-
320
- [hash_to_ruby(semantics), obj_to_ruby(error)]
321
349
  end
322
350
 
323
- def eval_gibbon(semantics, id, runtime_client)
324
- semantics = obj_to_js(semantics)
351
+ def run_compiled(compiled, entity_id, runtime_client)
325
352
  values, error = capture do |&callback|
326
- gibbon.eval(semantics, 0, id, runtime_client, callback)
353
+ compiled.run('/', entity_id, runtime_client, callback)
327
354
  end
328
355
 
329
356
  [hash_to_ruby(values), obj_to_ruby(error)]