看起来你有两种不同类型的输入:声明(创建新变量和函数)和表达式(计算事物)。
你应该首先定义一些数据结构,以便确定你要处理的是什么类型的东西。可以类似这样:
data Command = Define Definition | Calculate Expression | Quit
type Name = String
data Definition = DefVar Name Expression | DefFunc Name [Name] Expression
data Expression = Var Name | Add Expression Expression |
type Environment = [Definition]
首先,将其解析为
Command
(可能需要对其进行标记化和解析),然后决定对其采取什么操作。
表达式相对简单。假设您已经拥有了所有必需的定义(即
Environment
),然后只需查找任何变量或进行加法运算等操作。
定义有点棘手。一旦您决定创建新定义,就需要将其添加到环境中。如何准确地执行此操作取决于您如何迭代遍历行,但您需要将新环境从解释器传回到提取下一行并在其上运行解释器的事物。例如:
main :: IO ()
main = mainLoop emptyEnv
where
emptyEnv = []
mainLoop :: Environment -> IO ()
mainLoop env = do
str <- getLine
case parseCommnad str of
Nothing -> do
putStrLn "parse failed!"
mainLoop env
Just Quit -> do
return ()
Just (Define d) -> do
mainLoop (d : env)
Just (Calculate e) -> do
putStrLn (calc env e)
mainLoop env
parseCommand :: String -> Maybe Command
calc :: Environment -> Expression -> String
calc
需要在创建环境时查找相关信息,因此您可能还需要一个函数来查找给定
Name
对应的
Definition
(或者报告找不到该定义)。
一些其他的决策也需要您做出:
- 当有人试图重新定义变量时,我该怎么办?
- 如果我在函数的定义中使用了其中一个变量,那么该怎么办?我是在创建函数定义时还是在使用函数时计算它?
这些问题可能会影响上述程序的设计,但我会让您自行解决。
lex
,对吧? - Will Ness