From cba22db091499f246de761f998a03ebeaf94fabf Mon Sep 17 00:00:00 2001 From: xushiwei Date: Sat, 6 Mar 2021 12:30:14 +0800 Subject: [PATCH] github.com/goplus/gox --- README.md | 53 +++++++++++++++++++- conv/goconv.go | 40 +++++++++++++++ dom/codebuild.go | 66 +++++++++++++++++++++++++ dom/package.go | 123 +++++++++++++++++++++++++++++++++++++++++++++++ dom/pkgref.go | 20 ++++++++ dom/token.go | 64 ++++++++++++++++++++++++ go.mod | 3 ++ 7 files changed, 367 insertions(+), 2 deletions(-) create mode 100644 conv/goconv.go create mode 100644 dom/codebuild.go create mode 100644 dom/package.go create mode 100644 dom/pkgref.go create mode 100644 dom/token.go create mode 100644 go.mod diff --git a/README.md b/README.md index 547a3b9c..4d37263e 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,51 @@ -# gox -Code generator for the Go language +gox - Code generator for the Go language +======== + +[![Build Status](https://travis-ci.org/goplus/gox.png?branch=master)](https://travis-ci.org/goplus/gox) +[![Go Report Card](https://goreportcard.com/badge/github.com/goplus/gox)](https://goreportcard.com/report/github.com/goplus/gox) +[![GitHub release](https://img.shields.io/github/v/tag/goplus/gox.svg?label=release)](https://github.com/goplus/gox/releases) +[![Coverage Status](https://codecov.io/gh/goplus/gox/branch/master/graph/badge.svg)](https://codecov.io/gh/goplus/gox) +[![GoDoc](https://img.shields.io/badge/godoc-reference-teal.svg)](https://pkg.go.dev/mod/github.com/goplus/gox) + +## Tutorials + +```go +import ( + "github.com/goplus/gox/dom" + "github.com/goplus/gox/conv" +) + +var a, b, c *dom.Var + +pkg := dom.NewPkg("main") + +fmt := pkg.Import("fmt") + +pkg.NewFunc("main").BodyStart(pkg). + NewVar("a", &a).NewVar("b", &b).NewVar("c", &c). // type of variables will be auto detected + VarRef(a).VarRef(b).Const("Hi").Const(3).Assign(2).EndStmt(). // a, b = "Hi", 3 + VarRef(c).Val(b).Assign(1).EndStmt(). // c = b + Val(fmt.Ref("Println")).Val(a).Val(b).Val(c).Call(3).EndStmt(). // fmt.Println(a, b, c) + End() + +conv.WriteFile("./foo.go", pkg) +``` + +This will generate a Go source file named `./foo.go`. The following is its content: + +```go +package main + +import ( + "fmt" +) + +func main() { + var a string + var b int + var c int + a, b = "Hi", 3 + c = b + fmt.Println(a, b, c) +} +``` diff --git a/conv/goconv.go b/conv/goconv.go new file mode 100644 index 00000000..e835afaf --- /dev/null +++ b/conv/goconv.go @@ -0,0 +1,40 @@ +package goconv + +import ( + "go/ast" + "go/format" + "go/token" + "io" + "os" + + "github.com/goplus/gox/dom" +) + +// ---------------------------------------------------------------------------- + +// From func +func From(fset *token.FileSet, pkg *dom.Package) (file *ast.File, err error) { + return +} + +// WriteTo func +func WriteTo(dst io.Writer, pkg *dom.Package) (err error) { + fset := token.NewFileSet() + file, err := From(fset, pkg) + if err != nil { + return + } + return format.Node(dst, fset, file) +} + +// WriteFile func +func WriteFile(file string, pkg *dom.Package) (err error) { + f, err := os.Create(file) + if err != nil { + return + } + defer f.Close() + return WriteTo(f, pkg) +} + +// ---------------------------------------------------------------------------- diff --git a/dom/codebuild.go b/dom/codebuild.go new file mode 100644 index 00000000..f0af5733 --- /dev/null +++ b/dom/codebuild.go @@ -0,0 +1,66 @@ +package dom + +// ---------------------------------------------------------------------------- + +// Code type +type Code struct { + Tokens []Token +} + +// ---------------------------------------------------------------------------- + +// CodeBuilder type +type CodeBuilder struct { + code *Code +} + +// NewVar func +func (p *CodeBuilder) NewVar(name string, pv **Var) *CodeBuilder { + return p +} + +// VarRef func +func (p *CodeBuilder) VarRef(v *Var) *CodeBuilder { + return p +} + +// Val func +func (p *CodeBuilder) Val(v Ref) *CodeBuilder { + return p +} + +// Const func +func (p *CodeBuilder) Const(v interface{}) *CodeBuilder { + return p +} + +// Assign func +func (p *CodeBuilder) Assign(n int) *CodeBuilder { + return p +} + +// Call func +func (p *CodeBuilder) Call(n int) *CodeBuilder { + return p +} + +// Defer func +func (p *CodeBuilder) Defer(n int) *CodeBuilder { + return p +} + +// Go func +func (p *CodeBuilder) Go() *CodeBuilder { + return p +} + +// EndStmt func +func (p *CodeBuilder) EndStmt() *CodeBuilder { + return p +} + +// End func +func (p *CodeBuilder) End() { +} + +// ---------------------------------------------------------------------------- diff --git a/dom/package.go b/dom/package.go new file mode 100644 index 00000000..cf8f6ab5 --- /dev/null +++ b/dom/package.go @@ -0,0 +1,123 @@ +package dom + +// ---------------------------------------------------------------------------- + +// Type type +type Type interface { +} + +// ---------------------------------------------------------------------------- + +// Param type +type Param struct { + name string + typ Type + idx int +} + +// Name func +func (p *Param) Name() string { + return p.name +} + +// Type func +func (p *Param) Type() Type { + return p.typ +} + +// Index func +func (p *Param) Index() int { + return p.idx +} + +// ---------------------------------------------------------------------------- + +// Var type +type Var struct { + Param +} + +// SetType func +func (p *Var) SetType(typ Type) *Var { + if p.typ != nil { + if p.typ != typ { + panic("TODO") + } + } else { + p.typ = typ + } + return p +} + +// ---------------------------------------------------------------------------- + +// Func type +type Func struct { + name string + in []*Param + out []*Param + body *Code +} + +// SetResults func +func (p *Func) SetResults(out ...*Param) *Func { + return p +} + +// BodyStart func +func (p *Func) BodyStart(pkg *Package) *CodeBuilder { + return &CodeBuilder{} +} + +// ---------------------------------------------------------------------------- + +// Scope type +type Scope struct { + Parent *Scope +} + +// ---------------------------------------------------------------------------- + +// Package type +type Package struct { + Scope + gidx int +} + +func (p *Package) allocIdx() int { + p.gidx++ + return p.gidx +} + +// NewPkg func +func NewPkg(name string) *Package { + pkg := &Package{} + return pkg +} + +// MaxIndex func +func (p *Package) MaxIndex() int { + return p.gidx + 1 +} + +// Import func +func (p *Package) Import(name, path string) *PkgRef { + return &PkgRef{} +} + +// NewVar func +func (p *Package) NewVar(name string, typ Type) *Var { + return &Var{} +} + +// NewParam func +func (p *Package) NewParam(name string, typ Type) *Param { + return &Param{name: name, typ: typ, idx: p.allocIdx()} +} + +// NewFunc func +func (p *Package) NewFunc(name string, params ...*Param) *Func { + return &Func{} +} + +// ---------------------------------------------------------------------------- diff --git a/dom/pkgref.go b/dom/pkgref.go new file mode 100644 index 00000000..6d92ef1e --- /dev/null +++ b/dom/pkgref.go @@ -0,0 +1,20 @@ +package dom + +// ---------------------------------------------------------------------------- + +// Ref type +type Ref interface { +} + +// ---------------------------------------------------------------------------- + +// PkgRef type +type PkgRef struct { +} + +// Ref func +func (p *PkgRef) Ref(name string) Ref { + return nil +} + +// ---------------------------------------------------------------------------- diff --git a/dom/token.go b/dom/token.go new file mode 100644 index 00000000..09a9a23b --- /dev/null +++ b/dom/token.go @@ -0,0 +1,64 @@ +package dom + +// ---------------------------------------------------------------------------- + +// Token type +type Token interface { + tokenNode() +} + +// VarRefToken type +type VarRefToken struct { + Var *Var +} + +// VarToken type +type VarToken struct { + Var *Var +} + +// ConstToken type +type ConstToken struct { + Value interface{} +} + +// AssignToken type +type AssignToken struct { + N int +} + +// FuncToken type +type FuncToken struct { + Func Ref +} + +// CallToken type +type CallToken struct { + NArg int +} + +// DeferToken type +type DeferToken struct { +} + +// GoToken type +type GoToken struct { +} + +// EndStmtToken type +type EndStmtToken struct { +} + +// ---------------------------------------------------------------------------- + +func (p *VarRefToken) tokenNode() {} +func (p *VarToken) tokenNode() {} +func (p *ConstToken) tokenNode() {} +func (p *AssignToken) tokenNode() {} +func (p *FuncToken) tokenNode() {} +func (p *CallToken) tokenNode() {} +func (p *DeferToken) tokenNode() {} +func (p *GoToken) tokenNode() {} +func (p *EndStmtToken) tokenNode() {} + +// ---------------------------------------------------------------------------- diff --git a/go.mod b/go.mod new file mode 100644 index 00000000..9e4a62eb --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module github.com/goplus/gox + +go 1.14