본문으로 건너뛰기

리터럴과 식별자

숫자 리터럴

FunC는 10진수와 16진수 정수 리터럴을 허용합니다(앞에 오는 0들도 허용).

예를 들어, 0, 123, -17, 00987, 0xef, 0xEF, 0x0, -0xfFAb, 0x0001, -0, -0x0는 유효한 숫자 리터럴입니다.

문자열 리터럴

FunC의 문자열은 "this is a string"처럼 큰따옴표 "로 감싸집니다. \n과 같은 특수 문자나 여러 줄 문자열은 지원되지 않습니다. 선택적으로, 문자열 리터럴은 "string"u와 같이 그 뒤에 타입을 지정할 수 있습니다.

다음과 같은 문자열 타입들이 지원됩니다:

  • 타입 없음—asm 함수 정의와 ASCII 문자열로 슬라이스 상수를 정의하는 데 사용됨
  • s—내용으로 원시 슬라이스 상수를 정의 (16진수로 인코딩되고 선택적으로 비트 패딩됨)
  • a—지정된 주소로부터 MsgAddressInt 구조를 포함하는 슬라이스 상수를 생성
  • u—제공된 ASCII 문자열의 16진수 값에 해당하는 int 상수를 생성
  • h—문자열의 SHA256 해시의 처음 32비트인 int 상수를 생성
  • H—문자열의 SHA256 해시의 모든 256비트인 int 상수를 생성
  • c—문자열의 crc32 값인 int 상수를 생성

예를 들어, 다음 값들은 해당하는 상수로 변환됩니다:

  • "string"x{737472696e67} 슬라이스 상수가 됨
  • "abcdef"sx{abcdef} 슬라이스 상수가 됨
  • "Ef8zMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM0vF"ax{9FE6666666666666666666666666666666666666666666666666666666666666667_} 슬라이스 상수가 됨 (addr_std$10 anycast:none$0 workchain_id:int8=0xFF address:bits256=0x33...33)
  • "NstK"u0x4e73744b int 상수가 됨
  • "transfer(slice, int)"h0x7a62e8a8 int 상수가 됨
  • "transfer(slice, int)"H0x7a62e8a8ebac41bd6de16c65e7be363bc2d2cbc6a0873778dead4795c13db979 int 상수가 됨
  • "transfer(slice, int)"c2235694568 int 상수가 됨

식별자

FunC는 매우 넓은 범위의 식별자(함수와 변수 이름)를 허용합니다. 즉, 특수 문자 ;, ,, (, ), (공백이나 탭), ~, .를 포함하지 않고, 주석이나 문자열 리터럴(")로 시작하지 않으며, 숫자 리터럴이 아니고, 밑줄 _이 아니며, 키워드가 아닌 모든 (한 줄) 문자열은 유효한 식별자입니다(`로 시작하는 경우 같은 `로 끝나야 하고 이 두 개를 제외한 다른 `를 포함할 수 없다는 예외가 있습니다).

또한, 함수 정의에서 함수 이름은 . 또는 ~로 시작할 수 있습니다.

예를 들어, 다음은 유효한 식별자들입니다:

  • query, query', query''
  • elem0, elem1, elem2
  • CHECK
  • _internal_value
  • message_found?
  • get_pubkeys&signatures
  • dict::udict_set_builder
  • _+_ (전위 표기법에서 (int, int) -> int 타입의 표준 덧셈 연산자, 이미 정의되어 있지만)
  • fatal!

변수 이름 끝의 '는 관례적으로 기존 값의 수정된 버전이 도입될 때 사용됩니다. 예를 들어, 해시맵 조작을 위한 거의 모든 수정 내장 프리미티브들(~ 접두사가 있는 것들 제외)은 해시맵을 받아서 필요한 경우 다른 데이터와 함께 새로운 버전의 해시맵을 반환합니다. 이러한 값들은 같은 이름에 '를 붙여 명명하는 것이 편리합니다.

접미사 ?는 보통 불리언 변수(TVM은 내장 불 타입을 가지고 있지 않습니다; 불은 정수로 표현됩니다: 0은 거짓이고 -1은 참)나 보통 연산의 성공을 나타내는 플래그를 반환하는 함수(stdlib.fcudict_get?와 같은)에 사용됩니다.

다음은 유효하지 않은 식별자들입니다:

  • take(first)Entry
  • "not_a_string
  • msg.sender
  • send_message,then_terminate
  • _

더 특이한 유효한 식별자의 예시들:

  • 123validname
  • 2+2=2*2
  • -alsovalidname
  • 0xefefefhahaha
  • {hehehe}
  • pa{--}in"`aaa`"

다음도 유효하지 않은 식별자들입니다:

  • pa;;in"`aaa`" (;가 금지되어 있기 때문에)
  • {-aaa-}
  • aa(bb
  • 123 (이는 숫자입니다)

또한, FunC는 백틱 `으로 감싸지는 특별한 종류의 식별자를 가지고 있습니다. 따옴표 안에서는 \n과 따옴표 자체를 제외한 모든 문자가 허용됩니다.

예를 들어, `I'm a variable too``any symbols ; ~ () are allowed here...`와 마찬가지로 유효한 식별자입니다.

상수

FunC는 컴파일 중에 대체되고 미리 계산되는 컴파일 타임 상수를 정의할 수 있게 합니다.

상수는 const optional-type identifier = value-or-expression;로 정의됩니다.

optional-type은 특정 상수 타입을 강제하고 더 나은 가독성을 위해 사용될 수 있습니다.

현재로서는 intslice 타입이 지원됩니다.

value-or-expression은 리터럴이나 리터럴과 상수의 미리 계산 가능한 표현식일 수 있습니다.

예를 들어, 상수는 다음과 같이 정의될 수 있습니다:

  • const int101 = 101;은 숫자 리터럴 101과 동등한 int101 상수를 정의함
  • const str1 = "const1", str2 = "aabbcc"s;는 해당하는 문자열과 같은 두 상수를 정의함
  • const int int240 = ((int1 + int2) * 10) << 3;는 계산 결과와 같은 int240 상수를 정의함
  • const slice str2r = str2;str2 상수의 값과 같은 str2r 상수를 정의함

숫자 상수는 컴파일 중에 대체되므로, 컴파일 중에 수행되는 모든 최적화와 사전 계산이 성공적으로 수행됩니다(인라인 asm PUSHINT를 통한 옛 방식의 상수 정의와는 달리).