~mna/snow

89925d5a5697fa80aaf2c7eb2ac78833a61b7436 — Martin Angers 1 year, 8 months ago f403078
pkg/codegen: start building the Go AST
2 files changed, 69 insertions(+), 4 deletions(-)

M pkg/codegen/codegen.go
A pkg/codegen/treebuild.go
M pkg/codegen/codegen.go => pkg/codegen/codegen.go +5 -4
@@ 81,12 81,13 @@ func ExecUnit(outDir string, unit *semantic.Unit) ([]string, error) {
	}
	semantic.Walk(t, unit)

	// TODO: temp, just to avoid errors, will require 4.
	gofiles := make([]*goast.File, len(unit.Files))

	// TODO: 4
	// 4. build the Go AST tree from the Snow-associated nodes so that relative
	//    position of nodes respects the snow source
	tb := &treebuilder{
		nodeToGoAST: t.nodeToGoAST,
	}
	semantic.Walk(tb, unit)
	gofiles := tb.gofiles

	// 5. walk the Go AST and assign valid positions to nodes
	fset := token.NewFileSet()

A pkg/codegen/treebuild.go => pkg/codegen/treebuild.go +64 -0
@@ 0,0 1,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
}