type Todo struct {
Name string
Done bool
}
type Todos implements<Mutexed (Slice .Todo)> {
// it reads as a mutexed list of todo.
}
func (t *Todos) Hello(){fmt.Println("Hello")}
template Mutexed<.Name> struct {
lock *sync.Mutex
embed <.Name>
}
<range $m := .Methods> func (m Mutexed<$.Name>) <$m.Name>(<$m.Params>) <$m.Out> {
lock.Lock()
defer lock.Unlock()
m.embed.<$m.GetName>(<$m.Args>)
}
template <.Name>Slice struct {
items []<.Name>
}
func (s <.Name>Slice) Push(item <.Name>) int {
s.items = append(s.items, item)
return len(s.items)
}
func (s <.Name>Slice) Index(item <.Name>) int {
for i, items := range s.items {
if item == search {
return i
}
}
return -1
}
func (s <.Name>Slice) RemoveAt(i index) int {
s.items = append(s.items[:i], s.items[i+1:]...)
}
func (s <.Name>Slice) Remove(item <.Name>) int {
if i:= s.Index(item); i > -1 {
s.RemoveAt(i)
return i
}
return -1
}
It produces
type Todo struct {
Name string
Done bool
}
type TodoSlice struct {
items []Todo
}
func (s TodoSlice) Push(item Todo) int {
s.items = append(s.items, item)
return len(s.items)
}
func (s TodoSlice) Index(item Todo) int {
for i, items := range s.items {
if item == search {
return i
}
}
return -1
}
func (s TodoSlice) RemoveAt(i index) int {
s.items = append(s.items[:i], s.items[i+1:]...)
}
func (s TodoSlice) Remove(item Todo) int {
if i:= s.Index(item); i > -1 {
s.RemoveAt(i)
return i
}
return -1
}
// while this is compatible with its local contracts,
// it will work and still takes advantages of concrete types exported by consumed package.
type MutexedTodoSlice struct {
lock *sync.Mutex
embed TodoSlice
}
func (m MutexedTodoSlice) Push((item Todo)) int {
lock.Lock()
defer lock.Unlock()
m.embed.<$m.GetName>(<$m.Args>)
}
func (m MutexedTodoSlice) Index((item Todo)) int {
lock.Lock()
defer lock.Unlock()
m.embed.<$m.GetName>(<$m.Args>)
}
func (m MutexedTodoSlice) RemoveAt((i index)) int {
lock.Lock()
defer lock.Unlock()
m.embed.<$m.GetName>(<$m.Args>)
}
func (m MutexedTodoSlice) Remove((item Todo)) int {
lock.Lock()
defer lock.Unlock()
m.embed.<$m.GetName>(<$m.Args>)
}
type Todos struct {
MutexedTodoSlice
// it reads as a mutexed list of todo.
}
func (t *Todos) Hello(){fmt.Println("Hello")}
Still some work to be done, but you got the idea!
It implements a whole tokenizer/interpreter of go code (almost),
a bit like go/ast, but its way more lighter(so far),
the idea being to be able add more customization based on that.
The package currently tokenize a source code,
interprets it into declarations,
manipulates nodes to use a regular go template.Template
to execute the generation,
finally it builds a go file and output its.
It adds new syntaxes such as
implements, which produces a struct
type Todos implements<Mutexed (Slice .Todo)>
template, to define virutal structs type
template Mutexed<.Name> struct
Then the systems understands instructions blocks
such as "regular" method declaration to template
func (s <.Name>Slice) Push(item <.Name>) int {
s.items = append(s.items, item)
return len(s.items)
}
And pure template expressions,
(although, at that moment, its a limited to methods only)
<range $m := .Methods> func (m Mutexed<$.Name>) <$m.Name>(<$m.Params>) <$m.Out> {
lock.Lock()
defer lock.Unlock()
m.embed.<$m.GetName>(<$m.Args>)
}
I plan to be able to declare func to inject into template instructions,
so you ll be able to do pretty much anything i think.
I m not sure the new syntaxes are correct,
but i d that this project is the starting point of an effort to
improve go coding experience.
In that goal, any comments are welcome!
Last thing, at that very moment the package is extremly new,
don t expect too much,
it did work with the demo file https://github.com/mh-cbon/gigo/blob/master/demo.gigo.go ;)
~~ Happy coding !
type Todos implements<:Mutexed (Slice .Todo "Name")>
The Slice Type will handle the extra params to generate a FindByName method.
// range over args to produce new FindBy methods
<:range $a := .Args> func (m <:$.Name>Slice) FindBy<:$a>(<:$a> <:$.ArgType $a>) (<:$.Name>,bool) {
for i, items := range s.items {
if item.<:$a> == <:$a> {
return item, true
}
}
return <:$.Name>{}, false
}
package tomate
type tomate struct qsdqd{} // bad
unexpected token
In file=<noname> At=3:19
Found=wordToken wanted=[bracketOpenToken]
...
5 package tomate
6 type tomate struct qsdqd{}
---------------------↑
...
0
1 type Todos implements<:Mutexed (Slice, .Todo "Name"):> {
✘- ↑↑↑ ???
2 // it reads as a mutexed list of todo.
3 }
...
panic: in gigo template: gigo:3: unexpected "," in operand at line 3:-1 [recovered]
panic: in gigo template: gigo:3: unexpected "," in operand at line 3:-1