Improve call instruction interpreter

This commit is contained in:
2021-11-09 16:32:02 +01:00
parent 1573b055d2
commit 3faa4f4abf

View File

@@ -93,13 +93,17 @@ instructions = [ Simple { _op = Nop, _noParams = 0, _noPops = 0, _sAction = (\
] ]
call :: VM -> Params -> Pops -> ExceptT String IO VM call :: VM -> Params -> Pops -> ExceptT String IO VM
call vm (addr:_) _ = except $ return $ vm { _pc = addr, _fp = fp', _stack = stack' } call vm (addr:_) _ = except $ return $ flip execState vm $ do
where fp <- getFp
fp = _fp vm fp' <- getStackSize
stack = _stack vm retAddr <- getPc >>= return . (+2)
fp' = length stack
retAddr = _pc vm + 2 push [retAddr, fp]
stack' = S.fromList [retAddr, fp] <> stack setPc addr
setFp fp'
return ()
call _ [] _ = except $ Left $ "Address excepted" call _ [] _ = except $ Left $ "Address excepted"
ret :: VM -> Params -> Pops -> ExceptT String IO VM ret :: VM -> Params -> Pops -> ExceptT String IO VM
@@ -111,8 +115,8 @@ ret vm _ _ = do
fp' <- except $ evalState (runExceptT (getAt (stackSize - fp - 1) "Cannot determine previous frame pointer (fp)")) vm fp' <- except $ evalState (runExceptT (getAt (stackSize - fp - 1) "Cannot determine previous frame pointer (fp)")) vm
retAddr <- except $ evalState (runExceptT (getAt (stackSize - fp - 2) "Cannot determine return address" )) vm retAddr <- except $ evalState (runExceptT (getAt (stackSize - fp - 2) "Cannot determine return address" )) vm
return vm { _fp = fp', _pc = retAddr, _stack = stack' } return vm { _fp = fp', _pc = retAddr, _stack = stack' }
debug :: VM -> Params -> Pops -> ExceptT String IO VM debug :: VM -> Params -> Pops -> ExceptT String IO VM
debug vm _ _ = do debug vm _ _ = do
@@ -157,14 +161,30 @@ getAt index err = do
(Just i) -> return i (Just i) -> return i
Nothing -> except $ Left err Nothing -> except $ Left err
forward :: Int -> State VM () getPc :: State VM Int
getPc = get >>= (return . _pc)
getFp :: State VM Int
getFp = get >>= (return . _fp)
getStackSize :: State VM Int
getStackSize = get >>= (return . length . _stack)
setPc :: Int -> State VM ()
setPc pc' = do
vm <- get
put vm { _pc = pc' }
setFp :: Int -> State VM ()
setFp fp' = do
vm <- get
put vm { _fp = fp' }
forward :: Int -> State VM ()
forward offset = do forward offset = do
vm <- get vm <- get
put vm { _pc = _pc vm + offset } put vm { _pc = _pc vm + offset }
return () return ()
getPc :: State VM Int
getPc = get >>= (return . _pc)
-------------------------------------------------------------------------- --------------------------------------------------------------------------