summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/d5/tengo/v2/compiler.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/d5/tengo/v2/compiler.go')
-rw-r--r--vendor/github.com/d5/tengo/v2/compiler.go42
1 files changed, 28 insertions, 14 deletions
diff --git a/vendor/github.com/d5/tengo/v2/compiler.go b/vendor/github.com/d5/tengo/v2/compiler.go
index eb686ed6..cb1c8f30 100644
--- a/vendor/github.com/d5/tengo/v2/compiler.go
+++ b/vendor/github.com/d5/tengo/v2/compiler.go
@@ -44,6 +44,7 @@ type Compiler struct {
file *parser.SourceFile
parent *Compiler
modulePath string
+ importDir string
constants []Object
symbolTable *SymbolTable
scopes []compilationScope
@@ -520,7 +521,7 @@ func (c *Compiler) Compile(node parser.Node) error {
switch v := v.(type) {
case []byte: // module written in Tengo
compiled, err := c.compileModule(node,
- node.ModuleName, node.ModuleName, v)
+ node.ModuleName, v, false)
if err != nil {
return err
}
@@ -537,24 +538,20 @@ func (c *Compiler) Compile(node parser.Node) error {
moduleName += ".tengo"
}
- modulePath, err := filepath.Abs(moduleName)
+ modulePath, err := filepath.Abs(
+ filepath.Join(c.importDir, moduleName))
if err != nil {
return c.errorf(node, "module file path error: %s",
err.Error())
}
- if err := c.checkCyclicImports(node, modulePath); err != nil {
- return err
- }
-
- moduleSrc, err := ioutil.ReadFile(moduleName)
+ moduleSrc, err := ioutil.ReadFile(modulePath)
if err != nil {
return c.errorf(node, "module file read error: %s",
err.Error())
}
- compiled, err := c.compileModule(node,
- moduleName, modulePath, moduleSrc)
+ compiled, err := c.compileModule(node, modulePath, moduleSrc, true)
if err != nil {
return err
}
@@ -634,6 +631,11 @@ func (c *Compiler) EnableFileImport(enable bool) {
c.allowFileImport = enable
}
+// SetImportDir sets the initial import directory path for file imports.
+func (c *Compiler) SetImportDir(dir string) {
+ c.importDir = dir
+}
+
func (c *Compiler) compileAssign(
node parser.Node,
lhs, rhs []parser.Expr,
@@ -847,8 +849,8 @@ func (c *Compiler) compileForInStmt(stmt *parser.ForInStmt) error {
// ... body ...
// }
//
- // ":it" is a local variable but will be conflict with other user variables
- // because character ":" is not allowed.
+ // ":it" is a local variable but it will not conflict with other user variables
+ // because character ":" is not allowed in the variable names.
// init
// :it = iterator(iterable)
@@ -893,6 +895,7 @@ func (c *Compiler) compileForInStmt(stmt *parser.ForInStmt) error {
if keySymbol.Scope == ScopeGlobal {
c.emit(stmt, parser.OpSetGlobal, keySymbol.Index)
} else {
+ keySymbol.LocalAssigned = true
c.emit(stmt, parser.OpDefineLocal, keySymbol.Index)
}
}
@@ -909,6 +912,7 @@ func (c *Compiler) compileForInStmt(stmt *parser.ForInStmt) error {
if valueSymbol.Scope == ScopeGlobal {
c.emit(stmt, parser.OpSetGlobal, valueSymbol.Index)
} else {
+ valueSymbol.LocalAssigned = true
c.emit(stmt, parser.OpDefineLocal, valueSymbol.Index)
}
}
@@ -955,8 +959,9 @@ func (c *Compiler) checkCyclicImports(
func (c *Compiler) compileModule(
node parser.Node,
- moduleName, modulePath string,
+ modulePath string,
src []byte,
+ isFile bool,
) (*CompiledFunction, error) {
if err := c.checkCyclicImports(node, modulePath); err != nil {
return nil, err
@@ -967,7 +972,7 @@ func (c *Compiler) compileModule(
return compiledModule, nil
}
- modFile := c.file.Set().AddFile(moduleName, -1, len(src))
+ modFile := c.file.Set().AddFile(modulePath, -1, len(src))
p := parser.NewParser(modFile, src, nil)
file, err := p.ParseFile()
if err != nil {
@@ -984,7 +989,7 @@ func (c *Compiler) compileModule(
symbolTable = symbolTable.Fork(false)
// compile module
- moduleCompiler := c.fork(modFile, modulePath, symbolTable)
+ moduleCompiler := c.fork(modFile, modulePath, symbolTable, isFile)
if err := moduleCompiler.Compile(file); err != nil {
return nil, err
}
@@ -1082,10 +1087,16 @@ func (c *Compiler) fork(
file *parser.SourceFile,
modulePath string,
symbolTable *SymbolTable,
+ isFile bool,
) *Compiler {
child := NewCompiler(file, symbolTable, nil, c.modules, c.trace)
child.modulePath = modulePath // module file path
child.parent = c // parent to set to current compiler
+ child.allowFileImport = c.allowFileImport
+ child.importDir = c.importDir
+ if isFile && c.importDir != "" {
+ child.importDir = filepath.Dir(modulePath)
+ }
return child
}
@@ -1192,6 +1203,7 @@ func (c *Compiler) optimizeFunc(node parser.Node) {
var lastOp parser.Opcode
var appendReturn bool
endPos := len(c.scopes[c.scopeIndex].Instructions)
+ newEndPost := len(newInsts)
iterateInstructions(newInsts,
func(pos int, opcode parser.Opcode, operands []int) bool {
switch opcode {
@@ -1204,6 +1216,8 @@ func (c *Compiler) optimizeFunc(node parser.Node) {
} else if endPos == operands[0] {
// there's a jump instruction that jumps to the end of
// function compiler should append "return".
+ copy(newInsts[pos:],
+ MakeInstruction(opcode, newEndPost))
appendReturn = true
} else {
panic(fmt.Errorf("invalid jump position: %d", newDst))