rlang 0.3.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 +7 -0
- data/.gitignore +10 -0
- data/.rake_tasks~ +0 -0
- data/.travis.yml +7 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +4 -0
- data/LICENSE +373 -0
- data/README.md +61 -0
- data/Rakefile +10 -0
- data/bin/rlang +164 -0
- data/docs/RlangCompiler.md +37 -0
- data/docs/RlangManual.md +391 -0
- data/lib/builder/ext/tempfile.rb +7 -0
- data/lib/builder/ext.rb +5 -0
- data/lib/builder/rlang/builder.rb +31 -0
- data/lib/builder/rlang.rb +2 -0
- data/lib/builder/wat/builder.rb +52 -0
- data/lib/builder/wat/renderer.rb +28 -0
- data/lib/builder/wat.rb +3 -0
- data/lib/builder.rb +7 -0
- data/lib/rlang/lib/malloc.c +97 -0
- data/lib/rlang/lib/malloc.rb +169 -0
- data/lib/rlang/lib/memory.rb +11 -0
- data/lib/rlang/lib/type/i32.rb +7 -0
- data/lib/rlang/lib/type/i64.rb +7 -0
- data/lib/rlang/lib/type.rb +6 -0
- data/lib/rlang/lib/unistd.rb +47 -0
- data/lib/rlang/lib.rb +10 -0
- data/lib/rlang/parser/const.rb +15 -0
- data/lib/rlang/parser/cvar.rb +44 -0
- data/lib/rlang/parser/data.rb +105 -0
- data/lib/rlang/parser/export.rb +22 -0
- data/lib/rlang/parser/ext/integer.rb +5 -0
- data/lib/rlang/parser/ext/string.rb +5 -0
- data/lib/rlang/parser/ext/type.rb +64 -0
- data/lib/rlang/parser/global.rb +65 -0
- data/lib/rlang/parser/lvar.rb +29 -0
- data/lib/rlang/parser/marg.rb +30 -0
- data/lib/rlang/parser/method.rb +76 -0
- data/lib/rlang/parser/wattr.rb +65 -0
- data/lib/rlang/parser/wgenerator.rb +509 -0
- data/lib/rlang/parser/winstruction.rb +148 -0
- data/lib/rlang/parser/wnode.rb +455 -0
- data/lib/rlang/parser/wtree.rb +19 -0
- data/lib/rlang/parser/wtype.rb +116 -0
- data/lib/rlang/parser.rb +1842 -0
- data/lib/rlang/version.rb +3 -0
- data/lib/rlang.rb +4 -0
- data/lib/simul/classes/data.rb +80 -0
- data/lib/simul/classes/global.rb +38 -0
- data/lib/simul/classes/memory.rb +131 -0
- data/lib/utils/log.rb +32 -0
- data/rlang.gemspec +38 -0
- metadata +158 -0
@@ -0,0 +1,64 @@
|
|
1
|
+
module Type
|
2
|
+
|
3
|
+
class I64 < Numeric
|
4
|
+
MAX = 2**64 - 1
|
5
|
+
def size; 8; end # size in bytes
|
6
|
+
def self.size; 8; end # size in bytes
|
7
|
+
def wasm_type; 'i64'; end
|
8
|
+
def self.wasm_type; 'i64'; end
|
9
|
+
end
|
10
|
+
|
11
|
+
class I32 < Numeric
|
12
|
+
MAX = 2**64 - 1
|
13
|
+
def initialize(v); @v = Integer(v); end
|
14
|
+
def +(v); I32.new(v + @v); end
|
15
|
+
def size; 4; end # size in bytes
|
16
|
+
def self.size; 4; end # size in bytes
|
17
|
+
def wasm_type; 'i32'; end
|
18
|
+
def self.wasm_type; 'i32'; end
|
19
|
+
end
|
20
|
+
|
21
|
+
class F64 < Numeric
|
22
|
+
MAX = 1.7976931348623158E308
|
23
|
+
def size; 8; end # size in bytes
|
24
|
+
def wasm_type; 'f64'; end
|
25
|
+
def self.size; 8; end # size in bytes
|
26
|
+
def self.wasm_type; 'f64'; end
|
27
|
+
end
|
28
|
+
|
29
|
+
class F32 < Numeric
|
30
|
+
MAX = 3.4028235E38
|
31
|
+
# size in bytes
|
32
|
+
def size; 4; end
|
33
|
+
def wasm_type; 'f32'; end
|
34
|
+
def self.size; 4; end
|
35
|
+
def self.wasm_type; 'f32'; end
|
36
|
+
end
|
37
|
+
|
38
|
+
class Numeric
|
39
|
+
def type
|
40
|
+
if self.is_a? Integer
|
41
|
+
if self <= I32::MAX
|
42
|
+
'i32'
|
43
|
+
elsif self <= I64::MAX
|
44
|
+
'i64'
|
45
|
+
else
|
46
|
+
raise "Integer value too large #{self}"
|
47
|
+
end
|
48
|
+
elsif self.is_a? Float
|
49
|
+
if self <= F32::MAX
|
50
|
+
'f32'
|
51
|
+
elsif self <= F64::MAX
|
52
|
+
'f64'
|
53
|
+
else
|
54
|
+
raise "Float value too large #{self}"
|
55
|
+
end
|
56
|
+
else
|
57
|
+
raise "Unknown value type #{self.class} for #{self}"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
DEFAULT = Type::I32
|
63
|
+
|
64
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# Rubinius WebAssembly VM
|
2
|
+
# Copyright (c) 2019, Laurent Julliard and contributors
|
3
|
+
# All rights reserved.
|
4
|
+
|
5
|
+
# Class variables
|
6
|
+
|
7
|
+
require_relative './wtype'
|
8
|
+
require_relative './export'
|
9
|
+
|
10
|
+
module Rlang::Parser
|
11
|
+
class Global
|
12
|
+
@@globals = []
|
13
|
+
attr_accessor :name, :wtype, :mutable, :value
|
14
|
+
|
15
|
+
def initialize(name, wtype=WType::DEFAULT, value=0, mutable=true)
|
16
|
+
@name = name
|
17
|
+
@wtype = wtype
|
18
|
+
@mutable = mutable
|
19
|
+
@value = value
|
20
|
+
@@globals << self
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.find(name)
|
24
|
+
@@globals.find {|g| g.name == name}
|
25
|
+
end
|
26
|
+
|
27
|
+
def mutable?
|
28
|
+
@mutable
|
29
|
+
end
|
30
|
+
|
31
|
+
def wasm_name
|
32
|
+
@name
|
33
|
+
end
|
34
|
+
|
35
|
+
def wasm_type
|
36
|
+
@wtype.wasm_type
|
37
|
+
end
|
38
|
+
|
39
|
+
def export_name
|
40
|
+
@name
|
41
|
+
end
|
42
|
+
|
43
|
+
def export!
|
44
|
+
Export.new(self)
|
45
|
+
end
|
46
|
+
|
47
|
+
def export_wasm_code
|
48
|
+
'(export "%s" (global %s (mut %s)))' % [self.export_name, self.wasm_name, self.wtype.wasm_type]
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.transpile
|
52
|
+
output = []
|
53
|
+
@@globals.each do |g|
|
54
|
+
if g.mutable?
|
55
|
+
output << '(global %{name} (mut %{type}) (%{type}.const %{value}))' \
|
56
|
+
% {name: g.wasm_name, type: g.wtype.wasm_type, value: g.value}
|
57
|
+
else
|
58
|
+
output << '(global %{name} %{type} (%{type}.const %{value}))' \
|
59
|
+
% {name: g.wasm_name, type: g.wtype.wasm_type, value: g.value}
|
60
|
+
end
|
61
|
+
end
|
62
|
+
output.join("\n")
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# Rubinius WebAssembly VM
|
2
|
+
# Copyright (c) 2019, Laurent Julliard and contributors
|
3
|
+
# All rights reserved.
|
4
|
+
|
5
|
+
# Local variables
|
6
|
+
|
7
|
+
require_relative './wtype'
|
8
|
+
|
9
|
+
module Rlang::Parser
|
10
|
+
class LVar
|
11
|
+
attr_reader :name
|
12
|
+
attr_accessor :wtype
|
13
|
+
|
14
|
+
def initialize(name, wtype=WType::DEFAULT)
|
15
|
+
@name = name
|
16
|
+
# TODO: check if local/param value wtype
|
17
|
+
# was explicitely declared
|
18
|
+
@wtype = wtype
|
19
|
+
end
|
20
|
+
|
21
|
+
def wasm_name
|
22
|
+
"$#{name}"
|
23
|
+
end
|
24
|
+
|
25
|
+
def wasm_type
|
26
|
+
@wtype.wasm_type
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# Rubinius WebAssembly VM
|
2
|
+
# Copyright (c) 2019, Laurent Julliard and contributors
|
3
|
+
# All rights reserved.
|
4
|
+
|
5
|
+
# Method argument class
|
6
|
+
|
7
|
+
require_relative '../../utils/log'
|
8
|
+
require_relative './wtype'
|
9
|
+
|
10
|
+
module Rlang::Parser
|
11
|
+
class MArg
|
12
|
+
include Log
|
13
|
+
attr_reader :name
|
14
|
+
attr_accessor :wtype
|
15
|
+
|
16
|
+
def initialize(name, wtype=WType::DEFAULT)
|
17
|
+
@name = name
|
18
|
+
@wtype = wtype
|
19
|
+
logger.debug "Method argument #{name} created"
|
20
|
+
end
|
21
|
+
|
22
|
+
def wasm_name
|
23
|
+
"$#{@name}"
|
24
|
+
end
|
25
|
+
|
26
|
+
def wasm_type
|
27
|
+
@wtype.wasm_type
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# Rubinius WebAssembly VM
|
2
|
+
# Copyright (c) 2019, Laurent Julliard and contributors
|
3
|
+
# All rights reserved.
|
4
|
+
|
5
|
+
# Class variables
|
6
|
+
require_relative '../../utils/log'
|
7
|
+
require_relative './wtype'
|
8
|
+
require_relative './export'
|
9
|
+
|
10
|
+
module Rlang::Parser
|
11
|
+
# Note: Cannot use Method as class name
|
12
|
+
# because it's already used by Ruby
|
13
|
+
class MEthod
|
14
|
+
include Log
|
15
|
+
|
16
|
+
attr_reader :name, :wtype
|
17
|
+
attr_accessor :class_name
|
18
|
+
|
19
|
+
def initialize(name, class_name, wtype=WType::DEFAULT)
|
20
|
+
@name = name
|
21
|
+
@class_name = class_name
|
22
|
+
@wtype = wtype
|
23
|
+
@instance = false
|
24
|
+
logger.debug "Method instance created #{self.inspect}"
|
25
|
+
end
|
26
|
+
|
27
|
+
def instance!
|
28
|
+
@instance = true
|
29
|
+
end
|
30
|
+
|
31
|
+
def instance?
|
32
|
+
@instance
|
33
|
+
end
|
34
|
+
|
35
|
+
def class!
|
36
|
+
@instance = false
|
37
|
+
end
|
38
|
+
|
39
|
+
def class?
|
40
|
+
!@instance
|
41
|
+
end
|
42
|
+
|
43
|
+
def wtype=(wtype)
|
44
|
+
@wtype = wtype
|
45
|
+
logger.debug "Method wtype updated: #{self.inspect}"
|
46
|
+
end
|
47
|
+
|
48
|
+
def wasm_name
|
49
|
+
if @instance
|
50
|
+
"$#{@class_name}##{@name}"
|
51
|
+
else
|
52
|
+
"$#{@class_name}::#{@name}"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def wasm_type
|
57
|
+
@wtype.wasm_type
|
58
|
+
end
|
59
|
+
|
60
|
+
def export_name
|
61
|
+
if @instance
|
62
|
+
"#{@class_name.downcase}_i_#{@name}"
|
63
|
+
else
|
64
|
+
"#{@class_name.downcase}_c_#{@name}"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def export!
|
69
|
+
Export.new(self)
|
70
|
+
end
|
71
|
+
|
72
|
+
def export_wasm_code
|
73
|
+
'(export "%s" (func %s))' % [self.export_name, self.wasm_name]
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# Rubinius WebAssembly VM
|
2
|
+
# Copyright (c) 2019, Laurent Julliard and contributors
|
3
|
+
# All rights reserved.
|
4
|
+
|
5
|
+
# Method argument class
|
6
|
+
|
7
|
+
require_relative '../../utils/log'
|
8
|
+
require_relative './wtype'
|
9
|
+
|
10
|
+
module Rlang::Parser
|
11
|
+
class WAttr
|
12
|
+
include Log
|
13
|
+
attr_reader :name, :wtype, :getter, :setter
|
14
|
+
|
15
|
+
def initialize(class_wnode, name, wtype=WType::DEFAULT)
|
16
|
+
@class_wnode = class_wnode
|
17
|
+
@name = name
|
18
|
+
@wtype = wtype
|
19
|
+
# Also create the corresponding getter and setter
|
20
|
+
# method objects (with default WType - wattr_type
|
21
|
+
# directives might later change this wtype)
|
22
|
+
# Don't generate WAT code yet
|
23
|
+
@getter = @class_wnode.create_method(self.getter_name, nil, wtype, :instance)
|
24
|
+
@getter.instance!
|
25
|
+
logger.debug "Getter created: #{@getter.inspect}"
|
26
|
+
|
27
|
+
@setter = @class_wnode.create_method(self.setter_name, nil, wtype, :instance)
|
28
|
+
@setter.instance!
|
29
|
+
logger.debug "Setter created: #{@setter.inspect}"
|
30
|
+
|
31
|
+
logger.debug "Class attribute #{name} created"
|
32
|
+
end
|
33
|
+
|
34
|
+
def class_name
|
35
|
+
@class_wnode.class_name
|
36
|
+
end
|
37
|
+
|
38
|
+
def wtype=(wtype)
|
39
|
+
@wtype = wtype
|
40
|
+
# Adjust corresponding method objects wtype accordingly
|
41
|
+
@getter.wtype = wtype
|
42
|
+
@setter.wtype = wtype
|
43
|
+
logger.debug "Getter and Setter wtype updated : #{@getter.inspect}"
|
44
|
+
end
|
45
|
+
|
46
|
+
def size
|
47
|
+
@wtype.size
|
48
|
+
end
|
49
|
+
|
50
|
+
def wasm_name
|
51
|
+
"$#{@name}"
|
52
|
+
end
|
53
|
+
|
54
|
+
def getter_name
|
55
|
+
@name
|
56
|
+
end
|
57
|
+
|
58
|
+
def setter_name
|
59
|
+
"#{@name}=".to_sym
|
60
|
+
end
|
61
|
+
def wasm_type
|
62
|
+
@wtype.wasm_type
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|