diff options
Diffstat (limited to 'codegen/interpreter.go')
| -rw-r--r-- | codegen/interpreter.go | 24 |
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 { |
