Skip to content

Commit de8f9c5

Browse files
committed
compiler: assign and augmented assign
1 parent 54f3149 commit de8f9c5

File tree

3 files changed

+316
-6
lines changed

3 files changed

+316
-6
lines changed

compile/compile.go

+59-4
Original file line numberDiff line numberDiff line change
@@ -251,12 +251,57 @@ func (c *compiler) Stmt(stmt ast.Stmt) {
251251
case *ast.Assign:
252252
// Targets []Expr
253253
// Value Expr
254-
panic("FIXME compile: Assign not implemented")
254+
c.Expr(node.Value)
255+
for i, target := range node.Targets {
256+
if i != len(node.Targets)-1 {
257+
c.Op(vm.DUP_TOP)
258+
}
259+
c.Expr(target)
260+
}
255261
case *ast.AugAssign:
256262
// Target Expr
257263
// Op OperatorNumber
258264
// Value Expr
259-
panic("FIXME compile: AugAssign not implemented")
265+
setctx, ok := node.Target.(ast.SetCtxer)
266+
if !ok {
267+
panic("compile: can't set context in AugAssign")
268+
}
269+
// FIXME untidy modifying the ast temporarily!
270+
setctx.SetCtx(ast.Load)
271+
c.Expr(node.Target)
272+
c.Expr(node.Value)
273+
var op byte
274+
switch node.Op {
275+
case ast.Add:
276+
op = vm.INPLACE_ADD
277+
case ast.Sub:
278+
op = vm.INPLACE_SUBTRACT
279+
case ast.Mult:
280+
op = vm.INPLACE_MULTIPLY
281+
case ast.Div:
282+
op = vm.INPLACE_TRUE_DIVIDE
283+
case ast.Modulo:
284+
op = vm.INPLACE_MODULO
285+
case ast.Pow:
286+
op = vm.INPLACE_POWER
287+
case ast.LShift:
288+
op = vm.INPLACE_LSHIFT
289+
case ast.RShift:
290+
op = vm.INPLACE_RSHIFT
291+
case ast.BitOr:
292+
op = vm.INPLACE_OR
293+
case ast.BitXor:
294+
op = vm.INPLACE_XOR
295+
case ast.BitAnd:
296+
op = vm.INPLACE_AND
297+
case ast.FloorDiv:
298+
op = vm.INPLACE_FLOOR_DIVIDE
299+
default:
300+
panic("Unknown BinOp")
301+
}
302+
c.Op(op)
303+
setctx.SetCtx(ast.Store)
304+
c.Expr(node.Target)
260305
case *ast.For:
261306
// Target Expr
262307
// Iter Expr
@@ -569,8 +614,18 @@ func (c *compiler) Expr(expr ast.Expr) {
569614
case *ast.Name:
570615
// Id Identifier
571616
// Ctx ExprContext
572-
// FIXME do something with Ctx
573-
c.OpArg(vm.LOAD_NAME, c.Name(node.Id))
617+
switch node.Ctx {
618+
case ast.Load:
619+
c.OpArg(vm.LOAD_NAME, c.Name(node.Id))
620+
case ast.Store:
621+
c.OpArg(vm.STORE_NAME, c.Name(node.Id))
622+
// case ast.Del:
623+
// case ast.AugLoad:
624+
// case ast.AugStore:
625+
// case ast.Param:
626+
default:
627+
panic(fmt.Sprintf("FIXME ast.Name Ctx=%v not implemented", node.Ctx))
628+
}
574629
case *ast.List:
575630
// Elts []Expr
576631
// Ctx ExprContext

compile/compile_data_test.go

+239-1
Original file line numberDiff line numberDiff line change
@@ -1149,7 +1149,7 @@ var compileTestData = []struct {
11491149
Name: "<module>",
11501150
Firstlineno: 1,
11511151
Lnotab: "",
1152-
}, " 1 0 LOAD_CONST 0 (<code object <lambda> at 0x7fb0bc2ece40, file \"<string>\", line 1>)\n 3 LOAD_CONST 1 ('<lambda>')\n 6 MAKE_FUNCTION 0\n 9 RETURN_VALUE\n"},
1152+
}, " 1 0 LOAD_CONST 0 (<code object <lambda> at 0x7fa8931d3e40, file \"<string>\", line 1>)\n 3 LOAD_CONST 1 ('<lambda>')\n 6 MAKE_FUNCTION 0\n 9 RETURN_VALUE\n"},
11531153
{"pass", "exec", &py.Code{
11541154
Argcount: 0,
11551155
Kwonlyargcount: 0,
@@ -1252,4 +1252,242 @@ var compileTestData = []struct {
12521252
Firstlineno: 1,
12531253
Lnotab: "",
12541254
}, " 1 0 LOAD_CONST 0 (1)\n 3 POP_JUMP_IF_TRUE 12\n 6 LOAD_GLOBAL 0 (AssertionError)\n 9 RAISE_VARARGS 1\n >> 12 LOAD_CONST 1 (None)\n 15 RETURN_VALUE\n"},
1255+
{"a = 1", "exec", &py.Code{
1256+
Argcount: 0,
1257+
Kwonlyargcount: 0,
1258+
Nlocals: 0,
1259+
Stacksize: 1,
1260+
Flags: 64,
1261+
Code: "\x64\x00\x00\x5a\x00\x00\x64\x01\x00\x53",
1262+
Consts: []py.Object{py.Int(1), py.None},
1263+
Names: []string{"a"},
1264+
Varnames: []string{},
1265+
Freevars: []string{},
1266+
Cellvars: []string{},
1267+
Filename: "<string>",
1268+
Name: "<module>",
1269+
Firstlineno: 1,
1270+
Lnotab: "",
1271+
}, " 1 0 LOAD_CONST 0 (1)\n 3 STORE_NAME 0 (a)\n 6 LOAD_CONST 1 (None)\n 9 RETURN_VALUE\n"},
1272+
{"a = b = c = 1", "exec", &py.Code{
1273+
Argcount: 0,
1274+
Kwonlyargcount: 0,
1275+
Nlocals: 0,
1276+
Stacksize: 2,
1277+
Flags: 64,
1278+
Code: "\x64\x00\x00\x04\x5a\x00\x00\x04\x5a\x01\x00\x5a\x02\x00\x64\x01\x00\x53",
1279+
Consts: []py.Object{py.Int(1), py.None},
1280+
Names: []string{"a", "b", "c"},
1281+
Varnames: []string{},
1282+
Freevars: []string{},
1283+
Cellvars: []string{},
1284+
Filename: "<string>",
1285+
Name: "<module>",
1286+
Firstlineno: 1,
1287+
Lnotab: "",
1288+
}, " 1 0 LOAD_CONST 0 (1)\n 3 DUP_TOP\n 4 STORE_NAME 0 (a)\n 7 DUP_TOP\n 8 STORE_NAME 1 (b)\n 11 STORE_NAME 2 (c)\n 14 LOAD_CONST 1 (None)\n 17 RETURN_VALUE\n"},
1289+
{"a+=1", "exec", &py.Code{
1290+
Argcount: 0,
1291+
Kwonlyargcount: 0,
1292+
Nlocals: 0,
1293+
Stacksize: 2,
1294+
Flags: 64,
1295+
Code: "\x65\x00\x00\x64\x00\x00\x37\x5a\x00\x00\x64\x01\x00\x53",
1296+
Consts: []py.Object{py.Int(1), py.None},
1297+
Names: []string{"a"},
1298+
Varnames: []string{},
1299+
Freevars: []string{},
1300+
Cellvars: []string{},
1301+
Filename: "<string>",
1302+
Name: "<module>",
1303+
Firstlineno: 1,
1304+
Lnotab: "",
1305+
}, " 1 0 LOAD_NAME 0 (a)\n 3 LOAD_CONST 0 (1)\n 6 INPLACE_ADD\n 7 STORE_NAME 0 (a)\n 10 LOAD_CONST 1 (None)\n 13 RETURN_VALUE\n"},
1306+
{"a-=1", "exec", &py.Code{
1307+
Argcount: 0,
1308+
Kwonlyargcount: 0,
1309+
Nlocals: 0,
1310+
Stacksize: 2,
1311+
Flags: 64,
1312+
Code: "\x65\x00\x00\x64\x00\x00\x38\x5a\x00\x00\x64\x01\x00\x53",
1313+
Consts: []py.Object{py.Int(1), py.None},
1314+
Names: []string{"a"},
1315+
Varnames: []string{},
1316+
Freevars: []string{},
1317+
Cellvars: []string{},
1318+
Filename: "<string>",
1319+
Name: "<module>",
1320+
Firstlineno: 1,
1321+
Lnotab: "",
1322+
}, " 1 0 LOAD_NAME 0 (a)\n 3 LOAD_CONST 0 (1)\n 6 INPLACE_SUBTRACT\n 7 STORE_NAME 0 (a)\n 10 LOAD_CONST 1 (None)\n 13 RETURN_VALUE\n"},
1323+
{"a*=b", "exec", &py.Code{
1324+
Argcount: 0,
1325+
Kwonlyargcount: 0,
1326+
Nlocals: 0,
1327+
Stacksize: 2,
1328+
Flags: 64,
1329+
Code: "\x65\x00\x00\x65\x01\x00\x39\x5a\x00\x00\x64\x00\x00\x53",
1330+
Consts: []py.Object{py.None},
1331+
Names: []string{"a", "b"},
1332+
Varnames: []string{},
1333+
Freevars: []string{},
1334+
Cellvars: []string{},
1335+
Filename: "<string>",
1336+
Name: "<module>",
1337+
Firstlineno: 1,
1338+
Lnotab: "",
1339+
}, " 1 0 LOAD_NAME 0 (a)\n 3 LOAD_NAME 1 (b)\n 6 INPLACE_MULTIPLY\n 7 STORE_NAME 0 (a)\n 10 LOAD_CONST 0 (None)\n 13 RETURN_VALUE\n"},
1340+
{"a/=1", "exec", &py.Code{
1341+
Argcount: 0,
1342+
Kwonlyargcount: 0,
1343+
Nlocals: 0,
1344+
Stacksize: 2,
1345+
Flags: 64,
1346+
Code: "\x65\x00\x00\x64\x00\x00\x1d\x5a\x00\x00\x64\x01\x00\x53",
1347+
Consts: []py.Object{py.Int(1), py.None},
1348+
Names: []string{"a"},
1349+
Varnames: []string{},
1350+
Freevars: []string{},
1351+
Cellvars: []string{},
1352+
Filename: "<string>",
1353+
Name: "<module>",
1354+
Firstlineno: 1,
1355+
Lnotab: "",
1356+
}, " 1 0 LOAD_NAME 0 (a)\n 3 LOAD_CONST 0 (1)\n 6 INPLACE_TRUE_DIVIDE\n 7 STORE_NAME 0 (a)\n 10 LOAD_CONST 1 (None)\n 13 RETURN_VALUE\n"},
1357+
{"a%=1", "exec", &py.Code{
1358+
Argcount: 0,
1359+
Kwonlyargcount: 0,
1360+
Nlocals: 0,
1361+
Stacksize: 2,
1362+
Flags: 64,
1363+
Code: "\x65\x00\x00\x64\x00\x00\x3b\x5a\x00\x00\x64\x01\x00\x53",
1364+
Consts: []py.Object{py.Int(1), py.None},
1365+
Names: []string{"a"},
1366+
Varnames: []string{},
1367+
Freevars: []string{},
1368+
Cellvars: []string{},
1369+
Filename: "<string>",
1370+
Name: "<module>",
1371+
Firstlineno: 1,
1372+
Lnotab: "",
1373+
}, " 1 0 LOAD_NAME 0 (a)\n 3 LOAD_CONST 0 (1)\n 6 INPLACE_MODULO\n 7 STORE_NAME 0 (a)\n 10 LOAD_CONST 1 (None)\n 13 RETURN_VALUE\n"},
1374+
{"a**=1", "exec", &py.Code{
1375+
Argcount: 0,
1376+
Kwonlyargcount: 0,
1377+
Nlocals: 0,
1378+
Stacksize: 2,
1379+
Flags: 64,
1380+
Code: "\x65\x00\x00\x64\x00\x00\x43\x5a\x00\x00\x64\x01\x00\x53",
1381+
Consts: []py.Object{py.Int(1), py.None},
1382+
Names: []string{"a"},
1383+
Varnames: []string{},
1384+
Freevars: []string{},
1385+
Cellvars: []string{},
1386+
Filename: "<string>",
1387+
Name: "<module>",
1388+
Firstlineno: 1,
1389+
Lnotab: "",
1390+
}, " 1 0 LOAD_NAME 0 (a)\n 3 LOAD_CONST 0 (1)\n 6 INPLACE_POWER\n 7 STORE_NAME 0 (a)\n 10 LOAD_CONST 1 (None)\n 13 RETURN_VALUE\n"},
1391+
{"a<<=1", "exec", &py.Code{
1392+
Argcount: 0,
1393+
Kwonlyargcount: 0,
1394+
Nlocals: 0,
1395+
Stacksize: 2,
1396+
Flags: 64,
1397+
Code: "\x65\x00\x00\x64\x00\x00\x4b\x5a\x00\x00\x64\x01\x00\x53",
1398+
Consts: []py.Object{py.Int(1), py.None},
1399+
Names: []string{"a"},
1400+
Varnames: []string{},
1401+
Freevars: []string{},
1402+
Cellvars: []string{},
1403+
Filename: "<string>",
1404+
Name: "<module>",
1405+
Firstlineno: 1,
1406+
Lnotab: "",
1407+
}, " 1 0 LOAD_NAME 0 (a)\n 3 LOAD_CONST 0 (1)\n 6 INPLACE_LSHIFT\n 7 STORE_NAME 0 (a)\n 10 LOAD_CONST 1 (None)\n 13 RETURN_VALUE\n"},
1408+
{"a>>=1", "exec", &py.Code{
1409+
Argcount: 0,
1410+
Kwonlyargcount: 0,
1411+
Nlocals: 0,
1412+
Stacksize: 2,
1413+
Flags: 64,
1414+
Code: "\x65\x00\x00\x64\x00\x00\x4c\x5a\x00\x00\x64\x01\x00\x53",
1415+
Consts: []py.Object{py.Int(1), py.None},
1416+
Names: []string{"a"},
1417+
Varnames: []string{},
1418+
Freevars: []string{},
1419+
Cellvars: []string{},
1420+
Filename: "<string>",
1421+
Name: "<module>",
1422+
Firstlineno: 1,
1423+
Lnotab: "",
1424+
}, " 1 0 LOAD_NAME 0 (a)\n 3 LOAD_CONST 0 (1)\n 6 INPLACE_RSHIFT\n 7 STORE_NAME 0 (a)\n 10 LOAD_CONST 1 (None)\n 13 RETURN_VALUE\n"},
1425+
{"a|=1", "exec", &py.Code{
1426+
Argcount: 0,
1427+
Kwonlyargcount: 0,
1428+
Nlocals: 0,
1429+
Stacksize: 2,
1430+
Flags: 64,
1431+
Code: "\x65\x00\x00\x64\x00\x00\x4f\x5a\x00\x00\x64\x01\x00\x53",
1432+
Consts: []py.Object{py.Int(1), py.None},
1433+
Names: []string{"a"},
1434+
Varnames: []string{},
1435+
Freevars: []string{},
1436+
Cellvars: []string{},
1437+
Filename: "<string>",
1438+
Name: "<module>",
1439+
Firstlineno: 1,
1440+
Lnotab: "",
1441+
}, " 1 0 LOAD_NAME 0 (a)\n 3 LOAD_CONST 0 (1)\n 6 INPLACE_OR\n 7 STORE_NAME 0 (a)\n 10 LOAD_CONST 1 (None)\n 13 RETURN_VALUE\n"},
1442+
{"a^=1", "exec", &py.Code{
1443+
Argcount: 0,
1444+
Kwonlyargcount: 0,
1445+
Nlocals: 0,
1446+
Stacksize: 2,
1447+
Flags: 64,
1448+
Code: "\x65\x00\x00\x64\x00\x00\x4e\x5a\x00\x00\x64\x01\x00\x53",
1449+
Consts: []py.Object{py.Int(1), py.None},
1450+
Names: []string{"a"},
1451+
Varnames: []string{},
1452+
Freevars: []string{},
1453+
Cellvars: []string{},
1454+
Filename: "<string>",
1455+
Name: "<module>",
1456+
Firstlineno: 1,
1457+
Lnotab: "",
1458+
}, " 1 0 LOAD_NAME 0 (a)\n 3 LOAD_CONST 0 (1)\n 6 INPLACE_XOR\n 7 STORE_NAME 0 (a)\n 10 LOAD_CONST 1 (None)\n 13 RETURN_VALUE\n"},
1459+
{"a&=1", "exec", &py.Code{
1460+
Argcount: 0,
1461+
Kwonlyargcount: 0,
1462+
Nlocals: 0,
1463+
Stacksize: 2,
1464+
Flags: 64,
1465+
Code: "\x65\x00\x00\x64\x00\x00\x4d\x5a\x00\x00\x64\x01\x00\x53",
1466+
Consts: []py.Object{py.Int(1), py.None},
1467+
Names: []string{"a"},
1468+
Varnames: []string{},
1469+
Freevars: []string{},
1470+
Cellvars: []string{},
1471+
Filename: "<string>",
1472+
Name: "<module>",
1473+
Firstlineno: 1,
1474+
Lnotab: "",
1475+
}, " 1 0 LOAD_NAME 0 (a)\n 3 LOAD_CONST 0 (1)\n 6 INPLACE_AND\n 7 STORE_NAME 0 (a)\n 10 LOAD_CONST 1 (None)\n 13 RETURN_VALUE\n"},
1476+
{"a//=1", "exec", &py.Code{
1477+
Argcount: 0,
1478+
Kwonlyargcount: 0,
1479+
Nlocals: 0,
1480+
Stacksize: 2,
1481+
Flags: 64,
1482+
Code: "\x65\x00\x00\x64\x00\x00\x1c\x5a\x00\x00\x64\x01\x00\x53",
1483+
Consts: []py.Object{py.Int(1), py.None},
1484+
Names: []string{"a"},
1485+
Varnames: []string{},
1486+
Freevars: []string{},
1487+
Cellvars: []string{},
1488+
Filename: "<string>",
1489+
Name: "<module>",
1490+
Firstlineno: 1,
1491+
Lnotab: "",
1492+
}, " 1 0 LOAD_NAME 0 (a)\n 3 LOAD_CONST 0 (1)\n 6 INPLACE_FLOOR_DIVIDE\n 7 STORE_NAME 0 (a)\n 10 LOAD_CONST 1 (None)\n 13 RETURN_VALUE\n"},
12551493
}

compile/make_compile_test.py

+18-1
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,24 @@
104104
('''assert 1, 2''', "exec"),
105105
('''assert a''', "exec"),
106106
('''assert 1''', "exec"),
107-
107+
# assign
108+
('''a = 1''', "exec"),
109+
('''a = b = c = 1''', "exec"),
110+
# FIXME ('''a[1] = 1''', "exec"),
111+
# aug assign
112+
('''a+=1''', "exec"),
113+
('''a-=1''', "exec"),
114+
('''a*=b''', "exec"),
115+
('''a/=1''', "exec"),
116+
('''a%=1''', "exec"),
117+
('''a**=1''', "exec"),
118+
('''a<<=1''', "exec"),
119+
('''a>>=1''', "exec"),
120+
('''a|=1''', "exec"),
121+
('''a^=1''', "exec"),
122+
('''a&=1''', "exec"),
123+
('''a//=1''', "exec"),
124+
# FIXME ('''a[1]+=1''', "exec"),
108125
]
109126

110127
def string(s):

0 commit comments

Comments
 (0)