Статическая проверка типа обычно выполняется в AST, поэтому она может происходить либо между 1 и 2, либо как часть 2 (это означает, что IR-генератор вызывает функции из средства проверки типов всякий раз, когда обрабатывает AST-узел - конечно,ИК-генератор и средство проверки типов должны по-прежнему находиться в разных модулях / файлах.)
Теоретически вы можете выполнять проверку типа на ИК, но это обычно приводит к, по крайней мере, одной из следующих проблем:
- IR не содержит достаточно информации, чтобы по-прежнему фиксировать все ошибки, которые вы хотите.
- IR не содержит достаточно информации для получения наилучших сообщений об ошибках во всех случаях.В качестве примера рассмотрим, что IR представляет доступ к массиву и арифметику указателя с использованием тех же инструкций.Теперь вы хотите создать ошибку для доступа к массиву с индексом с плавающей запятой.Если сообщение «Значения с плавающей запятой не разрешены как операнды для арифметики указателей», это может привести к путанице, если код не содержит арифметику указателей.Требование, чтобы пользователь знал, что обращения к массивам представлены в виде арифметики указателей, чтобы иметь смысл сообщения об ошибке, не очень удобно для пользователя.
- Вы добавляете большое количество дополнительной информации в IR для целей типапроверка, делая IR более сложным и громоздким, но все, что вы получили от этого, - это возможность обрабатывать IR так же, как и AST, без получения каких-либо преимуществ.
Обычноработа над IR вместо AST означает, что вам не нужно обрабатывать столько случаев (именно потому, что IR представляет разные вещи с использованием одних и тех же инструкций).Это главное преимущество.Но если вы затем перепрыгиваете через дополнительные обручи, чтобы снова иметь возможность обрабатывать случаи по-другому, вы могли бы также использовать AST в первую очередь.
Так что проверка типов в AST type обычно предпочтительнее.GHC (основной компилятор Haskell) выполняет проверку типа AST.
¹ Или, по крайней мере, что-то очень близкое к AST - может быть, например, представление между AST и конечным IR, что упрощает вещив некоторых случаях (например, удаление выравнивающих вложенных выражений), без потери информации, относящейся к проверке типов.
Динамическая проверка типов происходит во время выполнения.Код, который выполняет эти динамические проверки типов, является либо частью интерпретатора (если имеется интерпретатор), либо вставляется генератором кода.
Ruby выполняет проверку типов в интерпретаторе.