Skip to content

Commit

Permalink
github.com/goplus/gox
Browse files Browse the repository at this point in the history
  • Loading branch information
xushiwei committed Mar 6, 2021
1 parent 970ff17 commit cba22db
Show file tree
Hide file tree
Showing 7 changed files with 367 additions and 2 deletions.
53 changes: 51 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -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)
}
```
40 changes: 40 additions & 0 deletions conv/goconv.go
Original file line number Diff line number Diff line change
@@ -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)
}

// ----------------------------------------------------------------------------
66 changes: 66 additions & 0 deletions dom/codebuild.go
Original file line number Diff line number Diff line change
@@ -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() {
}

// ----------------------------------------------------------------------------
123 changes: 123 additions & 0 deletions dom/package.go
Original file line number Diff line number Diff line change
@@ -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{}
}

// ----------------------------------------------------------------------------
20 changes: 20 additions & 0 deletions dom/pkgref.go
Original file line number Diff line number Diff line change
@@ -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
}

// ----------------------------------------------------------------------------
64 changes: 64 additions & 0 deletions dom/token.go
Original file line number Diff line number Diff line change
@@ -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() {}

// ----------------------------------------------------------------------------
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module github.com/goplus/gox

go 1.14

0 comments on commit cba22db

Please sign in to comment.