aboutsummaryrefslogtreecommitdiffstats
path: root/spec/parsing_spec.moon
blob: 0486276cf7f6adb0f3b6036d47564ea3acf3646f (plain)
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
import space, atom, expr, explist, cell, program, 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
    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

    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

  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'

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 '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!