Директивы компилятора
Эта страница переведена сообществом на русский язык, но нуждается в улучшениях. Если вы хотите принять участие в переводе свяжитесь с @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
работает только для кода после директивы.