1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
|
import space, atom, cell, program, tplstr, comment from require 'alv.parsing'
import Constant from require 'alv'
import Logger from require 'alv.logger'
Logger\init 'silent'
verify_parse = (parser, val) ->
with assert (parser\match val), "unable to parse '#{val}'"
assert.is.equal val, \stringify!
verify_parse_nope = (parser, val) ->
with assert parser\match val
without_nope = val\match '^(.*) nope$'
assert.is.equal without_nope, \stringify!
describe 'atom parsing', ->
test 'symbols', ->
sym = verify_parse_nope atom, 'some-toast nope'
assert.is.equal (Constant.sym 'some-toast'), sym
describe 'numbers', ->
it 'parses ints', ->
num = verify_parse_nope atom, '1234 nope'
assert.is.equal (Constant.num 1234), num
num = verify_parse_nope atom, '-1234 nope'
assert.is.equal (Constant.num -1234), num
it 'parses floats', ->
num = verify_parse_nope atom, '0.123 nope'
assert.is.equal (Constant.num 0.123), num
num = verify_parse_nope atom, '.123 nope'
assert.is.equal (Constant.num 0.123), num
num = verify_parse_nope atom, '0. nope'
assert.is.equal (Constant.num 0), num
num = verify_parse_nope atom, '-45.123 nope'
assert.is.equal (Constant.num -45.123), num
num = verify_parse_nope atom, '-.123 nope'
assert.is.equal (Constant.num -0.123), num
num = verify_parse_nope atom, '-0. nope'
assert.is.equal (Constant.num 0), num
it 'parses fractions', ->
num = verify_parse_nope atom, '1/2 nope'
assert.is.equal (Constant.num 0.5), num
num = verify_parse_nope atom, '-3/4 nope'
assert.is.equal (Constant.num -0.75), num
describe 'strings', ->
it 'parses double-quote strings', ->
str = verify_parse_nope atom, '"help some stuff!" nope'
assert.is.equal (Constant.str 'help some stuff!'), str
it 'parses single-quote strings', ->
str = verify_parse_nope atom, "'help some stuff!' nope"
assert.is.equal (Constant.str "help some stuff!"), str
it 'handles escapes', ->
str = verify_parse_nope atom, '"string with \\"quote\\"s and \\\\" nope'
assert.is.equal (Constant.str 'string with \"quote\"s and \\'), str
str = verify_parse_nope atom, "'string with \\'quote\\'s and \\\\' nope"
assert.is.equal (Constant.str "string with \'quote\'s and \\"), str
describe 'Cell', ->
test 'basic parsing', ->
node = verify_parse cell, '( 3 ok-yes
"friend" )'
assert.is.equal 3, #node.children
assert.is.equal (Constant.num 3), node.children[1]
assert.is.equal (Constant.sym 'ok-yes'), node.children[2]
assert.is.equal (Constant.str 'friend'), node.children[3]
test 'tag parsing', ->
node = verify_parse cell, '([42]tagged 2)'
assert.is.equal 2, #node.children
assert.is.equal 42, node.tag.value
test 'tag parsing with whitespace', ->
node = verify_parse cell, '([42]
tagged 2)'
assert.is.equal 2, #node.children
assert.is.equal 42, node.tag.value
describe 'RootCell parsing', ->
describe 'handles whitespace', ->
verify = (str) ->
node = verify_parse program, str
assert.is.equal 2, #node.children
assert.is.equal (Constant.num 3), node.children[1]
assert.is.equal (Constant.sym 'ok-yes'), node.children[2]
it 'at the front of the string', ->
verify ' 3\tok-yes'
it 'at the end of the string', ->
verify ' 3\tok-yes\n'
it 'everywhere', ->
verify ' 3\tok-yes\n'
describe 'TemplateString parsing', ->
test 'basic parsing', ->
verify_parse tplstr, '$hi"me"'
verify_parse tplstr, '$[123]hi"me"'
node = verify_parse tplstr, '$[123]hi" string with $3$5 some $(= "contents") "'
assert.is.equal 5, #node.children
assert.is.equal (Constant.sym 'hi'), node.children[1]
assert.is.same {' string with ', '', ' some ', ' '}, node.children[2]\eval!.result!
assert.is.equal (Constant.num 3), node.children[3]
assert.is.equal (Constant.num 5), node.children[4]
assert.is.equal (Constant.sym '='), node.children[5]\head!
test 'can be empty', ->
node = verify_parse tplstr, '$hi""'
assert.is.equal 2, #node.children
assert.is.equal (Constant.sym 'hi'), node.children[1]
assert.is.same {''}, node.children[2]\eval!.result!
test 'can contain escapes', ->
node = verify_parse tplstr, '$hi"hi\nmy \\$friend"'
assert.is.same {'hi\nmy $friend'}, node.children[2]\eval!.result!
node = verify_parse tplstr, '$hi"\\$(this would\\${3}be invalid!"'
assert.is.same {'$(this would${3}be invalid!'}, node.children[2]\eval!.result!
test 'can contain quotes', ->
node = verify_parse tplstr, '$hi"$"this" is a string"'
assert.is.same {'', ' is a string'}, node.children[2]\eval!.result!
assert.is.same 'this', node.children[3]\eval!.result!
node = verify_parse tplstr, '$hi"a string is $"this""'
assert.is.same {'a string is ', ''}, node.children[2]\eval!.result!
assert.is.same 'this', node.children[3]\eval!.result!
node = verify_parse tplstr, '$hi"uh $(= "a" "b") huh"'
assert.is.same {'uh ', ' huh'}, node.children[2]\eval!.result!
test 'can be applied', ->
node = verify_parse tplstr, '$[123]hi" string with $3$5 some $(= "contents") "'
substituted = node.__class.subst node.children[2]\eval!.result!, {123, "foot", " where "}
assert.is.equal " string with 123foot some where ", substituted
test 'whitespace', ->
assert.is.equal ' ', space\match ' '
assert.is.equal '\n\t ', space\match '\n\t '
describe 'comments', ->
comment = comment / 1
it 'are parsed', ->
str = '#(this is a comment)'
assert.is.equal str, comment\match str
it 'line comments are parsed', ->
str = '## this is a comment )))!'
assert.is.equal str, comment\match str
it 'extend to matching braces', ->
str = '#(this is a comment #(with nested comments))'
assert.is.equal str, comment\match str
it 'can nest', ->
str = '#(this is a comment (with nested parenthesis))'
assert.is.equal str, comment\match str
describe 'resynthesis', ->
test 'mixed parsing', ->
str = '( 3 ok-yes
"friend" )'
node = verify_parse program, str
assert.is.equal str, node\stringify!
test 'complex', ->
str = '
#(send a CC controlled LFO to /radius)
(osc "/radius" (lfo (cc 14)))
(osc rot
(step
#(whenever a kick is received...)
(note "kick")
#(..cycle through random rotation values)
(random-rot)
(random-rot)
(random-rot)
(random-rot)
)
) '
matched = assert.is.truthy verify_parse program, str
assert.is.equal str, matched\stringify!
test 'nested tags', ->
str = '([2]a ([3]b))'
matched = assert.is.truthy verify_parse program, str
assert.is.equal str, matched\stringify!
|