summaryrefslogtreecommitdiff
path: root/app/Code.hs
diff options
context:
space:
mode:
authorMirek Kratochvil <exa.exa@gmail.com>2023-01-03 15:51:12 +0100
committerMirek Kratochvil <exa.exa@gmail.com>2023-01-03 15:51:12 +0100
commit506551ab75133f92d79a3d51bdd9d40bc64df7aa (patch)
tree6e2ce9b27d3f7a662a7519c26ecf7d838a07b72d /app/Code.hs
parent2f07d890433bebedc136037ad9cce2eed25b0437 (diff)
downloadprlg-506551ab75133f92d79a3d51bdd9d40bc64df7aa.tar.gz
prlg-506551ab75133f92d79a3d51bdd9d40bc64df7aa.tar.bz2
struct structs
Diffstat (limited to 'app/Code.hs')
-rw-r--r--app/Code.hs20
1 files changed, 20 insertions, 0 deletions
diff --git a/app/Code.hs b/app/Code.hs
index eecd5b6..eb5149c 100644
--- a/app/Code.hs
+++ b/app/Code.hs
@@ -77,6 +77,7 @@ data Dereferenced
= FreeRef Int
| BoundRef Int Datum
| NoRef
+ deriving (Show)
-- TRICKY: HeapRefs alone must not form a cycle other than the FreeRef case.
derefHeap :: Heap -> Int -> Dereferenced
@@ -89,6 +90,25 @@ derefHeap h@(Heap _ hmap) x =
Just x' -> BoundRef x x'
_ -> NoRef
+writeHeap :: Int -> Datum -> Heap -> Heap
+writeHeap addr x (Heap nxt m) = Heap nxt (M.adjust (const x) addr m)
+
+newHeapVar :: Heap -> (Heap, Int)
+newHeapVar heap = head <$> newHeapVars 1 heap
+
+newHeapVars :: Int -> Heap -> (Heap, [Int])
+newHeapVars n (Heap nxt m) =
+ let addrs = [nxt + i - 1 | i <- [1 .. n]]
+ in ( Heap (nxt + n) $
+ foldr (uncurry M.insert) m [(a, HeapRef a) | a <- addrs]
+ , addrs)
+
+withNewHeapStruct :: Int -> Datum -> Heap -> ([Datum] -> Heap -> a) -> a
+withNewHeapStruct addr s@(Struct Id {arity = arity}) heap cont =
+ let (Heap nxt' m', addrs) = newHeapVars (arity + 1) heap
+ m'' = M.insert addr (HeapRef $ head addrs) . M.insert (head addrs) s $ m'
+ in cont (map HeapRef $ tail addrs) (Heap nxt' m'')
+
-- TODO are we actually going to use this?
codeStruct ::
Monad m