summaryrefslogtreecommitdiff
path: root/codegen/interpreter.go
diff options
context:
space:
mode:
Diffstat (limited to 'codegen/interpreter.go')
-rw-r--r--codegen/interpreter.go24
1 files changed, 15 insertions, 9 deletions
diff --git a/codegen/interpreter.go b/codegen/interpreter.go
index b26b403..a3268d9 100644
--- a/codegen/interpreter.go
+++ b/codegen/interpreter.go
@@ -19,24 +19,30 @@ func NewInterpreter(p *parser.Parser) *Interpreter {
return &Interpreter{p, NewCompiler(), &vm1.Machine{}}
}
-func (i *Interpreter) Eval(src string) (err error) {
+func (i *Interpreter) Eval(src string) (res any, err error) {
n := &parser.Node{}
if n.Child, err = i.Parse(src); err != nil {
- return err
+ return res, err
}
if debug {
n.Dot(os.Getenv("DOT"), "")
}
- offset := len(i.Code)
- i.PopExit() // Remove last exit from previous run.
+ codeOffset := len(i.Code)
+ dataOffset := 0
+ if codeOffset > 0 {
+ // All data must be copied to the VM the first time only (re-entrance).
+ dataOffset = len(i.Data)
+ }
+ i.PopExit() // Remove last exit from previous run (re-entrance).
if err = i.CodeGen(n); err != nil {
- return err
+ return res, err
}
- i.Push(i.Data...)
- i.PushCode(i.Code[offset:]...)
+ i.Push(i.Data[dataOffset:]...)
+ i.PushCode(i.Code[codeOffset:]...)
i.PushCode([]int64{0, vm1.Exit})
- i.SetIP(max(offset, i.Entry))
- return i.Run()
+ i.SetIP(max(codeOffset, i.Entry))
+ err = i.Run()
+ return i.Top(), err
}
func max(a, b int) int {