From edca72c160967f1918b65c91a40de89ecd8badda Mon Sep 17 00:00:00 2001 From: Mel Date: Wed, 1 Jun 2022 19:51:40 +0000 Subject: Implement proper object types --- pkg/lang/vm/value/env.go | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'pkg/lang/vm/value/env.go') 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 } -- cgit 1.4.1