Yes, it could be extracted to a separate module, but package  
github.com/cosmos72/gomacro/ast2 already has very few dependencies.
In particular, it does *not* depend on the Go interpreter 
github.com/cosmos72/gomacro/fast

The integer arguments are simple:
`y.Get(0)` means "get the first (index = 0 ) child node of y"
`y.Get(1)` means "get the second (index = 1) child node of y"
and so on.

The interface `ast2.Ast` also has methods to query the number of children, 
and to modify the AST:
```
type Ast interface {
        Interface() interface{}
        Op() token.Token
        Size() int
        Get(i int) Ast
        Set(i int, child Ast)
        New() Ast // returns a copy of Ast. the children are not copied
    }
```

On Wednesday, October 14, 2020 at 8:06:57 PM UTC+2 cpu...@gmail.com wrote:

> Hi Max,
>
> Great answer, thank you! Exactly what I was looking for in terms of a 
> fluid api, no need for parsing the selectors.
>
> The API is not quite suitable for public consumption. I feel this could be 
> a great success if extracted into its own module.
> Could you kindly clarify what the meaning of the int parameters is, i.e. 
> is there a general rule or does it depend on the function?
>
> I‘ll play a bit with it and will comment on GH if ok.
>
> Much appreciated,
> Andi
>
> On Wednesday, October 14, 2020 at 6:09:08 PM UTC+2 Max wrote:
>
>> I can only agree, traversing or navigating Go AST is cumbersome for at 
>> least two reasons:
>> 1. each type has its own fields - no uniform API is available
>> 2. you often need type assertions on fields because they have interface 
>> type instead of concrete type
>>
>> I developed a wrapper around them to mitigate these problems for my Go 
>> interpreter https://github.com/cosmos72/gomacro
>> If you are interested, it is the package 
>> https://github.com/cosmos72/gomacro/tree/master/ast2
>>
>> You may find it helps by providing an uniform API and removing the need 
>> for type assertions, but it still requires compile-time code,
>> not CSS-style strings that can be created at runtime.
>>
>> A quick example:  this uses plain go/ast
>> ```
>> package main
>> import (
>>     "fmt"
>>     "go/ast"
>>     "go/parser"
>> )
>> func main() {
>>     x, _ := parser.ParseExpr("foo[1 + 2 * 3]")
>>     // we want to extract the "3"
>>     var three string = 
>> x.(*ast.IndexExpr).Index.(*ast.BinaryExpr).Y.(*ast.BinaryExpr).Y.(*ast.BasicLit).Value
>>     fmt.Printf("%s\n", three) // prints 3
>> }
>> ```
>> while this is the equivalent using github.com/cosmos72/gomacro/ast2
>> ```
>> package main
>> import (
>>     "fmt"
>>     "go/ast"
>>     "go/parser"
>>     "github.com/cosmos72/gomacro/ast2"
>> )
>> func main() {
>>     x, _ := parser.ParseExpr("foo[1 + 2 * 3]")
>>     y := ast2.AnyToAst(x, nil) // wrap the existing AST. does not 
>> allocate memory.
>>     
>>     ythree := y.Get(1).Get(1).Get(1) // extract the "3" as ast2.Node
>>
>>     // now unwrap it, getting the *ast.BasicLit and the Value inside it
>>     var three string = ast2.ToBasicLit(ythree).Value
>>     fmt.Printf("%s\n", three) // prints 3
>> }
>> ```
>>
>> On Tuesday, October 13, 2020 at 9:37:21 AM UTC+2 cpu...@gmail.com wrote:
>>
>>> Good morning.
>>>
>>> I've recently found myself writing a code generator for dynamic 
>>> interface composition at runtime. It became ugly and I had to pass in quite 
>>> a number of parameters that should have been available from reading the 
>>> source code.
>>>
>>> In a second attempt I've reimplemented the generator using stringer-like 
>>> AST handling. It worked well but was cumbersome to code.
>>>
>>> Now an idea surfaced: wouldn't it make sense to implement a selector 
>>> interface on top of the golang AST, something like CSS or JQ selectors but 
>>> targeted at the go language constructs? I've stumbled across Guru but it 
>>> does seem to target a slightly different use case.
>>>
>>> Is anybody aware of such a selector lib/module or does the idea even 
>>> sound interesting?
>>>
>>> Cheers,
>>> Andi
>>>
>>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/a335ed5e-782b-4f55-baf3-e801b9b9f007n%40googlegroups.com.

Reply via email to