From 89925d5a5697fa80aaf2c7eb2ac78833a61b7436 Mon Sep 17 00:00:00 2001 From: Martin Angers Date: Sat, 1 Feb 2020 18:11:08 -0500 Subject: [PATCH] pkg/codegen: start building the Go AST --- pkg/codegen/codegen.go | 9 +++--- pkg/codegen/treebuild.go | 64 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 4 deletions(-) create mode 100644 pkg/codegen/treebuild.go diff --git a/pkg/codegen/codegen.go b/pkg/codegen/codegen.go index 3ae24a1..3dc7085 100644 --- a/pkg/codegen/codegen.go +++ b/pkg/codegen/codegen.go @@ -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() diff --git a/pkg/codegen/treebuild.go b/pkg/codegen/treebuild.go new file mode 100644 index 0000000..7b33e69 --- /dev/null +++ b/pkg/codegen/treebuild.go @@ -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 +} -- 2.45.2