diff --git a/gnovm/pkg/gnolang/nodes.go b/gnovm/pkg/gnolang/nodes.go index 5d430a8bcde..8f2c5054a8a 100644 --- a/gnovm/pkg/gnolang/nodes.go +++ b/gnovm/pkg/gnolang/nodes.go @@ -158,23 +158,6 @@ type Attributes struct { data map[interface{}]interface{} // not persisted } -func (attr *Attributes) Copy() Attributes { - if attr == nil { - return Attributes{} - } - - data := make(map[interface{}]interface{}) - for k, v := range attr.data { - data[k] = v - } - - return Attributes{ - Line: attr.Line, - Label: attr.Label, - data: data, - } -} - func (attr *Attributes) GetLine() int { return attr.Line } @@ -1631,7 +1614,7 @@ func (sb *StaticBlock) GetPathForName(store Store, n Name) ValuePath { bp = bp.GetParentNode(store) gen++ if 0xff < gen { - panic("GetPathForName: value path depth overflow") + panic("value path depth overflow") } } } diff --git a/gnovm/pkg/gnolang/preprocess.go b/gnovm/pkg/gnolang/preprocess.go index c485fd43346..64fe1fbff45 100644 --- a/gnovm/pkg/gnolang/preprocess.go +++ b/gnovm/pkg/gnolang/preprocess.go @@ -14,21 +14,11 @@ import ( // Anything predefined or preprocessed here get skipped during the Preprocess // phase. func PredefineFileSet(store Store, pn *PackageNode, fset *FileSet) { - for _, fn := range fset.Files { - decls, err := sortValueDeps(fn.Decls) - if err != nil { - panic(err) - } - - fn.Decls = decls - } - // First, initialize all file nodes and connect to package node. for _, fn := range fset.Files { SetNodeLocations(pn.PkgPath, string(fn.Name), fn) fn.InitStaticBlock(fn, pn) } - // NOTE: much of what follows is duplicated for a single *FileNode // in the main Preprocess translation function. Keep synced. @@ -40,7 +30,11 @@ func PredefineFileSet(store Store, pn *PackageNode, fset *FileSet) { d := fn.Decls[i] switch d.(type) { case *ImportDecl: - if d.GetAttribute(ATTR_PREDEFINED) != true { + if d.GetAttribute(ATTR_PREDEFINED) == true { + // skip declarations already predefined + // (e.g. through recursion for a + // dependent) + } else { // recursively predefine dependencies. d2, _ := predefineNow(store, fn, d) fn.Decls[i] = d2 @@ -48,14 +42,17 @@ func PredefineFileSet(store Store, pn *PackageNode, fset *FileSet) { } } } - // Predefine all type decls decls. for _, fn := range fset.Files { for i := 0; i < len(fn.Decls); i++ { d := fn.Decls[i] switch d.(type) { case *TypeDecl: - if d.GetAttribute(ATTR_PREDEFINED) != true { + if d.GetAttribute(ATTR_PREDEFINED) == true { + // skip declarations already predefined + // (e.g. through recursion for a + // dependent) + } else { // recursively predefine dependencies. d2, _ := predefineNow(store, fn, d) fn.Decls[i] = d2 @@ -69,7 +66,11 @@ func PredefineFileSet(store Store, pn *PackageNode, fset *FileSet) { d := fn.Decls[i] switch d.(type) { case *FuncDecl: - if d.GetAttribute(ATTR_PREDEFINED) != true { + if d.GetAttribute(ATTR_PREDEFINED) == true { + // skip declarations already predefined + // (e.g. through recursion for a + // dependent) + } else { // recursively predefine dependencies. d2, _ := predefineNow(store, fn, d) fn.Decls[i] = d2 @@ -77,13 +78,15 @@ func PredefineFileSet(store Store, pn *PackageNode, fset *FileSet) { } } } - // Finally, predefine other decls and // preprocess ValueDecls.. for _, fn := range fset.Files { for i := 0; i < len(fn.Decls); i++ { d := fn.Decls[i] - if d.GetAttribute(ATTR_PREDEFINED) != true { + if d.GetAttribute(ATTR_PREDEFINED) == true { + // skip declarations already predefined (e.g. + // through recursion for a dependent) + } else { // recursively predefine dependencies. d2, _ := predefineNow(store, fn, d) fn.Decls[i] = d2 diff --git a/gnovm/pkg/gnolang/value_decl_dep_graph.go b/gnovm/pkg/gnolang/value_decl_dep_graph.go deleted file mode 100644 index fe130dbf43a..00000000000 --- a/gnovm/pkg/gnolang/value_decl_dep_graph.go +++ /dev/null @@ -1,245 +0,0 @@ -package gnolang - -import ( - "fmt" - "slices" - "strings" -) - -// sortValueDeps creates a new topologically sorted -// decl slice ready for processing in order -func sortValueDeps(decls Decls) (Decls, error) { - graph := &graph{ - edges: make(map[string][]string), - vertices: make([]string, 0), - } - - otherDecls := make(Decls, 0) - - for i := 0; i < len(decls); i++ { - d := decls[i] - vd, ok := d.(*ValueDecl) - - if !ok { - otherDecls = append(otherDecls, d) - continue - } - - if isTuple(vd) { - _, ok := vd.Values[0].(*CallExpr) - if ok { - graph.addVertex(vd.NameExprs.String()) - continue - } - } - - for j := 0; j < len(vd.NameExprs); j++ { - graph.addVertex(string(vd.NameExprs[j].Name)) - } - } - - for i := 0; i < len(decls); i++ { - d := decls[i] - vd, ok := d.(*ValueDecl) - - if !ok { - continue - } - - if isTuple(vd) { - ce, ok := vd.Values[0].(*CallExpr) - if ok { - addDepFromExpr(graph, vd.NameExprs.String(), ce) - continue - } - } - - for j := 0; j < len(vd.NameExprs); j++ { - if len(vd.Values) > j { - addDepFromExpr(graph, string(vd.NameExprs[j].Name), vd.Values[j]) - } - } - } - - sorted := make(Decls, 0) - - for _, node := range graph.topologicalSort() { - var dd Decl - - for _, decl := range decls { - vd, ok := decl.(*ValueDecl) - - if !ok { - continue - } - - if isCompoundNode(node) { - dd = processCompound(node, vd, decl) - break - } - - for i, nameExpr := range vd.NameExprs { - if string(nameExpr.Name) == node { - if len(vd.Values) > i { - dd = &ValueDecl{ - Attributes: vd.Attributes.Copy(), - NameExprs: []NameExpr{nameExpr}, - Type: vd.Type, - Values: []Expr{vd.Values[i]}, - Const: vd.Const, - } - break - } else { - dd = vd - break - } - } - } - } - - if dd == nil { - continue - } - - sorted = append(sorted, dd) - } - - slices.Reverse(sorted) - - otherDecls = append(otherDecls, sorted...) - - return otherDecls, nil -} - -func addDepFromExpr(dg *graph, fromNode string, expr Expr) { - switch e := expr.(type) { - case *FuncLitExpr: - for _, stmt := range e.Body { - addDepFromExprStmt(dg, fromNode, stmt) - } - case *CallExpr: - addDepFromExpr(dg, fromNode, e.Func) - - for _, arg := range e.Args { - addDepFromExpr(dg, fromNode, arg) - } - case *NameExpr: - if isUverseName(e.Name) { - break - } - - toNode := string(e.Name) - dg.addEdge(fromNode, toNode) - } -} - -func addDepFromExprStmt(dg *graph, fromNode string, stmt Stmt) { - switch e := stmt.(type) { - case *ExprStmt: - addDepFromExpr(dg, fromNode, e.X) - case *IfStmt: - addDepFromExprStmt(dg, fromNode, e.Init) - addDepFromExpr(dg, fromNode, e.Cond) - - for _, stm := range e.Then.Body { - addDepFromExprStmt(dg, fromNode, stm) - } - for _, stm := range e.Else.Body { - addDepFromExprStmt(dg, fromNode, stm) - } - case *ReturnStmt: - for _, stm := range e.Results { - addDepFromExpr(dg, fromNode, stm) - } - case *AssignStmt: - for _, stm := range e.Rhs { - addDepFromExpr(dg, fromNode, stm) - } - case *SwitchStmt: - addDepFromExpr(dg, fromNode, e.X) - for _, clause := range e.Clauses { - addDepFromExpr(dg, fromNode, clause.bodyStmt.Cond) - for _, s := range clause.bodyStmt.Body { - addDepFromExprStmt(dg, fromNode, s) - } - } - case *ForStmt: - addDepFromExpr(dg, fromNode, e.Cond) - for _, s := range e.bodyStmt.Body { - addDepFromExprStmt(dg, fromNode, s) - } - case *BlockStmt: - for _, s := range e.Block.bodyStmt.Body { - addDepFromExprStmt(dg, fromNode, s) - } - } -} - -type graph struct { - edges map[string][]string - vertices []string -} - -func (g *graph) addEdge(u, v string) { - g.edges[u] = append(g.edges[u], v) -} - -func (g *graph) addVertex(v string) { - g.vertices = append(g.vertices, v) -} - -func (g *graph) topologicalSortUtil(v string, visited map[string]bool, stack *[]string) { - visited[v] = true - - for _, u := range g.edges[v] { - if !visited[u] { - g.topologicalSortUtil(u, visited, stack) - } - } - - *stack = append([]string{v}, *stack...) -} - -func (g *graph) topologicalSort() []string { - stack := make([]string, 0) - visited := make(map[string]bool) - - for _, v := range g.vertices { - if !visited[v] { - g.topologicalSortUtil(v, visited, &stack) - } - } - - return stack -} - -func isTuple(vd *ValueDecl) bool { - return len(vd.NameExprs) > len(vd.Values) && len(vd.Values) > 0 -} - -func isCompoundNode(node string) bool { - return strings.Contains(node, ", ") -} - -func processCompound(node string, vd *ValueDecl, decl Decl) Decl { - names := strings.Split(node, ", ") - - if len(names) != len(vd.NameExprs) { - panic("should not happen") - } - - equal := true - - for i, name := range names { - if vd.NameExprs[i].String() != name { - equal = false - break - } - } - - if !equal { - panic(fmt.Sprintf("names: %+v != nameExprs: %+v\n", names, vd.NameExprs)) - } - - return decl -} diff --git a/gnovm/tests/files/var18.gno b/gnovm/tests/files/var18.gno deleted file mode 100644 index 619aedef779..00000000000 --- a/gnovm/tests/files/var18.gno +++ /dev/null @@ -1,14 +0,0 @@ -package main - -func main() { - println(a) - println(b) -} - -func r2() (int, int) { return 1, 2 } - -var a, b int = r2() - -// Output: -// 1 -// 2 diff --git a/gnovm/tests/files/var19.gno b/gnovm/tests/files/var19.gno deleted file mode 100644 index f26c230de0d..00000000000 --- a/gnovm/tests/files/var19.gno +++ /dev/null @@ -1,14 +0,0 @@ -package main - -func main() { - println(a) - println(b) - println(c) -} - -var a, b, c = 1, a + 1, b + 1 - -// Output: -// 1 -// 2 -// 3 diff --git a/gnovm/tests/files/var20.gno b/gnovm/tests/files/var20.gno deleted file mode 100644 index 1aec4792fcb..00000000000 --- a/gnovm/tests/files/var20.gno +++ /dev/null @@ -1,17 +0,0 @@ -package main - -func main() { - println(a) - println(b) - println(c) - println(d) -} - -var a, b, c = 1, a + d, 3 -var d = a - -// Output: -// 1 -// 2 -// 3 -// 1 diff --git a/gnovm/tests/files/var21.gno b/gnovm/tests/files/var21.gno deleted file mode 100644 index 7ec32e1ebfa..00000000000 --- a/gnovm/tests/files/var21.gno +++ /dev/null @@ -1,17 +0,0 @@ -package main - -func main() { - myDep = "123" - myVar() -} - -func hello(s string) { - println(s) -} - -var myVar = func() { hello(myDep) } - -var myDep string - -// Output: -// 123