lang: Add a new function interface to accept data
Sometimes certain internal functions might want to get some data from the AST or from something relating to the state of the language. This adds a method to pass in that data. For now it's a very simple method, but we could generalize it in the future if it becomes more useful.
This commit is contained in:
@@ -108,3 +108,28 @@ type NamedArgsFunc interface {
|
|||||||
// the util.NumToAlpha function when this interface isn't implemented...
|
// the util.NumToAlpha function when this interface isn't implemented...
|
||||||
ArgGen(int) (string, error)
|
ArgGen(int) (string, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FuncData is some data that is passed into the function during compilation. It
|
||||||
|
// helps provide some context about the AST and the deploy for functions that
|
||||||
|
// might need it.
|
||||||
|
// TODO: Consider combining this with the existing Data struct or more of it...
|
||||||
|
// TODO: Do we want to add line/col/file values here, and generalize this?
|
||||||
|
type FuncData struct {
|
||||||
|
|
||||||
|
// Base directory (absolute path) that the running code is in. This is a
|
||||||
|
// copy of the value from the Expr and Stmt Data struct for Init.
|
||||||
|
Base string
|
||||||
|
}
|
||||||
|
|
||||||
|
// DataFunc is a function that accepts some context from the AST and deploy
|
||||||
|
// before Init and runtime. If you don't wish to accept this data, then don't
|
||||||
|
// implement this method and you won't get any. This is mostly useful for
|
||||||
|
// special functions that are useful in core.
|
||||||
|
// TODO: This could be replaced if a func ever needs a SetScope method...
|
||||||
|
type DataFunc interface {
|
||||||
|
Func // implement everything in Func but add the additional requirements
|
||||||
|
|
||||||
|
// SetData is used by the language to pass our function some code-level
|
||||||
|
// context.
|
||||||
|
SetData(*FuncData)
|
||||||
|
}
|
||||||
|
|||||||
@@ -6676,6 +6676,13 @@ func (obj *ExprFunc) Init(data *interfaces.Data) error {
|
|||||||
return fmt.Errorf("func is being re-built")
|
return fmt.Errorf("func is being re-built")
|
||||||
}
|
}
|
||||||
obj.function = obj.Function() // build it
|
obj.function = obj.Function() // build it
|
||||||
|
// pass in some data to the function
|
||||||
|
// TODO: do we want to pass in the full obj.data instead ?
|
||||||
|
if dataFunc, ok := obj.function.(interfaces.DataFunc); ok {
|
||||||
|
dataFunc.SetData(&interfaces.FuncData{
|
||||||
|
Base: obj.data.Base,
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(obj.Values) > 0 {
|
if len(obj.Values) > 0 {
|
||||||
@@ -6755,6 +6762,13 @@ func (obj *ExprFunc) Copy() (interfaces.Expr, error) {
|
|||||||
var function interfaces.Func
|
var function interfaces.Func
|
||||||
if obj.Function != nil {
|
if obj.Function != nil {
|
||||||
function = obj.Function() // force re-build a new pointer here!
|
function = obj.Function() // force re-build a new pointer here!
|
||||||
|
// pass in some data to the function
|
||||||
|
// TODO: do we want to pass in the full obj.data instead ?
|
||||||
|
if dataFunc, ok := function.(interfaces.DataFunc); ok {
|
||||||
|
dataFunc.SetData(&interfaces.FuncData{
|
||||||
|
Base: obj.data.Base,
|
||||||
|
})
|
||||||
|
}
|
||||||
copied = true
|
copied = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user