rlang 0.5.0 → 0.5.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -3
- data/Gemfile.lock +1 -1
- data/README.md +8 -6
- data/bin/rlang +13 -5
- data/docs/RlangCompiler.md +3 -1
- data/docs/RlangManual.md +36 -9
- data/examples/fib/fib.rb +5 -1
- data/lib/builder/rlang/compiler.rb +2 -21
- data/lib/rlang.rb +3 -0
- data/lib/rlang/lib/array/array32.rb +9 -2
- data/lib/rlang/lib/array/array64.rb +6 -1
- data/lib/rlang/lib/io.rb +70 -0
- data/lib/rlang/lib/kernel.rb +7 -2
- data/lib/rlang/lib/malloc.rb +2 -2
- data/lib/rlang/lib/object.rb +6 -0
- data/lib/rlang/lib/rlang.rb +29 -0
- data/lib/rlang/lib/rlang_core.rb +14 -0
- data/lib/rlang/lib/string.rb +14 -1
- data/lib/rlang/lib/type/i32.rb +25 -0
- data/lib/rlang/lib/type/i64.rb +4 -0
- data/lib/rlang/lib/wasi.rb +133 -0
- data/lib/rlang/parser.rb +134 -22
- data/lib/rlang/parser/const.rb +1 -1
- data/lib/rlang/parser/cvar.rb +2 -2
- data/lib/rlang/parser/data.rb +7 -4
- data/lib/rlang/parser/export.rb +4 -3
- data/lib/rlang/parser/global.rb +3 -2
- data/lib/rlang/parser/method.rb +15 -2
- data/lib/rlang/parser/wgenerator.rb +72 -16
- data/lib/rlang/parser/wnode.rb +55 -12
- data/lib/rlang/version.rb +1 -1
- metadata +6 -3
- data/lib/rlang/lib.rb +0 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 38b11b7ed747a6a72f0a46a2c498efef419039a9bf85b5ba6442b7fd8f5300fc
|
4
|
+
data.tar.gz: 2e1c220542d7b7356c6b963edb2d34e45cdbd0cd556dec6a718a4f663b5651b5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 71fc2a6a83c414edbc2dbfca1b1e465a1d265ba80350101e4536178e1959ccf4a823478c7c139acde6d3e88d56d25d0a2fd9d4a781b2c1da919b4de0f5a4268a
|
7
|
+
data.tar.gz: 65969682077beb48030e5f9ffff0f1d97aa2ee2ea48e2142feac74e3a687661aa5b7afcbb8db26b8b1da8936e7dbeca4d09e9a8be5108dda8dd6325fb15a3c99
|
data/CHANGELOG.md
CHANGED
@@ -1,9 +1,12 @@
|
|
1
|
+
## 0.5.1
|
2
|
+
* Imported WASM methods can now be defined
|
3
|
+
* Preliminary version of WASI interface and IO class added to Rlang library
|
4
|
+
|
1
5
|
## 0.5.0
|
2
|
-
* Class attributes
|
3
|
-
* Very preliminary version of Rlang String class
|
6
|
+
* Class attributes syntax now identical to plain Ruby
|
4
7
|
* Class in class definition and module supported
|
5
8
|
* Class inheritance
|
6
|
-
* Basic
|
9
|
+
* Basic Array and String class in Rlang library
|
7
10
|
|
8
11
|
## 0.4.0
|
9
12
|
* Object instances, instance methods and instance variables now supported
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Rlang : a
|
1
|
+
# Rlang : a Ruby-like language compiled to WebAssembly
|
2
2
|
|
3
3
|
Rlang is meant to generate fast and uncluttered [WebAssembly](https://webassembly.org) code from the comfort of the Ruby language.
|
4
4
|
|
@@ -6,14 +6,12 @@ Rlang is actually two things: 1) a subset of the Ruby language and 2) a **compil
|
|
6
6
|
|
7
7
|
So in summary what Rlang does is:
|
8
8
|
<p align="center"><b>
|
9
|
-
|
9
|
+
Rlang source code → Rlang compiler → WebAssembly bytecode
|
10
10
|
</b></p>
|
11
11
|
|
12
|
-
Rlang must not be confused with other projects claiming to "compile" Ruby to WebAssembly. What they really do is to actually compile a mruby VM written in C in Webassembly (using tools like emscripten) and then run that VM in a Webassembly runtime.
|
13
|
-
|
14
12
|
Rlang can be seen as a foundational language that can help you quickly develop and debug high performance WebAssembly modules. For the rationale behind the creation of Rlang see [below](#why-rlang).
|
15
13
|
|
16
|
-
This is still a young project but Rlang has already been successfully tested with some real code such as the dynamic memory allocator provided with the Rlang library. It will keep
|
14
|
+
This is still a young project but Rlang has already been successfully tested with some real code such as the dynamic memory allocator provided with the Rlang library. It will keep improving over time, always with the goal of generating crisp and uncluttered WebAssembly code.
|
17
15
|
|
18
16
|
If you want to help with Rlang see [How you can help](#how-you-can-help).
|
19
17
|
|
@@ -22,6 +20,8 @@ If you want to help with Rlang see [How you can help](#how-you-can-help).
|
|
22
20
|
* **WABT toolkit**: the rlang compiler can generate both WebAssembly source code (WAT file) and WebAssembly bytecode (WASM file). To generate WASM bytecode the rlang compiler uses wat2wasm. This utility is part of the [WABT toolkit](https://github.com/WebAssembly/wabt)
|
23
21
|
* **wasmer runtime** (optional): [Wasmer](https://wasmer.io/) is a fast WebAssembly runtime. You'll need it if you want to run the test suite from the source repo. You can also use it to run the compiled WASM code generated by the rlang compiler. You can get Wasmer at [wasmer.io](https://wasmer.io/)
|
24
22
|
|
23
|
+
Rlang has also been successfully tested with the [Wasmtime](https://wasmtime.dev/) WebAssembly runtime.
|
24
|
+
|
25
25
|
|
26
26
|
## Installing Rlang
|
27
27
|
Rlang is available as a gem from rubygems.org. So simply run the following command to install it:
|
@@ -78,7 +78,9 @@ This project was created out of the need to develop a Virtual Machine written in
|
|
78
78
|
|
79
79
|
After a first proof of concept written directly by hand in WebAssembly (WAT source code) it became clear that writing a full fledged VM directly in WebAssembly was going to be tedious, complex and unnecessarily painful.
|
80
80
|
|
81
|
-
Sure I could have written this VM in any of the language that can already be compiled directly to WebAssembly (C, C++, Rust, Go,...) but being fond of Ruby since 2000 I decided that I would go for a compiler capable of transforming a subset of the Ruby language directly into WebAssembly with a minimum overhead.
|
81
|
+
Sure I could have written this VM in any of the language that can already be compiled directly to WebAssembly (C, C++, Rust, Go,...) but being fond of Ruby since 2000 I decided that I would go for a compiler capable of transforming a subset of the Ruby language directly into WebAssembly with a minimum overhead.
|
82
|
+
|
83
|
+
So in a nutshell: the goal of Rlang is to let you develop efficient WebAssembly code with a reasonably high level of abstraction while keeping the generated WebAssembly code straightforward, human readable and slim.
|
82
84
|
|
83
85
|
## Why the name Rlang?
|
84
86
|
Yes I hear you: Rlang is already the name of the R language so why use that name and aren't you introducing some confusion? Well for one I couldn't resist using that name to honor software engineering history (see below) and because, after all, the intersection between the Ruby/WebAssembly community and the R language community focused on data processing and machine learning must be quite small to say the least.
|
data/bin/rlang
CHANGED
@@ -13,13 +13,16 @@
|
|
13
13
|
|
14
14
|
require 'optparse'
|
15
15
|
require 'fileutils'
|
16
|
-
require 'rlang'
|
16
|
+
require 'rlang' # setup RLANG_BASE_DIR
|
17
17
|
require 'builder'
|
18
18
|
|
19
|
+
RLANG_LIB_DIR = File.expand_path('./rlang/lib', RLANG_BASE_DIR)
|
20
|
+
|
19
21
|
include Log
|
20
22
|
logger.level = Logger::INFO
|
21
23
|
|
22
24
|
options = {}
|
25
|
+
custom_load_path = []
|
23
26
|
OptionParser.new do |opts|
|
24
27
|
opts.banner = %q{Usage: rlang [options] filename
|
25
28
|
read a Rlang file, check it for errors, and convert it
|
@@ -39,8 +42,8 @@ options:
|
|
39
42
|
}
|
40
43
|
|
41
44
|
opts.on("-I DIR", "--load_path DIRECTORY", "specify $LOAD_PATH directory (may be used more than once)") do |dir|
|
42
|
-
|
43
|
-
|
45
|
+
custom_load_path ||= []
|
46
|
+
custom_load_path << dir
|
44
47
|
end
|
45
48
|
|
46
49
|
opts.on("-M", "--module NAME", "WASM module name") do |name|
|
@@ -67,6 +70,10 @@ options:
|
|
67
70
|
options[:wasm] = v
|
68
71
|
end
|
69
72
|
|
73
|
+
opts.on("-S", "--start FUNCTION", "Function name where execution starts (default '_start')") do |function|
|
74
|
+
options[:start] = function
|
75
|
+
end
|
76
|
+
|
70
77
|
opts.on("-o", "--output FILE", "Write output to file") do |file|
|
71
78
|
options[:output] = file
|
72
79
|
end
|
@@ -87,9 +94,10 @@ options:
|
|
87
94
|
end
|
88
95
|
end.parse!(ARGV)
|
89
96
|
|
90
|
-
options[:module]
|
97
|
+
options[:module] ||= ''
|
91
98
|
options[:memory_min] ||= 4
|
92
|
-
options[:LOAD_PATH]
|
99
|
+
options[:LOAD_PATH] = custom_load_path << RLANG_LIB_DIR
|
100
|
+
options[:start] ||= '_start'
|
93
101
|
|
94
102
|
fh_out = options[:output] ? File.open(options[:output], 'w') : STDOUT
|
95
103
|
|
data/docs/RlangCompiler.md
CHANGED
@@ -19,6 +19,7 @@ Usage: rlang [options] rlang_file.rb
|
|
19
19
|
-w, --wat Generate WAT source file
|
20
20
|
-a, --ast Generate Ruby AST file
|
21
21
|
-s, --wasm Generate WASM bytecode file
|
22
|
+
-S, --start FUNCTION Function name where execution starts (default '_start')
|
22
23
|
-o, --output FILE Write output to file
|
23
24
|
-v, --verbose [LEVEL] Verbosity level (fatal, error, warn, info, debug)
|
24
25
|
-V, --version Displays Rlang version
|
@@ -30,7 +31,8 @@ Usage: rlang [options] rlang_file.rb
|
|
30
31
|
* **-m, --memory MIN[,MAX]**: size of the WASM memory allocated at run time. The first argument is the initial amount of memory allocated and the second one (optional) is the maximum memory that your WASM module can allocate while running. The unit of both arguments is in number of WASM pages (4 KBytes)
|
31
32
|
* **-w, --wat**: parse Rlang file and generate WAT source code
|
32
33
|
* **-a, --ast**: parse Rlang file and generate the Ruby abstract syntax tree
|
33
|
-
* **-
|
34
|
+
* **-s, --wasm**: parse Rlang file, generate WAT source code and compile it to WASM bytecode
|
35
|
+
* **-S, --start**: function to use as the execution starting point of the WASM module (default is `_start`)
|
34
36
|
* **-o, --output FILE**: send rlang output to FILE
|
35
37
|
* **-v, --verbose [LEVEL]**: verbosity level (fatal, error, warn, info, debug). Default is warn
|
36
38
|
* **-V, --version**: Displays Rlang version
|
data/docs/RlangManual.md
CHANGED
@@ -6,10 +6,6 @@ Ruby programmers will feel at home with Rlang and non Ruby programmers will find
|
|
6
6
|
|
7
7
|
Still, to make this Ruby to WebAssembly compilation possible a number of trade-offs had to be made. The goal of this document is to explain the features of Rlang are how it differs from plain Ruby.
|
8
8
|
|
9
|
-
## The Rlang object model
|
10
|
-
|
11
|
-
In Rlang you can define classes and those classes can be instantiated either statically at compile time or dynamically at runtime. There is no inheritance mechanism today between classes in the current version. Classes cannot be nested.
|
12
|
-
|
13
9
|
## What Rlang does
|
14
10
|
|
15
11
|
Rlang provides:
|
@@ -84,6 +80,12 @@ end
|
|
84
80
|
```
|
85
81
|
A Class in RLang can also inherit from another class as in Ruby. Whan a superclass is not specified, a newly defined class automatically inherits from the Object class.
|
86
82
|
|
83
|
+
If you need to use a class name in your code before the class is actually processed by the compiler you can use the following empty class notation to declare that the corresponding constant is actually a class. You can later reopen the class definition and define methods.
|
84
|
+
|
85
|
+
```ruby
|
86
|
+
class String; end
|
87
|
+
```
|
88
|
+
|
87
89
|
|
88
90
|
### Class attributes and instance variables
|
89
91
|
Rlang support both the use of class attributes and instance variables. Class attribute declaration is happening through the `attr_accessor`, `attr_reader` or `attr_writer` directives as in plain Ruby. It actually defines a couple of things for you:
|
@@ -147,6 +149,7 @@ class Test
|
|
147
149
|
# ...
|
148
150
|
end
|
149
151
|
```
|
152
|
+
The address in memory of both class variables and constants can be accessed by using the `addr` method as in `SQUARE.addr` for instance.
|
150
153
|
|
151
154
|
**IMPORTANT NOTE**: in the current version of Rlang the new method call used to allocate static objects doesn't do any initialization. That's why the new method in this context (class body or top level) doesn't accept any parameter.
|
152
155
|
|
@@ -180,7 +183,7 @@ class Main
|
|
180
183
|
cube = Cube.new(10, 20, 30)
|
181
184
|
v = cube.volume
|
182
185
|
# ... Do what ever you have to do...
|
183
|
-
|
186
|
+
cube.free
|
184
187
|
end
|
185
188
|
end
|
186
189
|
```
|
@@ -246,7 +249,9 @@ end
|
|
246
249
|
The `local` directive above instructs the compiler that `lvar` is of type `:I64` and the local variable mysquare is of type `Square`. Without it `lvar` would have been auto-vivified with the Wasm default type or `:I32`.
|
247
250
|
|
248
251
|
### Exporting a method
|
249
|
-
In WebAssembly, you can make functions visible to the outside world by declaring them in the export section. To achieve a similar result in Rlang, you can use the `export` keyword right before a method definition.
|
252
|
+
In WebAssembly, you can make functions visible to the outside world by declaring them in the export section. To achieve a similar result in Rlang, you can use the `export` keyword right before a method definition with an optional export name of your choice.
|
253
|
+
|
254
|
+
If no function name is specified, Rlang will build it for you. WASM exported functions are named after the class name (in lower case), the method type (class or instance) and the method name. As an example the exported method in the example above will be known to the WASM runtime as the `myclass_c_visible` function (where the `_c_` means it's a class function and `_i_` an instance method).
|
250
255
|
|
251
256
|
```ruby
|
252
257
|
class MyClass
|
@@ -256,18 +261,40 @@ class MyClass
|
|
256
261
|
# ...
|
257
262
|
end
|
258
263
|
|
264
|
+
export :seeable
|
265
|
+
def self.visible_too(arg1)
|
266
|
+
# ...
|
267
|
+
end
|
268
|
+
|
259
269
|
def self.not_visible
|
260
270
|
# ...
|
261
271
|
end
|
262
272
|
end
|
263
273
|
```
|
264
274
|
|
265
|
-
Note that the `export` keyword only applies to the method definition that immediately follows. In the example above `MyClass::
|
275
|
+
Note that the `export` keyword only applies to the method definition that immediately follows. In the example above `MyClass::visible` and `MyClass::visible_too` will be exported by the generated WASM module whereas `MyClass::not_visible` will not.
|
276
|
+
|
277
|
+
### Importing a method
|
278
|
+
An import statement in WebAssembly is a way to declare the signature of a method defined outside of the current WebAssembly module and then call it from your code.
|
279
|
+
|
280
|
+
Rlang has an equivalent import statement as shown in the example below:
|
281
|
+
```ruby
|
282
|
+
import :wasi_unstable, :proc_exit
|
283
|
+
def self.proc_exit(exitcode)
|
284
|
+
arg exitcode: :I32
|
285
|
+
result :none
|
286
|
+
end
|
287
|
+
```
|
288
|
+
|
289
|
+
The first 2 arguments of import are the imported module name and function name as in WebAssembly and then follows a regular method definition with arguments and possibly the `arg` directive to specify argument types and a `result` directive to indicate the nature of the returned value. Two points worth highlighting here:
|
290
|
+
1. The Rlang method name doesn't have to be the same as the function name in the import statement.
|
291
|
+
2. As imported function are external to your Rlang module they must be declared as class methods. This is bacause defining them as instance method would automatically pass `self` as the first argument in the method call therefore changing the signature of the method.
|
292
|
+
|
293
|
+
The example above is taken from the Rlang WASI class that defines the interface with [WASI (WebAssembly System Interface)](https::wasi.dev).
|
266
294
|
|
267
|
-
WASM exported functions are named after the class name (in lower case) followed by an underscore and the method name. So the exported method in the example above is known to the WASM runtime as the `myclass_c_visible` function (where the `_c_` means it's a class function and `_i_` an instance method)
|
268
295
|
|
269
296
|
## Rlang types
|
270
|
-
The types currently supported by Rlang are integers either long (`:I32`) or double (`:I64`) or a class type. Float types (
|
297
|
+
The types currently supported by Rlang are integers either long (`:I32`) or double (`:I64`) or a class type. Float types (`:F32`, `:F64`) may follow in a future version. By default Rlang assumes that any integer literal, variable, argument,... is of type `:I32`. If you need it to be of a different type you must state it explicitely in the method body (see above).
|
271
298
|
|
272
299
|
### Implicit type cast
|
273
300
|
Only in rare cases will you use the `local` directive in methods as Rlang does its best to infer the type of a variable from its first assigned value. As an example, in the code below, the fact that `arg1` is known to be an `:I64` type of argument is enough to auto-magically create lvar as in `:I64` local variable too.
|
data/examples/fib/fib.rb
CHANGED
@@ -17,23 +17,10 @@ module Builder::Rlang
|
|
17
17
|
# WAT source frame
|
18
18
|
WAT_FRAME = %q{
|
19
19
|
;; Generated by Rlang compiler version %{version} on %{time}\n"
|
20
|
-
(module %{module}
|
21
|
-
(memory $0 %{memory_min} %{memory_max})
|
22
20
|
|
23
|
-
|
24
|
-
(export "memory" (memory $0))
|
25
|
-
%{exports}
|
21
|
+
%{code}
|
26
22
|
|
27
|
-
|
28
|
-
%{globals}
|
29
|
-
|
30
|
-
;; ======= STATIC DATA =======
|
31
|
-
%{data}
|
32
|
-
|
33
|
-
;; ======= CODE =======
|
34
|
-
%{code}
|
35
|
-
)
|
36
|
-
}
|
23
|
+
}
|
37
24
|
|
38
25
|
# source: Path to Rlang file (.rb)
|
39
26
|
# target: Path to Wat file (.wat)
|
@@ -64,12 +51,6 @@ module Builder::Rlang
|
|
64
51
|
end
|
65
52
|
@tf.write(WAT_FRAME % {version: Rlang::VERSION,
|
66
53
|
time: Time.now,
|
67
|
-
module: @options[:module],
|
68
|
-
memory_min: @options[:memory_min],
|
69
|
-
memory_max: @options[:memory_max],
|
70
|
-
exports: Rlang::Parser::Export.transpile,
|
71
|
-
globals: Rlang::Parser::Global.transpile,
|
72
|
-
data: Rlang::Parser::DAta.transpile,
|
73
54
|
code: @wgenerator.root.transpile
|
74
55
|
})
|
75
56
|
@tf.close
|
data/lib/rlang.rb
CHANGED
@@ -5,13 +5,14 @@
|
|
5
5
|
# 4 bytes object array class
|
6
6
|
require_relative '../memory'
|
7
7
|
require_relative '../kernel'
|
8
|
-
require_relative '../
|
9
|
-
require_relative '../string'
|
8
|
+
#require_relative '../string'
|
10
9
|
|
11
10
|
|
12
11
|
class Array32
|
13
12
|
attr_reader :count, :ptr
|
14
13
|
|
14
|
+
result :Kernel, :raise, :none
|
15
|
+
|
15
16
|
# count: number of elements in Array
|
16
17
|
# Array elements are native types or
|
17
18
|
# pointers to objects
|
@@ -40,4 +41,10 @@ class Array32
|
|
40
41
|
value
|
41
42
|
end
|
42
43
|
|
44
|
+
def free
|
45
|
+
result :none
|
46
|
+
Object.free(@ptr)
|
47
|
+
Object.free(self)
|
48
|
+
end
|
49
|
+
|
43
50
|
end
|
@@ -4,7 +4,6 @@
|
|
4
4
|
#
|
5
5
|
# 4 bytes object array class
|
6
6
|
require_relative '../memory'
|
7
|
-
require_relative '../kernel'
|
8
7
|
require_relative '../object'
|
9
8
|
require_relative '../string'
|
10
9
|
|
@@ -40,4 +39,10 @@ class Array64
|
|
40
39
|
value
|
41
40
|
end
|
42
41
|
|
42
|
+
def free
|
43
|
+
result :none
|
44
|
+
Object.free(@ptr)
|
45
|
+
Object.free(self)
|
46
|
+
end
|
47
|
+
|
43
48
|
end
|
data/lib/rlang/lib/io.rb
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
# Rubinius WebAssembly VM
|
2
|
+
# Copyright (c) 2019-2020, Laurent Julliard and contributors
|
3
|
+
# All rights reserved.
|
4
|
+
#
|
5
|
+
# IO class for all basic input and output operations
|
6
|
+
|
7
|
+
require_relative './wasi'
|
8
|
+
|
9
|
+
class IO
|
10
|
+
attr_accessor :fd
|
11
|
+
|
12
|
+
@@num_bytes_written = 0
|
13
|
+
@@num_bytes_read = 0
|
14
|
+
|
15
|
+
def initialize(fd)
|
16
|
+
@fd = fd
|
17
|
+
end
|
18
|
+
|
19
|
+
def write(stg)
|
20
|
+
arg stg: :String
|
21
|
+
ciovec = WASI::CIOVec.new(1)
|
22
|
+
ciovec << stg
|
23
|
+
errno = WASI.fd_write(@fd, ciovec.ciovs.ptr, 1, @@num_bytes_written.addr)
|
24
|
+
ciovec.free
|
25
|
+
errno
|
26
|
+
end
|
27
|
+
|
28
|
+
def print(stg)
|
29
|
+
self.write(stg)
|
30
|
+
end
|
31
|
+
|
32
|
+
def puts(stg)
|
33
|
+
arg stg: :String
|
34
|
+
result :none
|
35
|
+
ciovec = WASI::CIOVec.new(2)
|
36
|
+
ciovec << stg
|
37
|
+
ciovec << "\n"
|
38
|
+
errno = WASI.fd_write(@fd, ciovec.ciovs.ptr, 2, @@num_bytes_written.addr)
|
39
|
+
ciovec.free
|
40
|
+
end
|
41
|
+
|
42
|
+
def read
|
43
|
+
result :I32 #:String
|
44
|
+
iovec = WASI::IOVec.new(1)
|
45
|
+
errno = WASI.fd_read(@fd, iovec.iovs.ptr, 1, @@num_bytes_read.addr)
|
46
|
+
# -1 below because of \0 terminated string
|
47
|
+
String.new(iovec.iovs[0], @@num_bytes_read-1)
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
STDIN = IO.new
|
53
|
+
STDOUT = IO.new
|
54
|
+
STDERR = IO.new
|
55
|
+
|
56
|
+
module Kernel
|
57
|
+
|
58
|
+
def puts(stg)
|
59
|
+
arg stg: :String
|
60
|
+
result :none
|
61
|
+
STDOUT.puts(stg)
|
62
|
+
end
|
63
|
+
|
64
|
+
def print(stg)
|
65
|
+
arg stg: :String
|
66
|
+
result :none
|
67
|
+
STDOUT.print(stg)
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
data/lib/rlang/lib/kernel.rb
CHANGED
@@ -3,15 +3,20 @@
|
|
3
3
|
# All rights reserved.
|
4
4
|
#
|
5
5
|
# Kernel methods
|
6
|
+
#
|
7
|
+
# Most of the Kernel methods are defined in other files
|
8
|
+
# to avoid requiring classes that rely on Kernel methods
|
9
|
+
# themselves.
|
6
10
|
|
7
|
-
|
11
|
+
class String; end
|
8
12
|
|
9
13
|
module Kernel
|
10
14
|
|
11
15
|
def raise(msg)
|
12
16
|
arg msg: :String
|
13
17
|
result :none
|
14
|
-
|
18
|
+
#$! = msg
|
19
|
+
#STDERR.puts msg
|
15
20
|
inline wat: '(unreachable)', wtype: :none
|
16
21
|
end
|
17
22
|
|
data/lib/rlang/lib/malloc.rb
CHANGED
@@ -8,8 +8,8 @@
|
|
8
8
|
# For a detailed explanation of the allocator code see
|
9
9
|
# https://gnuchops.wordpress.com/2013/02/26/memory-allocator-for-embedded-system-k-r-ritchie-book/
|
10
10
|
|
11
|
-
|
12
|
-
|
11
|
+
require_relative './memory'
|
12
|
+
require_relative './unistd'
|
13
13
|
|
14
14
|
# minimum number of units to request
|
15
15
|
$NALLOC = 1024
|