Compare commits
5 Commits
e96cddff9b
...
ee13a75141
Author | SHA1 | Date |
---|---|---|
Ivy | ee13a75141 | |
Ivy | 8043186001 | |
Ivy | f7119b1dd3 | |
Ivy | 65e4502799 | |
Ivy | 16e6cd8419 |
|
@ -22,7 +22,8 @@ executable cherry
|
||||||
Parser,
|
Parser,
|
||||||
TokenType,
|
TokenType,
|
||||||
Lexer,
|
Lexer,
|
||||||
Evaluator
|
Evaluator,
|
||||||
|
Enviroment
|
||||||
|
|
||||||
build-depends: base >= 4.7 && < 5,
|
build-depends: base >= 4.7 && < 5,
|
||||||
containers,
|
containers,
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
module Enviroment where
|
||||||
|
|
||||||
|
import qualified Data.Map as M
|
||||||
|
import ExprType
|
||||||
|
import Data.Maybe
|
||||||
|
|
||||||
|
data Enviroment = Enviroment (M.Map String Expr) (Maybe Enviroment)
|
||||||
|
|
||||||
|
base :: Enviroment
|
||||||
|
base = Enviroment (M.fromList [
|
||||||
|
("test-var", IntE 10),
|
||||||
|
("id", LambdaE "x" $ VarE "x"),
|
||||||
|
("first", LambdaE "x" $ LambdaE "y" $ VarE "x")
|
||||||
|
]) Nothing
|
||||||
|
|
||||||
|
lookupVar :: Enviroment -> String -> Maybe Expr
|
||||||
|
lookupVar (Enviroment menv upperEnv) var = let mExpr = M.lookup var menv in
|
||||||
|
if isNothing mExpr then upperEnv >>= (`lookupVar` var) else mExpr
|
||||||
|
|
||||||
|
insertVar :: Enviroment -> String -> Expr -> Enviroment
|
||||||
|
insertVar (Enviroment menv u) var expr = Enviroment (M.insert var expr menv) u
|
||||||
|
|
||||||
|
emptyEnv :: Enviroment
|
||||||
|
emptyEnv = Enviroment M.empty Nothing
|
||||||
|
|
||||||
|
extendEnv :: Enviroment -> Enviroment -> Enviroment
|
||||||
|
extendEnv (Enviroment menv Nothing) upper = Enviroment menv (Just upper)
|
||||||
|
extendEnv (Enviroment menv (Just upperMenv)) upper = Enviroment menv (Just $ extendEnv upperMenv upper)
|
|
@ -1,26 +1,25 @@
|
||||||
module Evaluator where
|
module Evaluator where
|
||||||
|
|
||||||
import qualified Data.Map as M
|
|
||||||
import ExprType
|
import ExprType
|
||||||
|
import Enviroment
|
||||||
type Env = M.Map String Expr
|
import Data.Maybe
|
||||||
|
|
||||||
-- TODO: create a separated file for builtinProcs
|
-- TODO: create a separated file for builtinProcs
|
||||||
-- TODO: create a BuiltinProc or something like that in data Expr, and make + a builtin proc
|
-- TODO: create a BuiltinProc or something like that in data Expr, and make + a builtin proc
|
||||||
|
|
||||||
base :: Env
|
eval :: Enviroment -> Expr -> (Enviroment, Expr)
|
||||||
base = M.fromList [
|
eval env i@(IntE _) = (env, i)
|
||||||
("test-var", IntE 10)
|
eval env (VarE v) = eval env $ fromJust $ lookupVar env v
|
||||||
]
|
eval env (SetE v expr) = (insertVar env v expr, NilE)
|
||||||
|
|
||||||
eval :: Env -> Expr -> (Env, Expr)
|
|
||||||
eval env i@(IntE x) = (env, i)
|
|
||||||
eval env (VarE v) = (M.insert v nExpr nEnv, nExpr)
|
|
||||||
where (nEnv, nExpr) = eval env $ env M.! v
|
|
||||||
eval env (SetE v expr) = (M.insert v expr env, NilE)
|
|
||||||
eval env (QuotedE e) = (env, e)
|
eval env (QuotedE e) = (env, e)
|
||||||
eval env c@(ConsE _ _) = (env, c)
|
eval env (ConsE p args) = (fEnv, fExpr)
|
||||||
|
where (uEnv, ap) = eval env p
|
||||||
|
(aEnv, aExpr) = apply ap args
|
||||||
|
(fEnv, fExpr) = eval (extendEnv aEnv uEnv) aExpr
|
||||||
|
eval env (LambdaE arg expr) = (env, LambdaE arg expr)
|
||||||
eval env NilE = (env, NilE)
|
eval env NilE = (env, NilE)
|
||||||
|
|
||||||
--apply :: Proc -> Args -> Expr
|
apply :: Expr -> Expr -> (Enviroment, Expr)
|
||||||
--apply p args
|
apply (LambdaE p expr) (ConsE x xs) = (extendEnv (insertVar emptyEnv p x) nEnv, nExp)
|
||||||
|
where (nEnv, nExp) = apply expr xs
|
||||||
|
apply e NilE = (emptyEnv, e)
|
||||||
|
|
|
@ -2,11 +2,12 @@ module ExprType where
|
||||||
|
|
||||||
data Expr = IntE Integer
|
data Expr = IntE Integer
|
||||||
| VarE String
|
| VarE String
|
||||||
| ProcedureE String [Expr]
|
|
||||||
| SetE String Expr
|
| SetE String Expr
|
||||||
| ConsE Expr Expr
|
| ConsE Expr Expr
|
||||||
|
| LambdaE String Expr
|
||||||
| QuotedE Expr
|
| QuotedE Expr
|
||||||
| NilE deriving (Show)
|
| NilE
|
||||||
|
deriving (Show)
|
||||||
|
|
||||||
-- instance Show Expr where
|
-- instance Show Expr where
|
||||||
-- show (IntE x) = show x
|
-- show (IntE x) = show x
|
||||||
|
|
|
@ -12,7 +12,7 @@ parseTokens = do
|
||||||
return tokns
|
return tokns
|
||||||
|
|
||||||
anyLispToken :: GenParser Char st Token
|
anyLispToken :: GenParser Char st Token
|
||||||
anyLispToken = leftParenT <|> rightParenT <|> apostropheT <|> symbolT <|> intT
|
anyLispToken = leftParenT <|> rightParenT <|> apostropheT <|> backslashT <|> symbolT <|> intT
|
||||||
|
|
||||||
------------------------------------------------------------
|
------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -30,7 +30,10 @@ apostropheT = char '\'' >> return ApostropheT
|
||||||
rightParenT :: GenParser Char st Token
|
rightParenT :: GenParser Char st Token
|
||||||
rightParenT = char ')' >> return RightParenT
|
rightParenT = char ')' >> return RightParenT
|
||||||
|
|
||||||
|
backslashT :: GenParser Char st Token
|
||||||
|
backslashT = char '\\' >> return BackslashT
|
||||||
|
|
||||||
symbolT :: GenParser Char st Token
|
symbolT :: GenParser Char st Token
|
||||||
symbolT = do
|
symbolT = do
|
||||||
var <- map toLower <$> many1 (letter <|> oneOf "+-*/\\!|@#$~%&/=<>")
|
var <- map toLower <$> many1 (letter <|> oneOf "+-*/!|@#$~%&/=<>")
|
||||||
return $ SymbolT var
|
return $ SymbolT var
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
module Main where
|
module Main where
|
||||||
|
|
||||||
import Evaluator
|
import Evaluator
|
||||||
|
import Enviroment
|
||||||
import Parser
|
import Parser
|
||||||
import Control.Monad
|
import Control.Monad
|
||||||
import Data.Maybe
|
import Data.Maybe
|
||||||
|
|
|
@ -20,9 +20,18 @@ expressionFromTokensEOF = do
|
||||||
|
|
||||||
expressionFromTokens :: GenParser Token st Expr
|
expressionFromTokens :: GenParser Token st Expr
|
||||||
expressionFromTokens = do
|
expressionFromTokens = do
|
||||||
expr <- intE <|> quotedE <|> try setE <|> try nilE <|> try consE <|> varE <|> procedureE
|
expr <- intE <|> quotedE <|> try setE <|> try nilE <|> try consE <|> try lambdaE <|> varE <|> listE
|
||||||
return expr
|
return expr
|
||||||
|
|
||||||
|
listE :: GenParser Token st Expr
|
||||||
|
listE = do
|
||||||
|
_ <- parseLeftParenT
|
||||||
|
exprs <- many expressionFromTokens
|
||||||
|
_ <- parseRightParenT
|
||||||
|
return $ toCons exprs
|
||||||
|
where toCons [] = NilE
|
||||||
|
toCons (x:xs) = ConsE x (toCons xs)
|
||||||
|
|
||||||
intE :: GenParser Token st Expr
|
intE :: GenParser Token st Expr
|
||||||
intE = do
|
intE = do
|
||||||
(IntT num) <- parseIntT
|
(IntT num) <- parseIntT
|
||||||
|
@ -34,14 +43,6 @@ quotedE = do
|
||||||
expr <- expressionFromTokens
|
expr <- expressionFromTokens
|
||||||
return $ QuotedE expr
|
return $ QuotedE expr
|
||||||
|
|
||||||
procedureE :: GenParser Token st Expr
|
|
||||||
procedureE = do
|
|
||||||
_ <- parseLeftParenT
|
|
||||||
(SymbolT p) <- parseSymbolT
|
|
||||||
args <- many expressionFromTokens
|
|
||||||
_ <- parseRightParenT
|
|
||||||
return $ ProcedureE p args
|
|
||||||
|
|
||||||
consE :: GenParser Token st Expr
|
consE :: GenParser Token st Expr
|
||||||
consE = do
|
consE = do
|
||||||
_ <- parseLeftParenT
|
_ <- parseLeftParenT
|
||||||
|
@ -70,6 +71,14 @@ setE = do
|
||||||
_ <- parseRightParenT
|
_ <- parseRightParenT
|
||||||
return $ SetE var expr
|
return $ SetE var expr
|
||||||
|
|
||||||
|
lambdaE :: GenParser Token st Expr
|
||||||
|
lambdaE = do
|
||||||
|
_ <- parseBackslashT
|
||||||
|
(SymbolT arg) <- parseSymbolT
|
||||||
|
body <- expressionFromTokens
|
||||||
|
return $ LambdaE arg body
|
||||||
|
|
||||||
|
|
||||||
------------------------------------------------------------
|
------------------------------------------------------------
|
||||||
|
|
||||||
satisfyT :: (Stream s m a, Show a) => (a -> Bool) -> ParsecT s u m a
|
satisfyT :: (Stream s m a, Show a) => (a -> Bool) -> ParsecT s u m a
|
||||||
|
@ -77,6 +86,9 @@ satisfyT f = tokenPrim show
|
||||||
(\pos _ _ -> incSourceColumn pos 1)
|
(\pos _ _ -> incSourceColumn pos 1)
|
||||||
(\t -> if f t then Just t else Nothing)
|
(\t -> if f t then Just t else Nothing)
|
||||||
|
|
||||||
|
parseBackslashT :: GenParser Token st Token
|
||||||
|
parseBackslashT = satisfyT (== BackslashT)
|
||||||
|
|
||||||
parseLeftParenT :: GenParser Token st Token
|
parseLeftParenT :: GenParser Token st Token
|
||||||
parseLeftParenT = satisfyT (== LeftParenT)
|
parseLeftParenT = satisfyT (== LeftParenT)
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ module TokenType where
|
||||||
|
|
||||||
data Token = LeftParenT
|
data Token = LeftParenT
|
||||||
| RightParenT
|
| RightParenT
|
||||||
|
| BackslashT
|
||||||
| SymbolT String
|
| SymbolT String
|
||||||
| ApostropheT
|
| ApostropheT
|
||||||
| IntT Integer
|
| IntT Integer
|
||||||
|
|
Loading…
Reference in New Issue