function-declaration % funcdecl
: "subr" identifier arguments-list statement % subr
| "method" identifier arguments-list statement % method
| "ffi" "subr" type-keyword identifier arguments-list ";" % ffisubr
| "ffi" "method" type-keyword identifier arguments-list ";" % ffimethod
;
arguments-list % arglist
: "(" ")" % empty
| arguments-begin ")" % some
;
arguments-begin % args
: "(" type-keyword identifier % base
| arguments-begin "," type-keyword identifier % genrule
;
type-keyword % typekw
: "val" % val
| "ref" % ref
| "long" % long
| "ulong" % ulong
| "double" % double
;
For subr
and method
, the function so defined or declared is a non-FFI
function. The type of its parameters must be val
or ref
. Its return type
is implicitly val
and is not spelled out.
For ffisubr
and ffimethod
, the function so defined or declared is an FFI
function. The type of its parameters can be val
, ref
, long
, ulong
,
double
, and they're passed to the function as described in
12.2. Calling Conventions and Foreign Function Interface.
The return type MUST NOT be ref
as prohibited in
8.3. Subroutines and Methods.
For subr
and method
, function body MUST be either emptystmt
, in which
case the function-declaration
declares a function, or brace
, in which case
it defines a function. FFI functions (ffisubr
and ffimethod
) can be
declared, but cannot be defined in cxing.
The type and order of parameters between all declarations and the definition of the function MUST be consistent, furthermore, whether a function is a method or a subroutine, is or is not an FFI function MUST be consistent. The name of the parameters may be changed in the source code of a program. Depending on the context, this may provide the benefit of both explanative argument naming in declaration, and avoidance identifier collision in function definition when the argument is appropriately renamed.