fix internal package issue (#241)
* fix internal package issue * ExampleSimple -> Example
This commit is contained in:
parent
7cb058b564
commit
a9a233a750
40 changed files with 1187 additions and 1137 deletions
|
@ -121,7 +121,6 @@ each([a, b, c, d], func(x) {
|
|||
mul := compiled.Get("mul")
|
||||
fmt.Println(sum, mul) // "22 288"
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## References
|
||||
|
|
24
bytecode.go
24
bytecode.go
|
@ -6,12 +6,12 @@ import (
|
|||
"io"
|
||||
"reflect"
|
||||
|
||||
"github.com/d5/tengo/internal"
|
||||
"github.com/d5/tengo/parser"
|
||||
)
|
||||
|
||||
// Bytecode is a compiled instructions and constants.
|
||||
type Bytecode struct {
|
||||
FileSet *internal.SourceFileSet
|
||||
FileSet *parser.SourceFileSet
|
||||
MainFunction *CompiledFunction
|
||||
Constants []Object
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ func (b *Bytecode) CountObjects() int {
|
|||
// FormatInstructions returns human readable string representations of
|
||||
// compiled instructions.
|
||||
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
|
||||
|
@ -51,7 +51,7 @@ func (b *Bytecode) FormatConstants() (output []string) {
|
|||
case *CompiledFunction:
|
||||
output = append(output, fmt.Sprintf(
|
||||
"[% 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))
|
||||
}
|
||||
default:
|
||||
|
@ -239,25 +239,25 @@ func updateConstIndexes(insts []byte, indexMap map[int]int) {
|
|||
i := 0
|
||||
for i < len(insts) {
|
||||
op := insts[i]
|
||||
numOperands := internal.OpcodeOperands[op]
|
||||
_, read := internal.ReadOperands(numOperands, insts[i+1:])
|
||||
numOperands := parser.OpcodeOperands[op]
|
||||
_, read := parser.ReadOperands(numOperands, insts[i+1:])
|
||||
|
||||
switch op {
|
||||
case internal.OpConstant:
|
||||
case parser.OpConstant:
|
||||
curIdx := int(insts[i+2]) | int(insts[i+1])<<8
|
||||
newIdx, ok := indexMap[curIdx]
|
||||
if !ok {
|
||||
panic(fmt.Errorf("constant index not found: %d", curIdx))
|
||||
}
|
||||
copy(insts[i:], internal.MakeInstruction(op, newIdx))
|
||||
case internal.OpClosure:
|
||||
copy(insts[i:], MakeInstruction(op, newIdx))
|
||||
case parser.OpClosure:
|
||||
curIdx := int(insts[i+2]) | int(insts[i+1])<<8
|
||||
numFree := int(insts[i+3])
|
||||
newIdx, ok := indexMap[curIdx]
|
||||
if !ok {
|
||||
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
|
||||
|
@ -272,8 +272,8 @@ func inferModuleName(mod *ImmutableMap) string {
|
|||
}
|
||||
|
||||
func init() {
|
||||
gob.Register(&internal.SourceFileSet{})
|
||||
gob.Register(&internal.SourceFile{})
|
||||
gob.Register(&parser.SourceFileSet{})
|
||||
gob.Register(&parser.SourceFile{})
|
||||
gob.Register(&Array{})
|
||||
gob.Register(&Bool{})
|
||||
gob.Register(&Bytes{})
|
||||
|
|
176
bytecode_test.go
176
bytecode_test.go
|
@ -6,8 +6,8 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/d5/tengo"
|
||||
"github.com/d5/tengo/internal"
|
||||
"github.com/d5/tengo/internal/require"
|
||||
"github.com/d5/tengo/parser"
|
||||
"github.com/d5/tengo/require"
|
||||
)
|
||||
|
||||
type srcfile struct {
|
||||
|
@ -23,20 +23,20 @@ func TestBytecode(t *testing.T) {
|
|||
&tengo.Char{Value: 'y'},
|
||||
&tengo.Float{Value: 93.11},
|
||||
compiledFunction(1, 0,
|
||||
internal.MakeInstruction(internal.OpConstant, 3),
|
||||
internal.MakeInstruction(internal.OpSetLocal, 0),
|
||||
internal.MakeInstruction(internal.OpGetGlobal, 0),
|
||||
internal.MakeInstruction(internal.OpGetFree, 0)),
|
||||
tengo.MakeInstruction(parser.OpConstant, 3),
|
||||
tengo.MakeInstruction(parser.OpSetLocal, 0),
|
||||
tengo.MakeInstruction(parser.OpGetGlobal, 0),
|
||||
tengo.MakeInstruction(parser.OpGetFree, 0)),
|
||||
&tengo.Float{Value: 39.2},
|
||||
&tengo.Int{Value: 192},
|
||||
&tengo.String{Value: "bar"})))
|
||||
|
||||
testBytecodeSerialization(t, bytecodeFileSet(
|
||||
concatInsts(
|
||||
internal.MakeInstruction(internal.OpConstant, 0),
|
||||
internal.MakeInstruction(internal.OpSetGlobal, 0),
|
||||
internal.MakeInstruction(internal.OpConstant, 6),
|
||||
internal.MakeInstruction(internal.OpPop)),
|
||||
tengo.MakeInstruction(parser.OpConstant, 0),
|
||||
tengo.MakeInstruction(parser.OpSetGlobal, 0),
|
||||
tengo.MakeInstruction(parser.OpConstant, 6),
|
||||
tengo.MakeInstruction(parser.OpPop)),
|
||||
objectsArray(
|
||||
&tengo.Int{Value: 55},
|
||||
&tengo.Int{Value: 66},
|
||||
|
@ -99,29 +99,29 @@ func TestBytecode(t *testing.T) {
|
|||
},
|
||||
},
|
||||
compiledFunction(1, 0,
|
||||
internal.MakeInstruction(internal.OpConstant, 3),
|
||||
internal.MakeInstruction(internal.OpSetLocal, 0),
|
||||
internal.MakeInstruction(internal.OpGetGlobal, 0),
|
||||
internal.MakeInstruction(internal.OpGetFree, 0),
|
||||
internal.MakeInstruction(internal.OpBinaryOp, 11),
|
||||
internal.MakeInstruction(internal.OpGetFree, 1),
|
||||
internal.MakeInstruction(internal.OpBinaryOp, 11),
|
||||
internal.MakeInstruction(internal.OpGetLocal, 0),
|
||||
internal.MakeInstruction(internal.OpBinaryOp, 11),
|
||||
internal.MakeInstruction(internal.OpReturn, 1)),
|
||||
tengo.MakeInstruction(parser.OpConstant, 3),
|
||||
tengo.MakeInstruction(parser.OpSetLocal, 0),
|
||||
tengo.MakeInstruction(parser.OpGetGlobal, 0),
|
||||
tengo.MakeInstruction(parser.OpGetFree, 0),
|
||||
tengo.MakeInstruction(parser.OpBinaryOp, 11),
|
||||
tengo.MakeInstruction(parser.OpGetFree, 1),
|
||||
tengo.MakeInstruction(parser.OpBinaryOp, 11),
|
||||
tengo.MakeInstruction(parser.OpGetLocal, 0),
|
||||
tengo.MakeInstruction(parser.OpBinaryOp, 11),
|
||||
tengo.MakeInstruction(parser.OpReturn, 1)),
|
||||
compiledFunction(1, 0,
|
||||
internal.MakeInstruction(internal.OpConstant, 2),
|
||||
internal.MakeInstruction(internal.OpSetLocal, 0),
|
||||
internal.MakeInstruction(internal.OpGetFree, 0),
|
||||
internal.MakeInstruction(internal.OpGetLocal, 0),
|
||||
internal.MakeInstruction(internal.OpClosure, 4, 2),
|
||||
internal.MakeInstruction(internal.OpReturn, 1)),
|
||||
tengo.MakeInstruction(parser.OpConstant, 2),
|
||||
tengo.MakeInstruction(parser.OpSetLocal, 0),
|
||||
tengo.MakeInstruction(parser.OpGetFree, 0),
|
||||
tengo.MakeInstruction(parser.OpGetLocal, 0),
|
||||
tengo.MakeInstruction(parser.OpClosure, 4, 2),
|
||||
tengo.MakeInstruction(parser.OpReturn, 1)),
|
||||
compiledFunction(1, 0,
|
||||
internal.MakeInstruction(internal.OpConstant, 1),
|
||||
internal.MakeInstruction(internal.OpSetLocal, 0),
|
||||
internal.MakeInstruction(internal.OpGetLocal, 0),
|
||||
internal.MakeInstruction(internal.OpClosure, 5, 1),
|
||||
internal.MakeInstruction(internal.OpReturn, 1))),
|
||||
tengo.MakeInstruction(parser.OpConstant, 1),
|
||||
tengo.MakeInstruction(parser.OpSetLocal, 0),
|
||||
tengo.MakeInstruction(parser.OpGetLocal, 0),
|
||||
tengo.MakeInstruction(parser.OpClosure, 5, 1),
|
||||
tengo.MakeInstruction(parser.OpReturn, 1))),
|
||||
fileSet(srcfile{name: "file1", size: 100},
|
||||
srcfile{name: "file2", size: 200})))
|
||||
}
|
||||
|
@ -133,10 +133,10 @@ func TestBytecode_RemoveDuplicates(t *testing.T) {
|
|||
&tengo.Char{Value: 'y'},
|
||||
&tengo.Float{Value: 93.11},
|
||||
compiledFunction(1, 0,
|
||||
internal.MakeInstruction(internal.OpConstant, 3),
|
||||
internal.MakeInstruction(internal.OpSetLocal, 0),
|
||||
internal.MakeInstruction(internal.OpGetGlobal, 0),
|
||||
internal.MakeInstruction(internal.OpGetFree, 0)),
|
||||
tengo.MakeInstruction(parser.OpConstant, 3),
|
||||
tengo.MakeInstruction(parser.OpSetLocal, 0),
|
||||
tengo.MakeInstruction(parser.OpGetGlobal, 0),
|
||||
tengo.MakeInstruction(parser.OpGetFree, 0)),
|
||||
&tengo.Float{Value: 39.2},
|
||||
&tengo.Int{Value: 192},
|
||||
&tengo.String{Value: "bar"})),
|
||||
|
@ -145,10 +145,10 @@ func TestBytecode_RemoveDuplicates(t *testing.T) {
|
|||
&tengo.Char{Value: 'y'},
|
||||
&tengo.Float{Value: 93.11},
|
||||
compiledFunction(1, 0,
|
||||
internal.MakeInstruction(internal.OpConstant, 3),
|
||||
internal.MakeInstruction(internal.OpSetLocal, 0),
|
||||
internal.MakeInstruction(internal.OpGetGlobal, 0),
|
||||
internal.MakeInstruction(internal.OpGetFree, 0)),
|
||||
tengo.MakeInstruction(parser.OpConstant, 3),
|
||||
tengo.MakeInstruction(parser.OpSetLocal, 0),
|
||||
tengo.MakeInstruction(parser.OpGetGlobal, 0),
|
||||
tengo.MakeInstruction(parser.OpGetFree, 0)),
|
||||
&tengo.Float{Value: 39.2},
|
||||
&tengo.Int{Value: 192},
|
||||
&tengo.String{Value: "bar"})))
|
||||
|
@ -156,63 +156,63 @@ func TestBytecode_RemoveDuplicates(t *testing.T) {
|
|||
testBytecodeRemoveDuplicates(t,
|
||||
bytecode(
|
||||
concatInsts(
|
||||
internal.MakeInstruction(internal.OpConstant, 0),
|
||||
internal.MakeInstruction(internal.OpConstant, 1),
|
||||
internal.MakeInstruction(internal.OpConstant, 2),
|
||||
internal.MakeInstruction(internal.OpConstant, 3),
|
||||
internal.MakeInstruction(internal.OpConstant, 4),
|
||||
internal.MakeInstruction(internal.OpConstant, 5),
|
||||
internal.MakeInstruction(internal.OpConstant, 6),
|
||||
internal.MakeInstruction(internal.OpConstant, 7),
|
||||
internal.MakeInstruction(internal.OpConstant, 8),
|
||||
internal.MakeInstruction(internal.OpClosure, 4, 1)),
|
||||
tengo.MakeInstruction(parser.OpConstant, 0),
|
||||
tengo.MakeInstruction(parser.OpConstant, 1),
|
||||
tengo.MakeInstruction(parser.OpConstant, 2),
|
||||
tengo.MakeInstruction(parser.OpConstant, 3),
|
||||
tengo.MakeInstruction(parser.OpConstant, 4),
|
||||
tengo.MakeInstruction(parser.OpConstant, 5),
|
||||
tengo.MakeInstruction(parser.OpConstant, 6),
|
||||
tengo.MakeInstruction(parser.OpConstant, 7),
|
||||
tengo.MakeInstruction(parser.OpConstant, 8),
|
||||
tengo.MakeInstruction(parser.OpClosure, 4, 1)),
|
||||
objectsArray(
|
||||
&tengo.Int{Value: 1},
|
||||
&tengo.Float{Value: 2.0},
|
||||
&tengo.Char{Value: '3'},
|
||||
&tengo.String{Value: "four"},
|
||||
compiledFunction(1, 0,
|
||||
internal.MakeInstruction(internal.OpConstant, 3),
|
||||
internal.MakeInstruction(internal.OpConstant, 7),
|
||||
internal.MakeInstruction(internal.OpSetLocal, 0),
|
||||
internal.MakeInstruction(internal.OpGetGlobal, 0),
|
||||
internal.MakeInstruction(internal.OpGetFree, 0)),
|
||||
tengo.MakeInstruction(parser.OpConstant, 3),
|
||||
tengo.MakeInstruction(parser.OpConstant, 7),
|
||||
tengo.MakeInstruction(parser.OpSetLocal, 0),
|
||||
tengo.MakeInstruction(parser.OpGetGlobal, 0),
|
||||
tengo.MakeInstruction(parser.OpGetFree, 0)),
|
||||
&tengo.Int{Value: 1},
|
||||
&tengo.Float{Value: 2.0},
|
||||
&tengo.Char{Value: '3'},
|
||||
&tengo.String{Value: "four"})),
|
||||
bytecode(
|
||||
concatInsts(
|
||||
internal.MakeInstruction(internal.OpConstant, 0),
|
||||
internal.MakeInstruction(internal.OpConstant, 1),
|
||||
internal.MakeInstruction(internal.OpConstant, 2),
|
||||
internal.MakeInstruction(internal.OpConstant, 3),
|
||||
internal.MakeInstruction(internal.OpConstant, 4),
|
||||
internal.MakeInstruction(internal.OpConstant, 0),
|
||||
internal.MakeInstruction(internal.OpConstant, 1),
|
||||
internal.MakeInstruction(internal.OpConstant, 2),
|
||||
internal.MakeInstruction(internal.OpConstant, 3),
|
||||
internal.MakeInstruction(internal.OpClosure, 4, 1)),
|
||||
tengo.MakeInstruction(parser.OpConstant, 0),
|
||||
tengo.MakeInstruction(parser.OpConstant, 1),
|
||||
tengo.MakeInstruction(parser.OpConstant, 2),
|
||||
tengo.MakeInstruction(parser.OpConstant, 3),
|
||||
tengo.MakeInstruction(parser.OpConstant, 4),
|
||||
tengo.MakeInstruction(parser.OpConstant, 0),
|
||||
tengo.MakeInstruction(parser.OpConstant, 1),
|
||||
tengo.MakeInstruction(parser.OpConstant, 2),
|
||||
tengo.MakeInstruction(parser.OpConstant, 3),
|
||||
tengo.MakeInstruction(parser.OpClosure, 4, 1)),
|
||||
objectsArray(
|
||||
&tengo.Int{Value: 1},
|
||||
&tengo.Float{Value: 2.0},
|
||||
&tengo.Char{Value: '3'},
|
||||
&tengo.String{Value: "four"},
|
||||
compiledFunction(1, 0,
|
||||
internal.MakeInstruction(internal.OpConstant, 3),
|
||||
internal.MakeInstruction(internal.OpConstant, 2),
|
||||
internal.MakeInstruction(internal.OpSetLocal, 0),
|
||||
internal.MakeInstruction(internal.OpGetGlobal, 0),
|
||||
internal.MakeInstruction(internal.OpGetFree, 0)))))
|
||||
tengo.MakeInstruction(parser.OpConstant, 3),
|
||||
tengo.MakeInstruction(parser.OpConstant, 2),
|
||||
tengo.MakeInstruction(parser.OpSetLocal, 0),
|
||||
tengo.MakeInstruction(parser.OpGetGlobal, 0),
|
||||
tengo.MakeInstruction(parser.OpGetFree, 0)))))
|
||||
|
||||
testBytecodeRemoveDuplicates(t,
|
||||
bytecode(
|
||||
concatInsts(
|
||||
internal.MakeInstruction(internal.OpConstant, 0),
|
||||
internal.MakeInstruction(internal.OpConstant, 1),
|
||||
internal.MakeInstruction(internal.OpConstant, 2),
|
||||
internal.MakeInstruction(internal.OpConstant, 3),
|
||||
internal.MakeInstruction(internal.OpConstant, 4)),
|
||||
tengo.MakeInstruction(parser.OpConstant, 0),
|
||||
tengo.MakeInstruction(parser.OpConstant, 1),
|
||||
tengo.MakeInstruction(parser.OpConstant, 2),
|
||||
tengo.MakeInstruction(parser.OpConstant, 3),
|
||||
tengo.MakeInstruction(parser.OpConstant, 4)),
|
||||
objectsArray(
|
||||
&tengo.Int{Value: 1},
|
||||
&tengo.Int{Value: 2},
|
||||
|
@ -221,11 +221,11 @@ func TestBytecode_RemoveDuplicates(t *testing.T) {
|
|||
&tengo.Int{Value: 3})),
|
||||
bytecode(
|
||||
concatInsts(
|
||||
internal.MakeInstruction(internal.OpConstant, 0),
|
||||
internal.MakeInstruction(internal.OpConstant, 1),
|
||||
internal.MakeInstruction(internal.OpConstant, 2),
|
||||
internal.MakeInstruction(internal.OpConstant, 0),
|
||||
internal.MakeInstruction(internal.OpConstant, 2)),
|
||||
tengo.MakeInstruction(parser.OpConstant, 0),
|
||||
tengo.MakeInstruction(parser.OpConstant, 1),
|
||||
tengo.MakeInstruction(parser.OpConstant, 2),
|
||||
tengo.MakeInstruction(parser.OpConstant, 0),
|
||||
tengo.MakeInstruction(parser.OpConstant, 2)),
|
||||
objectsArray(
|
||||
&tengo.Int{Value: 1},
|
||||
&tengo.Int{Value: 2},
|
||||
|
@ -241,19 +241,19 @@ func TestBytecode_CountObjects(t *testing.T) {
|
|||
&tengo.Int{Value: 77},
|
||||
&tengo.Int{Value: 88},
|
||||
compiledFunction(1, 0,
|
||||
internal.MakeInstruction(internal.OpConstant, 3),
|
||||
internal.MakeInstruction(internal.OpReturn, 1)),
|
||||
tengo.MakeInstruction(parser.OpConstant, 3),
|
||||
tengo.MakeInstruction(parser.OpReturn, 1)),
|
||||
compiledFunction(1, 0,
|
||||
internal.MakeInstruction(internal.OpConstant, 2),
|
||||
internal.MakeInstruction(internal.OpReturn, 1)),
|
||||
tengo.MakeInstruction(parser.OpConstant, 2),
|
||||
tengo.MakeInstruction(parser.OpReturn, 1)),
|
||||
compiledFunction(1, 0,
|
||||
internal.MakeInstruction(internal.OpConstant, 1),
|
||||
internal.MakeInstruction(internal.OpReturn, 1))))
|
||||
tengo.MakeInstruction(parser.OpConstant, 1),
|
||||
tengo.MakeInstruction(parser.OpReturn, 1))))
|
||||
require.Equal(t, 7, b.CountObjects())
|
||||
}
|
||||
|
||||
func fileSet(files ...srcfile) *internal.SourceFileSet {
|
||||
fileSet := internal.NewFileSet()
|
||||
func fileSet(files ...srcfile) *parser.SourceFileSet {
|
||||
fileSet := parser.NewFileSet()
|
||||
for _, f := range files {
|
||||
fileSet.AddFile(f.name, -1, f.size)
|
||||
}
|
||||
|
@ -263,7 +263,7 @@ func fileSet(files ...srcfile) *internal.SourceFileSet {
|
|||
func bytecodeFileSet(
|
||||
instructions []byte,
|
||||
constants []tengo.Object,
|
||||
fileSet *internal.SourceFileSet,
|
||||
fileSet *parser.SourceFileSet,
|
||||
) *tengo.Bytecode {
|
||||
return &tengo.Bytecode{
|
||||
FileSet: fileSet,
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/d5/tengo"
|
||||
"github.com/d5/tengo/internal"
|
||||
"github.com/d5/tengo/parser"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
@ -163,7 +163,7 @@ func runBench(
|
|||
result tengo.Object,
|
||||
err error,
|
||||
) {
|
||||
var astFile *internal.File
|
||||
var astFile *parser.File
|
||||
parseTime, astFile, err = parse(input)
|
||||
if err != nil {
|
||||
return
|
||||
|
@ -180,13 +180,13 @@ func runBench(
|
|||
return
|
||||
}
|
||||
|
||||
func parse(input []byte) (time.Duration, *internal.File, error) {
|
||||
fileSet := internal.NewFileSet()
|
||||
func parse(input []byte) (time.Duration, *parser.File, error) {
|
||||
fileSet := parser.NewFileSet()
|
||||
inputFile := fileSet.AddFile("bench", -1, len(input))
|
||||
|
||||
start := time.Now()
|
||||
|
||||
p := internal.NewParser(inputFile, input, nil)
|
||||
p := parser.NewParser(inputFile, input, nil)
|
||||
file, err := p.ParseFile()
|
||||
if err != nil {
|
||||
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
|
||||
}
|
||||
|
||||
func compileFile(file *internal.File) (time.Duration, *tengo.Bytecode, error) {
|
||||
symTable := internal.NewSymbolTable()
|
||||
func compileFile(file *parser.File) (time.Duration, *tengo.Bytecode, error) {
|
||||
symTable := tengo.NewSymbolTable()
|
||||
symTable.Define("out")
|
||||
|
||||
start := time.Now()
|
||||
|
|
|
@ -12,7 +12,7 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/d5/tengo"
|
||||
"github.com/d5/tengo/internal"
|
||||
"github.com/d5/tengo/parser"
|
||||
"github.com/d5/tengo/stdlib"
|
||||
)
|
||||
|
||||
|
@ -148,9 +148,9 @@ func RunCompiled(modules *tengo.ModuleMap, data []byte) (err error) {
|
|||
// RunREPL starts REPL.
|
||||
func RunREPL(modules *tengo.ModuleMap, in io.Reader, out io.Writer) {
|
||||
stdin := bufio.NewScanner(in)
|
||||
fileSet := internal.NewFileSet()
|
||||
fileSet := parser.NewFileSet()
|
||||
globals := make([]tengo.Object, tengo.GlobalsSize)
|
||||
symbolTable := internal.NewSymbolTable()
|
||||
symbolTable := tengo.NewSymbolTable()
|
||||
for idx, fn := range tengo.GetAllBuiltinFunctions() {
|
||||
symbolTable.DefineBuiltin(idx, fn.Name)
|
||||
}
|
||||
|
@ -185,7 +185,7 @@ func RunREPL(modules *tengo.ModuleMap, in io.Reader, out io.Writer) {
|
|||
|
||||
line := stdin.Text()
|
||||
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()
|
||||
if err != nil {
|
||||
_, _ = fmt.Fprintln(out, err.Error())
|
||||
|
@ -214,10 +214,10 @@ func compileSrc(
|
|||
src []byte,
|
||||
filename string,
|
||||
) (*tengo.Bytecode, error) {
|
||||
fileSet := internal.NewFileSet()
|
||||
fileSet := parser.NewFileSet()
|
||||
srcFile := fileSet.AddFile(filename, -1, len(src))
|
||||
|
||||
p := internal.NewParser(srcFile, src, nil)
|
||||
p := parser.NewParser(srcFile, src, nil)
|
||||
file, err := p.ParseFile()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -267,23 +267,23 @@ func doHelp() {
|
|||
fmt.Println()
|
||||
}
|
||||
|
||||
func addPrints(file *internal.File) *internal.File {
|
||||
var stmts []internal.Stmt
|
||||
func addPrints(file *parser.File) *parser.File {
|
||||
var stmts []parser.Stmt
|
||||
for _, s := range file.Stmts {
|
||||
switch s := s.(type) {
|
||||
case *internal.ExprStmt:
|
||||
stmts = append(stmts, &internal.ExprStmt{
|
||||
Expr: &internal.CallExpr{
|
||||
Func: &internal.Ident{Name: "__repl_println__"},
|
||||
Args: []internal.Expr{s.Expr},
|
||||
case *parser.ExprStmt:
|
||||
stmts = append(stmts, &parser.ExprStmt{
|
||||
Expr: &parser.CallExpr{
|
||||
Func: &parser.Ident{Name: "__repl_println__"},
|
||||
Args: []parser.Expr{s.Expr},
|
||||
},
|
||||
})
|
||||
case *internal.AssignStmt:
|
||||
case *parser.AssignStmt:
|
||||
stmts = append(stmts, s)
|
||||
|
||||
stmts = append(stmts, &internal.ExprStmt{
|
||||
Expr: &internal.CallExpr{
|
||||
Func: &internal.Ident{
|
||||
stmts = append(stmts, &parser.ExprStmt{
|
||||
Expr: &parser.CallExpr{
|
||||
Func: &parser.Ident{
|
||||
Name: "__repl_println__",
|
||||
},
|
||||
Args: s.LHS,
|
||||
|
@ -293,7 +293,7 @@ func addPrints(file *internal.File) *internal.File {
|
|||
stmts = append(stmts, s)
|
||||
}
|
||||
}
|
||||
return &internal.File{
|
||||
return &parser.File{
|
||||
InputFile: file.InputFile,
|
||||
Stmts: stmts,
|
||||
}
|
||||
|
|
465
compiler.go
465
compiler.go
File diff suppressed because it is too large
Load diff
1132
compiler_test.go
1132
compiler_test.go
File diff suppressed because it is too large
Load diff
3
doc.go
Normal file
3
doc.go
Normal file
|
@ -0,0 +1,3 @@
|
|||
// tengo is a small, dynamic, fast, secure script language for Go.
|
||||
|
||||
package tengo
|
46
example_test.go
Normal file
46
example_test.go
Normal 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
|
||||
}
|
|
@ -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.
|
||||
func MakeInstruction(opcode Opcode, operands ...int) []byte {
|
||||
numOperands := OpcodeOperands[opcode]
|
||||
func MakeInstruction(opcode parser.Opcode, operands ...int) []byte {
|
||||
numOperands := parser.OpcodeOperands[opcode]
|
||||
|
||||
totalLen := 1
|
||||
for _, w := range numOperands {
|
||||
|
@ -36,19 +40,19 @@ func FormatInstructions(b []byte, posOffset int) []string {
|
|||
|
||||
i := 0
|
||||
for i < len(b) {
|
||||
numOperands := OpcodeOperands[b[i]]
|
||||
operands, read := ReadOperands(numOperands, b[i+1:])
|
||||
numOperands := parser.OpcodeOperands[b[i]]
|
||||
operands, read := parser.ReadOperands(numOperands, b[i+1:])
|
||||
|
||||
switch len(numOperands) {
|
||||
case 0:
|
||||
out = append(out, fmt.Sprintf("%04d %-7s",
|
||||
posOffset+i, OpcodeNames[b[i]]))
|
||||
posOffset+i, parser.OpcodeNames[b[i]]))
|
||||
case 1:
|
||||
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:
|
||||
out = append(out, fmt.Sprintf("%04d %-7s %-5d %-5d",
|
||||
posOffset+i, OpcodeNames[b[i]],
|
||||
posOffset+i, parser.OpcodeNames[b[i]],
|
||||
operands[0], operands[1]))
|
||||
}
|
||||
i += 1 + read
|
10
objects.go
10
objects.go
|
@ -8,8 +8,8 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/d5/tengo/internal"
|
||||
"github.com/d5/tengo/internal/token"
|
||||
"github.com/d5/tengo/parser"
|
||||
"github.com/d5/tengo/token"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -574,7 +574,7 @@ type CompiledFunction struct {
|
|||
NumLocals int // number of local variables (including function parameters)
|
||||
NumParameters int
|
||||
VarArgs bool
|
||||
SourceMap map[int]internal.Pos
|
||||
SourceMap map[int]parser.Pos
|
||||
Free []*ObjectPtr
|
||||
}
|
||||
|
||||
|
@ -605,14 +605,14 @@ func (o *CompiledFunction) Equals(_ Object) bool {
|
|||
}
|
||||
|
||||
// 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 {
|
||||
if p, ok := o.SourceMap[ip]; ok {
|
||||
return p
|
||||
}
|
||||
ip--
|
||||
}
|
||||
return internal.NoPos
|
||||
return parser.NoPos
|
||||
}
|
||||
|
||||
// CanCall returns whether the Object can be Called.
|
||||
|
|
|
@ -4,8 +4,8 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/d5/tengo"
|
||||
"github.com/d5/tengo/internal/require"
|
||||
"github.com/d5/tengo/internal/token"
|
||||
"github.com/d5/tengo/require"
|
||||
"github.com/d5/tengo/token"
|
||||
)
|
||||
|
||||
func TestObject_TypeName(t *testing.T) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package internal
|
||||
package parser
|
||||
|
||||
import (
|
||||
"strings"
|
|
@ -1,14 +1,14 @@
|
|||
package internal_test
|
||||
package parser_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/d5/tengo/internal"
|
||||
"github.com/d5/tengo/parser"
|
||||
)
|
||||
|
||||
func TestIdentListString(t *testing.T) {
|
||||
identListVar := &internal.IdentList{
|
||||
List: []*internal.Ident{
|
||||
identListVar := &parser.IdentList{
|
||||
List: []*parser.Ident{
|
||||
{Name: "a"},
|
||||
{Name: "b"},
|
||||
{Name: "c"},
|
||||
|
@ -22,8 +22,8 @@ func TestIdentListString(t *testing.T) {
|
|||
identListVar, expectedVar, str)
|
||||
}
|
||||
|
||||
identList := &internal.IdentList{
|
||||
List: []*internal.Ident{
|
||||
identList := &parser.IdentList{
|
||||
List: []*parser.Ident{
|
||||
{Name: "a"},
|
||||
{Name: "b"},
|
||||
{Name: "c"},
|
|
@ -1,9 +1,9 @@
|
|||
package internal
|
||||
package parser
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/d5/tengo/internal/token"
|
||||
"github.com/d5/tengo/token"
|
||||
)
|
||||
|
||||
// Expr represents an expression node in the AST.
|
|
@ -1,4 +1,4 @@
|
|||
package internal
|
||||
package parser
|
||||
|
||||
import (
|
||||
"strings"
|
|
@ -1,4 +1,4 @@
|
|||
package internal
|
||||
package parser
|
||||
|
||||
// Opcode represents a single byte operation code.
|
||||
type Opcode = byte
|
|
@ -1,4 +1,4 @@
|
|||
package internal
|
||||
package parser
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
@ -6,7 +6,7 @@ import (
|
|||
"sort"
|
||||
"strconv"
|
||||
|
||||
"github.com/d5/tengo/internal/token"
|
||||
"github.com/d5/tengo/token"
|
||||
)
|
||||
|
||||
type bailout struct{}
|
||||
|
@ -20,37 +20,37 @@ var stmtStart = map[token.Token]bool{
|
|||
token.Export: true,
|
||||
}
|
||||
|
||||
// ParserError represents a parser error.
|
||||
type ParserError struct {
|
||||
// Error represents a parser error.
|
||||
type Error struct {
|
||||
Pos SourceFilePos
|
||||
Msg string
|
||||
}
|
||||
|
||||
func (e ParserError) Error() string {
|
||||
func (e Error) Error() string {
|
||||
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", e.Msg)
|
||||
}
|
||||
|
||||
// ParserErrorList is a collection of parser errors.
|
||||
type ParserErrorList []*ParserError
|
||||
// ErrorList is a collection of parser errors.
|
||||
type ErrorList []*Error
|
||||
|
||||
// Add adds a new parser error to the collection.
|
||||
func (p *ParserErrorList) Add(pos SourceFilePos, msg string) {
|
||||
*p = append(*p, &ParserError{pos, msg})
|
||||
func (p *ErrorList) Add(pos SourceFilePos, msg string) {
|
||||
*p = append(*p, &Error{pos, msg})
|
||||
}
|
||||
|
||||
// Len returns the number of elements in the collection.
|
||||
func (p ParserErrorList) Len() int {
|
||||
func (p ErrorList) Len() int {
|
||||
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]
|
||||
}
|
||||
|
||||
func (p ParserErrorList) Less(i, j int) bool {
|
||||
func (p ErrorList) Less(i, j int) bool {
|
||||
e := &p[i].Pos
|
||||
f := &p[j].Pos
|
||||
|
||||
|
@ -67,11 +67,11 @@ func (p ParserErrorList) Less(i, j int) bool {
|
|||
}
|
||||
|
||||
// Sort sorts the collection.
|
||||
func (p ParserErrorList) Sort() {
|
||||
func (p ErrorList) Sort() {
|
||||
sort.Sort(p)
|
||||
}
|
||||
|
||||
func (p ParserErrorList) Error() string {
|
||||
func (p ErrorList) Error() string {
|
||||
switch len(p) {
|
||||
case 0:
|
||||
return "no errors"
|
||||
|
@ -82,7 +82,7 @@ func (p ParserErrorList) Error() string {
|
|||
}
|
||||
|
||||
// Err returns an error.
|
||||
func (p ParserErrorList) Err() error {
|
||||
func (p ErrorList) Err() error {
|
||||
if len(p) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ func (p ParserErrorList) Err() error {
|
|||
// implementation.
|
||||
type Parser struct {
|
||||
file *SourceFile
|
||||
errors ParserErrorList
|
||||
errors ErrorList
|
||||
scanner *Scanner
|
||||
pos Pos
|
||||
token token.Token
|
|
@ -1,4 +1,4 @@
|
|||
package internal_test
|
||||
package parser_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
@ -7,20 +7,20 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
. "github.com/d5/tengo/internal"
|
||||
"github.com/d5/tengo/internal/require"
|
||||
"github.com/d5/tengo/internal/token"
|
||||
. "github.com/d5/tengo/parser"
|
||||
"github.com/d5/tengo/require"
|
||||
"github.com/d5/tengo/token"
|
||||
)
|
||||
|
||||
func TestParserError(t *testing.T) {
|
||||
err := &ParserError{Pos: SourceFilePos{
|
||||
err := &Error{Pos: SourceFilePos{
|
||||
Offset: 10, Line: 1, Column: 10,
|
||||
}, Msg: "test"}
|
||||
require.Equal(t, "Parse Error: test\n\tat 1:10", err.Error())
|
||||
}
|
||||
|
||||
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: 30, Line: 3, Column: 10}, "error 3")
|
||||
list.Add(SourceFilePos{Offset: 10, Line: 1, Column: 10}, "error 1")
|
|
@ -1,4 +1,4 @@
|
|||
package internal
|
||||
package parser
|
||||
|
||||
// Pos represents a position in the file set.
|
||||
type Pos int
|
|
@ -1,11 +1,11 @@
|
|||
package internal
|
||||
package parser
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/d5/tengo/internal/token"
|
||||
"github.com/d5/tengo/token"
|
||||
)
|
||||
|
||||
// byte order mark
|
|
@ -1,4 +1,4 @@
|
|||
package internal_test
|
||||
package parser_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
@ -7,12 +7,12 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/d5/tengo/internal"
|
||||
"github.com/d5/tengo/internal/require"
|
||||
"github.com/d5/tengo/internal/token"
|
||||
"github.com/d5/tengo/parser"
|
||||
"github.com/d5/tengo/require"
|
||||
"github.com/d5/tengo/token"
|
||||
)
|
||||
|
||||
var testFileSet = internal.NewFileSet()
|
||||
var testFileSet = parser.NewFileSet()
|
||||
|
||||
type scanResult struct {
|
||||
Token token.Token
|
||||
|
@ -151,7 +151,7 @@ func TestScanner_Scan(t *testing.T) {
|
|||
switch tc.token {
|
||||
case token.Comment:
|
||||
// strip CRs in comments
|
||||
expectedLiteral = string(internal.StripCR([]byte(tc.literal),
|
||||
expectedLiteral = string(parser.StripCR([]byte(tc.literal),
|
||||
tc.literal[1] == '*'))
|
||||
|
||||
//-style comment literal doesn't contain newline
|
||||
|
@ -167,7 +167,7 @@ func TestScanner_Scan(t *testing.T) {
|
|||
// strip CRs in raw string
|
||||
expectedLiteral = tc.literal
|
||||
if expectedLiteral[0] == '`' {
|
||||
expectedLiteral = string(internal.StripCR(
|
||||
expectedLiteral = string(parser.StripCR(
|
||||
[]byte(expectedLiteral), false))
|
||||
}
|
||||
} else if tc.token.IsKeyword() {
|
||||
|
@ -189,9 +189,9 @@ func TestScanner_Scan(t *testing.T) {
|
|||
}
|
||||
|
||||
scanExpect(t, strings.Join(lines, "\n"),
|
||||
internal.ScanComments|internal.DontInsertSemis, expected...)
|
||||
parser.ScanComments|parser.DontInsertSemis, expected...)
|
||||
scanExpect(t, strings.Join(lines, "\n"),
|
||||
internal.DontInsertSemis, expectedSkipComments...)
|
||||
parser.DontInsertSemis, expectedSkipComments...)
|
||||
}
|
||||
|
||||
func TestStripCR(t *testing.T) {
|
||||
|
@ -210,7 +210,7 @@ func TestStripCR(t *testing.T) {
|
|||
{"/*\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] == '*'))
|
||||
require.Equal(t, tc.expect, actual)
|
||||
}
|
||||
|
@ -219,15 +219,15 @@ func TestStripCR(t *testing.T) {
|
|||
func scanExpect(
|
||||
t *testing.T,
|
||||
input string,
|
||||
mode internal.ScanMode,
|
||||
mode parser.ScanMode,
|
||||
expected ...scanResult,
|
||||
) {
|
||||
testFile := testFileSet.AddFile("test", -1, len(input))
|
||||
|
||||
s := internal.NewScanner(
|
||||
s := parser.NewScanner(
|
||||
testFile,
|
||||
[]byte(input),
|
||||
func(_ internal.SourceFilePos, msg string) { require.Fail(t, msg) },
|
||||
func(_ parser.SourceFilePos, msg string) { require.Fail(t, msg) },
|
||||
mode)
|
||||
|
||||
for idx, e := range expected {
|
|
@ -1,4 +1,4 @@
|
|||
package internal
|
||||
package parser
|
||||
|
||||
import (
|
||||
"fmt"
|
|
@ -1,9 +1,9 @@
|
|||
package internal
|
||||
package parser
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/d5/tengo/internal/token"
|
||||
"github.com/d5/tengo/token"
|
||||
)
|
||||
|
||||
// Stmt represents a statement in the AST.
|
|
@ -11,8 +11,8 @@ import (
|
|||
"unicode/utf8"
|
||||
|
||||
"github.com/d5/tengo"
|
||||
"github.com/d5/tengo/internal"
|
||||
"github.com/d5/tengo/internal/token"
|
||||
"github.com/d5/tengo/parser"
|
||||
"github.com/d5/tengo/token"
|
||||
)
|
||||
|
||||
// NoError asserts err is not an error.
|
||||
|
@ -120,12 +120,12 @@ func Equal(
|
|||
if expected != actual.(rune) {
|
||||
failExpectedActual(t, expected, actual, msg...)
|
||||
}
|
||||
case *internal.Symbol:
|
||||
if !equalSymbol(expected, actual.(*internal.Symbol)) {
|
||||
case *tengo.Symbol:
|
||||
if !equalSymbol(expected, actual.(*tengo.Symbol)) {
|
||||
failExpectedActual(t, expected, actual, msg...)
|
||||
}
|
||||
case internal.Pos:
|
||||
if expected != actual.(internal.Pos) {
|
||||
case parser.Pos:
|
||||
if expected != actual.(parser.Pos) {
|
||||
failExpectedActual(t, expected, actual, msg...)
|
||||
}
|
||||
case token.Token:
|
||||
|
@ -176,14 +176,14 @@ func Equal(
|
|||
if !expected.Equals(actual.(tengo.Object)) {
|
||||
failExpectedActual(t, expected, actual, msg...)
|
||||
}
|
||||
case *internal.SourceFileSet:
|
||||
equalFileSet(t, expected, actual.(*internal.SourceFileSet), msg...)
|
||||
case *internal.SourceFile:
|
||||
Equal(t, expected.Name, actual.(*internal.SourceFile).Name, msg...)
|
||||
Equal(t, expected.Base, actual.(*internal.SourceFile).Base, msg...)
|
||||
Equal(t, expected.Size, actual.(*internal.SourceFile).Size, msg...)
|
||||
case *parser.SourceFileSet:
|
||||
equalFileSet(t, expected, actual.(*parser.SourceFileSet), msg...)
|
||||
case *parser.SourceFile:
|
||||
Equal(t, expected.Name, actual.(*parser.SourceFile).Name, msg...)
|
||||
Equal(t, expected.Base, actual.(*parser.SourceFile).Base, msg...)
|
||||
Equal(t, expected.Size, actual.(*parser.SourceFile).Size, msg...)
|
||||
True(t, equalIntSlice(expected.Lines,
|
||||
actual.(*internal.SourceFile).Lines), msg...)
|
||||
actual.(*parser.SourceFile).Lines), msg...)
|
||||
case error:
|
||||
if expected != actual.(error) {
|
||||
failExpectedActual(t, expected, actual, msg...)
|
||||
|
@ -253,7 +253,7 @@ func equalStringSlice(a, b []string) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
func equalSymbol(a, b *internal.Symbol) bool {
|
||||
func equalSymbol(a, b *tengo.Symbol) bool {
|
||||
return a.Name == b.Name &&
|
||||
a.Index == b.Index &&
|
||||
a.Scope == b.Scope
|
||||
|
@ -272,7 +272,7 @@ func equalObjectSlice(
|
|||
|
||||
func equalFileSet(
|
||||
t *testing.T,
|
||||
expected, actual *internal.SourceFileSet,
|
||||
expected, actual *parser.SourceFileSet,
|
||||
msg ...interface{},
|
||||
) {
|
||||
Equal(t, len(expected.Files), len(actual.Files), msg...)
|
||||
|
@ -303,8 +303,8 @@ func equalCompiledFunction(
|
|||
expectedT := expected.(*tengo.CompiledFunction)
|
||||
actualT := actual.(*tengo.CompiledFunction)
|
||||
Equal(t,
|
||||
internal.FormatInstructions(expectedT.Instructions, 0),
|
||||
internal.FormatInstructions(actualT.Instructions, 0), msg...)
|
||||
tengo.FormatInstructions(expectedT.Instructions, 0),
|
||||
tengo.FormatInstructions(actualT.Instructions, 0), msg...)
|
||||
}
|
||||
|
||||
func isNil(v interface{}) bool {
|
12
script.go
12
script.go
|
@ -5,7 +5,7 @@ import (
|
|||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/d5/tengo/internal"
|
||||
"github.com/d5/tengo/parser"
|
||||
)
|
||||
|
||||
// Script can simplify compilation and execution of embedded scripts.
|
||||
|
@ -83,9 +83,9 @@ func (s *Script) Compile() (*Compiled, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
fileSet := internal.NewFileSet()
|
||||
fileSet := parser.NewFileSet()
|
||||
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()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -104,7 +104,7 @@ func (s *Script) Compile() (*Compiled, error) {
|
|||
globalIndexes := make(map[string]int, len(globals))
|
||||
for _, name := range symbolTable.Names() {
|
||||
symbol, _, _ := symbolTable.Resolve(name)
|
||||
if symbol.Scope == internal.ScopeGlobal {
|
||||
if symbol.Scope == ScopeGlobal {
|
||||
globalIndexes[name] = symbol.Index
|
||||
}
|
||||
}
|
||||
|
@ -152,7 +152,7 @@ func (s *Script) RunContext(
|
|||
}
|
||||
|
||||
func (s *Script) prepCompile() (
|
||||
symbolTable *internal.SymbolTable,
|
||||
symbolTable *SymbolTable,
|
||||
globals []Object,
|
||||
err error,
|
||||
) {
|
||||
|
@ -161,7 +161,7 @@ func (s *Script) prepCompile() (
|
|||
names = append(names, name)
|
||||
}
|
||||
|
||||
symbolTable = internal.NewSymbolTable()
|
||||
symbolTable = NewSymbolTable()
|
||||
for idx, fn := range builtinFuncs {
|
||||
symbolTable.DefineBuiltin(idx, fn.Name)
|
||||
}
|
||||
|
|
|
@ -11,9 +11,9 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/d5/tengo"
|
||||
"github.com/d5/tengo/internal/require"
|
||||
"github.com/d5/tengo/internal/token"
|
||||
"github.com/d5/tengo/require"
|
||||
"github.com/d5/tengo/stdlib"
|
||||
"github.com/d5/tengo/token"
|
||||
)
|
||||
|
||||
func TestScript_Add(t *testing.T) {
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/d5/tengo"
|
||||
"github.com/d5/tengo/internal/require"
|
||||
"github.com/d5/tengo/require"
|
||||
"github.com/d5/tengo/stdlib"
|
||||
)
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/d5/tengo"
|
||||
"github.com/d5/tengo/internal/require"
|
||||
"github.com/d5/tengo/require"
|
||||
"github.com/d5/tengo/stdlib/json"
|
||||
)
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/d5/tengo"
|
||||
"github.com/d5/tengo/internal/require"
|
||||
"github.com/d5/tengo/require"
|
||||
)
|
||||
|
||||
func TestReadFile(t *testing.T) {
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/d5/tengo"
|
||||
"github.com/d5/tengo/internal/require"
|
||||
"github.com/d5/tengo/require"
|
||||
)
|
||||
|
||||
func TestRand(t *testing.T) {
|
||||
|
|
|
@ -6,7 +6,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/d5/tengo"
|
||||
"github.com/d5/tengo/internal/require"
|
||||
"github.com/d5/tengo/require"
|
||||
"github.com/d5/tengo/stdlib"
|
||||
)
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/d5/tengo"
|
||||
"github.com/d5/tengo/internal/require"
|
||||
"github.com/d5/tengo/require"
|
||||
)
|
||||
|
||||
func TestTimes(t *testing.T) {
|
||||
|
|
|
@ -1,33 +1,4 @@
|
|||
package internal
|
||||
|
||||
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)
|
||||
}
|
||||
package tengo
|
||||
|
||||
// SymbolScope represents a symbol scope.
|
||||
type SymbolScope string
|
|
@ -1,10 +1,10 @@
|
|||
package internal_test
|
||||
package tengo_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/d5/tengo/internal"
|
||||
"github.com/d5/tengo/internal/require"
|
||||
"github.com/d5/tengo"
|
||||
"github.com/d5/tengo/require"
|
||||
)
|
||||
|
||||
func TestSymbolTable(t *testing.T) {
|
||||
|
@ -93,37 +93,37 @@ func TestSymbolTable(t *testing.T) {
|
|||
|
||||
func symbol(
|
||||
name string,
|
||||
scope internal.SymbolScope,
|
||||
scope tengo.SymbolScope,
|
||||
index int,
|
||||
) *internal.Symbol {
|
||||
return &internal.Symbol{
|
||||
) *tengo.Symbol {
|
||||
return &tengo.Symbol{
|
||||
Name: name,
|
||||
Scope: scope,
|
||||
Index: index,
|
||||
}
|
||||
}
|
||||
|
||||
func globalSymbol(name string, index int) *internal.Symbol {
|
||||
return symbol(name, internal.ScopeGlobal, index)
|
||||
func globalSymbol(name string, index int) *tengo.Symbol {
|
||||
return symbol(name, tengo.ScopeGlobal, index)
|
||||
}
|
||||
|
||||
func localSymbol(name string, index int) *internal.Symbol {
|
||||
return symbol(name, internal.ScopeLocal, index)
|
||||
func localSymbol(name string, index int) *tengo.Symbol {
|
||||
return symbol(name, tengo.ScopeLocal, index)
|
||||
}
|
||||
|
||||
func freeSymbol(name string, index int) *internal.Symbol {
|
||||
return symbol(name, internal.ScopeFree, index)
|
||||
func freeSymbol(name string, index int) *tengo.Symbol {
|
||||
return symbol(name, tengo.ScopeFree, index)
|
||||
}
|
||||
|
||||
func symbolTable() *internal.SymbolTable {
|
||||
return internal.NewSymbolTable()
|
||||
func symbolTable() *tengo.SymbolTable {
|
||||
return tengo.NewSymbolTable()
|
||||
}
|
||||
|
||||
func resolveExpect(
|
||||
t *testing.T,
|
||||
symbolTable *internal.SymbolTable,
|
||||
symbolTable *tengo.SymbolTable,
|
||||
name string,
|
||||
expectedSymbol *internal.Symbol,
|
||||
expectedSymbol *tengo.Symbol,
|
||||
expectedDepth int,
|
||||
) {
|
||||
actualSymbol, actualDepth, ok := symbolTable.Resolve(name)
|
|
@ -6,16 +6,16 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/d5/tengo"
|
||||
"github.com/d5/tengo/internal"
|
||||
"github.com/d5/tengo/internal/require"
|
||||
"github.com/d5/tengo/parser"
|
||||
"github.com/d5/tengo/require"
|
||||
)
|
||||
|
||||
func TestInstructions_String(t *testing.T) {
|
||||
assertInstructionString(t,
|
||||
[][]byte{
|
||||
internal.MakeInstruction(internal.OpConstant, 1),
|
||||
internal.MakeInstruction(internal.OpConstant, 2),
|
||||
internal.MakeInstruction(internal.OpConstant, 65535),
|
||||
tengo.MakeInstruction(parser.OpConstant, 1),
|
||||
tengo.MakeInstruction(parser.OpConstant, 2),
|
||||
tengo.MakeInstruction(parser.OpConstant, 65535),
|
||||
},
|
||||
`0000 CONST 1
|
||||
0003 CONST 2
|
||||
|
@ -23,9 +23,9 @@ func TestInstructions_String(t *testing.T) {
|
|||
|
||||
assertInstructionString(t,
|
||||
[][]byte{
|
||||
internal.MakeInstruction(internal.OpBinaryOp, 11),
|
||||
internal.MakeInstruction(internal.OpConstant, 2),
|
||||
internal.MakeInstruction(internal.OpConstant, 65535),
|
||||
tengo.MakeInstruction(parser.OpBinaryOp, 11),
|
||||
tengo.MakeInstruction(parser.OpConstant, 2),
|
||||
tengo.MakeInstruction(parser.OpConstant, 65535),
|
||||
},
|
||||
`0000 BINARYOP 11
|
||||
0002 CONST 2
|
||||
|
@ -33,10 +33,10 @@ func TestInstructions_String(t *testing.T) {
|
|||
|
||||
assertInstructionString(t,
|
||||
[][]byte{
|
||||
internal.MakeInstruction(internal.OpBinaryOp, 11),
|
||||
internal.MakeInstruction(internal.OpGetLocal, 1),
|
||||
internal.MakeInstruction(internal.OpConstant, 2),
|
||||
internal.MakeInstruction(internal.OpConstant, 65535),
|
||||
tengo.MakeInstruction(parser.OpBinaryOp, 11),
|
||||
tengo.MakeInstruction(parser.OpGetLocal, 1),
|
||||
tengo.MakeInstruction(parser.OpConstant, 2),
|
||||
tengo.MakeInstruction(parser.OpConstant, 65535),
|
||||
},
|
||||
`0000 BINARYOP 11
|
||||
0002 GETL 1
|
||||
|
@ -45,15 +45,15 @@ func TestInstructions_String(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestMakeInstruction(t *testing.T) {
|
||||
makeInstruction(t, []byte{internal.OpConstant, 0, 0},
|
||||
internal.OpConstant, 0)
|
||||
makeInstruction(t, []byte{internal.OpConstant, 0, 1},
|
||||
internal.OpConstant, 1)
|
||||
makeInstruction(t, []byte{internal.OpConstant, 255, 254},
|
||||
internal.OpConstant, 65534)
|
||||
makeInstruction(t, []byte{internal.OpPop}, internal.OpPop)
|
||||
makeInstruction(t, []byte{internal.OpTrue}, internal.OpTrue)
|
||||
makeInstruction(t, []byte{internal.OpFalse}, internal.OpFalse)
|
||||
makeInstruction(t, []byte{parser.OpConstant, 0, 0},
|
||||
parser.OpConstant, 0)
|
||||
makeInstruction(t, []byte{parser.OpConstant, 0, 1},
|
||||
parser.OpConstant, 1)
|
||||
makeInstruction(t, []byte{parser.OpConstant, 255, 254},
|
||||
parser.OpConstant, 65534)
|
||||
makeInstruction(t, []byte{parser.OpPop}, parser.OpPop)
|
||||
makeInstruction(t, []byte{parser.OpTrue}, parser.OpTrue)
|
||||
makeInstruction(t, []byte{parser.OpFalse}, parser.OpFalse)
|
||||
}
|
||||
|
||||
func TestNumObjects(t *testing.T) {
|
||||
|
@ -123,15 +123,15 @@ func assertInstructionString(
|
|||
concatted = append(concatted, e...)
|
||||
}
|
||||
require.Equal(t, expected, strings.Join(
|
||||
internal.FormatInstructions(concatted, 0), "\n"))
|
||||
tengo.FormatInstructions(concatted, 0), "\n"))
|
||||
}
|
||||
|
||||
func makeInstruction(
|
||||
t *testing.T,
|
||||
expected []byte,
|
||||
opcode internal.Opcode,
|
||||
opcode parser.Opcode,
|
||||
operands ...int,
|
||||
) {
|
||||
inst := internal.MakeInstruction(opcode, operands...)
|
||||
inst := tengo.MakeInstruction(opcode, operands...)
|
||||
require.Equal(t, expected, inst)
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/d5/tengo"
|
||||
"github.com/d5/tengo/internal/require"
|
||||
"github.com/d5/tengo/require"
|
||||
)
|
||||
|
||||
type VariableTest struct {
|
||||
|
|
96
vm.go
96
vm.go
|
@ -4,8 +4,8 @@ import (
|
|||
"fmt"
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/d5/tengo/internal"
|
||||
"github.com/d5/tengo/internal/token"
|
||||
"github.com/d5/tengo/parser"
|
||||
"github.com/d5/tengo/token"
|
||||
)
|
||||
|
||||
// frame represents a function call frame.
|
||||
|
@ -22,7 +22,7 @@ type VM struct {
|
|||
stack [StackSize]Object
|
||||
sp int
|
||||
globals []Object
|
||||
fileSet *internal.SourceFileSet
|
||||
fileSet *parser.SourceFileSet
|
||||
frames [MaxFrames]frame
|
||||
framesIndex int
|
||||
curFrame *frame
|
||||
|
@ -99,16 +99,16 @@ func (v *VM) run() {
|
|||
v.ip++
|
||||
|
||||
switch v.curInsts[v.ip] {
|
||||
case internal.OpConstant:
|
||||
case parser.OpConstant:
|
||||
v.ip += 2
|
||||
cidx := int(v.curInsts[v.ip]) | int(v.curInsts[v.ip-1])<<8
|
||||
|
||||
v.stack[v.sp] = v.constants[cidx]
|
||||
v.sp++
|
||||
case internal.OpNull:
|
||||
case parser.OpNull:
|
||||
v.stack[v.sp] = UndefinedValue
|
||||
v.sp++
|
||||
case internal.OpBinaryOp:
|
||||
case parser.OpBinaryOp:
|
||||
v.ip++
|
||||
right := v.stack[v.sp-1]
|
||||
left := v.stack[v.sp-2]
|
||||
|
@ -133,7 +133,7 @@ func (v *VM) run() {
|
|||
|
||||
v.stack[v.sp-2] = res
|
||||
v.sp--
|
||||
case internal.OpEqual:
|
||||
case parser.OpEqual:
|
||||
right := v.stack[v.sp-1]
|
||||
left := v.stack[v.sp-2]
|
||||
v.sp -= 2
|
||||
|
@ -143,7 +143,7 @@ func (v *VM) run() {
|
|||
v.stack[v.sp] = FalseValue
|
||||
}
|
||||
v.sp++
|
||||
case internal.OpNotEqual:
|
||||
case parser.OpNotEqual:
|
||||
right := v.stack[v.sp-1]
|
||||
left := v.stack[v.sp-2]
|
||||
v.sp -= 2
|
||||
|
@ -153,15 +153,15 @@ func (v *VM) run() {
|
|||
v.stack[v.sp] = TrueValue
|
||||
}
|
||||
v.sp++
|
||||
case internal.OpPop:
|
||||
case parser.OpPop:
|
||||
v.sp--
|
||||
case internal.OpTrue:
|
||||
case parser.OpTrue:
|
||||
v.stack[v.sp] = TrueValue
|
||||
v.sp++
|
||||
case internal.OpFalse:
|
||||
case parser.OpFalse:
|
||||
v.stack[v.sp] = FalseValue
|
||||
v.sp++
|
||||
case internal.OpLNot:
|
||||
case parser.OpLNot:
|
||||
operand := v.stack[v.sp-1]
|
||||
v.sp--
|
||||
if operand.IsFalsy() {
|
||||
|
@ -170,7 +170,7 @@ func (v *VM) run() {
|
|||
v.stack[v.sp] = FalseValue
|
||||
}
|
||||
v.sp++
|
||||
case internal.OpBComplement:
|
||||
case parser.OpBComplement:
|
||||
operand := v.stack[v.sp-1]
|
||||
v.sp--
|
||||
|
||||
|
@ -189,7 +189,7 @@ func (v *VM) run() {
|
|||
operand.TypeName())
|
||||
return
|
||||
}
|
||||
case internal.OpMinus:
|
||||
case parser.OpMinus:
|
||||
operand := v.stack[v.sp-1]
|
||||
v.sp--
|
||||
|
||||
|
@ -217,14 +217,14 @@ func (v *VM) run() {
|
|||
operand.TypeName())
|
||||
return
|
||||
}
|
||||
case internal.OpJumpFalsy:
|
||||
case parser.OpJumpFalsy:
|
||||
v.ip += 2
|
||||
v.sp--
|
||||
if v.stack[v.sp].IsFalsy() {
|
||||
pos := int(v.curInsts[v.ip]) | int(v.curInsts[v.ip-1])<<8
|
||||
v.ip = pos - 1
|
||||
}
|
||||
case internal.OpAndJump:
|
||||
case parser.OpAndJump:
|
||||
v.ip += 2
|
||||
if v.stack[v.sp-1].IsFalsy() {
|
||||
pos := int(v.curInsts[v.ip]) | int(v.curInsts[v.ip-1])<<8
|
||||
|
@ -232,7 +232,7 @@ func (v *VM) run() {
|
|||
} else {
|
||||
v.sp--
|
||||
}
|
||||
case internal.OpOrJump:
|
||||
case parser.OpOrJump:
|
||||
v.ip += 2
|
||||
if v.stack[v.sp-1].IsFalsy() {
|
||||
v.sp--
|
||||
|
@ -240,15 +240,15 @@ func (v *VM) run() {
|
|||
pos := int(v.curInsts[v.ip]) | int(v.curInsts[v.ip-1])<<8
|
||||
v.ip = pos - 1
|
||||
}
|
||||
case internal.OpJump:
|
||||
case parser.OpJump:
|
||||
pos := int(v.curInsts[v.ip+2]) | int(v.curInsts[v.ip+1])<<8
|
||||
v.ip = pos - 1
|
||||
case internal.OpSetGlobal:
|
||||
case parser.OpSetGlobal:
|
||||
v.ip += 2
|
||||
v.sp--
|
||||
globalIndex := int(v.curInsts[v.ip]) | int(v.curInsts[v.ip-1])<<8
|
||||
v.globals[globalIndex] = v.stack[v.sp]
|
||||
case internal.OpSetSelGlobal:
|
||||
case parser.OpSetSelGlobal:
|
||||
v.ip += 3
|
||||
globalIndex := int(v.curInsts[v.ip-1]) | int(v.curInsts[v.ip-2])<<8
|
||||
numSelectors := int(v.curInsts[v.ip])
|
||||
|
@ -265,13 +265,13 @@ func (v *VM) run() {
|
|||
v.err = e
|
||||
return
|
||||
}
|
||||
case internal.OpGetGlobal:
|
||||
case parser.OpGetGlobal:
|
||||
v.ip += 2
|
||||
globalIndex := int(v.curInsts[v.ip]) | int(v.curInsts[v.ip-1])<<8
|
||||
val := v.globals[globalIndex]
|
||||
v.stack[v.sp] = val
|
||||
v.sp++
|
||||
case internal.OpArray:
|
||||
case parser.OpArray:
|
||||
v.ip += 2
|
||||
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.sp++
|
||||
case internal.OpMap:
|
||||
case parser.OpMap:
|
||||
v.ip += 2
|
||||
numElements := int(v.curInsts[v.ip]) | int(v.curInsts[v.ip-1])<<8
|
||||
kv := make(map[string]Object)
|
||||
|
@ -309,7 +309,7 @@ func (v *VM) run() {
|
|||
}
|
||||
v.stack[v.sp] = m
|
||||
v.sp++
|
||||
case internal.OpError:
|
||||
case parser.OpError:
|
||||
value := v.stack[v.sp-1]
|
||||
var e Object = &Error{
|
||||
Value: value,
|
||||
|
@ -320,7 +320,7 @@ func (v *VM) run() {
|
|||
return
|
||||
}
|
||||
v.stack[v.sp-1] = e
|
||||
case internal.OpImmutable:
|
||||
case parser.OpImmutable:
|
||||
value := v.stack[v.sp-1]
|
||||
switch value := value.(type) {
|
||||
case *Array:
|
||||
|
@ -344,7 +344,7 @@ func (v *VM) run() {
|
|||
}
|
||||
v.stack[v.sp-1] = immutableMap
|
||||
}
|
||||
case internal.OpIndex:
|
||||
case parser.OpIndex:
|
||||
index := v.stack[v.sp-1]
|
||||
left := v.stack[v.sp-2]
|
||||
v.sp -= 2
|
||||
|
@ -368,7 +368,7 @@ func (v *VM) run() {
|
|||
}
|
||||
v.stack[v.sp] = val
|
||||
v.sp++
|
||||
case internal.OpSliceIndex:
|
||||
case parser.OpSliceIndex:
|
||||
high := v.stack[v.sp-1]
|
||||
low := v.stack[v.sp-2]
|
||||
left := v.stack[v.sp-3]
|
||||
|
@ -535,7 +535,7 @@ func (v *VM) run() {
|
|||
v.stack[v.sp] = val
|
||||
v.sp++
|
||||
}
|
||||
case internal.OpCall:
|
||||
case parser.OpCall:
|
||||
numArgs := int(v.curInsts[v.ip+1])
|
||||
v.ip++
|
||||
value := v.stack[v.sp-1-numArgs]
|
||||
|
@ -576,9 +576,9 @@ func (v *VM) run() {
|
|||
// test if it's tail-call
|
||||
if callee == v.curFrame.fn { // recursion
|
||||
nextOp := v.curInsts[v.ip+1]
|
||||
if nextOp == internal.OpReturn ||
|
||||
(nextOp == internal.OpPop &&
|
||||
internal.OpReturn == v.curInsts[v.ip+2]) {
|
||||
if nextOp == parser.OpReturn ||
|
||||
(nextOp == parser.OpPop &&
|
||||
parser.OpReturn == v.curInsts[v.ip+2]) {
|
||||
for p := 0; p < numArgs; p++ {
|
||||
v.stack[v.curFrame.basePointer+p] =
|
||||
v.stack[v.sp-numArgs+p]
|
||||
|
@ -640,7 +640,7 @@ func (v *VM) run() {
|
|||
v.stack[v.sp] = ret
|
||||
v.sp++
|
||||
}
|
||||
case internal.OpReturn:
|
||||
case parser.OpReturn:
|
||||
v.ip++
|
||||
var retVal Object
|
||||
if int(v.curInsts[v.ip]) == 1 {
|
||||
|
@ -658,7 +658,7 @@ func (v *VM) run() {
|
|||
// skip stack overflow check because (newSP) <= (oldSP)
|
||||
v.stack[v.sp-1] = retVal
|
||||
//v.sp++
|
||||
case internal.OpDefineLocal:
|
||||
case parser.OpDefineLocal:
|
||||
v.ip++
|
||||
localIndex := int(v.curInsts[v.ip])
|
||||
sp := v.curFrame.basePointer + localIndex
|
||||
|
@ -668,7 +668,7 @@ func (v *VM) run() {
|
|||
val := v.stack[v.sp-1]
|
||||
v.sp--
|
||||
v.stack[sp] = val
|
||||
case internal.OpSetLocal:
|
||||
case parser.OpSetLocal:
|
||||
localIndex := int(v.curInsts[v.ip+1])
|
||||
v.ip++
|
||||
sp := v.curFrame.basePointer + localIndex
|
||||
|
@ -683,7 +683,7 @@ func (v *VM) run() {
|
|||
val = obj
|
||||
}
|
||||
v.stack[sp] = val // also use a copy of popped value
|
||||
case internal.OpSetSelLocal:
|
||||
case parser.OpSetSelLocal:
|
||||
localIndex := int(v.curInsts[v.ip+1])
|
||||
numSelectors := int(v.curInsts[v.ip+2])
|
||||
v.ip += 2
|
||||
|
@ -703,7 +703,7 @@ func (v *VM) run() {
|
|||
v.err = e
|
||||
return
|
||||
}
|
||||
case internal.OpGetLocal:
|
||||
case parser.OpGetLocal:
|
||||
v.ip++
|
||||
localIndex := int(v.curInsts[v.ip])
|
||||
val := v.stack[v.curFrame.basePointer+localIndex]
|
||||
|
@ -712,12 +712,12 @@ func (v *VM) run() {
|
|||
}
|
||||
v.stack[v.sp] = val
|
||||
v.sp++
|
||||
case internal.OpGetBuiltin:
|
||||
case parser.OpGetBuiltin:
|
||||
v.ip++
|
||||
builtinIndex := int(v.curInsts[v.ip])
|
||||
v.stack[v.sp] = builtinFuncs[builtinIndex]
|
||||
v.sp++
|
||||
case internal.OpClosure:
|
||||
case parser.OpClosure:
|
||||
v.ip += 3
|
||||
constIndex := int(v.curInsts[v.ip-1]) | int(v.curInsts[v.ip-2])<<8
|
||||
numFree := int(v.curInsts[v.ip])
|
||||
|
@ -752,24 +752,24 @@ func (v *VM) run() {
|
|||
}
|
||||
v.stack[v.sp] = cl
|
||||
v.sp++
|
||||
case internal.OpGetFreePtr:
|
||||
case parser.OpGetFreePtr:
|
||||
v.ip++
|
||||
freeIndex := int(v.curInsts[v.ip])
|
||||
val := v.curFrame.freeVars[freeIndex]
|
||||
v.stack[v.sp] = val
|
||||
v.sp++
|
||||
case internal.OpGetFree:
|
||||
case parser.OpGetFree:
|
||||
v.ip++
|
||||
freeIndex := int(v.curInsts[v.ip])
|
||||
val := *v.curFrame.freeVars[freeIndex].Value
|
||||
v.stack[v.sp] = val
|
||||
v.sp++
|
||||
case internal.OpSetFree:
|
||||
case parser.OpSetFree:
|
||||
v.ip++
|
||||
freeIndex := int(v.curInsts[v.ip])
|
||||
*v.curFrame.freeVars[freeIndex].Value = v.stack[v.sp-1]
|
||||
v.sp--
|
||||
case internal.OpGetLocalPtr:
|
||||
case parser.OpGetLocalPtr:
|
||||
v.ip++
|
||||
localIndex := int(v.curInsts[v.ip])
|
||||
sp := v.curFrame.basePointer + localIndex
|
||||
|
@ -783,7 +783,7 @@ func (v *VM) run() {
|
|||
}
|
||||
v.stack[v.sp] = freeVar
|
||||
v.sp++
|
||||
case internal.OpSetSelFree:
|
||||
case parser.OpSetSelFree:
|
||||
v.ip += 2
|
||||
freeIndex := int(v.curInsts[v.ip-1])
|
||||
numSelectors := int(v.curInsts[v.ip])
|
||||
|
@ -801,7 +801,7 @@ func (v *VM) run() {
|
|||
v.err = e
|
||||
return
|
||||
}
|
||||
case internal.OpIteratorInit:
|
||||
case parser.OpIteratorInit:
|
||||
var iterator Object
|
||||
dst := v.stack[v.sp-1]
|
||||
v.sp--
|
||||
|
@ -817,7 +817,7 @@ func (v *VM) run() {
|
|||
}
|
||||
v.stack[v.sp] = iterator
|
||||
v.sp++
|
||||
case internal.OpIteratorNext:
|
||||
case parser.OpIteratorNext:
|
||||
iterator := v.stack[v.sp-1]
|
||||
v.sp--
|
||||
hasMore := iterator.(Iterator).Next()
|
||||
|
@ -827,19 +827,19 @@ func (v *VM) run() {
|
|||
v.stack[v.sp] = FalseValue
|
||||
}
|
||||
v.sp++
|
||||
case internal.OpIteratorKey:
|
||||
case parser.OpIteratorKey:
|
||||
iterator := v.stack[v.sp-1]
|
||||
v.sp--
|
||||
val := iterator.(Iterator).Key()
|
||||
v.stack[v.sp] = val
|
||||
v.sp++
|
||||
case internal.OpIteratorValue:
|
||||
case parser.OpIteratorValue:
|
||||
iterator := v.stack[v.sp-1]
|
||||
v.sp--
|
||||
val := iterator.(Iterator).Value()
|
||||
v.stack[v.sp] = val
|
||||
v.sp++
|
||||
case internal.OpSuspend:
|
||||
case parser.OpSuspend:
|
||||
return
|
||||
default:
|
||||
v.err = fmt.Errorf("unknown opcode: %d", v.curInsts[v.ip])
|
||||
|
|
16
vm_test.go
16
vm_test.go
|
@ -11,10 +11,10 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/d5/tengo"
|
||||
"github.com/d5/tengo/internal"
|
||||
"github.com/d5/tengo/internal/require"
|
||||
"github.com/d5/tengo/internal/token"
|
||||
"github.com/d5/tengo/parser"
|
||||
"github.com/d5/tengo/require"
|
||||
"github.com/d5/tengo/stdlib"
|
||||
"github.com/d5/tengo/token"
|
||||
)
|
||||
|
||||
const testOut = "out"
|
||||
|
@ -3276,7 +3276,7 @@ func (o *vmTracer) Write(p []byte) (n int, err error) {
|
|||
}
|
||||
|
||||
func traceCompileRun(
|
||||
file *internal.File,
|
||||
file *parser.File,
|
||||
symbols map[string]tengo.Object,
|
||||
modules *tengo.ModuleMap,
|
||||
maxAllocs int64,
|
||||
|
@ -3306,7 +3306,7 @@ func traceCompileRun(
|
|||
|
||||
globals := make([]tengo.Object, tengo.GlobalsSize)
|
||||
|
||||
symTable := internal.NewSymbolTable()
|
||||
symTable := tengo.NewSymbolTable()
|
||||
for name, value := range symbols {
|
||||
sym := symTable.Define(name)
|
||||
|
||||
|
@ -3371,11 +3371,11 @@ func formatGlobals(globals []tengo.Object) (formatted []string) {
|
|||
return
|
||||
}
|
||||
|
||||
func parse(t *testing.T, input string) *internal.File {
|
||||
testFileSet := internal.NewFileSet()
|
||||
func parse(t *testing.T, input string) *parser.File {
|
||||
testFileSet := parser.NewFileSet()
|
||||
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()
|
||||
require.NoError(t, err)
|
||||
return file
|
||||
|
|
Loading…
Reference in a new issue