본문으로 건너뛰기

컴파일러 지시어

'#'로 시작하는 키워드로 컴파일러에 일부 작업, 검사 또는 매개변수 변경을 지시하는 키워드입니다.

이러한 지시어는 함수 정의 내부가 아닌 가장 바깥쪽 수준에서만 사용할 수 있습니다.

#포함

include` 지시어를 사용하면 include 대신 파싱할 다른 FunC 소스 코드 파일을 포함할 수 있습니다.

구문은 #include "filename.fc";입니다. 파일은 자동으로 재포함 여부를 확인하며, 파일을 두 번 이상 포함하려는 시도는 기본적으로 무시되고 상세도 수준이 2 이상인 경우 경고가 표시됩니다.

포함된 파일을 파싱하는 동안 오류가 발생하면 추가로 체인에 포함된 각 파일의 위치 가 포함된 포함 스택이 인쇄됩니다.

#프라그마

'#pragma` 지시어는 언어 자체에서 전달하는 것 외에 컴파일러에 추가 정보를 제공하는 데 사용됩니다.

#프라그마 버전

버전 프래그마는 파일을 컴파일할 때 특정 버전의 FunC 컴파일러를 적용하는 데 사용됩니다.

버전은 세미버 형식, 즉 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 부분보다 낮지 않아야 합니다.

다른 비교 연산자(=, >, >=, <, <=)의 경우 짧은 형식은 생략된 부분에 0을 가정합니다:

  • >a.b>a.b.0과 동일합니다(따라서 a.b.0 버전과 일치하지 않습니다).
  • <=a<=a.0.0과 동일합니다(따라서 a.0.1 버전과 일치하지 않습니다).
  • a.b.0^a.b_와 같지 않습니다.

예를 들어 ^a.1.2a.1.3과 일치하지만 a.2.3이나 a.1.0과는 일치하지 않지만 ^a.1은 모두 일치합니다.

이 지시어는 여러 번 사용할 수 있으며, 컴파일러 버전은 제공된 모든 조건을 충족해야 합니다.

#pragma not-version

이 프라그마의 구문은 버전 프라그마와 동일하지만 조건이 충족되면 실패합니다.

예를 들어 문제가 있는 것으로 알려진 특정 버전을 블랙리스트에 추가하는 데 사용할 수 있습니다.

#프라그마 허용-후 수정

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_bit(8))는 초기 ds를 포함하는 x, f(ds, ds~load_bit(8))의 첫번째 인수는 초기 ds, 두번째는 8 비트의 ds를 포함하는 f가 될 것입니다.

프라그마 허용-후 수정`은 프라그마 이후의 코드에 대해서만 작동합니다.

#프라그마 컴퓨트-아스-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(값 인덱스 딕션 키_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은 프라그마 뒤에 오는 코드에만 작동합니다.