feature request: add metadata in evaluable
skyf0cker opened this issue · 5 comments
I use this project in my job and solve a lot problems. Really appreciate for it.
But i found there are some scences that i need to get the metadata of parsed evaluable.
For example:
in our system, we allow users to configure their expression with functions and operators our language supported like a rule engine.
Apperently we want to check if user's input is valid (not syntax but business logic) but i found it is hard to get metadata by gval now, like which function does this expr use and the params pass by user.
From a legitimate point of view, this is an ability that parse module should support instead of user use init language and context to hack it.
I have read the other issues and found this problem also made other guys confused like #75
I have tried to solve it by adding wrap gval.Evaluable with a metadata, it looks fine to solve this problem. if you guys agree this request, i can work on it.
// EvaluableFunc evaluates given parameter
type EvaluableFunc func(c context.Context, parameter interface{}) (interface{}, error)
// when parse the specific token, we can pour metadata into Evaluable
type Evaluable struct {
EvaluableFunc
metadata *EvaluableMetadata
}
expect your replies. @generikvault @darh @impl
Hi skyf0cker,
I think the meta data should be collected via the context.Context inside the parser closures. This should be an optional feature that can be activated by swapping standard components with analytic versions of these components.
Something like
lang := gval.Full(gval.VariableAnalytics())
vars, ctx = gval.VariableAnalyticContext(ctx)
eval, err := lang.NewEvaluableWithContext(ctx, ...)
variableList := vars.VariableNames()
This would preserve backwards compabillity for calls like eval(ctx, x)
When I am trying to use gval.VariableAnalytics() in my code, I am getting compilation error with VariableAnalytics not declared by package gval
Please can you share more on how I can get list of functions and variables from expression before evaluation.
AnalyticContext
this has not been implemented. But i'm working on this recently.
i'm trying to implement it by the method you recommended before. Can you assign this issue to me?
@generikvault
Btw, i don't think it is expandable if we just implement the variable name analystic. Instead analystic should be a general ability for parsing stuff including operater, functions, literal values....
If we can build a tree like ast tree through the context, this will be solved maybe. We will get a pointer points to the root node of the ast tree when invoke gval.AnalyticContext
and the pointer is injected into the context. Then metadata will be added in the parsing process.
for example:
// here we open the parse analystic
lang := gval.Full(gval.ParseAnalystic())
// inject the metadata pointer(a tree node) into ctx
root, ctx = gval.AnalyticContext(ctx)
// build the tree through context when parsing
eval, err := lang.NewEvaluableWithContext(ctx, ...)
// here we can access the metadata by traversing the root node
root.traverse(func(node *gval.Metadata) {
// access to the parsing metadata
})
But the structure of tree node is hard to be defined because of all kinds of operator like postfixOperator, prefixOperator.
I cannot figure out how to build the tree considering all these operators.
Hope that i can get your help.
Anyway if this is not a good method, i will simply implement the variable name analystic
@skyf0cker Do you know if there is any other alternative for getting list of variables and functions from expression. It will be very helpful.