Skip to content

Commit 3510109

Browse files
CST: Handle repeat, break and continue (#210)
This PR adds support for serializing all the the repeat stmt node, as well as `break` and `continue` last stmt For break and continue, it is fairly simple - we serialize the tokens directly. For repeat, we serialize the `repeat` and `until` tokens using the CST data, alongside the condition and body.
1 parent 39e806e commit 3510109

File tree

6 files changed

+64
-7
lines changed

6 files changed

+64
-7
lines changed

batteries/syntax/ast_types.luau

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,18 @@ export type AstStatWhile = {
195195
["end"]: Token<"end">,
196196
}
197197

198+
export type AstStatRepeat = {
199+
tag: "repeat",
200+
["repeat"]: Token<"repeat">,
201+
body: AstStatBlock,
202+
["until"]: Token<"until">,
203+
condition: AstExpr,
204+
}
205+
206+
export type AstStatBreak = Token<"break"> & { tag: "break" }
207+
208+
export type AstStatContinue = Token<"continue"> & { tag: "continue" }
209+
198210
export type AstStatReturn = {
199211
tag: "return",
200212
["return"]: Token<"return">,
@@ -214,6 +226,15 @@ export type AstStatLocal = {
214226
values: Punctuated<AstExpr>,
215227
}
216228

217-
export type AstStat = AstStatBlock | AstStatIf | AstStatWhile | AstStatReturn | AstStatExpr | AstStatLocal
229+
export type AstStat =
230+
| AstStatBlock
231+
| AstStatIf
232+
| AstStatWhile
233+
| AstStatRepeat
234+
| AstStatBreak
235+
| AstStatContinue
236+
| AstStatReturn
237+
| AstStatExpr
238+
| AstStatLocal
218239

219240
return {}

batteries/syntax/visitor.luau

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ type Visitor = {
66
visitBlock: (T.AstStatBlock) -> boolean,
77
visitIf: (T.AstStatIf) -> boolean,
88
visitWhile: (T.AstStatWhile) -> boolean,
9+
visitRepeat: (T.AstStatRepeat) -> boolean,
910
visitReturn: (T.AstStatReturn) -> boolean,
1011
visitLocalDeclaration: (T.AstStatLocal) -> boolean,
1112

@@ -38,6 +39,7 @@ local defaultVisitor: Visitor = {
3839
visitBlock = alwaysVisit :: any,
3940
visitIf = alwaysVisit :: any,
4041
visitWhile = alwaysVisit :: any,
42+
visitRepeat = alwaysVisit :: any,
4143
visitReturn = alwaysVisit :: any,
4244
visitLocalDeclaration = alwaysVisit :: any,
4345

@@ -120,6 +122,15 @@ local function visitWhile(node: T.AstStatWhile, visitor: Visitor)
120122
end
121123
end
122124

125+
local function visitRepeat(node: T.AstStatRepeat, visitor: Visitor)
126+
if visitor.visitRepeat(node) then
127+
visitToken(node["repeat"], visitor)
128+
visitBlock(node.body, visitor)
129+
visitToken(node["until"], visitor)
130+
visitExpression(node.condition, visitor)
131+
end
132+
end
133+
123134
local function visitReturn(node: T.AstStatReturn, visitor: Visitor)
124135
if visitor.visitReturn(node) then
125136
visitToken(node["return"], visitor)
@@ -331,6 +342,12 @@ function visitStatement(statement: T.AstStat, visitor: Visitor)
331342
visitReturn(statement, visitor)
332343
elseif statement.tag == "while" then
333344
visitWhile(statement, visitor)
345+
elseif statement.tag == "break" then
346+
visitToken(statement, visitor)
347+
elseif statement.tag == "continue" then
348+
visitToken(statement, visitor)
349+
elseif statement.tag == "repeat" then
350+
visitRepeat(statement, visitor)
334351
else
335352
exhaustiveMatch(statement.tag)
336353
end

luau/src/luau.cpp

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1063,26 +1063,33 @@ struct AstSerialize : public Luau::AstVisitor
10631063

10641064
serializeNodePreamble(node, "repeat");
10651065

1066-
node->condition->visit(this);
1067-
lua_setfield(L, -2, "condition");
1066+
serializeToken(node->location.begin, "repeat");
1067+
lua_setfield(L, -2, "repeat");
10681068

10691069
node->body->visit(this);
10701070
lua_setfield(L, -2, "body");
1071+
1072+
if (const auto cstNode = lookupCstNode<Luau::CstStatRepeat>(node))
1073+
{
1074+
serializeToken(cstNode->untilPosition, "until");
1075+
lua_setfield(L, -2, "until");
1076+
}
1077+
1078+
node->condition->visit(this);
1079+
lua_setfield(L, -2, "condition");
10711080
}
10721081

10731082
void serializeStat(Luau::AstStatBreak* node)
10741083
{
10751084
lua_rawcheckstack(L, 2);
1076-
lua_createtable(L, 0, preambleSize);
1077-
1085+
serializeToken(node->location.begin, "break", preambleSize);
10781086
serializeNodePreamble(node, "break");
10791087
}
10801088

10811089
void serializeStat(Luau::AstStatContinue* node)
10821090
{
10831091
lua_rawcheckstack(L, 2);
1084-
lua_createtable(L, 0, preambleSize);
1085-
1092+
serializeToken(node->location.begin, "continue", preambleSize);
10861093
serializeNodePreamble(node, "continue");
10871094
}
10881095

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
while true do
2+
break
3+
end
4+
5+
while true do
6+
continue
7+
end
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
repeat
2+
call()
3+
until condition

tests/testAstSerializer.spec.luau

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,9 @@ local function test_roundtrippableAst()
129129
"examples/parsing.luau",
130130
"examples/time_example.luau",
131131
"examples/writeFile.luau",
132+
"tests/astSerializerTests/break-continue-1.luau",
132133
"tests/astSerializerTests/while-1.luau",
134+
"tests/astSerializerTests/repeat-until-1.luau",
133135
}
134136

135137
for _, path in files do

0 commit comments

Comments
 (0)