diff options
Diffstat (limited to 'vendor/github.com/d5/tengo/v2/compiler.go')
-rw-r--r-- | vendor/github.com/d5/tengo/v2/compiler.go | 42 |
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)) |