This commit is contained in:
2026-08-17 17:19:34 -06:00
parent 2914774ef5
commit f4b891f241
5 changed files with 143 additions and 0 deletions
+2
View File
@@ -61,6 +61,8 @@ library
Gyehoek.Options Gyehoek.Options
Gyehoek.Scheme.Syntax Gyehoek.Scheme.Syntax
Gyehoek.Sexp Gyehoek.Sexp
Gyehoek.Stack.Eval
Gyehoek.Stack.Syntax
Gyehoek.Wasm Gyehoek.Wasm
build-depends: build-depends:
+28
View File
@@ -38,10 +38,12 @@ module Gyehoek.Sexp
, makeSx' , makeSx'
, toSexp , toSexp
, fromSexp , fromSexp
, fromSexp'
, stripLocation , stripLocation
, format , format
, equivalent , equivalent
, encodeOrShow , encodeOrShow
, readSxs
) )
where where
@@ -87,6 +89,10 @@ 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)) import Data.String (IsString (fromString))
import Effectful
import qualified Effectful.FileSystem.IO as FS
import qualified Effectful.FileSystem.IO.ByteString as FB
import qualified Data.Text.Encoding as T
sexp :: SexpIso a => Iso' a Text sexp :: SexpIso a => Iso' a Text
@@ -120,6 +126,10 @@ parseSexps :: SexpIso a => FilePath -> Text -> Either String (List a)
parseSexps f = marshal . SL.parseSexps f . view lazy . encodeUtf8 parseSexps f = marshal . SL.parseSexps f . view lazy . encodeUtf8
where marshal = join . traverseOf (_Right . each) (Sexp.fromSexp sexpIso) where marshal = join . traverseOf (_Right . each) (Sexp.fromSexp sexpIso)
parseSexpsWith :: SexpGrammar a -> FilePath -> Text -> Either String (List a)
parseSexpsWith g f = marshal . SL.parseSexps f . view lazy . encodeUtf8
where marshal = join . traverseOf (_Right . each) (Sexp.fromSexp g)
parseSexp :: SexpIso a => FilePath -> Text -> Either String a parseSexp :: SexpIso a => FilePath -> Text -> Either String a
parseSexp f = marshal . SL.parseSexp f . view lazy . encodeUtf8 parseSexp f = marshal . SL.parseSexp f . view lazy . encodeUtf8
where marshal = join . traverseOf _Right (Sexp.fromSexp sexpIso) where marshal = join . traverseOf _Right (Sexp.fromSexp sexpIso)
@@ -140,6 +150,24 @@ parseSexpWithPos g pos =
marshal . SL.parseSexpWithPos pos . view lazy . encodeUtf8 marshal . SL.parseSexpWithPos pos . view lazy . encodeUtf8
where marshal = join . traverseOf _Right (Sexp.fromSexp g) where marshal = join . traverseOf _Right (Sexp.fromSexp g)
fileName :: FilePath -> FilePath
fileName "-" = "<interactive>"
fileName e = e
hGetContents :: FS.FileSystem :> es => FS.Handle -> Eff es Text
hGetContents h = T.decodeUtf8 <$> FB.hGetContents h
readSxs
:: IOE :> es
=> SexpGrammar a
-> FilePath -> Eff es (List a)
readSxs g fp = FS.runFileSystem $
FS.withFile fp FS.ReadMode $ \h ->
parseSexpsWith g (fileName fp) <$> hGetContents h
>>= either error pure
nonEmptyGrammar :: Grammar p (NonEmpty x :- t) (List x :- x :- t) nonEmptyGrammar :: Grammar p (NonEmpty x :- t) (List x :- x :- t)
nonEmptyGrammar = IGB.Iso nonEmptyGrammar = IGB.Iso
(\((x:|xs) :- t) -> reverse xs :- x :- t) (\((x:|xs) :- t) -> reverse xs :- x :- t)
+4
View File
@@ -0,0 +1,4 @@
module Gyehoek.Stack.Eval
(
) where
+87
View File
@@ -0,0 +1,87 @@
{-# LANGUAGE TemplateHaskellQuotes #-}
module Gyehoek.Stack.Syntax
( Program(..)
, Block(..)
, Instr(..)
, stk
, readProgram
) where
import Control.Lens
import Data.List (List)
import Gyehoek.Scheme.Syntax (Name)
import GHC.Generics (Generic)
import Data.HashMap.Strict (HashMap)
import Language.SexpGrammar (SexpIso, (>>>), (:-))
import Language.SexpGrammar qualified as S
import Language.SexpGrammar.Generic
import Data.Coerce (coerce)
import Data.Text (Text)
import qualified Gyehoek.Sexp
import Language.Haskell.TH.Quote (QuasiQuoter)
import Data.Data (Data)
import qualified Data.HashMap.Strict as H
import Effectful
newtype Program = MkProgram
{ blocks :: HashMap Name Block }
deriving stock (Show, Generic, Data)
newtype Block = MkBlock { code :: List Instr }
deriving stock (Show, Generic, Data)
instance Each Block Block Instr Instr where
each = #code . each
data Instr
= DefinePop Name
| DefinePopCont Name
| PushCont (List Name) Block
deriving stock (Show, Generic, Data)
-- Sexp work
blockGrammar :: S.SexpGrammar (Name, Block)
blockGrammar = g >>> S.pair where
g :: S.Grammar S.Position (S.Sexp :- t) (Block :- (Name :- t))
g = S.list $
S.el (S.sym "define")
>>> S.el (S.list $ S.el $ S.sexpIso @Name)
>>> S.rest (S.sexpIso @Instr)
>>> S.onTail (S.iso coerce coerce)
instance SexpIso Instr where
sexpIso = match
$ With (g_DefinePop >>>)
$ With (g_DefinePopCont >>>)
$ With (g_PushCont >>>)
$ End
where
def :: Text -> S.SexpGrammar Name
def s = S.list $
S.el (S.sym "define")
>>> S.el (S.sexpIso @Name)
>>> S.el (S.list $ S.el $ S.sym s)
g_DefinePop = def "pop!"
g_DefinePopCont = def "pop-cont!"
g_PushCont = S.list $
S.el (S.sym "push-cont!")
>>> S.el (S.list $
S.el Gyehoek.Sexp.kappaKeyword
>>> S.el (S.sexpIso @(List Name))
>>> S.rest (S.sexpIso @Instr)
>>> S.onTail (S.iso coerce coerce))
programFromSexps :: Foldable f => f S.Sexp -> Program
programFromSexps = MkProgram . foldMap f
where f = uncurry H.singleton . Gyehoek.Sexp.fromSexp' blockGrammar
stk :: QuasiQuoter
stk = Gyehoek.Sexp.makeSxs [|| programFromSexps ||]
readProgram
:: IOE :> es
=> FilePath -> Eff es Program
readProgram = fmap (MkProgram . H.fromList) . Gyehoek.Sexp.readSxs blockGrammar
+22
View File
@@ -0,0 +1,22 @@
;; -*- mode:scheme -*-
(define (silly)
(define f (pop!))
(define g (pop!))
(define h (pop!))
(define x (pop!))
(define ktail (pop-cont!))
(push-cont! (κ (x0)
(define x* (pop!))
(define g* (pop!))
(push-cont! (κ (x1)
(define f* (pop!))
(define x0* (pop!))
(push-cont! ktail)
(push! x0*)
(push! x1)
(call! f)))
(push! x*)
(call! g)))
(push! x)
(call! h))