diff --git a/src/Eval.hs b/src/Eval.hs index bdb022a..6b5baa2 100644 --- a/src/Eval.hs +++ b/src/Eval.hs @@ -10,26 +10,26 @@ import qualified Data.Set as Set evalSingle :: Env -> TricuAST -> Env evalSingle env term - | SDef name [] body <- term = - if - | Map.member name env -> - errorWithoutStackTrace $ - "Error: Identifier '" ++ name ++ "' is already defined." - | otherwise -> - let res = evalAST env body - in Map.insert "!result" res (Map.insert name res env) - | SApp func arg <- term = - let res = apply (evalAST env func) (evalAST env arg) + | SDef name [] body <- term + = case Map.lookup name env of + Just existingValue + | existingValue == evalAST env body -> env + | otherwise -> errorWithoutStackTrace $ + "Unable to rebind immutable identifier: '" ++ name + Nothing -> + let res = evalAST env body + in Map.insert "!result" res (Map.insert name res env) + | SApp func arg <- term + = let res = apply (evalAST env func) (evalAST env arg) in Map.insert "!result" res env - | SVar name <- term = - case Map.lookup name env of - Just v -> - Map.insert "!result" v env + | SVar name <- term + = case Map.lookup name env of + Just v -> Map.insert "!result" v env Nothing -> errorWithoutStackTrace $ "Variable `" ++ name ++ "` not defined\n\ \This error should never occur here. Please report this as an issue." - | otherwise = - Map.insert "!result" (evalAST env term) env + | otherwise + = Map.insert "!result" (evalAST env term) env evalTricu :: Env -> [TricuAST] -> Env evalTricu env x = go env (reorderDefs env x)