goodguide-gibbon 0.5.1 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,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)]