rlang 0.3.1 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|