SCI Programming Language/Procedures
Author: Jeff Stephenson
A procedure is like a user-defined function or subroutine. Procedures are created with the procedure construct. Note that it is allowable for the procedure to take no parameters and have no automatic variables (optional terms are shown in brackets). Procedure names are traditionally initial capitalized. "Code" in these examples represents any list of valid expressions:
Code:(procedure (MyProc [p1 p2...] [&tmp tl t2...]) code )
This defines the procedure "MyProc" with the parameters p1, p2, ete. and temporary variables t1, t2, ete. (designated by the precedent "&tmp"). These temporary variables disappear on exit from the procedure.
Temporary arrays are defined in the same way as local arrays. In the following example, "myArray" is the name of an array with n elements. Note that brackets are required when designating an array.
Code:(procedure (MyProc &tmp [myArray n]) code )
Even though parameters are optional in a procedure construct, all procedures have one inherent parameter, the compiler-defined variable argc (argument count). The argument count contains the total number of parameters passed to the procedure. In the following procedure calls:
Code:(MyProc 5 2 4) ;argc 3 (MyProc 1 3) ;argc 2 (MyProc 7) ;argc = 1
In the following example, argc is used to fail-safe the SetPosition procedure in the event that fewer than two parameters are passed.
Code:(procedure (SetPosition x y) (if argc ;if the argc is not zero, continue. (= theX x) (if (> argc 1) ;if the argc is > 1, continue. (= theY y) ) ) )
Following are several examples of procedure constructs. Ta square a number n:
Code:(procedure (MySquare n) (return (* n n)) )
The following procedure "MyMax" finds the maximum number in a series of arbitrary numbers passed to i1. The parameters for the variable p will be accessed as an array, biggest is the variable containing the maximum, and i is the index into the parameter array p.
Code:(procedure (MyMax p &tmp biggest i) (for ((= i 0) (= biggest 0)) ;initialize i, biggest (< i argc) ;compare to total number of parameters passed. ( (++ i)) ;re-initialize (if (> [p i] biggest) (= biggest [p i]) ) ) (return biggest) )
Passing the following parameters to MyMax will return the value of 12:
(myMax 3 -4 -9 0 -2 7 12 4 3 5)
In order to use a procedure before it has been defined in a source file (for example, making a call to MyMax before the actual definition of MyMax), the compiler must be told that the procedure's name corresponds to a procedure, not an objec1. This is done with another form of the procedure statement:
Code:(procedure ProcedureName1 ProcedureName2 ... )
This tells the compiler to compile code for procedure calls when it encounters the procedure names, rather than code for send messages to an object.
Note that you may not use a parameter as a procedure variable if the caller did not pass i1. In the following example, the caller passes the values a and b to the procedure. The value of c is not passed and will therefore be undefined. For example:
Code:... ... (Times 5 7) ;passes two parameters to the Times procedure ... ... (procedure (Times a b c) ;procedure expects three parameters (=c(* a b)) (return c) ;c will be undefined. The return will not be correct. )
In the previous example, c should be designated as a temporary value (&tmp c) or left out altogether (return (* a b)).
&rest stands for all of the parameters not specified in the procedure or method. If a procedure or method has a variable number of arguments and wants to pass them on to another procedure or method, &rest tells the spin-off procedure to do all of them without knowing just how many parameters there are. The following example uses the procedure MySquare to square the maximum number in a series, as determined by the procedure MyMax:Code:(procedure (MySquare &tmp max) ;no parameters passed to MySquare (= max (MyMax &rest)) ;&rest passes parameters to MyMax (return (* max max )) )
&rest can also be used to specify parameters starting at any point in the parameter list of a procedure or method definition. Modifying the previous example, MySquare now defines the first two parameters passed to it as "first" and "second." To include them in the parameter list passed on to MyMax:Code:(procedure (MySquare first second &tmp max) (= max (MyMax (&rest first))) ;passes all parameters ;beginning with "first" (return (* max max)) )
Calling a procedure in another script is another matter. Since there is no link phase in the development cycle, one procedure cannot know the address of a procedure in a different script. The extern statement allows a script to know where the external procedure is:Code:(extern ProcedureName scriptNumber entryNumber ... )
This says that the procedure referred to by the symbol "ProcedureName" in this script is to be found in script number "scriptNumber" at entry number "entryNumber" in the script's dispatch table. kernel.sh and system.sh both use the extern statement to let all other scripts know where their public procedures are.
The dispatch table for a script is defined by the public statement.
All procedures within a script which are to be accessed from outside the script must be entered in the dispatch table for the script with the public statement:Code:(public ProcedureName entryNumber ... )
puts the procedure "ProcedureName" in the dispatch table at entry number "entryNumber." The entries need not be in numeric order, nor do the numbers need to be continuous (though if they are not continuous, the table will be larger than it needs to be).