rlang 0.4.0 → 0.4.1

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.
@@ -9,7 +9,7 @@ require_relative './wtype'
9
9
  require_relative './const'
10
10
  require_relative './cvar'
11
11
  require_relative './lvar'
12
- require_relative './wattr'
12
+ require_relative './attr'
13
13
  require_relative './method'
14
14
  require_relative './klass'
15
15
 
@@ -26,7 +26,9 @@ module Rlang::Parser
26
26
  local: 'local %{name} %{wasm_type}',
27
27
  call: 'call %{func_name}',
28
28
  store: '%{wasm_type}.store',
29
+ store_offset: '%{wasm_type}.store offset=%{offset}',
29
30
  load: '%{wasm_type}.load',
31
+ load_offset: '%{wasm_type}.load offset=%{offset}',
30
32
  local_get: 'local.get %{var_name}',
31
33
  local_set: 'local.set %{var_name}',
32
34
  global_get: 'global.get %{var_name}',
@@ -48,11 +50,11 @@ module Rlang::Parser
48
50
  br_if: 'br_if %{label}',
49
51
  br: 'br %{label}',
50
52
  inline: '%{code}',
51
- wattr_reader: %q{func %{func_name} (param $_self_ i32) (result %{wtype})
53
+ attr_getter: %q{func %{func_name} (param $_self_ i32) (result %{wtype})
52
54
  (%{wtype}.load offset=%{offset} (local.get $_self_))},
53
- wattr_writer: %q{func %{func_name} (param $_self_ i32) (param %{wattr_name} %{wtype}) (result %{wtype})
54
- (local.get %{wattr_name})
55
- (%{wtype}.store offset=%{offset} (local.get $_self_) (local.get %{wattr_name}))},
55
+ attr_setter: %q{func %{func_name} (param $_self_ i32) (param %{attr_name} %{wtype}) (result %{wtype})
56
+ (local.get %{attr_name})
57
+ (%{wtype}.store offset=%{offset} (local.get $_self_) (local.get %{attr_name}))},
56
58
  class_size: %q{func %{func_name} (result %{wtype})
57
59
  (%{wtype}.const %{size})}
58
60
  }
@@ -82,9 +84,14 @@ module Rlang::Parser
82
84
 
83
85
  # For root wnode
84
86
  @classes = [] # classes
85
-
87
+ # top level class needed only if const are
88
+ # defined at top level
89
+ # NOTE: can't use create_klass as it find_class
90
+ # which doesn't find root class ... endless loop!!
91
+
86
92
  # For class wnode only
87
- @klass = nil
93
+ @@klass = nil
94
+ self.klass = Klass.new(:Top__) if self.root?
88
95
 
89
96
  # For method wnode only
90
97
  @method = nil
@@ -164,26 +171,38 @@ module Rlang::Parser
164
171
 
165
172
  # Remove child to current node
166
173
  def remove_child(wnode)
167
- logger.debug "Removing #{wnode.object_id} from #{self.children.map(&:object_id)}"
168
- wn = self.children.delete(wnode) do
169
- logger.error "Couldn't find wnode ID #{wnode.object_id} (#{wnode})"
170
- raise
174
+ logger.debug "Removing #{wnode.object_id} from wnodes list #{self.children.map(&:object_id)} under parent #{self.parent.object_id}"
175
+ unless (wn = self.children.delete(wnode)) && wn == wnode
176
+ raise "Couldn't find wnode ID #{wnode.object_id} (#{wnode})"
171
177
  end
172
178
  wn.parent = nil
173
179
  #logger.debug "Removed #{wnode.object_id} from #{self.object_id} (children: #{self.children.map(&:object_id)})"
174
- wn
180
+ wnode
175
181
  end
176
182
  alias :>> :remove_child
177
183
 
178
184
  # Reparent self node to another wnode
179
185
  def reparent_to(wnode)
180
- return if self.parent == wnode
181
- logger.debug "Reparenting #{self.object_id} to #{wnode.object_id}"
182
- old_parent, new_parent = self.parent, wnode
183
- new_parent << self
184
- old_parent >> self if old_parent
186
+ unless self.parent == wnode
187
+ logger.debug "Reparenting #{self.object_id} from #{self.parent.object_id} to #{wnode.object_id}"
188
+ old_parent, new_parent = self.parent, wnode
189
+ old_parent >> self if old_parent
190
+ new_parent << self
191
+ end
192
+ self
185
193
  end
186
194
 
195
+ # Reparent all children wnodes to another wnode
196
+ # (in the same order)
197
+ # WARNING!! Do not use self.children.each { } to
198
+ # reparent because we are modifying children list
199
+ # as we go
200
+ def reparent_children_to(wnode)
201
+ wnc = self.children
202
+ wnc.count.times { wnc.first.reparent_to(wnode) }
203
+ self
204
+ end
205
+
187
206
  # insert a blank wnode above self, so between self wnode
188
207
  # and its parent (self -> parent becomes self -> wn -> parent)
189
208
  def insert(wtype=:none)
@@ -196,6 +215,7 @@ module Rlang::Parser
196
215
  @klass = klass
197
216
  @klass.wnode = self
198
217
  WNode.root.classes << klass
218
+ klass
199
219
  end
200
220
 
201
221
  # Find class name in this node and up the tree
@@ -212,19 +232,27 @@ module Rlang::Parser
212
232
  # if no name given or lookup the matching class from
213
233
  # the root level if class name given
214
234
  def find_class(class_name)
215
- logger.debug "looking for class #{class_name ? class_name : 'current'}"
235
+ logger.debug "looking for class #{class_name ? class_name : 'current'}
236
+ in scope #{self.scope} at wnode #{self}"
216
237
  if class_name
217
- c = WNode.root.classes.find { |c| c.name == class_name }
238
+ c = WNode.root.classes.find { |c|
239
+ logger.debug "**** looking for class #{class_name} in class object #{c} / #{c.name}"; c.name == class_name }
218
240
  else
219
- logger.debug "Looking for class wnode from wnode #{self} / ID: #{self.object_id} /
220
- type: #{self.type} / class_wnode ID #{self.class_wnode.object_id} /
221
- class_wnode #{self.class_wnode} /
222
- self klass : #{self.klass} /
223
- self klass wtype : #{self.klass&.wtype} / "
224
- c = self.class_wnode.klass
241
+ if self.in_root_scope?
242
+ # if at root level and no class name given
243
+ # then it's the top level class
244
+ c = self.class.root.klass
245
+ else
246
+ logger.debug "Looking for class wnode from wnode #{self} / ID: #{self.object_id} /
247
+ type: #{self.type} / class_wnode ID #{self.class_wnode.object_id} /
248
+ class_wnode #{self.class_wnode} /
249
+ self klass : #{self.klass} /
250
+ self klass wtype : #{self.klass&.wtype} / "
251
+ c = self.class_wnode.klass
252
+ end
225
253
  end
226
254
  if c
227
- logger.debug "Found class #{c}"
255
+ logger.debug "Found class #{c.name} / #{c}"
228
256
  else
229
257
  logger.debug "Class #{class_name} not found"
230
258
  end
@@ -234,14 +262,9 @@ module Rlang::Parser
234
262
  # Create a Class object. **NOTE** the self
235
263
  # wnode must be the parent of the new class
236
264
  def create_class(class_name)
237
- if (k = self.find_class(class_name))
238
- raise "Cannot create class #{class_name} for wnode #{self} as it already exists!!"
239
- else
240
- wnc = WNode.new(:class, self)
241
- wnc.klass = Klass.new(class_name)
242
- logger.debug "Created class #{wnc.klass} under wnode #{self} / id: #{self.object_id}"
243
- logger.debug "k inspection: #{wnc.klass}"
244
- end
265
+ wnc = WNode.new(:class, self)
266
+ wnc.klass = Klass.new(class_name)
267
+ logger.debug "Created class #{wnc.klass} under wnode #{self} / id: #{self.object_id}"
245
268
  wnc.klass
246
269
  end
247
270
 
@@ -251,65 +274,73 @@ module Rlang::Parser
251
274
 
252
275
  # create a constant
253
276
  def create_const(c_name, class_name, value, wtype)
254
- class_name ||= self.class_name
277
+ k = find_class(class_name)
278
+ logger.debug "Creating constant #{c_name} in class #{k&.name} / wtype: #{wtype} at wnode #{self.class_wnode}..."
255
279
  if (cn = self.class_wnode)
256
- cn.klass.consts << (const = Const.new(class_name, c_name, value, wtype))
280
+ cn.klass.consts << (const = Const.new(k.name, c_name, value, wtype))
257
281
  else
258
282
  raise "No class found for class constant #{const}"
259
283
  end
260
284
  const
261
285
  end
262
286
 
263
- # Look for constant in the appropriate class wnode
264
- # (it can be the current class or another class)
287
+ # Look for constant
265
288
  def find_const(c_name, class_name=nil)
289
+ logger.debug "looking for constant #{c_name} in class #{class_name ? class_name : 'current'} from wnode #{self}..."
266
290
  k = find_class(class_name)
267
- raise "Can't find parent class for constant #{c_name}" unless k
268
- class_name = k.name
269
- logger.debug "looking for const #{c_name} in class #{class_name} at wnode #{self.class_wnode}..."
270
- k.consts.find { |c| c.class_name == class_name && c.name == c_name }
291
+ # Look for the constant both in current class and a roor class level
292
+ const = [k, @@root.klass].map(&:consts).flatten.find do |c|
293
+ logger.debug "exploring constant #{c} / name: #{c.name} / class_name: #{c.class_name}";
294
+ c.name == c_name
295
+ end
296
+ if const
297
+ logger.debug "Constant #{c_name} found in class #{k.name} at wnode #{k.wnode}..."
298
+ else
299
+ logger.debug "Constant #{c_name} not found in class #{k.name} or at top level..."
300
+ end
301
+ const
271
302
  end
272
303
 
273
304
  def find_or_create_const(c_name, class_name, value, wtype)
274
305
  self.find_const(c_name, class_name) || self.create_const(c_name, class_name, value, wtype)
275
306
  end
276
307
 
277
- def find_wattr(wa_name, class_name=nil)
308
+ def find_attr(name, class_name=nil)
278
309
  k = find_class(class_name)
279
- raise "Can't find parent class for wattr #{wa_name}" unless k
280
- logger.debug "looking for wattr #{wa_name} in class #{k.name} at wnode #{self.class_wnode}..."
281
- k.wattrs.find { |wa| wa.class_name == k.name && wa.name == wa_name }
310
+ raise "Can't find parent class for attr #{name}" unless k
311
+ logger.debug "looking for attr #{name} in class #{k.name} at wnode #{self.class_wnode}..."
312
+ k.attrs.find { |a| a.class_name == k.name && a.name == name }
282
313
  end
283
314
 
284
- def create_wattr(wa_name, wtype=WType::DEFAULT)
315
+ def create_attr(name, wtype=WType::DEFAULT)
285
316
  if (cn = self.class_wnode)
286
- logger.debug "creating wattr #{wa_name} in class #{self.class_name} at wnode #{self.class_wnode}..."
287
- cn.klass.wattrs << (wattr = WAttr.new(cn, wa_name, wtype))
317
+ logger.debug "creating attr #{name} in class #{self.class_name} at wnode #{self.class_wnode}..."
318
+ cn.klass.attrs << (_attr = Attr.new(cn, name, wtype))
288
319
  else
289
- raise "No class found for class attribute #{wa_name}"
320
+ raise "No class found for class attribute #{name}"
290
321
  end
291
- wattr
322
+ _attr
292
323
  end
293
324
 
294
- def find_or_create_wattr(wa_name, class_name=nil, wtype=WType::DEFAULT)
295
- find_wattr(wa_name, class_name) || create_wattr(wa_name, wtype)
325
+ def find_or_create_attr(name, class_name=nil, wtype=WType::DEFAULT)
326
+ find_attr(name, class_name) || create_attr(name, wtype)
296
327
  end
297
328
 
298
329
  def create_ivar(iv_name, wtype=WType::DEFAULT)
299
330
  if (cn = self.class_wnode)
300
331
  logger.debug "creating ivar #{iv_name} in class #{self.class_name} at wnode #{self.class_wnode}..."
301
- cn.klass.wattrs << (wattr = WAttr.new(cn, iv_name, wtype))
332
+ cn.klass.ivars << (ivar = IVar.new(cn, iv_name, wtype))
302
333
  else
303
334
  raise "No class found for instance variable #{iv_name}"
304
335
  end
305
- wattr
336
+ ivar
306
337
  end
307
338
 
308
339
  def find_ivar(iv_name, class_name=nil)
309
340
  klass = find_class(class_name)
310
341
  raise "Can't find parent class for ivar #{iv_name}" unless klass
311
342
  logger.debug "looking for ivar #{iv_name} in class #{class_name} at wnode #{self.class_wnode}..."
312
- self.class_wnode.klass.wattrs.find { |wa| wa.ivar.class_name == klass.name && wa.ivar.name == iv_name }
343
+ self.class_wnode.klass.ivars.find { |iv| iv.class_name == klass.name && iv.name == iv_name }
313
344
  end
314
345
 
315
346
  def find_or_create_ivar(iv_name)
@@ -369,30 +400,30 @@ module Rlang::Parser
369
400
  end
370
401
  if (cn = self.class_wnode)
371
402
  class_name ||= cn.klass.name
372
- cn.klass.methods << (method = MEthod.new(method_name, class_name, wtype))
403
+ cn.klass.methods << (method = MEthod.new(method_name, class_name, wtype, method_type))
373
404
  else
374
405
  raise "No class wnode found to create method #{method_name}"
375
406
  end
376
- method_type == :class ? method.class! : method.instance!
377
407
  logger.debug "Created MEthod: #{method}"
378
408
  method
379
409
  end
380
410
 
381
411
  # method_type is either :instance or :class
382
412
  def find_method(method_name, class_name, method_type)
413
+ logger.debug "looking for #{method_type} method '#{method_name}' in class name '#{class_name}' from wnode #{self}"
383
414
  k = self.find_class(class_name)
384
- raise "Couldn't find class wnode for class_name #{class_name}" unless k
415
+ return nil unless k
385
416
  if method_type == :class
386
- method = k.methods.find { |m| m.name == method_name && m.class_name == class_name && m.class? }
417
+ method = k.methods.find { |m| m.name == method_name && m.class_name == k.name && m.class? }
387
418
  elsif method_type == :instance
388
- method = k.methods.find { |m| m.name == method_name && m.class_name == class_name && m.instance? }
419
+ method = k.methods.find { |m| m.name == method_name && m.class_name == k.name && m.instance? }
389
420
  else
390
421
  raise "Unknown method type : #{method_type.inspect}"
391
422
  end
392
423
  if method
393
- logger.debug "Found MEthod: #{method}"
424
+ logger.debug "Found #{method_type} MEthod: #{k.name},#{method}"
394
425
  else
395
- logger.debug "Couldn't find MEthod: #{k.name},#{method_name}"
426
+ logger.debug "Couldn't find #{method_type} MEthod: #{k.name},#{method_name}"
396
427
  end
397
428
  method
398
429
  end
@@ -463,7 +494,7 @@ module Rlang::Parser
463
494
  end
464
495
 
465
496
  def in_root_scope?
466
- self.root? || self.parent.root?
497
+ self.root? || (self.parent.root? && !in_class_scope?)
467
498
  end
468
499
 
469
500
  def method?
@@ -471,7 +502,7 @@ module Rlang::Parser
471
502
  end
472
503
 
473
504
  def class?
474
- self.type == :class
505
+ self.type == :class || self.type == :root
475
506
  end
476
507
 
477
508
  # format the wnode and tree below
@@ -1,3 +1,3 @@
1
1
  module Rlang
2
- VERSION = "0.4.0"
2
+ VERSION = "0.4.1"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rlang
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Laurent Julliard
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-02-13 00:00:00.000000000 Z
11
+ date: 2020-02-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: parser
@@ -135,11 +135,13 @@ files:
135
135
  - lib/rlang/lib/malloc.rb
136
136
  - lib/rlang/lib/memory.rb
137
137
  - lib/rlang/lib/object.rb
138
+ - lib/rlang/lib/string.rb
138
139
  - lib/rlang/lib/type.rb
139
140
  - lib/rlang/lib/type/i32.rb
140
141
  - lib/rlang/lib/type/i64.rb
141
142
  - lib/rlang/lib/unistd.rb
142
143
  - lib/rlang/parser.rb
144
+ - lib/rlang/parser/attr.rb
143
145
  - lib/rlang/parser/const.rb
144
146
  - lib/rlang/parser/cvar.rb
145
147
  - lib/rlang/parser/data.rb
@@ -153,7 +155,6 @@ files:
153
155
  - lib/rlang/parser/lvar.rb
154
156
  - lib/rlang/parser/marg.rb
155
157
  - lib/rlang/parser/method.rb
156
- - lib/rlang/parser/wattr.rb
157
158
  - lib/rlang/parser/wgenerator.rb
158
159
  - lib/rlang/parser/winstruction.rb
159
160
  - lib/rlang/parser/wnode.rb