return, pushcall
build / build (push) Failing after 13m21s

This commit is contained in:
2026-08-28 11:39:37 -06:00
parent 5ccb3f3e1a
commit 9d5140c0e2
4 changed files with 74 additions and 17 deletions
+4 -4
View File
@@ -70,12 +70,12 @@ pattern ValLabel x = ValImm (ImmLabel x)
newtype Label = MkLabel { inner :: Name } newtype Label = MkLabel { inner :: Name }
deriving stock (Generic, Data) deriving stock (Generic, Data)
deriving newtype (Show, Eq, Gen, IsString, Hashable) deriving newtype (Show, Eq, Gen, IsString, Hashable)
deriving anyclass (NFData) deriving anyclass (NFData, Wrapped)
newtype Reg = MkReg { inner :: Name } newtype Reg = MkReg { inner :: Name }
deriving stock (Generic, Data) deriving stock (Generic, Data)
deriving newtype (Show, Eq, Gen, IsString, Hashable) deriving newtype (Show, Eq, Gen, IsString, Hashable)
deriving anyclass (NFData) deriving anyclass (NFData, Wrapped)
data Imm data Imm
= ImmInt Int = ImmInt Int
@@ -95,7 +95,7 @@ pattern ObjLabel l = ObjImm (ImmLabel l)
-- | a heap object. -- | a heap object.
data Hob data Hob
= HobClosure { label :: Name, env :: List Obj } = HobClosure { label :: Label, env :: List Obj }
| HobPair Obj Obj | HobPair Obj Obj
deriving stock (Show, Generic, Data, Eq) deriving stock (Show, Generic, Data, Eq)
deriving anyclass (NFData) deriving anyclass (NFData)
@@ -213,7 +213,7 @@ instance S.DatumIso Hob where
where where
conspair = S.dottedList (S.el S.datumIso) S.datumIso conspair = S.dottedList (S.el S.datumIso) S.datumIso
-- closures can be printed, but not parsed. -- closures can be printed, but not parsed.
closure :: G (Datum :- t) (List Obj :- Name :- t) closure :: G (Datum :- t) (List Obj :- Label :- t)
closure = IG.Flip $ IG.PartialIso closure = IG.Flip $ IG.PartialIso
(\(env:-code:-t) -> S.Unreadable "#<procedure>" :- t) (\(env:-code:-t) -> S.Unreadable "#<procedure>" :- t)
(const . Left $ mempty) (const . Left $ mempty)
+3 -1
View File
@@ -14,7 +14,9 @@ module Gyehoek.Stack.Syntax
, Imm(..) , Imm(..)
, Hob(..) , Hob(..)
, Prim(..) , Prim(..)
, Name , Name(..)
, Reg(..)
, Label(..)
, pattern ValLabel , pattern ValLabel
, pattern ObjLabel , pattern ObjLabel
, stkP , stkP
+54 -11
View File
@@ -32,14 +32,14 @@ import Data.String (fromString)
-- | non-essential information maintained only to aide in debugging. -- | non-essential information maintained only to aide in debugging.
data DebugVM = MkDebugVM data DebugVM = MkDebugVM
{ currentRoutine :: Name { currentRoutine :: Label
} }
deriving (Show, Generic) deriving (Show, Generic)
newtype Frame = MkFrame { locals :: List Obj } newtype Frame = MkFrame { locals :: List Obj }
deriving (Show, Generic) deriving (Show, Generic)
returnAddress :: Traversal' Frame Name returnAddress :: Traversal' Frame Label
returnAddress = #locals . _last . #ObjImm . #ImmLabel returnAddress = #locals . _last . #ObjImm . #ImmLabel
newtype Stack = MkStack { frames :: NonEmpty Frame } newtype Stack = MkStack { frames :: NonEmpty Frame }
@@ -49,7 +49,7 @@ data VM = MkVM
{ stack :: Stack { stack :: Stack
, code :: List Instr , code :: List Instr
, tail :: Tail , tail :: Tail
, registers :: HashMap Name Obj , registers :: HashMap Reg Obj
, stdout :: Text , stdout :: Text
, result :: Maybe (List Obj) , result :: Maybe (List Obj)
, debug :: DebugVM , debug :: DebugVM
@@ -63,6 +63,9 @@ instance Cons Frame Frame Obj Obj where
MkFrame (x:xs) -> Just (x, MkFrame xs) MkFrame (x:xs) -> Just (x, MkFrame xs)
MkFrame [] -> Nothing MkFrame [] -> Nothing
pushes :: Foldable f => f Obj -> Frame -> Frame
pushes = flip $ foldr cons
_NonEmpty :: Iso (NonEmpty a) (NonEmpty b) (a, List a) (b, List b) _NonEmpty :: Iso (NonEmpty a) (NonEmpty b) (a, List a) (b, List b)
_NonEmpty = iso _NonEmpty = iso
(\(x:|xs) -> (x,xs)) (\(x:|xs) -> (x,xs))
@@ -75,7 +78,7 @@ activeFrame :: Lens' VM Frame
activeFrame = #stack . #frames . _NonEmpty . _1 activeFrame = #stack . #frames . _NonEmpty . _1
data Env = MkEnv data Env = MkEnv
{ labels :: HashMap Name Routine { labels :: HashMap Label Routine
} }
deriving (Show, Generic) deriving (Show, Generic)
@@ -135,10 +138,35 @@ stepI e vm ins = vmerror [i|unimplemented instruction: #{ins}|]
stepT :: Jalmot :> es => Env -> VM -> Tail -> Eff es VM stepT :: Jalmot :> es => Env -> VM -> Tail -> Eff es VM
stepT g vm (Return nret) = stepT g vm tc@(Call nargs) =
case parseCall nargs (vm ^. activeFrame) of
Nothing -> vmerror "bla"
Just (args,f,ret,frm) ->
case g ^. #labels . at ret of
Nothing -> vmerror [i|undefined label #{ret}|]
Just rt -> do
let newFrame = MkFrame $ args ++ [ObjLabel f,ObjLabel ret]
pure $ vm
& #code .~ rt.start.code
& #tail .~ rt.start.tail
& activeFrame .~ frm
& #stack %~ pushFrame newFrame
& #registers .~ mempty
stepT g vm tc@(Return nret) =
case splitAtExact nret (vm ^. activeFrame . #locals) of case splitAtExact nret (vm ^. activeFrame . #locals) of
Nothing -> _ Nothing -> vmerror [i|bad stack at #{tc}|]
Just (_,_) -> _ Just (xs,_) ->
case vm ^? activeFrame . returnAddress of
Nothing -> vmerror [i|bad stack #{tc}|]
Just "halt" -> pure $ vm & #result ?~ xs
Just ra ->
case g ^. #labels . at ra of
Nothing -> vmerror [i|undefined label #{ra}|]
Just rt -> vm
& traverseOf (#stack . #frames) \st -> case NE.uncons st of
(_, Nothing) -> vmerror "explode"
(f, Just fs) -> pure $ fs & _NonEmpty . _1 %~ pushes xs
stepT g vm tc@(TailCall nargs) = stepT g vm tc@(TailCall nargs) =
case parseTailCall nargs (vm ^. activeFrame) of case parseTailCall nargs (vm ^. activeFrame) of
@@ -186,7 +214,7 @@ stepT g vm (If c t f) = do
_ -> t _ -> t
pure $ vm & #code .~ branch.code & #tail .~ branch.tail pure $ vm & #code .~ branch.code & #tail .~ branch.tail
evalToLabel :: Jalmot :> es => Env -> VM -> Val -> Eff es Name evalToLabel :: Jalmot :> es => Env -> VM -> Val -> Eff es Label
evalToLabel e vm v = evalToLabel e vm v =
evalVal e vm v >>= \case evalVal e vm v >>= \case
ObjImm (ImmLabel x) -> pure x ObjImm (ImmLabel x) -> pure x
@@ -209,7 +237,15 @@ takeExact n xs = case compareLength xs n of
(EQ;GT) -> Just $ take n xs (EQ;GT) -> Just $ take n xs
LT -> Nothing LT -> Nothing
parseTailCall :: Int -> Frame -> Maybe (List Obj, Name, Name) parseCall :: Int -> Frame -> Maybe (List Obj, Label, Label, Frame)
parseCall nargs frm = do
(xs,ys) <- splitAtExact (nargs+2) (frm ^. #locals)
let (xs',[f,ret]) = splitAt nargs xs
f' <- f ^? #ObjImm . #ImmLabel
ret' <- ret ^? #ObjImm . #ImmLabel
pure (xs',f',ret',MkFrame ys)
parseTailCall :: Int -> Frame -> Maybe (List Obj, Label, Label)
parseTailCall nargs frm = do parseTailCall nargs frm = do
(xs,_) <- splitAtExact (nargs+1) (frm ^. #locals) (xs,_) <- splitAtExact (nargs+1) (frm ^. #locals)
let (xs',f) = xs ^?! _Snoc let (xs',f) = xs ^?! _Snoc
@@ -362,7 +398,7 @@ ppVM vm = do
details_ do details_ do
summary_ do summary_ do
var_ [class_ "loc"] . toHtml $ vm ^. #debug . #currentRoutine var_ [class_ "loc"] . toHtml $ vm ^. #debug . #currentRoutine
. re (_Unwrapped' . prefixed "$") . re (prefixed "$" . _Unwrapped' . _Unwrapped')
pre_ do pre_ do
code_ . toHtml . pShowNoColor $ vm code_ . toHtml . pShowNoColor $ vm
td_ do td_ do
@@ -377,6 +413,13 @@ ppDatum :: S.DatumIso a => a -> Html ()
ppDatum = htmlDatum . runJalmotUnsafe . S.toDatum S.datumIso ppDatum = htmlDatum . runJalmotUnsafe . S.toDatum S.datumIso
blah = [stkP| blah = [stkP|
(define $id
(return 1))
(define $c
(return 1))
(define $start (define $start
(return 0)) (push! $c)
(push! $id)
(push! 123)
(call 1))
|] |]
+13 -1
View File
@@ -14,7 +14,7 @@ evalsTo rs p = runJalmotUnsafe (Sut.eval p) @?= rs
test_root = testGroup "stack machine" test_root = testGroup "stack machine"
[ testCase "immediate halt" do [ testCase "immediate halt" do
evalsTo [ObjImm (ImmInt 3)] [stkP| evalsTo [] [stkP|
(define $start (define $start
(return 0)) (return 0))
|] |]
@@ -24,6 +24,18 @@ test_root = testGroup "stack machine"
(push! 3) (push! 3)
(return 1)) (return 1))
|] |]
, testCase "non-tail identity function" do
evalsTo [ObjImm (ImmInt 123)] [stkP|
(define $id
(return 1))
(define $c
(return 1))
(define $start
(push! $c)
(push! $id)
(push! 123)
(call 1))
|]
-- , testCase "return constant" do -- , testCase "return constant" do
-- evalsTo [ObjImm (ImmInt 123)] [stkP| -- evalsTo [ObjImm (ImmInt 123)] [stkP|
-- (define ($start %ktail) -- (define ($start %ktail)