宣言 (新しい変数と関数の作成) と式 (計算) の 2 種類の入力があるようです。
最初にいくつかのデータ構造を定義して、どのような種類の処理を行うかを決定する必要があります。何かのようなもの:
data Command = Define Definition | Calculate Expression | Quit
type Name = String
data Definition = DefVar Name Expression | DefFunc Name [Name] Expression
-- ^ alternatively, implement variables as zero-argument functions
-- and merge these cases
data Expression = Var Name | Add Expression Expression | -- ... other stuff
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
-- the real meat:
parseCommand :: String -> Maybe Command
calc :: Environment -> Expression -> String -- or Integer or some other appropriate type
calc
Definition
作業を進めながら、作成した環境内のものを検索する必要があるため、おそらく、指定されたものに対応するものを見つけるための関数も必要になるでしょうName
(または、1 つがないと不平を言います)。
その他の決定事項:
- 誰かが変数を再定義しようとした場合、どうすればよいですか?
- 関数の定義でこれらの変数の 1 つを使用するとどうなりますか? 関数定義は、作成時または使用時に評価しますか?
これらの質問は、上記のプログラムの設計に影響を与える可能性がありますが、どのように解決するかはあなたに任せます。