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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/README.md +12 -2
- data/docs/RlangManual.md +43 -30
- data/lib/rlang/lib.rb +2 -1
- data/lib/rlang/lib/malloc.rb +2 -2
- data/lib/rlang/lib/memory.rb +18 -0
- data/lib/rlang/lib/string.rb +30 -0
- data/lib/rlang/parser.rb +263 -206
- data/lib/rlang/parser/{wattr.rb → attr.rb} +41 -33
- data/lib/rlang/parser/data.rb +3 -0
- data/lib/rlang/parser/ivar.rb +16 -7
- data/lib/rlang/parser/klass.rb +6 -3
- data/lib/rlang/parser/method.rb +17 -9
- data/lib/rlang/parser/wgenerator.rb +168 -47
- data/lib/rlang/parser/wnode.rb +96 -65
- data/lib/rlang/version.rb +1 -1
- metadata +4 -3
data/lib/rlang/parser/wnode.rb
CHANGED
@@ -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 './
|
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
|
-
|
53
|
+
attr_getter: %q{func %{func_name} (param $_self_ i32) (result %{wtype})
|
52
54
|
(%{wtype}.load offset=%{offset} (local.get $_self_))},
|
53
|
-
|
54
|
-
(local.get %{
|
55
|
-
(%{wtype}.store offset=%{offset} (local.get $_self_) (local.get %{
|
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
|
-
|
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)
|
169
|
-
|
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
|
-
|
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
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
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|
|
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
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
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
|
-
|
238
|
-
|
239
|
-
|
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
|
-
|
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(
|
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
|
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
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
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
|
308
|
+
def find_attr(name, class_name=nil)
|
278
309
|
k = find_class(class_name)
|
279
|
-
raise "Can't find parent class for
|
280
|
-
logger.debug "looking for
|
281
|
-
k.
|
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
|
315
|
+
def create_attr(name, wtype=WType::DEFAULT)
|
285
316
|
if (cn = self.class_wnode)
|
286
|
-
logger.debug "creating
|
287
|
-
cn.klass.
|
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 #{
|
320
|
+
raise "No class found for class attribute #{name}"
|
290
321
|
end
|
291
|
-
|
322
|
+
_attr
|
292
323
|
end
|
293
324
|
|
294
|
-
def
|
295
|
-
|
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.
|
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
|
-
|
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.
|
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
|
-
|
415
|
+
return nil unless k
|
385
416
|
if method_type == :class
|
386
|
-
method = k.methods.find { |m| m.name == method_name && m.class_name ==
|
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 ==
|
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
|
data/lib/rlang/version.rb
CHANGED
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.
|
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-
|
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
|