halunke 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/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
|