aboutsummaryrefslogtreecommitdiffstats
path: root/alv/parsing.moon
blob: 78ed7d18425fad45f75d24d27063f298d3754655 (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
----
-- Lpeg Grammar for parsing `alive` code.
--
-- @module parsing
import Constant from require 'alv.result'
import Cell from require 'alv.cell'
import Tag from require 'alv.tag'
import R, S, P, V, C, Ct from require 'lpeg'

-- whitespace
wc = S ' \t\r\n'
comment = P {
  'comment',
  expr: (P '(') * ((V 'expr') + (1 - P ')'))^0 * (P ')')
  comment: (P '#(') * ((V 'expr') + (1 - P ')'))^0 * (P ')')
}
mspace = (comment + wc)^0 / 1            -- optional whitespace
space  = (wc^1 * (comment^0 * wc)^0) / 1 -- required whitespace

-- atoms
digit = R '09'
first = (R 'az', 'AZ') + S '-_+*/.,=~!?%$><'
sym = first * (first + digit)^0 / Constant\parse 'sym'

strd = '"' * (C ((P '\\"') + (P '\\\\') + (1 - P '"'))^0) * '"' / Constant\parse 'str', '\"'
strq = "'" * (C ((P "\\'") + (P '\\\\') + (1 - P "'"))^0) * "'" / Constant\parse 'str', '\''
str = strd + strq

int = digit^1
float = (digit^1 * '.' * digit^0) + (digit^0 * '.' * digit^1)
num = ((P '-')^-1 * (float + int)) / Constant\parse 'num'

atom = num + sym + str

expr = (V 'cell') + atom
explist = Ct mspace * ((V 'expr') * (space * (V 'expr'))^0 * mspace)^-1

tag = (P '[') * (digit^1 / Tag.parse) * (P ']')
cell = (P '(') * tag^-1 * (V 'explist') * (P ')') / Cell.parse

root = P {
  (V 'explist') / Cell.parse_root
  :expr, :explist, :cell
}

cell = P {
  'cell'
  :expr, :explist, :cell
}

program = root * -1

--- exports
-- @table exports
-- @tfield pattern comment
-- @tfield pattern space
-- @tfield pattern atom
-- @tfield pattern expr
-- @tfield pattern explist
-- @tfield pattern explist
-- @tfield pattern cell
-- @tfield pattern root
-- @tfield pattern program the main parsing entrypoint
{
  :comment
  :space
  :atom
  :expr
  :explist
  :cell
  :root
  :program
}