aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Eval.hs55
-rw-r--r--src/Helper.hs38
-rw-r--r--src/Parser.hs52
3 files changed, 86 insertions, 59 deletions
diff --git a/src/Eval.hs b/src/Eval.hs
index fdaa2cb..eea56a8 100644
--- a/src/Eval.hs
+++ b/src/Eval.hs
@@ -55,14 +55,17 @@ loadFile path conf = do
(conf { isRepl = False, evalPaths = (path : (evalPaths conf)) })
)
-evalVar :: String -> Environment -> Program (Failable Expression)
-evalVar var (Environment sub) = state $ \env@(Environment e) ->
+evalIdent :: String -> Environment -> Program (Failable Expression)
+evalIdent ident (Environment sub) = state $ \env@(Environment e) ->
let lookup' name env' = case lookup name env' of
- Nothing -> Left $ UndeclaredFunction var
+ Nothing -> Left $ UndeclaredIdentifier name
Just x -> Right x
- in case lookup' var (map fst sub) of -- search in sub env
+ in case lookup' ident (map fst sub) of -- search in sub env
s@(Right _) -> (s, env)
- _ -> (lookup' var (map fst e), env) -- search in global env
+ _ -> (lookup' ident (map fst e), env) -- search in global env
+
+evalFun :: Identifier -> Environment -> Program (Failable Expression)
+evalFun = evalIdent . functionName
evalAbs :: Expression -> Environment -> Program (Failable Expression)
evalAbs e sub = evalExp e sub >>= pure . fmap Abstraction
@@ -78,28 +81,27 @@ evalApp f g sub =
evalInfix
:: Expression
- -> String
+ -> Identifier
-> Expression
-> Environment
-> Program (Failable Expression)
-evalInfix le i re =
- evalExp $ Application (Application (Variable $ "(" ++ i ++ ")") le) re
+evalInfix le i re = evalExp $ Application (Application (Function i) le) re
evalPrefix
- :: String -> Expression -> Environment -> Program (Failable Expression)
-evalPrefix p e = evalExp $ Application (Variable $ p ++ "(") e
+ :: Identifier -> Expression -> Environment -> Program (Failable Expression)
+evalPrefix p e = evalExp $ Application (Function p) e
evalExp :: Expression -> Environment -> Program (Failable Expression)
evalExp idx@(Bruijn _ ) = const $ pure $ Right idx
-evalExp ( Variable var) = evalVar var
+evalExp ( Function fun) = evalFun fun
evalExp ( Abstraction e ) = evalAbs e
evalExp ( Application f g) = evalApp f g
evalExp ( Infix le i re ) = evalInfix le i re
evalExp ( Prefix p e ) = evalPrefix p e
evalDefine
- :: String -> Expression -> Environment -> Program (Failable Expression)
-evalDefine name e sub =
+ :: Identifier -> Expression -> Environment -> Program (Failable Expression)
+evalDefine i e sub =
evalExp e sub
>>= (\case
Left e' -> pure $ Left e'
@@ -110,6 +112,7 @@ evalDefine name e sub =
)
>> pure (Right f)
)
+ where name = functionName i
evalTest
:: Expression -> Expression -> Environment -> Program (Failable Instruction)
@@ -136,14 +139,14 @@ evalInstruction
:: Instruction -> EnvState -> (EnvState -> IO EnvState) -> IO EnvState
evalInstruction (ContextualInstruction instr inp) s@(EnvState env conf) rec =
case instr of
- Define name e sub -> do
+ Define i e sub -> do
EnvState subEnv _ <- evalSubEnv sub s
- (res, env') <- pure $ evalDefine name e subEnv `runState` env
+ (res, env') <- pure $ evalDefine i e subEnv `runState` env
case res of
Left err ->
print (ContextualError err $ Context inp $ nicePath conf) >> pure s -- don't continue
Right _
- | isRepl conf -> (putStrLn $ name <> " = " <> show e)
+ | isRepl conf -> (putStrLn $ show i <> " = " <> show e)
>> return (EnvState env' conf)
| otherwise -> rec $ EnvState env' conf
Input path -> do
@@ -186,9 +189,9 @@ evalInstruction (ContextualInstruction instr inp) s@(EnvState env conf) rec =
<> (show e')
<> "\n*> "
<> (show reduced)
- <> " "
+ <> "\n?> "
<> (humanifyExpression reduced)
- <> " "
+ <> "\n#> "
<> (matchingFunctions reduced env)
where reduced = reduce e'
)
@@ -242,7 +245,7 @@ evalFileConf path wr conv conf = do
arg <- encodeStdin
case evalMainFunc env arg of
Nothing ->
- print $ ContextualError (UndeclaredFunction "main") (Context "" path)
+ print $ ContextualError (UndeclaredIdentifier "main") (Context "" path)
Just e -> wr $ conv e
defaultConf :: String -> EvalConf
@@ -253,12 +256,12 @@ defaultConf path = EvalConf { isRepl = False
, evalPaths = []
}
-reduceFile :: String -> (a -> IO ()) -> (Expression -> a) -> IO ()
-reduceFile path wr conv = do
+dumpFile :: String -> (a -> IO ()) -> (Expression -> a) -> IO ()
+dumpFile path wr conv = do
EnvState (Environment env) _ <- loadFile path (defaultConf path)
case lookup "main" (map fst env) of
Nothing ->
- print $ ContextualError (UndeclaredFunction "main") (Context "" path)
+ print $ ContextualError (UndeclaredIdentifier "main") (Context "" path)
Just e -> wr $ conv e
evalFile :: String -> (a -> IO ()) -> (Expression -> a) -> IO ()
@@ -345,10 +348,10 @@ evalMain = do
args <- getArgs
case args of
[] -> runRepl
- ["-b", path] -> reduceFile path
- (Byte.putStr . Bit.realizeBitStringStrict)
- (toBitString . toBinary)
- ["-B", path] -> reduceFile path putStrLn toBinary
+ ["-b", path] -> dumpFile path
+ (Byte.putStr . Bit.realizeBitStringStrict)
+ (toBitString . toBinary)
+ ["-B", path] -> dumpFile path putStrLn toBinary
["-e", path] ->
exec path (try . Byte.readFile) (fromBitString . Bit.bitString)
["-E", path] -> exec path (try . readFile) id
diff --git a/src/Helper.hs b/src/Helper.hs
index 418735e..d7064c1 100644
--- a/src/Helper.hs
+++ b/src/Helper.hs
@@ -34,13 +34,13 @@ printContext (Context inp path) = p $ lines inp
errPrefix :: String
errPrefix = "\ESC[41mERROR\ESC[0m "
-data Error = SyntaxError String | UndeclaredFunction String | InvalidIndex Int | FailedTest Expression Expression Expression Expression | ContextualError Error Context | ImportError String
+data Error = SyntaxError String | UndeclaredIdentifier String | InvalidIndex Int | FailedTest Expression Expression Expression Expression | ContextualError Error Context | ImportError String
instance Show Error where
show (ContextualError err ctx) = show err <> "\n" <> (printContext ctx)
show (SyntaxError err) =
errPrefix <> "invalid syntax\n\ESC[45mnear\ESC[0m " <> err
- show (UndeclaredFunction func) =
- errPrefix <> "undeclared function " <> show func
+ show (UndeclaredIdentifier ident) =
+ errPrefix <> "undeclared identifier " <> ident
show (InvalidIndex err) = errPrefix <> "invalid index " <> show err
show (FailedTest exp1 exp2 red1 red2) =
errPrefix
@@ -89,19 +89,35 @@ printBundle ParseErrorBundle {..} =
<> pointer
<> "\n"
-data Expression = Bruijn Int | Variable String | Abstraction Expression | Application Expression Expression | Infix Expression String Expression | Prefix String Expression
+data Identifier = NormalFunction String | InfixFunction String | PrefixFunction String | NamespacedFunction String Identifier
deriving (Ord, Eq)
-data Instruction = Define String Expression [Instruction] | Evaluate Expression | Comment | Input String | Import String String | Test Expression Expression | ContextualInstruction Instruction String
+functionName :: Identifier -> String
+functionName = \case
+ NormalFunction f -> f
+ InfixFunction i -> "(" <> i <> ")"
+ PrefixFunction p -> p <> "("
+ NamespacedFunction n f -> n <> functionName f
+instance Show Identifier where
+ show ident = "\ESC[95m" <> functionName ident <> "\ESC[0m"
+data Expression = Bruijn Int | Function Identifier | Abstraction Expression | Application Expression Expression | Infix Expression Identifier Expression | Prefix Identifier Expression
+ deriving (Ord, Eq)
+data Instruction = Define Identifier Expression [Instruction] | Evaluate Expression | Comment | Input String | Import String String | Test Expression Expression | ContextualInstruction Instruction String
deriving (Show)
instance Show Expression where
- show (Bruijn x ) = "\ESC[91m" <> show x <> "\ESC[0m"
- show (Variable var) = "\ESC[95m" <> var <> "\ESC[0m"
- show (Abstraction e ) = "\ESC[36m[\ESC[0m" <> show e <> "\ESC[36m]\ESC[0m"
+ show (Bruijn x ) = "\ESC[91m" <> show x <> "\ESC[0m"
+ show (Function ident) = "\ESC[95m" <> show ident <> "\ESC[0m"
+ show (Abstraction e ) = "\ESC[36m[\ESC[0m" <> show e <> "\ESC[36m]\ESC[0m"
show (Application exp1 exp2) =
"\ESC[33m(\ESC[0m" <> show exp1 <> " " <> show exp2 <> "\ESC[33m)\ESC[0m"
show (Infix le i re) =
- show le <> " \ESC[95m(" <> i <> ")" <> "\ESC[0m " <> show re
- show (Prefix p e) = "\ESC[95m" <> p <> show e <> "\ESC[0m"
+ "\ESC[33m(\ESC[0m"
+ <> show i
+ <> " "
+ <> show le
+ <> " "
+ <> show re
+ <> "\ESC[33m)\ESC[0m"
+ show (Prefix p e) = show p <> " " <> show e
type EnvDef = (String, Expression)
data EvalConf = EvalConf
@@ -193,7 +209,7 @@ maybeHumanifyExpression e = ternaryToDecimal e <|> decodeStdout e
humanifyExpression :: Expression -> String
humanifyExpression e = case maybeHumanifyExpression e of
- Nothing -> ""
+ Nothing -> show e
Just h -> h
---
diff --git a/src/Parser.hs b/src/Parser.hs
index c23130d..a27c6a2 100644
--- a/src/Parser.hs
+++ b/src/Parser.hs
@@ -17,36 +17,44 @@ type Parser = Parsec Void String
sc :: Parser ()
sc = void $ char ' '
+-- "'" can't be in special chars because of 'c' char notation and prefixation
specialChar :: Parser Char
specialChar = oneOf "!?*@.:;+-_#$%^&<>/\\|~="
+-- lower or upper
+greekLetter :: Parser Char
+greekLetter = satisfy isGreek
+ where isGreek c = ('Α' <= c && c <= 'Ω') || ('α' <= c && c <= 'ω')
+
infixOperator :: Parser String
-infixOperator = some specialChar
+infixOperator =
+ some specialChar <|> ((++) <$> dottedNamespace <*> infixOperator)
prefixOperator :: Parser String
-prefixOperator = some specialChar
+prefixOperator = infixOperator
--- def identifier disallows the import prefix dots
-defIdentifier :: Parser String
+defIdentifier :: Parser Identifier
defIdentifier =
- ((:) <$> letterChar <*> many (alphaNumChar <|> specialChar <|> char '\''))
- <|> ((\l i r -> [l] ++ i ++ [r]) <$> char '(' <*> infixOperator <*> char ')'
+ ( NormalFunction
+ <$> ((:) <$> (lowerChar <|> greekLetter) <*> many
+ (alphaNumChar <|> specialChar <|> char '\'')
)
- <|> ((\p i -> p ++ [i]) <$> prefixOperator <*> char '(')
+ )
+ <|> (InfixFunction <$> (char '(' *> infixOperator <* char ')'))
+ <|> (PrefixFunction <$> (prefixOperator <* char '('))
<?> "defining identifier"
--- TODO: write as extension to defIdentifier
-identifier :: Parser String
+identifier :: Parser Identifier
identifier =
- ((:) <$> letterChar <*> many (alphaNumChar <|> specialChar <|> oneOf ".\'"))
- <|> ((\l i r -> [l] ++ i ++ [r]) <$> char '(' <*> infixOperator <*> char ')'
- )
- <|> ((\p i -> p ++ [i]) <$> prefixOperator <*> char '(')
+ try (NamespacedFunction <$> dottedNamespace <*> defIdentifier)
+ <|> defIdentifier
<?> "identifier"
namespace :: Parser String
-namespace =
- ((:) <$> upperChar <*> many letterChar) <|> string "." <?> "namespace"
+namespace = (:) <$> upperChar <*> many letterChar <?> "namespace"
+
+dottedNamespace :: Parser String
+dottedNamespace = (\n d -> n ++ [d]) <$> namespace <*> char '.'
parens :: Parser a -> Parser a
parens = between (string "(") (string ")")
@@ -107,10 +115,10 @@ parseChar = do
<?> "quoted char"
pure $ charToExpression ch
-parseVariable :: Parser Expression
-parseVariable = do
+parseFunction :: Parser Expression
+parseFunction = do
var <- identifier
- pure $ Variable var
+ pure $ Function var
parseInfix :: Parser Expression
parseInfix = do
@@ -119,13 +127,13 @@ parseInfix = do
i <- infixOperator
sc
e2 <- parseSingleton
- pure $ Infix e1 i e2
+ pure $ Infix e1 (InfixFunction i) e2
parsePrefix :: Parser Expression
parsePrefix = do
p <- prefixOperator
e <- parseSingleton
- pure $ Prefix p e
+ pure $ Prefix (PrefixFunction p) e
parseSingleton :: Parser Expression
parseSingleton =
@@ -134,7 +142,7 @@ parseSingleton =
<|> parseString
<|> parseChar
<|> parseAbstraction
- <|> try parseVariable
+ <|> try parseFunction
<|> try (parens parseInfix <?> "enclosed infix expr")
<|> (parens parseApplication <?> "enclosed application")
<|> parsePrefix
@@ -180,7 +188,7 @@ parseImport = do
inp <- getInput
_ <- string ":import " <?> "import instruction"
path <- importPath
- ns <- (try $ sc *> namespace) <|> (eof >> return "")
+ ns <- (try $ (sc *> (namespace <|> string "."))) <|> (eof >> return "")
pure $ ContextualInstruction (Import (path ++ ".bruijn") ns) inp
parseInput :: Parser Instruction