@@ -960,7 +960,7 @@ func (c *compiler) Stmt(stmt ast.Stmt) {
960960 panic ("compile: can't set context in AugAssign" )
961961 }
962962 // FIXME untidy modifying the ast temporarily!
963- setctx .SetCtx (ast .Load )
963+ setctx .SetCtx (ast .AugLoad )
964964 c .Expr (node .Target )
965965 c .Expr (node .Value )
966966 var op byte
@@ -993,7 +993,7 @@ func (c *compiler) Stmt(stmt ast.Stmt) {
993993 panic ("Unknown BinOp" )
994994 }
995995 c .Op (op )
996- setctx .SetCtx (ast .Store )
996+ setctx .SetCtx (ast .AugStore )
997997 c .Expr (node .Target )
998998 case * ast.For :
999999 // Target Expr
@@ -1118,7 +1118,7 @@ func (c *compiler) Stmt(stmt ast.Stmt) {
11181118 panic (py .ExceptionNewf (py .SyntaxError , "'continue' not properly in loop" ))
11191119 }
11201120 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
11221122 c .Jump (vm .JUMP_ABSOLUTE , l .Start )
11231123 //c.Jump(vm.CONTINUE_LOOP, l.Start)
11241124 } else {
@@ -1183,16 +1183,14 @@ func (c *compiler) NameOp(name string, ctx ast.ExprContext) {
11831183 switch optype {
11841184 case OP_DEREF :
11851185 switch ctx {
1186- case ast .Load :
1186+ case ast .Load , ast . AugLoad :
11871187 if c .SymTable .Type == symtable .ClassBlock {
11881188 op = vm .LOAD_CLASSDEREF
11891189 } else {
11901190 op = vm .LOAD_DEREF
11911191 }
1192- case ast .Store :
1192+ case ast .Store , ast . AugStore :
11931193 op = vm .STORE_DEREF
1194- case ast .AugLoad :
1195- case ast .AugStore :
11961194 case ast .Del :
11971195 op = vm .DELETE_DEREF
11981196 case ast .Param :
@@ -1202,14 +1200,12 @@ func (c *compiler) NameOp(name string, ctx ast.ExprContext) {
12021200 }
12031201 case OP_FAST :
12041202 switch ctx {
1205- case ast .Load :
1203+ case ast .Load , ast . AugLoad :
12061204 op = vm .LOAD_FAST
1207- case ast .Store :
1205+ case ast .Store , ast . AugStore :
12081206 op = vm .STORE_FAST
12091207 case ast .Del :
12101208 op = vm .DELETE_FAST
1211- case ast .AugLoad :
1212- case ast .AugStore :
12131209 case ast .Param :
12141210 panic ("NameOp: param invalid for local variable" )
12151211 default :
@@ -1218,29 +1214,25 @@ func (c *compiler) NameOp(name string, ctx ast.ExprContext) {
12181214 dict = & c .Code .Varnames
12191215 case OP_GLOBAL :
12201216 switch ctx {
1221- case ast .Load :
1217+ case ast .Load , ast . AugLoad :
12221218 op = vm .LOAD_GLOBAL
1223- case ast .Store :
1219+ case ast .Store , ast . AugStore :
12241220 op = vm .STORE_GLOBAL
12251221 case ast .Del :
12261222 op = vm .DELETE_GLOBAL
1227- case ast .AugLoad :
1228- case ast .AugStore :
12291223 case ast .Param :
12301224 panic ("NameOp: param invalid for global variable" )
12311225 default :
12321226 panic ("NameOp: ctx invalid for global variable" )
12331227 }
12341228 case OP_NAME :
12351229 switch ctx {
1236- case ast .Load :
1230+ case ast .Load , ast . AugLoad :
12371231 op = vm .LOAD_NAME
1238- case ast .Store :
1232+ case ast .Store , ast . AugStore :
12391233 op = vm .STORE_NAME
12401234 case ast .Del :
12411235 op = vm .DELETE_NAME
1242- case ast .AugLoad :
1243- case ast .AugStore :
12441236 case ast .Param :
12451237 panic ("NameOp: param invalid for name variable" )
12461238 default :
@@ -1403,6 +1395,92 @@ func (c *compiler) tupleOrList(op byte, ctx ast.ExprContext, elts []ast.Expr) {
14031395 }
14041396}
14051397
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+
14061484// Compile expressions
14071485func (c * compiler ) Exprs (exprs []ast.Expr ) {
14081486 for _ , expr := range exprs {
@@ -1643,14 +1721,51 @@ func (c *compiler) Expr(expr ast.Expr) {
16431721 // Value Expr
16441722 // Attr Identifier
16451723 // 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 ))
16491747 case * ast.Subscript :
16501748 // Value Expr
16511749 // Slice Slicer
16521750 // 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+ }
16541769 case * ast.Starred :
16551770 // Value Expr
16561771 // Ctx ExprContext
0 commit comments