Nathan Ringo: 1 Adds datatypes. 10 files changed, 69 insertions(+), 18 deletions(-)
Copy & paste the following snippet into your terminal to import this patchset into git:
curl -s https://lists.sr.ht/~remexre/public-inbox/patches/25864/mbox | git am -3Learn more about email & git
--- bootstrap/Language/Sylvan/CST.hs | 4 ++++ bootstrap/Language/Sylvan/CST/Pretty.hs | 13 ++++++++---- bootstrap/Language/Sylvan/Env.hs | 8 +++++--- bootstrap/Language/Sylvan/Eval.hs | 3 +++ bootstrap/Language/Sylvan/Parser.y | 25 ++++++++++++++++++++++-- bootstrap/Language/Sylvan/Parser/Lexer.x | 7 +++++-- bootstrap/default.nix | 14 ++++++------- bootstrap/sylvan-bootstrap.cabal | 2 ++ src/std/data/linked_list/linked_list.syl | 8 ++++++++ src/sylvan/driver/main.syl | 3 +++ 10 files changed, 69 insertions(+), 18 deletions(-) create mode 100644 bootstrap/Language/Sylvan/Eval.hs create mode 100644 src/std/data/linked_list/linked_list.syl diff --git a/bootstrap/Language/Sylvan/CST.hs b/bootstrap/Language/Sylvan/CST.hs index cf16140..fbf8fe5 100644 --- a/bootstrap/Language/Sylvan/CST.hs @@ -36,6 +36,9 @@ data ImportModifier deriving (Show) data Decl where + D'AttrInh :: ByteString -> GenericDeclArgs -> Type -> Decl + D'AttrSyn :: ByteString -> GenericDeclArgs -> Type -> Decl + D'Data :: ByteString -> GenericDeclArgs -> Seq (ByteString, GenericDeclArgs, Seq Type) -> Decl D'ForeignGlobal :: ByteString -> GenericDeclArgs -> Type -> ForeignItems -> Decl D'ForeignType :: ByteString -> GenericDeclArgs -> Kind -> ForeignItems -> Decl D'Global :: ByteString -> GenericDeclArgs -> Type -> Expr -> Decl @@ -52,6 +55,7 @@ data Expr where E'App :: Expr -> Seq Expr -> Expr E'Access :: Expr -> LName -> Expr E'Inhs :: Seq (LName, Expr) -> Expr + E'Int :: Int -> Expr E'Lam :: Seq (ByteString, Maybe Type) -> Expr -> Expr E'String :: ByteString -> Expr E'Var :: LName -> Expr diff --git a/bootstrap/Language/Sylvan/CST/Pretty.hs b/bootstrap/Language/Sylvan/CST/Pretty.hs index f43abeb..58cef93 100644 --- a/bootstrap/Language/Sylvan/CST/Pretty.hs @@ -81,6 +81,7 @@ prettyDecl (D'Type name genericArgs kind ty) = equals, prettyType ty <> semi ] +prettyDecl decl = pretty (show decl) -- TODO -- Expressions @@ -99,6 +100,7 @@ prettyExpr2 expr = prettyExpr3 expr prettyExpr3 :: Expr -> Doc AnsiStyle prettyExpr3 (E'Var name) = prettyVarName name +prettyExpr3 (E'Int n) = prettyInt n prettyExpr3 (E'String s) = prettyString s prettyExpr3 (E'Inhs inhs) = group (braces (nest 2 (line <> prettyInhPairs inhs) <> line)) prettyExpr3 expr = parens (prettyExpr1 expr) @@ -186,8 +188,11 @@ dcolon = annotate styleModuleName (colon <> colon) -- Literals +prettyInt :: Int -> Doc AnsiStyle +prettyInt = annotate styleLiteral <<< pretty + prettyString :: ByteString -> Doc AnsiStyle -prettyString = annotate styleString <<< dquotes <<< BS.foldr (\ch -> (helper ch <>)) emptyDoc +prettyString = annotate styleLiteral <<< dquotes <<< BS.foldr (\ch -> (helper ch <>)) emptyDoc where helper ch = pretty $ @@ -268,12 +273,12 @@ styleKeyword = color Magenta <> bold styleKindName :: AnsiStyle styleKindName = colorDull Magenta +styleLiteral :: AnsiStyle +styleLiteral = color Yellow + styleModuleName :: AnsiStyle styleModuleName = colorDull Blue -styleString :: AnsiStyle -styleString = color Yellow - styleTypeName :: AnsiStyle styleTypeName = color Green diff --git a/bootstrap/Language/Sylvan/Env.hs b/bootstrap/Language/Sylvan/Env.hs index b333cdf..5ec94ef 100644 --- a/bootstrap/Language/Sylvan/Env.hs @@ -1,7 +1,9 @@ module Language.Sylvan.Env where -data ModuleEnv = MkModuleEnv - { module'globals :: (), - module'types :: () +import Data.Trie (Trie) + +data Env = MkEnv + { env'globals :: Trie (), + env'nts :: Trie () } deriving (Show) diff --git a/bootstrap/Language/Sylvan/Eval.hs b/bootstrap/Language/Sylvan/Eval.hs new file mode 100644 index 0000000..1485c03 --- /dev/null @@ -0,0 +1,3 @@ +-- | An interpreter for Sylvan. Interpreting the language in the bootstrapper +-- lets me put off needing to write a compiler backend! +module Language.Sylvan.Eval where diff --git a/bootstrap/Language/Sylvan/Parser.y b/bootstrap/Language/Sylvan/Parser.y index 62e67ae..8510532 100644 --- a/bootstrap/Language/Sylvan/Parser.y @@ -5,7 +5,7 @@ module Language.Sylvan.Parser (parse, parseLazy) where import Control.Arrow (first) -import Control.Category ((<<<)) +import Control.Category ((<<<), (>>>)) import Control.Monad ((<=<)) import Control.Monad.Error.Class (MonadError (..)) import Control.Monad.Reader.Class (MonadReader (..)) @@ -23,6 +23,7 @@ import Data.Sequence qualified as Seq import Language.Sylvan.CST import Language.Sylvan.Parser.Lexer (Token (..), lexer) import Language.Sylvan.Parser.Utils (uncheckedParseLName, uncheckedParseModuleName, uncheckedParseUName) +import Text.Read (readEither) } %name parser @@ -38,6 +39,7 @@ import Language.Sylvan.Parser.Utils (uncheckedParseLName, uncheckedParseModuleNa '-' { Just Token'Minus } '*' { Just Token'Star } '->' { Just Token'Arrow } + 'data' { Just Token'Data } 'fn' { Just Token'Fn } 'forall' { Just Token'Forall } 'foreign' { Just Token'Foreign } @@ -86,7 +88,9 @@ ImportModifier :: { ImportModifier } | 'renaming' '(' manyComma(pairSep(ID_L, 'to', ID_L)) ')' { Renaming $3 } Decl :: { Decl } - : 'fn' ID_L OptGenericDeclArgs '(' DeclFnArgs ')' ':' Type '=' Expr ';' + : 'data' ID_U OptGenericDeclArgs '{' manyComma(CtorDecl) '}' + { D'Data $2 $3 $5 } + | 'fn' ID_L OptGenericDeclArgs '(' DeclFnArgs ')' ':' Type '=' Expr ';' { D'Global $2 $3 (T'Arrow (fmap snd $5) $8) (E'Lam (fmap (second Just) $5) $10) } | 'foreign' 'global' ID_L OptGenericDeclArgs ':' Type '=' '{' ForeignItems '}' ';' { D'ForeignGlobal $3 $4 $6 $9 } @@ -94,11 +98,21 @@ Decl :: { Decl } { D'ForeignType $3 $4 $5 $8 } | 'global' ID_L OptGenericDeclArgs ':' Type '=' Expr ';' { D'Global $2 $3 $5 $7 } + | 'inh' ID_L OptGenericDeclArgs ':' Type ';' + { D'AttrInh $2 $3 $5 } | 'nt' ID_U OptGenericDeclArgs ';' { D'NT $2 $3 } + | 'syn' ID_L OptGenericDeclArgs ':' Type ';' + { D'AttrInh $2 $3 $5 } | 'type' ID_U OptGenericDeclArgs OptKind '=' Type ';' { D'Type $2 $3 $4 $6 } +CtorDecl :: { (ByteString, GenericDeclArgs, Seq Type) } + : ID_L OptGenericDeclArgs + { ($1, $2, Empty) } + | ID_L OptGenericDeclArgs '(' manyComma(Type) ')' + { ($1, $2, $4) } + -- Expressions Expr1 :: { Expr } @@ -112,6 +126,7 @@ Expr2 :: { Expr } Expr3 :: { Expr } : Name_L { E'Var $1 } + | Int { E'Int $1 } | String { E'String $1 } | '{' manyComma(pairSep(Name_L, '=', Expr1)) '}' { E'Inhs $2 } | '(' Expr1 ')' { $2 } @@ -158,6 +173,7 @@ Name_U :: { UName } -- Literals +Int :: { Int } : INT {% parseInt $1 } String :: { ByteString } : STRING {% parseString $1 } -- Aliases @@ -230,6 +246,11 @@ parseKind "TERM" = pure K'Term parseKind "TREE" = pure K'Tree parseKind name = parseError (Just (Token'NameU name), ["CONSTRAINT", "DATA", "INHS", "TERM", "TREE"]) +parseInt :: ByteString -> M Int +parseInt = BS.toString >>> readEither >>> \case + Left err -> throwError err + Right n -> pure n + -- TODO: This seems fairly inefficient... parseString :: ByteString -> M ByteString parseString = fmap BS.fromString <<< loop <<< BS.toString <<< BS.init <<< BS.tail where diff --git a/bootstrap/Language/Sylvan/Parser/Lexer.x b/bootstrap/Language/Sylvan/Parser/Lexer.x index 9e138e7..88c7c48 100644 --- a/bootstrap/Language/Sylvan/Parser/Lexer.x @@ -21,6 +21,7 @@ tokens :- "-" { const Token'Minus } "*" { const Token'Star } "->" { const Token'Arrow } + "data" { const Token'Data } "fn" { const Token'Fn } "forall" { const Token'Forall } "foreign" { const Token'Foreign } @@ -62,9 +63,10 @@ data Token | Token'Minus | Token'Star | Token'Arrow + | Token'Data + | Token'Fn | Token'Forall | Token'Foreign - | Token'Fn | Token'Global | Token'Hiding | Token'Import @@ -101,9 +103,10 @@ instance Show Token where show Token'Minus = "\"-\"" show Token'Star = "\"*\"" show Token'Arrow = "\"->\"" + show Token'Data = "\"data\"" + show Token'Fn = "\"fn\"" show Token'Forall = "\"forall\"" show Token'Foreign = "\"foreign\"" - show Token'Fn = "\"fn\"" show Token'Global = "\"global\"" show Token'Hiding = "\"hiding\"" show Token'Import = "\"import\"" diff --git a/bootstrap/default.nix b/bootstrap/default.nix index ae24293..79ec45a 100644 --- a/bootstrap/default.nix @@ -1,8 +1,8 @@ -{ mkDerivation, alex, array, base, bytestring, containers -, directory, filepath, happy, lib, logict, microlens, microlens-ghc -, microlens-th, mtl, optparse-applicative, prettyprinter -, prettyprinter-ansi-terminal, regex-tdfa, transformers -, utf8-string +{ mkDerivation, alex, array, base, bytestring, bytestring-trie +, containers, directory, filepath, happy, lib, logict, microlens +, microlens-ghc, microlens-th, mtl, optparse-applicative +, prettyprinter, prettyprinter-ansi-terminal, regex-tdfa +, transformers, utf8-string }: mkDerivation { pname = "sylvan-bootstrap"; @@ -11,8 +11,8 @@ mkDerivation { isLibrary = true; isExecutable = true; libraryHaskellDepends = [ - array base bytestring containers directory filepath logict - microlens microlens-ghc microlens-th mtl prettyprinter + array base bytestring bytestring-trie containers directory filepath + logict microlens microlens-ghc microlens-th mtl prettyprinter prettyprinter-ansi-terminal regex-tdfa transformers utf8-string ]; libraryToolDepends = [ alex happy ]; diff --git a/bootstrap/sylvan-bootstrap.cabal b/bootstrap/sylvan-bootstrap.cabal index 836b7a5..f880411 100644 --- a/bootstrap/sylvan-bootstrap.cabal @@ -10,6 +10,7 @@ library array ^>=0.5.4.0 , base >=4 && <5 , bytestring ^>=0.10.12.1 + , bytestring-trie ^>=0.2.5.2 , containers ^>=0.6.4.1 , directory ^>=1.3.6.1 , filepath ^>=1.4.2.1 @@ -76,6 +77,7 @@ library , Language.Sylvan.CST , Language.Sylvan.CST.Pretty , Language.Sylvan.Env + , Language.Sylvan.Eval , Language.Sylvan.Modules , Language.Sylvan.Parser , Language.Sylvan.Parser.Lexer diff --git a/src/std/data/linked_list/linked_list.syl b/src/std/data/linked_list/linked_list.syl new file mode 100644 index 0000000..56c5f59 --- /dev/null +++ b/src/std/data/linked_list/linked_list.syl @@ -0,0 +1,8 @@ +module std::data::linked_list; + +import std::prelude; + +data LinkedList<a> { + nil, + cons(a, LinkedList<a>) +} diff --git a/src/sylvan/driver/main.syl b/src/sylvan/driver/main.syl index 9eb4cf6..82275cd 100644 --- a/src/sylvan/driver/main.syl +++ b/src/sylvan/driver/main.syl @@ -1,6 +1,7 @@ module sylvan::driver; import std::prelude hiding (foo) renaming (bar to foo) using (baz, asdf); +import std::data::linked_list; import std::data::set; fn main(ioIn: IOToken): IOToken = print(ioIn, "Hello, world!"); @@ -10,3 +11,5 @@ global foo: Foo = { bar = one(), baz = "two", }; + +global n: Int = 3; -- 2.33.0