halunke 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/Gemfile.lock +1 -1
- data/docs/_config.yml +2 -0
- data/docs/_layouts/default.html +16 -12
- data/docs/array.md +65 -0
- data/docs/class.md +103 -0
- data/docs/dictionary.md +48 -0
- data/docs/function.md +18 -0
- data/docs/index.md +12 -6
- data/docs/number.md +106 -0
- data/docs/stdio.md +62 -0
- data/docs/string.md +74 -0
- data/docs/true-false.md +68 -0
- data/docs/web.md +32 -0
- data/examples/counter.hal +22 -0
- data/examples/hello.hal +1 -1
- data/examples/stdio.hal +13 -0
- data/lib/halunke/grammar.y +15 -13
- data/lib/halunke/interpreter.rb +1 -1
- data/lib/halunke/lexer.rb +6 -6
- data/lib/halunke/lexer.rl +1 -1
- data/lib/halunke/parser.rb +40 -53
- data/lib/halunke/runtime.rb +1 -1
- data/lib/halunke/runtime/false.hal +3 -0
- data/lib/halunke/runtime/harray.rb +10 -4
- data/lib/halunke/runtime/hdictionary.rb +15 -6
- data/lib/halunke/runtime/hnumber.rb +13 -1
- data/lib/halunke/runtime/hstdio.rb +22 -0
- data/lib/halunke/runtime/hstring.rb +3 -0
- data/lib/halunke/runtime/true.hal +3 -0
- data/lib/halunke/version.rb +1 -1
- metadata +14 -3
- data/lib/halunke/runtime/hstdout.rb +0 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d378d2686f483584090e764b7d90eeb13b18614c
|
4
|
+
data.tar.gz: 7f280aa4dfe247d55b37b863a8766bf9113fb80f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5d1721feb87183a3be4cb3efd2420cb1b4ca5263fcc525413c64ee1884420441761200227f200572a38f24d9b12e1b12f29ccfcafae05d7498cc3179a9a0dd41
|
7
|
+
data.tar.gz: ae52853223039380e48c35eb867f693a88b257f8510b9d79c67e4e0641d89df3489a3104ebffadc0bcdc5a9edcf588dae68f218e82c36a930f0d5e421bdb1340
|
data/Gemfile.lock
CHANGED
data/docs/_config.yml
CHANGED
data/docs/_layouts/default.html
CHANGED
@@ -10,41 +10,41 @@
|
|
10
10
|
<body>
|
11
11
|
<div class="container">
|
12
12
|
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
|
13
|
-
<a class="navbar-brand" href="
|
13
|
+
<a class="navbar-brand" href="/halunke">Halunke!</a>
|
14
14
|
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
|
15
15
|
<span class="navbar-toggler-icon"></span>
|
16
16
|
</button>
|
17
|
-
<div class="collapse navbar-collapse">
|
17
|
+
<div class="collapse navbar-collapse" id="navbarNav">
|
18
18
|
<ul class="navbar-nav">
|
19
19
|
<li class="nav-item">
|
20
|
-
<a class="nav-link" href="/">Intro</a>
|
20
|
+
<a class="nav-link" href="/halunke">Intro</a>
|
21
21
|
</li>
|
22
22
|
<li class="nav-item">
|
23
|
-
<a class="nav-link" href="/number">Number</a>
|
23
|
+
<a class="nav-link" href="/halunke/number">Number</a>
|
24
24
|
</li>
|
25
25
|
<li class="nav-item">
|
26
|
-
<a class="nav-link" href="/string">String</a>
|
26
|
+
<a class="nav-link" href="/halunke/string">String</a>
|
27
27
|
</li>
|
28
28
|
<li class="nav-item">
|
29
|
-
<a class="nav-link" href="/array">Array</a>
|
29
|
+
<a class="nav-link" href="/halunke/array">Array</a>
|
30
30
|
</li>
|
31
31
|
<li class="nav-item">
|
32
|
-
<a class="nav-link" href="/dictionary">Dictionary</a>
|
32
|
+
<a class="nav-link" href="/halunke/dictionary">Dictionary</a>
|
33
33
|
</li>
|
34
34
|
<li class="nav-item">
|
35
|
-
<a class="nav-link" href="/true-false">True & False</a>
|
35
|
+
<a class="nav-link" href="/halunke/true-false">True & False</a>
|
36
36
|
</li>
|
37
37
|
<li class="nav-item">
|
38
|
-
<a class="nav-link" href="/function">Function</a>
|
38
|
+
<a class="nav-link" href="/halunke/function">Function</a>
|
39
39
|
</li>
|
40
40
|
<li class="nav-item">
|
41
|
-
<a class="nav-link" href="/class">Class</a>
|
41
|
+
<a class="nav-link" href="/halunke/class">Class</a>
|
42
42
|
</li>
|
43
43
|
<li class="nav-item">
|
44
|
-
<a class="nav-link" href="/
|
44
|
+
<a class="nav-link" href="/halunke/stdio">Stdio</a>
|
45
45
|
</li>
|
46
46
|
<li class="nav-item">
|
47
|
-
<a class="nav-link" href="/
|
47
|
+
<a class="nav-link" href="/halunke/web">Web</a>
|
48
48
|
</li>
|
49
49
|
</ul>
|
50
50
|
</div>
|
@@ -57,5 +57,9 @@
|
|
57
57
|
{{ content }}
|
58
58
|
</main>
|
59
59
|
</div>
|
60
|
+
|
61
|
+
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
|
62
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
|
63
|
+
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
|
60
64
|
</body>
|
61
65
|
</html>
|
data/docs/array.md
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
---
|
2
|
+
title: Array
|
3
|
+
---
|
4
|
+
|
5
|
+
In Halunke arrays are collections of objects. The objects do not
|
6
|
+
need to be of the same class. Arrays are sorted. They are
|
7
|
+
surrounded by square brackets. The items are separated by
|
8
|
+
whitespace.
|
9
|
+
|
10
|
+
```
|
11
|
+
["a" 1 "b"]
|
12
|
+
[
|
13
|
+
"a"
|
14
|
+
5
|
15
|
+
]
|
16
|
+
```
|
17
|
+
|
18
|
+
It can answer to the following messages:
|
19
|
+
|
20
|
+
## `=`
|
21
|
+
|
22
|
+
Compares to arrays. If they have the same length and each item from
|
23
|
+
the first array returns true on the `=` message for the according
|
24
|
+
item from the second list, it returns true. Otherwise, it returns
|
25
|
+
false. This can also be used to destructure an array.
|
26
|
+
|
27
|
+
**Example:**
|
28
|
+
|
29
|
+
```
|
30
|
+
(["a" 1] = ["a" 1]) /* => true */
|
31
|
+
|
32
|
+
(['a 2] = [1 2]) /* => true */
|
33
|
+
/* a is now 2 */
|
34
|
+
```
|
35
|
+
|
36
|
+
## `map`
|
37
|
+
|
38
|
+
Calls the provided function for each element. Returns a new array of the same
|
39
|
+
length with the results of the function calls.
|
40
|
+
|
41
|
+
**Example:**
|
42
|
+
|
43
|
+
```
|
44
|
+
([0 1 2] map { |'x| (x + 1) }) /* => [1 2 3] */
|
45
|
+
```
|
46
|
+
|
47
|
+
## `to_s`
|
48
|
+
|
49
|
+
This returns a string to represent the array in output.
|
50
|
+
|
51
|
+
**Example:**
|
52
|
+
|
53
|
+
```
|
54
|
+
([0 1 2] to_s) /* => "0\n1\n2" */
|
55
|
+
```
|
56
|
+
|
57
|
+
## `inspect`
|
58
|
+
|
59
|
+
This returns a string to represent the array for debugging.
|
60
|
+
|
61
|
+
**Example:**
|
62
|
+
|
63
|
+
```
|
64
|
+
([0 1 2] inspect) /* => "[0 1 2]" */
|
65
|
+
```
|
data/docs/class.md
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
---
|
2
|
+
title: Class
|
3
|
+
---
|
4
|
+
|
5
|
+
In Halunke, Classes are objects. They consist of a dictionary that
|
6
|
+
maps message names to functions. Objects are a wrapper around a
|
7
|
+
dictionary. The dictionary contains the attributes of the object.
|
8
|
+
The object knows its class, and when messages are send to the
|
9
|
+
object, it will look up the according function in its class and
|
10
|
+
call it.
|
11
|
+
|
12
|
+
Classes are created by sending a message to the Class object. One
|
13
|
+
of these messages is `new attributes methods`. Let's create a
|
14
|
+
class:
|
15
|
+
|
16
|
+
```
|
17
|
+
(Class new 'Counter
|
18
|
+
attributes ["value"]
|
19
|
+
methods @[
|
20
|
+
"value" { |'self|
|
21
|
+
(self @ "value" else 0)
|
22
|
+
}
|
23
|
+
]
|
24
|
+
)
|
25
|
+
```
|
26
|
+
|
27
|
+
To create an instance of the class, we send the `new` message to
|
28
|
+
the class with a dictionary that represents the attributes:
|
29
|
+
|
30
|
+
```
|
31
|
+
('counter = (Counter new @["value" 0]))
|
32
|
+
```
|
33
|
+
|
34
|
+
Now we can send the `value` message to our counter, and we will
|
35
|
+
receive 0:
|
36
|
+
|
37
|
+
```
|
38
|
+
(counter value)
|
39
|
+
```
|
40
|
+
|
41
|
+
In our class definition, we first gave an array of attributes. You
|
42
|
+
can imagine it as kind of whitelist for attributes: The attribute
|
43
|
+
dictionary you pass to new can only have keys that are on this
|
44
|
+
list. Now let's look at the function that is called when you send
|
45
|
+
the value message:
|
46
|
+
|
47
|
+
```
|
48
|
+
{ |'self| (self @ "value" else 0) }
|
49
|
+
```
|
50
|
+
|
51
|
+
Every function that is used as a method receives the object itself
|
52
|
+
as its first argument. This can be used to send messages to the
|
53
|
+
object itself. Each object can receive the `@ else` message. This
|
54
|
+
is used to look up attributes in the dictionary. Our function
|
55
|
+
therefore returns the value attribute or 0, if it was not set.
|
56
|
+
|
57
|
+
Now let's add a method to increase the counter. Remember that objects
|
58
|
+
are immutable. So we need to return a new counter with the value
|
59
|
+
that is one higher than our current value:
|
60
|
+
|
61
|
+
```
|
62
|
+
"increase" { |'self|
|
63
|
+
(Counter new @["value" ((self value) + 1)])
|
64
|
+
}
|
65
|
+
```
|
66
|
+
|
67
|
+
We can use it like this:
|
68
|
+
|
69
|
+
```
|
70
|
+
('counter = (Counter new @["value" 0]))
|
71
|
+
('increased_counter = (counter increase))
|
72
|
+
```
|
73
|
+
|
74
|
+
The `'increased_counter` will return `1` as its value.
|
75
|
+
|
76
|
+
Now you might want to have a custom constructor that needs less typing and is
|
77
|
+
more expressive. You can do that by introducing a class method that calls the
|
78
|
+
`new` method. Class methods receive the class as the first parameter.
|
79
|
+
|
80
|
+
```
|
81
|
+
(Class new 'Counter
|
82
|
+
attributes ["value"]
|
83
|
+
methods @[
|
84
|
+
"value" { |'self|
|
85
|
+
(self @ "value" else 0)
|
86
|
+
}
|
87
|
+
"increase" { |'self|
|
88
|
+
(Counter new @["value" ((self value) + 1)])
|
89
|
+
}
|
90
|
+
]
|
91
|
+
class_methods @[
|
92
|
+
"from" { |'self 'value|
|
93
|
+
(self new @["value" value])
|
94
|
+
}
|
95
|
+
]
|
96
|
+
)
|
97
|
+
```
|
98
|
+
|
99
|
+
Now we can create a counter like this:
|
100
|
+
|
101
|
+
```
|
102
|
+
('counter = (Counter from 5))
|
103
|
+
```
|
data/docs/dictionary.md
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
---
|
2
|
+
title: Dictionary
|
3
|
+
---
|
4
|
+
|
5
|
+
In Halunke, dictionaries are collections of objects that map values
|
6
|
+
to other values. The first entry is the key for the second entry,
|
7
|
+
the third for the fourth etc. (the number of elements is therefore
|
8
|
+
always even). Like in a real dictionary, you can then look them up
|
9
|
+
Like in a real dictionary, you can then look them up. They are
|
10
|
+
written in square brackets, prefixed with an `@`.
|
11
|
+
|
12
|
+
```
|
13
|
+
@["a" 1 "b" 2]
|
14
|
+
```
|
15
|
+
|
16
|
+
It can answer to the following message:
|
17
|
+
|
18
|
+
## `@ else`
|
19
|
+
|
20
|
+
Looks up a value in the dictionary. If the key is not in the
|
21
|
+
dictionary, the fallback value is used.
|
22
|
+
|
23
|
+
**Example:**
|
24
|
+
|
25
|
+
```
|
26
|
+
(@["a" 1 "b" 2] @ "a" else "Not Found") /* => 1 */
|
27
|
+
(@["a" 1 "b" 2] @ "c" else "Not Found") /* => "Not Found" */
|
28
|
+
```
|
29
|
+
|
30
|
+
## `to_s`
|
31
|
+
|
32
|
+
This returns a string to represent the dictionary in output.
|
33
|
+
|
34
|
+
**Example:**
|
35
|
+
|
36
|
+
```
|
37
|
+
(@["a" 1 "b" 2] to_s) /* => "a 1\nb 2" */
|
38
|
+
```
|
39
|
+
|
40
|
+
## `inspect`
|
41
|
+
|
42
|
+
This returns a string to represent the dictionary for debugging.
|
43
|
+
|
44
|
+
**Example:**
|
45
|
+
|
46
|
+
```
|
47
|
+
(@["a" 1 "b" 2] inspect) /* => "@[\"a\" 1 \"b\" 2]" */
|
48
|
+
```
|
data/docs/function.md
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
---
|
2
|
+
title: Function
|
3
|
+
---
|
4
|
+
|
5
|
+
This is how you define a function:
|
6
|
+
|
7
|
+
```
|
8
|
+
('fn = { |'a 'b| (a + b) })
|
9
|
+
```
|
10
|
+
|
11
|
+
This is a function that expects two arguments. Functions in Halunke are
|
12
|
+
Objects. If you want to invoke a function, you send them the `call` message
|
13
|
+
with an array with the arguments (in our case two):
|
14
|
+
|
15
|
+
```
|
16
|
+
(fn call [1 2])
|
17
|
+
/* => 6 */
|
18
|
+
```
|
data/docs/index.md
CHANGED
@@ -57,12 +57,13 @@ works like this:
|
|
57
57
|
This will return `"Spelunke!"`. The message we send here is `replace with` and
|
58
58
|
the value is `["Ha" "Spe"]`.
|
59
59
|
|
60
|
-
If you want to find out more about the types of objects in Halunke
|
61
|
-
messages you can send to them, explore the navigation bar
|
62
|
-
want to learn more about conditionals, check out
|
63
|
-
False](/true-false). If you want
|
64
|
-
|
65
|
-
[
|
60
|
+
If you want to find out more about the types of objects in Halunke
|
61
|
+
and the messages you can send to them, explore the navigation bar
|
62
|
+
at the top. If you want to learn more about conditionals, check out
|
63
|
+
the section about [True & False](/halunke/true-false). If you want
|
64
|
+
to write your own functions, check out
|
65
|
+
[Function](/halunke/function) and if you want to define your own
|
66
|
+
classes, check out [Class](/halunke/class).
|
66
67
|
|
67
68
|
If you want to store an object in a variable, you can do it like this:
|
68
69
|
|
@@ -75,3 +76,8 @@ Now you can send messages to `a` like `(a + 2)`. Why is there a `'` though? The
|
|
75
76
|
with a value, and it will assign it. Be aware that you can't reassign. So if
|
76
77
|
you assign something to a once, it will stay like this forever (within that
|
77
78
|
scope). Reassigning will result in an error.
|
79
|
+
|
80
|
+
The values are also immutable. If you send a message to an object,
|
81
|
+
it will not change the object, but it will return an answer to you.
|
82
|
+
|
83
|
+
Comments are written between `/*` and `*/`. They can be multiline.
|
data/docs/number.md
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
---
|
2
|
+
title: Number
|
3
|
+
---
|
4
|
+
|
5
|
+
In Halunke all numbers are rational. You write them as decimal numbers:
|
6
|
+
|
7
|
+
```
|
8
|
+
2
|
9
|
+
-3
|
10
|
+
2.12
|
11
|
+
```
|
12
|
+
|
13
|
+
It can answer to the following messages:
|
14
|
+
|
15
|
+
## `+`
|
16
|
+
|
17
|
+
This adds two numbers.
|
18
|
+
|
19
|
+
**Example:**
|
20
|
+
|
21
|
+
```
|
22
|
+
(0.6 + 0.3) /* => 0.9 */
|
23
|
+
```
|
24
|
+
|
25
|
+
## `-`
|
26
|
+
|
27
|
+
This subtracts two numbers.
|
28
|
+
|
29
|
+
**Example:**
|
30
|
+
|
31
|
+
```
|
32
|
+
(0.6 - 0.3) /* => 0.3 */
|
33
|
+
```
|
34
|
+
|
35
|
+
## `/`
|
36
|
+
|
37
|
+
This divides two numbers.
|
38
|
+
|
39
|
+
**Example:**
|
40
|
+
|
41
|
+
```
|
42
|
+
(0.6 / 0.3) /* => 2 */
|
43
|
+
```
|
44
|
+
|
45
|
+
## `*`
|
46
|
+
|
47
|
+
This multiplies two numbers.
|
48
|
+
|
49
|
+
**Example:**
|
50
|
+
|
51
|
+
```
|
52
|
+
(0.6 * 0.3) /* => 0.18 */
|
53
|
+
```
|
54
|
+
|
55
|
+
## `<`
|
56
|
+
|
57
|
+
This compares two numbers. It is true, if the first number is smaller than the
|
58
|
+
second number. Otherwise, it is false.
|
59
|
+
|
60
|
+
**Example:**
|
61
|
+
|
62
|
+
```
|
63
|
+
(0.6 < 0.3) /* => false */
|
64
|
+
```
|
65
|
+
|
66
|
+
## `>`
|
67
|
+
|
68
|
+
This compares two numbers. It is true, if the first number is greater than the
|
69
|
+
second number. Otherwise, it is false.
|
70
|
+
|
71
|
+
**Example:**
|
72
|
+
|
73
|
+
```
|
74
|
+
(0.6 > 0.3) /* => true */
|
75
|
+
```
|
76
|
+
|
77
|
+
## `=`
|
78
|
+
|
79
|
+
This compares two numbers. It is true, if the two numbers are equal. Otherwise,
|
80
|
+
it is false.
|
81
|
+
|
82
|
+
**Example:**
|
83
|
+
|
84
|
+
```
|
85
|
+
(0.6 = 0.3) /* => false */
|
86
|
+
```
|
87
|
+
|
88
|
+
## `to_s`
|
89
|
+
|
90
|
+
This returns a string to represent the number in output.
|
91
|
+
|
92
|
+
**Example:**
|
93
|
+
|
94
|
+
```
|
95
|
+
(0.6 to_s) /* => "0.6" */
|
96
|
+
```
|
97
|
+
|
98
|
+
## `inspect`
|
99
|
+
|
100
|
+
This returns a string to represent the number for debugging.
|
101
|
+
|
102
|
+
**Example:**
|
103
|
+
|
104
|
+
```
|
105
|
+
(0.6 inspect) /* => "0.6" */
|
106
|
+
```
|
data/docs/stdio.md
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
---
|
2
|
+
title: Stdio
|
3
|
+
---
|
4
|
+
|
5
|
+
The object `stdio` is available from everywhere. *This will change in the
|
6
|
+
future. Interacting with STDIO is IO and will be isolated.*
|
7
|
+
|
8
|
+
## `puts`
|
9
|
+
|
10
|
+
Prints the object to stdout. To determine how to represent the object, it will
|
11
|
+
send the `to_s` message to the object, expecting a string.
|
12
|
+
|
13
|
+
**Example:**
|
14
|
+
|
15
|
+
```
|
16
|
+
(stdio puts "Hello World")
|
17
|
+
(stdio puts 5.2)
|
18
|
+
(stdio puts @["a" 2 "b" 3])
|
19
|
+
(stdio puts ["a" "b"])
|
20
|
+
(stdio puts true)
|
21
|
+
(stdio puts false)
|
22
|
+
```
|
23
|
+
|
24
|
+
This will output:
|
25
|
+
|
26
|
+
```
|
27
|
+
Hello World
|
28
|
+
5.2
|
29
|
+
a 2
|
30
|
+
b 3
|
31
|
+
a
|
32
|
+
b
|
33
|
+
true
|
34
|
+
false
|
35
|
+
```
|
36
|
+
|
37
|
+
## `p`
|
38
|
+
|
39
|
+
Prints the object to stdout for debugging. To determine how to represent the
|
40
|
+
object, it will send the `inspect` message to the object, expecting a string.
|
41
|
+
|
42
|
+
**Example:**
|
43
|
+
|
44
|
+
```
|
45
|
+
(stdio p "Hello World")
|
46
|
+
(stdio p 5.2)
|
47
|
+
(stdio p @["a" 2 "b" 3])
|
48
|
+
(stdio p ["a" "b"])
|
49
|
+
(stdio p true)
|
50
|
+
(stdio p false)
|
51
|
+
```
|
52
|
+
|
53
|
+
This will output:
|
54
|
+
|
55
|
+
```
|
56
|
+
"Hello World"
|
57
|
+
5.2
|
58
|
+
@["a" 2 "b" 3]
|
59
|
+
["a" "b"]
|
60
|
+
true
|
61
|
+
false
|
62
|
+
```
|
data/docs/string.md
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
---
|
2
|
+
title: String
|
3
|
+
---
|
4
|
+
|
5
|
+
In Halunke strings are used to represent all kinds of text
|
6
|
+
including single characters. They are surrounded by double quotes
|
7
|
+
(single quotes are not allowed).
|
8
|
+
|
9
|
+
```
|
10
|
+
"Foo Bar"
|
11
|
+
```
|
12
|
+
|
13
|
+
It can answer to the following messages:
|
14
|
+
|
15
|
+
## `reverse`
|
16
|
+
|
17
|
+
Return a reversed version of the String.
|
18
|
+
|
19
|
+
**Example:**
|
20
|
+
|
21
|
+
```
|
22
|
+
("hello" reverse) /* => "olleh" */
|
23
|
+
```
|
24
|
+
|
25
|
+
## `replace with`
|
26
|
+
|
27
|
+
Replace all occurrences of the first string with the second string.
|
28
|
+
|
29
|
+
**Example:**
|
30
|
+
|
31
|
+
```
|
32
|
+
("ababab" replace "a" with "c") /* => "cbcbcb" */
|
33
|
+
```
|
34
|
+
|
35
|
+
## `=`
|
36
|
+
|
37
|
+
This compares two strings. It is true, if the two strings are equal. Otherwise,
|
38
|
+
it is false.
|
39
|
+
|
40
|
+
**Example:**
|
41
|
+
|
42
|
+
```
|
43
|
+
("aaa" = "aaa") /* => true */
|
44
|
+
```
|
45
|
+
|
46
|
+
## `+`
|
47
|
+
|
48
|
+
Concatenate two strings.
|
49
|
+
|
50
|
+
**Example:**
|
51
|
+
|
52
|
+
```
|
53
|
+
("aaa" + "bbb") /* => "aaabbb" */
|
54
|
+
```
|
55
|
+
|
56
|
+
## `to_s`
|
57
|
+
|
58
|
+
This returns the string itself.
|
59
|
+
|
60
|
+
**Example:**
|
61
|
+
|
62
|
+
```
|
63
|
+
("aaa" to_s) /* => "aaa" */
|
64
|
+
```
|
65
|
+
|
66
|
+
## `inspect`
|
67
|
+
|
68
|
+
This returns a string to represent the string in output. This is done by surrounding it with `"`
|
69
|
+
|
70
|
+
**Example:**
|
71
|
+
|
72
|
+
```
|
73
|
+
("aaa" inspect) /* => "\"aaa\"" */
|
74
|
+
```
|
data/docs/true-false.md
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
---
|
2
|
+
title: True & False
|
3
|
+
---
|
4
|
+
|
5
|
+
In Halunke `true` is an instance of the `True` class, and `false`
|
6
|
+
is an instance of the `False` class. They are used to realize
|
7
|
+
boolean operations (for example `and`) as well as for branching.
|
8
|
+
They answer to the same messages. So you could use it like this:
|
9
|
+
|
10
|
+
```
|
11
|
+
((5 > 3) then { "yes!" } else { "no!" })
|
12
|
+
/* Returns "yes!" */
|
13
|
+
```
|
14
|
+
|
15
|
+
## `and`
|
16
|
+
|
17
|
+
Returns true if both the receiver as well as the provided value are
|
18
|
+
true.
|
19
|
+
|
20
|
+
**Example:**
|
21
|
+
|
22
|
+
```
|
23
|
+
((5 > 3) and (2 < 1)) /* => false */
|
24
|
+
```
|
25
|
+
|
26
|
+
## `or`
|
27
|
+
|
28
|
+
Returns true if either the receiver or the provided value are true.
|
29
|
+
|
30
|
+
**Example:**
|
31
|
+
|
32
|
+
```
|
33
|
+
((5 > 3) or (2 < 1)) /* => true */
|
34
|
+
```
|
35
|
+
|
36
|
+
## `then else`
|
37
|
+
|
38
|
+
If the receiver is true, it will execute the first branch. If it is
|
39
|
+
false, it will return the second branch.
|
40
|
+
|
41
|
+
**Example:**
|
42
|
+
|
43
|
+
```
|
44
|
+
(true then { "yes" } else { "no" }) /* => "yes" */
|
45
|
+
(false then { "yes" } else { "no" }) /* => "no" */
|
46
|
+
```
|
47
|
+
|
48
|
+
## `to_s`
|
49
|
+
|
50
|
+
This returns a string to represent true and false in output.
|
51
|
+
|
52
|
+
**Example:**
|
53
|
+
|
54
|
+
```
|
55
|
+
(true to_s) /* => "true" */
|
56
|
+
(false to_s) /* => "false" */
|
57
|
+
```
|
58
|
+
|
59
|
+
## `inspect`
|
60
|
+
|
61
|
+
This returns a string to represent true and false for debugging.
|
62
|
+
|
63
|
+
**Example:**
|
64
|
+
|
65
|
+
```
|
66
|
+
(true inspect) /* => "true" */
|
67
|
+
(false inspect) /* => "false" */
|
68
|
+
```
|
data/docs/web.md
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
---
|
2
|
+
title: Web
|
3
|
+
---
|
4
|
+
|
5
|
+
The object `web` is available from everywhere. *This will change in the future.
|
6
|
+
Interacting with STDIO is IO and will be isolated.*
|
7
|
+
|
8
|
+
You can send the `run on` message to `web`. It expects the first object to be
|
9
|
+
your application (more on that later) and the second one the bind address and
|
10
|
+
port in the format: `0.0.0.0:3000`.
|
11
|
+
|
12
|
+
Your app needs to be an object that can receive the `call` message. It will be
|
13
|
+
called with the environment dictionary that represents the request. It expects
|
14
|
+
that your return an array that represents the response.
|
15
|
+
|
16
|
+
## Environment Dictionary
|
17
|
+
|
18
|
+
The environment dictionary has the following keys:
|
19
|
+
|
20
|
+
* `request_method`: The request method in upper case (for example: `"GET"`)
|
21
|
+
* `path`: The path that was requested (for example: `"/the/path"`)
|
22
|
+
* `query`: The query part of the request (for example: `"foo=bar&beep=boop"`)
|
23
|
+
|
24
|
+
## Response Array
|
25
|
+
|
26
|
+
The response array has three elements:
|
27
|
+
|
28
|
+
1. The first element is the status code as a String (for example: `"200"`)
|
29
|
+
2. The second element are the headers as a dictionary (for example: `@[
|
30
|
+
"Content-Type" "text/html" ]`)
|
31
|
+
3. The third element is an array of strings that represent the body (for
|
32
|
+
example: `[ "<h1>Halunke!</h1>" ]`)
|
@@ -0,0 +1,22 @@
|
|
1
|
+
(Class new 'Counter
|
2
|
+
attributes ["value"]
|
3
|
+
methods @[
|
4
|
+
"value" { |'self|
|
5
|
+
(self @ "value" else 0)
|
6
|
+
}
|
7
|
+
"increase" { |'self|
|
8
|
+
(Counter new @["value" ((self value) + 1)])
|
9
|
+
}
|
10
|
+
]
|
11
|
+
class_methods @[
|
12
|
+
"from" { |'self 'value|
|
13
|
+
(self new @["value" value])
|
14
|
+
}
|
15
|
+
]
|
16
|
+
)
|
17
|
+
|
18
|
+
('counter = (Counter from 0))
|
19
|
+
(stdio puts (counter value))
|
20
|
+
|
21
|
+
('increased_counter = (counter increase))
|
22
|
+
(stdio puts (increased_counter value))
|
data/examples/hello.hal
CHANGED
data/examples/stdio.hal
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
(stdio puts "Hello World")
|
2
|
+
(stdio puts 5.2)
|
3
|
+
(stdio puts @["a" 2 "b" 3])
|
4
|
+
(stdio puts ["a" "b"])
|
5
|
+
(stdio puts true)
|
6
|
+
(stdio puts false)
|
7
|
+
|
8
|
+
(stdio p "Hello World")
|
9
|
+
(stdio p 5.2)
|
10
|
+
(stdio p @["a" 2 "b" 3])
|
11
|
+
(stdio p ["a" "b"])
|
12
|
+
(stdio p true)
|
13
|
+
(stdio p false)
|
data/lib/halunke/grammar.y
CHANGED
@@ -15,27 +15,29 @@ token BAR
|
|
15
15
|
token START_COMMENT
|
16
16
|
token END_COMMENT
|
17
17
|
|
18
|
+
options no_result_var
|
19
|
+
|
18
20
|
rule
|
19
21
|
Program:
|
20
|
-
Expressions {
|
22
|
+
Expressions { val[0] }
|
21
23
|
;
|
22
24
|
|
23
25
|
Expressions:
|
24
|
-
/* empty */ {
|
25
|
-
| Expression Expressions {
|
26
|
+
/* empty */ { Nodes.new([]) }
|
27
|
+
| Expression Expressions { Nodes.new([val[0]].concat(val[1].nodes)) }
|
26
28
|
;
|
27
29
|
|
28
30
|
Expression:
|
29
|
-
NUMBER {
|
30
|
-
| STRING {
|
31
|
-
| BAREWORD {
|
32
|
-
| UNASSIGNED_BAREWORD {
|
33
|
-
| START_COMMENT Expressions END_COMMENT {
|
34
|
-
| OPEN_CURLY Expressions CLOSE_CURLY {
|
35
|
-
| OPEN_CURLY BAR Expressions BAR Expressions CLOSE_CURLY {
|
36
|
-
| OPEN_PAREN Expression Expressions CLOSE_PAREN {
|
37
|
-
| OPEN_BRACKET Expressions CLOSE_BRACKET {
|
38
|
-
| OPEN_DICT_BRACKET Expressions CLOSE_BRACKET {
|
31
|
+
NUMBER { NumberNode.new(val[0]) }
|
32
|
+
| STRING { StringNode.new(val[0]) }
|
33
|
+
| BAREWORD { BarewordNode.new(val[0]) }
|
34
|
+
| UNASSIGNED_BAREWORD { UnassignedNode.new(BarewordNode.new(val[0])) }
|
35
|
+
| START_COMMENT Expressions END_COMMENT { Nodes.new([]) }
|
36
|
+
| OPEN_CURLY Expressions CLOSE_CURLY { FunctionNode.new(ArrayNode.new([]), val[1]) }
|
37
|
+
| OPEN_CURLY BAR Expressions BAR Expressions CLOSE_CURLY { FunctionNode.new(val[2].to_array, val[4]) }
|
38
|
+
| OPEN_PAREN Expression Expressions CLOSE_PAREN { MessageSendNode.new(val[1], val[2].to_message) }
|
39
|
+
| OPEN_BRACKET Expressions CLOSE_BRACKET { val[1].to_array }
|
40
|
+
| OPEN_DICT_BRACKET Expressions CLOSE_BRACKET { val[1].to_dictionary }
|
39
41
|
;
|
40
42
|
end
|
41
43
|
|
data/lib/halunke/interpreter.rb
CHANGED
@@ -17,7 +17,7 @@ module Halunke
|
|
17
17
|
@root_context["Array"] = Halunke::Runtime::HArray
|
18
18
|
@root_context["Dictionary"] = Halunke::Runtime::HDictionary
|
19
19
|
@root_context["UnassignedBareword"] = Halunke::Runtime::HUnassignedBareword
|
20
|
-
@root_context["
|
20
|
+
@root_context["stdio"] = Halunke::Runtime::HStdio.create_instance
|
21
21
|
@root_context["web"] = Halunke::Runtime::HWeb.create_instance
|
22
22
|
|
23
23
|
preludes.each do |prelude|
|
data/lib/halunke/lexer.rb
CHANGED
@@ -99,10 +99,10 @@ self._lexer_trans_actions = [
|
|
99
99
|
13, 0, 0, 0, 0, 0, 19, 21,
|
100
100
|
0, 15, 29, 17, 31, 5, 9, 0,
|
101
101
|
0, 33, 7, 0, 47, 47, 47, 45,
|
102
|
-
27,
|
103
|
-
35, 25,
|
104
|
-
37, 43, 41, 39, 45,
|
105
|
-
35,
|
102
|
+
27, 37, 5, 37, 0, 5, 35, 0,
|
103
|
+
35, 25, 37, 23, 37, 0, 0, 0,
|
104
|
+
37, 43, 41, 39, 45, 37, 37, 35,
|
105
|
+
35, 37, 37, 37, 0
|
106
106
|
]
|
107
107
|
|
108
108
|
class << self
|
@@ -128,8 +128,8 @@ class << self
|
|
128
128
|
private :_lexer_eof_trans, :_lexer_eof_trans=
|
129
129
|
end
|
130
130
|
self._lexer_eof_trans = [
|
131
|
-
50, 51, 0,
|
132
|
-
57,
|
131
|
+
50, 51, 0, 52, 53, 60, 60, 57,
|
132
|
+
57, 60, 60, 60
|
133
133
|
]
|
134
134
|
|
135
135
|
class << self
|
data/lib/halunke/lexer.rl
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
number = ('+'|'-')?[0-9]+('.'[0-9]+)?;
|
6
6
|
string = '"' [^"]* '"';
|
7
7
|
unassigned_bareword = "'" [a-zA-Z_]+;
|
8
|
-
bareword = [a-zA-Z_]+ | '+' | '-' | '<' | '>' | '=' | '@';
|
8
|
+
bareword = [a-zA-Z_]+ | '+' | '-' | '*' | '/' | '<' | '>' | '=' | '@';
|
9
9
|
open_paren = '(';
|
10
10
|
close_paren = ')';
|
11
11
|
open_curly = '{';
|
data/lib/halunke/parser.rb
CHANGED
@@ -13,7 +13,7 @@ require "halunke/nodes"
|
|
13
13
|
module Halunke
|
14
14
|
class Parser < Racc::Parser
|
15
15
|
|
16
|
-
module_eval(<<'...end grammar.y/module_eval...', 'grammar.y',
|
16
|
+
module_eval(<<'...end grammar.y/module_eval...', 'grammar.y', 50)
|
17
17
|
|
18
18
|
def parse(code)
|
19
19
|
@tokens = Lexer.new.tokenize(code)
|
@@ -124,7 +124,7 @@ racc_token_table = {
|
|
124
124
|
|
125
125
|
racc_nt_base = 16
|
126
126
|
|
127
|
-
racc_use_result_var =
|
127
|
+
racc_use_result_var = false
|
128
128
|
|
129
129
|
Racc_arg = [
|
130
130
|
racc_action_table,
|
@@ -170,98 +170,85 @@ Racc_debug_parser = false
|
|
170
170
|
|
171
171
|
# reduce 0 omitted
|
172
172
|
|
173
|
-
module_eval(<<'.,.,', 'grammar.y',
|
174
|
-
def _reduce_1(val, _values
|
175
|
-
|
176
|
-
result
|
173
|
+
module_eval(<<'.,.,', 'grammar.y', 21)
|
174
|
+
def _reduce_1(val, _values)
|
175
|
+
val[0]
|
177
176
|
end
|
178
177
|
.,.,
|
179
178
|
|
180
|
-
module_eval(<<'.,.,', 'grammar.y',
|
181
|
-
def _reduce_2(val, _values
|
182
|
-
|
183
|
-
result
|
179
|
+
module_eval(<<'.,.,', 'grammar.y', 25)
|
180
|
+
def _reduce_2(val, _values)
|
181
|
+
Nodes.new([])
|
184
182
|
end
|
185
183
|
.,.,
|
186
184
|
|
187
|
-
module_eval(<<'.,.,', 'grammar.y',
|
188
|
-
def _reduce_3(val, _values
|
189
|
-
|
190
|
-
result
|
191
|
-
end
|
192
|
-
.,.,
|
193
|
-
|
194
|
-
module_eval(<<'.,.,', 'grammar.y', 28)
|
195
|
-
def _reduce_4(val, _values, result)
|
196
|
-
result = NumberNode.new(val[0])
|
197
|
-
result
|
198
|
-
end
|
199
|
-
.,.,
|
200
|
-
|
201
|
-
module_eval(<<'.,.,', 'grammar.y', 29)
|
202
|
-
def _reduce_5(val, _values, result)
|
203
|
-
result = StringNode.new(val[0])
|
204
|
-
result
|
185
|
+
module_eval(<<'.,.,', 'grammar.y', 26)
|
186
|
+
def _reduce_3(val, _values)
|
187
|
+
Nodes.new([val[0]].concat(val[1].nodes))
|
205
188
|
end
|
206
189
|
.,.,
|
207
190
|
|
208
191
|
module_eval(<<'.,.,', 'grammar.y', 30)
|
209
|
-
def
|
210
|
-
|
211
|
-
result
|
192
|
+
def _reduce_4(val, _values)
|
193
|
+
NumberNode.new(val[0])
|
212
194
|
end
|
213
195
|
.,.,
|
214
196
|
|
215
197
|
module_eval(<<'.,.,', 'grammar.y', 31)
|
216
|
-
def
|
217
|
-
|
218
|
-
result
|
198
|
+
def _reduce_5(val, _values)
|
199
|
+
StringNode.new(val[0])
|
219
200
|
end
|
220
201
|
.,.,
|
221
202
|
|
222
203
|
module_eval(<<'.,.,', 'grammar.y', 32)
|
223
|
-
def
|
224
|
-
|
225
|
-
result
|
204
|
+
def _reduce_6(val, _values)
|
205
|
+
BarewordNode.new(val[0])
|
226
206
|
end
|
227
207
|
.,.,
|
228
208
|
|
229
209
|
module_eval(<<'.,.,', 'grammar.y', 33)
|
230
|
-
def
|
231
|
-
|
232
|
-
result
|
210
|
+
def _reduce_7(val, _values)
|
211
|
+
UnassignedNode.new(BarewordNode.new(val[0]))
|
233
212
|
end
|
234
213
|
.,.,
|
235
214
|
|
236
215
|
module_eval(<<'.,.,', 'grammar.y', 34)
|
237
|
-
def
|
238
|
-
|
239
|
-
result
|
216
|
+
def _reduce_8(val, _values)
|
217
|
+
Nodes.new([])
|
240
218
|
end
|
241
219
|
.,.,
|
242
220
|
|
243
221
|
module_eval(<<'.,.,', 'grammar.y', 35)
|
244
|
-
def
|
245
|
-
|
246
|
-
result
|
222
|
+
def _reduce_9(val, _values)
|
223
|
+
FunctionNode.new(ArrayNode.new([]), val[1])
|
247
224
|
end
|
248
225
|
.,.,
|
249
226
|
|
250
227
|
module_eval(<<'.,.,', 'grammar.y', 36)
|
251
|
-
def
|
252
|
-
|
253
|
-
result
|
228
|
+
def _reduce_10(val, _values)
|
229
|
+
FunctionNode.new(val[2].to_array, val[4])
|
254
230
|
end
|
255
231
|
.,.,
|
256
232
|
|
257
233
|
module_eval(<<'.,.,', 'grammar.y', 37)
|
258
|
-
def
|
259
|
-
|
260
|
-
|
234
|
+
def _reduce_11(val, _values)
|
235
|
+
MessageSendNode.new(val[1], val[2].to_message)
|
236
|
+
end
|
237
|
+
.,.,
|
238
|
+
|
239
|
+
module_eval(<<'.,.,', 'grammar.y', 38)
|
240
|
+
def _reduce_12(val, _values)
|
241
|
+
val[1].to_array
|
242
|
+
end
|
243
|
+
.,.,
|
244
|
+
|
245
|
+
module_eval(<<'.,.,', 'grammar.y', 39)
|
246
|
+
def _reduce_13(val, _values)
|
247
|
+
val[1].to_dictionary
|
261
248
|
end
|
262
249
|
.,.,
|
263
250
|
|
264
|
-
def _reduce_none(val, _values
|
251
|
+
def _reduce_none(val, _values)
|
265
252
|
val[0]
|
266
253
|
end
|
267
254
|
|
data/lib/halunke/runtime.rb
CHANGED
@@ -4,10 +4,6 @@ module Halunke
|
|
4
4
|
"Array",
|
5
5
|
[],
|
6
6
|
{
|
7
|
-
"inspect" => HFunction.new([:self], lambda { |context|
|
8
|
-
inspected_members = context["self"].ruby_value.map { |member| member.inspect(context) }
|
9
|
-
HString.create_instance("[#{inspected_members.join(' ')}]")
|
10
|
-
}),
|
11
7
|
"=" => HFunction.new([:self, :other], lambda { |context|
|
12
8
|
return context["false"] if context["self"].ruby_value.length != context["other"].ruby_value.length
|
13
9
|
|
@@ -21,6 +17,16 @@ module Halunke
|
|
21
17
|
return HArray.create_instance(context["self"].ruby_value.map do |x|
|
22
18
|
context["fn"].receive_message(context, "call", [HArray.create_instance([x])])
|
23
19
|
end)
|
20
|
+
}),
|
21
|
+
"to_s" => HFunction.new([:self], lambda { |context|
|
22
|
+
inspected_members = context["self"].ruby_value.map do |member|
|
23
|
+
member.receive_message(context, "to_s", []).ruby_value
|
24
|
+
end
|
25
|
+
HString.create_instance("#{inspected_members.join("\n")}")
|
26
|
+
}),
|
27
|
+
"inspect" => HFunction.new([:self], lambda { |context|
|
28
|
+
inspected_members = context["self"].ruby_value.map { |member| member.inspect(context) }
|
29
|
+
HString.create_instance("[#{inspected_members.join(' ')}]")
|
24
30
|
})
|
25
31
|
},
|
26
32
|
{},
|
@@ -4,6 +4,21 @@ module Halunke
|
|
4
4
|
"Dictionary",
|
5
5
|
[],
|
6
6
|
{
|
7
|
+
"@ else" => HFunction.new([:self, :search, :fallback], lambda { |context|
|
8
|
+
result = context["self"].ruby_value.find do |key, _value|
|
9
|
+
key.receive_message(context, "=", [context["search"]]).inspect(context) == "true"
|
10
|
+
end
|
11
|
+
result ? result[1] : context["fallback"]
|
12
|
+
}),
|
13
|
+
"to_s" => HFunction.new([:self], lambda { |context|
|
14
|
+
x = []
|
15
|
+
context["self"].ruby_value.each_pair do |key, value|
|
16
|
+
key_s = key.receive_message(context, "to_s", [])
|
17
|
+
value_s = value.receive_message(context, "to_s", [])
|
18
|
+
x.push("#{key_s.ruby_value} #{value_s.ruby_value}")
|
19
|
+
end
|
20
|
+
HString.create_instance(x.join("\n"))
|
21
|
+
}),
|
7
22
|
"inspect" => HFunction.new([:self], lambda { |context|
|
8
23
|
x = []
|
9
24
|
context["self"].ruby_value.each_pair do |key, value|
|
@@ -11,12 +26,6 @@ module Halunke
|
|
11
26
|
x.push(value.inspect(context))
|
12
27
|
end
|
13
28
|
HString.create_instance("@[#{x.join(' ')}]")
|
14
|
-
}),
|
15
|
-
"@ else" => HFunction.new([:self, :search, :fallback], lambda { |context|
|
16
|
-
result = context["self"].ruby_value.find do |key, _value|
|
17
|
-
key.receive_message(context, "=", [context["search"]]).inspect(context) == "true"
|
18
|
-
end
|
19
|
-
result ? result[1] : context["fallback"]
|
20
29
|
})
|
21
30
|
},
|
22
31
|
{},
|
@@ -7,6 +7,15 @@ module Halunke
|
|
7
7
|
"+" => HFunction.new([:self, :other], lambda { |context|
|
8
8
|
HNumber.create_instance(context["self"].ruby_value + context["other"].ruby_value)
|
9
9
|
}),
|
10
|
+
"-" => HFunction.new([:self, :other], lambda { |context|
|
11
|
+
HNumber.create_instance(context["self"].ruby_value - context["other"].ruby_value)
|
12
|
+
}),
|
13
|
+
"/" => HFunction.new([:self, :other], lambda { |context|
|
14
|
+
HNumber.create_instance(context["self"].ruby_value / context["other"].ruby_value)
|
15
|
+
}),
|
16
|
+
"*" => HFunction.new([:self, :other], lambda { |context|
|
17
|
+
HNumber.create_instance(context["self"].ruby_value * context["other"].ruby_value)
|
18
|
+
}),
|
10
19
|
"<" => HFunction.new([:self, :other], lambda { |context|
|
11
20
|
if context["self"].ruby_value < context["other"].ruby_value
|
12
21
|
context["true"]
|
@@ -28,10 +37,13 @@ module Halunke
|
|
28
37
|
context["false"]
|
29
38
|
end
|
30
39
|
}),
|
31
|
-
"
|
40
|
+
"to_s" => HFunction.new([:self], lambda { |context|
|
32
41
|
float_value = context["self"].ruby_value.to_f
|
33
42
|
float_value = float_value.to_i if float_value.to_i == float_value
|
34
43
|
HString.create_instance(float_value.to_s)
|
44
|
+
}),
|
45
|
+
"inspect" => HFunction.new([:self], lambda { |context|
|
46
|
+
context["self"].receive_message(context, "to_s", [])
|
35
47
|
})
|
36
48
|
},
|
37
49
|
{},
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Halunke
|
2
|
+
module Runtime
|
3
|
+
HStdio = HClass.new(
|
4
|
+
"Stdio",
|
5
|
+
[],
|
6
|
+
{
|
7
|
+
"puts" => HFunction.new([:self, :obj], lambda { |context|
|
8
|
+
str = context["obj"].receive_message(context, "to_s", [])
|
9
|
+
puts str.ruby_value
|
10
|
+
str
|
11
|
+
}),
|
12
|
+
"p" => HFunction.new([:self, :obj], lambda { |context|
|
13
|
+
str = context["obj"].receive_message(context, "inspect", [])
|
14
|
+
puts str.ruby_value
|
15
|
+
context["obj"]
|
16
|
+
})
|
17
|
+
},
|
18
|
+
{},
|
19
|
+
true
|
20
|
+
)
|
21
|
+
end
|
22
|
+
end
|
@@ -24,6 +24,9 @@ module Halunke
|
|
24
24
|
"+" => HFunction.new([:self, :other], lambda { |context|
|
25
25
|
HString.create_instance(context["self"].ruby_value + context["other"].ruby_value)
|
26
26
|
}),
|
27
|
+
"to_s" => HFunction.new([:self], lambda { |context|
|
28
|
+
context["self"]
|
29
|
+
}),
|
27
30
|
"inspect" => HFunction.new([:self], lambda { |context|
|
28
31
|
HString.create_instance(context["self"].ruby_value.inspect)
|
29
32
|
})
|
data/lib/halunke/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: halunke
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lucas Dohmen
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-02-
|
11
|
+
date: 2018-02-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
@@ -104,8 +104,19 @@ files:
|
|
104
104
|
- docs/Gemfile.lock
|
105
105
|
- docs/_config.yml
|
106
106
|
- docs/_layouts/default.html
|
107
|
+
- docs/array.md
|
108
|
+
- docs/class.md
|
109
|
+
- docs/dictionary.md
|
110
|
+
- docs/function.md
|
107
111
|
- docs/index.md
|
112
|
+
- docs/number.md
|
113
|
+
- docs/stdio.md
|
114
|
+
- docs/string.md
|
115
|
+
- docs/true-false.md
|
116
|
+
- docs/web.md
|
117
|
+
- examples/counter.hal
|
108
118
|
- examples/hello.hal
|
119
|
+
- examples/stdio.hal
|
109
120
|
- examples/web.hal
|
110
121
|
- exe/halunke
|
111
122
|
- halunke.gemspec
|
@@ -125,7 +136,7 @@ files:
|
|
125
136
|
- lib/halunke/runtime/hnative_object.rb
|
126
137
|
- lib/halunke/runtime/hnumber.rb
|
127
138
|
- lib/halunke/runtime/hobject.rb
|
128
|
-
- lib/halunke/runtime/
|
139
|
+
- lib/halunke/runtime/hstdio.rb
|
129
140
|
- lib/halunke/runtime/hstring.rb
|
130
141
|
- lib/halunke/runtime/hunassigned_bareword.rb
|
131
142
|
- lib/halunke/runtime/hweb.rb
|