aboutsummaryrefslogtreecommitdiff
path: root/pkg/lang/vm/mem
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
parent11bcf772bf8d9aa353eb4c04bfb85378ba392b1e (diff)
downloadjinx-d2f69dccb3643834a79da79be4ece189a7178c9e.tar.zst
jinx-d2f69dccb3643834a79da79be4ece189a7178c9e.zip
Types, Methods and basic Core Lib
Diffstat (limited to 'pkg/lang/vm/mem')
-rw-r--r--pkg/lang/vm/mem/cell.go3
-rw-r--r--pkg/lang/vm/mem/mem.go30
-rw-r--r--pkg/lang/vm/mem/mem_test.go9
3 files changed, 42 insertions, 0 deletions
diff --git a/pkg/lang/vm/mem/cell.go b/pkg/lang/vm/mem/cell.go
index 562d4da..5a0e9fb 100644
--- a/pkg/lang/vm/mem/cell.go
+++ b/pkg/lang/vm/mem/cell.go
@@ -6,6 +6,7 @@ const (
CellKindEmpty CellKind = iota
CellKindString
CellKindArray
+ CellKindType
CellKindEnv
CellKindOutlet
@@ -21,6 +22,8 @@ func (c CellKind) String() string {
return "string"
case CellKindArray:
return "array"
+ case CellKindType:
+ return "type"
case CellKindEnv:
return "env"
case CellKindOutlet:
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 {
diff --git a/pkg/lang/vm/mem/mem_test.go b/pkg/lang/vm/mem/mem_test.go
index a75753c..f916e49 100644
--- a/pkg/lang/vm/mem/mem_test.go
+++ b/pkg/lang/vm/mem/mem_test.go
@@ -21,6 +21,15 @@ func TestAllocation(t *testing.T) {
assert.Equal(t, two, mem.Ptr(2))
}
+func TestSpecificAllocation(t *testing.T) {
+ m := mem.New()
+
+ assert.NoError(t, m.AllocateAt(mem.Ptr(123), mem.CellKindString))
+ assert.Error(t, m.AllocateAt(mem.NullPtr, mem.CellKindString))
+ assert.Error(t, m.AllocateAt(mem.Ptr(124), mem.CellKindEmpty))
+ assert.Error(t, m.AllocateAt(mem.Ptr(123), mem.CellKindArray))
+}
+
func TestGetSet(t *testing.T) {
m := mem.New()