Skip to content

Commit

Permalink
Add variables to instructions
Browse files Browse the repository at this point in the history
  • Loading branch information
jaspervdj committed Oct 22, 2024
1 parent e082be1 commit 6b0ea77
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 27 deletions.
85 changes: 59 additions & 26 deletions lib/Patat/Presentation/Instruction.hs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ module Patat.Presentation.Instruction
, fromList
, toList

, Var
, VarGen
, zeroVarGen
, freshVar

, Instruction (..)
, numFragments

Expand Down Expand Up @@ -36,21 +41,37 @@ fromList = Instructions . go
toList :: Instructions a -> [Instruction a]
toList (Instructions xs) = xs

-- | A variable is like a placeholder in the instructions, something we don't
-- know yet, dynamic content. Currently this is only used for code evaluation.
newtype Var = Var Int deriving (Show)

-- | Used to generate fresh variables.
newtype VarGen = VarGen Int deriving (Show)

zeroVarGen :: VarGen
zeroVarGen = VarGen 0

freshVar :: VarGen -> (Var, VarGen)
freshVar (VarGen x) = (Var x, VarGen (x + 1))

data Instruction a
-- Pause.
= Pause
-- Append items.
| Append [a]
-- Append the content of a variable.
| AppendVar Var
-- Remove the last item.
| Delete
-- Modify the last block with the provided instruction.
| ModifyLast (Instruction a)
deriving (Show)

isPause :: Instruction a -> Bool
isPause Pause = True
isPause (Append _) = False
isPause Delete = False
isPause Pause = True
isPause (Append _) = False
isPause (AppendVar _) = False
isPause Delete = False
isPause (ModifyLast i) = isPause i

numPauses :: Instructions a -> Int
Expand All @@ -61,39 +82,51 @@ numFragments = succ . numPauses

newtype Fragment = Fragment [Pandoc.Block] deriving (Show)

renderFragment :: Int -> Instructions Pandoc.Block -> Fragment
renderFragment = \n (Instructions instrs) -> Fragment $ go [] n instrs
renderFragment
:: (Var -> [Pandoc.Block]) -> Int -> Instructions Pandoc.Block -> Fragment
renderFragment resolve = \n (Instructions instrs) -> Fragment $ go [] n instrs
where
go acc _ [] = acc
go acc _ [] = acc
go acc n (Pause : instrs) = if n <= 0 then acc else go acc (n - 1) instrs
go acc n (instr : instrs) = go (goBlocks instr acc) n instrs

goBlocks :: Instruction Pandoc.Block -> [Pandoc.Block] -> [Pandoc.Block]
goBlocks Pause xs = xs
goBlocks (Append ys) xs = xs ++ ys
goBlocks Delete xs = sinit xs
goBlocks (ModifyLast f) xs
go acc n (instr : instrs) = go (goBlocks resolve instr acc) n instrs

goBlocks
:: (Var -> [Pandoc.Block]) -> Instruction Pandoc.Block -> [Pandoc.Block]
-> [Pandoc.Block]
goBlocks _ Pause xs = xs
goBlocks _ (Append ys) xs = xs ++ ys
goBlocks resolve (AppendVar v) xs = xs ++ resolve v
goBlocks _ Delete xs = sinit xs
goBlocks resolve (ModifyLast f) xs
| null xs = xs -- Shouldn't happen unless instructions are malformed.
| otherwise = modifyLast (goBlock f) xs
| otherwise = modifyLast (goBlock resolve f) xs

goBlock :: Instruction Pandoc.Block -> Pandoc.Block -> Pandoc.Block
goBlock Pause x = x
goBlock (Append ys) block = case block of
goBlock
:: (Var -> [Pandoc.Block]) -> Instruction Pandoc.Block -> Pandoc.Block
-> Pandoc.Block
goBlock _ Pause x = x
goBlock _ (Append ys) block = case block of
-- We can only append to a few specific block types for now.
Pandoc.BulletList xs -> Pandoc.BulletList $ xs ++ [ys]
Pandoc.BulletList xs -> Pandoc.BulletList $ xs ++ [ys]
Pandoc.OrderedList attr xs -> Pandoc.OrderedList attr $ xs ++ [ys]
_ -> block
goBlock Delete block = case block of
_ -> block
goBlock resolve (AppendVar v) block = case block of
-- We can only append to a few specific block types for now.
Pandoc.BulletList xs -> Pandoc.BulletList $ sinit xs
Pandoc.BulletList xs -> Pandoc.BulletList $ xs ++ [resolve v]
Pandoc.OrderedList attr xs -> Pandoc.OrderedList attr $ xs ++ [resolve v]
_ -> block
goBlock _ Delete block = case block of
-- We can only delete from a few specific block types for now.
Pandoc.BulletList xs -> Pandoc.BulletList $ sinit xs
Pandoc.OrderedList attr xs -> Pandoc.OrderedList attr $ sinit xs
_ -> block
goBlock (ModifyLast f) block = case block of
_ -> block
goBlock resolve (ModifyLast f) block = case block of
-- We can only modify the last content of a few specific block types for
-- now.
Pandoc.BulletList xs -> Pandoc.BulletList $ modifyLast (goBlocks f) xs
Pandoc.OrderedList attr xs ->
Pandoc.OrderedList attr $ modifyLast (goBlocks f) xs
Pandoc.BulletList xs -> Pandoc.BulletList $
modifyLast (goBlocks resolve f) xs
Pandoc.OrderedList attr xs -> Pandoc.OrderedList attr $
modifyLast (goBlocks resolve f) xs
_ -> block

modifyLast :: (a -> a) -> [a] -> [a]
Expand Down
4 changes: 3 additions & 1 deletion lib/Patat/Presentation/Internal.hs
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,9 @@ activeFragment presentation = do
TitleSlide lvl is -> ActiveTitle $
Pandoc.Header lvl Pandoc.nullAttr is
ContentSlide instrs -> ActiveContent $
Instruction.renderFragment fidx instrs
Instruction.renderFragment resolve fidx instrs
where
resolve _ = [Pandoc.Para [Pandoc.Str "implement resolve"]]


--------------------------------------------------------------------------------
Expand Down

0 comments on commit 6b0ea77

Please sign in to comment.