diff options
| author | Marc Vertes <mvertes@free.fr> | 2023-08-31 17:53:54 +0200 |
|---|---|---|
| committer | Marc Vertes <mvertes@free.fr> | 2023-08-31 17:53:54 +0200 |
| commit | 851c793da43be9e4d3319afe440d603c85834045 (patch) | |
| tree | fd4b3d3812f5743213b5849858c459c8196dbf7f /codegen/interpreter.go | |
| parent | 0f4bfe6e70263fbeb580014b62632f403b29b414 (diff) | |
codegen: fix interpreter re-entrance
So multiple successive incremental Evals function correctly.
Also improve the following:
- Apply the same Eval API to vm0 and vm1
- parser: dot diagram display is now synchronous
- codegen: outsource complex code generation for readability
- vm1: Pop take the number of values to pop as operand
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 { |
