fix internal package issue (#241)

* fix internal package issue

* ExampleSimple -> Example
This commit is contained in:
daniel 2019-12-24 07:42:30 -08:00 committed by GitHub
parent 7cb058b564
commit a9a233a750
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
40 changed files with 1187 additions and 1137 deletions

View file

@ -121,7 +121,6 @@ each([a, b, c, d], func(x) {
mul := compiled.Get("mul") mul := compiled.Get("mul")
fmt.Println(sum, mul) // "22 288" fmt.Println(sum, mul) // "22 288"
} }
``` ```
## References ## References

View file

@ -6,12 +6,12 @@ import (
"io" "io"
"reflect" "reflect"
"github.com/d5/tengo/internal" "github.com/d5/tengo/parser"
) )
// Bytecode is a compiled instructions and constants. // Bytecode is a compiled instructions and constants.
type Bytecode struct { type Bytecode struct {
FileSet *internal.SourceFileSet FileSet *parser.SourceFileSet
MainFunction *CompiledFunction MainFunction *CompiledFunction
Constants []Object Constants []Object
} }
@ -40,7 +40,7 @@ func (b *Bytecode) CountObjects() int {
// FormatInstructions returns human readable string representations of // FormatInstructions returns human readable string representations of
// compiled instructions. // compiled instructions.
func (b *Bytecode) FormatInstructions() []string { func (b *Bytecode) FormatInstructions() []string {
return internal.FormatInstructions(b.MainFunction.Instructions, 0) return FormatInstructions(b.MainFunction.Instructions, 0)
} }
// FormatConstants returns human readable string representations of // FormatConstants returns human readable string representations of
@ -51,7 +51,7 @@ func (b *Bytecode) FormatConstants() (output []string) {
case *CompiledFunction: case *CompiledFunction:
output = append(output, fmt.Sprintf( output = append(output, fmt.Sprintf(
"[% 3d] (Compiled Function|%p)", cidx, &cn)) "[% 3d] (Compiled Function|%p)", cidx, &cn))
for _, l := range internal.FormatInstructions(cn.Instructions, 0) { for _, l := range FormatInstructions(cn.Instructions, 0) {
output = append(output, fmt.Sprintf(" %s", l)) output = append(output, fmt.Sprintf(" %s", l))
} }
default: default:
@ -239,25 +239,25 @@ func updateConstIndexes(insts []byte, indexMap map[int]int) {
i := 0 i := 0
for i < len(insts) { for i < len(insts) {
op := insts[i] op := insts[i]
numOperands := internal.OpcodeOperands[op] numOperands := parser.OpcodeOperands[op]
_, read := internal.ReadOperands(numOperands, insts[i+1:]) _, read := parser.ReadOperands(numOperands, insts[i+1:])
switch op { switch op {
case internal.OpConstant: case parser.OpConstant:
curIdx := int(insts[i+2]) | int(insts[i+1])<<8 curIdx := int(insts[i+2]) | int(insts[i+1])<<8
newIdx, ok := indexMap[curIdx] newIdx, ok := indexMap[curIdx]
if !ok { if !ok {
panic(fmt.Errorf("constant index not found: %d", curIdx)) panic(fmt.Errorf("constant index not found: %d", curIdx))
} }
copy(insts[i:], internal.MakeInstruction(op, newIdx)) copy(insts[i:], MakeInstruction(op, newIdx))
case internal.OpClosure: case parser.OpClosure:
curIdx := int(insts[i+2]) | int(insts[i+1])<<8 curIdx := int(insts[i+2]) | int(insts[i+1])<<8
numFree := int(insts[i+3]) numFree := int(insts[i+3])
newIdx, ok := indexMap[curIdx] newIdx, ok := indexMap[curIdx]
if !ok { if !ok {
panic(fmt.Errorf("constant index not found: %d", curIdx)) panic(fmt.Errorf("constant index not found: %d", curIdx))
} }
copy(insts[i:], internal.MakeInstruction(op, newIdx, numFree)) copy(insts[i:], MakeInstruction(op, newIdx, numFree))
} }
i += 1 + read i += 1 + read
@ -272,8 +272,8 @@ func inferModuleName(mod *ImmutableMap) string {
} }
func init() { func init() {
gob.Register(&internal.SourceFileSet{}) gob.Register(&parser.SourceFileSet{})
gob.Register(&internal.SourceFile{}) gob.Register(&parser.SourceFile{})
gob.Register(&Array{}) gob.Register(&Array{})
gob.Register(&Bool{}) gob.Register(&Bool{})
gob.Register(&Bytes{}) gob.Register(&Bytes{})

View file

@ -6,8 +6,8 @@ import (
"time" "time"
"github.com/d5/tengo" "github.com/d5/tengo"
"github.com/d5/tengo/internal" "github.com/d5/tengo/parser"
"github.com/d5/tengo/internal/require" "github.com/d5/tengo/require"
) )
type srcfile struct { type srcfile struct {
@ -23,20 +23,20 @@ func TestBytecode(t *testing.T) {
&tengo.Char{Value: 'y'}, &tengo.Char{Value: 'y'},
&tengo.Float{Value: 93.11}, &tengo.Float{Value: 93.11},
compiledFunction(1, 0, compiledFunction(1, 0,
internal.MakeInstruction(internal.OpConstant, 3), tengo.MakeInstruction(parser.OpConstant, 3),
internal.MakeInstruction(internal.OpSetLocal, 0), tengo.MakeInstruction(parser.OpSetLocal, 0),
internal.MakeInstruction(internal.OpGetGlobal, 0), tengo.MakeInstruction(parser.OpGetGlobal, 0),
internal.MakeInstruction(internal.OpGetFree, 0)), tengo.MakeInstruction(parser.OpGetFree, 0)),
&tengo.Float{Value: 39.2}, &tengo.Float{Value: 39.2},
&tengo.Int{Value: 192}, &tengo.Int{Value: 192},
&tengo.String{Value: "bar"}))) &tengo.String{Value: "bar"})))
testBytecodeSerialization(t, bytecodeFileSet( testBytecodeSerialization(t, bytecodeFileSet(
concatInsts( concatInsts(
internal.MakeInstruction(internal.OpConstant, 0), tengo.MakeInstruction(parser.OpConstant, 0),
internal.MakeInstruction(internal.OpSetGlobal, 0), tengo.MakeInstruction(parser.OpSetGlobal, 0),
internal.MakeInstruction(internal.OpConstant, 6), tengo.MakeInstruction(parser.OpConstant, 6),
internal.MakeInstruction(internal.OpPop)), tengo.MakeInstruction(parser.OpPop)),
objectsArray( objectsArray(
&tengo.Int{Value: 55}, &tengo.Int{Value: 55},
&tengo.Int{Value: 66}, &tengo.Int{Value: 66},
@ -99,29 +99,29 @@ func TestBytecode(t *testing.T) {
}, },
}, },
compiledFunction(1, 0, compiledFunction(1, 0,
internal.MakeInstruction(internal.OpConstant, 3), tengo.MakeInstruction(parser.OpConstant, 3),
internal.MakeInstruction(internal.OpSetLocal, 0), tengo.MakeInstruction(parser.OpSetLocal, 0),
internal.MakeInstruction(internal.OpGetGlobal, 0), tengo.MakeInstruction(parser.OpGetGlobal, 0),
internal.MakeInstruction(internal.OpGetFree, 0), tengo.MakeInstruction(parser.OpGetFree, 0),
internal.MakeInstruction(internal.OpBinaryOp, 11), tengo.MakeInstruction(parser.OpBinaryOp, 11),
internal.MakeInstruction(internal.OpGetFree, 1), tengo.MakeInstruction(parser.OpGetFree, 1),
internal.MakeInstruction(internal.OpBinaryOp, 11), tengo.MakeInstruction(parser.OpBinaryOp, 11),
internal.MakeInstruction(internal.OpGetLocal, 0), tengo.MakeInstruction(parser.OpGetLocal, 0),
internal.MakeInstruction(internal.OpBinaryOp, 11), tengo.MakeInstruction(parser.OpBinaryOp, 11),
internal.MakeInstruction(internal.OpReturn, 1)), tengo.MakeInstruction(parser.OpReturn, 1)),
compiledFunction(1, 0, compiledFunction(1, 0,
internal.MakeInstruction(internal.OpConstant, 2), tengo.MakeInstruction(parser.OpConstant, 2),
internal.MakeInstruction(internal.OpSetLocal, 0), tengo.MakeInstruction(parser.OpSetLocal, 0),
internal.MakeInstruction(internal.OpGetFree, 0), tengo.MakeInstruction(parser.OpGetFree, 0),
internal.MakeInstruction(internal.OpGetLocal, 0), tengo.MakeInstruction(parser.OpGetLocal, 0),
internal.MakeInstruction(internal.OpClosure, 4, 2), tengo.MakeInstruction(parser.OpClosure, 4, 2),
internal.MakeInstruction(internal.OpReturn, 1)), tengo.MakeInstruction(parser.OpReturn, 1)),
compiledFunction(1, 0, compiledFunction(1, 0,
internal.MakeInstruction(internal.OpConstant, 1), tengo.MakeInstruction(parser.OpConstant, 1),
internal.MakeInstruction(internal.OpSetLocal, 0), tengo.MakeInstruction(parser.OpSetLocal, 0),
internal.MakeInstruction(internal.OpGetLocal, 0), tengo.MakeInstruction(parser.OpGetLocal, 0),
internal.MakeInstruction(internal.OpClosure, 5, 1), tengo.MakeInstruction(parser.OpClosure, 5, 1),
internal.MakeInstruction(internal.OpReturn, 1))), tengo.MakeInstruction(parser.OpReturn, 1))),
fileSet(srcfile{name: "file1", size: 100}, fileSet(srcfile{name: "file1", size: 100},
srcfile{name: "file2", size: 200}))) srcfile{name: "file2", size: 200})))
} }
@ -133,10 +133,10 @@ func TestBytecode_RemoveDuplicates(t *testing.T) {
&tengo.Char{Value: 'y'}, &tengo.Char{Value: 'y'},
&tengo.Float{Value: 93.11}, &tengo.Float{Value: 93.11},
compiledFunction(1, 0, compiledFunction(1, 0,
internal.MakeInstruction(internal.OpConstant, 3), tengo.MakeInstruction(parser.OpConstant, 3),
internal.MakeInstruction(internal.OpSetLocal, 0), tengo.MakeInstruction(parser.OpSetLocal, 0),
internal.MakeInstruction(internal.OpGetGlobal, 0), tengo.MakeInstruction(parser.OpGetGlobal, 0),
internal.MakeInstruction(internal.OpGetFree, 0)), tengo.MakeInstruction(parser.OpGetFree, 0)),
&tengo.Float{Value: 39.2}, &tengo.Float{Value: 39.2},
&tengo.Int{Value: 192}, &tengo.Int{Value: 192},
&tengo.String{Value: "bar"})), &tengo.String{Value: "bar"})),
@ -145,10 +145,10 @@ func TestBytecode_RemoveDuplicates(t *testing.T) {
&tengo.Char{Value: 'y'}, &tengo.Char{Value: 'y'},
&tengo.Float{Value: 93.11}, &tengo.Float{Value: 93.11},
compiledFunction(1, 0, compiledFunction(1, 0,
internal.MakeInstruction(internal.OpConstant, 3), tengo.MakeInstruction(parser.OpConstant, 3),
internal.MakeInstruction(internal.OpSetLocal, 0), tengo.MakeInstruction(parser.OpSetLocal, 0),
internal.MakeInstruction(internal.OpGetGlobal, 0), tengo.MakeInstruction(parser.OpGetGlobal, 0),
internal.MakeInstruction(internal.OpGetFree, 0)), tengo.MakeInstruction(parser.OpGetFree, 0)),
&tengo.Float{Value: 39.2}, &tengo.Float{Value: 39.2},
&tengo.Int{Value: 192}, &tengo.Int{Value: 192},
&tengo.String{Value: "bar"}))) &tengo.String{Value: "bar"})))
@ -156,63 +156,63 @@ func TestBytecode_RemoveDuplicates(t *testing.T) {
testBytecodeRemoveDuplicates(t, testBytecodeRemoveDuplicates(t,
bytecode( bytecode(
concatInsts( concatInsts(
internal.MakeInstruction(internal.OpConstant, 0), tengo.MakeInstruction(parser.OpConstant, 0),
internal.MakeInstruction(internal.OpConstant, 1), tengo.MakeInstruction(parser.OpConstant, 1),
internal.MakeInstruction(internal.OpConstant, 2), tengo.MakeInstruction(parser.OpConstant, 2),
internal.MakeInstruction(internal.OpConstant, 3), tengo.MakeInstruction(parser.OpConstant, 3),
internal.MakeInstruction(internal.OpConstant, 4), tengo.MakeInstruction(parser.OpConstant, 4),
internal.MakeInstruction(internal.OpConstant, 5), tengo.MakeInstruction(parser.OpConstant, 5),
internal.MakeInstruction(internal.OpConstant, 6), tengo.MakeInstruction(parser.OpConstant, 6),
internal.MakeInstruction(internal.OpConstant, 7), tengo.MakeInstruction(parser.OpConstant, 7),
internal.MakeInstruction(internal.OpConstant, 8), tengo.MakeInstruction(parser.OpConstant, 8),
internal.MakeInstruction(internal.OpClosure, 4, 1)), tengo.MakeInstruction(parser.OpClosure, 4, 1)),
objectsArray( objectsArray(
&tengo.Int{Value: 1}, &tengo.Int{Value: 1},
&tengo.Float{Value: 2.0}, &tengo.Float{Value: 2.0},
&tengo.Char{Value: '3'}, &tengo.Char{Value: '3'},
&tengo.String{Value: "four"}, &tengo.String{Value: "four"},
compiledFunction(1, 0, compiledFunction(1, 0,
internal.MakeInstruction(internal.OpConstant, 3), tengo.MakeInstruction(parser.OpConstant, 3),
internal.MakeInstruction(internal.OpConstant, 7), tengo.MakeInstruction(parser.OpConstant, 7),
internal.MakeInstruction(internal.OpSetLocal, 0), tengo.MakeInstruction(parser.OpSetLocal, 0),
internal.MakeInstruction(internal.OpGetGlobal, 0), tengo.MakeInstruction(parser.OpGetGlobal, 0),
internal.MakeInstruction(internal.OpGetFree, 0)), tengo.MakeInstruction(parser.OpGetFree, 0)),
&tengo.Int{Value: 1}, &tengo.Int{Value: 1},
&tengo.Float{Value: 2.0}, &tengo.Float{Value: 2.0},
&tengo.Char{Value: '3'}, &tengo.Char{Value: '3'},
&tengo.String{Value: "four"})), &tengo.String{Value: "four"})),
bytecode( bytecode(
concatInsts( concatInsts(
internal.MakeInstruction(internal.OpConstant, 0), tengo.MakeInstruction(parser.OpConstant, 0),
internal.MakeInstruction(internal.OpConstant, 1), tengo.MakeInstruction(parser.OpConstant, 1),
internal.MakeInstruction(internal.OpConstant, 2), tengo.MakeInstruction(parser.OpConstant, 2),
internal.MakeInstruction(internal.OpConstant, 3), tengo.MakeInstruction(parser.OpConstant, 3),
internal.MakeInstruction(internal.OpConstant, 4), tengo.MakeInstruction(parser.OpConstant, 4),
internal.MakeInstruction(internal.OpConstant, 0), tengo.MakeInstruction(parser.OpConstant, 0),
internal.MakeInstruction(internal.OpConstant, 1), tengo.MakeInstruction(parser.OpConstant, 1),
internal.MakeInstruction(internal.OpConstant, 2), tengo.MakeInstruction(parser.OpConstant, 2),
internal.MakeInstruction(internal.OpConstant, 3), tengo.MakeInstruction(parser.OpConstant, 3),
internal.MakeInstruction(internal.OpClosure, 4, 1)), tengo.MakeInstruction(parser.OpClosure, 4, 1)),
objectsArray( objectsArray(
&tengo.Int{Value: 1}, &tengo.Int{Value: 1},
&tengo.Float{Value: 2.0}, &tengo.Float{Value: 2.0},
&tengo.Char{Value: '3'}, &tengo.Char{Value: '3'},
&tengo.String{Value: "four"}, &tengo.String{Value: "four"},
compiledFunction(1, 0, compiledFunction(1, 0,
internal.MakeInstruction(internal.OpConstant, 3), tengo.MakeInstruction(parser.OpConstant, 3),
internal.MakeInstruction(internal.OpConstant, 2), tengo.MakeInstruction(parser.OpConstant, 2),
internal.MakeInstruction(internal.OpSetLocal, 0), tengo.MakeInstruction(parser.OpSetLocal, 0),
internal.MakeInstruction(internal.OpGetGlobal, 0), tengo.MakeInstruction(parser.OpGetGlobal, 0),
internal.MakeInstruction(internal.OpGetFree, 0))))) tengo.MakeInstruction(parser.OpGetFree, 0)))))
testBytecodeRemoveDuplicates(t, testBytecodeRemoveDuplicates(t,
bytecode( bytecode(
concatInsts( concatInsts(
internal.MakeInstruction(internal.OpConstant, 0), tengo.MakeInstruction(parser.OpConstant, 0),
internal.MakeInstruction(internal.OpConstant, 1), tengo.MakeInstruction(parser.OpConstant, 1),
internal.MakeInstruction(internal.OpConstant, 2), tengo.MakeInstruction(parser.OpConstant, 2),
internal.MakeInstruction(internal.OpConstant, 3), tengo.MakeInstruction(parser.OpConstant, 3),
internal.MakeInstruction(internal.OpConstant, 4)), tengo.MakeInstruction(parser.OpConstant, 4)),
objectsArray( objectsArray(
&tengo.Int{Value: 1}, &tengo.Int{Value: 1},
&tengo.Int{Value: 2}, &tengo.Int{Value: 2},
@ -221,11 +221,11 @@ func TestBytecode_RemoveDuplicates(t *testing.T) {
&tengo.Int{Value: 3})), &tengo.Int{Value: 3})),
bytecode( bytecode(
concatInsts( concatInsts(
internal.MakeInstruction(internal.OpConstant, 0), tengo.MakeInstruction(parser.OpConstant, 0),
internal.MakeInstruction(internal.OpConstant, 1), tengo.MakeInstruction(parser.OpConstant, 1),
internal.MakeInstruction(internal.OpConstant, 2), tengo.MakeInstruction(parser.OpConstant, 2),
internal.MakeInstruction(internal.OpConstant, 0), tengo.MakeInstruction(parser.OpConstant, 0),
internal.MakeInstruction(internal.OpConstant, 2)), tengo.MakeInstruction(parser.OpConstant, 2)),
objectsArray( objectsArray(
&tengo.Int{Value: 1}, &tengo.Int{Value: 1},
&tengo.Int{Value: 2}, &tengo.Int{Value: 2},
@ -241,19 +241,19 @@ func TestBytecode_CountObjects(t *testing.T) {
&tengo.Int{Value: 77}, &tengo.Int{Value: 77},
&tengo.Int{Value: 88}, &tengo.Int{Value: 88},
compiledFunction(1, 0, compiledFunction(1, 0,
internal.MakeInstruction(internal.OpConstant, 3), tengo.MakeInstruction(parser.OpConstant, 3),
internal.MakeInstruction(internal.OpReturn, 1)), tengo.MakeInstruction(parser.OpReturn, 1)),
compiledFunction(1, 0, compiledFunction(1, 0,
internal.MakeInstruction(internal.OpConstant, 2), tengo.MakeInstruction(parser.OpConstant, 2),
internal.MakeInstruction(internal.OpReturn, 1)), tengo.MakeInstruction(parser.OpReturn, 1)),
compiledFunction(1, 0, compiledFunction(1, 0,
internal.MakeInstruction(internal.OpConstant, 1), tengo.MakeInstruction(parser.OpConstant, 1),
internal.MakeInstruction(internal.OpReturn, 1)))) tengo.MakeInstruction(parser.OpReturn, 1))))
require.Equal(t, 7, b.CountObjects()) require.Equal(t, 7, b.CountObjects())
} }
func fileSet(files ...srcfile) *internal.SourceFileSet { func fileSet(files ...srcfile) *parser.SourceFileSet {
fileSet := internal.NewFileSet() fileSet := parser.NewFileSet()
for _, f := range files { for _, f := range files {
fileSet.AddFile(f.name, -1, f.size) fileSet.AddFile(f.name, -1, f.size)
} }
@ -263,7 +263,7 @@ func fileSet(files ...srcfile) *internal.SourceFileSet {
func bytecodeFileSet( func bytecodeFileSet(
instructions []byte, instructions []byte,
constants []tengo.Object, constants []tengo.Object,
fileSet *internal.SourceFileSet, fileSet *parser.SourceFileSet,
) *tengo.Bytecode { ) *tengo.Bytecode {
return &tengo.Bytecode{ return &tengo.Bytecode{
FileSet: fileSet, FileSet: fileSet,

View file

@ -5,7 +5,7 @@ import (
"time" "time"
"github.com/d5/tengo" "github.com/d5/tengo"
"github.com/d5/tengo/internal" "github.com/d5/tengo/parser"
) )
func main() { func main() {
@ -163,7 +163,7 @@ func runBench(
result tengo.Object, result tengo.Object,
err error, err error,
) { ) {
var astFile *internal.File var astFile *parser.File
parseTime, astFile, err = parse(input) parseTime, astFile, err = parse(input)
if err != nil { if err != nil {
return return
@ -180,13 +180,13 @@ func runBench(
return return
} }
func parse(input []byte) (time.Duration, *internal.File, error) { func parse(input []byte) (time.Duration, *parser.File, error) {
fileSet := internal.NewFileSet() fileSet := parser.NewFileSet()
inputFile := fileSet.AddFile("bench", -1, len(input)) inputFile := fileSet.AddFile("bench", -1, len(input))
start := time.Now() start := time.Now()
p := internal.NewParser(inputFile, input, nil) p := parser.NewParser(inputFile, input, nil)
file, err := p.ParseFile() file, err := p.ParseFile()
if err != nil { if err != nil {
return time.Since(start), nil, err return time.Since(start), nil, err
@ -195,8 +195,8 @@ func parse(input []byte) (time.Duration, *internal.File, error) {
return time.Since(start), file, nil return time.Since(start), file, nil
} }
func compileFile(file *internal.File) (time.Duration, *tengo.Bytecode, error) { func compileFile(file *parser.File) (time.Duration, *tengo.Bytecode, error) {
symTable := internal.NewSymbolTable() symTable := tengo.NewSymbolTable()
symTable.Define("out") symTable.Define("out")
start := time.Now() start := time.Now()

View file

@ -12,7 +12,7 @@ import (
"strings" "strings"
"github.com/d5/tengo" "github.com/d5/tengo"
"github.com/d5/tengo/internal" "github.com/d5/tengo/parser"
"github.com/d5/tengo/stdlib" "github.com/d5/tengo/stdlib"
) )
@ -148,9 +148,9 @@ func RunCompiled(modules *tengo.ModuleMap, data []byte) (err error) {
// RunREPL starts REPL. // RunREPL starts REPL.
func RunREPL(modules *tengo.ModuleMap, in io.Reader, out io.Writer) { func RunREPL(modules *tengo.ModuleMap, in io.Reader, out io.Writer) {
stdin := bufio.NewScanner(in) stdin := bufio.NewScanner(in)
fileSet := internal.NewFileSet() fileSet := parser.NewFileSet()
globals := make([]tengo.Object, tengo.GlobalsSize) globals := make([]tengo.Object, tengo.GlobalsSize)
symbolTable := internal.NewSymbolTable() symbolTable := tengo.NewSymbolTable()
for idx, fn := range tengo.GetAllBuiltinFunctions() { for idx, fn := range tengo.GetAllBuiltinFunctions() {
symbolTable.DefineBuiltin(idx, fn.Name) symbolTable.DefineBuiltin(idx, fn.Name)
} }
@ -185,7 +185,7 @@ func RunREPL(modules *tengo.ModuleMap, in io.Reader, out io.Writer) {
line := stdin.Text() line := stdin.Text()
srcFile := fileSet.AddFile("repl", -1, len(line)) srcFile := fileSet.AddFile("repl", -1, len(line))
p := internal.NewParser(srcFile, []byte(line), nil) p := parser.NewParser(srcFile, []byte(line), nil)
file, err := p.ParseFile() file, err := p.ParseFile()
if err != nil { if err != nil {
_, _ = fmt.Fprintln(out, err.Error()) _, _ = fmt.Fprintln(out, err.Error())
@ -214,10 +214,10 @@ func compileSrc(
src []byte, src []byte,
filename string, filename string,
) (*tengo.Bytecode, error) { ) (*tengo.Bytecode, error) {
fileSet := internal.NewFileSet() fileSet := parser.NewFileSet()
srcFile := fileSet.AddFile(filename, -1, len(src)) srcFile := fileSet.AddFile(filename, -1, len(src))
p := internal.NewParser(srcFile, src, nil) p := parser.NewParser(srcFile, src, nil)
file, err := p.ParseFile() file, err := p.ParseFile()
if err != nil { if err != nil {
return nil, err return nil, err
@ -267,23 +267,23 @@ func doHelp() {
fmt.Println() fmt.Println()
} }
func addPrints(file *internal.File) *internal.File { func addPrints(file *parser.File) *parser.File {
var stmts []internal.Stmt var stmts []parser.Stmt
for _, s := range file.Stmts { for _, s := range file.Stmts {
switch s := s.(type) { switch s := s.(type) {
case *internal.ExprStmt: case *parser.ExprStmt:
stmts = append(stmts, &internal.ExprStmt{ stmts = append(stmts, &parser.ExprStmt{
Expr: &internal.CallExpr{ Expr: &parser.CallExpr{
Func: &internal.Ident{Name: "__repl_println__"}, Func: &parser.Ident{Name: "__repl_println__"},
Args: []internal.Expr{s.Expr}, Args: []parser.Expr{s.Expr},
}, },
}) })
case *internal.AssignStmt: case *parser.AssignStmt:
stmts = append(stmts, s) stmts = append(stmts, s)
stmts = append(stmts, &internal.ExprStmt{ stmts = append(stmts, &parser.ExprStmt{
Expr: &internal.CallExpr{ Expr: &parser.CallExpr{
Func: &internal.Ident{ Func: &parser.Ident{
Name: "__repl_println__", Name: "__repl_println__",
}, },
Args: s.LHS, Args: s.LHS,
@ -293,7 +293,7 @@ func addPrints(file *internal.File) *internal.File {
stmts = append(stmts, s) stmts = append(stmts, s)
} }
} }
return &internal.File{ return &parser.File{
InputFile: file.InputFile, InputFile: file.InputFile,
Stmts: stmts, Stmts: stmts,
} }

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

3
doc.go Normal file
View file

@ -0,0 +1,3 @@
// tengo is a small, dynamic, fast, secure script language for Go.
package tengo

46
example_test.go Normal file
View file

@ -0,0 +1,46 @@
package tengo_test
import (
"context"
"fmt"
"github.com/d5/tengo"
)
func Example() {
// Tengo script code
src := `
each := func(seq, fn) {
for x in seq { fn(x) }
}
sum := 0
mul := 1
each([a, b, c, d], func(x) {
sum += x
mul *= x
})`
// create a new Script instance
script := tengo.NewScript([]byte(src))
// set values
_ = script.Add("a", 1)
_ = script.Add("b", 9)
_ = script.Add("c", 8)
_ = script.Add("d", 4)
// run the script
compiled, err := script.RunContext(context.Background())
if err != nil {
panic(err)
}
// retrieve values
sum := compiled.Get("sum")
mul := compiled.Get("mul")
fmt.Println(sum, mul)
// Output:
// 22 288
}

View file

@ -1,10 +1,14 @@
package internal package tengo
import "fmt" import (
"fmt"
"github.com/d5/tengo/parser"
)
// MakeInstruction returns a bytecode for an opcode and the operands. // MakeInstruction returns a bytecode for an opcode and the operands.
func MakeInstruction(opcode Opcode, operands ...int) []byte { func MakeInstruction(opcode parser.Opcode, operands ...int) []byte {
numOperands := OpcodeOperands[opcode] numOperands := parser.OpcodeOperands[opcode]
totalLen := 1 totalLen := 1
for _, w := range numOperands { for _, w := range numOperands {
@ -36,19 +40,19 @@ func FormatInstructions(b []byte, posOffset int) []string {
i := 0 i := 0
for i < len(b) { for i < len(b) {
numOperands := OpcodeOperands[b[i]] numOperands := parser.OpcodeOperands[b[i]]
operands, read := ReadOperands(numOperands, b[i+1:]) operands, read := parser.ReadOperands(numOperands, b[i+1:])
switch len(numOperands) { switch len(numOperands) {
case 0: case 0:
out = append(out, fmt.Sprintf("%04d %-7s", out = append(out, fmt.Sprintf("%04d %-7s",
posOffset+i, OpcodeNames[b[i]])) posOffset+i, parser.OpcodeNames[b[i]]))
case 1: case 1:
out = append(out, fmt.Sprintf("%04d %-7s %-5d", out = append(out, fmt.Sprintf("%04d %-7s %-5d",
posOffset+i, OpcodeNames[b[i]], operands[0])) posOffset+i, parser.OpcodeNames[b[i]], operands[0]))
case 2: case 2:
out = append(out, fmt.Sprintf("%04d %-7s %-5d %-5d", out = append(out, fmt.Sprintf("%04d %-7s %-5d %-5d",
posOffset+i, OpcodeNames[b[i]], posOffset+i, parser.OpcodeNames[b[i]],
operands[0], operands[1])) operands[0], operands[1]))
} }
i += 1 + read i += 1 + read

View file

@ -8,8 +8,8 @@ import (
"strings" "strings"
"time" "time"
"github.com/d5/tengo/internal" "github.com/d5/tengo/parser"
"github.com/d5/tengo/internal/token" "github.com/d5/tengo/token"
) )
var ( var (
@ -574,7 +574,7 @@ type CompiledFunction struct {
NumLocals int // number of local variables (including function parameters) NumLocals int // number of local variables (including function parameters)
NumParameters int NumParameters int
VarArgs bool VarArgs bool
SourceMap map[int]internal.Pos SourceMap map[int]parser.Pos
Free []*ObjectPtr Free []*ObjectPtr
} }
@ -605,14 +605,14 @@ func (o *CompiledFunction) Equals(_ Object) bool {
} }
// SourcePos returns the source position of the instruction at ip. // SourcePos returns the source position of the instruction at ip.
func (o *CompiledFunction) SourcePos(ip int) internal.Pos { func (o *CompiledFunction) SourcePos(ip int) parser.Pos {
for ip >= 0 { for ip >= 0 {
if p, ok := o.SourceMap[ip]; ok { if p, ok := o.SourceMap[ip]; ok {
return p return p
} }
ip-- ip--
} }
return internal.NoPos return parser.NoPos
} }
// CanCall returns whether the Object can be Called. // CanCall returns whether the Object can be Called.

View file

@ -4,8 +4,8 @@ import (
"testing" "testing"
"github.com/d5/tengo" "github.com/d5/tengo"
"github.com/d5/tengo/internal/require" "github.com/d5/tengo/require"
"github.com/d5/tengo/internal/token" "github.com/d5/tengo/token"
) )
func TestObject_TypeName(t *testing.T) { func TestObject_TypeName(t *testing.T) {

View file

@ -1,4 +1,4 @@
package internal package parser
import ( import (
"strings" "strings"

View file

@ -1,14 +1,14 @@
package internal_test package parser_test
import ( import (
"testing" "testing"
"github.com/d5/tengo/internal" "github.com/d5/tengo/parser"
) )
func TestIdentListString(t *testing.T) { func TestIdentListString(t *testing.T) {
identListVar := &internal.IdentList{ identListVar := &parser.IdentList{
List: []*internal.Ident{ List: []*parser.Ident{
{Name: "a"}, {Name: "a"},
{Name: "b"}, {Name: "b"},
{Name: "c"}, {Name: "c"},
@ -22,8 +22,8 @@ func TestIdentListString(t *testing.T) {
identListVar, expectedVar, str) identListVar, expectedVar, str)
} }
identList := &internal.IdentList{ identList := &parser.IdentList{
List: []*internal.Ident{ List: []*parser.Ident{
{Name: "a"}, {Name: "a"},
{Name: "b"}, {Name: "b"},
{Name: "c"}, {Name: "c"},

View file

@ -1,9 +1,9 @@
package internal package parser
import ( import (
"strings" "strings"
"github.com/d5/tengo/internal/token" "github.com/d5/tengo/token"
) )
// Expr represents an expression node in the AST. // Expr represents an expression node in the AST.

View file

@ -1,4 +1,4 @@
package internal package parser
import ( import (
"strings" "strings"

View file

@ -1,4 +1,4 @@
package internal package parser
// Opcode represents a single byte operation code. // Opcode represents a single byte operation code.
type Opcode = byte type Opcode = byte

View file

@ -1,4 +1,4 @@
package internal package parser
import ( import (
"fmt" "fmt"
@ -6,7 +6,7 @@ import (
"sort" "sort"
"strconv" "strconv"
"github.com/d5/tengo/internal/token" "github.com/d5/tengo/token"
) )
type bailout struct{} type bailout struct{}
@ -20,37 +20,37 @@ var stmtStart = map[token.Token]bool{
token.Export: true, token.Export: true,
} }
// ParserError represents a parser error. // Error represents a parser error.
type ParserError struct { type Error struct {
Pos SourceFilePos Pos SourceFilePos
Msg string Msg string
} }
func (e ParserError) Error() string { func (e Error) Error() string {
if e.Pos.Filename != "" || e.Pos.IsValid() { if e.Pos.Filename != "" || e.Pos.IsValid() {
return fmt.Sprintf("Parse Error: %s\n\tat %s", e.Msg, e.Pos) return fmt.Sprintf("Parse Error: %s\n\tat %s", e.Msg, e.Pos)
} }
return fmt.Sprintf("Parse Error: %s", e.Msg) return fmt.Sprintf("Parse Error: %s", e.Msg)
} }
// ParserErrorList is a collection of parser errors. // ErrorList is a collection of parser errors.
type ParserErrorList []*ParserError type ErrorList []*Error
// Add adds a new parser error to the collection. // Add adds a new parser error to the collection.
func (p *ParserErrorList) Add(pos SourceFilePos, msg string) { func (p *ErrorList) Add(pos SourceFilePos, msg string) {
*p = append(*p, &ParserError{pos, msg}) *p = append(*p, &Error{pos, msg})
} }
// Len returns the number of elements in the collection. // Len returns the number of elements in the collection.
func (p ParserErrorList) Len() int { func (p ErrorList) Len() int {
return len(p) return len(p)
} }
func (p ParserErrorList) Swap(i, j int) { func (p ErrorList) Swap(i, j int) {
p[i], p[j] = p[j], p[i] p[i], p[j] = p[j], p[i]
} }
func (p ParserErrorList) Less(i, j int) bool { func (p ErrorList) Less(i, j int) bool {
e := &p[i].Pos e := &p[i].Pos
f := &p[j].Pos f := &p[j].Pos
@ -67,11 +67,11 @@ func (p ParserErrorList) Less(i, j int) bool {
} }
// Sort sorts the collection. // Sort sorts the collection.
func (p ParserErrorList) Sort() { func (p ErrorList) Sort() {
sort.Sort(p) sort.Sort(p)
} }
func (p ParserErrorList) Error() string { func (p ErrorList) Error() string {
switch len(p) { switch len(p) {
case 0: case 0:
return "no errors" return "no errors"
@ -82,7 +82,7 @@ func (p ParserErrorList) Error() string {
} }
// Err returns an error. // Err returns an error.
func (p ParserErrorList) Err() error { func (p ErrorList) Err() error {
if len(p) == 0 { if len(p) == 0 {
return nil return nil
} }
@ -93,7 +93,7 @@ func (p ParserErrorList) Err() error {
// implementation. // implementation.
type Parser struct { type Parser struct {
file *SourceFile file *SourceFile
errors ParserErrorList errors ErrorList
scanner *Scanner scanner *Scanner
pos Pos pos Pos
token token.Token token token.Token

View file

@ -1,4 +1,4 @@
package internal_test package parser_test
import ( import (
"fmt" "fmt"
@ -7,20 +7,20 @@ import (
"strings" "strings"
"testing" "testing"
. "github.com/d5/tengo/internal" . "github.com/d5/tengo/parser"
"github.com/d5/tengo/internal/require" "github.com/d5/tengo/require"
"github.com/d5/tengo/internal/token" "github.com/d5/tengo/token"
) )
func TestParserError(t *testing.T) { func TestParserError(t *testing.T) {
err := &ParserError{Pos: SourceFilePos{ err := &Error{Pos: SourceFilePos{
Offset: 10, Line: 1, Column: 10, Offset: 10, Line: 1, Column: 10,
}, Msg: "test"} }, Msg: "test"}
require.Equal(t, "Parse Error: test\n\tat 1:10", err.Error()) require.Equal(t, "Parse Error: test\n\tat 1:10", err.Error())
} }
func TestParserErrorList(t *testing.T) { func TestParserErrorList(t *testing.T) {
var list ParserErrorList var list ErrorList
list.Add(SourceFilePos{Offset: 20, Line: 2, Column: 10}, "error 2") list.Add(SourceFilePos{Offset: 20, Line: 2, Column: 10}, "error 2")
list.Add(SourceFilePos{Offset: 30, Line: 3, Column: 10}, "error 3") list.Add(SourceFilePos{Offset: 30, Line: 3, Column: 10}, "error 3")
list.Add(SourceFilePos{Offset: 10, Line: 1, Column: 10}, "error 1") list.Add(SourceFilePos{Offset: 10, Line: 1, Column: 10}, "error 1")

View file

@ -1,4 +1,4 @@
package internal package parser
// Pos represents a position in the file set. // Pos represents a position in the file set.
type Pos int type Pos int

View file

@ -1,11 +1,11 @@
package internal package parser
import ( import (
"fmt" "fmt"
"unicode" "unicode"
"unicode/utf8" "unicode/utf8"
"github.com/d5/tengo/internal/token" "github.com/d5/tengo/token"
) )
// byte order mark // byte order mark

View file

@ -1,4 +1,4 @@
package internal_test package parser_test
import ( import (
"fmt" "fmt"
@ -7,12 +7,12 @@ import (
"testing" "testing"
"time" "time"
"github.com/d5/tengo/internal" "github.com/d5/tengo/parser"
"github.com/d5/tengo/internal/require" "github.com/d5/tengo/require"
"github.com/d5/tengo/internal/token" "github.com/d5/tengo/token"
) )
var testFileSet = internal.NewFileSet() var testFileSet = parser.NewFileSet()
type scanResult struct { type scanResult struct {
Token token.Token Token token.Token
@ -151,7 +151,7 @@ func TestScanner_Scan(t *testing.T) {
switch tc.token { switch tc.token {
case token.Comment: case token.Comment:
// strip CRs in comments // strip CRs in comments
expectedLiteral = string(internal.StripCR([]byte(tc.literal), expectedLiteral = string(parser.StripCR([]byte(tc.literal),
tc.literal[1] == '*')) tc.literal[1] == '*'))
//-style comment literal doesn't contain newline //-style comment literal doesn't contain newline
@ -167,7 +167,7 @@ func TestScanner_Scan(t *testing.T) {
// strip CRs in raw string // strip CRs in raw string
expectedLiteral = tc.literal expectedLiteral = tc.literal
if expectedLiteral[0] == '`' { if expectedLiteral[0] == '`' {
expectedLiteral = string(internal.StripCR( expectedLiteral = string(parser.StripCR(
[]byte(expectedLiteral), false)) []byte(expectedLiteral), false))
} }
} else if tc.token.IsKeyword() { } else if tc.token.IsKeyword() {
@ -189,9 +189,9 @@ func TestScanner_Scan(t *testing.T) {
} }
scanExpect(t, strings.Join(lines, "\n"), scanExpect(t, strings.Join(lines, "\n"),
internal.ScanComments|internal.DontInsertSemis, expected...) parser.ScanComments|parser.DontInsertSemis, expected...)
scanExpect(t, strings.Join(lines, "\n"), scanExpect(t, strings.Join(lines, "\n"),
internal.DontInsertSemis, expectedSkipComments...) parser.DontInsertSemis, expectedSkipComments...)
} }
func TestStripCR(t *testing.T) { func TestStripCR(t *testing.T) {
@ -210,7 +210,7 @@ func TestStripCR(t *testing.T) {
{"/*\r/\r*\r/*/", "/*/*\r/*/"}, {"/*\r/\r*\r/*/", "/*/*\r/*/"},
{"/*\r\r\r\r*/", "/**/"}, {"/*\r\r\r\r*/", "/**/"},
} { } {
actual := string(internal.StripCR([]byte(tc.input), actual := string(parser.StripCR([]byte(tc.input),
len(tc.input) >= 2 && tc.input[1] == '*')) len(tc.input) >= 2 && tc.input[1] == '*'))
require.Equal(t, tc.expect, actual) require.Equal(t, tc.expect, actual)
} }
@ -219,15 +219,15 @@ func TestStripCR(t *testing.T) {
func scanExpect( func scanExpect(
t *testing.T, t *testing.T,
input string, input string,
mode internal.ScanMode, mode parser.ScanMode,
expected ...scanResult, expected ...scanResult,
) { ) {
testFile := testFileSet.AddFile("test", -1, len(input)) testFile := testFileSet.AddFile("test", -1, len(input))
s := internal.NewScanner( s := parser.NewScanner(
testFile, testFile,
[]byte(input), []byte(input),
func(_ internal.SourceFilePos, msg string) { require.Fail(t, msg) }, func(_ parser.SourceFilePos, msg string) { require.Fail(t, msg) },
mode) mode)
for idx, e := range expected { for idx, e := range expected {

View file

@ -1,4 +1,4 @@
package internal package parser
import ( import (
"fmt" "fmt"

View file

@ -1,9 +1,9 @@
package internal package parser
import ( import (
"strings" "strings"
"github.com/d5/tengo/internal/token" "github.com/d5/tengo/token"
) )
// Stmt represents a statement in the AST. // Stmt represents a statement in the AST.

View file

@ -11,8 +11,8 @@ import (
"unicode/utf8" "unicode/utf8"
"github.com/d5/tengo" "github.com/d5/tengo"
"github.com/d5/tengo/internal" "github.com/d5/tengo/parser"
"github.com/d5/tengo/internal/token" "github.com/d5/tengo/token"
) )
// NoError asserts err is not an error. // NoError asserts err is not an error.
@ -120,12 +120,12 @@ func Equal(
if expected != actual.(rune) { if expected != actual.(rune) {
failExpectedActual(t, expected, actual, msg...) failExpectedActual(t, expected, actual, msg...)
} }
case *internal.Symbol: case *tengo.Symbol:
if !equalSymbol(expected, actual.(*internal.Symbol)) { if !equalSymbol(expected, actual.(*tengo.Symbol)) {
failExpectedActual(t, expected, actual, msg...) failExpectedActual(t, expected, actual, msg...)
} }
case internal.Pos: case parser.Pos:
if expected != actual.(internal.Pos) { if expected != actual.(parser.Pos) {
failExpectedActual(t, expected, actual, msg...) failExpectedActual(t, expected, actual, msg...)
} }
case token.Token: case token.Token:
@ -176,14 +176,14 @@ func Equal(
if !expected.Equals(actual.(tengo.Object)) { if !expected.Equals(actual.(tengo.Object)) {
failExpectedActual(t, expected, actual, msg...) failExpectedActual(t, expected, actual, msg...)
} }
case *internal.SourceFileSet: case *parser.SourceFileSet:
equalFileSet(t, expected, actual.(*internal.SourceFileSet), msg...) equalFileSet(t, expected, actual.(*parser.SourceFileSet), msg...)
case *internal.SourceFile: case *parser.SourceFile:
Equal(t, expected.Name, actual.(*internal.SourceFile).Name, msg...) Equal(t, expected.Name, actual.(*parser.SourceFile).Name, msg...)
Equal(t, expected.Base, actual.(*internal.SourceFile).Base, msg...) Equal(t, expected.Base, actual.(*parser.SourceFile).Base, msg...)
Equal(t, expected.Size, actual.(*internal.SourceFile).Size, msg...) Equal(t, expected.Size, actual.(*parser.SourceFile).Size, msg...)
True(t, equalIntSlice(expected.Lines, True(t, equalIntSlice(expected.Lines,
actual.(*internal.SourceFile).Lines), msg...) actual.(*parser.SourceFile).Lines), msg...)
case error: case error:
if expected != actual.(error) { if expected != actual.(error) {
failExpectedActual(t, expected, actual, msg...) failExpectedActual(t, expected, actual, msg...)
@ -253,7 +253,7 @@ func equalStringSlice(a, b []string) bool {
return true return true
} }
func equalSymbol(a, b *internal.Symbol) bool { func equalSymbol(a, b *tengo.Symbol) bool {
return a.Name == b.Name && return a.Name == b.Name &&
a.Index == b.Index && a.Index == b.Index &&
a.Scope == b.Scope a.Scope == b.Scope
@ -272,7 +272,7 @@ func equalObjectSlice(
func equalFileSet( func equalFileSet(
t *testing.T, t *testing.T,
expected, actual *internal.SourceFileSet, expected, actual *parser.SourceFileSet,
msg ...interface{}, msg ...interface{},
) { ) {
Equal(t, len(expected.Files), len(actual.Files), msg...) Equal(t, len(expected.Files), len(actual.Files), msg...)
@ -303,8 +303,8 @@ func equalCompiledFunction(
expectedT := expected.(*tengo.CompiledFunction) expectedT := expected.(*tengo.CompiledFunction)
actualT := actual.(*tengo.CompiledFunction) actualT := actual.(*tengo.CompiledFunction)
Equal(t, Equal(t,
internal.FormatInstructions(expectedT.Instructions, 0), tengo.FormatInstructions(expectedT.Instructions, 0),
internal.FormatInstructions(actualT.Instructions, 0), msg...) tengo.FormatInstructions(actualT.Instructions, 0), msg...)
} }
func isNil(v interface{}) bool { func isNil(v interface{}) bool {

View file

@ -5,7 +5,7 @@ import (
"fmt" "fmt"
"sync" "sync"
"github.com/d5/tengo/internal" "github.com/d5/tengo/parser"
) )
// Script can simplify compilation and execution of embedded scripts. // Script can simplify compilation and execution of embedded scripts.
@ -83,9 +83,9 @@ func (s *Script) Compile() (*Compiled, error) {
return nil, err return nil, err
} }
fileSet := internal.NewFileSet() fileSet := parser.NewFileSet()
srcFile := fileSet.AddFile("(main)", -1, len(s.input)) srcFile := fileSet.AddFile("(main)", -1, len(s.input))
p := internal.NewParser(srcFile, s.input, nil) p := parser.NewParser(srcFile, s.input, nil)
file, err := p.ParseFile() file, err := p.ParseFile()
if err != nil { if err != nil {
return nil, err return nil, err
@ -104,7 +104,7 @@ func (s *Script) Compile() (*Compiled, error) {
globalIndexes := make(map[string]int, len(globals)) globalIndexes := make(map[string]int, len(globals))
for _, name := range symbolTable.Names() { for _, name := range symbolTable.Names() {
symbol, _, _ := symbolTable.Resolve(name) symbol, _, _ := symbolTable.Resolve(name)
if symbol.Scope == internal.ScopeGlobal { if symbol.Scope == ScopeGlobal {
globalIndexes[name] = symbol.Index globalIndexes[name] = symbol.Index
} }
} }
@ -152,7 +152,7 @@ func (s *Script) RunContext(
} }
func (s *Script) prepCompile() ( func (s *Script) prepCompile() (
symbolTable *internal.SymbolTable, symbolTable *SymbolTable,
globals []Object, globals []Object,
err error, err error,
) { ) {
@ -161,7 +161,7 @@ func (s *Script) prepCompile() (
names = append(names, name) names = append(names, name)
} }
symbolTable = internal.NewSymbolTable() symbolTable = NewSymbolTable()
for idx, fn := range builtinFuncs { for idx, fn := range builtinFuncs {
symbolTable.DefineBuiltin(idx, fn.Name) symbolTable.DefineBuiltin(idx, fn.Name)
} }

View file

@ -11,9 +11,9 @@ import (
"time" "time"
"github.com/d5/tengo" "github.com/d5/tengo"
"github.com/d5/tengo/internal/require" "github.com/d5/tengo/require"
"github.com/d5/tengo/internal/token"
"github.com/d5/tengo/stdlib" "github.com/d5/tengo/stdlib"
"github.com/d5/tengo/token"
) )
func TestScript_Add(t *testing.T) { func TestScript_Add(t *testing.T) {

View file

@ -7,7 +7,7 @@ import (
"testing" "testing"
"github.com/d5/tengo" "github.com/d5/tengo"
"github.com/d5/tengo/internal/require" "github.com/d5/tengo/require"
"github.com/d5/tengo/stdlib" "github.com/d5/tengo/stdlib"
) )

View file

@ -5,7 +5,7 @@ import (
"testing" "testing"
"github.com/d5/tengo" "github.com/d5/tengo"
"github.com/d5/tengo/internal/require" "github.com/d5/tengo/require"
"github.com/d5/tengo/stdlib/json" "github.com/d5/tengo/stdlib/json"
) )

View file

@ -6,7 +6,7 @@ import (
"testing" "testing"
"github.com/d5/tengo" "github.com/d5/tengo"
"github.com/d5/tengo/internal/require" "github.com/d5/tengo/require"
) )
func TestReadFile(t *testing.T) { func TestReadFile(t *testing.T) {

View file

@ -5,7 +5,7 @@ import (
"testing" "testing"
"github.com/d5/tengo" "github.com/d5/tengo"
"github.com/d5/tengo/internal/require" "github.com/d5/tengo/require"
) )
func TestRand(t *testing.T) { func TestRand(t *testing.T) {

View file

@ -6,7 +6,7 @@ import (
"time" "time"
"github.com/d5/tengo" "github.com/d5/tengo"
"github.com/d5/tengo/internal/require" "github.com/d5/tengo/require"
"github.com/d5/tengo/stdlib" "github.com/d5/tengo/stdlib"
) )

View file

@ -5,7 +5,7 @@ import (
"time" "time"
"github.com/d5/tengo" "github.com/d5/tengo"
"github.com/d5/tengo/internal/require" "github.com/d5/tengo/require"
) )
func TestTimes(t *testing.T) { func TestTimes(t *testing.T) {

View file

@ -1,33 +1,4 @@
package internal package tengo
import "fmt"
// CompilationScope represents a compiled instructions and the last two
// instructions that were emitted.
type CompilationScope struct {
Instructions []byte
SymbolInit map[string]bool
SourceMap map[int]Pos
}
// Loop represents a loop construct that the compiler uses to track the current
// loop.
type Loop struct {
Continues []int
Breaks []int
}
// CompilerError represents a compiler error.
type CompilerError struct {
FileSet *SourceFileSet
Node Node
Err error
}
func (e *CompilerError) Error() string {
filePos := e.FileSet.Position(e.Node.Pos())
return fmt.Sprintf("Compile Error: %s\n\tat %s", e.Err.Error(), filePos)
}
// SymbolScope represents a symbol scope. // SymbolScope represents a symbol scope.
type SymbolScope string type SymbolScope string

View file

@ -1,10 +1,10 @@
package internal_test package tengo_test
import ( import (
"testing" "testing"
"github.com/d5/tengo/internal" "github.com/d5/tengo"
"github.com/d5/tengo/internal/require" "github.com/d5/tengo/require"
) )
func TestSymbolTable(t *testing.T) { func TestSymbolTable(t *testing.T) {
@ -93,37 +93,37 @@ func TestSymbolTable(t *testing.T) {
func symbol( func symbol(
name string, name string,
scope internal.SymbolScope, scope tengo.SymbolScope,
index int, index int,
) *internal.Symbol { ) *tengo.Symbol {
return &internal.Symbol{ return &tengo.Symbol{
Name: name, Name: name,
Scope: scope, Scope: scope,
Index: index, Index: index,
} }
} }
func globalSymbol(name string, index int) *internal.Symbol { func globalSymbol(name string, index int) *tengo.Symbol {
return symbol(name, internal.ScopeGlobal, index) return symbol(name, tengo.ScopeGlobal, index)
} }
func localSymbol(name string, index int) *internal.Symbol { func localSymbol(name string, index int) *tengo.Symbol {
return symbol(name, internal.ScopeLocal, index) return symbol(name, tengo.ScopeLocal, index)
} }
func freeSymbol(name string, index int) *internal.Symbol { func freeSymbol(name string, index int) *tengo.Symbol {
return symbol(name, internal.ScopeFree, index) return symbol(name, tengo.ScopeFree, index)
} }
func symbolTable() *internal.SymbolTable { func symbolTable() *tengo.SymbolTable {
return internal.NewSymbolTable() return tengo.NewSymbolTable()
} }
func resolveExpect( func resolveExpect(
t *testing.T, t *testing.T,
symbolTable *internal.SymbolTable, symbolTable *tengo.SymbolTable,
name string, name string,
expectedSymbol *internal.Symbol, expectedSymbol *tengo.Symbol,
expectedDepth int, expectedDepth int,
) { ) {
actualSymbol, actualDepth, ok := symbolTable.Resolve(name) actualSymbol, actualDepth, ok := symbolTable.Resolve(name)

View file

@ -6,16 +6,16 @@ import (
"time" "time"
"github.com/d5/tengo" "github.com/d5/tengo"
"github.com/d5/tengo/internal" "github.com/d5/tengo/parser"
"github.com/d5/tengo/internal/require" "github.com/d5/tengo/require"
) )
func TestInstructions_String(t *testing.T) { func TestInstructions_String(t *testing.T) {
assertInstructionString(t, assertInstructionString(t,
[][]byte{ [][]byte{
internal.MakeInstruction(internal.OpConstant, 1), tengo.MakeInstruction(parser.OpConstant, 1),
internal.MakeInstruction(internal.OpConstant, 2), tengo.MakeInstruction(parser.OpConstant, 2),
internal.MakeInstruction(internal.OpConstant, 65535), tengo.MakeInstruction(parser.OpConstant, 65535),
}, },
`0000 CONST 1 `0000 CONST 1
0003 CONST 2 0003 CONST 2
@ -23,9 +23,9 @@ func TestInstructions_String(t *testing.T) {
assertInstructionString(t, assertInstructionString(t,
[][]byte{ [][]byte{
internal.MakeInstruction(internal.OpBinaryOp, 11), tengo.MakeInstruction(parser.OpBinaryOp, 11),
internal.MakeInstruction(internal.OpConstant, 2), tengo.MakeInstruction(parser.OpConstant, 2),
internal.MakeInstruction(internal.OpConstant, 65535), tengo.MakeInstruction(parser.OpConstant, 65535),
}, },
`0000 BINARYOP 11 `0000 BINARYOP 11
0002 CONST 2 0002 CONST 2
@ -33,10 +33,10 @@ func TestInstructions_String(t *testing.T) {
assertInstructionString(t, assertInstructionString(t,
[][]byte{ [][]byte{
internal.MakeInstruction(internal.OpBinaryOp, 11), tengo.MakeInstruction(parser.OpBinaryOp, 11),
internal.MakeInstruction(internal.OpGetLocal, 1), tengo.MakeInstruction(parser.OpGetLocal, 1),
internal.MakeInstruction(internal.OpConstant, 2), tengo.MakeInstruction(parser.OpConstant, 2),
internal.MakeInstruction(internal.OpConstant, 65535), tengo.MakeInstruction(parser.OpConstant, 65535),
}, },
`0000 BINARYOP 11 `0000 BINARYOP 11
0002 GETL 1 0002 GETL 1
@ -45,15 +45,15 @@ func TestInstructions_String(t *testing.T) {
} }
func TestMakeInstruction(t *testing.T) { func TestMakeInstruction(t *testing.T) {
makeInstruction(t, []byte{internal.OpConstant, 0, 0}, makeInstruction(t, []byte{parser.OpConstant, 0, 0},
internal.OpConstant, 0) parser.OpConstant, 0)
makeInstruction(t, []byte{internal.OpConstant, 0, 1}, makeInstruction(t, []byte{parser.OpConstant, 0, 1},
internal.OpConstant, 1) parser.OpConstant, 1)
makeInstruction(t, []byte{internal.OpConstant, 255, 254}, makeInstruction(t, []byte{parser.OpConstant, 255, 254},
internal.OpConstant, 65534) parser.OpConstant, 65534)
makeInstruction(t, []byte{internal.OpPop}, internal.OpPop) makeInstruction(t, []byte{parser.OpPop}, parser.OpPop)
makeInstruction(t, []byte{internal.OpTrue}, internal.OpTrue) makeInstruction(t, []byte{parser.OpTrue}, parser.OpTrue)
makeInstruction(t, []byte{internal.OpFalse}, internal.OpFalse) makeInstruction(t, []byte{parser.OpFalse}, parser.OpFalse)
} }
func TestNumObjects(t *testing.T) { func TestNumObjects(t *testing.T) {
@ -123,15 +123,15 @@ func assertInstructionString(
concatted = append(concatted, e...) concatted = append(concatted, e...)
} }
require.Equal(t, expected, strings.Join( require.Equal(t, expected, strings.Join(
internal.FormatInstructions(concatted, 0), "\n")) tengo.FormatInstructions(concatted, 0), "\n"))
} }
func makeInstruction( func makeInstruction(
t *testing.T, t *testing.T,
expected []byte, expected []byte,
opcode internal.Opcode, opcode parser.Opcode,
operands ...int, operands ...int,
) { ) {
inst := internal.MakeInstruction(opcode, operands...) inst := tengo.MakeInstruction(opcode, operands...)
require.Equal(t, expected, inst) require.Equal(t, expected, inst)
} }

View file

@ -4,7 +4,7 @@ import (
"testing" "testing"
"github.com/d5/tengo" "github.com/d5/tengo"
"github.com/d5/tengo/internal/require" "github.com/d5/tengo/require"
) )
type VariableTest struct { type VariableTest struct {

96
vm.go
View file

@ -4,8 +4,8 @@ import (
"fmt" "fmt"
"sync/atomic" "sync/atomic"
"github.com/d5/tengo/internal" "github.com/d5/tengo/parser"
"github.com/d5/tengo/internal/token" "github.com/d5/tengo/token"
) )
// frame represents a function call frame. // frame represents a function call frame.
@ -22,7 +22,7 @@ type VM struct {
stack [StackSize]Object stack [StackSize]Object
sp int sp int
globals []Object globals []Object
fileSet *internal.SourceFileSet fileSet *parser.SourceFileSet
frames [MaxFrames]frame frames [MaxFrames]frame
framesIndex int framesIndex int
curFrame *frame curFrame *frame
@ -99,16 +99,16 @@ func (v *VM) run() {
v.ip++ v.ip++
switch v.curInsts[v.ip] { switch v.curInsts[v.ip] {
case internal.OpConstant: case parser.OpConstant:
v.ip += 2 v.ip += 2
cidx := int(v.curInsts[v.ip]) | int(v.curInsts[v.ip-1])<<8 cidx := int(v.curInsts[v.ip]) | int(v.curInsts[v.ip-1])<<8
v.stack[v.sp] = v.constants[cidx] v.stack[v.sp] = v.constants[cidx]
v.sp++ v.sp++
case internal.OpNull: case parser.OpNull:
v.stack[v.sp] = UndefinedValue v.stack[v.sp] = UndefinedValue
v.sp++ v.sp++
case internal.OpBinaryOp: case parser.OpBinaryOp:
v.ip++ v.ip++
right := v.stack[v.sp-1] right := v.stack[v.sp-1]
left := v.stack[v.sp-2] left := v.stack[v.sp-2]
@ -133,7 +133,7 @@ func (v *VM) run() {
v.stack[v.sp-2] = res v.stack[v.sp-2] = res
v.sp-- v.sp--
case internal.OpEqual: case parser.OpEqual:
right := v.stack[v.sp-1] right := v.stack[v.sp-1]
left := v.stack[v.sp-2] left := v.stack[v.sp-2]
v.sp -= 2 v.sp -= 2
@ -143,7 +143,7 @@ func (v *VM) run() {
v.stack[v.sp] = FalseValue v.stack[v.sp] = FalseValue
} }
v.sp++ v.sp++
case internal.OpNotEqual: case parser.OpNotEqual:
right := v.stack[v.sp-1] right := v.stack[v.sp-1]
left := v.stack[v.sp-2] left := v.stack[v.sp-2]
v.sp -= 2 v.sp -= 2
@ -153,15 +153,15 @@ func (v *VM) run() {
v.stack[v.sp] = TrueValue v.stack[v.sp] = TrueValue
} }
v.sp++ v.sp++
case internal.OpPop: case parser.OpPop:
v.sp-- v.sp--
case internal.OpTrue: case parser.OpTrue:
v.stack[v.sp] = TrueValue v.stack[v.sp] = TrueValue
v.sp++ v.sp++
case internal.OpFalse: case parser.OpFalse:
v.stack[v.sp] = FalseValue v.stack[v.sp] = FalseValue
v.sp++ v.sp++
case internal.OpLNot: case parser.OpLNot:
operand := v.stack[v.sp-1] operand := v.stack[v.sp-1]
v.sp-- v.sp--
if operand.IsFalsy() { if operand.IsFalsy() {
@ -170,7 +170,7 @@ func (v *VM) run() {
v.stack[v.sp] = FalseValue v.stack[v.sp] = FalseValue
} }
v.sp++ v.sp++
case internal.OpBComplement: case parser.OpBComplement:
operand := v.stack[v.sp-1] operand := v.stack[v.sp-1]
v.sp-- v.sp--
@ -189,7 +189,7 @@ func (v *VM) run() {
operand.TypeName()) operand.TypeName())
return return
} }
case internal.OpMinus: case parser.OpMinus:
operand := v.stack[v.sp-1] operand := v.stack[v.sp-1]
v.sp-- v.sp--
@ -217,14 +217,14 @@ func (v *VM) run() {
operand.TypeName()) operand.TypeName())
return return
} }
case internal.OpJumpFalsy: case parser.OpJumpFalsy:
v.ip += 2 v.ip += 2
v.sp-- v.sp--
if v.stack[v.sp].IsFalsy() { if v.stack[v.sp].IsFalsy() {
pos := int(v.curInsts[v.ip]) | int(v.curInsts[v.ip-1])<<8 pos := int(v.curInsts[v.ip]) | int(v.curInsts[v.ip-1])<<8
v.ip = pos - 1 v.ip = pos - 1
} }
case internal.OpAndJump: case parser.OpAndJump:
v.ip += 2 v.ip += 2
if v.stack[v.sp-1].IsFalsy() { if v.stack[v.sp-1].IsFalsy() {
pos := int(v.curInsts[v.ip]) | int(v.curInsts[v.ip-1])<<8 pos := int(v.curInsts[v.ip]) | int(v.curInsts[v.ip-1])<<8
@ -232,7 +232,7 @@ func (v *VM) run() {
} else { } else {
v.sp-- v.sp--
} }
case internal.OpOrJump: case parser.OpOrJump:
v.ip += 2 v.ip += 2
if v.stack[v.sp-1].IsFalsy() { if v.stack[v.sp-1].IsFalsy() {
v.sp-- v.sp--
@ -240,15 +240,15 @@ func (v *VM) run() {
pos := int(v.curInsts[v.ip]) | int(v.curInsts[v.ip-1])<<8 pos := int(v.curInsts[v.ip]) | int(v.curInsts[v.ip-1])<<8
v.ip = pos - 1 v.ip = pos - 1
} }
case internal.OpJump: case parser.OpJump:
pos := int(v.curInsts[v.ip+2]) | int(v.curInsts[v.ip+1])<<8 pos := int(v.curInsts[v.ip+2]) | int(v.curInsts[v.ip+1])<<8
v.ip = pos - 1 v.ip = pos - 1
case internal.OpSetGlobal: case parser.OpSetGlobal:
v.ip += 2 v.ip += 2
v.sp-- v.sp--
globalIndex := int(v.curInsts[v.ip]) | int(v.curInsts[v.ip-1])<<8 globalIndex := int(v.curInsts[v.ip]) | int(v.curInsts[v.ip-1])<<8
v.globals[globalIndex] = v.stack[v.sp] v.globals[globalIndex] = v.stack[v.sp]
case internal.OpSetSelGlobal: case parser.OpSetSelGlobal:
v.ip += 3 v.ip += 3
globalIndex := int(v.curInsts[v.ip-1]) | int(v.curInsts[v.ip-2])<<8 globalIndex := int(v.curInsts[v.ip-1]) | int(v.curInsts[v.ip-2])<<8
numSelectors := int(v.curInsts[v.ip]) numSelectors := int(v.curInsts[v.ip])
@ -265,13 +265,13 @@ func (v *VM) run() {
v.err = e v.err = e
return return
} }
case internal.OpGetGlobal: case parser.OpGetGlobal:
v.ip += 2 v.ip += 2
globalIndex := int(v.curInsts[v.ip]) | int(v.curInsts[v.ip-1])<<8 globalIndex := int(v.curInsts[v.ip]) | int(v.curInsts[v.ip-1])<<8
val := v.globals[globalIndex] val := v.globals[globalIndex]
v.stack[v.sp] = val v.stack[v.sp] = val
v.sp++ v.sp++
case internal.OpArray: case parser.OpArray:
v.ip += 2 v.ip += 2
numElements := int(v.curInsts[v.ip]) | int(v.curInsts[v.ip-1])<<8 numElements := int(v.curInsts[v.ip]) | int(v.curInsts[v.ip-1])<<8
@ -290,7 +290,7 @@ func (v *VM) run() {
v.stack[v.sp] = arr v.stack[v.sp] = arr
v.sp++ v.sp++
case internal.OpMap: case parser.OpMap:
v.ip += 2 v.ip += 2
numElements := int(v.curInsts[v.ip]) | int(v.curInsts[v.ip-1])<<8 numElements := int(v.curInsts[v.ip]) | int(v.curInsts[v.ip-1])<<8
kv := make(map[string]Object) kv := make(map[string]Object)
@ -309,7 +309,7 @@ func (v *VM) run() {
} }
v.stack[v.sp] = m v.stack[v.sp] = m
v.sp++ v.sp++
case internal.OpError: case parser.OpError:
value := v.stack[v.sp-1] value := v.stack[v.sp-1]
var e Object = &Error{ var e Object = &Error{
Value: value, Value: value,
@ -320,7 +320,7 @@ func (v *VM) run() {
return return
} }
v.stack[v.sp-1] = e v.stack[v.sp-1] = e
case internal.OpImmutable: case parser.OpImmutable:
value := v.stack[v.sp-1] value := v.stack[v.sp-1]
switch value := value.(type) { switch value := value.(type) {
case *Array: case *Array:
@ -344,7 +344,7 @@ func (v *VM) run() {
} }
v.stack[v.sp-1] = immutableMap v.stack[v.sp-1] = immutableMap
} }
case internal.OpIndex: case parser.OpIndex:
index := v.stack[v.sp-1] index := v.stack[v.sp-1]
left := v.stack[v.sp-2] left := v.stack[v.sp-2]
v.sp -= 2 v.sp -= 2
@ -368,7 +368,7 @@ func (v *VM) run() {
} }
v.stack[v.sp] = val v.stack[v.sp] = val
v.sp++ v.sp++
case internal.OpSliceIndex: case parser.OpSliceIndex:
high := v.stack[v.sp-1] high := v.stack[v.sp-1]
low := v.stack[v.sp-2] low := v.stack[v.sp-2]
left := v.stack[v.sp-3] left := v.stack[v.sp-3]
@ -535,7 +535,7 @@ func (v *VM) run() {
v.stack[v.sp] = val v.stack[v.sp] = val
v.sp++ v.sp++
} }
case internal.OpCall: case parser.OpCall:
numArgs := int(v.curInsts[v.ip+1]) numArgs := int(v.curInsts[v.ip+1])
v.ip++ v.ip++
value := v.stack[v.sp-1-numArgs] value := v.stack[v.sp-1-numArgs]
@ -576,9 +576,9 @@ func (v *VM) run() {
// test if it's tail-call // test if it's tail-call
if callee == v.curFrame.fn { // recursion if callee == v.curFrame.fn { // recursion
nextOp := v.curInsts[v.ip+1] nextOp := v.curInsts[v.ip+1]
if nextOp == internal.OpReturn || if nextOp == parser.OpReturn ||
(nextOp == internal.OpPop && (nextOp == parser.OpPop &&
internal.OpReturn == v.curInsts[v.ip+2]) { parser.OpReturn == v.curInsts[v.ip+2]) {
for p := 0; p < numArgs; p++ { for p := 0; p < numArgs; p++ {
v.stack[v.curFrame.basePointer+p] = v.stack[v.curFrame.basePointer+p] =
v.stack[v.sp-numArgs+p] v.stack[v.sp-numArgs+p]
@ -640,7 +640,7 @@ func (v *VM) run() {
v.stack[v.sp] = ret v.stack[v.sp] = ret
v.sp++ v.sp++
} }
case internal.OpReturn: case parser.OpReturn:
v.ip++ v.ip++
var retVal Object var retVal Object
if int(v.curInsts[v.ip]) == 1 { if int(v.curInsts[v.ip]) == 1 {
@ -658,7 +658,7 @@ func (v *VM) run() {
// skip stack overflow check because (newSP) <= (oldSP) // skip stack overflow check because (newSP) <= (oldSP)
v.stack[v.sp-1] = retVal v.stack[v.sp-1] = retVal
//v.sp++ //v.sp++
case internal.OpDefineLocal: case parser.OpDefineLocal:
v.ip++ v.ip++
localIndex := int(v.curInsts[v.ip]) localIndex := int(v.curInsts[v.ip])
sp := v.curFrame.basePointer + localIndex sp := v.curFrame.basePointer + localIndex
@ -668,7 +668,7 @@ func (v *VM) run() {
val := v.stack[v.sp-1] val := v.stack[v.sp-1]
v.sp-- v.sp--
v.stack[sp] = val v.stack[sp] = val
case internal.OpSetLocal: case parser.OpSetLocal:
localIndex := int(v.curInsts[v.ip+1]) localIndex := int(v.curInsts[v.ip+1])
v.ip++ v.ip++
sp := v.curFrame.basePointer + localIndex sp := v.curFrame.basePointer + localIndex
@ -683,7 +683,7 @@ func (v *VM) run() {
val = obj val = obj
} }
v.stack[sp] = val // also use a copy of popped value v.stack[sp] = val // also use a copy of popped value
case internal.OpSetSelLocal: case parser.OpSetSelLocal:
localIndex := int(v.curInsts[v.ip+1]) localIndex := int(v.curInsts[v.ip+1])
numSelectors := int(v.curInsts[v.ip+2]) numSelectors := int(v.curInsts[v.ip+2])
v.ip += 2 v.ip += 2
@ -703,7 +703,7 @@ func (v *VM) run() {
v.err = e v.err = e
return return
} }
case internal.OpGetLocal: case parser.OpGetLocal:
v.ip++ v.ip++
localIndex := int(v.curInsts[v.ip]) localIndex := int(v.curInsts[v.ip])
val := v.stack[v.curFrame.basePointer+localIndex] val := v.stack[v.curFrame.basePointer+localIndex]
@ -712,12 +712,12 @@ func (v *VM) run() {
} }
v.stack[v.sp] = val v.stack[v.sp] = val
v.sp++ v.sp++
case internal.OpGetBuiltin: case parser.OpGetBuiltin:
v.ip++ v.ip++
builtinIndex := int(v.curInsts[v.ip]) builtinIndex := int(v.curInsts[v.ip])
v.stack[v.sp] = builtinFuncs[builtinIndex] v.stack[v.sp] = builtinFuncs[builtinIndex]
v.sp++ v.sp++
case internal.OpClosure: case parser.OpClosure:
v.ip += 3 v.ip += 3
constIndex := int(v.curInsts[v.ip-1]) | int(v.curInsts[v.ip-2])<<8 constIndex := int(v.curInsts[v.ip-1]) | int(v.curInsts[v.ip-2])<<8
numFree := int(v.curInsts[v.ip]) numFree := int(v.curInsts[v.ip])
@ -752,24 +752,24 @@ func (v *VM) run() {
} }
v.stack[v.sp] = cl v.stack[v.sp] = cl
v.sp++ v.sp++
case internal.OpGetFreePtr: case parser.OpGetFreePtr:
v.ip++ v.ip++
freeIndex := int(v.curInsts[v.ip]) freeIndex := int(v.curInsts[v.ip])
val := v.curFrame.freeVars[freeIndex] val := v.curFrame.freeVars[freeIndex]
v.stack[v.sp] = val v.stack[v.sp] = val
v.sp++ v.sp++
case internal.OpGetFree: case parser.OpGetFree:
v.ip++ v.ip++
freeIndex := int(v.curInsts[v.ip]) freeIndex := int(v.curInsts[v.ip])
val := *v.curFrame.freeVars[freeIndex].Value val := *v.curFrame.freeVars[freeIndex].Value
v.stack[v.sp] = val v.stack[v.sp] = val
v.sp++ v.sp++
case internal.OpSetFree: case parser.OpSetFree:
v.ip++ v.ip++
freeIndex := int(v.curInsts[v.ip]) freeIndex := int(v.curInsts[v.ip])
*v.curFrame.freeVars[freeIndex].Value = v.stack[v.sp-1] *v.curFrame.freeVars[freeIndex].Value = v.stack[v.sp-1]
v.sp-- v.sp--
case internal.OpGetLocalPtr: case parser.OpGetLocalPtr:
v.ip++ v.ip++
localIndex := int(v.curInsts[v.ip]) localIndex := int(v.curInsts[v.ip])
sp := v.curFrame.basePointer + localIndex sp := v.curFrame.basePointer + localIndex
@ -783,7 +783,7 @@ func (v *VM) run() {
} }
v.stack[v.sp] = freeVar v.stack[v.sp] = freeVar
v.sp++ v.sp++
case internal.OpSetSelFree: case parser.OpSetSelFree:
v.ip += 2 v.ip += 2
freeIndex := int(v.curInsts[v.ip-1]) freeIndex := int(v.curInsts[v.ip-1])
numSelectors := int(v.curInsts[v.ip]) numSelectors := int(v.curInsts[v.ip])
@ -801,7 +801,7 @@ func (v *VM) run() {
v.err = e v.err = e
return return
} }
case internal.OpIteratorInit: case parser.OpIteratorInit:
var iterator Object var iterator Object
dst := v.stack[v.sp-1] dst := v.stack[v.sp-1]
v.sp-- v.sp--
@ -817,7 +817,7 @@ func (v *VM) run() {
} }
v.stack[v.sp] = iterator v.stack[v.sp] = iterator
v.sp++ v.sp++
case internal.OpIteratorNext: case parser.OpIteratorNext:
iterator := v.stack[v.sp-1] iterator := v.stack[v.sp-1]
v.sp-- v.sp--
hasMore := iterator.(Iterator).Next() hasMore := iterator.(Iterator).Next()
@ -827,19 +827,19 @@ func (v *VM) run() {
v.stack[v.sp] = FalseValue v.stack[v.sp] = FalseValue
} }
v.sp++ v.sp++
case internal.OpIteratorKey: case parser.OpIteratorKey:
iterator := v.stack[v.sp-1] iterator := v.stack[v.sp-1]
v.sp-- v.sp--
val := iterator.(Iterator).Key() val := iterator.(Iterator).Key()
v.stack[v.sp] = val v.stack[v.sp] = val
v.sp++ v.sp++
case internal.OpIteratorValue: case parser.OpIteratorValue:
iterator := v.stack[v.sp-1] iterator := v.stack[v.sp-1]
v.sp-- v.sp--
val := iterator.(Iterator).Value() val := iterator.(Iterator).Value()
v.stack[v.sp] = val v.stack[v.sp] = val
v.sp++ v.sp++
case internal.OpSuspend: case parser.OpSuspend:
return return
default: default:
v.err = fmt.Errorf("unknown opcode: %d", v.curInsts[v.ip]) v.err = fmt.Errorf("unknown opcode: %d", v.curInsts[v.ip])

View file

@ -11,10 +11,10 @@ import (
"testing" "testing"
"github.com/d5/tengo" "github.com/d5/tengo"
"github.com/d5/tengo/internal" "github.com/d5/tengo/parser"
"github.com/d5/tengo/internal/require" "github.com/d5/tengo/require"
"github.com/d5/tengo/internal/token"
"github.com/d5/tengo/stdlib" "github.com/d5/tengo/stdlib"
"github.com/d5/tengo/token"
) )
const testOut = "out" const testOut = "out"
@ -3276,7 +3276,7 @@ func (o *vmTracer) Write(p []byte) (n int, err error) {
} }
func traceCompileRun( func traceCompileRun(
file *internal.File, file *parser.File,
symbols map[string]tengo.Object, symbols map[string]tengo.Object,
modules *tengo.ModuleMap, modules *tengo.ModuleMap,
maxAllocs int64, maxAllocs int64,
@ -3306,7 +3306,7 @@ func traceCompileRun(
globals := make([]tengo.Object, tengo.GlobalsSize) globals := make([]tengo.Object, tengo.GlobalsSize)
symTable := internal.NewSymbolTable() symTable := tengo.NewSymbolTable()
for name, value := range symbols { for name, value := range symbols {
sym := symTable.Define(name) sym := symTable.Define(name)
@ -3371,11 +3371,11 @@ func formatGlobals(globals []tengo.Object) (formatted []string) {
return return
} }
func parse(t *testing.T, input string) *internal.File { func parse(t *testing.T, input string) *parser.File {
testFileSet := internal.NewFileSet() testFileSet := parser.NewFileSet()
testFile := testFileSet.AddFile("test", -1, len(input)) testFile := testFileSet.AddFile("test", -1, len(input))
p := internal.NewParser(testFile, []byte(input), nil) p := parser.NewParser(testFile, []byte(input), nil)
file, err := p.ParseFile() file, err := p.ParseFile()
require.NoError(t, err) require.NoError(t, err)
return file return file