about summary refs log tree commit diff
path: root/pkg/lang/vm/mem/mem.go
diff options
context:
space:
mode:
authorMel <einebeere@gmail.com>2022-05-29 21:42:32 +0000
committerGitHub <noreply@github.com>2022-05-29 21:42:32 +0000
commitd2f69dccb3643834a79da79be4ece189a7178c9e (patch)
tree7e32365a25f37bee199dde36dfdfef12916de46f /pkg/lang/vm/mem/mem.go
parent11bcf772bf8d9aa353eb4c04bfb85378ba392b1e (diff)
downloadjinx-d2f69dccb3643834a79da79be4ece189a7178c9e.tar.zst
jinx-d2f69dccb3643834a79da79be4ece189a7178c9e.zip
Types, Methods and basic Core Lib
Diffstat (limited to 'pkg/lang/vm/mem/mem.go')
-rw-r--r--pkg/lang/vm/mem/mem.go30
1 files changed, 30 insertions, 0 deletions
diff --git a/pkg/lang/vm/mem/mem.go b/pkg/lang/vm/mem/mem.go
index 0f15743..6c1d58d 100644
--- a/pkg/lang/vm/mem/mem.go
+++ b/pkg/lang/vm/mem/mem.go
@@ -2,6 +2,7 @@ package mem
 
 type Mem interface {
 	Allocate(kind CellKind) (Ptr, error)
+	AllocateAt(ptr Ptr, kind CellKind) error
 
 	Set(ptr Ptr, v CellData) error
 	Get(ptr Ptr) (CellData, error)
@@ -55,7 +56,36 @@ func (m *memImpl) Allocate(kind CellKind) (Ptr, error) {
 		m.cells = append(m.cells, cell{kind: kind, refs: 1})
 		return Ptr(idx), nil
 	}
+}
+
+func (m *memImpl) AllocateAt(ptr Ptr, kind CellKind) error {
+	if kind == CellKindForbidden || kind == CellKindEmpty {
+		return ErrInvalidCellKind{kind}
+	}
+
+	if ptr < Ptr(len(m.cells)) && m.cells[ptr].kind != CellKindEmpty {
+		return ErrInvalidMemAccess{ptr}
+	}
+
+	if ptr > 10000 {
+		return ErrMemOverflow
+	}
 
+	if ptr >= Ptr(len(m.cells)) {
+		m.cells = append(m.cells, make([]cell, ptr-Ptr(len(m.cells))+1)...)
+	}
+
+	m.cells[ptr] = cell{kind: kind, refs: 1}
+
+	// Remove cell from free list, if it was there.
+	for i, f := range m.free {
+		if f == ptr {
+			m.free = append(m.free[:i], m.free[i+1:]...)
+			break
+		}
+	}
+
+	return nil
 }
 
 func (m *memImpl) Set(ptr Ptr, v CellData) error {