Added car, cdr and cons builtin procs

This commit is contained in:
Ivy 2021-02-04 00:32:52 +01:00
parent d786923335
commit 50b714b1f8
7 changed files with 42 additions and 25 deletions

13
src/BuiltinProcs.hs Normal file
View File

@ -0,0 +1,13 @@
module BuiltinProcs where
import Types.Language
import Control.Monad.State
car :: [Expr] -> State Enviroment Expr
car [ConsE x _] = return $ QuotedE x
cdr :: [Expr] -> State Enviroment Expr
cdr [ConsE _ xs] = return $ QuotedE xs
cons :: [Expr] -> State Enviroment Expr
cons [e1, e2] = return $ QuotedE $ ConsE e1 e2

View File

@ -4,13 +4,6 @@ import qualified Data.Map as M
import Types.Language import Types.Language
import Data.Maybe import Data.Maybe
-- The base enviroment, that contains the main functions and variables
base :: Enviroment
base = Enviroment (M.fromList [
("id", LambdaE "x" $ VarE "x"), -- Given a expression, returns the same expression
("const", LambdaE "x" $ LambdaE "y" $ VarE "x") -- Given two expressions, returns the first expression
]) Nothing
lookupVar :: String -> Enviroment -> Maybe Expr lookupVar :: String -> Enviroment -> Maybe Expr
lookupVar var (Enviroment menv upperEnv) = let mExpr = M.lookup var menv in lookupVar var (Enviroment menv upperEnv) = let mExpr = M.lookup var menv in
if isNothing mExpr then upperEnv >>= lookupVar var else mExpr if isNothing mExpr then upperEnv >>= lookupVar var else mExpr

14
src/Enviroment/Base.hs Normal file
View File

@ -0,0 +1,14 @@
module Enviroment.Base where
import BuiltinProcs
import Types.Language
import Data.Map as M
base :: Enviroment
base = Enviroment (M.fromList [
("id", LambdaE "x" $ VarE "x"), -- Given a expression, returns the same expression
("const", LambdaE "x" $ LambdaE "y" $ VarE "x"), -- Given two expressions, returns the first expression
("car", BuiltinProcE car),
("cdr", BuiltinProcE cdr),
("cons", BuiltinProcE cons)
]) Nothing

View File

@ -22,6 +22,7 @@ evalS (ConsE pr args) = do
finalExpr <- evalS resExpr finalExpr <- evalS resExpr
return finalExpr return finalExpr
evalS l@(LambdaE _ _) = return l evalS l@(LambdaE _ _) = return l
evalS p@(BuiltinProcE _) = return p
evalS NilE = return NilE evalS NilE = return NilE
applyS :: Expr -> Expr -> State Enviroment Expr applyS :: Expr -> Expr -> State Enviroment Expr
@ -29,4 +30,8 @@ applyS (LambdaE p expr) (ConsE x xs) = do
e <- applyS expr xs e <- applyS expr xs
get >>= put . (`extendEnv` insertVar p x emptyEnv) get >>= put . (`extendEnv` insertVar p x emptyEnv)
return e return e
applyS (BuiltinProcE p) args = do
args' <- mapM evalS $ cons2List args
e <- p args'
return e
applyS e NilE = return e applyS e NilE = return e

View File

@ -1,8 +1,8 @@
module Main where module Main where
import Evaluator import Evaluator
import Enviroment
import Parser import Parser
import Enviroment.Base
import Control.Monad import Control.Monad
import Data.Maybe import Data.Maybe
import System.Console.Haskeline import System.Console.Haskeline

View File

@ -20,7 +20,7 @@ anyExpressionEOF = do
anyExpression :: GenParser Token st Expr anyExpression :: GenParser Token st Expr
anyExpression = do anyExpression = do
expr <- intE <|> quotedE <|> try setE <|> try nilE <|> try consE <|> try lambdaE <|> varE <|> listE expr <- intE <|> quotedE <|> try setE <|> try nilE <|> try lambdaE <|> varE <|> listE
return expr return expr
------------------------------------------------------------ ------------------------------------------------------------
@ -45,15 +45,6 @@ quotedE = do
expr <- anyExpression expr <- anyExpression
return $ QuotedE expr return $ QuotedE expr
consE :: GenParser Token st Expr
consE = do
_ <- parseLeftParenT
_ <- parseConsT
expr1 <- anyExpression
expr2 <- anyExpression
_ <- parseRightParenT
return $ ConsE expr1 expr2
varE :: GenParser Token st Expr varE :: GenParser Token st Expr
varE = do varE = do
(SymbolT var) <- parseSymbolT (SymbolT var) <- parseSymbolT
@ -109,11 +100,6 @@ parseNilT = satisfyT isNilT
where isNilT (SymbolT "nil") = True where isNilT (SymbolT "nil") = True
isNilT _ = False isNilT _ = False
parseConsT :: GenParser Token st Token
parseConsT = satisfyT isConsT
where isConsT (SymbolT "cons") = True
isConsT _ = False
parseSymbolT :: GenParser Token st Token parseSymbolT :: GenParser Token st Token
parseSymbolT = satisfyT isSymbolT parseSymbolT = satisfyT isSymbolT
where isSymbolT (SymbolT _) = True where isSymbolT (SymbolT _) = True

View File

@ -1,6 +1,7 @@
module Types.Language where module Types.Language where
import Data.Map (Map) import Data.Map (Map)
import Control.Monad.State
data Enviroment = Enviroment (Map String Expr) (Maybe Enviroment) data Enviroment = Enviroment (Map String Expr) (Maybe Enviroment)
@ -9,6 +10,7 @@ data Expr = IntE Integer
| SetE String Expr | SetE String Expr
| ConsE Expr Expr | ConsE Expr Expr
| LambdaE String Expr | LambdaE String Expr
| BuiltinProcE ([Expr] -> State Enviroment Expr)
| QuotedE Expr | QuotedE Expr
| NilE | NilE
@ -18,9 +20,13 @@ instance Show Expr where
show (SetE v x) = "#[set " ++ show v ++ show x ++ "]" show (SetE v x) = "#[set " ++ show v ++ show x ++ "]"
show c@(ConsE _ _) = "(" ++ showCons c show c@(ConsE _ _) = "(" ++ showCons c
where showCons (ConsE x NilE) = show x ++ ")" where showCons (ConsE x NilE) = show x ++ ")"
showCons (ConsE x xs) = show x ++ " " ++ showCons xs showCons (ConsE x xs) = show x ++ " " ++ show xs ++ ")"
show (LambdaE s e) = "#[lambda " ++ s ++ " " ++ show e ++ "]" show (LambdaE s e) = "#[lambda " ++ s ++ " " ++ show e ++ "]"
show (QuotedE e) = show e show (QuotedE e) = "Q" ++ show e
show NilE = "nil" show NilE = "nil"
cons2List :: Expr -> [Expr]
cons2List NilE = []
cons2List (ConsE x xs) = x:cons2List xs
-- TODO: Make set! and lambda(?) parsed as cons, detect later set! and lambda as special procedures -- TODO: Make set! and lambda(?) parsed as cons, detect later set! and lambda as special procedures