@@ -238,6 +238,29 @@ func (c *codegen) emitStoreStructField(i int) {
238
238
emit .Opcodes (c .prog .BinWriter , opcode .ROT , opcode .SETITEM )
239
239
}
240
240
241
+ func (c * codegen ) emitStoreSelectorExpr (n * ast.SelectorExpr ) {
242
+ typ := c .typeOf (n .X )
243
+ if c .isInvalidType (typ ) {
244
+ // This is a global variable from a package.
245
+ c .emitStoreVar (n .X .(* ast.Ident ).Name , n .Sel .Name )
246
+ return
247
+ }
248
+ strct , ok := c .getStruct (typ )
249
+ if ! ok {
250
+ c .prog .Err = fmt .Errorf ("nested selector assigns not supported yet" )
251
+ return
252
+ }
253
+ ast .Walk (c , n .X )
254
+ i := indexOfStruct (strct , n .Sel .Name )
255
+ c .emitStoreStructField (i )
256
+ }
257
+
258
+ func (c * codegen ) emitStoreIndexExpr (n * ast.IndexExpr ) {
259
+ ast .Walk (c , n .X )
260
+ ast .Walk (c , n .Index )
261
+ emit .Opcodes (c .prog .BinWriter , opcode .ROT , opcode .SETITEM )
262
+ }
263
+
241
264
// getVarIndex returns variable type and position in the corresponding slot,
242
265
// according to the current scope.
243
266
func (c * codegen ) getVarIndex (pkg string , name string ) * varInfo {
@@ -711,30 +734,15 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor {
711
734
if ! isAssignOp && ! isMapKeyCheck {
712
735
ast .Walk (c , n .Rhs [i ])
713
736
}
714
- typ := c .typeOf (t .X )
715
- if c .isInvalidType (typ ) {
716
- // Store to other package global variable.
717
- c .emitStoreVar (t .X .(* ast.Ident ).Name , t .Sel .Name )
718
- return nil
719
- }
720
- strct , ok := c .getStruct (typ )
721
- if ! ok {
722
- c .prog .Err = fmt .Errorf ("nested selector assigns not supported yet" )
723
- return nil
724
- }
725
- ast .Walk (c , t .X ) // load the struct
726
- i := indexOfStruct (strct , t .Sel .Name ) // get the index of the field
727
- c .emitStoreStructField (i ) // store the field
737
+ c .emitStoreSelectorExpr (t )
728
738
729
739
// Assignments to index expressions.
730
740
// slice[0] = 10
731
741
case * ast.IndexExpr :
732
742
if ! isAssignOp && ! isMapKeyCheck {
733
743
ast .Walk (c , n .Rhs [i ])
734
744
}
735
- ast .Walk (c , t .X )
736
- ast .Walk (c , t .Index )
737
- emit .Opcodes (c .prog .BinWriter , opcode .ROT , opcode .SETITEM )
745
+ c .emitStoreIndexExpr (t )
738
746
}
739
747
}
740
748
return nil
@@ -1207,11 +1215,17 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor {
1207
1215
ast .Walk (c , n .X )
1208
1216
c .emitToken (n .Tok , c .typeOf (n .X ))
1209
1217
1210
- // For now, only identifiers are supported for (post) for stmts.
1211
- // for i := 0; i < 10; i++ {}
1212
- // Where the post stmt is ( i++ )
1213
- if ident , ok := n .X .(* ast.Ident ); ok {
1214
- c .emitStoreVar ("" , ident .Name )
1218
+ switch t := n .X .(type ) {
1219
+ case * ast.Ident :
1220
+ c .emitStoreVar ("" , t .Name )
1221
+
1222
+ case * ast.SelectorExpr :
1223
+ // myStruct.t--
1224
+ c .emitStoreSelectorExpr (t )
1225
+
1226
+ case * ast.IndexExpr :
1227
+ // slice[0]++
1228
+ c .emitStoreIndexExpr (t )
1215
1229
}
1216
1230
return nil
1217
1231
0 commit comments