google / starlark-go

Starlark in Go: the Starlark configuration language, implemented in Go
BSD 3-Clause "New" or "Revised" License
2.31k stars 210 forks source link

Question: Targeting AST for execution #460

Closed andrewrowe-wk closed 1 year ago

andrewrowe-wk commented 1 year ago

Hello!

Are there any examples of targeting the starlark-go AST format, and executing that, as opposed to executing a starlark script itself?

For example, I'm wondering if you can do things like "visit and patch" the AST nodes (go expr library): https://expr.medv.io/docs/Visitor-and-Patch

Additionally, can a starlark-go program be ingested/exported as an AST? For example(source):

MemberNode{
    Node: MemberNode{
        Node: IdentifierNode{
            Value: "products",
            Deref: false,
            FieldIndex: []int{
                0,
            },
            Method: false,
            MethodIndex: 0,
        },
        Property: IntegerNode{
            Value: 0,
        },
        Name: "",
        Optional: false,
        Deref: false,
        FieldIndex: []int{},
        Method: false,
        MethodIndex: 0,
    },
    Property: StringNode{
        Value: "Name",
    },
    Name: "Name",
    Optional: false,
    Deref: false,
    FieldIndex: []int{
        0,
    },
    Method: false,
    MethodIndex: 0,
}

Wonderful, library!

Thank you!

adonovan commented 1 year ago

Are there any examples of targeting the starlark-go AST format, and executing that, as opposed to executing a starlark script itself?

No. But if the cost of parsing/resolving/compiling a script is too high for you, then you can cache the results of compilation and skip those steps when you reecounter the same script.

For example, I'm wondering if you can do things like "visit and patch" the AST nodes (go expr library): https://expr.medv.io/docs/Visitor-and-Patch

There's a Walk function to visit the tree: https://pkg.go.dev/go.starlark.net/syntax#Walk But there isn't a patch function to modify each subtree.

Additionally, can a starlark-go program be ingested/exported as an AST? For example(source):

There's no prettyprinter for the tree yet. You could study https://github.com/bazelbuild/buildtools/blob/master/build/print.go if you're interested in building one.

You can print the bytecode using the -disassemble flag, but don't forget that it's not a stable public interface.

$ starlark -disassemble <(echo 'print(1)')
Function <toplevel>: (1 blocks, 10 bytes)
0:
                    ; 63:1:1
    0   universal   0   ; print
    2   constant    0   ; 1
                    ; 63:1:6
    4   call        256 ; 1 pos, 0 named
    7   pop
    8   none
    9   return
1
andrewrowe-wk commented 1 year ago

Thank you! This is exactly what I needed.