rlang 0.3.1 → 0.4.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.
- checksums.yaml +4 -4
- data/.gitignore +2 -1
- data/CHANGELOG.md +5 -0
- data/Gemfile.lock +7 -1
- data/README.md +21 -1
- data/bin/rlang +18 -53
- data/docs/RlangManual.md +65 -27
- data/examples/fib/fib.rb +11 -0
- data/examples/fib/index.html +38 -0
- data/examples/fib/server.rb +16 -0
- data/lib/builder/rlang.rb +1 -1
- data/lib/builder/rlang/builder.rb +41 -9
- data/lib/builder/rlang/compiler.rb +83 -0
- data/lib/builder/wat/builder.rb +12 -21
- data/lib/rlang/lib.rb +1 -1
- data/lib/rlang/lib/malloc.rb +9 -19
- data/lib/rlang/lib/object.rb +16 -0
- data/lib/rlang/lib/unistd.rb +22 -0
- data/lib/rlang/parser.rb +176 -33
- data/lib/rlang/parser/data.rb +5 -0
- data/lib/rlang/parser/export.rb +4 -0
- data/lib/rlang/parser/global.rb +4 -0
- data/lib/rlang/parser/ivar.rb +36 -0
- data/lib/rlang/parser/klass.rb +49 -0
- data/lib/rlang/parser/marg.rb +4 -0
- data/lib/rlang/parser/method.rb +8 -4
- data/lib/rlang/parser/wattr.rb +19 -6
- data/lib/rlang/parser/wgenerator.rb +146 -47
- data/lib/rlang/parser/wnode.rb +108 -60
- data/lib/rlang/parser/wtype.rb +1 -0
- data/lib/rlang/version.rb +1 -1
- data/rlang.gemspec +1 -0
- metadata +23 -2
data/lib/rlang/parser/wnode.rb
CHANGED
@@ -11,6 +11,7 @@ require_relative './cvar'
|
|
11
11
|
require_relative './lvar'
|
12
12
|
require_relative './wattr'
|
13
13
|
require_relative './method'
|
14
|
+
require_relative './klass'
|
14
15
|
|
15
16
|
module Rlang::Parser
|
16
17
|
class WNode
|
@@ -56,10 +57,9 @@ module Rlang::Parser
|
|
56
57
|
(%{wtype}.const %{size})}
|
57
58
|
}
|
58
59
|
|
59
|
-
attr_accessor :type, :wargs, :children, :parent, :comment,
|
60
|
-
|
61
|
-
|
62
|
-
attr_reader :wtype, :label, :klass_name, :klass_size, :wattrs
|
60
|
+
attr_accessor :type, :wargs, :children, :parent, :comment,
|
61
|
+
:method, :template, :keep_on_stack, :classes
|
62
|
+
attr_reader :wtype, :label, :klass
|
63
63
|
|
64
64
|
@@label_index = 0
|
65
65
|
|
@@ -81,19 +81,13 @@ module Rlang::Parser
|
|
81
81
|
@wtype = WType::DEFAULT
|
82
82
|
|
83
83
|
# For root wnode
|
84
|
-
@
|
84
|
+
@classes = [] # classes
|
85
85
|
|
86
86
|
# For class wnode only
|
87
|
-
@
|
88
|
-
@wattrs = [] # class attributes
|
89
|
-
@cvars = [] # class variables=
|
90
|
-
@consts = [] # class constants
|
91
|
-
@methods = [] # methods
|
87
|
+
@klass = nil
|
92
88
|
|
93
89
|
# For method wnode only
|
94
90
|
@method = nil
|
95
|
-
@margs = [] # method args
|
96
|
-
@lvars = [] # local variables
|
97
91
|
|
98
92
|
# For insn wnode with
|
99
93
|
# label (.e.g block, loop)
|
@@ -184,6 +178,7 @@ module Rlang::Parser
|
|
184
178
|
# Reparent self node to another wnode
|
185
179
|
def reparent_to(wnode)
|
186
180
|
return if self.parent == wnode
|
181
|
+
logger.debug "Reparenting #{self.object_id} to #{wnode.object_id}"
|
187
182
|
old_parent, new_parent = self.parent, wnode
|
188
183
|
new_parent << self
|
189
184
|
old_parent >> self if old_parent
|
@@ -197,36 +192,68 @@ module Rlang::Parser
|
|
197
192
|
wn
|
198
193
|
end
|
199
194
|
|
200
|
-
|
201
|
-
|
202
|
-
@
|
195
|
+
def klass=(klass)
|
196
|
+
@klass = klass
|
197
|
+
@klass.wnode = self
|
198
|
+
WNode.root.classes << klass
|
203
199
|
end
|
204
200
|
|
205
201
|
# Find class name in this node and up the tree
|
206
202
|
def class_name
|
207
|
-
(cn = self.class_wnode) ? cn.
|
203
|
+
(cn = self.class_wnode) ? cn.klass.name : nil
|
208
204
|
end
|
209
205
|
|
210
|
-
# Find class
|
206
|
+
# Find class size in this wnode or up the tree
|
211
207
|
def class_size
|
212
|
-
(cn = self.class_wnode) ? cn.
|
208
|
+
(cn = self.class_wnode) ? cn.klass.size : nil
|
213
209
|
end
|
214
210
|
|
215
|
-
# Find the class
|
216
|
-
# class
|
217
|
-
|
211
|
+
# Find the class object of the current and up the tree
|
212
|
+
# if no name given or lookup the matching class from
|
213
|
+
# the root level if class name given
|
214
|
+
def find_class(class_name)
|
215
|
+
logger.debug "looking for class #{class_name ? class_name : 'current'}"
|
218
216
|
if class_name
|
219
|
-
WNode.root.
|
217
|
+
c = WNode.root.classes.find { |c| c.name == class_name }
|
218
|
+
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
|
225
|
+
end
|
226
|
+
if c
|
227
|
+
logger.debug "Found class #{c}"
|
220
228
|
else
|
221
|
-
|
222
|
-
end
|
229
|
+
logger.debug "Class #{class_name} not found"
|
230
|
+
end
|
231
|
+
c
|
232
|
+
end
|
233
|
+
|
234
|
+
# Create a Class object. **NOTE** the self
|
235
|
+
# wnode must be the parent of the new class
|
236
|
+
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
|
245
|
+
wnc.klass
|
246
|
+
end
|
247
|
+
|
248
|
+
def find_or_create_class(class_name)
|
249
|
+
self.find_class(class_name) || self.create_class(class_name)
|
223
250
|
end
|
224
251
|
|
225
252
|
# create a constant
|
226
253
|
def create_const(c_name, class_name, value, wtype)
|
227
254
|
class_name ||= self.class_name
|
228
255
|
if (cn = self.class_wnode)
|
229
|
-
cn.consts << (const = Const.new(class_name, c_name, value, wtype))
|
256
|
+
cn.klass.consts << (const = Const.new(class_name, c_name, value, wtype))
|
230
257
|
else
|
231
258
|
raise "No class found for class constant #{const}"
|
232
259
|
end
|
@@ -236,11 +263,11 @@ module Rlang::Parser
|
|
236
263
|
# Look for constant in the appropriate class wnode
|
237
264
|
# (it can be the current class or another class)
|
238
265
|
def find_const(c_name, class_name=nil)
|
239
|
-
|
240
|
-
raise "Can't find parent class for constant #{c_name}" unless
|
241
|
-
class_name =
|
266
|
+
k = find_class(class_name)
|
267
|
+
raise "Can't find parent class for constant #{c_name}" unless k
|
268
|
+
class_name = k.name
|
242
269
|
logger.debug "looking for const #{c_name} in class #{class_name} at wnode #{self.class_wnode}..."
|
243
|
-
|
270
|
+
k.consts.find { |c| c.class_name == class_name && c.name == c_name }
|
244
271
|
end
|
245
272
|
|
246
273
|
def find_or_create_const(c_name, class_name, value, wtype)
|
@@ -248,27 +275,51 @@ module Rlang::Parser
|
|
248
275
|
end
|
249
276
|
|
250
277
|
def find_wattr(wa_name, class_name=nil)
|
251
|
-
|
252
|
-
raise "Can't find parent class for wattr #{wa_name}" unless
|
253
|
-
|
254
|
-
|
255
|
-
wn_class.wattrs.find { |wa| wa.class_name == class_name && wa.name == wa_name }
|
278
|
+
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 }
|
256
282
|
end
|
257
283
|
|
258
284
|
def create_wattr(wa_name, wtype=WType::DEFAULT)
|
259
285
|
if (cn = self.class_wnode)
|
260
286
|
logger.debug "creating wattr #{wa_name} in class #{self.class_name} at wnode #{self.class_wnode}..."
|
261
|
-
cn.wattrs << (wattr = WAttr.new(cn, wa_name, wtype))
|
287
|
+
cn.klass.wattrs << (wattr = WAttr.new(cn, wa_name, wtype))
|
262
288
|
else
|
263
289
|
raise "No class found for class attribute #{wa_name}"
|
264
290
|
end
|
265
291
|
wattr
|
266
292
|
end
|
267
293
|
|
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)
|
296
|
+
end
|
297
|
+
|
298
|
+
def create_ivar(iv_name, wtype=WType::DEFAULT)
|
299
|
+
if (cn = self.class_wnode)
|
300
|
+
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))
|
302
|
+
else
|
303
|
+
raise "No class found for instance variable #{iv_name}"
|
304
|
+
end
|
305
|
+
wattr
|
306
|
+
end
|
307
|
+
|
308
|
+
def find_ivar(iv_name, class_name=nil)
|
309
|
+
klass = find_class(class_name)
|
310
|
+
raise "Can't find parent class for ivar #{iv_name}" unless klass
|
311
|
+
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 }
|
313
|
+
end
|
314
|
+
|
315
|
+
def find_or_create_ivar(iv_name)
|
316
|
+
self.find_ivar(iv_name) || self.create_ivar(iv_name)
|
317
|
+
end
|
318
|
+
|
268
319
|
def create_cvar(cv_name, value=0, wtype=WType::DEFAULT)
|
269
320
|
if (cn = self.class_wnode)
|
270
321
|
logger.debug "creating cvar #{cv_name} in class #{self.class_name} at wnode #{self.class_wnode}..."
|
271
|
-
cn.cvars << (cvar = CVar.new(cn.
|
322
|
+
cn.klass.cvars << (cvar = CVar.new(cn.klass.name, cv_name, value, wtype))
|
272
323
|
else
|
273
324
|
raise "No class found for class variable #{cv_name}"
|
274
325
|
end
|
@@ -277,12 +328,12 @@ module Rlang::Parser
|
|
277
328
|
|
278
329
|
def find_cvar(cv_name)
|
279
330
|
logger.debug "looking for cvar #{cv_name} in class #{self.class_name} at wnode #{self.class_wnode}..."
|
280
|
-
self.class_wnode.cvars.find { |cv| cv.class_name == self.class_name && cv.name == cv_name }
|
331
|
+
self.class_wnode.klass.cvars.find { |cv| cv.class_name == self.class_name && cv.name == cv_name }
|
281
332
|
end
|
282
333
|
|
283
334
|
def create_lvar(name)
|
284
335
|
if (mn = self.method_wnode)
|
285
|
-
mn.lvars << (lvar = LVar.new(name))
|
336
|
+
mn.method.lvars << (lvar = LVar.new(name))
|
286
337
|
else
|
287
338
|
raise "No method found for local variable #{name}"
|
288
339
|
end
|
@@ -290,7 +341,7 @@ module Rlang::Parser
|
|
290
341
|
end
|
291
342
|
|
292
343
|
def find_lvar(name)
|
293
|
-
self.method_wnode.lvars.find { |lv| lv.name == name }
|
344
|
+
self.method_wnode.method.lvars.find { |lv| lv.name == name }
|
294
345
|
end
|
295
346
|
|
296
347
|
def find_or_create_lvar(name)
|
@@ -300,7 +351,7 @@ module Rlang::Parser
|
|
300
351
|
# add method argument
|
301
352
|
def create_marg(name)
|
302
353
|
if (mn = self.method_wnode)
|
303
|
-
mn.margs << (marg = MArg.new(name))
|
354
|
+
mn.method.margs << (marg = MArg.new(name))
|
304
355
|
else
|
305
356
|
raise "No class found for class variable #{marg}"
|
306
357
|
end
|
@@ -308,51 +359,48 @@ module Rlang::Parser
|
|
308
359
|
end
|
309
360
|
|
310
361
|
def find_marg(name)
|
311
|
-
self.method_wnode.margs.find { |ma| ma.name == name }
|
362
|
+
self.method_wnode.method.margs.find { |ma| ma.name == name }
|
312
363
|
end
|
313
364
|
|
314
365
|
# method_type is either :instance or :class
|
315
366
|
def create_method(method_name, class_name, wtype, method_type)
|
316
|
-
|
317
|
-
|
367
|
+
if (m = find_method(method_name, class_name, method_type))
|
368
|
+
raise "MEthod already exists: #{m.inspect}"
|
369
|
+
end
|
318
370
|
if (cn = self.class_wnode)
|
319
|
-
class_name ||= cn.
|
320
|
-
cn.methods << (method = MEthod.new(method_name, class_name, wtype))
|
371
|
+
class_name ||= cn.klass.name
|
372
|
+
cn.klass.methods << (method = MEthod.new(method_name, class_name, wtype))
|
321
373
|
else
|
322
374
|
raise "No class wnode found to create method #{method_name}"
|
323
375
|
end
|
324
376
|
method_type == :class ? method.class! : method.instance!
|
325
|
-
logger.debug "Created MEthod: #{method
|
377
|
+
logger.debug "Created MEthod: #{method}"
|
326
378
|
method
|
327
379
|
end
|
328
380
|
|
329
|
-
|
381
|
+
# method_type is either :instance or :class
|
330
382
|
def find_method(method_name, class_name, method_type)
|
331
|
-
|
332
|
-
|
333
|
-
else
|
334
|
-
class_wnode = self.class_wnode
|
335
|
-
end
|
336
|
-
raise "Couldn't find class wnode for class_name #{class_name}" unless class_wnode
|
337
|
-
class_name = class_wnode.klass_name
|
383
|
+
k = self.find_class(class_name)
|
384
|
+
raise "Couldn't find class wnode for class_name #{class_name}" unless k
|
338
385
|
if method_type == :class
|
339
|
-
method =
|
386
|
+
method = k.methods.find { |m| m.name == method_name && m.class_name == class_name && m.class? }
|
340
387
|
elsif method_type == :instance
|
341
|
-
method =
|
388
|
+
method = k.methods.find { |m| m.name == method_name && m.class_name == class_name && m.instance? }
|
342
389
|
else
|
343
390
|
raise "Unknown method type : #{method_type.inspect}"
|
344
391
|
end
|
345
392
|
if method
|
346
|
-
logger.debug "Found MEthod: #{method
|
393
|
+
logger.debug "Found MEthod: #{method}"
|
347
394
|
else
|
348
|
-
logger.debug "Couldn't find MEthod: #{
|
395
|
+
logger.debug "Couldn't find MEthod: #{k.name},#{method_name}"
|
349
396
|
end
|
350
397
|
method
|
351
398
|
end
|
352
399
|
|
353
|
-
def find_or_create_method(method_name, class_name
|
400
|
+
def find_or_create_method(method_name, class_name, wtype, method_type)
|
401
|
+
wtype ||= WType::DEFAULT
|
354
402
|
self.find_method(method_name, class_name, method_type) || \
|
355
|
-
self.create_method(method_name, class_name,
|
403
|
+
self.create_method(method_name, class_name, wtype, method_type)
|
356
404
|
end
|
357
405
|
|
358
406
|
# Find block wnode up the tree
|
data/lib/rlang/parser/wtype.rb
CHANGED
data/lib/rlang/version.rb
CHANGED
data/rlang.gemspec
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
|
+
version: 0.4.0
|
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-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: parser
|
@@ -80,6 +80,20 @@ dependencies:
|
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0.3'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: simplecov
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0.18'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0.18'
|
83
97
|
description: "Rlang is meant to create fast and uncluttered WebAssembly code \n from
|
84
98
|
the comfort of the Ruby language. It is actually made of two things: a supported
|
85
99
|
\n subset of the Ruby language and a compiler transforming this Ruby subset in
|
@@ -103,11 +117,15 @@ files:
|
|
103
117
|
- bin/rlang
|
104
118
|
- docs/RlangCompiler.md
|
105
119
|
- docs/RlangManual.md
|
120
|
+
- examples/fib/fib.rb
|
121
|
+
- examples/fib/index.html
|
122
|
+
- examples/fib/server.rb
|
106
123
|
- lib/builder.rb
|
107
124
|
- lib/builder/ext.rb
|
108
125
|
- lib/builder/ext/tempfile.rb
|
109
126
|
- lib/builder/rlang.rb
|
110
127
|
- lib/builder/rlang/builder.rb
|
128
|
+
- lib/builder/rlang/compiler.rb
|
111
129
|
- lib/builder/wat.rb
|
112
130
|
- lib/builder/wat/builder.rb
|
113
131
|
- lib/builder/wat/renderer.rb
|
@@ -116,6 +134,7 @@ files:
|
|
116
134
|
- lib/rlang/lib/malloc.c
|
117
135
|
- lib/rlang/lib/malloc.rb
|
118
136
|
- lib/rlang/lib/memory.rb
|
137
|
+
- lib/rlang/lib/object.rb
|
119
138
|
- lib/rlang/lib/type.rb
|
120
139
|
- lib/rlang/lib/type/i32.rb
|
121
140
|
- lib/rlang/lib/type/i64.rb
|
@@ -129,6 +148,8 @@ files:
|
|
129
148
|
- lib/rlang/parser/ext/string.rb
|
130
149
|
- lib/rlang/parser/ext/type.rb
|
131
150
|
- lib/rlang/parser/global.rb
|
151
|
+
- lib/rlang/parser/ivar.rb
|
152
|
+
- lib/rlang/parser/klass.rb
|
132
153
|
- lib/rlang/parser/lvar.rb
|
133
154
|
- lib/rlang/parser/marg.rb
|
134
155
|
- lib/rlang/parser/method.rb
|