Compare commits

...

2 Commits

Author SHA1 Message Date
Ivy d355a5db8a Added cons expression 2021-01-30 14:55:22 +01:00
Ivy 438db74148 Now vars 'set!' and 'nil' are treated as symbols in the lexer 2021-01-30 14:54:28 +01:00
7 changed files with 41 additions and 30 deletions

View File

@ -22,8 +22,7 @@ executable cherry
Parser, Parser,
TokenType, TokenType,
Lexer, Lexer,
Evaluator, Evaluator
ParserUtils
build-depends: base >= 4.7 && < 5, build-depends: base >= 4.7 && < 5,
containers, containers,

View File

@ -14,10 +14,11 @@ base = M.fromList [
] ]
eval :: Env -> Expr -> (Env, Expr) eval :: Env -> Expr -> (Env, Expr)
eval env (IntE x) = (env, IntE x) eval env i@(IntE x) = (env, i)
eval env (VarE v) = (M.insert v nExpr nEnv, nExpr) eval env (VarE v) = (M.insert v nExpr nEnv, nExpr)
where (nEnv, nExpr) = eval env $ env M.! v where (nEnv, nExpr) = eval env $ env M.! v
eval env (SetE v expr) = (M.insert v expr env, NilE) eval env (SetE v expr) = (M.insert v expr env, NilE)
eval env c@(ConsE _ _) = (env, c)
eval env NilE = (env, NilE) eval env NilE = (env, NilE)
--apply :: Proc -> Args -> Expr --apply :: Proc -> Args -> Expr

View File

@ -4,6 +4,7 @@ data Expr = IntE Integer
| VarE String | VarE String
| ProcedureE String [Expr] | ProcedureE String [Expr]
| SetE String Expr | SetE String Expr
| ConsE Expr Expr
| NilE deriving (Show) | NilE deriving (Show)
-- instance Show Expr where -- instance Show Expr where

View File

@ -1,7 +1,6 @@
module Lexer where module Lexer where
import Text.ParserCombinators.Parsec import Text.ParserCombinators.Parsec
import ParserUtils
import Data.Char import Data.Char
import TokenType import TokenType
@ -13,7 +12,7 @@ parseTokens = do
return tokns return tokns
anyLispToken :: GenParser Char st Token anyLispToken :: GenParser Char st Token
anyLispToken = leftParenT <|> rightParenT <|> try nilT <|> try setT <|> varT <|> intT anyLispToken = leftParenT <|> rightParenT <|> symbolT <|> intT
------------------------------------------------------------ ------------------------------------------------------------
@ -28,13 +27,7 @@ leftParenT = char '(' >> return LeftParenT
rightParenT :: GenParser Char st Token rightParenT :: GenParser Char st Token
rightParenT = char ')' >> return RightParenT rightParenT = char ')' >> return RightParenT
setT :: GenParser Char st Token symbolT :: GenParser Char st Token
setT = caseInsensitiveString "set!" >> return SetT symbolT = do
var <- map toLower <$> many1 (letter <|> oneOf "+-*/\\!|@#$~%&/=<>")
nilT :: GenParser Char st Token return $ SymbolT var
nilT = caseInsensitiveString "nil" >> return NilT
varT :: GenParser Char st Token
varT = do
var <- map toLower <$> many1 (letter <|> oneOf "+-*/!|@#$~%&/=<>")
return $ VarT var

View File

@ -20,7 +20,7 @@ expressionFromTokensEOF = do
expressionFromTokens :: GenParser Token st Expr expressionFromTokens :: GenParser Token st Expr
expressionFromTokens = do expressionFromTokens = do
expr <- intE <|> try defineE <|> try nilE <|> varE <|> procedureE expr <- intE <|> try setE <|> try nilE <|> try consE <|> varE <|> procedureE
return expr return expr
intE :: GenParser Token st Expr intE :: GenParser Token st Expr
@ -31,14 +31,23 @@ intE = do
procedureE :: GenParser Token st Expr procedureE :: GenParser Token st Expr
procedureE = do procedureE = do
_ <- parseLeftParenT _ <- parseLeftParenT
(VarT p) <- parseVarT (SymbolT p) <- parseSymbolT
args <- many expressionFromTokens args <- many expressionFromTokens
_ <- parseRightParenT _ <- parseRightParenT
return $ ProcedureE p args return $ ProcedureE p args
consE :: GenParser Token st Expr
consE = do
_ <- parseLeftParenT
_ <- parseConsT
expr1 <- expressionFromTokens
expr2 <- expressionFromTokens
_ <- parseRightParenT
return $ ConsE expr1 expr2
varE :: GenParser Token st Expr varE :: GenParser Token st Expr
varE = do varE = do
(VarT var) <- parseVarT (SymbolT var) <- parseSymbolT
return $ VarE var return $ VarE var
nilE :: GenParser Token st Expr nilE :: GenParser Token st Expr
@ -46,11 +55,11 @@ nilE = do
_ <- parseNilT _ <- parseNilT
return NilE return NilE
defineE :: GenParser Token st Expr setE :: GenParser Token st Expr
defineE = do setE = do
_ <- parseLeftParenT _ <- parseLeftParenT
_ <- parseSetT _ <- parseSetT
(VarT var) <- parseVarT (SymbolT var) <- parseSymbolT
expr <- expressionFromTokens expr <- expressionFromTokens
_ <- parseRightParenT _ <- parseRightParenT
return $ SetE var expr return $ SetE var expr
@ -69,15 +78,24 @@ parseRightParenT :: GenParser Token st Token
parseRightParenT = satisfyT (== RightParenT) parseRightParenT = satisfyT (== RightParenT)
parseSetT :: GenParser Token st Token parseSetT :: GenParser Token st Token
parseSetT = satisfyT (== SetT) parseSetT = satisfyT isSetT
where isSetT (SymbolT "set!") = True
isSetT _ = False
parseNilT :: GenParser Token st Token parseNilT :: GenParser Token st Token
parseNilT = satisfyT (== NilT) parseNilT = satisfyT isNilT
where isNilT (SymbolT "nil") = True
isNilT _ = False
parseVarT :: GenParser Token st Token parseConsT :: GenParser Token st Token
parseVarT = satisfyT isVarT parseConsT = satisfyT isConsT
where isVarT (VarT _) = True where isConsT (SymbolT "cons") = True
isVarT _ = False isConsT _ = False
parseSymbolT :: GenParser Token st Token
parseSymbolT = satisfyT isSymbolT
where isSymbolT (SymbolT _) = True
isSymbolT _ = False
parseIntT :: GenParser Token st Token parseIntT :: GenParser Token st Token
parseIntT = satisfyT isIntT parseIntT = satisfyT isIntT

View File

@ -1,3 +1,4 @@
-- UNUSED
module ParserUtils where module ParserUtils where
import Text.ParserCombinators.Parsec import Text.ParserCombinators.Parsec

View File

@ -2,8 +2,6 @@ module TokenType where
data Token = LeftParenT data Token = LeftParenT
| RightParenT | RightParenT
| SetT | SymbolT String
| VarT String
| IntT Integer | IntT Integer
| NilT
deriving (Show, Eq) deriving (Show, Eq)