@@ -960,7 +960,7 @@ func (c *compiler) Stmt(stmt ast.Stmt) {
960
960
panic ("compile: can't set context in AugAssign" )
961
961
}
962
962
// FIXME untidy modifying the ast temporarily!
963
- setctx .SetCtx (ast .Load )
963
+ setctx .SetCtx (ast .AugLoad )
964
964
c .Expr (node .Target )
965
965
c .Expr (node .Value )
966
966
var op byte
@@ -993,7 +993,7 @@ func (c *compiler) Stmt(stmt ast.Stmt) {
993
993
panic ("Unknown BinOp" )
994
994
}
995
995
c .Op (op )
996
- setctx .SetCtx (ast .Store )
996
+ setctx .SetCtx (ast .AugStore )
997
997
c .Expr (node .Target )
998
998
case * ast.For :
999
999
// Target Expr
@@ -1118,7 +1118,7 @@ func (c *compiler) Stmt(stmt ast.Stmt) {
1118
1118
panic (py .ExceptionNewf (py .SyntaxError , "'continue' not properly in loop" ))
1119
1119
}
1120
1120
if l .IsForLoop {
1121
- // FIXME when do we use CONTINUE_LOOP?
1121
+ // FIXME when do we use CONTINUE_LOOP? - need to port the code from compile.c
1122
1122
c .Jump (vm .JUMP_ABSOLUTE , l .Start )
1123
1123
//c.Jump(vm.CONTINUE_LOOP, l.Start)
1124
1124
} else {
@@ -1183,16 +1183,14 @@ func (c *compiler) NameOp(name string, ctx ast.ExprContext) {
1183
1183
switch optype {
1184
1184
case OP_DEREF :
1185
1185
switch ctx {
1186
- case ast .Load :
1186
+ case ast .Load , ast . AugLoad :
1187
1187
if c .SymTable .Type == symtable .ClassBlock {
1188
1188
op = vm .LOAD_CLASSDEREF
1189
1189
} else {
1190
1190
op = vm .LOAD_DEREF
1191
1191
}
1192
- case ast .Store :
1192
+ case ast .Store , ast . AugStore :
1193
1193
op = vm .STORE_DEREF
1194
- case ast .AugLoad :
1195
- case ast .AugStore :
1196
1194
case ast .Del :
1197
1195
op = vm .DELETE_DEREF
1198
1196
case ast .Param :
@@ -1202,14 +1200,12 @@ func (c *compiler) NameOp(name string, ctx ast.ExprContext) {
1202
1200
}
1203
1201
case OP_FAST :
1204
1202
switch ctx {
1205
- case ast .Load :
1203
+ case ast .Load , ast . AugLoad :
1206
1204
op = vm .LOAD_FAST
1207
- case ast .Store :
1205
+ case ast .Store , ast . AugStore :
1208
1206
op = vm .STORE_FAST
1209
1207
case ast .Del :
1210
1208
op = vm .DELETE_FAST
1211
- case ast .AugLoad :
1212
- case ast .AugStore :
1213
1209
case ast .Param :
1214
1210
panic ("NameOp: param invalid for local variable" )
1215
1211
default :
@@ -1218,29 +1214,25 @@ func (c *compiler) NameOp(name string, ctx ast.ExprContext) {
1218
1214
dict = & c .Code .Varnames
1219
1215
case OP_GLOBAL :
1220
1216
switch ctx {
1221
- case ast .Load :
1217
+ case ast .Load , ast . AugLoad :
1222
1218
op = vm .LOAD_GLOBAL
1223
- case ast .Store :
1219
+ case ast .Store , ast . AugStore :
1224
1220
op = vm .STORE_GLOBAL
1225
1221
case ast .Del :
1226
1222
op = vm .DELETE_GLOBAL
1227
- case ast .AugLoad :
1228
- case ast .AugStore :
1229
1223
case ast .Param :
1230
1224
panic ("NameOp: param invalid for global variable" )
1231
1225
default :
1232
1226
panic ("NameOp: ctx invalid for global variable" )
1233
1227
}
1234
1228
case OP_NAME :
1235
1229
switch ctx {
1236
- case ast .Load :
1230
+ case ast .Load , ast . AugLoad :
1237
1231
op = vm .LOAD_NAME
1238
- case ast .Store :
1232
+ case ast .Store , ast . AugStore :
1239
1233
op = vm .STORE_NAME
1240
1234
case ast .Del :
1241
1235
op = vm .DELETE_NAME
1242
- case ast .AugLoad :
1243
- case ast .AugStore :
1244
1236
case ast .Param :
1245
1237
panic ("NameOp: param invalid for name variable" )
1246
1238
default :
@@ -1403,6 +1395,92 @@ func (c *compiler) tupleOrList(op byte, ctx ast.ExprContext, elts []ast.Expr) {
1403
1395
}
1404
1396
}
1405
1397
1398
+ // compile a subscript
1399
+ func (c * compiler ) subscript (kind string , ctx ast.ExprContext ) {
1400
+ switch ctx {
1401
+ case ast .AugLoad :
1402
+ c .Op (vm .DUP_TOP_TWO )
1403
+ c .Op (vm .BINARY_SUBSCR )
1404
+ case ast .Load :
1405
+ c .Op (vm .BINARY_SUBSCR )
1406
+ case ast .AugStore :
1407
+ c .Op (vm .ROT_THREE )
1408
+ c .Op (vm .STORE_SUBSCR )
1409
+ case ast .Store :
1410
+ c .Op (vm .STORE_SUBSCR )
1411
+ case ast .Del :
1412
+ c .Op (vm .DELETE_SUBSCR )
1413
+ case ast .Param :
1414
+ panic (fmt .Sprintf ("invalid %v kind %v in subscript" , kind , ctx ))
1415
+ }
1416
+ }
1417
+
1418
+ // build the slice
1419
+ func (c * compiler ) buildSlice (slice * ast.Slice , ctx ast.ExprContext ) {
1420
+ n := uint32 (2 )
1421
+
1422
+ /* only handles the cases where BUILD_SLICE is emitted */
1423
+ if slice .Lower != nil {
1424
+ c .Expr (slice .Lower )
1425
+ } else {
1426
+ c .LoadConst (py .None )
1427
+ }
1428
+
1429
+ if slice .Upper != nil {
1430
+ c .Expr (slice .Upper )
1431
+ } else {
1432
+ c .LoadConst (py .None )
1433
+ }
1434
+
1435
+ if slice .Step != nil {
1436
+ n ++
1437
+ c .Expr (slice .Step )
1438
+ }
1439
+ c .OpArg (vm .BUILD_SLICE , n )
1440
+ }
1441
+
1442
+ // compile a nested slice
1443
+ func (c * compiler ) nestedSlice (s ast.Slicer , ctx ast.ExprContext ) {
1444
+ switch node := s .(type ) {
1445
+ case * ast.Slice :
1446
+ c .buildSlice (node , ctx )
1447
+ case * ast.Index :
1448
+ c .Expr (node .Value )
1449
+ case * ast.ExtSlice :
1450
+ panic ("extended slice invalid in nested slice" )
1451
+ default :
1452
+ panic ("nestedSlice: unknown type" )
1453
+ }
1454
+ }
1455
+
1456
+ // Compile a slice
1457
+ func (c * compiler ) slice (s ast.Slicer , ctx ast.ExprContext ) {
1458
+ kindname := ""
1459
+ switch node := s .(type ) {
1460
+ case * ast.Index :
1461
+ kindname = "index"
1462
+ if ctx != ast .AugStore {
1463
+ c .Expr (node .Value )
1464
+ }
1465
+ case * ast.Slice :
1466
+ kindname = "slice"
1467
+ if ctx != ast .AugStore {
1468
+ c .buildSlice (node , ctx )
1469
+ }
1470
+ case * ast.ExtSlice :
1471
+ kindname = "extended slice"
1472
+ if ctx != ast .AugStore {
1473
+ for _ , sub := range node .Dims {
1474
+ c .nestedSlice (sub , ctx )
1475
+ }
1476
+ c .OpArg (vm .BUILD_TUPLE , uint32 (len (node .Dims )))
1477
+ }
1478
+ default :
1479
+ panic (fmt .Sprintf ("invalid subscript kind %T" , s ))
1480
+ }
1481
+ c .subscript (kindname , ctx )
1482
+ }
1483
+
1406
1484
// Compile expressions
1407
1485
func (c * compiler ) Exprs (exprs []ast.Expr ) {
1408
1486
for _ , expr := range exprs {
@@ -1643,14 +1721,51 @@ func (c *compiler) Expr(expr ast.Expr) {
1643
1721
// Value Expr
1644
1722
// Attr Identifier
1645
1723
// Ctx ExprContext
1646
- // FIXME do something with Ctx
1647
- c .Expr (node .Value )
1648
- c .OpArg (vm .LOAD_ATTR , c .Name (node .Attr ))
1724
+ if node .Ctx != ast .AugStore {
1725
+ c .Expr (node .Value )
1726
+ }
1727
+ var op byte
1728
+ switch node .Ctx {
1729
+ case ast .AugLoad :
1730
+ c .Op (vm .DUP_TOP )
1731
+ op = vm .LOAD_ATTR
1732
+ case ast .Load :
1733
+ op = vm .LOAD_ATTR
1734
+ case ast .AugStore :
1735
+ c .Op (vm .ROT_TWO )
1736
+ op = vm .STORE_ATTR
1737
+ case ast .Store :
1738
+ op = vm .STORE_ATTR
1739
+ case ast .Del :
1740
+ op = vm .DELETE_ATTR
1741
+ case ast .Param :
1742
+ panic ("param invalid in attribute expression" )
1743
+ default :
1744
+ panic ("unknown context in attribute expression" )
1745
+ }
1746
+ c .OpArg (op , c .Name (node .Attr ))
1649
1747
case * ast.Subscript :
1650
1748
// Value Expr
1651
1749
// Slice Slicer
1652
1750
// Ctx ExprContext
1653
- panic ("FIXME compile: Subscript not implemented" )
1751
+ switch node .Ctx {
1752
+ case ast .AugLoad :
1753
+ c .Expr (node .Value )
1754
+ c .slice (node .Slice , ast .AugLoad )
1755
+ case ast .Load :
1756
+ c .Expr (node .Value )
1757
+ c .slice (node .Slice , ast .Load )
1758
+ case ast .AugStore :
1759
+ c .slice (node .Slice , ast .AugStore )
1760
+ case ast .Store :
1761
+ c .Expr (node .Value )
1762
+ c .slice (node .Slice , ast .Store )
1763
+ case ast .Del :
1764
+ c .Expr (node .Value )
1765
+ c .slice (node .Slice , ast .Del )
1766
+ default :
1767
+ panic ("param invalid in subscript expression" )
1768
+ }
1654
1769
case * ast.Starred :
1655
1770
// Value Expr
1656
1771
// Ctx ExprContext
0 commit comments