~mna/snow

ref: 89925d5a5697fa80aaf2c7eb2ac78833a61b7436 snow/pkg/codegen/treebuild.go -rw-r--r-- 1.5 KiB
89925d5aMartin Angers pkg/codegen: start building the Go AST 1 year, 10 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
package codegen

import (
	goast "go/ast"

	"git.sr.ht/~mna/snow/pkg/semantic"
)

// The treebuilder builds the Go AST from the nodes associated with the
// abstract semantic graph in the translator phase.
type treebuilder struct {
	curGoFile   *goast.File
	gofiles     []*goast.File
	nodeToGoAST map[semantic.Node][]goast.Node
}

func (tb *treebuilder) Visit(n semantic.Node) semantic.Visitor {
	switch n := n.(type) {
	case *semantic.Unit:
		for _, f := range n.Files {
			semantic.Walk(tb, f)
			tb.gofiles = append(tb.gofiles, tb.curGoFile)
		}

	case *semantic.File:
		// file node should have its goast.File as first node, rest should be added
		// to the file's declarations.
		ns := tb.nodeToGoAST[n]
		tb.curGoFile = ns[0].(*goast.File)
		for i := 1; i < len(ns); i++ {
			tb.curGoFile.Decls = append(tb.curGoFile.Decls, ns[i].(goast.Decl))
		}

		decls := make([]semantic.Decl, 0, len(n.Vars)+len(n.Structs)+len(n.Fns))
		for _, v := range n.Vars {
			semantic.Walk(tb, v)
			decls = append(decls, v)
		}
		for _, str := range n.Structs {
			semantic.Walk(tb, str)
			decls = append(decls, str)
		}
		for _, fn := range n.Fns {
			semantic.Walk(tb, fn)
			decls = append(decls, fn)
		}
		for _, decl := range decls {
			for _, gons := range tb.nodeToGoAST[decl] {
				tb.curGoFile.Decls = append(tb.curGoFile.Decls, gons.(goast.Decl))
			}
		}

	case *semantic.Fn:
	case *semantic.Struct:
	case *semantic.Var:
	case *semantic.Block:
	case *semantic.Return:
	case *semantic.Assign:
	case *semantic.ExprStmt:
	case *semantic.If:
	case *semantic.Guard:
	}
	return nil
}