-
Notifications
You must be signed in to change notification settings - Fork 195
Expand file tree
/
Copy pathvalue.moon
More file actions
164 lines (128 loc) · 3.93 KB
/
value.moon
File metadata and controls
164 lines (128 loc) · 3.93 KB
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
import Transformer from require "moonscript.transform.transformer"
import build, ntype, smart_node from require "moonscript.types"
import NameProxy from require "moonscript.transform.names"
import Accumulator, default_accumulator from require "moonscript.transform.accumulator"
import lua_keywords from require "moonscript.data"
import Run, transform_last_stm, implicitly_return, chain_is_stub from require "moonscript.transform.statements"
import construct_comprehension from require "moonscript.transform.comprehension"
import insert from table
import unpack from require "moonscript.util"
Transformer {
for: default_accumulator
while: default_accumulator
foreach: default_accumulator
do: (node) =>
build.block_exp node[2]
decorated: (node) =>
@transform.statement node
class: (node) =>
build.block_exp { node }
string: (node) =>
delim = node[2]
convert_part = (part) ->
if type(part) == "string" or part == nil
{"string", delim, part or ""}
else
build.chain { base: "tostring", {"call", {part[2]}} }
-- reduced to single item
if #node <= 3
return if type(node[3]) == "string"
node
else
convert_part node[3]
e = {"exp", convert_part node[3]}
for i=4, #node
insert e, ".."
insert e, convert_part node[i]
e
comprehension: (node) =>
a = Accumulator!
node = @transform.statement node, (exp) ->
a\mutate_body {exp}
a\wrap node
tblcomprehension: (node) =>
explist, clauses = unpack node, 2
key_exp, value_exp = unpack explist
accum = NameProxy "tbl"
inner = if value_exp
dest = build.chain { base: accum, {"index", key_exp} }
{ build.assign_one dest, value_exp }
else
-- If we only have single expression then
-- unpack the result into key and value
key_name, val_name = NameProxy"key", NameProxy"val"
dest = build.chain { base: accum, {"index", key_name} }
{
build.assign names: {key_name, val_name}, values: {key_exp}
build.assign_one dest, val_name
}
build.block_exp {
build.assign_one accum, build.table!
construct_comprehension inner, clauses
accum
}
fndef: (node) =>
smart_node node
node.body = transform_last_stm node.body, implicitly_return self
node.body = {
Run => @listen "varargs", -> -- capture event
unpack node.body
}
node
if: (node) =>
build.block_exp { node }
unless: (node) =>
build.block_exp { node }
with: (node) =>
build.block_exp { node }
switch: (node) =>
build.block_exp { node }
-- pull out colon chain
chain: (node) =>
-- escape lua keywords used in dot accessors
for i=2,#node
part = node[i]
if ntype(part) == "dot" and lua_keywords[part[2]]
node[i] = { "index", {"string", '"', part[2]} }
if ntype(node[2]) == "string"
-- add parens if callee is raw string
node[2] = {"parens", node[2] }
if chain_is_stub node
base_name = NameProxy "base"
fn_name = NameProxy "fn"
colon = table.remove node
is_super = ntype(node[2]) == "ref" and node[2][2] == "super"
build.block_exp {
build.assign {
names: {base_name}
values: {node}
}
build.assign {
names: {fn_name}
values: {
build.chain { base: base_name, {"dot", colon[2]} }
}
}
build.fndef {
args: {{"..."}}
body: {
build.chain {
base: fn_name, {"call", {is_super and "self" or base_name, "..."}}
}
}
}
}
block_exp: (node) =>
body = unpack node, 2
fn = nil
arg_list = {}
fn = smart_node build.fndef body: {
Run =>
@listen "varargs", ->
insert arg_list, "..."
insert fn.args, {"..."}
@unlisten "varargs"
unpack body
}
build.chain { base: {"parens", fn}, {"call", arg_list} }
}