subtle-lang 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +7 -0
- data/README.md +24 -16
- data/lib/subtle/evaluator.rb +60 -24
- data/lib/subtle/parser.rb +42 -7
- data/lib/subtle/transform.rb +42 -4
- data/lib/subtle/version.rb +1 -1
- data/spec/examples/project_euler_spec.rb +7 -1
- data/spec/spec_helper.rb +6 -3
- data/spec/subtle/evaluator_spec.rb +66 -5
- data/subtle.gemspec +1 -1
- metadata +3 -18
data/.travis.yml
ADDED
data/README.md
CHANGED
@@ -1,29 +1,37 @@
|
|
1
|
-
# Subtle
|
1
|
+
# Subtle [![Build Status](https://travis-ci.org/utkarshkukreti/subtle-lang.png)](https://travis-ci.org/utkarshkukreti/subtle-lang)
|
2
2
|
|
3
|
-
|
3
|
+
Subtle is a Terse, Array based Programming Language, heavily inspired by the K
|
4
|
+
Programming Language, and partly by APL and J.
|
4
5
|
|
5
6
|
## Installation
|
6
7
|
|
7
|
-
|
8
|
+
### Using Git (Recommended)
|
8
9
|
|
9
|
-
|
10
|
+
git clone https://github.com/utkarshkukreti/subtle-lang.git
|
11
|
+
cd subtle-lang
|
12
|
+
bundle install
|
13
|
+
rake install
|
10
14
|
|
11
|
-
|
15
|
+
### From RubyGems
|
12
16
|
|
13
|
-
|
17
|
+
gem install subtle-lang
|
14
18
|
|
15
|
-
|
19
|
+
## Usage
|
16
20
|
|
17
|
-
|
21
|
+
Run
|
18
22
|
|
19
|
-
|
23
|
+
subtle
|
24
|
+
|
25
|
+
to start the interactive REPL.
|
26
|
+
|
27
|
+
## Documentation
|
28
|
+
|
29
|
+
No docs yet, but the language is **heavily** tested.
|
30
|
+
|
31
|
+
Best way to learn more is to read the specs in `spec/`.
|
20
32
|
|
21
|
-
|
33
|
+
## License
|
22
34
|
|
23
|
-
|
35
|
+
The MIT License
|
24
36
|
|
25
|
-
|
26
|
-
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
-
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
|
-
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
-
5. Create new Pull Request
|
37
|
+
Copyright (c) 2012 Utkarsh Kukreti
|
data/lib/subtle/evaluator.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
module Subtle
|
2
2
|
class Evaluator
|
3
3
|
def initialize
|
4
|
+
@state = {}
|
4
5
|
@parser = Parser.new
|
5
6
|
@transform = Transform.new
|
6
7
|
end
|
@@ -15,7 +16,45 @@ module Subtle
|
|
15
16
|
|
16
17
|
if Hash === t
|
17
18
|
type = t[:type]
|
19
|
+
|
18
20
|
case type
|
21
|
+
when :assignment
|
22
|
+
identifier = t[:identifier]
|
23
|
+
right = try_eval t[:right]
|
24
|
+
@state[identifier] = right
|
25
|
+
when :deassignment
|
26
|
+
identifier = t[:identifier]
|
27
|
+
@state[identifier]
|
28
|
+
when :function
|
29
|
+
t[:function]
|
30
|
+
when :function_call
|
31
|
+
function = t[:function]
|
32
|
+
adverb = t[:adverb]
|
33
|
+
right = try_eval t[:right]
|
34
|
+
if adverb
|
35
|
+
case adverb
|
36
|
+
when "/:"
|
37
|
+
right = [right] unless Array === right
|
38
|
+
right.map do |r|
|
39
|
+
eval type: :function_call, function: function, right: r
|
40
|
+
end
|
41
|
+
else
|
42
|
+
ae! t, "Invalid adverb #{adverb.inspect} for :function_call."
|
43
|
+
end
|
44
|
+
else
|
45
|
+
_x = @state["x"]
|
46
|
+
@state["x"] = right
|
47
|
+
eval(function).tap do
|
48
|
+
@state["x"] = _x
|
49
|
+
end
|
50
|
+
end
|
51
|
+
when :variable_call
|
52
|
+
identifier = t[:identifier]
|
53
|
+
adverb = t[:adverb]
|
54
|
+
arguments = t[:arguments]
|
55
|
+
function = @state[identifier]
|
56
|
+
eval type: :function_call, function: function, adverb: adverb,
|
57
|
+
right: arguments
|
19
58
|
when :monad
|
20
59
|
verb = t[:verb]
|
21
60
|
adverb = t[:adverb]
|
@@ -35,6 +74,10 @@ module Subtle
|
|
35
74
|
" You passed in #{right.class}."
|
36
75
|
end
|
37
76
|
case adverb
|
77
|
+
when "//:"
|
78
|
+
right.map do |r|
|
79
|
+
eval type: :monad, verb: verb, adverb: "/", right: r
|
80
|
+
end
|
38
81
|
when "/"
|
39
82
|
right.reduce do |fold, r|
|
40
83
|
eval type: :dyad, verb: verb, left: fold, right: r
|
@@ -76,21 +119,16 @@ module Subtle
|
|
76
119
|
end
|
77
120
|
end
|
78
121
|
when :dyad
|
122
|
+
# Evaluate right first.
|
123
|
+
right = try_eval t[:right]
|
79
124
|
left = try_eval t[:left]
|
80
125
|
verb = t[:verb]
|
81
126
|
adverb = t[:adverb]
|
82
|
-
right = try_eval t[:right]
|
83
127
|
|
84
128
|
# `^` in Subtle is `**` in Ruby.
|
85
129
|
verb = "**" if verb == "^"
|
86
130
|
|
87
131
|
if adverb
|
88
|
-
if Array === left && Array === right
|
89
|
-
else
|
90
|
-
ae! t, "Adverb `#{adverb}` must have arrays on both left and" +
|
91
|
-
" right. You passed in #{left.class} and #{right.class}."
|
92
|
-
end
|
93
|
-
|
94
132
|
case adverb
|
95
133
|
when "/:" # Map each over right
|
96
134
|
right.map do |r|
|
@@ -125,34 +163,31 @@ module Subtle
|
|
125
163
|
end
|
126
164
|
else
|
127
165
|
left.zip(right).map do |l, r|
|
128
|
-
l.send(verb, r)
|
166
|
+
(try_eval l).send(verb, try_eval(r))
|
129
167
|
end
|
130
168
|
end
|
131
169
|
|
132
170
|
elsif Array === left && Numeric === right
|
133
|
-
|
134
|
-
|
135
|
-
|
171
|
+
left.map do |l|
|
172
|
+
# Multi-dimensional arrays
|
173
|
+
if Array === l
|
136
174
|
eval type: :dyad, verb: verb, left: l, right: right
|
137
|
-
|
138
|
-
|
139
|
-
left.map do |l|
|
140
|
-
l.send(verb, right)
|
175
|
+
else
|
176
|
+
(try_eval l).send(verb, right)
|
141
177
|
end
|
142
178
|
end
|
143
179
|
elsif Numeric === left && Array === right
|
144
|
-
|
145
|
-
|
146
|
-
|
180
|
+
right.map do |r|
|
181
|
+
# Multi-dimensional arrays
|
182
|
+
if Array === r
|
147
183
|
eval type: :dyad, verb: verb, left: left, right: r
|
148
|
-
|
149
|
-
else
|
150
|
-
right.map do |r|
|
184
|
+
else
|
151
185
|
left.send(verb, r)
|
152
186
|
end
|
153
187
|
end
|
154
188
|
else
|
155
|
-
nie! t
|
189
|
+
nie! t, "Left and Array must be Numeric or Arrays." +
|
190
|
+
" You passed in #{left.class} and #{right.class}."
|
156
191
|
end
|
157
192
|
when "&", "|"
|
158
193
|
verb = "min" if verb == "&"
|
@@ -197,10 +232,11 @@ module Subtle
|
|
197
232
|
if Numeric === last
|
198
233
|
(0...last.floor).to_a
|
199
234
|
else
|
200
|
-
nie! t
|
235
|
+
nie! t, "`last` must be Numeric for type: :enumerate. You passed" +
|
236
|
+
" in #{last.class}."
|
201
237
|
end
|
202
238
|
else
|
203
|
-
nie! t
|
239
|
+
nie! t, "Type #{t[:type].inspect} not implemented."
|
204
240
|
end
|
205
241
|
else
|
206
242
|
t
|
data/lib/subtle/parser.rb
CHANGED
@@ -2,9 +2,10 @@ module Subtle
|
|
2
2
|
class Parser < Parslet::Parser
|
3
3
|
def initialize
|
4
4
|
@monadic_verbs = %w{+ - * / % ^ | & ~}
|
5
|
-
@monadic_adverbs = %w{/: /}
|
5
|
+
@monadic_adverbs = %w{//: /: /}
|
6
6
|
@dyadic_verbs = %w{+ - * / % ^ | & !}
|
7
7
|
@dyadic_adverbs = %w{/: \:}
|
8
|
+
@function_adverbs = %w{/:}
|
8
9
|
end
|
9
10
|
|
10
11
|
rule(:spaces) { match["\\s"].repeat(1) }
|
@@ -12,10 +13,39 @@ module Subtle
|
|
12
13
|
rule(:digits) { match["0-9"].repeat(1) }
|
13
14
|
rule(:minus) { str("-") }
|
14
15
|
|
15
|
-
rule(:integer)
|
16
|
-
rule(:float)
|
17
|
-
|
18
|
-
rule(:
|
16
|
+
rule(:integer) { (minus.maybe >> digits).as(:integer) >> spaces? }
|
17
|
+
rule(:float) { (minus.maybe >> digits >> str(".") >> digits).
|
18
|
+
as(:float) >> spaces? }
|
19
|
+
rule(:identifier) { (match["a-zA-Z"] >> match["a-zA-Z0-9_"].repeat).
|
20
|
+
as(:identifier) }
|
21
|
+
rule(:assignment) { (identifier >> spaces? >> str(":") >> spaces? >>
|
22
|
+
word.as(:right)).as(:assignment) >> spaces? }
|
23
|
+
rule(:deassignment) { identifier.as(:deassignment) >> spaces? }
|
24
|
+
|
25
|
+
rule(:function) do
|
26
|
+
str("{") >> spaces? >> word.as(:function) >> spaces? >> str("}") >>
|
27
|
+
spaces?
|
28
|
+
end
|
29
|
+
|
30
|
+
rule :function_adverb do
|
31
|
+
@function_adverbs.map { |adverb| str(adverb) }.reduce(:|).as(:adverb) >>
|
32
|
+
spaces?
|
33
|
+
end
|
34
|
+
|
35
|
+
rule(:function_call) do
|
36
|
+
(function >> function_adverb.maybe >> word.as(:right)).
|
37
|
+
as(:function_call) >> spaces?
|
38
|
+
end
|
39
|
+
|
40
|
+
rule(:variable_call) do
|
41
|
+
(identifier >> spaces? >> function_adverb.maybe >>
|
42
|
+
(assignment | dyad | noun).as(:arguments)).as(:variable_call)
|
43
|
+
end
|
44
|
+
|
45
|
+
rule(:atom) do
|
46
|
+
variable_call | function_call | function | float | integer | pword |
|
47
|
+
deassignment
|
48
|
+
end
|
19
49
|
|
20
50
|
rule :array do
|
21
51
|
atom_or_array = (array | (atom >> spaces?).repeat.as(:array)) >> spaces?
|
@@ -27,7 +57,7 @@ module Subtle
|
|
27
57
|
end
|
28
58
|
|
29
59
|
rule :enumerate do
|
30
|
-
(str("!") >> spaces? >> (
|
60
|
+
(str("!") >> spaces? >> (word).as(:last)).as(:enumerate)
|
31
61
|
end
|
32
62
|
|
33
63
|
rule(:noun) { enumerate | array | atom }
|
@@ -60,7 +90,12 @@ module Subtle
|
|
60
90
|
end
|
61
91
|
|
62
92
|
rule :word do
|
63
|
-
dyad | noun | monad
|
93
|
+
assignment | dyad | noun | monad
|
94
|
+
end
|
95
|
+
|
96
|
+
# This is the last option of rule(:atom) above ^
|
97
|
+
rule :pword do
|
98
|
+
str("(") >> spaces? >> word >> spaces? >> str(")") >> spaces?
|
64
99
|
end
|
65
100
|
|
66
101
|
rule :sentence do
|
data/lib/subtle/transform.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
module Subtle
|
2
2
|
class Transform < Parslet::Transform
|
3
|
-
rule(integer:
|
4
|
-
rule(float:
|
5
|
-
rule(array:
|
3
|
+
rule(integer: simple(:x)) { x.to_i }
|
4
|
+
rule(float: simple(:x)) { x.to_f }
|
5
|
+
rule(array: subtree(:x)) { x.size == 1 ? x.first : x }
|
6
6
|
|
7
7
|
rule monad: { verb: simple(:verb), right: subtree(:right) } do
|
8
8
|
{ type: :monad, verb: verb.to_s, right: right }
|
@@ -20,11 +20,49 @@ module Subtle
|
|
20
20
|
|
21
21
|
rule dyad: { left: subtree(:left), verb: simple(:verb),
|
22
22
|
adverb: simple(:adverb), right: subtree(:right) } do
|
23
|
-
{ type: :dyad, left: left, verb: verb.to_s, adverb: adverb,
|
23
|
+
{ type: :dyad, left: left, verb: verb.to_s, adverb: adverb.to_s,
|
24
|
+
right: right }
|
24
25
|
end
|
25
26
|
|
26
27
|
rule enumerate: { last: subtree(:last) } do
|
27
28
|
{ type: :enumerate, last: last }
|
28
29
|
end
|
30
|
+
|
31
|
+
rule assignment: { identifier: simple(:identifier),
|
32
|
+
right: subtree(:right) } do
|
33
|
+
{ type: :assignment, identifier: identifier.to_s, right: right }
|
34
|
+
end
|
35
|
+
|
36
|
+
rule deassignment: { identifier: simple(:identifier) } do
|
37
|
+
{ type: :deassignment, identifier: identifier.to_s }
|
38
|
+
end
|
39
|
+
|
40
|
+
rule function: subtree(:function) do
|
41
|
+
{ type: :function, function: function }
|
42
|
+
end
|
43
|
+
|
44
|
+
rule function_call: { function: subtree(:function),
|
45
|
+
right: subtree(:right) } do
|
46
|
+
{ type: :function_call, function: function, right: right }
|
47
|
+
end
|
48
|
+
|
49
|
+
rule function_call: { function: subtree(:function), adverb: simple(:adverb),
|
50
|
+
right: subtree(:right) } do
|
51
|
+
{ type: :function_call, function: function, adverb: adverb.to_s,
|
52
|
+
right: right }
|
53
|
+
end
|
54
|
+
|
55
|
+
rule variable_call: { identifier: simple(:identifier),
|
56
|
+
arguments: subtree(:arguments) } do
|
57
|
+
{ type: :variable_call, identifier: identifier.to_s,
|
58
|
+
arguments: arguments }
|
59
|
+
end
|
60
|
+
|
61
|
+
rule variable_call: { identifier: simple(:identifier),
|
62
|
+
adverb: simple(:adverb),
|
63
|
+
arguments: subtree(:arguments) } do
|
64
|
+
{ type: :variable_call, identifier: identifier.to_s, adverb: adverb.to_s,
|
65
|
+
arguments: arguments }
|
66
|
+
end
|
29
67
|
end
|
30
68
|
end
|
data/lib/subtle/version.rb
CHANGED
@@ -5,7 +5,13 @@ describe Subtle do
|
|
5
5
|
describe "Project Euler" do
|
6
6
|
describe "Problem 1:" +
|
7
7
|
" Find the sum of all the multiples of 3 or 5 below 1000." do
|
8
|
-
e "
|
8
|
+
e "+/&~&/(!1000)%/:3 5", 233168
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "Problem 6:" +
|
12
|
+
" Find the difference between the sum of the squares of the first" +
|
13
|
+
" one hundred natural numbers and the square of the sum." do
|
14
|
+
e "((+/!101)^2)-+/(!101)^2", 25164150
|
9
15
|
end
|
10
16
|
end
|
11
17
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -8,10 +8,13 @@ end
|
|
8
8
|
require "subtle"
|
9
9
|
|
10
10
|
RSpec.configure do |config|
|
11
|
-
def e(input, output)
|
11
|
+
def e(input, output, evaluator = nil)
|
12
12
|
it "should evaluate #{input.inspect} to #{output.inspect}" do
|
13
|
-
evaluator
|
14
|
-
evaluator.eval(input)
|
13
|
+
evaluator ||= Subtle::Evaluator.new
|
14
|
+
evaluated = evaluator.eval(input)
|
15
|
+
if output
|
16
|
+
evaluated.should eq output
|
17
|
+
end
|
15
18
|
end
|
16
19
|
end
|
17
20
|
|
@@ -37,17 +37,17 @@ describe Subtle::Evaluator do
|
|
37
37
|
describe "Rotate (`!`) (on left: Integer, right: Array)" do
|
38
38
|
e "2 ! 1 2 3", [3, 1, 2]
|
39
39
|
e "2 ! (1 2)", [1, 2]
|
40
|
-
e "2 ! (2 3; 4 5; 8)", [
|
40
|
+
e "2 ! (2 3; 4 5; 8)", [8, [2, 3], [4, 5]]
|
41
41
|
e "-2 ! 1 2 3", [2, 3, 1]
|
42
42
|
e "-2 ! (1 2)", [1, 2]
|
43
|
-
e "-2 ! (2 3; 4 5; 8)", [[4, 5],
|
43
|
+
e "-2 ! (2 3; 4 5; 8)", [[4, 5], 8, [2, 3]]
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
47
47
|
describe "Enumerate (`!`)" do
|
48
48
|
describe "Precedence" do
|
49
49
|
e "!4", [0, 1, 2, 3]
|
50
|
-
e "
|
50
|
+
e "5 - !2 + 2", [5, 4, 3, 2]
|
51
51
|
end
|
52
52
|
|
53
53
|
describe "on Floats" do
|
@@ -63,6 +63,7 @@ describe Subtle::Evaluator do
|
|
63
63
|
e "3 2 3 ^/: 2 3", [[9, 4, 9], [27, 8, 27]]
|
64
64
|
e "3 2 3 &/: 2 3", [[2, 2, 2], [3, 2, 3]]
|
65
65
|
e "1 2 3 |/: 0 3", [[1, 2, 3], [3, 3, 3]]
|
66
|
+
e "2 !/: (1 2 3; 2 3 4; 4 5 6)", [[3, 1, 2], [4, 2, 3], [6, 4, 5]]
|
66
67
|
end
|
67
68
|
|
68
69
|
describe "Map over each left (`\:`)" do
|
@@ -91,6 +92,11 @@ describe Subtle::Evaluator do
|
|
91
92
|
e "+/: ((1 2; 3 4); (5 6; 7 8))", [[[1, 3], [2, 4]], [[5, 7], [6, 8]]]
|
92
93
|
e "|/: (0 1; 0 2)", [[1, 0], [2, 0]]
|
93
94
|
end
|
95
|
+
|
96
|
+
describe "Map over and fold (`//:`)" do
|
97
|
+
e "+//: (2 4; 3 1)", [6, 4]
|
98
|
+
e "+//:+(2 4; 3 1)", [5, 5]
|
99
|
+
end
|
94
100
|
end
|
95
101
|
end
|
96
102
|
|
@@ -111,7 +117,7 @@ describe Subtle::Evaluator do
|
|
111
117
|
|
112
118
|
describe "Reverse (`|`)" do
|
113
119
|
e "|1 2", [2, 1]
|
114
|
-
e "|(1 2; 3; (6 7; 8))", [[[6, 7],
|
120
|
+
e "|(1 2; 3; (6 7; 8))", [[[6, 7], 8], 3, [1, 2]]
|
115
121
|
end
|
116
122
|
end
|
117
123
|
|
@@ -120,12 +126,13 @@ describe Subtle::Evaluator do
|
|
120
126
|
e "(1 2; 3 4; 5 6.6 7)", [[1, 2], [3, 4], [5, 6.6, 7]]
|
121
127
|
e "(;;;)", [[], [], [], []]
|
122
128
|
e "(;;3 8;)", [[], [], [3, 8], []]
|
123
|
-
e "(1;2.2 3.3;(;;3 8;);)", [
|
129
|
+
e "(1;2.2 3.3;(;;3 8;);)", [1, [2.2, 3.3], [[], [], [3, 8], []], []]
|
124
130
|
end
|
125
131
|
|
126
132
|
describe "Dyads" do
|
127
133
|
describe "on Atoms and 2D/3D Arrays" do
|
128
134
|
e "1 + (;1 2; 3 4)", [[], [2, 3], [4, 5]]
|
135
|
+
e "(1; 2 3) + 1", [2, [3, 4]]
|
129
136
|
e "2 ^ ((5 6; 0 1);1 2; 3 4)", [[[32, 64], [1, 2]], [2, 4], [8, 16]]
|
130
137
|
e "(;1 2; 3 4) - 1", [[], [0, 1], [2, 3]]
|
131
138
|
e "((5 6; 0 1);1 2; 3 4) ^ 2", [[[25, 36], [0, 1]], [1, 4], [9, 16]]
|
@@ -134,6 +141,7 @@ describe Subtle::Evaluator do
|
|
134
141
|
describe "on 1D/2D/3D Arrays with 2D/3D Arrays" do
|
135
142
|
e "(1 2; 3 4) + (2 3; 4 5)", [[3, 5], [7, 9]]
|
136
143
|
e "(1 2; 3 4) % (2 3; 4 5)", [[1, 2], [3, 4]]
|
144
|
+
e "(1 2; 3) + (1; 2 3)", [[2, 3], [5, 6]]
|
137
145
|
e "((1 2); 5 6) + (3 1)", [[4, 5], [6, 7]]
|
138
146
|
e "(((2 4); (6 8)); ((2 4); (6 8))) + 1 2", [[[3, 5], [7, 9]],
|
139
147
|
[[4, 6], [8, 10]]]
|
@@ -141,10 +149,63 @@ describe Subtle::Evaluator do
|
|
141
149
|
[[[4, 16], [36, 64]], [[4, 16], [36, 64]]]
|
142
150
|
e "1 2 + (((2 4); (6 8)); ((2 4); (6 8)))", [[[3, 5], [7, 9]],
|
143
151
|
[[4, 6], [8, 10]]]
|
152
|
+
e "1 2 + ((2; (6 8)); ((2 4 3); 6))", [[3, [7, 9]],
|
153
|
+
[[4, 6, 5], 8]]
|
144
154
|
end
|
145
155
|
end
|
146
156
|
end
|
147
157
|
|
158
|
+
describe "Parentheses" do
|
159
|
+
e "(1 + 1) * 2", 4
|
160
|
+
e "3 + (1 + 1) * 2", 7
|
161
|
+
e "(1 + 2) * 3", 9
|
162
|
+
e "(((((1 + 1) * 2) + 2) * 3) + 3) * 4", 84
|
163
|
+
end
|
164
|
+
|
165
|
+
describe "Variables" do
|
166
|
+
@e = Subtle::Evaluator.new
|
167
|
+
e "a: 10", 10, @e
|
168
|
+
e "a", 10, @e
|
169
|
+
e "b", nil, @e
|
170
|
+
e "a: 1 + 2", 3, @e
|
171
|
+
e "b: a + 2", 5, @e
|
172
|
+
# Tests whether dyads are evaluated from right to left.
|
173
|
+
e "a: 1", 1, @e
|
174
|
+
e "(a: 10) + (b: 6) * a * (a: 3) + a", 82, @e
|
175
|
+
end
|
176
|
+
|
177
|
+
describe "Functions" do
|
178
|
+
describe "Map" do
|
179
|
+
e "{x * 2 - x} 4", -8
|
180
|
+
e "{x * 2 - x} 4 6 8", [-8, -24, -48]
|
181
|
+
e "{x + 1} {x * 2 - x} 4 6 8", [-7, -23, -47]
|
182
|
+
e "{x + {x + x} x} 1 2 3", [3, 6, 9]
|
183
|
+
e "{!x} 2", [0, 1]
|
184
|
+
e "{!x + 1} 2", [0, 1, 2]
|
185
|
+
end
|
186
|
+
|
187
|
+
describe "Map over each right (`/:`)" do
|
188
|
+
e "{!x}/:1 2 3", [[0], [0, 1], [0, 1, 2]]
|
189
|
+
e "{!x + 1}/:!3", [[0], [0, 1], [0, 1, 2]]
|
190
|
+
e "{+x}/:((1 2; 3 4); (4 5; 6 7))", [[[1, 3], [2, 4]], [[4, 6], [5, 7]]]
|
191
|
+
end
|
192
|
+
|
193
|
+
describe "Storing in variables" do
|
194
|
+
@e = Subtle::Evaluator.new
|
195
|
+
e "a: {x + !x}", nil, @e
|
196
|
+
e "a 3", [3, 4, 5], @e
|
197
|
+
e "a /: 1 2 3", [[1], [2, 3], [3, 4, 5]], @e
|
198
|
+
e "b: {x + 1}", nil, @e
|
199
|
+
e "c: 4", 4, @e
|
200
|
+
e "c: b b b c", 7, @e
|
201
|
+
|
202
|
+
e "d: {x * 2}", nil, @e
|
203
|
+
e "e: {2 * d x}", nil, @e
|
204
|
+
e "f: {(d x) + e x}", nil, @e
|
205
|
+
e "d e f f d e 6", 13824, @e
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
148
209
|
describe "Errors" do
|
149
210
|
describe "on Arrays" do
|
150
211
|
ae! "1 2 + 2 3 4"
|
data/subtle.gemspec
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: subtle-lang
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-12-
|
12
|
+
date: 2012-12-11 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: parslet
|
@@ -91,22 +91,6 @@ dependencies:
|
|
91
91
|
- - ! '>='
|
92
92
|
- !ruby/object:Gem::Version
|
93
93
|
version: '0'
|
94
|
-
- !ruby/object:Gem::Dependency
|
95
|
-
name: pry-debugger
|
96
|
-
requirement: !ruby/object:Gem::Requirement
|
97
|
-
none: false
|
98
|
-
requirements:
|
99
|
-
- - ! '>='
|
100
|
-
- !ruby/object:Gem::Version
|
101
|
-
version: '0'
|
102
|
-
type: :development
|
103
|
-
prerelease: false
|
104
|
-
version_requirements: !ruby/object:Gem::Requirement
|
105
|
-
none: false
|
106
|
-
requirements:
|
107
|
-
- - ! '>='
|
108
|
-
- !ruby/object:Gem::Version
|
109
|
-
version: '0'
|
110
94
|
description: ! "Subtle is a Terse, Array based Programming Language,\n heavily
|
111
95
|
inspired by the K Programming Language, and\n partly by
|
112
96
|
APL and J."
|
@@ -119,6 +103,7 @@ extra_rdoc_files: []
|
|
119
103
|
files:
|
120
104
|
- .gitignore
|
121
105
|
- .rspec
|
106
|
+
- .travis.yml
|
122
107
|
- Gemfile
|
123
108
|
- Guardfile
|
124
109
|
- LICENSE.txt
|