Skip to content

Commit 97394fb

Browse files
committed
classes can be expressions, classes don't require name or body anymore
1 parent bcb4327 commit 97394fb

File tree

7 files changed

+288
-49
lines changed

7 files changed

+288
-49
lines changed

moonscript/parse.lua

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,7 @@ local build_grammar = wrap_env(function()
383383
Line = (CheckIndent * Statement + Space * #Stop),
384384

385385
Statement = pos(
386-
Import + While + With + For + ForEach + Switch + Return + ClassDecl +
386+
Import + While + With + For + ForEach + Switch + Return +
387387
Local + Export + BreakLoop +
388388
Ct(ExpList) * (Update + Assign)^-1 / format_assign
389389
) * Space * ((
@@ -467,6 +467,7 @@ local build_grammar = wrap_env(function()
467467
If + Unless +
468468
Switch +
469469
With +
470+
ClassDecl +
470471
ForEach + For + While +
471472
Cmt(Do, check_do) +
472473
sym"-" * -SomeSpace * Exp / mark"minus" +
@@ -552,10 +553,10 @@ local build_grammar = wrap_env(function()
552553
TableBlockInner = Ct(KeyValueLine * (SpaceBreak^1 * KeyValueLine)^0),
553554
TableBlock = SpaceBreak^1 * Advance * ensure(TableBlockInner, PopIndent) / mark"table",
554555

555-
ClassDecl = key"class" * Assignable * (key"extends" * PreventIndent * ensure(Exp, PopIndent) + C"")^-1 * ClassBlock / mark"class",
556+
ClassDecl = key"class" * (Assignable + Cc(nil)) * (key"extends" * PreventIndent * ensure(Exp, PopIndent) + C"")^-1 * (ClassBlock + Ct("")) / mark"class",
556557

557558
ClassBlock = SpaceBreak^1 * Advance *
558-
Ct(ClassLine * (SpaceBreak^1 * ClassLine)^0) * PopIndent,
559+
Ct(ClassLine * (SpaceBreak^1 * ClassLine)^0) * PopIndent,
559560
ClassLine = CheckIndent * ((
560561
KeyValueList / mark"props" +
561562
Statement / mark"stm" +

moonscript/transform.lua

Lines changed: 36 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -975,20 +975,23 @@ Statement = Transformer({
975975
constructor.arrow = "fat"
976976
end
977977
local real_name
978-
if ntype(name) == "chain" then
978+
local _exp_0 = ntype(name)
979+
if "chain" == _exp_0 then
979980
local last = name[#name]
980-
local _exp_0 = ntype(last)
981-
if "dot" == _exp_0 then
981+
local _exp_1 = ntype(last)
982+
if "dot" == _exp_1 then
982983
real_name = {
983984
"string",
984985
'"',
985986
last[2]
986987
}
987-
elseif "index" == _exp_0 then
988+
elseif "index" == _exp_1 then
988989
real_name = last[2]
989990
else
990991
real_name = "nil"
991992
end
993+
elseif "nil" == _exp_0 then
994+
real_name = "nil"
992995
else
993996
real_name = {
994997
"string",
@@ -1112,7 +1115,9 @@ Statement = Transformer({
11121115
local _with_0 = build
11131116
local out_body = {
11141117
Run(function(self)
1115-
self:put_name(name)
1118+
if name then
1119+
self:put_name(name)
1120+
end
11161121
return self:set("super", function(block, chain)
11171122
if chain then
11181123
local slice = (function()
@@ -1134,8 +1139,8 @@ Statement = Transformer({
11341139
if head == nil then
11351140
return parent_cls_name
11361141
end
1137-
local _exp_0 = head[1]
1138-
if "call" == _exp_0 then
1142+
local _exp_1 = head[1]
1143+
if "call" == _exp_1 then
11391144
local calling_name = block:get("current_block")
11401145
slice[1] = {
11411146
"call",
@@ -1155,7 +1160,7 @@ Statement = Transformer({
11551160
calling_name
11561161
})
11571162
end
1158-
elseif "colon" == _exp_0 then
1163+
elseif "colon" == _exp_1 then
11591164
local call = head[3]
11601165
insert(new_chain, {
11611166
"dot",
@@ -1186,7 +1191,7 @@ Statement = Transformer({
11861191
properties
11871192
}),
11881193
_with_0.assign_one(base_name:chain("__index"), base_name),
1189-
build["if"]({
1194+
_with_0["if"]({
11901195
cond = parent_cls_name,
11911196
["then"] = {
11921197
_with_0.chain({
@@ -1215,11 +1220,9 @@ Statement = Transformer({
12151220
_with_0.assign_one(LocalName("self"), cls_name),
12161221
_with_0.group(statements)
12171222
}
1218-
else
1219-
return { }
12201223
end
12211224
end)()),
1222-
build["if"]({
1225+
_with_0["if"]({
12231226
cond = {
12241227
"exp",
12251228
parent_cls_name,
@@ -1236,7 +1239,13 @@ Statement = Transformer({
12361239
})
12371240
}
12381241
}),
1239-
_with_0.assign_one(name, cls_name),
1242+
_with_0.group((function()
1243+
if name then
1244+
return {
1245+
_with_0.assign_one(name, cls_name)
1246+
}
1247+
end
1248+
end)()),
12401249
(function()
12411250
if ret then
12421251
return ret(cls_name)
@@ -1245,15 +1254,17 @@ Statement = Transformer({
12451254
}
12461255
hoist_declarations(out_body)
12471256
value = _with_0.group({
1248-
(function()
1257+
_with_0.group((function()
12491258
if ntype(name) == "value" then
1250-
return _with_0.declare({
1251-
names = {
1252-
name
1253-
}
1254-
})
1259+
return {
1260+
_with_0.declare({
1261+
names = {
1262+
name
1263+
}
1264+
})
1265+
}
12551266
end
1256-
end)(),
1267+
end)()),
12571268
_with_0["do"](out_body)
12581269
})
12591270
end
@@ -1415,6 +1426,11 @@ Value = Transformer({
14151426
decorated = function(self, node)
14161427
return self.transform.statement(node)
14171428
end,
1429+
class = function(self, node)
1430+
return build.block_exp({
1431+
node
1432+
})
1433+
end,
14181434
string = function(self, node)
14191435
local delim = node[2]
14201436
local convert_part

moonscript/transform.moon

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -505,17 +505,20 @@ Statement = Transformer {
505505
smart_node constructor
506506
constructor.arrow = "fat"
507507

508-
real_name = if ntype(name) == "chain"
509-
last = name[#name]
510-
switch ntype last
511-
when "dot"
512-
{"string", '"', last[2]}
513-
when "index"
514-
last[2]
515-
else
516-
"nil"
517-
else
518-
{"string", '"', name}
508+
real_name = switch ntype(name)
509+
when "chain"
510+
last = name[#name]
511+
switch ntype last
512+
when "dot"
513+
{"string", '"', last[2]}
514+
when "index"
515+
last[2]
516+
else
517+
"nil"
518+
when "nil"
519+
"nil"
520+
else
521+
{"string", '"', name}
519522

520523
cls = build.table {
521524
{"__init", constructor}
@@ -569,7 +572,7 @@ Statement = Transformer {
569572
out_body = {
570573
Run =>
571574
-- make sure we don't assign the class to a local inside the do
572-
@put_name name
575+
@put_name name if name
573576

574577
@set "super", (block, chain) ->
575578
if chain
@@ -608,7 +611,7 @@ Statement = Transformer {
608611
.assign_one base_name, {"table", properties}
609612
.assign_one base_name\chain"__index", base_name
610613

611-
build["if"] {
614+
.if {
612615
cond: parent_cls_name
613616
then: {
614617
.chain {
@@ -624,13 +627,13 @@ Statement = Transformer {
624627
.assign_one cls_name, cls
625628
.assign_one base_name\chain"__class", cls_name
626629

627-
.group if #statements > 0 {
630+
.group if #statements > 0 then {
628631
.assign_one LocalName"self", cls_name
629632
.group statements
630-
} else {}
633+
}
631634

632635
-- run the inherited callback
633-
build["if"] {
636+
.if {
634637
cond: {"exp",
635638
parent_cls_name, "and", parent_cls_name\chain "__inherited"
636639
}
@@ -641,16 +644,20 @@ Statement = Transformer {
641644
}
642645
}
643646

644-
.assign_one name, cls_name
647+
.group if name then {
648+
.assign_one name, cls_name
649+
}
650+
645651
if ret
646652
ret cls_name
647653
}
648654

649655
hoist_declarations out_body
650656

651657
value = .group {
652-
if ntype(name) == "value"
658+
.group if ntype(name) == "value" then {
653659
.declare names: {name}
660+
}
654661

655662
.do out_body
656663
}
@@ -755,6 +762,9 @@ Value = Transformer {
755762
decorated: (node) =>
756763
@transform.statement node
757764

765+
class: (node) =>
766+
build.block_exp { node }
767+
758768
string: (node) =>
759769
delim = node[2]
760770

moonscript/types.lua

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,13 @@ comprehension_has_value = function(comp)
2424
return is_value(comp[2])
2525
end
2626
ntype = function(node)
27-
if type(node) ~= "table" then
28-
return "value"
29-
else
27+
local _exp_0 = type(node)
28+
if "nil" == _exp_0 then
29+
return "nil"
30+
elseif "table" == _exp_0 then
3031
return node[1]
32+
else
33+
return "value"
3134
end
3235
end
3336
value_is_singular = function(node)
@@ -175,6 +178,9 @@ end
175178
build = nil
176179
build = setmetatable({
177180
group = function(body)
181+
if body == nil then
182+
body = { }
183+
end
178184
return {
179185
"group",
180186
body

moonscript/types.moon

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,13 @@ comprehension_has_value = (comp) ->
2525

2626
-- type of node as string
2727
ntype = (node) ->
28-
if type(node) != "table"
29-
"value"
30-
else
31-
node[1]
28+
switch type node
29+
when "nil"
30+
"nil"
31+
when "table"
32+
node[1]
33+
else
34+
"value"
3235

3336
value_is_singular = (node) ->
3437
type(node) != "table" or node[1] != "exp" or #node == 2
@@ -102,7 +105,7 @@ make_builder = (name) ->
102105

103106
build = nil
104107
build = setmetatable {
105-
group: (body) ->
108+
group: (body={}) ->
106109
{"group", body}
107110
do: (body) ->
108111
{"do", body}

tests/inputs/class.moon

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,14 @@ class a.b["hello"]
146146
class (-> require "moon")!.Something extends Hello.World
147147
nil
148148

149+
--
150+
151+
a = class
152+
b = class Something
153+
c = class Something extends Hello
154+
d = class extends World
149155

156+
print (class WhatsUp).__name
150157

151158
--
152159

0 commit comments

Comments
 (0)