Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(gnovm): improve interface/func/struct type String methods #3875

Merged
merged 11 commits into from
Mar 5, 2025
4 changes: 2 additions & 2 deletions gno.land/pkg/sdk/vm/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ func TestVmHandlerQuery_Eval(t *testing.T) {
{input: []byte(`gno.land/r/hello.myStructInst`), expectedResult: `(struct{(1000 int)} gno.land/r/hello.myStruct)`},
{input: []byte(`gno.land/r/hello.myStructInst.Foo()`), expectedResult: `("myStruct.Foo" string)`},
{input: []byte(`gno.land/r/hello.myStruct`), expectedResultMatch: `\(typeval{gno.land/r/hello.myStruct \(0x.*\)} type{}\)`},
{input: []byte(`gno.land/r/hello.Inc`), expectedResult: `(Inc func()( int))`},
{input: []byte(`gno.land/r/hello.Inc`), expectedResult: `(Inc func() int)`},
{input: []byte(`gno.land/r/hello.fn()("hi")`), expectedResult: `("echo:hi" string)`},
{input: []byte(`gno.land/r/hello.sl`), expectedResultMatch: `(slice[ref(.*)] []int)`}, // XXX: should return the actual value
{input: []byte(`gno.land/r/hello.sl[1]`), expectedResultMatch: `(slice[ref(.*)] []int)`}, // XXX: should return the actual value
Expand Down Expand Up @@ -168,7 +168,7 @@ func pvEcho(msg string) string { return "pvecho:"+msg }
if tc.expectedErrorMatch == "" {
assert.True(t, res.IsOK(), "should not have error")
if tc.expectedResult != "" {
assert.Equal(t, string(res.Data), tc.expectedResult)
assert.Equal(t, tc.expectedResult, string(res.Data))
}
if tc.expectedResultMatch != "" {
assert.Regexp(t, tc.expectedResultMatch, string(res.Data))
Expand Down
63 changes: 40 additions & 23 deletions gnovm/pkg/gnolang/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -453,27 +453,29 @@
}

func (l FieldTypeList) String() string {
ll := len(l)
s := ""
for i, ft := range l {
s += string(ft.Name) + " " + ft.Type.TypeID().String()
if i != ll-1 {
s += ";"
}
}
return s
return l.string(true, "; ")
}

func (l FieldTypeList) StringWithCommas() string {
ll := len(l)
s := ""
// StringForFunc returns a list of the fields, suitable for functions.
// Compared to [FieldTypeList.String], this method does not return field names,
// and separates the fields using ", ".
func (l FieldTypeList) StringForFunc() string {
return l.string(false, ", ")
}

func (l FieldTypeList) string(withName bool, sep string) string {
var bld strings.Builder
for i, ft := range l {
s += string(ft.Name) + " " + ft.Type.String()
if i != ll-1 {
s += ","
if i != 0 {
bld.WriteString(sep)
}
if withName {
bld.WriteString(string(ft.Name))
bld.WriteByte(' ')
}
bld.WriteString(ft.Type.String())
}
return s
return bld.String()
}

// Like TypeID() but without considering field names;
Expand Down Expand Up @@ -751,7 +753,10 @@
}

func (st *StructType) String() string {
return fmt.Sprintf("struct{%s}",
if len(st.Fields) == 0 {
return "struct {}"
}
return fmt.Sprintf("struct { %s }",
FieldTypeList(st.Fields).String())
}

Expand Down Expand Up @@ -932,12 +937,15 @@
}

func (it *InterfaceType) String() string {
if it.Generic != "" {
switch {
case it.Generic != "":

Check warning on line 941 in gnovm/pkg/gnolang/types.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/types.go#L941

Added line #L941 was not covered by tests
return fmt.Sprintf("<%s>{%s}",
it.Generic,
FieldTypeList(it.Methods).String())
} else {
return fmt.Sprintf("interface{%s}",
case len(it.Methods) == 0:
return "interface {}"
default:
return fmt.Sprintf("interface { %s }",
FieldTypeList(it.Methods).String())
}
}
Expand Down Expand Up @@ -1305,9 +1313,18 @@
}

func (ft *FuncType) String() string {
return fmt.Sprintf("func(%s)(%s)",
FieldTypeList(ft.Params).StringWithCommas(),
FieldTypeList(ft.Results).StringWithCommas())
switch len(ft.Results) {
case 0:
return fmt.Sprintf("func(%s)", FieldTypeList(ft.Params).StringForFunc())
case 1:
return fmt.Sprintf("func(%s) %s",
FieldTypeList(ft.Params).StringForFunc(),
ft.Results[0].Type.String())
default:
return fmt.Sprintf("func(%s) (%s)",
FieldTypeList(ft.Params).StringForFunc(),
FieldTypeList(ft.Results).StringForFunc())
}
}

func (ft *FuncType) Elem() Type {
Expand Down
4 changes: 2 additions & 2 deletions gnovm/pkg/gnolang/values_string.go
Original file line number Diff line number Diff line change
Expand Up @@ -196,9 +196,9 @@
)
if ft, ok := v.Func.Type.(*FuncType); ok {
recvT = ft.Params[0].Type.String()
params = FieldTypeList(ft.Params).StringWithCommas()
params = FieldTypeList(ft.Params).StringForFunc()

Check warning on line 199 in gnovm/pkg/gnolang/values_string.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/values_string.go#L199

Added line #L199 was not covered by tests
if len(results) > 0 {
results = FieldTypeList(ft.Results).StringWithCommas()
results = FieldTypeList(ft.Results).StringForFunc()

Check warning on line 201 in gnovm/pkg/gnolang/values_string.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/values_string.go#L201

Added line #L201 was not covered by tests
results = "(" + results + ")"
}
}
Expand Down
6 changes: 3 additions & 3 deletions gnovm/pkg/gnolang/values_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,23 +32,23 @@ func TestGetLengthPanic(t *testing.T) {
},
},
},
expected: "unexpected type for len(): *struct{}",
expected: "unexpected type for len(): *struct {}",
},
{
name: "UnexpectedType",
tv: TypedValue{
T: &StructType{},
V: &mockTypedValueStruct{field: 42},
},
expected: "unexpected type for len(): struct{}",
expected: "unexpected type for len(): struct {}",
},
{
name: "UnexpectedPointerType",
tv: TypedValue{
T: &PointerType{Elt: &StructType{}},
V: nil,
},
expected: "unexpected type for len(): *struct{}",
expected: "unexpected type for len(): *struct {}",
},
}

Expand Down
2 changes: 1 addition & 1 deletion gnovm/tests/files/addressable_10b_err.gno
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ func main() {
}

// Error:
// main/files/addressable_10b_err.gno:8:10: cannot take address of (const (new func(t type{})( *main.S)))(S<VPBlock(3,0)>)
// main/files/addressable_10b_err.gno:8:10: cannot take address of (const (new func(type{}) *main.S))(S<VPBlock(3,0)>)
2 changes: 1 addition & 1 deletion gnovm/tests/files/addressable_8.gno
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ func main() {
}

// Output:
// &(func()(){...} func()())
// &(func(){...} func())
2 changes: 1 addition & 1 deletion gnovm/tests/files/addressable_8a_err.gno
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ func main() {
}

// Error:
// main/files/addressable_8a_err.gno:4:6: cannot take address of func func(){ (const (println func(xs ...interface{})()))((const ("Hello, World!" string))) }
// main/files/addressable_8a_err.gno:4:6: cannot take address of func func(){ (const (println func(...interface {})))((const ("Hello, World!" string))) }
2 changes: 1 addition & 1 deletion gnovm/tests/files/assign29.gno
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ func main() {
}

// Error:
// main/files/assign29.gno:4:2: struct{} (type) is not an expression
// main/files/assign29.gno:4:2: struct {} (type) is not an expression
2 changes: 1 addition & 1 deletion gnovm/tests/files/assign30.gno
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ func main() {
}

// Error:
// main/files/assign30.gno:4:2: *struct{} (type) is not an expression
// main/files/assign30.gno:4:2: *struct {} (type) is not an expression
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,5 @@ func main() {
// (nil main.nat)
// (nil map[int]int)
// (nil main.nmap)
// nil func()()
// nil func()
// (nil main.nfunc)
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ func main() {
}

// Error:
// main/files/assign_unnamed_type/more/return_interface1_filetest.gno:10:2: cannot use interface{} as uint
// main/files/assign_unnamed_type/more/return_interface1_filetest.gno:10:2: cannot use interface {} as uint
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@ func main() {
}

// Error:
// main/files/assign_unnamed_type/more/return_interface_filetest.gno:13:2: cannot use interface{} as []int
// main/files/assign_unnamed_type/more/return_interface_filetest.gno:13:2: cannot use interface {} as []int
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ func main() {

// Output:
// 1 (inc main.op)
// 0 func(n int)( int){...}
// 0 func(int) int{...}
// -1 dec
// 0 (func(n int)( int){...} main.op)
// 0 (func(int) int{...} main.op)
// -1 dec
// 1 inc
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func main() {
}

// Output:
// func(n int)( int){...}
// func(int) int{...}
// 1
// (func(n int)( int){...} main.op)
// (func(int) int{...} main.op)
// -1
2 changes: 1 addition & 1 deletion gnovm/tests/files/cap10.gno
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ func main() {
}

// Error:
// unexpected type for cap(): struct{A int}
// unexpected type for cap(): struct { A int }
2 changes: 1 addition & 1 deletion gnovm/tests/files/const31.gno
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ func main() {
}

// Error:
// main/files/const31.gno:10:8: (const (v func()( string, string)))() (variable of type (string,string)) is not constant
// main/files/const31.gno:10:8: (const (v func() (string, string)))() (variable of type (string,string)) is not constant
2 changes: 1 addition & 1 deletion gnovm/tests/files/const34.gno
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ func main() {
}

// Error:
// main/files/const34.gno:3:7: func func(){ (const (println func(xs ...interface{})()))((const ("hey" string))) } (variable of type func()()) is not constant
// main/files/const34.gno:3:7: func func(){ (const (println func(...interface {})))((const ("hey" string))) } (variable of type func()) is not constant
2 changes: 1 addition & 1 deletion gnovm/tests/files/const39.gno
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ func main() {
}

// Error:
// main/files/const39.gno:10:8: T<VPBlock(3,0)>.Mv (variable of type func(tv main.T,a int)( int)) is not constant
// main/files/const39.gno:10:8: T<VPBlock(3,0)>.Mv (variable of type func(main.T, int) int) is not constant
2 changes: 1 addition & 1 deletion gnovm/tests/files/const44.gno
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ func main() {
}

// Error:
// main/files/const44.gno:3:7: (const (undefined)) (variable of type interface{}) is not constant
// main/files/const44.gno:3:7: (const (undefined)) (variable of type interface {}) is not constant
2 changes: 1 addition & 1 deletion gnovm/tests/files/fun10.gno
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@ func main() {
}

// Output:
// nil func()()
// nil func()
// nil func
2 changes: 1 addition & 1 deletion gnovm/tests/files/heap_alloc_forloop1.gno
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func main() {
// go 1.22 loop var is not supported for now.

// Preprocessed:
// file{ package main; import fmt fmt; var s1<!VPBlock(2,0)> []*((const-type int)); func forLoopRef() { defer func func(){ for i<VPBlock(1,0)>, e<VPBlock(1,1)> := range s1<VPBlock(5,0)> { fmt<VPBlock(4,0)>.Printf((const ("s1[%d] is: %d\n" string)), (const-type gonative{interface {}})(i<VPBlock(1,0)>), (const-type gonative{interface {}})(*(e<VPBlock(1,1)>))) } }(); for i<!~VPBlock(1,0)> := (const (0 int)); i<~VPBlock(1,0)> < (const (3 int)); i<~VPBlock(1,0)>++ { s1<VPBlock(4,0)> = (const (append func(x []*int,args ...*int)(res []*int)))(s1<VPBlock(4,0)>, &(i<~VPBlock(1,0)>)) } }; func main() { forLoopRef<VPBlock(3,1)>() } }
// file{ package main; import fmt fmt; var s1<!VPBlock(2,0)> []*((const-type int)); func forLoopRef() { defer func func(){ for i<VPBlock(1,0)>, e<VPBlock(1,1)> := range s1<VPBlock(5,0)> { fmt<VPBlock(4,0)>.Printf((const ("s1[%d] is: %d\n" string)), (const-type gonative{interface {}})(i<VPBlock(1,0)>), (const-type gonative{interface {}})(*(e<VPBlock(1,1)>))) } }(); for i<!~VPBlock(1,0)> := (const (0 int)); i<~VPBlock(1,0)> < (const (3 int)); i<~VPBlock(1,0)>++ { s1<VPBlock(4,0)> = (const (append func([]*int, ...*int) []*int))(s1<VPBlock(4,0)>, &(i<~VPBlock(1,0)>)) } }; func main() { forLoopRef<VPBlock(3,1)>() } }

// Output:
// s1[0] is: 3
Expand Down
2 changes: 1 addition & 1 deletion gnovm/tests/files/heap_alloc_forloop1a.gno
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func main() {
// go 1.22 loop var is not supported for now.

// Preprocessed:
// file{ package main; import fmt fmt; type Int (const-type main.Int); var s1<!VPBlock(2,1)> []*(Int<VPBlock(2,0)>); func inc2(j *(Int<VPBlock(2,0)>)) { *(j<VPBlock(1,0)>) = *(j<VPBlock(1,0)>) + (const (2 main.Int)) }; func forLoopRef() { defer func func(){ for i<VPBlock(1,0)>, e<VPBlock(1,1)> := range s1<VPBlock(5,1)> { fmt<VPBlock(4,0)>.Printf((const ("s1[%d] is: %d\n" string)), (const-type gonative{interface {}})(i<VPBlock(1,0)>), (const-type gonative{interface {}})(*(e<VPBlock(1,1)>))) } }(); for i<!~VPBlock(1,0)> := (const (0 main.Int)); i<~VPBlock(1,0)> < (const (10 main.Int)); inc2<VPBlock(4,2)>(&(i<~VPBlock(1,0)>)) { s1<VPBlock(4,1)> = (const (append func(x []*main.Int,args ...*main.Int)(res []*main.Int)))(s1<VPBlock(4,1)>, &(i<~VPBlock(1,0)>)) } }; func main() { forLoopRef<VPBlock(3,3)>() } }
// file{ package main; import fmt fmt; type Int (const-type main.Int); var s1<!VPBlock(2,1)> []*(Int<VPBlock(2,0)>); func inc2(j *(Int<VPBlock(2,0)>)) { *(j<VPBlock(1,0)>) = *(j<VPBlock(1,0)>) + (const (2 main.Int)) }; func forLoopRef() { defer func func(){ for i<VPBlock(1,0)>, e<VPBlock(1,1)> := range s1<VPBlock(5,1)> { fmt<VPBlock(4,0)>.Printf((const ("s1[%d] is: %d\n" string)), (const-type gonative{interface {}})(i<VPBlock(1,0)>), (const-type gonative{interface {}})(*(e<VPBlock(1,1)>))) } }(); for i<!~VPBlock(1,0)> := (const (0 main.Int)); i<~VPBlock(1,0)> < (const (10 main.Int)); inc2<VPBlock(4,2)>(&(i<~VPBlock(1,0)>)) { s1<VPBlock(4,1)> = (const (append func([]*main.Int, ...*main.Int) []*main.Int))(s1<VPBlock(4,1)>, &(i<~VPBlock(1,0)>)) } }; func main() { forLoopRef<VPBlock(3,3)>() } }

// Output:
// s1[0] is: 10
Expand Down
2 changes: 1 addition & 1 deletion gnovm/tests/files/heap_alloc_forloop1b.gno
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func main() {
// go 1.22 loop var is not supported for now.

// Preprocessed:
// file{ package main; import fmt fmt; var s1<!VPBlock(2,0)> []*((const-type int)); func forLoopRef() { defer func func(){ for i<VPBlock(1,0)>, e<VPBlock(1,1)> := range s1<VPBlock(5,0)> { fmt<VPBlock(4,0)>.Printf((const ("s1[%d] is: %d\n" string)), (const-type gonative{interface {}})(i<VPBlock(1,0)>), (const-type gonative{interface {}})(*(e<VPBlock(1,1)>))) } }(); for i<!~VPBlock(1,0)> := (const (0 int)); i<~VPBlock(1,0)> < (const (3 int)); i<~VPBlock(1,0)>++ { r<!VPBlock(1,1)> := i<~VPBlock(1,0)>; r<VPBlock(1,1)>, ok<!VPBlock(1,2)> := (const (0 int)), (const (true bool)); (const (println func(xs ...interface{})()))(ok<VPBlock(1,2)>, r<VPBlock(1,1)>); s1<VPBlock(4,0)> = (const (append func(x []*int,args ...*int)(res []*int)))(s1<VPBlock(4,0)>, &(i<~VPBlock(1,0)>)) } }; func main() { forLoopRef<VPBlock(3,1)>() } }
// file{ package main; import fmt fmt; var s1<!VPBlock(2,0)> []*((const-type int)); func forLoopRef() { defer func func(){ for i<VPBlock(1,0)>, e<VPBlock(1,1)> := range s1<VPBlock(5,0)> { fmt<VPBlock(4,0)>.Printf((const ("s1[%d] is: %d\n" string)), (const-type gonative{interface {}})(i<VPBlock(1,0)>), (const-type gonative{interface {}})(*(e<VPBlock(1,1)>))) } }(); for i<!~VPBlock(1,0)> := (const (0 int)); i<~VPBlock(1,0)> < (const (3 int)); i<~VPBlock(1,0)>++ { r<!VPBlock(1,1)> := i<~VPBlock(1,0)>; r<VPBlock(1,1)>, ok<!VPBlock(1,2)> := (const (0 int)), (const (true bool)); (const (println func(...interface {})))(ok<VPBlock(1,2)>, r<VPBlock(1,1)>); s1<VPBlock(4,0)> = (const (append func([]*int, ...*int) []*int))(s1<VPBlock(4,0)>, &(i<~VPBlock(1,0)>)) } }; func main() { forLoopRef<VPBlock(3,1)>() } }

// Output:
// true 0
Expand Down
2 changes: 1 addition & 1 deletion gnovm/tests/files/heap_alloc_forloop2.gno
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func main() {
// You can tell by the preprocess printout of z<!~...> and z<~...>.

// Preprocessed:
// file{ package main; import fmt fmt; var s1<!VPBlock(2,0)> []*((const-type int)); func forLoopRef() { defer func func(){ for i<VPBlock(1,0)>, e<VPBlock(1,1)> := range s1<VPBlock(5,0)> { fmt<VPBlock(4,0)>.Printf((const ("s1[%d] is: %d\n" string)), (const-type gonative{interface {}})(i<VPBlock(1,0)>), (const-type gonative{interface {}})(*(e<VPBlock(1,1)>))) } }(); for i<!VPBlock(1,0)> := (const (0 int)); i<VPBlock(1,0)> < (const (3 int)); i<VPBlock(1,0)>++ { z<!~VPBlock(1,1)> := i<VPBlock(1,0)> + (const (1 int)); s1<VPBlock(4,0)> = (const (append func(x []*int,args ...*int)(res []*int)))(s1<VPBlock(4,0)>, &(z<~VPBlock(1,1)>)) } }; func main() { forLoopRef<VPBlock(3,1)>() } }
// file{ package main; import fmt fmt; var s1<!VPBlock(2,0)> []*((const-type int)); func forLoopRef() { defer func func(){ for i<VPBlock(1,0)>, e<VPBlock(1,1)> := range s1<VPBlock(5,0)> { fmt<VPBlock(4,0)>.Printf((const ("s1[%d] is: %d\n" string)), (const-type gonative{interface {}})(i<VPBlock(1,0)>), (const-type gonative{interface {}})(*(e<VPBlock(1,1)>))) } }(); for i<!VPBlock(1,0)> := (const (0 int)); i<VPBlock(1,0)> < (const (3 int)); i<VPBlock(1,0)>++ { z<!~VPBlock(1,1)> := i<VPBlock(1,0)> + (const (1 int)); s1<VPBlock(4,0)> = (const (append func([]*int, ...*int) []*int))(s1<VPBlock(4,0)>, &(z<~VPBlock(1,1)>)) } }; func main() { forLoopRef<VPBlock(3,1)>() } }

// Output:
// s1[0] is: 1
Expand Down
2 changes: 1 addition & 1 deletion gnovm/tests/files/heap_alloc_forloop2a.gno
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func main() {
// You can tell by the preprocess printout of z<!~...> and z<~...>.

// Preprocessed:
// file{ package main; import fmt fmt; var s1<!VPBlock(2,0)> []*((const-type int)); func forLoopRef() { defer func func(){ for i<VPBlock(1,0)>, e<VPBlock(1,1)> := range s1<VPBlock(5,0)> { fmt<VPBlock(4,0)>.Printf((const ("s1[%d] is: %d\n" string)), (const-type gonative{interface {}})(i<VPBlock(1,0)>), (const-type gonative{interface {}})(*(e<VPBlock(1,1)>))) } }(); for i<!VPBlock(1,0)> := (const (0 int)); i<VPBlock(1,0)> < (const (3 int)); i<VPBlock(1,0)>++ { z<!~VPBlock(1,1)> := i<VPBlock(1,0)>; s1<VPBlock(4,0)> = (const (append func(x []*int,args ...*int)(res []*int)))(s1<VPBlock(4,0)>, &(z<~VPBlock(1,1)>)); z<~VPBlock(1,1)>++ } }; func main() { forLoopRef<VPBlock(3,1)>() } }
// file{ package main; import fmt fmt; var s1<!VPBlock(2,0)> []*((const-type int)); func forLoopRef() { defer func func(){ for i<VPBlock(1,0)>, e<VPBlock(1,1)> := range s1<VPBlock(5,0)> { fmt<VPBlock(4,0)>.Printf((const ("s1[%d] is: %d\n" string)), (const-type gonative{interface {}})(i<VPBlock(1,0)>), (const-type gonative{interface {}})(*(e<VPBlock(1,1)>))) } }(); for i<!VPBlock(1,0)> := (const (0 int)); i<VPBlock(1,0)> < (const (3 int)); i<VPBlock(1,0)>++ { z<!~VPBlock(1,1)> := i<VPBlock(1,0)>; s1<VPBlock(4,0)> = (const (append func([]*int, ...*int) []*int))(s1<VPBlock(4,0)>, &(z<~VPBlock(1,1)>)); z<~VPBlock(1,1)>++ } }; func main() { forLoopRef<VPBlock(3,1)>() } }

// Output:
// s1[0] is: 1
Expand Down
2 changes: 1 addition & 1 deletion gnovm/tests/files/heap_alloc_forloop3.gno
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func main() {
// You can tell by the preprocess printout of z<!~...> and z<()~...>.

// Preprocessed:
// file{ package main; type f (const-type main.f); var fs<!VPBlock(2,1)> []f<VPBlock(2,0)>; func forLoopClosure() { defer func func(){ for _<VPBlock(0,0)>, f<VPBlock(1,0)> := range fs<VPBlock(5,1)> { f<VPBlock(1,0)>() } }(); for i<!VPBlock(1,0)> := (const (0 int)); i<VPBlock(1,0)> < (const (3 int)); i<VPBlock(1,0)>++ { z<!~VPBlock(1,1)> := i<VPBlock(1,0)>; fs<VPBlock(4,1)> = (const (append func(x []main.f,args ...main.f)(res []main.f)))(fs<VPBlock(4,1)>, (const-type main.f)(func func(){ (const (println func(xs ...interface{})()))(z<~VPBlock(1,0)>) }<z<()~VPBlock(1,1)>>)) } }; func main() { forLoopClosure<VPBlock(3,2)>() } }
// file{ package main; type f (const-type main.f); var fs<!VPBlock(2,1)> []f<VPBlock(2,0)>; func forLoopClosure() { defer func func(){ for _<VPBlock(0,0)>, f<VPBlock(1,0)> := range fs<VPBlock(5,1)> { f<VPBlock(1,0)>() } }(); for i<!VPBlock(1,0)> := (const (0 int)); i<VPBlock(1,0)> < (const (3 int)); i<VPBlock(1,0)>++ { z<!~VPBlock(1,1)> := i<VPBlock(1,0)>; fs<VPBlock(4,1)> = (const (append func([]main.f, ...main.f) []main.f))(fs<VPBlock(4,1)>, (const-type main.f)(func func(){ (const (println func(...interface {})))(z<~VPBlock(1,0)>) }<z<()~VPBlock(1,1)>>)) } }; func main() { forLoopClosure<VPBlock(3,2)>() } }

// Output:
// 0
Expand Down
2 changes: 1 addition & 1 deletion gnovm/tests/files/heap_alloc_forloop3a.gno
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func main() {
// You can tell by the preprocess printout of z<!~...> and z<()~...>.

// Preprocessed:
// file{ package main; type f (const-type main.f); var fs<!VPBlock(2,1)> []f<VPBlock(2,0)>; func forLoopClosure() { defer func func(){ for _<VPBlock(0,0)>, f<VPBlock(1,0)> := range fs<VPBlock(5,1)> { f<VPBlock(1,0)>() } }(); for i<!VPBlock(1,0)> := (const (0 int)); i<VPBlock(1,0)> < (const (3 int)); i<VPBlock(1,0)>++ { x<!VPBlock(1,1)> := i<VPBlock(1,0)>; (const (println func(xs ...interface{})()))(x<VPBlock(1,1)>); z<!~VPBlock(1,2)> := i<VPBlock(1,0)>; fs<VPBlock(4,1)> = (const (append func(x []main.f,args ...main.f)(res []main.f)))(fs<VPBlock(4,1)>, (const-type main.f)(func func(){ (const (println func(xs ...interface{})()))(z<~VPBlock(1,0)>) }<z<()~VPBlock(1,2)>>)) } }; func main() { forLoopClosure<VPBlock(3,2)>() } }
// file{ package main; type f (const-type main.f); var fs<!VPBlock(2,1)> []f<VPBlock(2,0)>; func forLoopClosure() { defer func func(){ for _<VPBlock(0,0)>, f<VPBlock(1,0)> := range fs<VPBlock(5,1)> { f<VPBlock(1,0)>() } }(); for i<!VPBlock(1,0)> := (const (0 int)); i<VPBlock(1,0)> < (const (3 int)); i<VPBlock(1,0)>++ { x<!VPBlock(1,1)> := i<VPBlock(1,0)>; (const (println func(...interface {})))(x<VPBlock(1,1)>); z<!~VPBlock(1,2)> := i<VPBlock(1,0)>; fs<VPBlock(4,1)> = (const (append func([]main.f, ...main.f) []main.f))(fs<VPBlock(4,1)>, (const-type main.f)(func func(){ (const (println func(...interface {})))(z<~VPBlock(1,0)>) }<z<()~VPBlock(1,2)>>)) } }; func main() { forLoopClosure<VPBlock(3,2)>() } }

// Output:
// 0
Expand Down
Loading
Loading