Skip to content

Commit

Permalink
cons operator WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
bristermitten committed Nov 6, 2023
1 parent 4616233 commit 643ad57
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 8 deletions.
3 changes: 2 additions & 1 deletion app/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ import System.Environment (getEnvironment)
import System.IO (openFile)
import System.Process
import Text.Printf
import Elara.Prim (primModule)

outDirName :: IsString s => s
outDirName = "build"
Expand Down Expand Up @@ -100,7 +101,7 @@ runElara dumpShunted dumpTyped dumpCore run = fmap fst <$> finalisePipeline $ do
source <- loadModule "source.elr"
prelude <- loadModule "prelude.elr"

let graph = createGraph [source, prelude]
let graph = createGraph [primModule, source, prelude]
coreGraph <- processModules graph (dumpShunted, dumpTyped)

when dumpCore $ do
Expand Down
15 changes: 14 additions & 1 deletion prelude.elr
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
module Prelude
import Elara.Prim

def println : String -> IO ()
let println = elaraPrimitive "println"
Expand All @@ -13,4 +14,16 @@ def (==) : a -> a -> Bool
let (==) = elaraPrimitive "=="

def toString : a -> String
let toString = elaraPrimitive "toString"
let toString = elaraPrimitive "toString"

def (++) : [a] -> [a] -> [a]
let (++) a b =
match a with
[] -> b
(x::xs) -> x :: (xs ++ b)

def reverse : [a] -> [a]
let reverse x =
match x with
[] -> []
(x::xs) -> reverse xs ++ [x]
15 changes: 12 additions & 3 deletions src/Elara/Parse/Expression.hs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{-# LANGUAGE DataKinds #-}
module Elara.Parse.Expression where

import Control.Lens (Iso', iso, (^.))
Expand All @@ -7,7 +8,7 @@ import Data.Set qualified as Set
import Elara.AST.Frontend
import Elara.AST.Generic (BinaryOperator (..), BinaryOperator' (..), Expr (Expr), Expr' (..))
import Elara.AST.Name (VarName, nameText)
import Elara.AST.Region (Located (..), sourceRegion, spanningRegion')
import Elara.AST.Region (Located (..), sourceRegion, spanningRegion', withLocationOf)
import Elara.Lexer.Token (Token (..))
import Elara.Parse.Combinators (liftedBinary, sepEndBy1')
import Elara.Parse.Error
Expand All @@ -19,6 +20,8 @@ import Elara.Parse.Primitives (Parser, inParens, located, token_, withPredicate)
import Elara.Utils (curry3)
import Text.Megaparsec (MonadParsec (eof), customFailure, sepEndBy, try, (<?>))
import Prelude hiding (Op)
import qualified Elara.Prim as Prim
import Elara.AST.Select (LocatedAST(Frontend))

locatedExpr :: Parser FrontendExpr' -> Parser FrontendExpr
locatedExpr = fmap (\x -> Expr (x, Nothing)) . located
Expand All @@ -28,6 +31,7 @@ exprParser =
makeExprParser
expression
[ [InfixL functionCall]
, [InfixL cons]
, [InfixR binOp]
]
<?> "expression"
Expand All @@ -51,8 +55,14 @@ statement =
unannotatedExpr :: Iso' FrontendExpr (Located FrontendExpr')
unannotatedExpr = iso (\(Expr (e, _)) -> e) (\x -> Expr (x, Nothing))

binOp, functionCall :: Parser (FrontendExpr -> FrontendExpr -> FrontendExpr)
binOp, cons, functionCall :: Parser (FrontendExpr -> FrontendExpr -> FrontendExpr)
binOp = liftedBinary operator (curry3 BinaryOperator) unannotatedExpr
cons = liftedBinary consName (curry3 BinaryOperator) unannotatedExpr
where consName :: Parser FrontendBinaryOperator
consName = do
l <- located (token_ TokenDoubleColon)
let y = (SymOp (Prim.cons `withLocationOf` l)) :: BinaryOperator' Frontend
pure $ MkBinaryOperator (y `withLocationOf`l)
functionCall = liftedBinary pass (const FunctionCall) unannotatedExpr

-- This isn't actually used in `expressionTerm` as `varName` also covers (+) operators, but this is used when parsing infix applications
Expand Down Expand Up @@ -168,7 +178,6 @@ lambda = locatedExpr $ do
ifElse :: Parser FrontendExpr
ifElse = locatedExpr $ do
token_ TokenIf

condition <- exprParser
_ <- optional (token_ TokenSemicolon)
token_ TokenThen
Expand Down
27 changes: 25 additions & 2 deletions src/Elara/Prim.hs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ The compiler will then replace these with the actual primitive functions.
-}
module Elara.Prim where

import Elara.AST.Name (ModuleName (..), Name (..), Qualified (..), TypeName (..), VarName (NormalVarName))
import Elara.AST.Frontend
import Elara.AST.Module
import Elara.AST.Name (MaybeQualified (..), ModuleName (..), Name (..), OpName (..), Qualified (..), TypeName (..), VarName (NormalVarName))
import Elara.AST.Region (IgnoreLocation (IgnoreLocation), Located, SourceRegion, generatedLocated, generatedSourceRegion)
import Elara.AST.VarRef (VarRef, VarRef' (Global))
import Elara.Data.Kind (ElaraKind (..))
Expand All @@ -16,6 +18,13 @@ import Elara.TypeInfer.Monotype (Scalar (..))
import Elara.TypeInfer.Type (Type (..))
import Elara.TypeInfer.Unique (makeUniqueTyVarWith)
import Polysemy
import Elara.AST.Generic.Types (ASTLocate')

consName :: VarName
consName = NormalVarName "::"

cons :: MaybeQualified OpName
cons = MaybeQualified (OpName "::") (Just primModuleName)

fetchPrimitiveName :: VarName
fetchPrimitiveName = NormalVarName "elaraPrimitive"
Expand All @@ -41,17 +50,31 @@ ioName = TypeName "IO"
primModuleName :: ModuleName
primModuleName = ModuleName ["Elara", "Prim"]

primModule :: forall ast. (ASTLocate' ast ~ Located) => Module ast
primModule =
Module $
primLocated
( Module'
(primLocated primModuleName)
ExposingAll
[]
[]
)

primRegion :: SourceRegion
primRegion = generatedSourceRegion (Just "<primitive>")

primLocated :: a -> Located a
primLocated = generatedLocated (Just "<primitive>")

mkPrimQual :: c -> Qualified c
mkPrimQual c = Qualified c primModuleName

mkPrimVarRef :: c -> Located (Qualified c)
mkPrimVarRef c = generatedLocated (Just "<primitive>") (mkPrimQual c)

primitiveVars :: [VarName]
primitiveVars = [fetchPrimitiveName]
primitiveVars = [fetchPrimitiveName, consName]

primitiveTypes :: [TypeName]
primitiveTypes = [stringName, charName, intName, boolName]
Expand Down
2 changes: 2 additions & 0 deletions test/Parse/Common.hs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ shouldParsePattern source expected = withFrozenCallStack $ do
parsed <- lexAndParse patParser source >>= evalEitherParseError
diff (stripLocation parsed) (==) expected



shouldParseExpr :: MonadTest m => Text -> Expr 'UnlocatedFrontend -> m ()
shouldParseExpr source expected = withFrozenCallStack $ do
parsed <- lexAndParse (exprBlock element) source >>= evalEitherParseError
Expand Down
1 change: 0 additions & 1 deletion test/Parse/Expressions.hs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
module Parse.Expressions where

import Arbitrary.AST (genExpr)
import Data.Generics.Wrapped
import Elara.AST.Generic
import Elara.AST.Name
import Elara.AST.StripLocation
Expand Down

0 comments on commit 643ad57

Please sign in to comment.