Extract ModuleGetter interface for dynamic imports (#349)
* Extract ModuleGetter interface for dynamic imports * ModuleGetter: add example in interop doc.
This commit is contained in:
parent
d9b300cb70
commit
3b65ddf2b8
4 changed files with 35 additions and 4 deletions
|
@ -49,7 +49,7 @@ type Compiler struct {
|
|||
symbolTable *SymbolTable
|
||||
scopes []compilationScope
|
||||
scopeIndex int
|
||||
modules *ModuleMap
|
||||
modules ModuleGetter
|
||||
compiledModules map[string]*CompiledFunction
|
||||
allowFileImport bool
|
||||
loops []*loop
|
||||
|
@ -63,7 +63,7 @@ func NewCompiler(
|
|||
file *parser.SourceFile,
|
||||
symbolTable *SymbolTable,
|
||||
constants []Object,
|
||||
modules *ModuleMap,
|
||||
modules ModuleGetter,
|
||||
trace io.Writer,
|
||||
) *Compiler {
|
||||
mainScope := compilationScope{
|
||||
|
|
|
@ -168,6 +168,32 @@ mods.AddSourceModule("double", []byte(`export func(x) { return x * 2 }`))
|
|||
s.SetImports(mods)
|
||||
```
|
||||
|
||||
To dynamically load or generate code for imported modules, implement and
|
||||
provide a `tengo.ModuleGetter`.
|
||||
|
||||
```golang
|
||||
type DynamicModules struct {
|
||||
mods tengo.ModuleGetter
|
||||
fallback func (name string) tengo.Importable
|
||||
}
|
||||
func (dm *DynamicModules) Get(name string) tengo.Importable {
|
||||
if mod := dm.mods.Get(name); mod != nil {
|
||||
return mod
|
||||
}
|
||||
return dm.fallback()
|
||||
}
|
||||
// ...
|
||||
mods := &DynamicModules{
|
||||
mods: stdlib.GetModuleMap("math"),
|
||||
fallback: func(name string) tengo.Importable {
|
||||
src := ... // load or generate src for `name`
|
||||
return &tengo.SourceModule{Src: src}
|
||||
},
|
||||
}
|
||||
s := tengo.NewScript(`foo := import("foo")`)
|
||||
s.SetImports(mods)
|
||||
```
|
||||
|
||||
### Script.SetMaxAllocs(n int64)
|
||||
|
||||
SetMaxAllocs sets the maximum number of object allocations. Note this is a
|
||||
|
|
|
@ -6,6 +6,11 @@ type Importable interface {
|
|||
Import(moduleName string) (interface{}, error)
|
||||
}
|
||||
|
||||
// ModuleGetter enables implementing dynamic module loading.
|
||||
type ModuleGetter interface {
|
||||
Get(name string) Importable
|
||||
}
|
||||
|
||||
// ModuleMap represents a set of named modules. Use NewModuleMap to create a
|
||||
// new module map.
|
||||
type ModuleMap struct {
|
||||
|
|
|
@ -12,7 +12,7 @@ import (
|
|||
// Script can simplify compilation and execution of embedded scripts.
|
||||
type Script struct {
|
||||
variables map[string]*Variable
|
||||
modules *ModuleMap
|
||||
modules ModuleGetter
|
||||
input []byte
|
||||
maxAllocs int64
|
||||
maxConstObjects int
|
||||
|
@ -54,7 +54,7 @@ func (s *Script) Remove(name string) bool {
|
|||
}
|
||||
|
||||
// SetImports sets import modules.
|
||||
func (s *Script) SetImports(modules *ModuleMap) {
|
||||
func (s *Script) SetImports(modules ModuleGetter) {
|
||||
s.modules = modules
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue