subtle-lang 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/subtle/evaluator.rb +54 -6
- data/lib/subtle/parser.rb +11 -3
- data/lib/subtle/version.rb +1 -1
- data/spec/subtle/evaluator_spec.rb +87 -20
- metadata +2 -2
data/lib/subtle/evaluator.rb
CHANGED
@@ -39,6 +39,12 @@ module Subtle
|
|
39
39
|
right.reduce do |fold, r|
|
40
40
|
eval type: :dyad, verb: verb, left: fold, right: r
|
41
41
|
end
|
42
|
+
when "/:" # Map each over right
|
43
|
+
right.map do |r|
|
44
|
+
eval type: :monad, verb: verb, right: r
|
45
|
+
end
|
46
|
+
else
|
47
|
+
nie! t, "Invalid adverb #{adverb} on Monads."
|
42
48
|
end
|
43
49
|
else
|
44
50
|
if Array === right
|
@@ -57,6 +63,14 @@ module Subtle
|
|
57
63
|
right.map do |r|
|
58
64
|
r == 0 ? 1 : 0
|
59
65
|
end
|
66
|
+
when "+"
|
67
|
+
if Array === right.first
|
68
|
+
right.transpose
|
69
|
+
else
|
70
|
+
right
|
71
|
+
end
|
72
|
+
when "|"
|
73
|
+
right.reverse
|
60
74
|
else
|
61
75
|
nie! "Verb #{verb} without Adverb not implemented as a Monad"
|
62
76
|
end
|
@@ -100,16 +114,42 @@ module Subtle
|
|
100
114
|
" right one, but #{left.size} != #{right.size}."
|
101
115
|
end
|
102
116
|
|
103
|
-
|
104
|
-
|
117
|
+
# Both have another dimension
|
118
|
+
if Array === left.first && Array === right.first
|
119
|
+
left.zip(right).map do |l, r|
|
120
|
+
eval type: :dyad, verb: verb, left: l, right: r
|
121
|
+
end
|
122
|
+
elsif Array === left.first || Array === right.first
|
123
|
+
left.zip(right).map do |l, r|
|
124
|
+
eval type: :dyad, verb: verb, left: l, right: r
|
125
|
+
end
|
126
|
+
else
|
127
|
+
left.zip(right).map do |l, r|
|
128
|
+
l.send(verb, r)
|
129
|
+
end
|
105
130
|
end
|
131
|
+
|
106
132
|
elsif Array === left && Numeric === right
|
107
|
-
|
108
|
-
|
133
|
+
# Multi-dimensional arrays
|
134
|
+
if Array === left.first
|
135
|
+
left.map do |l|
|
136
|
+
eval type: :dyad, verb: verb, left: l, right: right
|
137
|
+
end
|
138
|
+
else
|
139
|
+
left.map do |l|
|
140
|
+
l.send(verb, right)
|
141
|
+
end
|
109
142
|
end
|
110
143
|
elsif Numeric === left && Array === right
|
111
|
-
|
112
|
-
|
144
|
+
# Multi-dimensional arrays
|
145
|
+
if Array === right.first
|
146
|
+
right.map do |r|
|
147
|
+
eval type: :dyad, verb: verb, left: left, right: r
|
148
|
+
end
|
149
|
+
else
|
150
|
+
right.map do |r|
|
151
|
+
left.send(verb, r)
|
152
|
+
end
|
113
153
|
end
|
114
154
|
else
|
115
155
|
nie! t
|
@@ -140,6 +180,14 @@ module Subtle
|
|
140
180
|
else
|
141
181
|
nie! t
|
142
182
|
end
|
183
|
+
when "!"
|
184
|
+
if Numeric === left && Array === right
|
185
|
+
else
|
186
|
+
ae! t, "Left must be Numeric and right must be an Array for" +
|
187
|
+
" rotate (`!`) dyad. You passed in #{left.class} and" +
|
188
|
+
" #{right.class}"
|
189
|
+
end
|
190
|
+
right.rotate(left)
|
143
191
|
else
|
144
192
|
nie! t, "Invalid verb #{verb}."
|
145
193
|
end
|
data/lib/subtle/parser.rb
CHANGED
@@ -2,8 +2,8 @@ module Subtle
|
|
2
2
|
class Parser < Parslet::Parser
|
3
3
|
def initialize
|
4
4
|
@monadic_verbs = %w{+ - * / % ^ | & ~}
|
5
|
-
@monadic_adverbs = %w{/}
|
6
|
-
@dyadic_verbs = %w{+ - * / % ^ | &}
|
5
|
+
@monadic_adverbs = %w{/: /}
|
6
|
+
@dyadic_verbs = %w{+ - * / % ^ | & !}
|
7
7
|
@dyadic_adverbs = %w{/: \:}
|
8
8
|
end
|
9
9
|
|
@@ -16,7 +16,15 @@ module Subtle
|
|
16
16
|
rule(:float) { (minus.maybe >> digits >> str(".") >> digits).as(:float) >>
|
17
17
|
spaces? }
|
18
18
|
rule(:atom) { float | integer }
|
19
|
-
|
19
|
+
|
20
|
+
rule :array do
|
21
|
+
atom_or_array = (array | (atom >> spaces?).repeat.as(:array)) >> spaces?
|
22
|
+
|
23
|
+
(str("(") >> spaces? >> atom_or_array >>
|
24
|
+
(str(";") >> spaces? >> atom_or_array).repeat >>
|
25
|
+
spaces? >> str(")") >> spaces?).as(:array) |
|
26
|
+
(atom >> spaces?).repeat(2).as(:array) >> spaces?
|
27
|
+
end
|
20
28
|
|
21
29
|
rule :enumerate do
|
22
30
|
(str("!") >> spaces? >> (float | integer).as(:last)).as(:enumerate)
|
data/lib/subtle/version.rb
CHANGED
@@ -33,6 +33,15 @@ describe Subtle::Evaluator do
|
|
33
33
|
e "1 | 7 0 & 8 2 | 8 & 6 7 & 1", [7, 1]
|
34
34
|
end
|
35
35
|
end
|
36
|
+
|
37
|
+
describe "Rotate (`!`) (on left: Integer, right: Array)" do
|
38
|
+
e "2 ! 1 2 3", [3, 1, 2]
|
39
|
+
e "2 ! (1 2)", [1, 2]
|
40
|
+
e "2 ! (2 3; 4 5; 8)", [[8], [2, 3], [4, 5]]
|
41
|
+
e "-2 ! 1 2 3", [2, 3, 1]
|
42
|
+
e "-2 ! (1 2)", [1, 2]
|
43
|
+
e "-2 ! (2 3; 4 5; 8)", [[4, 5], [8], [2, 3]]
|
44
|
+
end
|
36
45
|
end
|
37
46
|
|
38
47
|
describe "Enumerate (`!`)" do
|
@@ -47,29 +56,41 @@ describe Subtle::Evaluator do
|
|
47
56
|
end
|
48
57
|
|
49
58
|
describe "Adverbs" do
|
50
|
-
describe "
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
59
|
+
describe "on Dyads" do
|
60
|
+
describe "Map over each right (`/:`)" do
|
61
|
+
e "1 2 3 +/: 5 6", [[6, 7, 8], [7, 8, 9]]
|
62
|
+
e "1 2 3 -/: 0 1", [[1, 2, 3], [0, 1, 2]]
|
63
|
+
e "3 2 3 ^/: 2 3", [[9, 4, 9], [27, 8, 27]]
|
64
|
+
e "3 2 3 &/: 2 3", [[2, 2, 2], [3, 2, 3]]
|
65
|
+
e "1 2 3 |/: 0 3", [[1, 2, 3], [3, 3, 3]]
|
66
|
+
end
|
67
|
+
|
68
|
+
describe "Map over each left (`\:`)" do
|
69
|
+
e "1 2 3 +\\: 5 6", [[6, 7, 8], [7, 8, 9]].transpose
|
70
|
+
e "1 2 3 -\\: 0 1", [[1, 2, 3], [0, 1, 2]].transpose
|
71
|
+
e "3 2 3 ^\\: 2 3", [[9, 4, 9], [27, 8, 27]].transpose
|
72
|
+
e "3 2 3 &\\: 2 3", [[2, 2, 2], [3, 2, 3]].transpose
|
73
|
+
e "1 2 3 |\\: 0 3", [[1, 2, 3], [3, 3, 3]].transpose
|
74
|
+
end
|
57
75
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
76
|
+
describe "Fold (`/`)" do
|
77
|
+
e "+/1 2 3", 6
|
78
|
+
# +/3 4 => 7; 1 2 + 7 => 8 9; +/8 9 => 17;
|
79
|
+
e "+/1 2 + +/3 4", 17
|
80
|
+
e "^/2 3 4", 4096
|
81
|
+
e "&/1 2 3", 1
|
82
|
+
e "|/1 2 3", 3
|
83
|
+
end
|
64
84
|
end
|
65
85
|
|
66
|
-
describe "
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
86
|
+
describe "on Monads" do
|
87
|
+
describe "Map over each right (`/:`)" do
|
88
|
+
# Where (`&`), Not (`~`), Transpose (`+`) and Reverse (`|`)
|
89
|
+
e "&/: (0 2; 2 1)", [[1, 1], [0, 0, 1]]
|
90
|
+
e "~/: (0 1; 0 1)", [[1, 0], [1, 0]]
|
91
|
+
e "+/: ((1 2; 3 4); (5 6; 7 8))", [[[1, 3], [2, 4]], [[5, 7], [6, 8]]]
|
92
|
+
e "|/: (0 1; 0 2)", [[1, 0], [2, 0]]
|
93
|
+
end
|
73
94
|
end
|
74
95
|
end
|
75
96
|
|
@@ -82,11 +103,57 @@ describe Subtle::Evaluator do
|
|
82
103
|
describe "Not (`~`)" do
|
83
104
|
e "~1 0 -1 1 7 8 0 0", [0, 1, 0, 0, 0, 0, 1, 1]
|
84
105
|
end
|
106
|
+
|
107
|
+
describe "Transpose (`+`)" do
|
108
|
+
e "+1 2 3", [1, 2, 3]
|
109
|
+
e "+(1 2; 3 4; 5 6)", [[1, 3, 5], [2, 4, 6]]
|
110
|
+
end
|
111
|
+
|
112
|
+
describe "Reverse (`|`)" do
|
113
|
+
e "|1 2", [2, 1]
|
114
|
+
e "|(1 2; 3; (6 7; 8))", [[[6, 7], [8]], [3], [1, 2]]
|
115
|
+
end
|
85
116
|
end
|
117
|
+
|
118
|
+
describe "Multi-dimensional Arrays" do
|
119
|
+
describe "Declaring" do
|
120
|
+
e "(1 2; 3 4; 5 6.6 7)", [[1, 2], [3, 4], [5, 6.6, 7]]
|
121
|
+
e "(;;;)", [[], [], [], []]
|
122
|
+
e "(;;3 8;)", [[], [], [3, 8], []]
|
123
|
+
e "(1;2.2 3.3;(;;3 8;);)", [[1], [2.2, 3.3], [[], [], [3, 8], []], []]
|
124
|
+
end
|
125
|
+
|
126
|
+
describe "Dyads" do
|
127
|
+
describe "on Atoms and 2D/3D Arrays" do
|
128
|
+
e "1 + (;1 2; 3 4)", [[], [2, 3], [4, 5]]
|
129
|
+
e "2 ^ ((5 6; 0 1);1 2; 3 4)", [[[32, 64], [1, 2]], [2, 4], [8, 16]]
|
130
|
+
e "(;1 2; 3 4) - 1", [[], [0, 1], [2, 3]]
|
131
|
+
e "((5 6; 0 1);1 2; 3 4) ^ 2", [[[25, 36], [0, 1]], [1, 4], [9, 16]]
|
132
|
+
end
|
133
|
+
|
134
|
+
describe "on 1D/2D/3D Arrays with 2D/3D Arrays" do
|
135
|
+
e "(1 2; 3 4) + (2 3; 4 5)", [[3, 5], [7, 9]]
|
136
|
+
e "(1 2; 3 4) % (2 3; 4 5)", [[1, 2], [3, 4]]
|
137
|
+
e "((1 2); 5 6) + (3 1)", [[4, 5], [6, 7]]
|
138
|
+
e "(((2 4); (6 8)); ((2 4); (6 8))) + 1 2", [[[3, 5], [7, 9]],
|
139
|
+
[[4, 6], [8, 10]]]
|
140
|
+
e "(((2 4); (6 8)); ((2 4); (6 8))) * (((2 4); (6 8)); ((2 4); (6 8)))",
|
141
|
+
[[[4, 16], [36, 64]], [[4, 16], [36, 64]]]
|
142
|
+
e "1 2 + (((2 4); (6 8)); ((2 4); (6 8)))", [[[3, 5], [7, 9]],
|
143
|
+
[[4, 6], [8, 10]]]
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
86
148
|
describe "Errors" do
|
87
149
|
describe "on Arrays" do
|
88
150
|
ae! "1 2 + 2 3 4"
|
89
151
|
ae! "1 2 | 2 3 4"
|
90
152
|
end
|
153
|
+
|
154
|
+
describe "on Rotate" do
|
155
|
+
ae! "1 2 ! 2 3"
|
156
|
+
ae! "2 ! 1"
|
157
|
+
end
|
91
158
|
end
|
92
159
|
end
|
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.2
|
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-09 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: parslet
|