Declaring a user function

!function

Declare a user function


Syntax

!function func_id ([arg1, arg2,…]) {
    [local variables]
    statements
    [return [value]]
}

Declare a user function. A function is a piece of code terminated with a return statement, which may be sent arguments and may return a value. Sculptor already includes a wide library of pre-defined functions. The !function structure permits the programmer to create new functions, which may be specific to a program or may be located in include file function libraries.

It is not necessary to declare the type of a function.

func_id

The function name, or identifier. Normal identifier naming rules apply.

([arg1, arg2,…])

Arguments for internal use within the function. The arguments are separated by commas. An argument may be a constant, an expression involving constants, operators and field names, or an object identifier. It is not necessary to declare the arguments as temporary fields or to specify their type. The argument values are sent in calls to the function. See Arguments.

[local variables]

Local variables may be defined within the function, by means of the !temp declaration. Temporary fields defined within a function may only be used within that function. They may bear the same name as temporary fields declared in other functions, or as globally declared temporary fields, without conflict.

Local variables can be qualified in the function code using the prefix “local.” This is never strictly necessary, since a local variable always takes precedence over a global variable with the same name. However, the qualifier helps to make the code more readable.

To specify a global variable in preference to a local variable with the same name, use the qualifier “tmp.” The tmp group includes all global variables that are not part of a !record structure.

statements

A block of Sculptor code.

return [value ]

Functions may return a value. This is optional, and only one value may be returned. The value follows the return statement. It may be enclosed in brackets, but these are optional, unless required to force a particular order of operations in an expression. The return value may be a constant, an expression involving constants, operators and field names, or an object identifier. If a function returns without specifying a return value, the null object is returned. This equates to 0 if assigned to a field.

If the return value is a global object, the object_id is returned and the return value may be used where an object_id is valid. If the return value is a local object (!temp), its value is returned, since the object will not exist once the function has returned.

EXAMPLES:

return (tmp.Value)
return 1
return(val1 * val2)
return Window3

If no value is returned, the return statement at the end of a function can be omitted. A return statement, with or without a value, can be used within the function to terminate it at any point.


Arguments

Arguments may be sent to the function code from the function call.

A call to the function should pass appropriate arguments, contained in brackets after the func_id. An object that is sent as an argument may be updated by the function. Arguments may be any of the following:

1

Constants.

2

Expressions. Any attempt within a function to update a parameter which was passed as an expression or constant is ignored at run time.

3

Objects. This includes any object type supported by Sculptor, such as field, textbox, button and window identifiers. The argument is passed by reference, which means that the function directly references the object. The function may update the object. Note that if a file_id is used as an argument, and the index = clause is used inside the function, the original file_id, rather than the argument name used in the !function definition, must be used.

Note that if a field_id is passed as an argument to a function, the function references this argument as a pointer to the field, rather than using the field’s current value. The following example clarifies this:

!temp Number,,i1
    tmp.Number = 10
    Process(tmp.Number)
    Process(tmp.Number * 1)

!function Process(Num) { ...
}

In the first call to the function Process(), the field_id is sent as an argument. The function references the field, which may be updated during the function.

In the second call to the function, the argument is an expression. This forces the current value of “tmp.Number” to be sent as the argument. The argument is a constant, and cannot be updated by the function.

Clearly, only certain arguments and return values make sense within any given function - to send a window identifier or alpha field to a mathematical function which is expecting a numerical value, or to send a number to a function which is expecting a textbox identifier, is completely meaningless. The code will compile, but the operation will be ignored at run time. If the program is running in debug mode an error may be generated and, depending on the value in sys.Warn, may generate a run-time error message in the debug window.

Since Sculptor version 6.2.0 is possible to have a runtime reference to access all the elements of a !record or !file received as an argument, e.g:

!record DataRec[2] {
    !record SubRec[2] {
        num,,i4[2]
    }
}

fTestDataRec(DataRec)
exit

!function fTestDataRec(arg1) {
    arg1[1].SubRec[1].num[1] = 1111
}

NOTES

  • In the function definition, a pair of brackets must follow the function identifier, even if the function does not take arguments. In such cases the brackets are empty.

  • Be careful not to omit the braces. If a function has no arguments and the braces are omitted, the program will compile successfully but the function will not work.


EXAMPLES

Cost = Multiply(stk.level, stk.price)

!function Multiply(var1, var2) {
!temp Value,,i4

     Value = var1 * var1
     return Value
}
pp_namecode = MakeCode(pp_name, pp_ref, 1900)

!function MakeCode(var1, var2, var3) {
!temp NameCode,,a12
!temp Alpha,,a10

     setstr(NameCode, 1, 5, var1)
     Alpha = var2 * var3
     setstr(NameCode, 6, 7, Alpha)
     return NameCode
}
!define _BSLASH "\\"
!define _FSLASH "/"
!define _QM "\""

!function Quote(OldString) {
!temp String,,a255
!temp NewString,,a255,,v
!temp Pos,,i2
!temp FoundPos,,i2
!temp StrLen,,i2

     String = OldString
     StrLen = strlen(String)
     Pos = 1

     while (TRUE) {
          FoundPos = instr(String, Pos, _QM)
          if (FoundPos = 0) then break
          String = getstr(String, 1, FoundPos -1) / _BSLASH / getstr(String, FoundPos, 255)
          Pos = FoundPos + 2
          continue
     }

     NewString = _QM + String / _QM
     return NewString
}

RELATED TOPICS

Event functions

General functions