Skip to content

Commit 53cbd85

Browse files
committed
Handle assignment and compound assignment
1 parent 7e88715 commit 53cbd85

File tree

6 files changed

+90
-7
lines changed

6 files changed

+90
-7
lines changed

batteries/syntax/ast_types.luau

+18-1
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ export type AstStatLocal = {
229229
export type AstStatFor = {
230230
tag: "for",
231231
["for"]: Token<"for">,
232-
variable: Token<string>,
232+
variable: AstLocal,
233233
equals: Token<"=">,
234234
from: AstExpr,
235235
toComma: Token<",">,
@@ -251,6 +251,21 @@ export type AstStatForIn = {
251251
body: AstStatBlock,
252252
["end"]: Token<"end">,
253253
}
254+
255+
export type AstStatAssign = {
256+
tag: "assign",
257+
variables: Punctuated<AstExpr>,
258+
equals: Token<"=">,
259+
values: Punctuated<AstExpr>,
260+
}
261+
262+
export type AstStatCompoundAssign = {
263+
tag: "compoundassign",
264+
variable: AstExpr,
265+
operand: Token, -- TODO: enforce token type,
266+
value: AstExpr,
267+
}
268+
254269
export type AstStat =
255270
| AstStatBlock
256271
| AstStatIf
@@ -263,5 +278,7 @@ export type AstStat =
263278
| AstStatLocal
264279
| AstStatFor
265280
| AstStatForIn
281+
| AstStatAssign
282+
| AstStatCompoundAssign
266283

267284
return {}

batteries/syntax/visitor.luau

+24
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ type Visitor = {
1111
visitLocalDeclaration: (T.AstStatLocal) -> boolean,
1212
visitFor: (T.AstStatFor) -> boolean,
1313
visitForIn: (T.AstStatForIn) -> boolean,
14+
visitAssign: (T.AstStatAssign) -> boolean,
15+
visitCompoundAssign: (T.AstStatCompoundAssign) -> boolean,
1416

1517
visitLocalReference: (T.AstExprLocal) -> boolean,
1618
visitGlobal: (T.AstExprGlobal) -> boolean,
@@ -46,6 +48,8 @@ local defaultVisitor: Visitor = {
4648
visitLocalDeclaration = alwaysVisit :: any,
4749
visitFor = alwaysVisit :: any,
4850
visitForIn = alwaysVisit :: any,
51+
visitAssign = alwaysVisit :: any,
52+
visitCompoundAssign = alwaysVisit :: any,
4953

5054
visitLocalReference = alwaysVisit :: any,
5155
visitGlobal = alwaysVisit :: any,
@@ -185,6 +189,22 @@ local function visitForIn(node: T.AstStatForIn, visitor: Visitor)
185189
end
186190
end
187191

192+
local function visitAssign(node: T.AstStatAssign, visitor: Visitor)
193+
if visitor.visitAssign(node) then
194+
visitPunctuated(node.variables, visitor, visitExpression)
195+
visitToken(node.equals, visitor)
196+
visitPunctuated(node.values, visitor, visitExpression)
197+
end
198+
end
199+
200+
local function visitCompoundAssign(node: T.AstStatCompoundAssign, visitor: Visitor)
201+
if visitor.visitCompoundAssign(node) then
202+
visitExpression(node.variable, visitor)
203+
visitToken(node.operand, visitor)
204+
visitExpression(node.value, visitor)
205+
end
206+
end
207+
188208
local function visitString(node: T.AstExprConstantString, visitor: Visitor)
189209
if visitor.visitString(node) then
190210
visitor.visitToken(node)
@@ -388,6 +408,10 @@ function visitStatement(statement: T.AstStat, visitor: Visitor)
388408
visitFor(statement, visitor)
389409
elseif statement.tag == "forin" then
390410
visitForIn(statement, visitor)
411+
elseif statement.tag == "assign" then
412+
visitAssign(statement, visitor)
413+
elseif statement.tag == "compoundassign" then
414+
visitCompoundAssign(statement, visitor)
391415
else
392416
exhaustiveMatch(statement.tag)
393417
end

luau/src/luau.cpp

+17-6
Original file line numberDiff line numberDiff line change
@@ -1241,14 +1241,22 @@ struct AstSerialize : public Luau::AstVisitor
12411241
void serializeStat(Luau::AstStatAssign* node)
12421242
{
12431243
lua_rawcheckstack(L, 2);
1244-
lua_createtable(L, 0, preambleSize + 2);
1244+
lua_createtable(L, 0, preambleSize + 3);
1245+
1246+
const auto cstNode = lookupCstNode<Luau::CstStatAssign>(node);
12451247

12461248
serializeNodePreamble(node, "assign");
12471249

1248-
serializeExprs(node->vars);
1250+
serializePunctuated(node->vars, cstNode ? cstNode->varsCommaPositions : Luau::AstArray<Luau::Position>{}, ",");
12491251
lua_setfield(L, -2, "variables");
12501252

1251-
serializeExprs(node->values);
1253+
if (cstNode)
1254+
{
1255+
serializeToken(cstNode->equalsPosition, "=");
1256+
lua_setfield(L, -2, "equals");
1257+
}
1258+
1259+
serializePunctuated(node->values, cstNode ? cstNode->valuesCommaPositions : Luau::AstArray<Luau::Position>{}, ",");
12521260
lua_setfield(L, -2, "values");
12531261
}
12541262

@@ -1259,12 +1267,15 @@ struct AstSerialize : public Luau::AstVisitor
12591267

12601268
serializeNodePreamble(node, "compoundassign");
12611269

1262-
serialize(node->op);
1263-
lua_setfield(L, -2, "operand");
1264-
12651270
node->var->visit(this);
12661271
lua_setfield(L, -2, "variable");
12671272

1273+
if (const auto cstNode = lookupCstNode<Luau::CstStatCompoundAssign>(node))
1274+
serializeToken(cstNode->opPosition, (Luau::toString(node->op) + "=").data());
1275+
else
1276+
serialize(node->op);
1277+
lua_setfield(L, -2, "operand");
1278+
12681279
node->value->visit(this);
12691280
lua_setfield(L, -2, "value");
12701281
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
x = 1
2+
3+
a, b = 1, true
4+
5+
a, b, c.d.e[f][g][1], h:i().j[k]:l()[m] = true, false, 1, 4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
local x = 1
2+
local y = 2
3+
4+
x += 5
5+
x -= 5
6+
x *= 5
7+
x /= 5
8+
x //= 5
9+
x %= 5
10+
x ^= 5
11+
12+
x += y
13+
x -= y
14+
x *= y
15+
x /= y
16+
x //= y
17+
x %= y
18+
x ^= y
19+
20+
local str1 = "Hello, "
21+
local str2 = "world!"
22+
23+
str1 ..= "world!"
24+
str1 ..= str2

tests/testAstSerializer.spec.luau

+2
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/assignment-1.luau",
132133
"tests/astSerializerTests/break-continue-1.luau",
134+
"tests/astSerializerTests/compound-assignment-1.luau",
133135
"tests/astSerializerTests/generic-for-loop-1.luau",
134136
"tests/astSerializerTests/numeric-for-loop-1.luau",
135137
"tests/astSerializerTests/while-1.luau",

0 commit comments

Comments
 (0)