Skip to content

Commit 39e806e

Browse files
CST: Handle AstStatWhile (#209)
Serializes the full AstStatWhile node, including all its tokens `while` / `do` / `end`. At the moment, the keys are still keywords. In a follow up we intend to clean up the overall AST structure for standardisation
1 parent 2d623e4 commit 39e806e

File tree

5 files changed

+39
-6
lines changed

5 files changed

+39
-6
lines changed

batteries/syntax/ast_types.luau

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,15 @@ export type AstStatIf = {
186186
["end"]: Token<"end">,
187187
}
188188

189+
export type AstStatWhile = {
190+
tag: "while",
191+
["while"]: Token<"while">,
192+
condition: AstExpr,
193+
["do"]: Token<"do">,
194+
body: AstStatBlock,
195+
["end"]: Token<"end">,
196+
}
197+
189198
export type AstStatReturn = {
190199
tag: "return",
191200
["return"]: Token<"return">,
@@ -205,6 +214,6 @@ export type AstStatLocal = {
205214
values: Punctuated<AstExpr>,
206215
}
207216

208-
export type AstStat = AstStatBlock | AstStatIf | AstStatReturn | AstStatExpr | AstStatLocal
217+
export type AstStat = AstStatBlock | AstStatIf | AstStatWhile | AstStatReturn | AstStatExpr | AstStatLocal
209218

210219
return {}

batteries/syntax/visitor.luau

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ local T = require("./ast_types")
55
type Visitor = {
66
visitBlock: (T.AstStatBlock) -> boolean,
77
visitIf: (T.AstStatIf) -> boolean,
8+
visitWhile: (T.AstStatWhile) -> boolean,
89
visitReturn: (T.AstStatReturn) -> boolean,
910
visitLocalDeclaration: (T.AstStatLocal) -> boolean,
1011

@@ -36,6 +37,7 @@ end
3637
local defaultVisitor: Visitor = {
3738
visitBlock = alwaysVisit :: any,
3839
visitIf = alwaysVisit :: any,
40+
visitWhile = alwaysVisit :: any,
3941
visitReturn = alwaysVisit :: any,
4042
visitLocalDeclaration = alwaysVisit :: any,
4143

@@ -108,6 +110,16 @@ local function visitIf(node: T.AstStatIf, visitor: Visitor)
108110
end
109111
end
110112

113+
local function visitWhile(node: T.AstStatWhile, visitor: Visitor)
114+
if visitor.visitWhile(node) then
115+
visitToken(node["while"], visitor)
116+
visitExpression(node.condition, visitor)
117+
visitToken(node["do"], visitor)
118+
visitBlock(node.body, visitor)
119+
visitToken(node["end"], visitor)
120+
end
121+
end
122+
111123
local function visitReturn(node: T.AstStatReturn, visitor: Visitor)
112124
if visitor.visitReturn(node) then
113125
visitToken(node["return"], visitor)
@@ -317,6 +329,8 @@ function visitStatement(statement: T.AstStat, visitor: Visitor)
317329
visitLocalStatement(statement, visitor)
318330
elseif statement.tag == "return" then
319331
visitReturn(statement, visitor)
332+
elseif statement.tag == "while" then
333+
visitWhile(statement, visitor)
320334
else
321335
exhaustiveMatch(statement.tag)
322336
end

luau/src/luau.cpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1037,17 +1037,23 @@ struct AstSerialize : public Luau::AstVisitor
10371037

10381038
serializeNodePreamble(node, "while");
10391039

1040+
serializeToken(node->location.begin, "while");
1041+
lua_setfield(L, -2, "while");
1042+
10401043
node->condition->visit(this);
10411044
lua_setfield(L, -2, "condition");
10421045

1043-
node->body->visit(this);
1044-
lua_setfield(L, -2, "body");
1045-
10461046
if (node->hasDo)
1047-
serialize(node->doLocation);
1047+
serializeToken(node->doLocation.begin, "do");
10481048
else
10491049
lua_pushnil(L);
1050-
lua_setfield(L, -2, "doLocation");
1050+
lua_setfield(L, -2, "do");
1051+
1052+
node->body->visit(this);
1053+
lua_setfield(L, -2, "body");
1054+
1055+
serializeToken(node->body->location.end, "end");
1056+
lua_setfield(L, -2, "end");
10511057
}
10521058

10531059
void serializeStat(Luau::AstStatRepeat* node)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
while condition do
2+
call()
3+
end

tests/testAstSerializer.spec.luau

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ local function test_roundtrippableAst()
129129
"examples/parsing.luau",
130130
"examples/time_example.luau",
131131
"examples/writeFile.luau",
132+
"tests/astSerializerTests/while-1.luau",
132133
}
133134

134135
for _, path in files do

0 commit comments

Comments
 (0)