123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262 |
- package generator
- import (
- bytes "bytes"
- "fmt"
- "os/exec"
- "reflect"
- "strings"
- "git.eugeniocarvalho.dev/eugeniucarvalho/utils"
- )
- var (
- LitTemplates = map[string]string{
- "string": " '%s' ",
- "int": " %d ",
- "int8": " %d ",
- "int16": " %d ",
- "int32": " %d ",
- "int64": " %d ",
- "float32": " %.2f ",
- "float64": " %.2f ",
- "bool": " %.2f ",
- }
- )
- type File struct {
- Group
- Name string
- }
- func NewFile(file string) *File {
- return &File{Name: file}
- }
- // Entidade representa menor unidade de Statement.
- type Stmt struct {
- Group
- Value interface{}
- Template string
- Separete string
- }
- // Root node group of Statement.
- type Group struct {
- Stmts []CodeInterface
- }
- // Metodo realiza a renderização de um grupo e todos os seus statements.
- func (g *Group) Render(buffer *bytes.Buffer) (err error) {
- for _, s := range g.Stmts {
- err = s.Render(buffer)
- }
- return
- }
- // Metodo Gera a string do arquivo.
- func (g *Group) GoString() string {
- buf := bytes.Buffer{}
- if err := g.Render(&buf); err != nil {
- panic(err)
- }
- return buf.String()
- }
- func NewGroup() *Group {
- return &Group{}
- }
- func (f *File) Save() (err error) {
- fmt.Println("Save in :", f.Name)
- if err = utils.FilePutContents(f.Name, f.GoString(), 777); err != nil {
- return
- }
- // Formate code with https://www.npmjs.com/package/typescript-formatter
- var out bytes.Buffer
- cmd := exec.Command("tsfmt", "-r", f.Name)
- cmd.Stdin = strings.NewReader("")
- cmd.Stdout = &out
- if err = cmd.Run(); err != nil {
- panic(err)
- }
- fmt.Printf("in all caps: %q\n", out.String())
- return
- }
- func (s *Stmt) Render(buffer *bytes.Buffer) (err error) {
- // fmt.Println("Render stmt")
- // spew.Dump(s)
- var (
- Value interface{}
- bufLocal *bytes.Buffer
- bufLocalMaster = &bytes.Buffer{}
- wbv string
- )
- if len(s.Stmts) > 0 {
- for _, stmt := range s.Stmts {
- bufLocal = &bytes.Buffer{}
- stmt.Render(bufLocal)
- bufLocalMaster.WriteString(bufLocal.String())
- }
- Value = bufLocalMaster.String()
- } else {
- Value = s.Value
- }
- if strings.Contains(s.Template, "%") {
- // switch Value.(type) {
- // case string:
- // wbv = fmt.Sprintf(s.Template, Value.(string))
- // case :
- // }
- wbv = fmt.Sprintf(s.Template, Value)
- } else {
- wbv = s.Template
- }
- buffer.WriteString(wbv)
- return
- }
- func (g *Group) Lit(stmt interface{}) *Group {
- var (
- Template string
- typ = reflect.TypeOf(stmt).Name()
- )
- if t, ok := LitTemplates[typ]; ok {
- Template = t
- } else {
- Template = " %v "
- }
- s := &Stmt{
- Template: Template,
- Value: stmt,
- }
- g.Stmts = append(g.Stmts, s)
- return g
- }
- func Lit(stmt interface{}) *Group {
- return NewGroup().Lit(stmt)
- }
- func (g *Group) Comment(stmt string) *Group {
- var (
- Template string
- )
- if strings.Contains(stmt, "\n") {
- Template = " \n/*\n%s\n*/\n "
- } else {
- Template = " \n//%s\n "
- }
- s := &Stmt{
- Template: Template,
- Value: stmt,
- }
- g.Stmts = append(g.Stmts, s)
- return g
- }
- func Comment(stmt string) *Group {
- return NewGroup().Comment(stmt)
- }
- func (g *Group) Params(params ...CodeInterface) *Group {
- s := &Stmt{Template: " (%s) ", Group: Group{Stmts: params}, Value: "params"}
- g.Stmts = append(g.Stmts, s)
- return g
- }
- func Params(params ...CodeInterface) *Group {
- return NewGroup().Params(params...)
- }
- func (g *Group) Op(op string) *Group {
- s := &Stmt{Template: " %s ", Value: op}
- g.Stmts = append(g.Stmts, s)
- return g
- }
- func Op(op string) *Group {
- return NewGroup().Op(op)
- }
- func (g *Group) Block(stmts ...CodeInterface) *Group {
- s := &Stmt{Template: " {%s}\n ", Group: Group{Stmts: stmts}, Value: "block"}
- g.Stmts = append(g.Stmts, s)
- return g
- }
- func Block(stmts ...CodeInterface) *Group {
- return NewGroup().Block(stmts...)
- }
- func (g *Group) Call(params CodeInterface) *Group {
- s := &Stmt{Template: " (%s) ", Group: Group{Stmts: []CodeInterface{params}}, Value: "call"}
- g.Stmts = append(g.Stmts, s)
- return g
- }
- func Call(params CodeInterface) *Group {
- return NewGroup().Call(params)
- }
- func (g *Group) Id(stmt string) *Group {
- s := &Stmt{Template: " %s ", Value: stmt}
- g.Stmts = append(g.Stmts, s)
- return g
- }
- func Id(stmt string) *Group {
- return NewGroup().Id(stmt)
- }
- func (g *Group) Index(index CodeInterface) *Group {
- s := &Stmt{Template: " [%s] ", Group: Group{Stmts: []CodeInterface{index}}, Value: "index"}
- g.Stmts = append(g.Stmts, s)
- return g
- }
- func Index(index CodeInterface) *Group {
- return NewGroup().Index(index)
- }
- func (g *Group) Produce(f func(g *Group)) *Group {
- s := &Stmt{
- Template: " %s ",
- Value: f,
- }
- g.Stmts = append(g.Stmts, s)
- return g
- }
- func Produce(f func(g *Group)) *Group {
- return NewGroup().Produce(f)
- }
- type CodeInterface interface {
- Render(buffer *bytes.Buffer) error
- GoString() string
- Block(stmts ...CodeInterface) *Group
- Call(params CodeInterface) *Group
- Comment(stmt string) *Group
- Id(stmt string) *Group
- Index(index CodeInterface) *Group
- Lit(stmt interface{}) *Group
- Op(op string) *Group
- Params(params ...CodeInterface) *Group
- Produce(f func(g *Group)) *Group
- }
|