about summary refs log tree commit diff
path: root/pkg/lang/vm/value/env.go
diff options
context:
space:
mode:
authorMel <einebeere@gmail.com>2022-06-01 19:51:40 +0000
committerGitHub <noreply@github.com>2022-06-01 19:51:40 +0000
commitedca72c160967f1918b65c91a40de89ecd8badda (patch)
treeb79feabc0889a3f6cfddf09906a486d09e5c60a1 /pkg/lang/vm/value/env.go
parent33671436680e7922001df9921ee582c486c7c3f4 (diff)
downloadjinx-edca72c160967f1918b65c91a40de89ecd8badda.tar.zst
jinx-edca72c160967f1918b65c91a40de89ecd8badda.zip
Implement proper object types
Diffstat (limited to 'pkg/lang/vm/value/env.go')
-rw-r--r--pkg/lang/vm/value/env.go37
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
 }