diff options
Diffstat (limited to 'pkg/lang/vm/value/env.go')
| -rw-r--r-- | pkg/lang/vm/value/env.go | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/pkg/lang/vm/value/env.go b/pkg/lang/vm/value/env.go index 34a396c..2617699 100644 --- a/pkg/lang/vm/value/env.go +++ b/pkg/lang/vm/value/env.go @@ -12,6 +12,19 @@ func NewEnv() Env { } } +func (e *Env) Allocate(m mem.Mem) (mem.Ptr, error) { + ptr, err := m.Allocate(mem.CellKindEnv) + if err != nil { + return mem.NullPtr, err + } + + if err = m.Set(ptr, EnvCell(*e)); err != nil { + return mem.NullPtr, err + } + + return ptr, nil +} + func (e *Env) Add(stackIndex int, outlet mem.Ptr) { e.references = append(e.references, reference{ stackIndex: stackIndex, @@ -19,6 +32,30 @@ func (e *Env) Add(stackIndex int, outlet mem.Ptr) { }) } +func (e *Env) Prepend(stackIndex int, outlet mem.Ptr) { + e.references = append([]reference{ + { + stackIndex: stackIndex, + outlet: outlet, + }, + }, e.references...) +} + +func (e *Env) Clone(m mem.Mem) (Env, error) { + cloned := NewEnv() + for i := 0; i < e.Len(); i++ { + differentOutlet := e.GetOutlet(i) + if err := m.Retain(differentOutlet); err != nil { + return Env{}, err + } + + cloned.Add(e.GetStackIndex(i), differentOutlet) + } + return cloned, nil +} + +// TODO: Add bounds checking + func (e *Env) GetOutlet(envIndex int) mem.Ptr { return e.references[envIndex].outlet } |
