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.
@@ -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, :lvars, :cvars, :margs,
60
- :consts, :methods, :method, :template, :keep_on_stack,
61
- :class_wnodes
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
- @class_wnodes = [] # wnodes of classes
84
+ @classes = [] # classes
85
85
 
86
86
  # For class wnode only
87
- @klass_name = nil
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
- # Set this node class name
201
- def class_name=(class_name)
202
- @klass_name = class_name
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.klass_name : nil
203
+ (cn = self.class_wnode) ? cn.klass.name : nil
208
204
  end
209
205
 
210
- # Find class name in this node and up the tree
206
+ # Find class size in this wnode or up the tree
211
207
  def class_size
212
- (cn = self.class_wnode) ? cn.wattrs.sum(&:size) : nil
208
+ (cn = self.class_wnode) ? cn.klass.size : nil
213
209
  end
214
210
 
215
- # Find the class wnode matching with the given
216
- # class name
217
- def find_class(class_name=nil)
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.class_wnodes.find { |wn| wn.class_name == class_name }
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
- self.class_wnode
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
- wn_class = find_class(class_name)
240
- raise "Can't find parent class for constant #{c_name}" unless wn_class
241
- class_name = wn_class.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
- wn_class.consts.find { |c| c.class_name == class_name && c.name == c_name }
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
- wn_class = find_class(class_name)
252
- raise "Can't find parent class for wattr #{wa_name}" unless wn_class
253
- class_name = wn_class.class_name
254
- logger.debug "looking for wattr #{wa_name} in class #{class_name} at wnode #{self.class_wnode}..."
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.klass_name, cv_name, value, wtype))
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
- raise "MEthod already exists: #{m}" \
317
- if (m = find_method(method_name, class_name, method_type))
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.klass_name
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.inspect}"
377
+ logger.debug "Created MEthod: #{method}"
326
378
  method
327
379
  end
328
380
 
329
- # method_type is either :instance or :class
381
+ # method_type is either :instance or :class
330
382
  def find_method(method_name, class_name, method_type)
331
- if class_name
332
- class_wnode = find_class(class_name)
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 = class_wnode.methods.find { |m| m.name == method_name && m.class_name == class_name && m.class? }
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 = class_wnode.methods.find { |m| m.name == method_name && m.class_name == class_name && m.instance? }
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.inspect}"
393
+ logger.debug "Found MEthod: #{method}"
347
394
  else
348
- logger.debug "Couldn't find MEthod: #{class_name.inspect},#{method_name.inspect}"
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=nil, method_type=:class)
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, WType::DEFAULT, method_type)
403
+ self.create_method(method_name, class_name, wtype, method_type)
356
404
  end
357
405
 
358
406
  # Find block wnode up the tree
@@ -15,6 +15,7 @@ require_relative '../../utils/log'
15
15
  require_relative './ext/type'
16
16
 
17
17
  class WType
18
+ include Log
18
19
 
19
20
  WASM_TYPE_MAP = {
20
21
  I64: Type::I64,
@@ -1,3 +1,3 @@
1
1
  module Rlang
2
- VERSION = "0.3.1"
2
+ VERSION = "0.4.0"
3
3
  end
@@ -37,4 +37,5 @@ Gem::Specification.new do |spec|
37
37
  spec.add_development_dependency "rake", "~> 12.0"
38
38
  spec.add_development_dependency "minitest", "~> 5.0"
39
39
  spec.add_development_dependency "wasmer", "~> 0.3"
40
+ spec.add_development_dependency "simplecov", "~> 0.18"
40
41
  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.3.1
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-01 00:00:00.000000000 Z
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