Директивы компилятора
Эта страница переведена сообществом на русский язык, но нуждается в улучшениях. Если вы хотите принять участие в переводе свяжитесь с @alexgton.
Это ключевые слова, которые начинаются с # и предписывают компилятору выполнить некоторые действия, проверки или изменить параметры.
Эти директивы можно использовать только на самом внешнем уровне (не внутри определения какой-либо функции).
#include
Директива #include позволяет включить другой файл исходного кода FunC, который будет проанализирован вместо include.
Синтаксис: #include "filename.fc";. Файлы автоматически проверяются на повторное включение, и попытки включить
файл более одного раза будут игнорироваться по умолчанию с предупреждением, если уровень детализации не ниже 2.
Если во время анализа включенного файла происходит ошибка, дополнительно выводится стек включений с расположением каждого включенного файла в цепочке.
#pragma
Директива #pragma используется для предоставления компилятору дополнительной информации, выходящей за рамки того, что передает сам язык.
#pragma version
Pragma Version используется для принудительного применения определенной версии компилятора FunC при компиляции файла.
Версия указывается в формате semver, то есть a.b.c, где a — основная версия, b — дополнительная, а c — патч.
Разработчику доступно несколько операторов сравнения:
- a.b.c или =a.b.c — требует именно a.b.c версию компилятора
- >a.b.c — требует, чтобы версия компилятора была выше a.b.c,
- >=a.b.c — требует, чтобы версия компилятора была выше или равна a.b.c
- <a.b.c — требует, чтобы версия компилятора была ниже a.b.c,
- <=a.b.c — требует, чтобы версия компилятора была ниже или равна a.b.c
- ^a.b.c — требует, чтобы основная версия компилятора была равна части
a, а второстепенная — не ниж е частиb,- ^a.b — требует, чтобы основная версия компилятора была равна части a, а второстепенная — не ниже части b
- ^a — требует, чтобы основная версия компилятора была не ниже части a
Для других операторов сравнения (=, >, >=, <, <=) короткий формат предполагает нули в пропущенных частях, то есть:
- >a.b совпадает с >a.b.0 (и поэтому НЕ соответствует версии a.b.0)
- <=a совпадает с <=a.0.0 (и поэтому НЕ соответствует версии a.0.1)
- ^a.b.0 НЕ совпадает с ^a.b
Например, ^a.1.2 совпадает с a.1.3 но не a.2.3 или a.1.0, однако ^a.1 соответствует им всем.
Эту директиву можно использовать несколько раз; версия компилятора должна удовлетворять всем предоставленным условиям.
#pragma not-version
Синтаксис этой директивы такой же, как и у директивы version, но она завершается неудачей, если условие выполняется.
Например, ее можно использо вать для внесения в черный список определенной версии, известной своими проблемами.
#pragma allow-post-modification
funC v0.4.1
По умолчанию запрещено использовать переменную до ее изменения в том же выражении. Другими словами, выражение (x, y) = (ds, ds~load_uint(8)) не будет скомпилировано, в то время как (x, y) = (ds~load_uint(8), ds) допустимо.
Это правило может быть заменено #pragma allow-post-modification, которое позволяет изменять переменную после использования в массовых назначениях и вызовах функций; как обычно, вложенные выражения будут вычисляться слева направо: (x, y) = (ds, ds~load_bits(8)) приведет к x, содержащему начальную ds; f(ds, ds~load_bits(8)) первый аргумент f будет содержать начальную ds, а второй - 8 бит ds.
#pragma allow-post-modification работает только для кода после директивы.
#pragma compute-asm-ltr
funC v0.4.1
Объявления Asm могут перезаписывать порядок аргументов, например, в следующем выражении
idict_set_ref(ds~load_dict(), ds~load_uint(8), ds~load_uint(256), ds~load_ref())
порядок разбора будет: load_ref(), load_uint(256), load_dict() и load_uint(8) из-за следующего объявления asm (обратите внимание asm(value index dict key_len)):
cell idict_set_ref(cell dict, int key_len, int index, cell value) asm(value index dict key_len) "DICTISETREF";
Это поведение можно изменить на строгий порядок вычислений слева направо с помощью #pragma compute-asm-ltr
В результате в
#pragma compute-asm-ltr
...
idict_set_ref(ds~load_dict(), ds~load_uint(8), ds~load_uint(256), ds~load_ref());
порядок разбора будет load_dict(), load_uint(8), load_uint(256), load_ref() и все перестановки asm будут происходить после вычислений.
#pragma compute-asm-ltr работает только для кода после директивы.