diff options
Diffstat (limited to 'pkg/lang/vm/mem')
| -rw-r--r-- | pkg/lang/vm/mem/cell.go | 3 | ||||
| -rw-r--r-- | pkg/lang/vm/mem/mem.go | 30 | ||||
| -rw-r--r-- | pkg/lang/vm/mem/mem_test.go | 9 |
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() |
