subtle-lang 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/.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 [](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
|