subtle-lang 0.0.1 → 0.0.2
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/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
|