From 59c96f9ffbcd962eaaf31afc02c2e7f0a0dff57e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Madeleine=20Sydney=20=C5=9Alaga?= Date: Tue, 30 Jun 2026 11:47:51 -0600 Subject: [PATCH] cps --- app/Gyehoek/ANF/Syntax.hs | 574 ------------------------------- app/Gyehoek/CPS/Convert.hs | 31 ++ app/Gyehoek/CPS/Syntax.hs | 77 +++++ app/Gyehoek/GenSym.hs | 5 - app/Gyehoek/QBE.hs | 61 ---- app/Gyehoek/QBE/Parse.hs | 194 ----------- app/Gyehoek/Scheme/Syntax.hs | 40 ++- app/Gyehoek/Sexp.hs | 44 ++- app/Main.hs | 67 +--- example/ascii-string-literal | Bin 16624 -> 0 bytes example/ascii-string-literal.anf | 4 - example/ascii-string-literal.s | 23 -- example/ascii-string-literal.scm | 1 - example/ascii-string-literal.ssa | 10 - example/cons | Bin 16520 -> 0 bytes example/cons.anf | 4 - example/cons.s | 18 - example/cons.scm | 1 - example/cons.ssa | 10 - example/pseudo/closure.scm | 15 - example/pseudo/t.s | 70 ---- example/pseudo/t.scm | 16 - example/pseudo/t.ssa | 30 -- example/string-literal | Bin 16600 -> 0 bytes example/string-literal.anf | 4 - example/string-literal.s | 23 -- example/string-literal.scm | 1 - example/string-literal.ssa | 10 - flake.nix | 25 +- gyehoek.cabal | 13 +- play/.gitignore | 4 - play/car.scm | 1 - play/cdr.scm | 1 - play/string.scm | 1 - play/symbol.scm | 3 - play/write-cons.scm | 1 - repl | 2 + runtime/.gitignore | 1 - runtime/Cargo.lock | 112 ------ runtime/Cargo.toml | 20 -- runtime/default.nix | 24 -- runtime/src/capi.rs | 24 -- runtime/src/gc.rs | 34 -- runtime/src/lib.rs | 9 - runtime/src/primitives.rs | 31 -- runtime/src/scm.rs | 203 ----------- runtime/src/var.rs | 26 -- shake-wrapper.nix | 14 + 48 files changed, 205 insertions(+), 1677 deletions(-) delete mode 100644 app/Gyehoek/ANF/Syntax.hs create mode 100644 app/Gyehoek/CPS/Convert.hs create mode 100644 app/Gyehoek/CPS/Syntax.hs delete mode 100644 app/Gyehoek/QBE.hs delete mode 100644 app/Gyehoek/QBE/Parse.hs delete mode 100755 example/ascii-string-literal delete mode 100644 example/ascii-string-literal.anf delete mode 100644 example/ascii-string-literal.s delete mode 100644 example/ascii-string-literal.scm delete mode 100644 example/ascii-string-literal.ssa delete mode 100755 example/cons delete mode 100644 example/cons.anf delete mode 100644 example/cons.s delete mode 100644 example/cons.scm delete mode 100644 example/cons.ssa delete mode 100644 example/pseudo/closure.scm delete mode 100644 example/pseudo/t.s delete mode 100644 example/pseudo/t.scm delete mode 100644 example/pseudo/t.ssa delete mode 100755 example/string-literal delete mode 100644 example/string-literal.anf delete mode 100644 example/string-literal.s delete mode 100644 example/string-literal.scm delete mode 100644 example/string-literal.ssa delete mode 100644 play/.gitignore delete mode 100644 play/car.scm delete mode 100644 play/cdr.scm delete mode 100644 play/string.scm delete mode 100644 play/symbol.scm delete mode 100644 play/write-cons.scm create mode 100644 repl delete mode 100644 runtime/.gitignore delete mode 100644 runtime/Cargo.lock delete mode 100644 runtime/Cargo.toml delete mode 100644 runtime/default.nix delete mode 100644 runtime/src/capi.rs delete mode 100644 runtime/src/gc.rs delete mode 100644 runtime/src/lib.rs delete mode 100644 runtime/src/primitives.rs delete mode 100644 runtime/src/scm.rs delete mode 100644 runtime/src/var.rs create mode 100644 shake-wrapper.nix diff --git a/app/Gyehoek/ANF/Syntax.hs b/app/Gyehoek/ANF/Syntax.hs deleted file mode 100644 index 1ddd875..0000000 --- a/app/Gyehoek/ANF/Syntax.hs +++ /dev/null @@ -1,574 +0,0 @@ -{-# LANGUAGE OverloadedLabels #-} -{-# LANGUAGE PatternSynonyms #-} -{-# LANGUAGE ViewPatterns #-} -{-# LANGUAGE BlockArguments #-} -{-# LANGUAGE OverloadedLists #-} -{-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE PartialTypeSignatures #-} -{-# OPTIONS_GHC -Wno-orphans -Wno-unused-matches -Wno-missing-signatures #-} -{- HLINT ignore "Avoid lambda using `infix`" -} -module Gyehoek.ANF.Syntax - ( Exp(..) - , toANF - , lower - , wrapFunction - , lowerProgram - ) - where - -import Data.Text (Text) -import Effectful -import Gyehoek.QBE qualified as QBE -import Data.List (List) -import Data.Text.IO qualified as TIO -import Control.Lens -import Data.Generics.Labels -import Data.Vector.Strict (Vector) -import Data.Function (fix) -import Effectful.Writer.Static.Local -import Gyehoek.Scheme.Syntax qualified as Lam -import Gyehoek.Scheme.Syntax (Name, Prim(..), Lit(..)) -import Gyehoek.GenSym -import Control.Monad.Cont -import Data.Foldable -import Data.List.NonEmpty (NonEmpty((:|))) -import Data.List.NonEmpty qualified as NE -import Gyehoek.QBE (FuncDef(FuncDef)) -import Data.Foldable1 -import qualified Data.Text as T -import Data.String (fromString) -import Language.SexpGrammar as Sexp hiding (List, iso, encode, decode, traversed) -import Language.SexpGrammar.Generic -import GHC.Generics (Generic) -import Gyehoek.Sexp -import Control.Category -import Prelude hiding ((.), id) -import Data.InvertibleGrammar.Base qualified as IG -import Data.InvertibleGrammar.Base ((:-)((:-))) -import qualified Gyehoek.Sexp -import Control.Lens.Unsound -import qualified Data.Bits -import qualified GHC.IO.Encoding as T -import qualified Data.Text.Encoding as T -import Data.HashMap.Strict (HashMap) -import Effectful.State.Static.Local -import qualified Data.HashMap.Strict as HM - - -data Val - = ValLit Lit - | ValVar Name - deriving (Show, Generic) - -data Exp - = ExpLetApply Name Val (List Val) Exp - | ExpLetPrim Name (Prim Val) Exp - | ExpBegin (List Exp) - | ExpVal Val - deriving (Show, Generic) - - - -expandBindings - -- | Match constructor. (an affine fold would be preferable to a - -- prism here) - :: Prism' e (lhs, rhs, e) - -> e - -> (List (lhs, rhs), e) -expandBindings p = go [] where - go acc e = - case e ^? p of - Just (l,r,e') -> go ((l,r):acc) e' - Nothing -> (acc, e) - -collapseBindings - :: Foldable f => AReview e (lhs, rhs, e) -> f (lhs, rhs) - -> e -> e -collapseBindings p bs e = foldr (\(l,r) e' -> p # (l,r,e')) e bs - --- | Technically unlawful. -bindingTelescope - :: Prism' e (lhs, rhs, e) - -> Iso' e (List (lhs, rhs), e) -bindingTelescope p = iso - (expandBindings p) - (uncurry $ collapseBindings p) - -foldLet - :: Prism' Exp (lhs, rhs, Exp) - -> Grammar - Position - (Exp :- NonEmpty (lhs, rhs) :- t) - (Exp :- rhs :- lhs :- t) -foldLet p = - IG.Iso - (\(e :- ((l1,r1):|bs) :- t) -> - collapseBindings p bs e :- r1 :- l1 :- t) - (\(e :- r :- l :- t) -> - let (bs,e') = expandBindings p e - in e' :- ((l,r) :| bs) :- t) - -instance SexpIso Val where - sexpIso = match - $ With (. sexpIso) - $ With (. symbol) - $ End - -nonEmptyIso :: Iso (NonEmpty a) (NonEmpty b) (a, List a) (b, List b) -nonEmptyIso = iso (\(x:|xs) -> (x,xs)) (uncurry (:|)) - --- nonEmptyGrammar :: Grammar p (NonEmpty x :- t) (List x :- x :- t) --- nonEmptyGrammar = IG.Iso --- (\((x:|xs) :- t) -> xs :- x :- t) --- (\(xs :- x :- t) -> (x:|xs) :- t) - -instance SexpIso Exp where - sexpIso = match - $ With (. letapp) - $ With (. letprim) - $ With (\bgn -> bgn . list (el (sym "begin") >>> rest sexpIso)) - $ With (. sexpIso) - $ End - where - letprim - :: Grammar Position (Sexp :- t) (Exp :- (Prim Val :- (Text :- t))) - letprim = - Gyehoek.Sexp.let_ symbol (sexpIso @(Prim Val)) (sexpIso @Exp) - >>> foldLet #ExpLetPrim - letapp :: Grammar - Position (Sexp :- t) (Exp :- List Val :- Val :- Text :- t) - letapp = - Gyehoek.Sexp.let_ symbol (sexpIso @(NonEmpty Val)) (sexpIso @Exp) - >>> foldLet (#ExpLetApply - . iso (\(rhs,f,xs,e) -> (rhs, f:|xs, e)) - (\(rhs,f:|xs,e) -> (rhs,f,xs,e))) - >>> onTail nonEmptyGrammar - - - --- 뻘짓이어라 -telescope :: Traversable t => t ((a -> r) -> r) -> (t a -> r) -> r -telescope = runCont . traverse cont - -toANF' - :: forall es. GenSym :> es - => Lam.Exp - -> (Val -> Eff es Exp) - -> Eff es Exp - -toANF' (Lam.ExpLit v) k = k . ValLit $ v - -toANF' (Lam.ExpPrim p) k = - telescope (toANF' <$> p) \p' -> do - r <- gensym - ExpLetPrim r p' <$> k (ValVar r) - -toANF' (Lam.ExpApply f xs) k = - telescope (toANF' <$> (f:|xs)) \(f':|xs') -> do - r <- gensym - ExpLetApply r f' xs' <$> k (ValVar r) - -toANF' (Lam.ExpBegin xs) k = ExpBegin <$> traverse anf xs - where - anf x = toANF' x (pure . ExpVal) - -toANF' (Lam.ExpLet xs e) k = _ - -toANF' e k = _ - -toANF e = toANF' e (pure . ExpVal) - - - -expr = - Lam.ExpPrim - (PrimAdd - (Lam.ExpPrim - (PrimMul - (Lam.ExpLit (LitInt 2)) - (Lam.ExpLit (LitInt 3)))) - (Lam.ExpLit (LitInt 4))) - -expr2 = - Lam.ExpBegin - [ Lam.ExpPrim - (PrimWrite - (Lam.ExpPrim - (PrimCons - (Lam.ExpLit (LitInt 2)) - (Lam.ExpLit (LitInt 3))))) - , Lam.ExpPrim - (PrimWrite - (Lam.ExpPrim - (PrimMul - (Lam.ExpLit (LitInt 5)) - (Lam.ExpLit (LitInt 4))))) - ] - - - -instance Semigroup QBE.Program where - QBE.Program ts ds fs <> QBE.Program ts' ds' fs' = - QBE.Program (ts <> ts') (ds <> ds') (fs <> fs') - -instance Monoid QBE.Program where - mempty :: QBE.Program - mempty = QBE.Program mempty mempty mempty - -funcdef - :: QBE.Ident QBE.Global - -> List QBE.Param -> NonEmpty QBE.Block -> FuncDef -funcdef name ps = - QBE.FuncDef - mempty - (Just (QBE.AbiBaseTy QBE.Long)) - name Nothing ps QBE.NoVariadic - -prims :: QBE.Program -prims = QBE.Program primtys mempty primfns where - primtys = - [ QBE.TypeDef "scm" Nothing - [ (QBE.SubExtTy (QBE.BaseTy QBE.Long), Just 2) ] - ] - primfns = [ -- write - -- , mkArith "plus" QBE.Add - -- , mkArith "star" QBE.Mul - -- , mkArith "_" QBE.Sub - -- , mkArith "slash" (QBE.Div QBE.Signed) - ] - mkArith name bop = - funcdef name - [ QBE.Param (QBE.AbiBaseTy QBE.Long) "x" - , QBE.Param (QBE.AbiBaseTy QBE.Long) "y" - ] - [ QBE.Block "start" [] - [ QBE.BinaryOp ("r" QBE.:= QBE.Long) bop - (QBE.ValTemporary "x") (QBE.ValTemporary "y") - ] - (QBE.Ret (Just (QBE.ValTemporary "r"))) - ] - -data BlockBuilder - = Emit (Vector QBE.Inst) !BlockBuilder - | Exit QBE.Jump - deriving (Show) - -instance Semigroup BlockBuilder where - Emit a as <> bs = Emit a (as <> bs) - Exit _ <> bs = bs - -instance Each BlockBuilder BlockBuilder QBE.Inst QBE.Inst where - each k (Emit is bb) = Emit <$> traverse k is <*> each k bb - each k (Exit j) = pure (Exit j) - -evalBlockBuilder :: BlockBuilder -> (Vector QBE.Inst, QBE.Jump) -evalBlockBuilder (Emit is bb) = evalBlockBuilder bb & _1 <>:~ is -evalBlockBuilder (Exit j) = ([],j) - -buildBlock :: QBE.Ident QBE.Label -> BlockBuilder -> QBE.Block -buildBlock n bb = QBE.Block n [] (is ^.. each) j - where (is,j) = evalBlockBuilder bb - -lowerName :: Name -> QBE.Ident t -lowerName = fromString . T.unpack - -lowerInt' = QBE.ValConst . QBE.CInt . fromIntegral - -lowerInt = QBE.ValConst . QBE.CInt - . (Data.Bits..|. 2) - . (Data.Bits..<<. 2) - . fromIntegral - -lowerString - :: forall es. (GenSym :> es, State StringLiterals :> es) - => Text -> (QBE.Val -> Eff es BlockBuilder) -> Eff es BlockBuilder -lowerString s k = do - let len = lengthOf each $ T.encodeUtf8 s - rawString <- getRawString - r <- gensym - Emit (alloc r rawString len) <$> k (QBE.ValTemporary r) - where - -- getRawString - -- :: forall es. (GenSym :> es, State StringLiterals :> es) - -- => Eff es _ - getRawString = do - x <- get - case x ^. at s of - Just s' -> pure s' - Nothing -> do r <- gensym - state \lits -> (r, HM.insert s r lits) - alloc r rs len = - [ QBE.Call - (Just (r, QBE.AbiBaseTy QBE.Long)) - (QBE.ValGlobal "scm_from_utf8_string") - Nothing - [ QBE.Arg (QBE.AbiBaseTy QBE.Long) (QBE.ValGlobal rs) - -- N.b. The C function declares this argument as size_t, which - -- /is/ long on my system. - , QBE.Arg (QBE.AbiBaseTy QBE.Long) (lowerInt' len) - ] - [] - ] - -type StringLiterals = HashMap Text (QBE.Ident QBE.Global) - -lowerVal - :: forall es. (GenSym :> es, State StringLiterals :> es) - => Val - -> (QBE.Val -> Eff es BlockBuilder) - -> Eff es BlockBuilder - -lowerVal (ValLit (LitInt n)) k = k . lowerInt $ n - -lowerVal (ValLit (LitQuote (Lam.SexpSymbol s))) k = - lowerString s \s' -> do - r <- gensym - Emit (intern r s') <$> k (QBE.ValTemporary r) - where - intern r s' = - [ QBE.Call - (Just (r, QBE.AbiBaseTy QBE.Long)) - (QBE.ValGlobal "scm_string_to_symbol") - Nothing - [ QBE.Arg (QBE.AbiBaseTy QBE.Long) s' - ] - [] - ] - -lowerVal (ValLit (LitString s)) k = lowerString s k - -lowerVal (ValLit _) k = error "todo" -lowerVal (ValVar x) k = k . QBE.ValTemporary . lowerName $ x - -binaryPrim :: Prism' (Prim a) (QBE.BinaryOp, a, a) -binaryPrim = prism' up down where - up (bop,a,b) = case bop of - QBE.Add -> _ - QBE.Mul -> _ - _ -> _ - down = \case - PrimAdd a b -> Just (QBE.Add,a,b) - PrimMul a b -> Just (QBE.Mul,a,b) - _ -> Nothing - -lowerArithmetic :: QBE.Assignment -> Prim QBE.Val -> QBE.Inst -lowerArithmetic r p = QBE.BinaryOp r bop x y - where - (bop,x,y) = case p of - PrimAdd a b -> (QBE.Add,a,b) - PrimMul a b -> (QBE.Mul,a,b) - _ -> _ - -sizeofScm :: Integral a => a -sizeofScm = 8 - -lowerCons - :: (GenSym :> es, State StringLiterals :> es) - => Name -> QBE.Val -> QBE.Val -> Exp - -> (QBE.Val -> Eff es BlockBuilder) - -> Eff es BlockBuilder -lowerCons r car cdr e k = do - r1 <- gensym - Emit (alloc <> initialise r1) <$> lower' e k - where - alloc = [ QBE.Call - (Just (lowerName r, QBE.AbiBaseTy QBE.Long)) - (QBE.ValGlobal "GC_malloc") - Nothing - [ QBE.Arg - (QBE.AbiBaseTy QBE.Long) - (QBE.ValConst (QBE.CInt (sizeofScm * 2))) ] - [] - ] - initialise r1 = - [ QBE.BinaryOp (r1 QBE.:= QBE.Long) QBE.Add - (QBE.ValTemporary (lowerName r)) (QBE.ValConst (QBE.CInt 8)) - , QBE.Store (QBE.BaseTy QBE.Long) car (QBE.ValTemporary (lowerName r)) - , QBE.Store (QBE.BaseTy QBE.Long) cdr (QBE.ValTemporary r1) - ] - -smallIntHelper' - :: GenSym :> es - => QBE.Ident 'QBE.Temporary - -> QBE.BinaryOp - -> QBE.Val -> QBE.Val - -> (QBE.Val -> Eff es BlockBuilder) - -> Eff es BlockBuilder -smallIntHelper' r bop v1 v2 k = do - Emit [ QBE.BinaryOp (r QBE.:= QBE.Long) - bop v1 v2 ] - <$> k (QBE.ValTemporary r) - -smallIntHelper - :: GenSym :> es - => QBE.BinaryOp - -> QBE.Val -> QBE.Val - -> (QBE.Val -> Eff es BlockBuilder) - -> Eff es BlockBuilder -smallIntHelper bop a b k = do - r <- gensym - smallIntHelper' r bop a b k - -makeSmallInt' - :: forall es. (GenSym :> es) - => QBE.Ident 'QBE.Temporary - -> QBE.Val - -> (QBE.Val -> Eff es BlockBuilder) - -> Eff es BlockBuilder -makeSmallInt' r n k = - smallIntHelper QBE.Shl n (lowerInt' 2) \n' -> - smallIntHelper' r QBE.Add n' (lowerInt' 2) k - -makeSmallInt - :: forall es. (GenSym :> es) - => QBE.Val - -> (QBE.Val -> Eff es BlockBuilder) - -> Eff es BlockBuilder -makeSmallInt n k = do - r <- gensym - makeSmallInt' r n k - -getSmallInt - :: forall es. (GenSym :> es) - => QBE.Val - -> (QBE.Val -> Eff es BlockBuilder) - -> Eff es BlockBuilder -getSmallInt n = smallIntHelper QBE.Shr n (lowerInt' 2) - -lowerWrite - :: forall es. (GenSym :> es) - => Name -> QBE.Val -> Exp - -> (QBE.Val -> Eff es BlockBuilder) - -> Eff es BlockBuilder -lowerWrite r x e k = - Emit [ QBE.Call (Just (lowerName r, QBE.AbiBaseTy QBE.Long)) - (QBE.ValGlobal "scm_write") Nothing - [QBE.Arg (QBE.AbiBaseTy QBE.Long) x] - [] - ] - <$> k (QBE.ValTemporary (lowerName r)) - -smallIntMask :: Integer -smallIntMask = 2 ^ (sizeofScm * 8) - 2 - -lowerCar - :: (GenSym :> es, State StringLiterals :> es) - => Name -> QBE.Val -> _ - -> (QBE.Val -> Eff es BlockBuilder) -> Eff es BlockBuilder -lowerCar r x e k = do - Emit [ QBE.Load (lowerName r QBE.:= QBE.Long) QBE.Long x - ] - <$> lower' e k - -lowerCdr - :: (GenSym :> es, State StringLiterals :> es) - => Name -> QBE.Val -> Exp - -> (QBE.Val -> Eff es BlockBuilder) -> Eff es BlockBuilder -lowerCdr r x e k = do - x1 <- gensym - Emit [ QBE.BinaryOp (x1 QBE.:= QBE.Long) - QBE.Add x (lowerInt' sizeofScm) - , QBE.Load (lowerName r QBE.:= QBE.Long) QBE.Long - (QBE.ValTemporary x1) - ] - <$> lower' e k - -lowerNewline r k = - Emit [ QBE.Call (Just (lowerName r, QBE.AbiBaseTy QBE.Long)) - (QBE.ValGlobal "scm_newline") Nothing - [] - [] - ] - <$> k (QBE.ValTemporary (lowerName r)) - -lowerPrim - :: forall es. (GenSym :> es, State StringLiterals :> es) - => Name -> Prim Val -> Exp - -> (QBE.Val -> Eff es BlockBuilder) - -> Eff es BlockBuilder -lowerPrim r p e k = - telescope (lowerVal <$> p) \case - (preview binaryPrim -> Just (bop,a,b)) -> - getSmallInt a \a' -> - getSmallInt b \b' -> - smallIntHelper bop a' b' \c -> - makeSmallInt' (lowerName r) c \_ -> - lower' e k - PrimCons x y -> lowerCons r x y e k - PrimCar x -> lowerCar r x e k - PrimCdr x -> lowerCdr r x e k - PrimWrite x -> lowerWrite r x e k - PrimNewline -> lowerNewline r k - -lower' - :: forall es. (GenSym :> es, State StringLiterals :> es) - => Exp - -> (QBE.Val -> Eff es BlockBuilder) - -> Eff es BlockBuilder - -lower' (ExpVal v) k = lowerVal v k - -lower' (ExpLetPrim r p e) k = lowerPrim r p e k - -lower' (ExpLetApply r f xs e) k = - telescope (lowerVal @es <$> (f:|xs)) \(f':|xs') -> - Emit [ QBE.Call - (Just (lowerName r, QBE.AbiBaseTy QBE.Long)) - f' - Nothing - (QBE.Arg (QBE.AbiBaseTy QBE.Long) <$> xs') - [] - ] - <$> lower' e k - -lower' (ExpBegin (x:xs)) k = fold1 <$> traverse low (x:|xs) - where low e = lower' @es e (pure . Exit . QBE.Ret . Just) - -lower' _ k = _ - -lower - :: (GenSym :> es, State StringLiterals :> es) - => QBE.Ident QBE.Label - -> Exp - -> Eff es QBE.Block -lower n e = buildBlock n <$> lower' e (pure . Exit . QBE.Ret . Just) - -lowerStringLiterals = - ifoldMapOf itraversed \s v -> - [ QBE.DataDef [] v Nothing - [QBE.FieldExtTy QBE.Byte [QBE.String (T.encodeUtf8 s)]]] - -lowerProgram - :: (GenSym :> es, Traversable t) - => t Exp -> Eff es QBE.Program -lowerProgram anfs = - case toList anfs of - -- hack for dev convenience: if there's only one expression, let - -- it be the entry point. - [e] -> do - (b,stringLits) <- runState mempty . lower "start" $ e - let f = wrapFunction @NonEmpty "main" [b] - dataDefs = lowerStringLiterals stringLits - pure $ QBE.Program [] dataDefs [f] - _ -> do - let low e = do - bl <- gensym' "b" - fl <- gensym' "f" - b <- lower bl e - pure $ wrapFunction @NonEmpty fl [b] - (fs,stringLits) <- runState mempty $ traverse low anfs - pure $ QBE.Program [] (lowerStringLiterals stringLits) (fs ^.. traversed) - -wrapFunction - :: Foldable1 t - => QBE.Ident 'QBE.Global -> t QBE.Block -> QBE.FuncDef -wrapFunction l bs = - QBE.FuncDef [QBE.Export] - (Just (QBE.AbiBaseTy QBE.Word)) - l Nothing [] QBE.NoVariadic (toNonEmpty bs) - -wrapProgram :: Foldable1 t => t QBE.Block -> QBE.Program -wrapProgram bs = prims <> QBE.Program [] [] [main] where - main = QBE.FuncDef [QBE.Export] - (Just (QBE.AbiBaseTy QBE.Word)) - "main" Nothing [] QBE.NoVariadic (toNonEmpty bs) diff --git a/app/Gyehoek/CPS/Convert.hs b/app/Gyehoek/CPS/Convert.hs new file mode 100644 index 0000000..7796bce --- /dev/null +++ b/app/Gyehoek/CPS/Convert.hs @@ -0,0 +1,31 @@ +module Gyehoek.CPS.Convert + ( convert + ) where + +import Gyehoek.CPS.Syntax +import Gyehoek.Scheme.Syntax qualified as Scm +import Gyehoek.GenSym +import Effectful +import Control.Monad.Cont qualified as Cont + + +-- 뻘짓이어라 +telescope + :: Traversable t + => (a -> (b -> r) -> r) + -> t a -> (t b -> r) -> r +telescope f = Cont.runCont . traverse (Cont.cont . f) + +convert + :: forall es. (GenSym :> es) + => Scm.Exp -> (Val -> Eff es Exp) -> Eff es Exp + +convert (Scm.ExpVar x) k = k $ ValVar x +convert (Scm.ExpLit l) k = k $ ValLit l + +convert (Scm.ExpPrim p) k = + telescope (convert @es) p \p' -> do + r <- gensym' "r" + ExpPrim p' [r] . pure <$> k (ValVar r) + +convert _ _ = _ diff --git a/app/Gyehoek/CPS/Syntax.hs b/app/Gyehoek/CPS/Syntax.hs new file mode 100644 index 0000000..19ebb3a --- /dev/null +++ b/app/Gyehoek/CPS/Syntax.hs @@ -0,0 +1,77 @@ +{-# LANGUAGE OverloadedLabels #-} +module Gyehoek.CPS.Syntax + ( Val(..) + , Kappa(..) + , Exp(..) + , Name(..) + , Prim(..) + ) + where + +import Language.SexpGrammar qualified as S +import Gyehoek.Sexp qualified +import Gyehoek.Scheme.Syntax (Name (..), Prim(..), primSexpIso, Lit) +import Data.Text (Text) +import Data.List (List) +import GHC.Generics (Generic) +import Language.SexpGrammar.Generic +import Control.Category +import Data.Text qualified as T +import Data.Generics.Labels +import Prelude hiding ((.), id) +import Data.List.NonEmpty (NonEmpty) + +-- Data types + +data Val + = ValLabel Name + | ValVar Name + | ValLit Lit + deriving (Show, Generic) + +data Kappa = MkKappa (List Name) Exp + deriving (Show, Generic) + +data Exp + = ExpPrim (Prim Val) (List Name) (List Exp) + | ExpFix (NonEmpty (Name, Kappa)) Exp + | ExpApply Val (List Val) + deriving (Show, Generic) + + +-- SexpIso instances + +instance S.SexpIso Val where + sexpIso = match + $ With (. label) + $ With (. var) + $ With (. S.sexpIso) + $ End + where + label = S.keyword >>> S.iso MkName getName + var = S.sexpIso + +instance S.SexpIso Kappa where + sexpIso = match + $ With (. kappa) + $ End + where + kappa = S.list $ + S.el Gyehoek.Sexp.kappaKeyword + >>> S.el (S.list $ S.rest S.sexpIso) + >>> S.el S.sexpIso + +instance S.SexpIso Exp where + sexpIso = match + $ With (. prim) + $ With (. let_) + $ With (. app) + $ End + where + let_ = Gyehoek.Sexp.let_ "fix" S.sexpIso S.sexpIso S.sexpIso + app = S.list $ S.el S.sexpIso >>> S.rest S.sexpIso + prim = S.list $ + S.el (S.sym "prim") + >>> S.el (primSexpIso id (S.sexpIso @Val)) + >>> S.el S.sexpIso + >>> S.rest S.sexpIso diff --git a/app/Gyehoek/GenSym.hs b/app/Gyehoek/GenSym.hs index 05ae094..839a74f 100644 --- a/app/Gyehoek/GenSym.hs +++ b/app/Gyehoek/GenSym.hs @@ -6,7 +6,6 @@ import Numeric.Natural import Effectful.State.Dynamic import Effectful.Dispatch.Dynamic import Effectful -import Language.QBE as QBE import Data.String (IsString(fromString)) import Data.Text (Text) import qualified Data.Text.Short as ST @@ -33,10 +32,6 @@ runGenSym = reinterpret (evalStateLocal (0 :: Natural)) \cases _ GenSym -> state \n -> (gen n, succ n) _ (GenSym' s) -> state \n -> (gen' s n, succ n) -instance Gen (QBE.Ident s) where - gen = Ident . fromString . ('.':) . show - gen' s = Ident . (ST.fromText s <>) . fromString . show - instance Gen Text where gen = fromString . ('x':) . show gen' s = (s <>) . fromString . show diff --git a/app/Gyehoek/QBE.hs b/app/Gyehoek/QBE.hs deleted file mode 100644 index 26aacc5..0000000 --- a/app/Gyehoek/QBE.hs +++ /dev/null @@ -1,61 +0,0 @@ -{-# LANGUAGE RequiredTypeArguments #-} -{-# LANGUAGE TypeFamilies #-} -{-# LANGUAGE BlockArguments #-} -{-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE ApplicativeDo #-} -{-# LANGUAGE PartialTypeSignatures #-} -{-# LANGUAGE TemplateHaskellQuotes #-} -module Gyehoek.QBE - ( module QBE - , render - , fn - , writeTo - ) - where - -import Gyehoek.QBE.Parse -import Language.QBE as QBE -import Data.String (IsString(fromString)) -import Prettyprinter (Pretty(pretty), layoutPretty, defaultLayoutOptions) -import Data.Text (Text) -import Data.Data -import Prettyprinter.Render.Text (renderStrict) -import Text.Megaparsec -import Text.Megaparsec.Char -import Language.Haskell.TH qualified as TH -import Language.Haskell.TH.Quote -import Data.Kind (Type) -import qualified Data.Text.IO as TIO - - -writeTo :: FilePath -> Text -> IO () -writeTo = TIO.writeFile - -render :: Pretty a => a -> Text -render = renderStrict . layoutPretty defaultLayoutOptions . pretty - - - -parseQuoteExp - :: (TH.Quote m, MonadFail m, Data a) => P a -> String -> m TH.Exp -parseQuoteExp p s = - case parse (space *> p <* space <* eof) "qq" (fromString s) of - Left es -> fail . foldMap f . bundleErrors $ es - where f e = parseErrorPretty e ++ "\n\n" - Right x -> dataToExpQ (\_ -> Nothing) x - --- quoteExp :: TH.Quote m => forall (t :: Type) -> (Parser t) => String -> m TH.Exp --- quoteExp t s = case parse (parser @t) "qq" (fromString s) of --- Left es -> _ --- Right x -> dataToExpQ (\_ -> Nothing) x - -makeQQ :: forall (t :: Type) -> Parser t => QuasiQuoter -makeQQ t = QuasiQuoter - { quoteExp = parseQuoteExp (parser @t) - , quotePat = _ - , quoteType = undefined - , quoteDec = undefined - } - -fn :: QuasiQuoter -fn = makeQQ (type FuncDef) diff --git a/app/Gyehoek/QBE/Parse.hs b/app/Gyehoek/QBE/Parse.hs deleted file mode 100644 index 098bffc..0000000 --- a/app/Gyehoek/QBE/Parse.hs +++ /dev/null @@ -1,194 +0,0 @@ -{-# LANGUAGE RequiredTypeArguments #-} -{-# LANGUAGE TypeFamilies #-} -{-# LANGUAGE BlockArguments #-} -{-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE ApplicativeDo #-} -{-# LANGUAGE PartialTypeSignatures #-} -module Gyehoek.QBE.Parse where - -import Language.QBE as QBE -import Effectful.State.Dynamic -import Effectful.Dispatch.Dynamic -import Effectful -import Numeric.Natural -import Data.String (IsString(fromString)) -import Prettyprinter (Pretty(pretty), layoutPretty, defaultLayoutOptions) -import Data.Text (Text) -import Data.Data -import Prettyprinter.Render.Text (renderStrict) -import Text.Megaparsec -import Text.Megaparsec.Char -import Text.Megaparsec.Char.Lexer qualified as L -import Data.Void (Void) -import Data.Char (isAlpha, isAlphaNum) -import Control.Lens.Wrapped -import Data.Functor.Contravariant (Predicate(Predicate)) -import qualified Data.Text as T -import Data.Functor -import Data.List (List) -import Data.Foldable (fold) -import Data.Maybe (isJust, fromMaybe) -import Control.Monad.Fix (MonadFix(mfix)) -import Data.List.NonEmpty (fromList) -import Language.Haskell.TH qualified as TH -import Language.Haskell.TH.Quote -import Data.Proxy -import Data.Kind (Type) - - -type P = Parsec Void Text - -sc :: P () -sc = L.space hspace1 (L.skipLineComment "#") empty - -lexeme :: P a -> P a -lexeme = L.lexeme sc - -symbol :: Text -> P Text -symbol = L.symbol sc - -infixr 8 .: -(.:) :: (c -> d) -> (a -> b -> c) -> a -> b -> d -(.:) f g x y = f (g x y) - -rawIdent :: P QBE.RawIdent -rawIdent = (fromString .: (:) <$> lead <*> trail) "ident" - where - lead = satisfy \x -> isAlpha x || (x=='.') || (x=='_') - trail = fmap T.unpack . takeWhileP Nothing $ \x -> - isAlphaNum x || (x=='.') || (x=='_') - -class ParseIdent (s :: Sigil) where - ident :: P (QBE.Ident s) - -rawIdentWithSigil :: Char -> P (Ident t) -rawIdentWithSigil c = Ident <$> lexeme (char c *> rawIdent) - -instance ParseIdent AggregateTy where ident = rawIdentWithSigil ':' -instance ParseIdent Global where ident = rawIdentWithSigil '$' -instance ParseIdent Temporary where ident = rawIdentWithSigil '%' -instance ParseIdent QBE.Label where ident = rawIdentWithSigil '@' - -const :: P QBE.Const -const = cint <|> csingle <|> cdouble <|> cglobal "const" - where - cint = CInt <$> lexeme (L.signed empty L.decimal) "integer" - csingle = empty "single-precision float" - cdouble = empty "double-precision float" - cglobal = CGlobal <$> ident "global symbol" - -val :: P QBE.Val -val = vconst <|> vtemp "val" - where - vconst = ValConst <$> Gyehoek.QBE.Parse.const - vtemp = ValTemporary <$> ident "temporary symbol" - -assignment :: P QBE.Assignment -assignment = - Assignment <$> ident <*> (char '=' *> basety) - -basety :: P QBE.BaseTy -basety = lexeme $ char 'w' $> Word - <|> char 'l' $> Long - <|> char 's' $> Single - <|> char 'd' $> Double - -abity :: P AbiTy -abity = AbiBaseTy <$> basety - <|> AbiAggregateTy <$> ident - -binaryOp :: P QBE.BinaryOp -binaryOp = lexeme $ "add" $> Add - <|> "sub" $> Sub - <|> "mul" $> Mul - <|> "div" $> Div Signed - -comma :: P a -> P a -comma p = symbol "," *> p - -inst :: P QBE.Inst -inst = try binaryOpInst <|> negInst "inst" - where - binaryOpInst = - BinaryOp - <$> assignment - <*> binaryOp - <*> val <*> comma val - negInst = Neg <$> assignment <*> (symbol "neg" *> val) - -jump :: P QBE.Jump -jump = jmp <|> jnz <|> ret <|> hlt "jump" - where - jmp = symbol "jmp" *> (Jmp <$> ident) - jnz = symbol "jnz" *> (Jnz <$> val <*> ident <*> comma ident) - ret = symbol "ret" *> (Ret <$> optional val) - hlt = empty - -nl :: P () -nl = void (some (newline *> sc)) "newline" - -phi :: P QBE.Phi -phi = empty - -block :: P QBE.Block -block = Block - <$> (ident <* nl) - <*> sepBy phi nl - <*> sepBy inst nl - <*> jump - -sepByTry :: MonadParsec e s m => m a -> m sep -> m (List a) -sepByTry p sep = do - x <- p - xs <- many (try $ sep *> p) - pure (x:xs) - -paramList :: P (Maybe (Ident Temporary), List Param, Variadic) -paramList = label "parameter list" $ between (symbol "(") (symbol ")") do - e <- optional env - ps <- optional . try $ do - commaIf (isJust e) - sepByTry reg (symbol ",") - v <- optional do - commaIf (isJust e || isJust ps) - variadic - pure (e, fromMaybe [] ps, fromMaybe NoVariadic v) - where - commaIf True = void $ symbol "," - commaIf False = pure () - env = symbol "env" *> ident @Temporary "environment parameter" - reg = Param <$> abity <*> ident "regular parameter" - variadic = symbol "..." $> Variadic "variadic parameter" - -funcdef :: P QBE.FuncDef -funcdef = do - linkages <- many linkage - symbol "function" - returnTy <- optional abity - name <- ident @Global - (env,params,variadic) <- paramList - code <- fmap fromList . between (symbol "{" *> nl) (symbol "}") $ - sepEndBy1 block nl - pure $ FuncDef linkages returnTy name env params variadic code - -linkage :: P Linkage -linkage = symbol "export" $> Export - --- stripped :: P a -> P a --- stripped p = optional nl *> - - - -class Data a => Parser a where - parser :: P a - -instance Parser FuncDef where parser = funcdef - -class ParseSeparator a where - parseSeparator :: Proxy a -> P () - -instance (Parser a, ParseSeparator a) => Parser (List a) where - parser = sepBy parser (parseSeparator @a Proxy) - -instance ParseSeparator FuncDef where parseSeparator _ = nl -instance ParseSeparator Block where parseSeparator _ = nl diff --git a/app/Gyehoek/Scheme/Syntax.hs b/app/Gyehoek/Scheme/Syntax.hs index 6edd27d..d8949ff 100644 --- a/app/Gyehoek/Scheme/Syntax.hs +++ b/app/Gyehoek/Scheme/Syntax.hs @@ -2,13 +2,15 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE PartialTypeSignatures #-} +{-# LANGUAGE DerivingStrategies #-} module Gyehoek.Scheme.Syntax - ( Name + ( Name(..) , Prim(..) , Lit(..) , Define(..) , Exp(..) , Sexp(..) + , primSexpIso ) where @@ -23,10 +25,14 @@ import Prelude hiding ((.), id) import Control.Category import Data.List.NonEmpty (NonEmpty ((:|))) import Gyehoek.Sexp qualified +import Gyehoek.GenSym (Gen) import Control.Lens (Each) +import Data.String (IsString) -type Name = Text +newtype Name = MkName { getName :: Text } + deriving newtype (Show, Eq, IsString, Gen) + deriving stock (Generic) data Prim e = PrimAdd e e @@ -40,6 +46,7 @@ data Prim e | PrimConsP e | PrimIntegerP e | PrimWrite e + | PrimZeroP e | PrimNewline deriving (Show, Generic, Functor, Foldable, Traversable) @@ -78,8 +85,14 @@ data Sexp -instance SexpIso a => SexpIso (Prim a) where - sexpIso = match +instance SexpIso Name where + sexpIso = symbol >>> Sexp.partialOsi f g + where + f = Right . MkName + g (MkName s) = s + +primSexpIso :: (Text -> Text) -> Sexp.SexpGrammar a -> Sexp.SexpGrammar (Prim a) +primSexpIso namefn a = match $ With (. binop "+") $ With (. binop "-") $ With (. binop "*") @@ -91,13 +104,16 @@ instance SexpIso a => SexpIso (Prim a) where $ With (. unop "cons?") $ With (. unop "integer?") $ With (. unop "write") + $ With (. unop "zero?") $ With (. nullop "newline") $ End where - primname = ("prim:" <>) - nullop s = list $ el (sym (primname s)) - unop s = list $ el (sym (primname s)) >>> el sexpIso - binop s = list $ el (sym (primname s)) >>> el sexpIso >>> el sexpIso + nullop s = list $ el (sym (namefn s)) + unop s = list $ el (sym (namefn s)) >>> el a + binop s = list $ el (sym (namefn s)) >>> el a >>> el a + +instance SexpIso a => SexpIso (Prim a) where + sexpIso = primSexpIso ("prim:"<>) sexpIso instance SexpIso Lit where sexpIso = match @@ -121,20 +137,20 @@ instance SexpIso Define where $ With (. defun) $ End where - defconst = list $ el (sym "define") >>> el symbol >>> el sexpIso + defconst = list $ el (sym "define") >>> el sexpIso >>> el sexpIso defun = list $ el (sym "define") >>> el args >>> rest sexpIso - args = list $ el symbol >>> rest symbol + args = list $ el sexpIso >>> rest sexpIso instance SexpIso Exp where sexpIso = match - $ With (. Gyehoek.Sexp.let_ symbol sexpIso sexpIso) + $ With (. Gyehoek.Sexp.let_ "let" sexpIso sexpIso sexpIso) $ With (. sexpIso) $ With (\bgn -> bgn . list (el (sym "begin") >>> rest sexpIso)) $ With (. sexpIso) $ With (. if_) $ With (. sexpIso) $ With (. lam) - $ With (. symbol) + $ With (. sexpIso) $ With (\app -> app . list (el sexpIso >>> rest sexpIso)) $ End where diff --git a/app/Gyehoek/Sexp.hs b/app/Gyehoek/Sexp.hs index 57864d7..826649b 100644 --- a/app/Gyehoek/Sexp.hs +++ b/app/Gyehoek/Sexp.hs @@ -12,11 +12,18 @@ module Gyehoek.Sexp , parseSexps , prefixSugar , todo + , isoIso + , encodeWith + , decodeWith + , kappa + , lambda + , kappaKeyword + , lambdaKeyword ) where import Data.Text (Text) -import Language.SexpGrammar as Sexp hiding (List, encode, decode, iso) +import Language.SexpGrammar as Sexp hiding (List, encode, decode, encodeWith, decodeWith, iso) import Language.SexpGrammar qualified as Sexp import Language.Sexp qualified as S import Language.SexpGrammar.Generic @@ -44,10 +51,16 @@ sexp = iso (either error id . decode) encode :: SexpIso a => a -> Either String Text -encode = (_Right %~ decodeUtf8 . view strict) . Sexp.encode +encode = encodeWith sexpIso decode :: SexpIso a => Text -> Either String a -decode = Sexp.decode . view lazy . encodeUtf8 +decode = decodeWith sexpIso + +encodeWith :: SexpGrammar a -> a -> Either String Text +encodeWith g = (_Right %~ decodeUtf8 . view strict) . Sexp.encodeWith g + +decodeWith :: SexpGrammar a -> Text -> Either String a +decodeWith g = Sexp.decodeWith g "FILE" . view lazy . encodeUtf8 parseSexps :: SexpIso a => FilePath -> Text -> Either String (List a) parseSexps f = marshal . SexpLoc.parseSexps f . view lazy . encodeUtf8 @@ -64,11 +77,12 @@ nonempty a = IG.flipped nonEmptyGrammar let_ - :: (forall t. Grammar Position (Sexp :- t) (a :- t)) + :: Text + -> (forall t. Grammar Position (Sexp :- t) (a :- t)) -> (forall t. Grammar Position (Sexp :- t) (b :- t)) -> Grammar Position (Sexp :- (NonEmpty (a, b) :- t1)) t2 -> Grammar Position (Sexp :- t1) t2 -let_ name rhs e = list (el (sym "let") >>> el bindings >>> el e) +let_ kw name rhs e = list (el (sym kw) >>> el bindings >>> el e) where -- bindings :: Grammar Position (Sexp :- _) (List (_, _) :- _) bindings = nonempty binding @@ -101,11 +115,29 @@ todo = (IGB.Flip $ IGB.PartialIso absurd f) >>> IGB.PartialIso absurd g f _ = Left $ unexpected "todo" g _ = Left $ unexpected "todo" +kappa + :: (forall t. Grammar Position (Sexp :- t) (a :- t)) + -> Grammar Position (Sexp :- List a :- t1) t2 + -> Grammar Position (Sexp :- t1) t2 +kappa name e = list $ + el kappaKeyword + >>> el (list $ rest name) + >>> el e + lambda :: (forall t. Grammar Position (Sexp :- t) (a :- t)) -> Grammar Position (Sexp :- List a :- t1) t2 -> Grammar Position (Sexp :- t1) t2 lambda name e = list $ - el (sym "lambda") + el lambdaKeyword >>> el (list $ rest name) >>> el e + +isoIso :: Iso' s a -> Grammar p (s :- t) (a :- t) +isoIso l = Sexp.iso (view l) (review l) + +kappaKeyword :: Grammar Position (Sexp :- t) t +kappaKeyword = coproduct [ sym "κ", sym "kappa" ] + +lambdaKeyword :: Grammar Position (Sexp :- t) t +lambdaKeyword = coproduct [ sym "λ", sym "lambda" ] diff --git a/app/Main.hs b/app/Main.hs index ca6206e..22431bd 100644 --- a/app/Main.hs +++ b/app/Main.hs @@ -5,13 +5,10 @@ module Main (main) where -import qualified Gyehoek.ANF.Syntax as ANF -import Gyehoek.QBE (render) import Gyehoek.Options import qualified Data.Text.IO as TIO import Data.Text (Text) import Prelude hiding (readFile, (.),id) -import Control.Category import Options.Applicative import Control.Lens import Data.Generics.Labels @@ -27,7 +24,6 @@ import Data.Text.Lens import Data.List (List) import qualified Gyehoek.Scheme.Syntax as Scm import Effectful.Exception -import qualified Gyehoek.QBE as QBE import qualified Data.Text as T import qualified Data.Text.Encoding as T import System.IO (Handle) @@ -57,68 +53,7 @@ readFile f = FS.withFile f FS.ReadMode hGetContents readScm :: FileSystem :> es => FilePath -> Eff es (List Scm.Exp) readScm f = (Sexp.parseSexps f <$> readFile f) >>= either error pure -toANF - :: (GenSym :> es, FileSystem :> es) - => FilePath -> List Scm.Exp -> Eff es (List ANF.Exp) -toANF f exps = do - anfs <- traverse ANF.toANF exps - case traverse Sexp.encode anfs of - Left e -> hPutStr FS.stderr (view packed e) - Right ss -> do - let anf_file = f -<.> "anf" - FS.withFile anf_file FS.WriteMode \h_anf -> do - hPutStr h_anf ";;; -*- mode:scheme -*-\n\n" - hPutStr h_anf $ foldr (\x y -> x <> "\n\n" <> y) "" ss - hPutStrLn FS.stderr $ "wrote " <> T.pack anf_file - pure anfs - -toQBE - :: (GenSym :> es, FileSystem :> es, Traversable t) - => FilePath -> t ANF.Exp -> Eff es QBE.Program -toQBE f anfs = do - p <- ANF.lowerProgram anfs - let qbe_file = f -<.> "ssa" - FS.withFile qbe_file FS.WriteMode \h -> do - hPutStr h . render $ p - hPutStrLn FS.stderr $ "wrote " <> T.pack qbe_file - pure p - -callQBE - :: (GenSym :> es, FileSystem :> es, IOE :> es) - => FilePath -> Eff es FilePath -callQBE f = do - let asm_file = f -<.> "s" - qbe_file = f -<.> "ssa" - C.StdoutUntrimmed stdout <- - C.run $ C.cmd "qbe" & C.addArgs [qbe_file] - FS.withFile asm_file FS.WriteMode \h -> do - hPutStr h stdout - hPutStrLn FS.stderr $ "wrote " <> T.pack asm_file - pure asm_file - -callGCC - :: (GenSym :> es, FileSystem :> es, IOE :> es) - => FilePath -> List String -> Eff es FilePath -callGCC f args = do - let asm_file = f -<.> "s" - exe = f -<.> "out" - C.StdoutTrimmed (T.words -> flags) <- - C.run $ C.cmd "pkg-config" - & C.addArgs @String ["--cflags", "--libs", "bdw-gc"] - C.run_ $ C.cmd "cc" - & C.addArgs flags - & C.addArgs ["-o", exe, asm_file] - & C.addArgs args - hPutStrLn FS.stderr $ "wrote " <> T.pack exe - pure exe - driver :: (GenSym :> es, FileSystem :> es, IOE :> es) => Options -> Eff es () -driver = runGenSym . traverseOf_ (#sourceFiles . folded) \f -> do - exps <- readScm f - anfs <- toANF f exps - qbe <- toQBE f anfs - callQBE f - callGCC f ["../runtime/target/debug/libgyehoek.a"] - pure () +driver = _ diff --git a/example/ascii-string-literal b/example/ascii-string-literal deleted file mode 100755 index a0f06653863f29a6ece900393f632c8f96124a55..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16624 zcmb<-^>JfjWMqH=W(GS35O0D2M8p9?F%(!r84L^z4h$9yybKNuatyKzYzzzxEMPH+ zJWM@|zQF_$htV7mE(0@Ep9F}(z`%e`2Se4tXpoygLLeGsABc?&pMY8bqZy$70O?}| zX@K%!;xPIl)EzJyCJxdEwod`1nSp@;jqZT@4@M*F1BFe1E<|5|Eh>Eks_z7phUo)w zLHZJ)`Vye}V6*{90RsaAjD~s_90wqGYA8YML8oEy0i)6NWkB_z(`eoW+XJ#8_-RQB zIrarW^?5)IMyFFihBGiQz-W*iAfdpgB`KhA0kMg}uxJi~+J`G1HbBD@MuXxTWWIi0 zW`%xnNq$kPepYU=c~wPKu6em(c}8+od0wSyu5o&HdP-J$MsB82k#2fUW>T`Qk)DZ> zuBoAZPG*vRPKs_$W?pH9ZiR)Ju9=BmalW1r$W#V!y60tJVBln6VBlh4VBm%b!%2{H zKyCmfN08rPer9K2VBle3U;xD%C>?{;f%JmZg4H-Qg3RCmiGkEzOg)#o`|+e2kRUdk z#K6EHghiqdhd9U{Xq2Jo%3@$(5JVAyaNKa16M#cp7Ab2%On{J~IMh$VA+CeNoMr|F z251t87z`zMGB7X*Fi0{;z%m9@oFU#b#5X=AwJ0?`v$!O+D8$z}CqFMWBrz!`l_5Sp zJvTouzPKc@s3blfq7LCwrf%*2tQC_@l4B?rVb z0x`jYW(@JEc_|F;KAuj_@kV;adL{@qf@!2@%AlW-pPQ9>ssg;=@}ZKYp$p;N=&RYPOq{wsVYjWw9L&et28w+DJU{FG0in9Gtf=SPtC~H z#i^h4jEL;?#3W;LQ{!B-O!Lg*^s=ggjGV+GgG7spBny-D980rI-Sp&ST|-knBRvCM za30PCpNM>?^YQlX`u`Ls)v4L{?DJZ{G3M9|O za22AQ0ahP?@-s-N0Gf#+pyfSG+yE-h0ZpGUaTx!CJxDhLxE=HP+0;K ze}E(oDqmpYFObARWerUH1CltXyn>1UKoSR)IWX}RP;rnMpfUp{z5z)bRDQw4cOZ#_ z%Q2|L0VHvlpFvV5ki@Lv_g&j882eDMGO|Np94`V0&i zpsN1m1u#De#0ND+ULFARqd@zq|_r157{2eGRrZ^%xi!O0`2hnr%0Mm>!)^OL#oGZMW$$Fuc(G|NsAs zl>h(#A7kC9$H2fCdzfDyMgPn4|NsAodUQVB2MPv{UfXt%wo8l*3?7}wUwAPvFq}LL z^Ixb(H>-sn1H*n$hJ&m9^JJsUKIZS{~zRm zP7vK|x(dmxZ!k5nAi2)tFH-;i|G!_8fq~)0YLFBTYg`x@JPy8M^5`{1nV}F2y=x`b$IwpYBJBE06 ze%S}g0wA6HMM2))^8f#TpUwmhkIo2zXvY{xWb(^17#={@o(9n$=GplTtQ9n>@uKt3 z|Nm(o{CS7dJo)p^rSaz+{1V%$(Gz3ONU^E0q zLtr!nMnhmU1V%$(q=x`#ZbLOEg+W12fkD|OBQ>!=AwMZAHMvB=phDHa&@89I4je?F zP78~?e|Ns9C1_lO;5C8uk0Cf{T{QnQ?ghzb*|NjO9 z14G5f|Nnn5Ffep{{QsYak%3{x$N&Eo7#SE|eER=ChLM3m;`9IiHK5+`=l}l~FfuSi zeE$D`3#iw|z`!5^wUDtYh=H*}fKi%1t&{|F~6V!NSU|;~P9R=~P2!lul z21y77Ur#0t<%9YrAf^cWcQ(+hA<}wQ36LfR1_oHa5y}Oxe+988K-Y0WwJ}tH1d;l8uzr&` zR6GFcV3>FXlmQiH0QDPxaG6*xk){}$!njkfxWQ$F`JOcv*69X^90W^OoLd8Fz ziG%v|AoZ|(1~MCjL9^$K43Z2Y(Djla_kqO2zvGZ;V(hLs~5LFyTJ876=dDg$T*FGR;NsCox9^_QXQ4WR15 z<1-8l40oa8=<)j;>V5{abn*qP9%2_V$;t!@A7l{-TZD;$L6Av;0hVteq6`d*AaMqM zxF%Tn4%#mw#K6mt0CgvLoQQ#e!IcRVo|x<3--6x4%K+O41RhgkU|{fqs)yw-n7v_4 zpmf5^PzjAMP<{r8ypp0yhP0x@+|>A#(%jri zhWL0SUVLU=W(kVYzjd%5P0d0tIiS%>y^>k*4k9YSAjd%5c%6hm2F~qz3_&YiJ#QVFs z1-pjChd4UaaLpZ=TE`W9@VC;y1%Nm6b29T% z8RAn@5=#;p5PLJg0S5MANwRr-ab<2&eh!$MR+OI`Us{r8fh<^(Y#g7QpH~c4QJ!Cv z0%d`BXT-;Y%!cgZ0DB6>73lj$;!}$A<1-TTQb2o3JpJQ~OHwlP;!BHDQ^1BJSzl6= znU@aP+Yuk1R9p-#YAL8o_i%!s17_9qSP`9X{8URXKV5>k@7ehS2pjTX(TauW>pjTW{1fervtjxTU z)S?0gz4W|Ny^O@-3E2W8=a(?(m84dbFzBUa=4CSI73G8Ci9s(l1DYK&Qi>2f2EDxel2ouu3X1Xz zQj1C|p+b&Mp1PpC3pN{)aUe#**eR8HiMg4{40;grlZuNO^pf*)b5rv`vk35Ff@}t; zeGh8Wz}n5Y_D#Yp0I7wsL9{w_3?HT+*6xSV9w0^FHVcFSs~2JQh%y5M!?*wc^I`g7 z{R9{dS{4Y>2~!W#4-x}mP`v}1BZBFN^&?=k1=PWy?goen(+_LUn?mbkn0{El1V+R9 zAt1Xz7-R;BhGEe58c-V_rXSX>htaV963qQDbub##z6A9dV0>7=0Y<~Bb#(W`?2m+o zElfYG9|NOd{TP`2=>AWJ>UV+~21qlkM1APLT8Zs zVftb1a2O4mLxt%D(dhQiL$iMaw4DK?OF)K$G(s`D{h8KnU{xJQp{?Y_}kZJ~o z0tf{sVftb8D>VJ^egJ546>0nfW&lhdjQ;`ZN0|MvcDM*sKYDnhB?pGDQ2U|EVa77R z^rPTQ3~VruK_y}K bLb>3*#%M~wQhA^Wb_NE9e_$ShK-Uid&%Y+x diff --git a/example/ascii-string-literal.anf b/example/ascii-string-literal.anf deleted file mode 100644 index a25a687..0000000 --- a/example/ascii-string-literal.anf +++ /dev/null @@ -1,4 +0,0 @@ -;;; -*- mode:scheme -*- - -(let ((x0 (prim:write "wawa"))) x0) - diff --git a/example/ascii-string-literal.s b/example/ascii-string-literal.s deleted file mode 100644 index 38d65f3..0000000 --- a/example/ascii-string-literal.s +++ /dev/null @@ -1,23 +0,0 @@ -.data -.balign 8 -.1: - .ascii "wawa" -/* end data */ - -.text -.globl main -main: - pushq %rbp - movq %rsp, %rbp - movl $4, %esi - leaq .1(%rip), %rdi - callq scm_from_utf8_string - movq %rax, %rdi - callq scm_write - leave - ret -.type main, @function -.size main, .-main -/* end function main */ - -.section .note.GNU-stack,"",@progbits diff --git a/example/ascii-string-literal.scm b/example/ascii-string-literal.scm deleted file mode 100644 index 81525d1..0000000 --- a/example/ascii-string-literal.scm +++ /dev/null @@ -1 +0,0 @@ -(prim:write "wawa") diff --git a/example/ascii-string-literal.ssa b/example/ascii-string-literal.ssa deleted file mode 100644 index 2a1f3cd..0000000 --- a/example/ascii-string-literal.ssa +++ /dev/null @@ -1,10 +0,0 @@ - -data $.1 = -{b "wawa"} -export -function w $main () { -@start - %.2 =l call $scm_from_utf8_string (l $.1, l 4) - %x0 =l call $scm_write (l %.2) - ret %x0 -} \ No newline at end of file diff --git a/example/cons b/example/cons deleted file mode 100755 index 26c03d7db4d06af5625cc3872eb4d0323e66a39e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16520 zcmb<-^>JfjWMqH=W(GS35U)W1BH{p{7&t7U3!)Oi&mw_3oPXfeXU|>L}gQ4nRG{{XLArK9+55&fXPe3hz(F{<3fb_9~ zG(h<JAtU69?%7+ou51%)r2aMxTKC4@M*F1BFe5E<|61Eh@bOs_y`lhUo)w zLHaVF`ZA#UV6*{90RsaAjD~s_90wqGW+*}IL8oEy0i)6Nt$^x7r_sC%wg+TG@Y9kM za_kF$>g#|Sj83P33};|qfYBg3Kth2}OHx4L0%8+`VbL4}wGUT3tbm3mj0VLw$b9|0 z%nJSDlKi4n{TzcFqnsSWoZQNs@3;t8r)qnZW@P1F5~3dMGuOux#IU^e^l95=%P+XFdUs}Qt z9}h|`P&0EAGxHeYP@Db_D8O4d)WOwGto&DPB**3U03DJU%g(-5VIEK-nS zXql3iYmsAKnV6ewlALIomXViaYHn6oZc&w3P^_DjQl6fyYoTYPXJ~}3xuU`-F|pD( zy~@(0swlD2GB>-d($vJHpvc(7G}oxiKsPBrH6vFSr+(7&rxjAzWM&kkBxO{Z6s1)p zW>#b-=2j+|T3A%2B^#Gz8CoXh=%yzp>l&Ks8R;45g0preDC;mVF)%YQGB80g3zTMH zU}RusSOHFJkOWpDnaK&NA-6-twoIJH1}X&(L;0mrAbBQ+a}ebWuzCWN*Fi!F(9D$p ztp{M@3Q%zlXnKZ;!}u5MLAn{h^)slffbbX?ZXk(+${3jV10-=!xdRh_fg}zpvtZ&M zki zJ_Eyl)f#;U27Y-5hX1M{eg??&mk<8`|NmdLNS}cr15~BIya48Bf%u>%$IAm?eiDce zYHGaP0OmL8Gccr002u(nAo~s9dUjrn^XPo!(fs5?K!~g10mG9Xy|$+q7#RMGYU?vF zd`Z*emu~?nXYlB?jRd)~mo*4PS^g*y_2_2h1F>5VlyLrkz%SnbQg|3jd-U3Bf+TxQ zl|Yo{Kab829tYpqdmQ}1?7?`<M<}d#vbOEN74VX{Qv*| zp&p%2_k((+FHZjZ|KFqYxW{pJPzTK8xI2d!0|UbgCk6(FlZQh+x>-H+7#Q}08c!bG z1|FSHU#$4||G(jZSi^6I{||d~vm5?Dj1(T-?i?TiSonl`bpG<_d>ZW0{6?brIU9fL zY>;!inN~2Cm^44A_h|kh%HINNjC%B%D)2Ed><7h^;ei(+AV+n_{xCdn((sbuNw8g@ z_};Gp(%%{S;sp~}MeU0hmH)x+e=!k6_nIE!MVP_|QpcD<_y7O@`!zw{JN)uvF#maUdkJ`SM{z*i?a?dh#>>Fq(Q8@_qB?zFyyyaJ z_kGcM3#`VY*VK@gfx+;=i$bsjsuw4Kq9xd)^LOWWkAu&dK{?@tCP-bU1jw>F*erl5;&;g{xdvq7|FUch<#z6o!>x?gruL&KmY%ydGO~Q zPV?l?JD0|vbC6$b=9!JtCbz|btG!j7T1q{vD^wE)yh1qWeqer~ElXw)+%%qY!l4Vv=>&0WrT|Ns9CP@nPr|NjRV7#M!M|NkG< zspt6k|NjjJ1_q6f|NsABU|_KL`2Rl-BLjoS$N&Eo7#SEUKK=h6!N|a{;?w{C6^slF z9H0OHU%<$~Ao2PC|1F>q3I+xS5vYZXRY44l6#|UXJnS437$M>^3=9kf@BjZ-1F3Og z2X)pNR2Uc-Oh9gU_y0d=?vjB|z>QDBi=Vrkqk+L*%38}<1w7pdGB*Y^C;9&Wf8==y zkeMYQH-Gs5A3T5R$S2Uo6vWHs!NU$x2eM=eR30|Z0TKhvA*p=${~t780&)(>4SPW5 zfB64jALJLXIc~gcuFcHlTs-U?zT8Y9AlipJ4nzfUGr56m0NMWqw7%lw|NkJrFo5+r z^RhWMGe_~TbAZG|7$IRA4zdU)@6^le)x+Z3%vuaG2E07MhLM3G;p6}Rpq?*CDabzo zj0_AhAOHV11PQ?P_A$FOvm}8vg2bU~Jq#Ea7(nsw?ib3y)WC26G|vR`3P=ef10$FZ zn@eJX@?r8IwV-eT@j?1QdO+@gCqR(EC>{-g(GVC7fzc2c4S~@R7!85Z5Eu=C0SW=w zx-Hl`El|4^R_1o1SkV4%mC^if|SDg5itAZK!VUUv>@j1{}BIyx``nE zKPW!{YTkb+9~N&PpnNl^{7)z!>V1$ARK>9M-spy!LF3;IN{2z|G$@U(o>)F?-JrX( zvz3B|yI-iL0%Xx60Ruqc!@}_KKe{qd_%kvHGr-o9gZhdfHK62*O}#vLO*1dU1~h*t zLd74TiG%vXObomXu>1uw8-%^Uc}tQ(0J<&`ctq))5Qz0HUS3MI(jgdfq~&SSiLv{EPuho1sSog`&Pvv?!<`L@&GdfM8`2=U-x|* ztX=}NNd%+}jtjx&^D<0;h7T+~)G~tBWlO;03#Oq3tRBWg(0w3rCO&w%2a}lsb`L*8 z0n}hvd9WCyo`IKP0x01zfL7i@bnJktZ$MLj6sn#9sva~x0@86FDvln%H=*ulfTlN) zS`dB)Ru5vK;_u+_K@|h>*q9g?1eqilVEGUv2ExK1aRz>PB*4mPB_>cj@-i4e-3cDM zVPIe|X99&M<~sNLVE6Dc!1nck$G8|67;K>GVfh7QCkT5$&Ci6!mpVw0fq}snEDq%$ zQE6atUWN@&^{}z5JgECC(89S6s(t~~{owH<1_p+9sQ3Y>Ind&kp&w)p6J|P@%>)k` zB-b!7Y-Pf}58wjGd?qeXAfc$g1~Q+4pCJRyoeaUrMJ0xM`3&*#iAkC9C5h<_$wehe zsp*+{!Fu@&h>ZjBCAsm*psfSN4DsV(P<|O81CKiL-oSK&ca&dgTTacr#YrLzU3usG&OQfHpuctFZe7w6~ zXuPWjRMx{Kh#}tH$KT1(C*I%9E!Z_AKE%<<$2A_doxuUN0|B(v0Ao)BT-MkGvTFhn zPAD5JAbTRYwV$drtDT2@$Fji(>Nor96gI;=Gsa{56aR!54N@ZSgWiEs+DT2t9r4|)u=I5bs z;)@vcK=T104Nz7=P6>k^DD5)n737rYrRSG0=#`{alrZR}W#(lv=oRIIBU~>v1De`1 zQi>ShJO;hI{E}3#OA3ne3sQ?pDxpG-PM*4;tO+(7k}n`e!q_R5d5O81$qafB^OK5; z8T69#b8}PkK!furB>{OHPnGRA5V}oc=`3h=d!}P=2;V{|-qzK%W zfG}Y78>~K1W?*3W_WyrAOh2sM4x>TK_&_>g>S6jpVjv9KZU}0#!}P=2^)MPVzXDPR zawEv?F#WLhwJEf2h3SX&6JRu~UjQ-#gh6J2Xcz`_D4d)7N#H8uYl38eg({abpIzq^@CP%g3N^VQ(!c#Ujxz) z>dT<(&jq*F5dA9fgbTRkn>J{S$2y8%H2Y!wS{M!M?}8OW z!y3j0(H&6zu=qpYrwft?se@sdyJ39Lf@F~UVftb1X&4Qfn}n$a(dgkn56%7$&~^lj zE&&-1(g?-q_JjHrptcUoeq8%^q1xf$599BK?kR=ohxNN)G}JjTVm^mOC7WW`=7}kIq z_yd|?LE}E4CO6DIuyU0XDehrU}s=pc#38?$Ucxf41=2MFu%jZKs2ibh-6^+ K2ch63x_$up5kZsy diff --git a/example/cons.anf b/example/cons.anf deleted file mode 100644 index b6008d9..0000000 --- a/example/cons.anf +++ /dev/null @@ -1,4 +0,0 @@ -;;; -*- mode:scheme -*- - -(let ((x0 (prim:cons 4 5)) (x1 (prim:write x0))) x1) - diff --git a/example/cons.s b/example/cons.s deleted file mode 100644 index 155dd85..0000000 --- a/example/cons.s +++ /dev/null @@ -1,18 +0,0 @@ -.text -.globl main -main: - pushq %rbp - movq %rsp, %rbp - movl $16, %edi - callq GC_malloc - movq %rax, %rdi - movq $18, (%rdi) - movq $22, 8(%rdi) - callq scm_write - leave - ret -.type main, @function -.size main, .-main -/* end function main */ - -.section .note.GNU-stack,"",@progbits diff --git a/example/cons.scm b/example/cons.scm deleted file mode 100644 index 172cb5d..0000000 --- a/example/cons.scm +++ /dev/null @@ -1 +0,0 @@ -(prim:write (prim:cons 4 5)) diff --git a/example/cons.ssa b/example/cons.ssa deleted file mode 100644 index f10a040..0000000 --- a/example/cons.ssa +++ /dev/null @@ -1,10 +0,0 @@ -export -function w $main () { -@start - %x0 =l call $GC_malloc (l 16) - %.2 =l add %x0, 8 - storel 18, %x0 - storel 22, %.2 - %x1 =l call $scm_write (l %x0) - ret %x1 -} \ No newline at end of file diff --git a/example/pseudo/closure.scm b/example/pseudo/closure.scm deleted file mode 100644 index 547a0eb..0000000 --- a/example/pseudo/closure.scm +++ /dev/null @@ -1,15 +0,0 @@ -(define (adder x) - (lambda (y) - (+ x y))) - -((adder 3) 4) - - - -(define (adder x) - (list (lambda (self y) - (+ (nth self 1) y)) - x)) - -(let ((closure (adder 3))) - ((nth closure 0) closure 4)) diff --git a/example/pseudo/t.s b/example/pseudo/t.s deleted file mode 100644 index 1eda806..0000000 --- a/example/pseudo/t.s +++ /dev/null @@ -1,70 +0,0 @@ -.text -zerop: - pushq %rbp - movq %rsp, %rbp - cmpl $0, %edi - jnz .Lbb2 - movl $1, %eax - jmp .Lbb3 -.Lbb2: - movl $0, %eax -.Lbb3: - leave - ret -.type zerop, @function -.size zerop, .-zerop -/* end function zerop */ - -.text -factorial: - pushq %rbp - movq %rsp, %rbp - subq $8, %rsp - pushq %rbx - movq %rdi, %rbx - callq zerop - movq %rbx, %rdi - cmpl $0, %eax - jnz .Lbb6 - movq %rdi, %rbx - subq $1, %rdi - callq factorial - movq %rbx, %rdi - imulq %rdi, %rax - jmp .Lbb7 -.Lbb6: - movl $1, %eax -.Lbb7: - popq %rbx - leave - ret -.type factorial, @function -.size factorial, .-factorial -/* end function factorial */ - -.data -.balign 8 -fstr: - .ascii "fac 3 = %d\n" - .byte 0 -/* end data */ - -.text -.globl main -main: - pushq %rbp - movq %rsp, %rbp - movl $3, %edi - callq factorial - movq %rax, %rsi - leaq fstr(%rip), %rdi - movl $0, %eax - callq printf - movl $0, %eax - leave - ret -.type main, @function -.size main, .-main -/* end function main */ - -.section .note.GNU-stack,"",@progbits diff --git a/example/pseudo/t.scm b/example/pseudo/t.scm deleted file mode 100644 index fb8a3c8..0000000 --- a/example/pseudo/t.scm +++ /dev/null @@ -1,16 +0,0 @@ -(define (factorial n) - (if (zero? n) - 1 - (* n (factorial (- n 1))))) - - -;;; ANF - -(define (factorial n) - (let ((r₁ (zero? n))) - (if r₁ - 1 - (let ((r₂ (- n 1)) - (r₃ (factorial r₂)) - (r₄ (* n r₃))) - r₄)))) diff --git a/example/pseudo/t.ssa b/example/pseudo/t.ssa deleted file mode 100644 index aa7270b..0000000 --- a/example/pseudo/t.ssa +++ /dev/null @@ -1,30 +0,0 @@ -function l $zerop (l %n) { -@start - jnz %n, @b1, @b2 -@b1 - ret 0 -@b2 - ret 1 -} - -function l $factorial (l %n) { -@start - %r1 =l call $zerop (l %n) - jnz %r1, @b1, @b2 -@b1 - ret 1 -@b2 - %r2 =l sub %n, 1 - %r3 =l call $factorial (l %r2) - %r4 =l mul %n, %r3 - ret %r4 -} - -data $fstr = { b "fac 3 = %d\n", b 0 } - -export function w $main () { -@start - %r =l call $factorial (l 3) - call $printf (l $fstr, ..., l %r) - ret 0 -} \ No newline at end of file diff --git a/example/string-literal b/example/string-literal deleted file mode 100755 index 7530ee0d527868695fd0183bbbc76f33810550de..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16600 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 diff --git a/example/string-literal.anf b/example/string-literal.anf deleted file mode 100644 index bcdd017..0000000 --- a/example/string-literal.anf +++ /dev/null @@ -1,4 +0,0 @@ -;;; -*- mode:scheme -*- - -(let ((x0 (prim:write "안녕하세요"))) x0) - diff --git a/example/string-literal.s b/example/string-literal.s deleted file mode 100644 index 68a9c79..0000000 --- a/example/string-literal.s +++ /dev/null @@ -1,23 +0,0 @@ -.data -.balign 8 -.1: - .ascii "\354\225\210\353\205\225\355\225\230\354\204\270\354\232\224" -/* end data */ - -.text -.globl main -main: - pushq %rbp - movq %rsp, %rbp - movl $15, %esi - leaq .1(%rip), %rdi - callq scm_from_utf8_string - movq %rax, %rdi - callq scm_write - leave - ret -.type main, @function -.size main, .-main -/* end function main */ - -.section .note.GNU-stack,"",@progbits diff --git a/example/string-literal.scm b/example/string-literal.scm deleted file mode 100644 index 70b4480..0000000 --- a/example/string-literal.scm +++ /dev/null @@ -1 +0,0 @@ -(prim:write "안녕하세요") diff --git a/example/string-literal.ssa b/example/string-literal.ssa deleted file mode 100644 index 6f84a5d..0000000 --- a/example/string-literal.ssa +++ /dev/null @@ -1,10 +0,0 @@ - -data $.1 = -{b "\354\225\210\353\205\225\355\225\230\354\204\270\354\232\224"} -export -function w $main () { -@start - %.2 =l call $scm_from_utf8_string (l $.1, l 15) - %x0 =l call $scm_write (l %.2) - ret %x0 -} \ No newline at end of file diff --git a/flake.nix b/flake.nix index 9902215..18a1fff 100644 --- a/flake.nix +++ b/flake.nix @@ -18,19 +18,13 @@ overlays = [ haskellNix.overlay - (final: prev: { - inherit (sydpkgs.packages.${final.stdenv.hostPlatform.system}) - bdwgc; - }) (final: prev: { gyehoek = final.haskell-nix.project' { src = ./.; compiler-nix-name = "ghc912"; shell = { withHoogle = true; - inputsFrom = [ - self.packages.${final.stdenv.hostPlatform.system}.runtime - ]; + inputsFrom = []; tools = { cabal = {}; haskell-language-server = {}; @@ -39,13 +33,13 @@ gcc qbe haskellPackages.cabal-fmt - bdwgc - pkg-config - guile - clang-tools # clangd - gdb - gdbgui - rust-analyzer + self.packages.${final.stdenv.hostPlatform.system}.shake + final.wabt + final.nodejs + final.wasmtime + final.wasm-tools + final.wac-cli + final.guile ]; }; }; @@ -76,8 +70,7 @@ packages = each-system ({ pkgs, system, ... }: hf.packages.${system} // { default = hf.packages.${system}."gyehoek:exe:gyehoek"; - runtime = pkgs.callPackage ./runtime {}; - inherit (pkgs) bdwgc; + shake = pkgs.callPackage ./shake-wrapper.nix {}; }); devShells = each-system diff --git a/gyehoek.cabal b/gyehoek.cabal index fbc5270..33ab1b5 100644 --- a/gyehoek.cabal +++ b/gyehoek.cabal @@ -20,8 +20,7 @@ common ghcstuffs-dev common ghcstuffs ghc-options: -Wall -fdefer-type-errors -fno-show-valid-hole-fits - -fdefer-out-of-scope-variables -fplugin=Effectful.Plugin - -threaded + -fdefer-out-of-scope-variables -fplugin=Effectful.Plugin -threaded default-extensions: BlockArguments @@ -36,17 +35,17 @@ executable gyehoek -- cabal-fmt: expand app -Main other-modules: - Gyehoek.ANF.Syntax + Gyehoek.CPS.Convert + Gyehoek.CPS.Syntax Gyehoek.GenSym Gyehoek.Options - Gyehoek.QBE - Gyehoek.QBE.Parse Gyehoek.Scheme.Syntax Gyehoek.Sexp build-depends: , base ^>=4.21.2.0 , containers + , cradle , effectful , effectful-core , effectful-plugin @@ -59,15 +58,13 @@ executable gyehoek , optparse-applicative , prettyprinter , process - , qbe , recursion-schemes , sexp-grammar , template-haskell , text + , text-short , unordered-containers , vector - , text-short - , cradle hs-source-dirs: app default-language: GHC2024 diff --git a/play/.gitignore b/play/.gitignore deleted file mode 100644 index f35d769..0000000 --- a/play/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -*.anf -*.s -*.ssa -*.out \ No newline at end of file diff --git a/play/car.scm b/play/car.scm deleted file mode 100644 index 8fd7653..0000000 --- a/play/car.scm +++ /dev/null @@ -1 +0,0 @@ -(prim:write (prim:car (prim:cons 123 456))) diff --git a/play/cdr.scm b/play/cdr.scm deleted file mode 100644 index e3abdb6..0000000 --- a/play/cdr.scm +++ /dev/null @@ -1 +0,0 @@ -(prim:write (prim:cdr (prim:cons 123 456))) diff --git a/play/string.scm b/play/string.scm deleted file mode 100644 index 8ef0d31..0000000 --- a/play/string.scm +++ /dev/null @@ -1 +0,0 @@ -(prim:write "abc") diff --git a/play/symbol.scm b/play/symbol.scm deleted file mode 100644 index 56ae711..0000000 --- a/play/symbol.scm +++ /dev/null @@ -1,3 +0,0 @@ -(begin (prim:write 'abc) - (prim:newline) - (prim:write 'abc)) diff --git a/play/write-cons.scm b/play/write-cons.scm deleted file mode 100644 index 0f24db8..0000000 --- a/play/write-cons.scm +++ /dev/null @@ -1 +0,0 @@ -(prim:write (prim:cons 4 2)) diff --git a/repl b/repl new file mode 100644 index 0000000..c655882 --- /dev/null +++ b/repl @@ -0,0 +1,2 @@ +#!/usr/bin/env sh +cabal repl --repl-options "-interactive-print=Text.Pretty.Simple.pPrint" --build-depends pretty-simple diff --git a/runtime/.gitignore b/runtime/.gitignore deleted file mode 100644 index 1de5659..0000000 --- a/runtime/.gitignore +++ /dev/null @@ -1 +0,0 @@ -target \ No newline at end of file diff --git a/runtime/Cargo.lock b/runtime/Cargo.lock deleted file mode 100644 index 39c75dc..0000000 --- a/runtime/Cargo.lock +++ /dev/null @@ -1,112 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "allocator-api2" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" - -[[package]] -name = "bdwgc-alloc" -version = "0.6.13" -source = "git+https://git.deertopia.net/msyds/bdwgc-rust.git#ccc273a168f3ddfee0a2ae170f561f19da8c274a" -dependencies = [ - "cmake", - "libc", -] - -[[package]] -name = "cc" -version = "1.2.62" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1dce859f0832a7d088c4f1119888ab94ef4b5d6795d1ce05afb7fe159d79f98" -dependencies = [ - "find-msvc-tools", - "shlex", -] - -[[package]] -name = "cmake" -version = "0.1.58" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0f78a02292a74a88ac736019ab962ece0bc380e3f977bf72e376c5d78ff0678" -dependencies = [ - "cc", -] - -[[package]] -name = "const_panic" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e262cdaac42494e3ae34c43969f9cdeb7da178bdb4b66fa6a1ea2edb4c8ae652" -dependencies = [ - "typewit", -] - -[[package]] -name = "equivalent" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" - -[[package]] -name = "find-msvc-tools" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" - -[[package]] -name = "foldhash" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" - -[[package]] -name = "gyehoek" -version = "0.1.0" -dependencies = [ - "bdwgc-alloc", - "const_panic", - "internment", - "libc", -] - -[[package]] -name = "hashbrown" -version = "0.15.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" -dependencies = [ - "allocator-api2", - "equivalent", - "foldhash", -] - -[[package]] -name = "internment" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "636d4b0f6a39fd684effe2a73f5310df16a3fa7954c26d36833e98f44d1977a2" -dependencies = [ - "hashbrown", -] - -[[package]] -name = "libc" -version = "0.2.186" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" - -[[package]] -name = "shlex" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" - -[[package]] -name = "typewit" -version = "1.15.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "214ca0b2191785cbc06209b9ca1861e048e39b5ba33574b3cedd58363d5bb5f6" diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml deleted file mode 100644 index bc73bad..0000000 --- a/runtime/Cargo.toml +++ /dev/null @@ -1,20 +0,0 @@ -[package] -name = "gyehoek" -version = "0.1.0" -edition = "2024" - -[lib] -name = "gyehoek" -# crate-type = ["cdylib"] -crate-type = ["staticlib"] - -[dependencies] -bdwgc-alloc = { version = "0.6.13" - , default-features = false - , features = ["cmake"] } -const_panic = "0.2.15" -internment = "0.8.6" -libc = "0.2.186" - -[patch.crates-io] -bdwgc-alloc = { git = 'https://git.deertopia.net/msyds/bdwgc-rust.git' } diff --git a/runtime/default.nix b/runtime/default.nix deleted file mode 100644 index d89519b..0000000 --- a/runtime/default.nix +++ /dev/null @@ -1,24 +0,0 @@ -{ lib -, rustPlatform -, bdwgc -, cmake -, pkg-config -}: - -rustPlatform.buildRustPackage (finalAttrs: { - pname = "gyehoek-runtime"; - version = "0.0.1"; - src = ./.; - cargoLock = { - lockFile = ./Cargo.lock; - outputHashes."bdwgc-alloc-0.6.13" = - "sha256-8/EZ9FThVVsdkwB+OIlNHQJxIr6DPf701Mlfq5U1j4E="; - }; - nativeBuildInputs = [ - pkg-config - cmake - ]; - buildInputs = [ - bdwgc - ]; -}) diff --git a/runtime/src/capi.rs b/runtime/src/capi.rs deleted file mode 100644 index 1f30f79..0000000 --- a/runtime/src/capi.rs +++ /dev/null @@ -1,24 +0,0 @@ -use std::slice; - -use crate::scm::scm_bits; -use crate::scm; - -#[unsafe(no_mangle)] -pub extern "C" fn scm_from_utf8_string ( - ptr : *const u8, - len : usize -) -> scm_bits { - let bytes = unsafe { slice::from_raw_parts (ptr, len) }; - scm::make_string (str::from_utf8 (bytes).unwrap ()) -} - -// #[unsafe(no_mangle)] -// pub extern "C" fn scm_hash (ptr : *const u8, len : usize) -> u64 { -// let bytes = unsafe { slice::from_raw_parts (ptr, len) }; -// crate::obarray::hash (str::from_utf8 (bytes).unwrap ()) -// } - -#[unsafe(no_mangle)] -pub extern "C" fn scm_string_to_symbol (str : scm_bits) -> scm_bits { - crate::scm::string_to_symbol (str) -} diff --git a/runtime/src/gc.rs b/runtime/src/gc.rs deleted file mode 100644 index d6c90a4..0000000 --- a/runtime/src/gc.rs +++ /dev/null @@ -1,34 +0,0 @@ -use libc::{c_void, size_t}; - -#[link(name = "gc", kind = "static")] -unsafe extern "C" { - // fn GC_allow_register_threads (); - // fn GC_alloc_lock (); - // fn GC_alloc_unlock (); - // fn GC_free (ptr: *mut c_void); - // fn GC_get_stack_base (stack_base: *mut GcStackBase) -> c_int; - // fn GC_init (); - fn GC_malloc (size: size_t) -> *mut c_void; - fn GC_realloc (ptr: *mut c_void, size: size_t) -> *mut c_void; - // fn GC_register_my_thread - // (stack_base: *const GcStackBase) -> c_int; - // fn GC_set_stackbottom - // (thread: *const c_void, stack_bottom: *const GcStackBase); - // fn GC_unregister_my_thread (); - // fn GC_gcollect (); - // fn GC_register_finalizer ( - // ptr: *const c_void, - // finalizer: extern "C" fn (*mut c_void, *mut c_void), - // client_data: *const c_void, - // opt_old_finalizer: *const c_void, - // opt_old_client_data: *const c_void, - // ) -> *mut c_void; -} - -pub unsafe fn malloc (size: usize) -> *mut T { - unsafe { GC_malloc (size) as *mut T } -} - -pub unsafe fn realloc (ptr: *mut T, size: usize) -> *mut T { - unsafe { GC_realloc (ptr as *mut c_void, size) as *mut T } -} diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs deleted file mode 100644 index 07f245f..0000000 --- a/runtime/src/lib.rs +++ /dev/null @@ -1,9 +0,0 @@ -#![allow(non_upper_case_globals)] -#![allow(non_camel_case_types)] - -mod gc; -mod scm; -mod primitives; -// mod obarray; -mod capi; -mod var; diff --git a/runtime/src/primitives.rs b/runtime/src/primitives.rs deleted file mode 100644 index 36f2d9e..0000000 --- a/runtime/src/primitives.rs +++ /dev/null @@ -1,31 +0,0 @@ -use crate::scm; -use crate::scm::{scm_bits, SCM}; -use std::io::{stdout, Write}; - -#[unsafe(no_mangle)] -pub extern "C" fn scm_write (x: scm_bits) -> scm_bits { - match scm::unpack (x) { - SCM::SmallInt (n) => print! ("{n}"), - SCM::Cons (car, cdr) => { - print! ("("); - scm_write (car); - print! (" . "); - scm_write (cdr); - print! (")"); - }, - SCM::String (s) => print! ("\"{s}\""), - SCM::Nil => print! ("()"), - SCM::False => print! ("#f"), - SCM::True => print! ("#t"), - SCM::Symbol (_s) => print! ("{x:#016x}"), - // SCM::Symbol (s) => print! ("{s}"), - }; - let _ = stdout ().flush (); - return 0; -} - -#[unsafe(no_mangle)] -pub extern "C" fn scm_newline () -> scm_bits { - print! ("\n"); - 0 -} diff --git a/runtime/src/scm.rs b/runtime/src/scm.rs deleted file mode 100644 index 1528046..0000000 --- a/runtime/src/scm.rs +++ /dev/null @@ -1,203 +0,0 @@ -#![allow(non_upper_case_globals)] -#![allow(non_camel_case_types)] - -use std::slice; - -use internment::Intern; - -use crate::gc; - -pub type scm_bits = u64; - -pub const tc2_int : u64 = 2; -pub const tc3_cons : u64 = 0; -pub const tc7_obarray : u64 = 0x55; -pub const tc7_symbol : u64 = 0x05; -pub const tc7_string : u64 = 0x15; - -// pub const scm_false : SCM = pack (0b00100); -// pub const scm_true : SCM = pack (0b01100); -// pub const scm_eol : SCM = pack (0b10100); - -pub enum SCM { - SmallInt (i64), - Cons (scm_bits, scm_bits), - String (String), - Symbol (String), - Nil, - False, - True, -} - -// #[inline(always)] -// pub fn pack (x : SCM) -> scm_bits { -// } - -#[inline(always)] -pub fn unpack_string (x : scm_bits) -> String { - let len = unsafe { cell_word (x, 1) }; - let str_beginning = (x as *const scm_bits).wrapping_add (2) as *const u8; - let slice = unsafe { - str::from_utf8 ( - slice::from_raw_parts ( - str_beginning, - len.try_into ().unwrap () - ) - ).unwrap () - }; - String::from (slice) -} - -// super duper important for this to inline. we want to eliminate the -// SCM type at runtime as much as possible. the hope is for inlining -// to lead to a case-of-case–esque transformation. -#[inline(always)] -pub fn unpack (x : scm_bits) -> SCM { - if is_small_int (x) { - SCM::SmallInt ((x >> 2) as i64) - } else if is_cons (x) { - // `car` x and `cdr` x are safe iff `is_cons` x. - unsafe { SCM::Cons (car (x), cdr (x)) } - } else if is_string (x) { - SCM::String (unpack_string (x)) - } else if is_symbol (x) { - let s = unpack_string (unsafe { cell_word (x, 1) }); - SCM::Symbol (s) - } else { - // concat_panic! ("don't know how to unpack: ", x) - panic! ("don't know how to unpack {x:#016x}") - } -} - -const fn is_small_int (x: scm_bits) -> bool { - 3 & x == tc2_int -} - -const fn is_immediate (x: scm_bits) -> bool { - 6 & x != 0 -} - -fn is_string (x: scm_bits) -> bool { - has_tc7 (x, tc7_string) -} - -fn is_cons (x: scm_bits) -> bool { - // safety of `cell_type` is mutually exclusive with - // `is_immediate`, so this is okay. - unsafe { - ! is_immediate (x) && (1 & cell_type (x)) == 0 - } -} - -fn is_symbol (x : scm_bits) -> bool { - has_tc7 (x, tc7_symbol) -} - -fn has_tc7 (x: scm_bits, tc7: u64) -> bool { - unsafe { - ! is_immediate (x) && (0x7f & cell_type (x)) == tc7 - } -} - -unsafe fn cell_type (x: scm_bits) -> scm_bits { - unsafe { cell_word (x, 0) } -} - -unsafe fn cell_word (x: scm_bits, n: usize) -> scm_bits { - let p = x as *mut scm_bits; - unsafe { - *(p.wrapping_add (n)) - } -} - -unsafe fn car (x: scm_bits) -> scm_bits { - unsafe { cell_word (x, 0) } -} - -unsafe fn cdr (x: scm_bits) -> scm_bits { - unsafe { cell_word (x, 1) } -} - -pub unsafe fn words (tag : scm_bits, n : usize) -> *mut scm_bits { - let r = unsafe { gc::malloc (n * size_of:: ()) }; - unsafe { *r = tag }; - return r -} - -pub fn pack_ptr (obj : *const scm_bits) -> scm_bits { - obj as scm_bits -} - -pub unsafe fn set_word (obj : *mut scm_bits, ix : usize, val : scm_bits) { - let x = obj.wrapping_add (ix); - unsafe { *x = val; } -} - - - -pub fn make_string_from_raw_parts ( - ptr : *const u8, - len : usize -) -> scm_bits { - let bytes = unsafe { slice::from_raw_parts (ptr, len) }; - make_string (str::from_utf8 (bytes).unwrap ()) -} - -pub fn make_string (s : &str) -> scm_bits { - let len = s.len (); - let size_of_tag_and_len = 2 * size_of:: (); - let size_of_contents = len; - let r = unsafe { gc::malloc (size_of_tag_and_len + size_of_contents) }; - unsafe { - set_word (r, 0, tc7_string); - set_word (r, 1, len as u64); - } - let str_beginning = r.wrapping_add (2) as *mut u8; - for (i, b) in s.as_bytes ().iter ().enumerate () { - unsafe { *(str_beginning.wrapping_add (i)) = *b }; - } - return pack_ptr (r) -} - - - -// pub fn make_symbol (name : &str) -> scm_bits { -// let r = unsafe { words (tc7_symbol, 2) }; -// let sym = obarray::symbols.intern (name).to_usize (); -// unsafe { set_word (r, 1, sym.try_into ().unwrap ()) }; -// pack_ptr (r) -// } - -struct Symbol ([scm_bits; 2]); - -impl PartialEq for Symbol { - fn eq (&self, other: &Self) -> bool { - if let (SCM::String (s1), SCM::String (s2)) - = (unpack (self.0[1]), unpack (other.0[1])) { - s1 == s2 - } else { - panic! ("not a symbol") - } - } -} - -impl Eq for Symbol {} - -impl std::hash::Hash for Symbol { - fn hash (&self, state: &mut H) { - if let SCM::String (s) = unpack (self.0[1]) { - s.hash (state) - } else { - panic! ("not a symbol") - } - } -} - -fn make_symbol_off_heap (name : scm_bits) -> Symbol { - Symbol ([ tc7_symbol, name ]) -} - -pub fn string_to_symbol (str : scm_bits) -> scm_bits { - let r = Intern::new (make_symbol_off_heap (str)); - pack_ptr (r.0.as_ptr ()) -} diff --git a/runtime/src/var.rs b/runtime/src/var.rs deleted file mode 100644 index be2ba9c..0000000 --- a/runtime/src/var.rs +++ /dev/null @@ -1,26 +0,0 @@ -use std::{collections::HashMap, ops::DerefMut as _, sync::{LazyLock, RwLock}}; -use crate::scm::scm_bits; - -struct Vars ( - LazyLock >> -); - -impl Vars { - pub const fn new () -> Vars { - Vars (LazyLock::new (|| RwLock::new (HashMap::new ()))) - } - - pub fn lookup (&self, name : String) -> Option { - // let r = self.0.write ().unwrap (); - // (*r).get (&name).map (|x| *x) - todo! () - } - - pub fn define (&self, name : String, value : scm_bits) { - // let mut r = self.0.write ().unwrap (); - // r.deref_mut ().insert (name, value); - todo! () - } -} - -static vars : Vars = Vars::new (); diff --git a/shake-wrapper.nix b/shake-wrapper.nix new file mode 100644 index 0000000..9b39443 --- /dev/null +++ b/shake-wrapper.nix @@ -0,0 +1,14 @@ +{ runCommandLocal, makeWrapper, lib, haskellPackages }: + +let + our-ghc = haskellPackages.ghc.withPackages (ps: [ + ps.shake + ]); +in runCommandLocal + "shake-wrapper" + { nativeBuildInputs = [ makeWrapper ]; } + '' + mkdir -p $out/bin + makeWrapper ${lib.getExe haskellPackages.shake} $out/bin/shake \ + --prefix PATH : ${lib.makeBinPath [our-ghc]} + ''