idk ^w^
build / build (push) Failing after 14m11s

This commit is contained in:
2026-07-20 01:56:53 -06:00
parent 57defed077
commit 2f471ae4b1
10 changed files with 260 additions and 106 deletions
+30 -27
View File
@@ -25,23 +25,22 @@ common ghcstuffs
default-extensions: default-extensions:
BlockArguments BlockArguments
DeriveGeneric DeriveGeneric
OverloadedRecordDot DerivingVia
DuplicateRecordFields DuplicateRecordFields
NoFieldSelectors NoFieldSelectors
OrPatterns
OverloadedLabels
OverloadedRecordDot
OverloadedStrings OverloadedStrings
PartialTypeSignatures PartialTypeSignatures
PatternSynonyms PatternSynonyms
QuasiQuotes QuasiQuotes
DerivingVia
OverloadedLabels
OrPatterns
executable gyehoek executable gyehoek
import: ghcstuffs, ghcstuffs-dev import: ghcstuffs, ghcstuffs-dev
main-is: Main.hs main-is: Main.hs
build-depends: build-depends:
, base ^>=4.21.2.0 , base ^>=4.21.2.0
, gyehoek , gyehoek
hs-source-dirs: app hs-source-dirs: app
@@ -49,19 +48,19 @@ executable gyehoek
library library
import: ghcstuffs, ghcstuffs-dev import: ghcstuffs, ghcstuffs-dev
ghc-options: -fplugin=Effectful.Plugin ghc-options: -fplugin=Effectful.Plugin
-- cabal-fmt: expand src -- cabal-fmt: expand src
exposed-modules: exposed-modules:
Gyehoek.CPS.Convert Gyehoek.CPS.Convert
Gyehoek.CPS.Lower Gyehoek.CPS.Lower
Gyehoek.CPS.Syntax Gyehoek.CPS.Syntax
Gyehoek.Driver
Gyehoek.GenSym Gyehoek.GenSym
Gyehoek.Options Gyehoek.Options
Gyehoek.Scheme.Syntax Gyehoek.Scheme.Syntax
Gyehoek.Sexp Gyehoek.Sexp
Gyehoek.Wasm Gyehoek.Wasm
Gyehoek.Driver
build-depends: build-depends:
, base ^>=4.21.2.0 , base ^>=4.21.2.0
@@ -79,36 +78,40 @@ library
, megaparsec , megaparsec
, mtl , mtl
, optparse-applicative , optparse-applicative
, pretty-simple
, prettyprinter , prettyprinter
, process , process
, recursion-schemes , recursion-schemes
, sexp-grammar , sexp-grammar
, string-interpolate
, template-haskell , template-haskell
, text , text
, text-short , text-short
, unordered-containers , unordered-containers
, vector , vector
, string-interpolate
, pretty-simple
hs-source-dirs: src hs-source-dirs: src
default-language: GHC2024 default-language: GHC2024
test-suite test test-suite test
import: ghcstuffs, ghcstuffs-dev import: ghcstuffs, ghcstuffs-dev
type: exitcode-stdio-1.0 type: exitcode-stdio-1.0
hs-source-dirs: test hs-source-dirs: test
main-is: Main.hs main-is: Main.hs
other-modules: other-modules:
Gyehoek.Test.Golden Gyehoek.Test.CPS.Syntax
Gyehoek.Test.Sexp Gyehoek.Test.Golden
build-depends: base Gyehoek.Test.Sexp
, gyehoek
, filepath build-depends:
, tasty , base
, tasty-silver , directory
, tasty-hunit , filepath
, directory , gyehoek
, process-extras , process-extras
, sexp-grammar , sexp-grammar
default-language: GHC2024 , tasty
, tasty-hunit
, tasty-silver
default-language: GHC2024
+21 -8
View File
@@ -1,7 +1,7 @@
{-# LANGUAGE OverloadedLists #-} {-# LANGUAGE OverloadedLists #-}
{- HLINT ignore "Use camelCase" -}
module Gyehoek.CPS.Convert module Gyehoek.CPS.Convert
( convert ( convertProgram
, convertProgram
) where ) where
import Gyehoek.CPS.Syntax import Gyehoek.CPS.Syntax
@@ -12,6 +12,7 @@ import Effectful
import Control.Monad.Cont qualified as Cont import Control.Monad.Cont qualified as Cont
import Control.Lens import Control.Lens
import qualified Data.List.NonEmpty as NE import qualified Data.List.NonEmpty as NE
import qualified Gyehoek.Sexp
-- 뻘짓이어라 -- 뻘짓이어라
@@ -21,6 +22,14 @@ telescope
-> t a -> (t b -> r) -> r -> t a -> (t b -> r) -> r
telescope f = Cont.runCont . traverse (Cont.cont . f) telescope f = Cont.runCont . traverse (Cont.cont . f)
pattern Atomic e <-
e@( Scm.ExpLambda _ _
; Scm.ExpVar _
; Scm.ExpLit _ )
-- | Transform an expression with a meta-continuation.
convert convert
:: forall es. (GenSym :> es) :: forall es. (GenSym :> es)
=> Scm.Exp -> (Val -> Eff es Exp) -> Eff es Exp => Scm.Exp -> (Val -> Eff es Exp) -> Eff es Exp
@@ -31,21 +40,25 @@ convert (Scm.ExpLit l) k = k $ ValLit l
convert (Scm.ExpPrim p) k = convert (Scm.ExpPrim p) k =
telescope (convert @es) p \p' -> do telescope (convert @es) p \p' -> do
r <- gensym' "r" r <- gensym' "r"
ExpPrim p' [r] <$> k (ValVar r) ExpPrim p' . MkKappa [r] <$> k (ValVar r)
convert (Scm.ExpLambda xs e) k = do convert (Scm.ExpLambda xs e) k = do
f <- gensym' "λ-body" f <- gensym' "λ-body"
ktail <- gensym' "λ-tail" ktail <- gensym' "λ-tail"
m <- convert e $ \e' -> m <- convert e $ \e' -> pure $ ExpContinue ktail [e']
pure $ ExpContinue ktail [e'] ke <- k $ ValVar f
ExpLet [(f, MkLambda xs ktail m)] <$> k (ValVar f) pure [cps|
(letrec ((#{f} (λ (##{xs} #{ktail}) #{m})))
#{ke})
|]
convert (Scm.ExpApply f xs) k = convert (Scm.ExpApply f xs) k =
telescope (convert @es) (f:|xs) \(f':|xs') -> do telescope (convert @es) (f:|xs) \(f':|xs') -> do
r <- gensym' "r" -- r <- gensym' "r"
x <- gensym' "x" x <- gensym' "x"
m <- k (ValVar x) m <- k (ValVar x)
pure $ ExpFix [(r, MkKappa [x] m)] $ ExpApply f' (xs' ++ [ValVar r]) -- pure $ ExpFix [(r, MkKappa [x] m)] $ ExpApply f' (xs' ++ [ValVar r])
_
convert (Scm.ExpBegin xs) k = _ convert (Scm.ExpBegin xs) k = _
+46 -33
View File
@@ -23,6 +23,8 @@ import Gyehoek.Wasm qualified as Wasm
import Gyehoek.Wasm hiding (Expr) import Gyehoek.Wasm hiding (Expr)
import Language.Sexp.Located qualified as SL import Language.Sexp.Located qualified as SL
import Control.Monad.Fix import Control.Monad.Fix
import qualified Gyehoek.Sexp
import Data.Text qualified as T
data Env = MkEnv data Env = MkEnv
@@ -70,10 +72,10 @@ popArg n = [expr|
lowerVal :: Env -> Val -> Wasm.Expr lowerVal :: GenMod :> es => Env -> Val -> Eff es Wasm.Expr
lowerVal g (ValLit l) = lowerVal g (ValLit l) =
case l of pure $ case l of
LitInt n -> [expr| LitInt n -> [expr|
(i32.const #{n}) (i32.const #{n})
##{makeSmallFixnum} ##{makeSmallFixnum}
@@ -85,27 +87,36 @@ lowerVal g (ValLit l) =
where b' :: Int = if b then 0b11 else 0b01 where b' :: Int = if b then 0b11 else 0b01
_ -> _ _ -> _
lowerVal g (ValVar x) = [expr|(local.get #{l})|] lowerVal g (ValVar x) = pure $ [expr|(local.get #{l})|]
where where
l = succ $ V.elemIndex x g.vars ^?! _Just l = succ $ V.elemIndex x g.vars ^?! _Just
-- lowerVal g (ValLambda lam) = do
-- idx <- lowerLambda g lam
-- pure [expr|
-- (i32.const 0)
-- (ref.func #{idx})
-- (struct.new $closure)
-- |]
lower' :: (GenMod :> es) => Env -> Exp -> Eff es Wasm.Expr lower' :: (GenMod :> es) => Env -> Exp -> Eff es Wasm.Expr
lower' g (Halt [v]) = pure [expr| lower' g (Halt [v]) = do
##{arg} arg <- pushArg 0 <$> lowerVal g v
(return_call $halt (i32.const 1)) pure [expr|
|] ##{arg}
where arg = pushArg 0 (lowerVal g v) (return_call $halt (i32.const 1))
|]
lower' g (ExpPrim p [r] e) = lower' g (ExpPrim p k) =
case p of case p of
PrimAdd x y -> lowerBinOp "i32.add" g x y r e PrimAdd x y -> lowerBinOp "i32.add" g x y k
PrimMul x y -> lowerBinOp "i32.mul" g x y r e PrimMul x y -> lowerBinOp "i32.mul" g x y k
lower' g (ExpIf c t f) = do lower' g (ExpIf c t f) = do
c' <- lowerVal g c
t' <- lower' g t t' <- lower' g t
f' <- lower' g f f' <- lower' g f
let c' = lowerVal g c
pure [expr| pure [expr|
##{c'} ##{c'}
(call $gh-truthy?) (call $gh-truthy?)
@@ -113,7 +124,7 @@ lower' g (ExpIf c t f) = do
(else ##{f'})) (else ##{f'}))
|] |]
lower' g (ExpLet [(r,lam)] e) = do lower' g (ExpLetRec [(r,AbsLambda lam)] e) = do
idx <- lowerLambda g lam idx <- lowerLambda g lam
let g' = g & #vars <>~ [r] let g' = g & #vars <>~ [r]
let n = succ $ length g.vars let n = succ $ length g.vars
@@ -126,25 +137,27 @@ lower' g (ExpLet [(r,lam)] e) = do
##{e'} ##{e'}
|] |]
lower' g (ExpContinue k [x]) = pure . mconcat $ lower' g (ExpContinue k [x]) = do
[ pushArg 0 (lowerVal g x) arg <- pushArg 0 <$> lowerVal g x
, [expr| pure [expr|
(i32.const 1) ##{arg}
(global.get $cont-stack) (i32.const 1)
(global.get $cont-stack-top) (global.get $cont-stack)
(array.get $cont-stack-type) (global.get $cont-stack-top)
ref.as_non_null (array.get $cont-stack-type)
(global.get $cont-stack-top) ref.as_non_null
(i32.const #{l}) (global.get $cont-stack-top)
i32.sub (i32.const #{l})
(global.set $cont-stack-top) i32.sub
(return_call_ref $cont-type) (global.set $cont-stack-top)
|] (return_call_ref $cont-type)
] |]
where where
l = succ $ V.elemIndex k g.kvars ^?! _Just l = succ $ V.elemIndex k g.kvars ^?! _Just
lower' g e = error . show $ e lower' g e = error $ case Gyehoek.Sexp.encode e of
Left _ -> show e
Right x -> T.unpack x
lowerLambda :: GenMod :> es => Env -> Lambda -> Eff es Idx lowerLambda :: GenMod :> es => Env -> Lambda -> Eff es Idx
lowerLambda g (MkLambda xs ktail m) = do lowerLambda g (MkLambda xs ktail m) = do
@@ -167,13 +180,13 @@ lowerLambda g (MkLambda xs ktail m) = do
lowerBinOp lowerBinOp
:: (GenMod :> es) :: (GenMod :> es)
=> Text -> Env -> Val -> Val -> Name -> Exp -> Eff es Wasm.Expr => Text -> Env -> Val -> Val -> Kappa -> Eff es Wasm.Expr
lowerBinOp op g x y r e = do lowerBinOp op g x y (MkKappa [r] e) = do
let op' = SL.Symbol op let op' = SL.Symbol op
let g' = g & #vars <>~ [r] let g' = g & #vars <>~ [r]
let n = succ $ length (g ^. #vars) let n = succ $ length (g ^. #vars)
let x' = lowerVal g x x' <- lowerVal g x
let y' = lowerVal g y y' <- lowerVal g y
e' <- lower' g' e e' <- lower' g' e
pure [expr| pure [expr|
##{x'} ##{x'}
+90 -30
View File
@@ -1,6 +1,7 @@
{-# LANGUAGE OverloadedLabels #-} {-# LANGUAGE OverloadedLabels #-}
{-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE PatternSynonyms #-} {-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE ViewPatterns #-}
module Gyehoek.CPS.Syntax module Gyehoek.CPS.Syntax
( Val(..) ( Val(..)
, Kappa(..) , Kappa(..)
@@ -15,8 +16,12 @@ module Gyehoek.CPS.Syntax
, pattern Halt1 , pattern Halt1
, _MkKappa , _MkKappa
, _ExpPrim , _ExpPrim
, _ExpFix , _ExpLetRec
, _ExpApply , _ExpApply
, cps
, pattern AbsLambda'
, pattern AbsKappa'
, Abs(..)
) )
where where
@@ -27,46 +32,62 @@ import Data.List (List)
import GHC.Generics (Generic) import GHC.Generics (Generic)
import Language.SexpGrammar.Generic import Language.SexpGrammar.Generic
import Control.Category import Control.Category
import Control.Lens import Control.Lens hiding (op)
import Prelude hiding ((.), id) import Prelude hiding ((.), id)
import Data.List.NonEmpty (NonEmpty) import Data.List.NonEmpty (NonEmpty)
import Language.Haskell.TH.Quote (QuasiQuoter)
import Data.Data (Data)
import Language.Sexp.Located (Sexp)
import qualified Data.InvertibleGrammar.Base as IG
import qualified Gyehoek.Scheme.Syntax as Gyehoek
import Data.InvertibleGrammar.Base (type (:-)((:-)))
-- Data types -- Data types
data Val data Val
= ValLabel Name = ValVar Name
| ValVar Name
| ValLit Lit | ValLit Lit
deriving (Show, Generic) deriving (Show, Generic, Data, Eq)
data Kappa = MkKappa (List Name) Exp data Kappa = MkKappa (List Name) Exp
deriving (Show, Generic) deriving (Show, Generic, Data, Eq)
data Lambda = MkLambda (List Name) Name Exp data Lambda = MkLambda (List Name) Name Exp
deriving (Show, Generic) deriving (Show, Generic, Data, Eq)
data Abs
= AbsKappa Kappa
| AbsLambda Lambda
deriving (Show, Generic, Data, Eq)
pattern AbsKappa' xs e = AbsKappa (MkKappa xs e)
pattern AbsLambda' xs e ktail = AbsLambda (MkLambda xs e ktail)
data Exp data Exp
= ExpPrim (Prim Val) (List Name) Exp = ExpPrim (Prim Val) Kappa
| ExpFix (NonEmpty (Name, Kappa)) Exp | ExpLetRec (NonEmpty (Name, Abs)) Exp
| ExpLet (NonEmpty (Name, Lambda)) Exp
| ExpContinue Name (List Val) | ExpContinue Name (List Val)
| ExpIf Val Exp Exp | ExpIf Val Exp Exp
| ExpApply Val (List Val) | ExpApply
deriving (Show, Generic) { op :: Val
, args :: List Val
, cont :: Name
}
deriving (Show, Generic, Data, Eq)
pattern Halt :: List Val -> Exp pattern Halt :: List Val -> Exp
pattern Halt xs = ExpApply (ValVar "halt") xs pattern Halt xs = ExpContinue "halt" xs
pattern Halt1 :: Val -> Exp pattern Halt1 :: Val -> Exp
pattern Halt1 x = ExpApply (ValVar "halt") [x] pattern Halt1 x = ExpContinue "halt" [x]
data Def = DefConstant Name Exp data Def = DefConstant Name Exp
deriving (Show, Generic) deriving (Show, Generic, Data)
data Program = MkProgram data Program = MkProgram
{ body :: Exp { body :: Exp
} }
deriving (Show, Generic) deriving (Show, Generic, Data)
makePrisms ''Kappa makePrisms ''Kappa
makePrisms ''Exp makePrisms ''Exp
@@ -76,13 +97,10 @@ makePrisms ''Exp
instance S.SexpIso Val where instance S.SexpIso Val where
sexpIso = match sexpIso = match
$ With (. label) -- $ With (. label)
$ With (. var) $ With (\var -> var . S.sexpIso)
$ With (. S.sexpIso) $ With (\lit -> lit . S.sexpIso)
$ End $ End
where
label = S.keyword >>> S.iso MkName getName
var = S.sexpIso
instance S.SexpIso Lambda where instance S.SexpIso Lambda where
sexpIso = match sexpIso = match
@@ -91,9 +109,18 @@ instance S.SexpIso Lambda where
where where
lambda = S.list $ lambda = S.list $
S.el Gyehoek.Sexp.lambdaKeyword S.el Gyehoek.Sexp.lambdaKeyword
>>> S.el (S.list (S.rest S.sexpIso)) >>> S.el binders
>>> S.el S.sexpIso
>>> S.el S.sexpIso >>> S.el S.sexpIso
binders :: forall t.
IG.Grammar S.Position (Sexp :- t) (Name :- List Name :- t)
binders = S.list $
S.rest (S.sexpIso @Name)
>>> S.onTail (S.flipped $ IG.PartialIso
(\(ktail:-args:-t) -> (args ++ [ktail]) :- t)
(\(args:-t) -> case args ^? _Snoc of
Just (args',ktail) -> Right $ ktail :- args' :- t
Nothing -> Left $ S.expected "cont param")
)
instance S.SexpIso Kappa where instance S.SexpIso Kappa where
sexpIso = match sexpIso = match
@@ -105,11 +132,16 @@ instance S.SexpIso Kappa where
>>> S.el (S.list $ S.rest S.sexpIso) >>> S.el (S.list $ S.rest S.sexpIso)
>>> S.el S.sexpIso >>> S.el S.sexpIso
instance S.SexpIso Abs where
sexpIso = match
$ With (\lambda -> lambda . S.sexpIso)
$ With (\kappa -> kappa . S.sexpIso)
$ End
instance S.SexpIso Exp where instance S.SexpIso Exp where
sexpIso = match sexpIso = match
$ With (. prim) $ With (. prim)
$ With (. fix) $ With (. letrec)
$ With (. let_)
$ With (. continue) $ With (. continue)
$ With (. if_) $ With (. if_)
$ With (. app) $ With (. app)
@@ -119,16 +151,44 @@ instance S.SexpIso Exp where
S.el (S.sym "continue") S.el (S.sym "continue")
>>> S.el S.sexpIso >>> S.el S.sexpIso
>>> S.rest S.sexpIso >>> S.rest S.sexpIso
fix = Gyehoek.Sexp.let_ "fix" S.sexpIso S.sexpIso S.sexpIso letrec = Gyehoek.Sexp.let_ "letrec" S.sexpIso S.sexpIso S.sexpIso
let_ = Gyehoek.Sexp.let_ "let" S.sexpIso S.sexpIso S.sexpIso
if_ = S.list $ S.el (S.sym "if") if_ = S.list $ S.el (S.sym "if")
>>> S.el S.sexpIso >>> S.el S.sexpIso >>> S.el S.sexpIso >>> S.el S.sexpIso >>> S.el S.sexpIso >>> S.el S.sexpIso
app = S.list $ S.el S.sexpIso >>> S.rest S.sexpIso app :: forall t.
IG.Grammar S.Position (Sexp :- t) (Name :- ([Val] :- (Val :- t)))
app = S.list $ S.el (S.sexpIso @Val)
-- >>> S.flipped Gyehoek.Sexp.nonEmptyGrammar
>>> S.rest (S.sexpIso @Val)
-- >>> _
>>> S.onTail (S.flipped $ IG.PartialIso
(\(karg :- args :- op :- t) ->
(args ++ [ValVar karg]) :- op :- t)
(\(xs :- op :- t) -> case xs ^? _Snoc of
Just (args,preview #ValVar -> Just karg) ->
Right $ karg:- args :- op :- t
_ -> Left $ S.expected "continuation arg"
))
where
_ = S.flipped $ Gyehoek.Sexp.nonEmptyGrammar @S.Position @Val
prim = S.list $ prim = S.list $
S.el (S.sym "prim") S.el (S.sym "prim")
>>> S.el (primSexpIso id (S.sexpIso @Val)) >>> S.el (primSexpIso id (S.sexpIso @Val))
>>> S.el S.sexpIso >>> S.el S.sexpIso
>>> S.el S.sexpIso
instance S.SexpIso Program where instance S.SexpIso Program where
sexpIso = with \prog -> S.sexpIso @Exp >>> prog sexpIso = with \prog -> S.sexpIso @Exp >>> prog
-- quasiquoters
class Data a => CPS a where
toCPS :: Sexp -> a
instance CPS Exp where toCPS = Gyehoek.Sexp.fromSexp
instance CPS Val where toCPS = Gyehoek.Sexp.fromSexp
instance CPS Kappa where toCPS = Gyehoek.Sexp.fromSexp
instance CPS Lambda where toCPS = Gyehoek.Sexp.fromSexp
instance CPS Abs where toCPS = Gyehoek.Sexp.fromSexp
cps :: QuasiQuoter
cps = Gyehoek.Sexp.makeSx' [| toCPS |]
+8 -3
View File
@@ -22,6 +22,7 @@ module Gyehoek.Scheme.Syntax
, free , free
, subst , subst
, getName , getName
, scm
) )
where where
@@ -47,6 +48,7 @@ import Data.Functor.Foldable hiding (fold)
import Data.HashSet (HashSet) import Data.HashSet (HashSet)
import qualified Data.HashSet as HS import qualified Data.HashSet as HS
import Data.Foldable (fold) import Data.Foldable (fold)
import Language.Haskell.TH.Quote (QuasiQuoter)
newtype Name = MkName { inner :: Text } newtype Name = MkName { inner :: Text }
@@ -70,7 +72,7 @@ data Prim e
| PrimWrite e | PrimWrite e
| PrimZeroP e | PrimZeroP e
| PrimNewline | PrimNewline
deriving (Show, Generic, Functor, Foldable, Traversable, Data) deriving (Show, Generic, Functor, Foldable, Traversable, Data, Eq)
instance Each (Prim e) (Prim e') e e' instance Each (Prim e) (Prim e') e e'
@@ -80,7 +82,7 @@ data Lit
| LitBool Bool | LitBool Bool
| LitString Text | LitString Text
| LitQuote Sexp | LitQuote Sexp
deriving (Show, Generic, Data) deriving (Show, Generic, Data, Eq)
pattern Void :: Lit pattern Void :: Lit
pattern Void = LitNil pattern Void = LitNil
@@ -105,7 +107,7 @@ data Sexp
= SexpCons Sexp Sexp = SexpCons Sexp Sexp
| SexpSymbol Text | SexpSymbol Text
| SexpLit Lit | SexpLit Lit
deriving (Show, Generic, Data) deriving (Show, Generic, Data, Eq)
data CommandOrDef data CommandOrDef
= Command Exp = Command Exp
@@ -228,6 +230,9 @@ instance SexpIso CommandOrDef where
-- utilities -- utilities
scm :: QuasiQuoter
scm = Gyehoek.Sexp.makeSx [|| Gyehoek.Sexp.fromSexp @Exp ||]
free :: Exp -> HashSet Name free :: Exp -> HashSet Name
free = cata \case free = cata \case
ExpVarF x -> HS.singleton x ExpVarF x -> HS.singleton x
+16 -3
View File
@@ -35,11 +35,13 @@ module Gyehoek.Sexp
, sxs , sxs
, makeSx , makeSx
, makeSxs , makeSxs
, makeSx'
, toSexp , toSexp
, fromSexp , fromSexp
, stripLocation , stripLocation
, format , format
, equivalent , equivalent
, encodeOrShow
) )
where where
@@ -84,6 +86,7 @@ import Debug.Pretty.Simple
import qualified Data.Vector as V import qualified Data.Vector as V
import qualified Data.Vector.Strict import qualified Data.Vector.Strict
import Data.Function (on) import Data.Function (on)
import Data.String (IsString (fromString))
sexp :: SexpIso a => Iso' a Text sexp :: SexpIso a => Iso' a Text
@@ -385,6 +388,11 @@ deriving instance Lift SL.Atom
deriving instance Lift SL.Position deriving instance Lift SL.Position
deriving instance Lift SL.Prefix deriving instance Lift SL.Prefix
encodeOrShow :: (SexpIso a, Show a, IsString s) => a -> s
encodeOrShow a = fromString case encode a of
Left _ -> show a
Right e -> T.unpack e
extQ :: (Typeable a, Typeable b) => (a -> r) -> (b -> r) -> a -> r extQ :: (Typeable a, Typeable b) => (a -> r) -> (b -> r) -> a -> r
extQ f g a = maybe (f a) g (cast a) extQ f g a = maybe (f a) g (cast a)
@@ -404,13 +412,15 @@ makeSxs f = QuasiQuoter
, quoteDec = undefined , quoteDec = undefined
} }
makeSx :: Data r => Code Q (Sexp -> r) -> QuasiQuoter -- | An untyped variant of 'makeSx', useful when the user function is
makeSx f = QuasiQuoter -- polymorphic in its return value.
makeSx' :: ExpQ -> QuasiQuoter
makeSx' f = QuasiQuoter
{ quoteExp = \str -> do { quoteExp = \str -> do
pos <- getPos pos <- getPos
case readSexpWithPos pos (T.pack str) of case readSexpWithPos pos (T.pack str) of
Left e -> fail e Left e -> fail e
Right x -> [| $(unTypeCode f) $e |] Right x -> [| $f $e |]
where where
e = dataToExpQ e = dataToExpQ
(const Nothing `extQ` metaSexp `extQ` metaSexps) (const Nothing `extQ` metaSexp `extQ` metaSexps)
@@ -420,5 +430,8 @@ makeSx f = QuasiQuoter
, quoteDec = undefined , quoteDec = undefined
} }
makeSx :: Data r => Code Q (Sexp -> r) -> QuasiQuoter
makeSx = makeSx' . unTypeCode
sxs = makeSxs [||id||] sxs = makeSxs [||id||]
sx = makeSx [||id||] sx = makeSx [||id||]
+39
View File
@@ -0,0 +1,39 @@
module Gyehoek.Test.CPS.Syntax (root) where
import Test.Tasty (TestTree, testGroup)
import Test.Tasty.HUnit
import Language.Sexp.Located qualified as SL
import Language.SexpGrammar ()
import Gyehoek.CPS.Syntax (cps)
import Gyehoek.CPS.Syntax qualified as Sut
import Data.Function (on)
import Gyehoek.Test.Sexp (equivto)
root :: IO TestTree
root = pure . testGroup "cps syntax" $
[ qqTree
]
qqTree :: TestTree
qqTree = testGroup "parser"
[ testCase "lambda" do
assertEqual "" (Sut.MkLambda ["x","y"] "ktail"
(Sut.ExpContinue "ktail" [Sut.ValVar "x"]))
[cps|(λ (x y ktail) (continue ktail x))|]
assertEqual "" (Sut.MkLambda [] "ktail"
(Sut.ExpContinue "ktail" [Sut.ValVar "x"]))
[cps|(λ (ktail) (continue ktail x))|]
, testCase "kappa" do
assertEqual "" (Sut.MkKappa ["x","y"]
(Sut.ExpContinue "k123" [Sut.ValVar "x", Sut.ValVar "y"]))
[cps|(κ (x y) (continue k123 x y))|]
, testCase "application" do
assertEqual "" (Sut.ExpApply (Sut.ValVar "f")
[Sut.ValVar "x",Sut.ValVar "y"]
"k")
[cps|(f x y k)|]
assertEqual "" (Sut.ExpApply (Sut.ValVar "f")
[] "k")
[cps|(f k)|]
]
+1 -1
View File
@@ -14,7 +14,7 @@ import qualified System.Process.Text as PT
disabled :: List String disabled :: List String
disabled = disabled =
[ "square" [
] ]
root :: IO TestTree root :: IO TestTree
+7 -1
View File
@@ -1,4 +1,10 @@
module Gyehoek.Test.Sexp (root) where module Gyehoek.Test.Sexp
( root
, EquivSexp(..)
, assertEquiv
, equivto
)
where
import Test.Tasty (TestTree, testGroup) import Test.Tasty (TestTree, testGroup)
import Test.Tasty.HUnit import Test.Tasty.HUnit
+2
View File
@@ -4,6 +4,7 @@ import Test.Tasty (TestTree, testGroup)
import Test.Tasty.Silver.Interactive (defaultMain) import Test.Tasty.Silver.Interactive (defaultMain)
import qualified Gyehoek.Test.Golden import qualified Gyehoek.Test.Golden
import qualified Gyehoek.Test.Sexp import qualified Gyehoek.Test.Sexp
import qualified Gyehoek.Test.CPS.Syntax
main :: IO () main :: IO ()
@@ -13,5 +14,6 @@ root :: IO TestTree
root = testGroup "test" <$> sequenceA root = testGroup "test" <$> sequenceA
[ Gyehoek.Test.Golden.root [ Gyehoek.Test.Golden.root
, Gyehoek.Test.Sexp.root , Gyehoek.Test.Sexp.root
, Gyehoek.Test.CPS.Syntax.root
] ]