Обращаясь к вашему вопросу в комментариях о том, как приступить к проверке и оценке типов.
Если вам не нужно делать вывод или полиморфизм, проверка типов довольно проста. Также проверка типов и оценка очень близко отражают друг друга в этих условиях.
Начните с определения монады с нужными вам функциями. Для проверки типов вам понадобится
- A типовая среда , то есть компонент
Reader
(Map Id LangType)
, чтобы отслеживать типы локальные переменные. - ошибка способность, например
Except
String
.
Таким образом, вы можете определить монаду как
type TypeEnv = Map.Map Id LangType
type TC = ReaderT TypeEnv (Except String)
И тогда ваша функция проверки типов будет выглядеть так:
typeCheck :: AST -> TC ()
(Мы возвращаем ()
, потому что нет ничего интересного в процессе проверки типов, кроме знания того, прошла ли программа.)
Это будет в значительной степени структурно индуктивно, например:
typeCheck (Program stmt) = -- typecheckStmt each statement*
typeCheckStmt :: Statement -> TC ()
typeCheckStmt (VariableDecl v type defn) = ...
typeCheckStmt (Assignment v exp) = do
Just t <- asks (Map.lookup v)
t' <- typeCheckExp exp
when (t /= t') $ throwError "Types do not match"
...
-- Return the type of a composite expression to use elsewhere
typeCheckExp :: Expression -> TC LangType
...
Потребуется немного изящества чтобы убедиться, что объявления переменных в списке операторов могут быть видны более поздними операторами в том же списке. Я оставлю это как загадку. (Подсказка: см. Функцию local
, чтобы обеспечить обновленную среду в области действия.)
Оценка - аналогичная история. Вы правы, что вам нужен тип значений времени выполнения. Без некоторой сообразительности, к которой вы, вероятно, не готовы (и которая может быть сомнительной, даже если бы вы были), на самом деле нет способа использовать LangType
в Value
, поэтому вы на правильном пути.
Вам понадобится монада, которая поддерживает отслеживание значений переменных и возможность делать все, что нужно вашему языку. Для начала я рекомендую
type Eval = StateT (Map Id Value) IO
и действую, как и прежде. Опять же, при обработке переменных областей и теней потребуется некоторая утонченность, и вам может потребоваться изменить тип среды или немного поработать с типом Value
, чтобы учесть эти тонкости, но важно продумать эти проблемы. Начните с простого, не пытайтесь осуществлять проверку типов и оценку сразу для всего языка.