Blocks

With our monad we’ll create several functions to manipulate the current block state so that we can push and pop the block “cursor” and append instructions into the current block.

  1. entry :: Codegen Name
  2. entry = gets currentBlock
  3. addBlock :: String -> Codegen Name
  4. addBlock bname = do
  5. bls <- gets blocks
  6. ix <- gets blockCount
  7. nms <- gets names
  8. let new = emptyBlock ix
  9. (qname, supply) = uniqueName bname nms
  10. modify $ \s -> s { blocks = Map.insert (Name qname) new bls
  11. , blockCount = ix + 1
  12. , names = supply
  13. }
  14. return (Name qname)
  15. setBlock :: Name -> Codegen Name
  16. setBlock bname = do
  17. modify $ \s -> s { currentBlock = bname }
  18. return bname
  19. getBlock :: Codegen Name
  20. getBlock = gets currentBlock
  21. modifyBlock :: BlockState -> Codegen ()
  22. modifyBlock new = do
  23. active <- gets currentBlock
  24. modify $ \s -> s { blocks = Map.insert active new (blocks s) }
  25. current :: Codegen BlockState
  26. current = do
  27. c <- gets currentBlock
  28. blks <- gets blocks
  29. case Map.lookup c blks of
  30. Just x -> return x
  31. Nothing -> error $ "No such block: " ++ show c