iode 0.0.2 → 0.0.3
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.
- data/README.md +64 -55
- data/lib/iode/core/lists.rb +4 -0
- data/lib/iode/core.rb +2 -0
- data/lib/iode/reader.rb +5 -1
- data/lib/iode/version.rb +1 -1
- metadata +26 -19
- checksums.yaml +0 -7
data/README.md
CHANGED
@@ -4,17 +4,9 @@ An experimental lisp-family language hosted on Ruby.
|
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
And then execute:
|
12
|
-
|
13
|
-
$ bundle
|
14
|
-
|
15
|
-
Or install it yourself as:
|
16
|
-
|
17
|
-
$ gem install iode
|
7
|
+
```
|
8
|
+
gem install iode
|
9
|
+
```
|
18
10
|
|
19
11
|
## Usage
|
20
12
|
|
@@ -28,8 +20,8 @@ what the syntax and language features may include. Ruby is perfect for that.
|
|
28
20
|
Once I have good ideas put down as working examples in this project, they will
|
29
21
|
be ported upstream to the native JIT interpreter for LLVM.
|
30
22
|
|
31
|
-
Currently this project just implements the guts of a functional
|
32
|
-
|
23
|
+
Currently this project just implements the guts of a functional language in the
|
24
|
+
lisp-family. It will change considerably from the current implementation.
|
33
25
|
|
34
26
|
### Command Line
|
35
27
|
|
@@ -45,6 +37,58 @@ Or you can send the source code to STDIN:
|
|
45
37
|
iode-rb < path/to/file.io
|
46
38
|
```
|
47
39
|
|
40
|
+
The basic hello world looks like so.
|
41
|
+
|
42
|
+
``` lisp
|
43
|
+
;; this is a comment
|
44
|
+
(puts "Hello World!")
|
45
|
+
```
|
46
|
+
|
47
|
+
Some built-in data types (e.g. fractions) are enriched with literals in iode.
|
48
|
+
|
49
|
+
``` lisp
|
50
|
+
(+ 1/2 2/3) ; 7/6
|
51
|
+
```
|
52
|
+
|
53
|
+
Functions are (currently) defined in terms of `lambda`.
|
54
|
+
|
55
|
+
``` lisp
|
56
|
+
((lambda (x y) (* x y)) 6 3) ; 18
|
57
|
+
```
|
58
|
+
|
59
|
+
As you'd expect, functions are first-class objects in Iode.
|
60
|
+
|
61
|
+
Of course, functions can be defined recursively too.
|
62
|
+
|
63
|
+
``` lisp
|
64
|
+
;; Recursive function example.
|
65
|
+
(def loop
|
66
|
+
(lambda (n)
|
67
|
+
(if (= n 0)
|
68
|
+
(quote done)
|
69
|
+
(progn
|
70
|
+
(puts n)
|
71
|
+
(loop (- n 1))))))
|
72
|
+
|
73
|
+
(loop 20)
|
74
|
+
```
|
75
|
+
|
76
|
+
The above code will print 20 through 1 to the screen and finally return the
|
77
|
+
Symbol `:done` to Ruby (quoted Iode Symbols are also Ruby Symbols). Note that
|
78
|
+
I haven't yet done tail call elimination.
|
79
|
+
|
80
|
+
Similarly, closures can be returned from functions.
|
81
|
+
|
82
|
+
``` lisp
|
83
|
+
;; Provides partial application of a function
|
84
|
+
(def curry
|
85
|
+
(lambda (fn a)
|
86
|
+
(lambda (b) (fn a b))))
|
87
|
+
|
88
|
+
((curry + 2) 3) ; 5
|
89
|
+
```
|
90
|
+
|
91
|
+
|
48
92
|
### In Ruby Code
|
49
93
|
|
50
94
|
Using Iode from inside Ruby code can be interesting, as it will interoperate
|
@@ -62,12 +106,8 @@ PROG
|
|
62
106
|
puts result
|
63
107
|
```
|
64
108
|
|
65
|
-
|
66
|
-
|
67
|
-
with the input `false`, thereby returning `false`.
|
68
|
-
|
69
|
-
The `if` form evaluates false and therefore evaluates the else part of the
|
70
|
-
`if`, returning the string "x = false".
|
109
|
+
This returns the string "x = false" to Ruby. Hopefully you can see what the
|
110
|
+
code does.
|
71
111
|
|
72
112
|
Here's another example showing how you can pass values from Ruby into Iode.
|
73
113
|
|
@@ -85,10 +125,10 @@ prog.call(false) #=> 7
|
|
85
125
|
prog.call(true) #=> 42
|
86
126
|
```
|
87
127
|
|
88
|
-
This works because internally,
|
128
|
+
This works because internally, iode lambdas are represented as Procs.
|
89
129
|
|
90
130
|
Incidentally, that means you can even pass higher-order functions from Ruby
|
91
|
-
to
|
131
|
+
to iode.
|
92
132
|
|
93
133
|
``` ruby
|
94
134
|
require "iode"
|
@@ -102,37 +142,6 @@ prog.call(->(x){ x * 2 }) #=> 84
|
|
102
142
|
prog.call(->(x){ x + 4 }) #=> 46
|
103
143
|
```
|
104
144
|
|
105
|
-
Of course, functions can be defined recursively too.
|
106
|
-
|
107
|
-
``` lisp
|
108
|
-
;; Recursive function example.
|
109
|
-
(def loop
|
110
|
-
(lambda (n)
|
111
|
-
(if (= n 0)
|
112
|
-
(quote done)
|
113
|
-
(progn
|
114
|
-
(puts n)
|
115
|
-
(loop (- n 1))))))
|
116
|
-
|
117
|
-
|
118
|
-
(loop 20)
|
119
|
-
```
|
120
|
-
|
121
|
-
The above code will print 20 through 1 to the screen and finally return the
|
122
|
-
Symbol `:done` to Ruby (quoted Iode Symbols are also Ruby Symbols). Note that
|
123
|
-
I haven't yet done tail call elimination.
|
124
|
-
|
125
|
-
Similarly, closures can be returned from functions.
|
126
|
-
|
127
|
-
``` lisp
|
128
|
-
;; Provides partial application of a function
|
129
|
-
(def curry
|
130
|
-
(lambda (fn a)
|
131
|
-
(lambda (b) (fn a b))))
|
132
|
-
|
133
|
-
((curry + 2) 3) ; 5
|
134
|
-
```
|
135
|
-
|
136
145
|
## Development
|
137
146
|
|
138
147
|
Iode (in this Ruby incarnation) is literally a few hours old at the time I
|
@@ -140,7 +149,7 @@ write this. Much is still not yet developed. However, you may poke around in
|
|
140
149
|
the internals and find some interesting this. A string of source code takes
|
141
150
|
this path to being executed as code.
|
142
151
|
|
143
|
-
|
152
|
+
Input -> Reader<data> -> Interpreter<data> -> Core<data> -> Output
|
144
153
|
|
145
154
|
The source string is parsed by the Reader into native lisp data (using Ruby
|
146
155
|
data types, like Array and Symbol). The data representation is then given to
|
@@ -150,7 +159,7 @@ a Proc). Variables are held in the Scope class, which is able to chain Scopes
|
|
150
159
|
together to create lexical closures. Core functions are registered as mixins
|
151
160
|
in the Core module.
|
152
161
|
|
153
|
-
If you want to add a native Ruby function to be applied like an
|
162
|
+
If you want to add a native Ruby function to be applied like an iode function,
|
154
163
|
put it in a Module and register it into `Iode::Core`:
|
155
164
|
|
156
165
|
``` ruby
|
@@ -167,7 +176,7 @@ Iode::Core.register MyFunctions
|
|
167
176
|
Iode.run('(example 7 5)') #=> 12
|
168
177
|
```
|
169
178
|
|
170
|
-
Once I have namespacing done, you'll be able to write actual
|
179
|
+
Once I have namespacing done, you'll be able to write actual iode code in
|
171
180
|
separate files and have them loaded under a namespace.
|
172
181
|
|
173
182
|
## Copyright & Licensing
|
data/lib/iode/core/lists.rb
CHANGED
data/lib/iode/core.rb
CHANGED
data/lib/iode/reader.rb
CHANGED
@@ -29,9 +29,12 @@ module Iode
|
|
29
29
|
rule("(")
|
30
30
|
rule(")")
|
31
31
|
|
32
|
+
# fractions as literals
|
33
|
+
rule(:rational => /[0-9]+\/[0-9]+/).as{|n| Rational(n)}
|
34
|
+
|
32
35
|
# scalars
|
33
36
|
{
|
34
|
-
float: /[0-9]
|
37
|
+
float: /[0-9]+\.[0-9]+/,
|
35
38
|
int: /[0-9]+/,
|
36
39
|
string: /"(\\.|[^"])*"/,
|
37
40
|
regexp: /\/(\\.|[^\/])*\//
|
@@ -57,6 +60,7 @@ module Iode
|
|
57
60
|
rule(:atom) do |r|
|
58
61
|
r[:int]
|
59
62
|
r[:float]
|
63
|
+
r[:rational]
|
60
64
|
r[:string]
|
61
65
|
r[:symbol]
|
62
66
|
end
|
data/lib/iode/version.rb
CHANGED
metadata
CHANGED
@@ -1,62 +1,68 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: iode
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
|
+
prerelease:
|
5
6
|
platform: ruby
|
6
7
|
authors:
|
7
8
|
- Chris Corbyn
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date: 2014-03-
|
12
|
+
date: 2014-03-18 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: whittle
|
15
16
|
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
16
18
|
requirements:
|
17
|
-
- -
|
19
|
+
- - ~>
|
18
20
|
- !ruby/object:Gem::Version
|
19
21
|
version: 0.0.8
|
20
22
|
type: :runtime
|
21
23
|
prerelease: false
|
22
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
23
26
|
requirements:
|
24
|
-
- -
|
27
|
+
- - ~>
|
25
28
|
- !ruby/object:Gem::Version
|
26
29
|
version: 0.0.8
|
27
30
|
- !ruby/object:Gem::Dependency
|
28
31
|
name: bundler
|
29
32
|
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
30
34
|
requirements:
|
31
|
-
- -
|
35
|
+
- - ~>
|
32
36
|
- !ruby/object:Gem::Version
|
33
37
|
version: '1.5'
|
34
38
|
type: :development
|
35
39
|
prerelease: false
|
36
40
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
37
42
|
requirements:
|
38
|
-
- -
|
43
|
+
- - ~>
|
39
44
|
- !ruby/object:Gem::Version
|
40
45
|
version: '1.5'
|
41
46
|
- !ruby/object:Gem::Dependency
|
42
47
|
name: rake
|
43
48
|
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
44
50
|
requirements:
|
45
|
-
- -
|
51
|
+
- - ! '>='
|
46
52
|
- !ruby/object:Gem::Version
|
47
53
|
version: '0'
|
48
54
|
type: :development
|
49
55
|
prerelease: false
|
50
56
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
51
58
|
requirements:
|
52
|
-
- -
|
59
|
+
- - ! '>='
|
53
60
|
- !ruby/object:Gem::Version
|
54
61
|
version: '0'
|
55
|
-
description:
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
intended for general use, nor is it intended to be fast or concise.
|
62
|
+
description: ! " Iode is a work in progress real language on LLVM.\n This Ruby Gem
|
63
|
+
exists solely so the author can experiment with new language\n features before
|
64
|
+
committing those ideas to the real language. It is not\n intended for general use,
|
65
|
+
nor is it intended to be fast or concise.\n"
|
60
66
|
email:
|
61
67
|
- chris@w3style.co.uk
|
62
68
|
executables:
|
@@ -64,7 +70,7 @@ executables:
|
|
64
70
|
extensions: []
|
65
71
|
extra_rdoc_files: []
|
66
72
|
files:
|
67
|
-
-
|
73
|
+
- .gitignore
|
68
74
|
- Gemfile
|
69
75
|
- LICENSE.txt
|
70
76
|
- README.md
|
@@ -84,25 +90,26 @@ files:
|
|
84
90
|
homepage: https://github.com/d11wtq/iode-rb
|
85
91
|
licenses:
|
86
92
|
- MIT
|
87
|
-
metadata: {}
|
88
93
|
post_install_message:
|
89
94
|
rdoc_options: []
|
90
95
|
require_paths:
|
91
96
|
- lib
|
92
97
|
required_ruby_version: !ruby/object:Gem::Requirement
|
98
|
+
none: false
|
93
99
|
requirements:
|
94
|
-
- -
|
100
|
+
- - ! '>='
|
95
101
|
- !ruby/object:Gem::Version
|
96
102
|
version: '0'
|
97
103
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
104
|
+
none: false
|
98
105
|
requirements:
|
99
|
-
- -
|
106
|
+
- - ! '>='
|
100
107
|
- !ruby/object:Gem::Version
|
101
108
|
version: '0'
|
102
109
|
requirements: []
|
103
110
|
rubyforge_project:
|
104
|
-
rubygems_version:
|
111
|
+
rubygems_version: 1.8.23
|
105
112
|
signing_key:
|
106
|
-
specification_version:
|
113
|
+
specification_version: 3
|
107
114
|
summary: An experimental lisp-family language hosted on Ruby
|
108
115
|
test_files: []
|
checksums.yaml
DELETED
@@ -1,7 +0,0 @@
|
|
1
|
-
---
|
2
|
-
SHA1:
|
3
|
-
metadata.gz: ef8311e9162a113a3aff4d5741524ac2bd6eafcb
|
4
|
-
data.tar.gz: 56634c23acfedee8d05d6bc38a78392dc9df0865
|
5
|
-
SHA512:
|
6
|
-
metadata.gz: 295055612ba622c3f84503f957e996a9996f32201bf934c571c63a17c93144dad7fe7fa206abfe469c5f4dc0e34262c12f1b19a9e69c24dabe9a9c401a25f837
|
7
|
-
data.tar.gz: fc8b1824b95dbf0583917390f64b4df9614f320e4d0c972d6c8e8d81f84518a9be58d5b2e570feaaf13d5178efddbbb6edee38f0368e03a9cda27be6a6455db9
|