Functions and Procedures
Functions and procedures, collectively referred to as routines, are subprograms (self-contained statement blocks) which perform a certain task based on a number of input parameters. When executed, a function returns a value while procedure does not.
mikroPascal PRO for AVR does not support inline routines.
Functions
A function is declared like this:
function function_name(parameter_list) : return_type; { local declarations } begin { function body } end;
function_name
represents a function’s name and can be any valid identifier. return_type
is a type of return value and can be any simple type or complex type. Within parentheses, parameter_list
is a formal parameter list very similar to variable declaration. In mikroPascal for AVR, parameters are always passed to a function by the value. To pass an argument by address, add the keyword var
ahead of identifier.
Local declarations
are optional declarations of variables and/or constants, local for the given function. Function body
is a sequence of statements to be executed upon calling the function.
Calling a function
A function is called by its name, with actual arguments placed in the same sequence as their matching formal parameters. The compiler is able to coerce mismatching arguments to the proper type according to implicit conversion rules. Upon a function call, all formal parameters are created as local objects initialized by values of actual arguments. Upon return from a function, a temporary object is created in the place of the call and it is initialized by the value of the function result. This means that function call as an operand in complex expression is treated as the function result.
In standard Pascal, a function_name
is automatically created local variable that can be used for returning a value of a function. mikroPascal PRO for AVR also allows you to use the automatically created local variable result
to assign the return value of a function if you find function name to be too ponderous. If the return value of a function is not defined the compiler will report an error.
Function calls are considered to be primary expressions and can be used in situations where expression is expected. A function call can also be a self-contained statement and in that case the return value is discarded.
Example
Here’s a simple function which calculates xn based on input parameters x
and n
(n > 0
):
function power(x, n : byte) : longint; var i : byte; begin i := 0; result := 1; if n > 0 then for i := 1 to n do result := result*x; end;
Now we could call it to calculate, say, 312:
tmp := power(3, 12);
Procedures
Procedure is declared like this:
procedure procedure_name(parameter_list); { local declarations } begin { procedure body } end;
procedure_name
represents a procedure’s name and can be any valid identifier. Within parentheses, parameter_list
is a formal parameter list very similar to variable declaration. In Pascal, parameters are always passed to a procedure by the value — to pass an argument by address, add the keyword var
ahead of identifier.
Local declarations
are optional declaration of variables and/or constants, local for the given procedure. Procedure body
is a sequence of statements to be executed upon calling the procedure.
Calling a procedure
A procedure is called by its name, with actual arguments placed in the same sequence as their matching formal parameters. The compiler is able to coerce mismatching arguments to the proper type according to implicit conversion rules. Upon procedure call, all formal parameters are created as local objects initialized by the values of actual arguments.
Procedure call is a self-contained statement.
Example
Here’s an example procedure which transforms its input time parameters, preparing them for output on Lcd:
procedure time_prep(var sec, min, hr : byte); begin sec := ((sec and $F0) shr 4)*10 + (sec and $0F); min := ((min and $F0) shr 4)*10 + (min and $0F); hr := ((hr and $F0) shr 4)*10 + (hr and $0F); end;
A function can return a complex type. Follow the example bellow to learn how to declare and use a function which returns a complex type.
Example:
This example shows how to declare a function which returns a complex type.
program Example; type TCircle = record // Record CenterX, CenterY: word; Radius: byte; end; var MyCircle: TCircle; // Global variable function DefineCircle(x, y: word; r: byte): TCircle; // DefineCircle function returns a Record begin result.CenterX := x; result.CenterY := y; result.Radius := r; end; begin MyCircle := DefineCircle(100, 200, 30); // Get a Record via function call MyCircle.CenterX := DefineCircle(100, 200, 30).CenterX + 20; // Access a Record field via function call // |-----------------------| |-----| // | | // Function returns TCircle Access to one field of TCircle end.
Forward declaration
A function can be declared without having it followed by it's implementation, by having it followed by the forward procedure. The effective implementation of that function must follow later in the unit. The function can be used after a forward declaration as if it had been implemented already. The following is an example of a forward declaration:
program Volume; var Volume : word; function First(a, b : word) : word; forward; function Second(c : word) : word; var tmp : word; begin tmp := First(2, 3); result := tmp * c; end; function First(a, b : word) : word; begin result := a * b; end; begin Volume := Second(4); end.
Functions reentrancy
Functions reentrancy is allowed. Remember that the AVR has memory limitations that can vary between MCUs.
What do you think about this topic ? Send us feedback!