dfa rework

This commit is contained in:
crumbtoo
2023-11-09 14:11:31 -07:00
parent 4c8eba0b41
commit 80e55e6437

View File

@@ -1,5 +1,6 @@
{-# LANGUAGE LambdaCase, BlockArguments #-} {-# LANGUAGE LambdaCase, BlockArguments, ViewPatterns #-}
module TI where module TI
where
---------------------------------------------------------------------------------- ----------------------------------------------------------------------------------
import Data.Map (Map, (!?), (!)) import Data.Map (Map, (!?), (!))
import Data.Map qualified as M import Data.Map qualified as M
@@ -58,42 +59,6 @@ buildInitialHeap (Program scdefs) = mapAccumL allocateSc mempty scdefs
where where
(h', addr) = alloc h (NSupercomb n a b) (h', addr) = alloc h (NSupercomb n a b)
evalProgram :: Program -> Maybe TiState
evalProgram p = last <$> evalDFA step <$> compile p
step :: DFA TiState
step = DFA \ st@(TiState stack _ heap _ _) -> do
case stack of
[] -> error "stack is empty"
[a] -> case hLookup a heap of
Just (NNum n) -> Nothing
_ -> error "i don't wanna properly handle errors rn :3"
(a:_) -> case hLookup a heap of
Just node -> Just $ dispatch st node
Nothing -> error "imaginary segfault oooh"
where
dispatch :: TiState -> Node -> TiState
dispatch st = \case
NNum n -> numStep st n
NAp f x -> apStep st f x
NSupercomb n a b -> scStep st n a b
numStep :: TiState -> Int -> TiState
numStep _ _ = error "number applied as a function"
apStep :: TiState -> Addr -> Addr -> TiState
apStep (TiState s d h g sts) f x =
TiState (f:s) d h g sts
scStep :: TiState -> Name -> [Name] -> Expr -> TiState
scStep (TiState s d h g sts) n as b =
TiState s' d h' g sts
where
s' = resAddr : drop (length as + 1) s
(h', resAddr) = instantiate b h env
env = argBinds ++ g
argBinds = as `zip` getArgs h s
getArgs :: TiHeap -> [Addr] -> [Addr] getArgs :: TiHeap -> [Addr] -> [Addr]
getArgs h (sc:s) = fmap f s getArgs h (sc:s) = fmap f s
where where
@@ -112,11 +77,45 @@ instantiate (Var k) h g = (h, fromMaybe (error "variable not in scope") v)
instantiate (Case _ _) _ _ = error "cannot instantiate case expressions" instantiate (Case _ _) _ _ = error "cannot instantiate case expressions"
instantiate _ _ _ = error "unimplemented" instantiate _ _ _ = error "unimplemented"
----------------------------------------------------------------------------------
eval :: TiState -> [TiState]
eval st = st : sts
where
sts | isFinal st = []
| otherwise = eval next
next = doAdmin (step st)
step :: TiState -> TiState
step st =
let TiState (top:_) _ h _ _ = st
in case fromMaybe (error "segfault!") (hLookup top h) of
NNum n -> numStep n st
NAp f x -> apStep f x st
NSupercomb n as b -> ncStep n as b st
where
numStep :: Int -> TiState -> TiState
numStep _ _ = error "number applied as function..."
apStep :: Addr -> Addr -> TiState -> TiState
apStep f x (TiState s d h g sts) =
TiState (f:s) d h g sts
ncStep :: Name -> [Name] -> Expr -> TiState -> TiState
ncStep n as b (TiState s d h g sts) =
TiState s' d h' g sts
where
s' = resAddr : drop (length as + 1) s
(h', resAddr) = instantiate b h env
env = argBinds ++ g
argBinds = as `zip` getArgs h s
isFinal :: TiState -> Bool isFinal :: TiState -> Bool
isFinal (TiState [addr] _ h _ _) = isFinal (TiState [addr] _ h _ _) =
case hLookup addr h of case hLookup addr h of
Just a -> isDataNode a Just a -> isDataNode a
_ -> error "i don't wanna properly handle errors rn :3" _ -> error "isFinal: segfault!"
isFinal (TiState [] _ _ _ _) = error "empty stack..." isFinal (TiState [] _ _ _ _) = error "empty stack..."
isFinal _ = False isFinal _ = False
@@ -127,4 +126,8 @@ isDataNode _ = False
doAdmin :: TiState -> TiState doAdmin :: TiState -> TiState
doAdmin (TiState s d h g stats) = TiState s d h g (stats+1) doAdmin (TiState s d h g stats) = TiState s d h g (stats+1)
testProg :: Program
testProg = Program
[ ScDef "main" [] $ IntP 2
]