From 2980523a5b0d270762b0d8c93a271cd0ea4de637 Mon Sep 17 00:00:00 2001 From: James Shubin Date: Mon, 22 Jul 2019 06:46:04 -0400 Subject: [PATCH] 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. --- lang/interfaces/func.go | 25 +++++++++++++++++++++++++ lang/structs.go | 14 ++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/lang/interfaces/func.go b/lang/interfaces/func.go index fd88205d..948c49bb 100644 --- a/lang/interfaces/func.go +++ b/lang/interfaces/func.go @@ -108,3 +108,28 @@ type NamedArgsFunc interface { // the util.NumToAlpha function when this interface isn't implemented... 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) +} diff --git a/lang/structs.go b/lang/structs.go index 6eddba94..4d14c113 100644 --- a/lang/structs.go +++ b/lang/structs.go @@ -6676,6 +6676,13 @@ func (obj *ExprFunc) Init(data *interfaces.Data) error { return fmt.Errorf("func is being re-built") } 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 { @@ -6755,6 +6762,13 @@ func (obj *ExprFunc) Copy() (interfaces.Expr, error) { var function interfaces.Func if obj.Function != nil { 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 }