Skip to content

Commit

Permalink
Extract ModuleGetter interface for dynamic imports (#349)
Browse files Browse the repository at this point in the history
* Extract ModuleGetter interface for dynamic imports

* ModuleGetter: add example in interop doc.
  • Loading branch information
bfreis authored Nov 7, 2021
1 parent d9b300c commit 3b65ddf
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 4 deletions.
4 changes: 2 additions & 2 deletions compiler.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -63,7 +63,7 @@ func NewCompiler(
file *parser.SourceFile,
symbolTable *SymbolTable,
constants []Object,
modules *ModuleMap,
modules ModuleGetter,
trace io.Writer,
) *Compiler {
mainScope := compilationScope{
Expand Down
26 changes: 26 additions & 0 deletions docs/interoperability.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 5 additions & 0 deletions modules.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
4 changes: 2 additions & 2 deletions script.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
}

Expand Down

0 comments on commit 3b65ddf

Please sign in to comment.