mirror of https://github.com/voidlizard/hbs2
wip, lambdas
This commit is contained in:
parent
b4341a7163
commit
de673c6d3b
|
@ -16,6 +16,7 @@ import Data.List (isPrefixOf)
|
||||||
import Data.List qualified as List
|
import Data.List qualified as List
|
||||||
import Data.Kind
|
import Data.Kind
|
||||||
import Data.Maybe
|
import Data.Maybe
|
||||||
|
import Data.Either
|
||||||
import Data.HashMap.Strict qualified as HM
|
import Data.HashMap.Strict qualified as HM
|
||||||
import Data.Text qualified as Text
|
import Data.Text qualified as Text
|
||||||
import Data.Text.IO qualified as TIO
|
import Data.Text.IO qualified as TIO
|
||||||
|
@ -36,6 +37,7 @@ pattern StringLikeList e <- (stringLikeList -> e)
|
||||||
pattern BlobLike :: forall {c} . ByteString -> Syntax c
|
pattern BlobLike :: forall {c} . ByteString -> Syntax c
|
||||||
pattern BlobLike s <- (blobLike -> Just s)
|
pattern BlobLike s <- (blobLike -> Just s)
|
||||||
|
|
||||||
|
|
||||||
class Display a where
|
class Display a where
|
||||||
display :: MonadIO m => a -> m ()
|
display :: MonadIO m => a -> m ()
|
||||||
|
|
||||||
|
@ -118,6 +120,22 @@ stringLike = \case
|
||||||
stringLikeList :: [Syntax c] -> [String]
|
stringLikeList :: [Syntax c] -> [String]
|
||||||
stringLikeList syn = [ stringLike s | s <- syn ] & takeWhile isJust & catMaybes
|
stringLikeList syn = [ stringLike s | s <- syn ] & takeWhile isJust & catMaybes
|
||||||
|
|
||||||
|
pattern Lambda :: forall {c}. [Syntax c] -> Syntax c -> Syntax c
|
||||||
|
pattern Lambda a e <- ListVal [SymbolVal "lambda", LambdaArgs a, e]
|
||||||
|
|
||||||
|
pattern LambdaArgs :: [Syntax c] -> Syntax c
|
||||||
|
pattern LambdaArgs a <- (lambdaArgList -> Just a)
|
||||||
|
|
||||||
|
lambdaArgList :: Syntax c -> Maybe [Syntax c]
|
||||||
|
|
||||||
|
lambdaArgList (ListVal a) = sequence argz
|
||||||
|
where
|
||||||
|
argz = flip fmap a \case
|
||||||
|
x@(SymbolVal{}) -> Just x
|
||||||
|
_ -> Nothing
|
||||||
|
|
||||||
|
lambdaArgList _ = Nothing
|
||||||
|
|
||||||
blobLike :: Syntax c -> Maybe ByteString
|
blobLike :: Syntax c -> Maybe ByteString
|
||||||
blobLike = \case
|
blobLike = \case
|
||||||
LitStrVal s -> Just $ BS8.pack (Text.unpack s)
|
LitStrVal s -> Just $ BS8.pack (Text.unpack s)
|
||||||
|
@ -167,6 +185,7 @@ newtype NotLambda = NotLambda Id
|
||||||
instance Exception NotLambda
|
instance Exception NotLambda
|
||||||
|
|
||||||
data BadFormException c = BadFormException (Syntax c)
|
data BadFormException c = BadFormException (Syntax c)
|
||||||
|
| ArgsMismatch (Syntax c)
|
||||||
|
|
||||||
newtype TypeCheckError c = TypeCheckError (Syntax c)
|
newtype TypeCheckError c = TypeCheckError (Syntax c)
|
||||||
|
|
||||||
|
@ -180,6 +199,7 @@ instance Exception NameNotBoundException
|
||||||
|
|
||||||
instance IsContext c => Show (BadFormException c) where
|
instance IsContext c => Show (BadFormException c) where
|
||||||
show (BadFormException sy) = show $ "BadFormException" <+> pretty sy
|
show (BadFormException sy) = show $ "BadFormException" <+> pretty sy
|
||||||
|
show (ArgsMismatch sy) = show $ "ArgsMismatch" <+> pretty sy
|
||||||
|
|
||||||
instance IsContext c => Show (TypeCheckError c) where
|
instance IsContext c => Show (TypeCheckError c) where
|
||||||
show (TypeCheckError sy) = show $ "TypeCheckError" <+> pretty sy
|
show (TypeCheckError sy) = show $ "TypeCheckError" <+> pretty sy
|
||||||
|
@ -242,12 +262,15 @@ apply name args' = do
|
||||||
Just (BindValue v) -> throwIO (NotLambda name)
|
Just (BindValue v) -> throwIO (NotLambda name)
|
||||||
Nothing -> throwIO (NameNotBound name)
|
Nothing -> throwIO (NameNotBound name)
|
||||||
|
|
||||||
|
|
||||||
runExpr :: forall c m . ( IsContext c
|
runExpr :: forall c m . ( IsContext c
|
||||||
, MonadUnliftIO m
|
, MonadUnliftIO m
|
||||||
, Exception (BadFormException c)
|
, Exception (BadFormException c)
|
||||||
) => Syntax c -> RunM c m (Syntax c)
|
) => Syntax c -> RunM c m (Syntax c)
|
||||||
runExpr syn = handle (handleForm syn) $ case syn of
|
runExpr syn = handle (handleForm syn) $ do
|
||||||
|
|
||||||
|
dict <- ask >>= readTVarIO <&> fromDict
|
||||||
|
|
||||||
|
case syn of
|
||||||
|
|
||||||
ListVal [ w, SymbolVal ".", b] -> do
|
ListVal [ w, SymbolVal ".", b] -> do
|
||||||
pure $ mkList [w, b]
|
pure $ mkList [w, b]
|
||||||
|
@ -258,16 +281,29 @@ runExpr syn = handle (handleForm syn) $ case syn of
|
||||||
ListVal [SymbolVal "lambda", arglist, body] -> do
|
ListVal [SymbolVal "lambda", arglist, body] -> do
|
||||||
pure $ mkForm @c "lambda" [ arglist, body ]
|
pure $ mkForm @c "lambda" [ arglist, body ]
|
||||||
|
|
||||||
ListVal (ListVal [SymbolVal "lambda", ListVal decl, body] : args) -> do
|
|
||||||
error "oopsie"
|
ListVal (SymbolVal "begin" : what) -> do
|
||||||
-- d <- ask
|
evalTop what
|
||||||
-- void $ liftIO do
|
|
||||||
-- dd <- readTVarIO d
|
lc@(ListVal (Lambda decl body : args)) -> do
|
||||||
-- undefined
|
|
||||||
-- runReaderT $ runExpr body
|
when (length decl /= length args) do
|
||||||
-- error "FUCK!"
|
throwIO (ArgsMismatch lc)
|
||||||
-- -- liftIO (run d body)
|
|
||||||
pure nil
|
ev <- mapM runExpr args
|
||||||
|
tv <- ask
|
||||||
|
d0 <- readTVarIO tv
|
||||||
|
atomically do
|
||||||
|
forM_ (zip [ x | SymbolVal x <- decl ] ev) $ \(n,v) -> do
|
||||||
|
let what = case v of
|
||||||
|
Lambda a b -> Bind (BindLambda (error "CALLIN FUCKING LAMBDA") ) "" ""
|
||||||
|
x -> Bind (BindValue x) "runtime-value" ""
|
||||||
|
modifyTVar tv (Dict . HM.insert n what . fromDict)
|
||||||
|
|
||||||
|
e <- runExpr body
|
||||||
|
|
||||||
|
atomically $ writeTVar tv d0
|
||||||
|
pure e
|
||||||
|
|
||||||
ListVal (SymbolVal name : args') -> do
|
ListVal (SymbolVal name : args') -> do
|
||||||
apply name args'
|
apply name args'
|
||||||
|
@ -275,21 +311,27 @@ runExpr syn = handle (handleForm syn) $ case syn of
|
||||||
SymbolVal (Id s) | Text.isPrefixOf ":" s -> do
|
SymbolVal (Id s) | Text.isPrefixOf ":" s -> do
|
||||||
pure (mkSym @c (Text.drop 1 s))
|
pure (mkSym @c (Text.drop 1 s))
|
||||||
|
|
||||||
SymbolVal name -> do
|
SymbolVal name | HM.member name dict -> do
|
||||||
what <- ask >>= readTVarIO
|
let what = HM.lookup name dict
|
||||||
<&> HM.lookup name . fromDict
|
& maybe (BindValue (mkSym name)) bindAction
|
||||||
<&> maybe (BindValue (mkSym name)) bindAction
|
|
||||||
|
|
||||||
case what of
|
case what of
|
||||||
BindValue e -> pure e
|
BindValue e -> pure e
|
||||||
BindLambda e -> pure $ mkForm "lambda" [mkSym name, mkSym "..."]
|
BindLambda e -> pure $ mkForm "lambda" [mkSym name, mkSym "..."]
|
||||||
|
|
||||||
e -> pure e
|
e@(SymbolVal name) | not (HM.member name dict) -> do
|
||||||
|
pure e
|
||||||
|
|
||||||
|
e@Literal{} -> pure e
|
||||||
|
|
||||||
|
e -> error (show $ "WTF:" <+> pretty e )
|
||||||
|
|
||||||
where
|
where
|
||||||
handleForm syn = \case
|
handleForm syn = \case
|
||||||
(BadFormException _ :: BadFormException c) -> do
|
(BadFormException _ :: BadFormException c) -> do
|
||||||
throwIO (BadFormException syn)
|
throwIO (BadFormException syn)
|
||||||
|
(ArgsMismatch s :: BadFormException c) -> do
|
||||||
|
throwIO (ArgsMismatch syn)
|
||||||
|
|
||||||
runM :: forall c m a. ( IsContext c
|
runM :: forall c m a. ( IsContext c
|
||||||
, MonadUnliftIO m
|
, MonadUnliftIO m
|
||||||
|
|
Loading…
Reference in New Issue