-
Notifications
You must be signed in to change notification settings - Fork 3
/
compiler.syrup
80 lines (72 loc) · 1.68 KB
/
compiler.syrup
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
# WORK IN PROGRESS COMPILER PORT TO SYRUP
# Featuring such features like destructuring assignment
# and actual method calls
chunker = {
"leftbracket": /^\[/
"rightbracket": /^\]/
"leftparen": /^\(/
"rightparen": /^\)[;:]?/
"leftbrace": /^\{/
"rightbrace": /^\}/
"quote": /^`/
"indent": /^\n[\t ]*/
"string": /^("([^\\"]|\\\\|\\")*"|'([^\\']|\\\\|\\')*')[:]?/
"regex": /^\/([^\\\/]|\\\\|\\\/)*\//
"callargs": /^[a-zA-Z_?!+\-\/*=\.]+[:]/
"call": /^[a-zA-Z_?!+\-\/*=\.]+[;]/
"atom": /^[a-zA-Z_?!+\-\/*=\.]+/
"comma": /^,/
"semicolon": /^;/
"null": /^null/
"bool": /^true|^false/
"number": /^[0-9+]+/
"comment": /^\#[^\n]+/
}
tokenInner = fn: [c2, tokens]
loop: [mylist = pairs: chunker]
item = first: mylist
k = first: item
patt = first: rest: item
if:
m = patt.exec: c2
do: fn: []
token = first: m
c3 = c2.substr: token.length
c4 = c3.replace: /^[\t ]+/, ''
tokens.push: [k, token]
c4
if:
first: rest: mylist
continue: rest: mylist
throw: new: host.Error 'Invalid Code'
while = macro: [match cond body else]
[`loop match [`if cond body else]]
tokenize = fn: [code]
c1 = code.replace: /^[\t ]+/, ''
tokens = []
while: [c2 = c1] (c2.length)
continue: tokenInner: c2, tokens
tokens
parse = fn: [code]
tokens = tokenize: code
i = 0
# Return parse tree.
res = []
# Stack of current node, and indentation level
stack = [[res, -1]]
indent = 0
at = fn: [type]
if: tokens[i]
tokens[i][0] == type
false
peek = fn: [type]
if: tokens[i + 1]
tokens[i + 1][0] == type
false
next = fn: []
i = i + 1
tokens[i - 1]
top = fn: []
if: stack[stack.length - 1]
stack[stack.length - 1][0]
false