Функции

Материал из Compilers Wiki
Перейти к: навигация, поиск
FUNCDEF :=
    ['export'] 'function' [ABITY] $IDENT '(' (PARAM), ')'
    '{'
       BLOCK+
    '}'
PARAM :=
    ABITY %IDENT  # Regular parameter
  | 'env' %IDENT  # Environment parameter (first)
  | '...'         # Variadic marker (last)
ABITY := BASETY | :IDENT

Объявления функций содержат фактический код для размещения в скомпилированном файле. Они определяются глобальным символом, содержащим указатель на код функции. Этот указатель может использоваться в инструкциях вызова или храниться в памяти.

Function definitions contain the actual code to emit in the compiled file. They define a global symbol that contains a pointer to the function code. This pointer can be used in call instructions or stored in memory.

Тип, записанный прямо перед именем функции, является возвращаемым типом функции. Все возвращаемые значения этой функции должны иметь этот же возвращаемый тип. Если возвращаемый тип отсутствует, функция не может вернуть какое-либо значение.

The type given right before the function name is the return type of the function. All return values of this function must have this return type. If the return type is missing, the function cannot return any value.

Список параметров представляет собой список временных переменных, разделенных запятыми, с указанием их типов. Типы используются для правильной реализации совместимости Cи. Когда тип аргумента является составным, указатель на него передается при вызове функции. В приведенном ниже примере мы должны использовать команду load для получения значения первого (и единственного) элемента структуры.

The parameter list is a comma separated list of temporary names prefixed by types. The types are used to correctly implement C compatibility. When an argument has an aggregate type, a pointer to the aggregate is passed by the caller. In the example below, we have to use a load instruction to get the value of the first (and only) member of the struct.
type :one = { w }
function w $getone(:one %p) {
@start
        %val =w loadw %p
        ret %val
}

Если список параметров заканчивается на ..., функция является вариативной: она может принимать переменное количество аргументов. Для доступа к дополнительным аргументам, подаваемым при вызове функции, используйте инструкции largeart и vaarg, описанные в разделе Вариативность.

If the parameter list ends with ..., the function is a variadic function: it can accept a variable number of arguments. To access the extra arguments provided by the caller, use the vastart and vaarg instructions described in the Variadic section.

Вообще, список параметров может начинаться с параметра среды env %e. Этот специальный параметр является 64-битной целочисленной переменной (то есть типа l - long). Если функция не использует свой параметр среды, вызовы функции могут ее опустить. Этот параметр невидим для вызова в Cи: например, функция...

Optionally, the parameter list can start with an environment parameter env %e. This special parameter is a 64-bit integer temporary (i.e., of type l). If the function does not use its environment parameter, callers can safely omit it. This parameter is invisible to a C caller: for example, the function
export function w $add(env %e, w %a, w %b) {
@start
        %c =w add %a, %b
        ret %c
}

... должна быть предоставлена на Cи как int add (int, int). Предполагаемое использование этой функции - передать указатель окружения, сохраняя при этом совместимость с Cи. Раздел «Инструкция Call» объясняет, как передать параметр среды.

must be given the C prototype int add(int, int). The intended use of this feature is to pass the environment pointer of closures while retaining a very good compatibility with C. The Call section explains how to pass an environment parameter.

Поскольку глобальные символы определены взаимно рекурсивно, нет необходимости в объявлениях функций: функция может быть использована до своего объявления. Аналогично, функции из других модулей могут использоваться без предварительного объявления. Вся информация о типе указана в статье об инструкциях вызова.

Since global symbols are defined mutually recursive, there is no need for function declarations: a function can be referenced before its definition. Similarly, functions from other modules can be used without previous declaration. All the type information is provided in the call instructions.

Синтаксис и семантика для тела функций описаны в разделах «Блоки» и «Переходы».

The syntax and semantics for the body of functions are described in the Control section.



Источник: c9x.me