|
|
(4 intermediate revisions by the same user not shown) |
Line 24: |
Line 24: |
| | | |
| | | |
− | ===<br /> define ===
| + | ==<br /> define == |
| | | |
| + | <blockquote> |
| The define statement allows you to define a symbol which will stand for a string of text: | | The define statement allows you to define a symbol which will stand for a string of text: |
| | | |
− | (define symbol lots of text) | + | <blockquote><code>(define symbol lots of text)</code></blockquote> |
| | | |
| will replace symbol, wherever it is encountered as a token, with lots of text and then continue scanning at the beginning of the replacement text. Thus, if we write: | | will replace symbol, wherever it is encountered as a token, with lots of text and then continue scanning at the beginning of the replacement text. Thus, if we write: |
| | | |
− | (define symbol some text) | + | <blockquote> |
− | (define same even more) | + | <code>(define symbol some text)</code><br /> |
| + | <code>(define same even more)</code> |
| + | </blockquote> |
| | | |
| then: | | then: |
| | | |
− | (symbol) | + | <blockquote><code>(symbol)</code></blockquote> |
| | | |
| will become: | | will become: |
| | | |
− | (some text) | + | <blockquote><code>(some text)</code></blockquote> |
| | | |
| which then becomes: | | which then becomes: |
| | | |
− | (even more text) | + | <blockquote><code>(even more text)</code></blockquote> |
− | | + | </blockquote> |
− | enum
| |
| | | |
| + | ==<br /> enum == |
| + | <blockquote> |
| The enum statement eases the definition of the various states of a state-variable. Say you want to walk an actor from the door of a room across the floor, up the stairs, and through another door. You have a state-variable called actor-pos which will take on a number of values. These could be defined with defines as follows: | | The enum statement eases the definition of the various states of a state-variable. Say you want to walk an actor from the door of a room across the floor, up the stairs, and through another door. You have a state-variable called actor-pos which will take on a number of values. These could be defined with defines as follows: |
| | | |
| + | <blockquote> |
| <div class="CodeBlockHeader">Code:</div> | | <div class="CodeBlockHeader">Code:</div> |
| <syntaxhighlight lang="sci"> | | <syntaxhighlight lang="sci"> |
Line 61: |
Line 66: |
| ) | | ) |
| </syntaxhighlight> | | </syntaxhighlight> |
| + | </blockquote> |
| | | |
| or you could get the same result with enum: | | or you could get the same result with enum: |
| | | |
| + | <blockquote> |
| <div class="CodeBlockHeader">Code:</div> | | <div class="CodeBlockHeader">Code:</div> |
| <syntaxhighlight lang="sci"> | | <syntaxhighlight lang="sci"> |
Line 76: |
Line 83: |
| ) | | ) |
| </syntaxhighlight> | | </syntaxhighlight> |
− | | + | </blockquote> |
− | '''Page 14'''
| |
− | | |
− | | |
− | | |
− | | |
− | | |
| | | |
| Enum defaults its first symbol to O. If you want a different starting value, put it right after the word enum: | | Enum defaults its first symbol to O. If you want a different starting value, put it right after the word enum: |
| | | |
| + | <blockquote> |
| <div class="CodeBlockHeader">Code:</div> | | <div class="CodeBlockHeader">Code:</div> |
| <syntaxhighlight lang="sci"> | | <syntaxhighlight lang="sci"> |
Line 96: |
Line 98: |
| ) | | ) |
| </syntaxhighlight> | | </syntaxhighlight> |
| + | </blockquote> |
| | | |
− | sets AT FRONT_ DOOR to 7, IN _ ROOM to 8, etc. | + | sets <code>AT FRONT_ DOOR</code> to 7, <code>IN _ ROOM</code> to 8, etc. |
| | | |
| The value of an enum may also be defined by an expression, as follows: | | The value of an enum may also be defined by an expression, as follows: |
| | | |
| + | <blockquote> |
| <div class="CodeBlockHeader">Code:</div> | | <div class="CodeBlockHeader">Code:</div> |
| <syntaxhighlight lang="sci"> | | <syntaxhighlight lang="sci"> |
Line 107: |
Line 111: |
| ) | | ) |
| </syntaxhighlight> | | </syntaxhighlight> |
| + | </blockquote> |
| | | |
| Note: Define and enum statements may be included within both global and local variable definitions. | | Note: Define and enum statements may be included within both global and local variable definitions. |
| + | </blockquote> |
| | | |
| + | ;Notes |
| + | <references /> |
| | | |
− | Page 15
| + | [[SCI Programming Language | Table of Contents]] |
− | | |
− | | |
− | | |
− | | |
− | | |
− | | |
− | Control Flow
| |
− | | |
− | The value of a control flow expression is the value of the last expression in the control body which was evaluated. Thus, if we execute the following code:
| |
− | | |
− | <div class="CodeBlockHeader">Code:</div>
| |
− | <syntaxhighlight lang="sci">
| |
− | (= x 3)
| |
− | (= Y 2)
| |
− | (= Y
| |
− | (if (> x y)
| |
− | (-x y)
| |
− | else
| |
− | (+ x y)
| |
− | )
| |
− | </syntaxhighlight>
| |
− | | |
− | Y will have the value 1.
| |
− | | |
− | In the following, code1, code2, ... codeN are sequences of expressions. Brackets [...] indicate optional entries. The term "not FALSE" is used to indicate a non-zero result.
| |
− | | |
− | | |
− | Conditionals
| |
− | | |
− | if
| |
− | | |
− | (if expression code1 [else code2])
| |
− | | |
− | If expression is not FALSE, execute code1, else execute code2.
| |
− | |-
| |
− | |''example:'' ||Set the value 0'x to the larger of a or b.
| |
− | | |
− | <div class="CodeBlockHeader">Code:</div>
| |
− | <syntaxhighlight lang="sci">
| |
− | (if (> a b) ;expression
| |
− | ( = x a) ;code1
| |
− | else
| |
− | (= x b) ;code2
| |
− | )
| |
− | </syntaxhighlight>
| |
− | | |
− | cond
| |
− | | |
− | (cond (expl codel) (exp2 code2) ... [(else codeN)])
| |
− | | |
− | Evaluate e1. If it is not FALSE, execute code1 and exit the cond clause. If it is FALSE, evaluate e2 and continue. If all of the expressions are FALSE and the optional else clause is present, execute codeN.
| |
− | | |
− | | |
− | Page 16
| |
− | | |
− | | |
− | | |
− | | |
− | | |
− | |-
| |
− | |''example:'' ||Set x to the larger of a or b and to 0 if a = b.
| |
− | | |
− | (cond
| |
− | ((== a b) ;expression1
| |
− | (= x 0) ;code1
| |
− | )
| |
− | ((> a b) ;expression2
| |
− | (= x a) ;code2
| |
− | )
| |
− | (else
| |
− | (= x b) ;codeN
| |
− | )
| |
− | | |
− | switch
| |
− | | |
− | (switch expression (exp1 code1) (exp2 code2) ... [(else codeN) 1 )
| |
− | | |
− | Evaluate expression. If it is equal to exp1, execute code1 and exit the switch. If it is equal to exp2, execute code2 and exit. If it doesn't equal any of the expressions and the optional else clause is present, execute codeN.
| |
− | |-
| |
− | |''example:'' ||Evaluates a -b.
| |
− | | |
− | <div class="CodeBlockHeader">Code:</div>
| |
− | <syntaxhighlight lang="sci">
| |
− | (switch (-a b) ;expression
| |
− | (0 ;expression1
| |
− | (Prints "They are equal") ;code1
| |
− | )
| |
− | (-1 ;expression2
| |
− | (Prints "B is one unit larger than A") ;code2
| |
− | )
| |
− | ( 1 ;expression3
| |
− | (Prints "A is one unit larger than B") ;code3
| |
− | )
| |
− | (else
| |
− | (Prints "A and B differ by more than one") ;codeN
| |
− | )
| |
− | )
| |
− | </syntaxhighlight>
| |
− | | |
− | switchto
| |
− | | |
− | (switchto e xpression (code1) (code2) ... [(else codeN)])
| |
− | | |
− | Evaluate expression. If it is equal to 0, execute code1. If it is equal to 1, execute code2, and so on. switchto is a shorthand form of the switch statement where the test values are consecutive integers beginning with 0. It is commonly used in the changeState method of an SCI script object (where the expression is the state of the script).
| |
− | | |
− | | |
− | Page 17
| |
− | | |
− | | |
− | | |
− | | |
− | |-
| |
− | |''example:'' ||Evaluates the variable stateNum.
| |
− | | |
− | <div class="CodeBlockHeader">Code:</div>
| |
− | <syntaxhighlight lang="sci">
| |
− | (switchto stateNum ;expression
| |
− | (
| |
− | (Prints "This is state O") ;code1
| |
− | )
| |
− | (
| |
− | (Prints "This is state 1") ;code2
| |
− | )
| |
− | (else
| |
− | (Prints "The variable stateNum is not 0 or 1") ;codeN
| |
− | )
| |
− | )
| |
− | </syntaxhighlight>
| |
− | | |
− | Iteration
| |
− | | |
− | for
| |
− | | |
− | (for (initialization) condition (re-initialization) code)
| |
− | | |
− | Evaluate the expressions comprising initialization. Then evaluate condition. If the result is FALSE, exit the loop. Otherwise, execute code, then the expressions comprising re-initialization, and loop back to condition.
| |
− | |-
| |
− | |''example:'' ||Set x = a + b while i < n. Note that this value does not change.
| |
− | | |
− | <div class="CodeBlockHeader">Code:</div>
| |
− | <syntaxhighlight lang="sci">
| |
− | (for
| |
− | ((= a 0)(= b 1)(= i 3)) ;initialization
| |
− | (< i n) ;condition
| |
− | ((++ i)) ;re-initialization
| |
− | (= x (+ a b)) ;code
| |
− | )
| |
− | </syntaxhighlight>
| |
− | | |
− | Note that the initialization statements may include more than one expression and therefore require a set of surrounding parentheses.
| |
− | | |
− | while
| |
− | | |
− | (while condition code)
| |
− | | |
− | Evaluate condition. If not FALSE, execute code and loop back to evaluate condition again. Exit the loop when condition is FALSE. (Note that this means that the resultant value of a while condition is always FALSE.) This is equivalent to:
| |
− | | |
− | (for (0) condition (0) code).
| |
− | |-
| |
− | |''example:'' ||Set x = x + the incremented value of i while i < n.
| |
− | | |
− | (while
| |
− | (< i n) ;condition
| |
− | (+= x (++ i)) ;code
| |
− | )
| |
− | | |
− | | |
− | Page 18
| |
− | | |
− | | |
− | | |
− | | |
− | repeat
| |
− | | |
− | (repeat code)
| |
− | | |
− | Continually execute the code until some condition in the code (a break) causes the loop to be exited. This is equivalent to:
| |
− | | |
− | (while TRUE code) or (for (0) TRUE (0) code)
| |
− | |-
| |
− | |''example:'' ||Set x =x + 2. Note that this will loop forever.
| |
− | | |
− | <div class="CodeBlockHeader">Code:</div>
| |
− | <syntaxhighlight lang="sci">
| |
− | (repeat
| |
− | (+= x 2) ;code
| |
− | )
| |
− | </syntaxhighlight>
| |
− | | |
− | Supporting constructs tor iteration
| |
− | | |
− | break
| |
− | | |
− | (break [n])
| |
− | | |
− | Break out of n levels of loops. If n is not specified break out of the innermost loop.
| |
− | |-
| |
− | |''example:'' ||Repeat incrementing i until i > n.
| |
− | | |
− | <div class="CodeBlockHeader">Code:</div>
| |
− | <syntaxhighlight lang="sci">
| |
− | (repeat
| |
− | (++ i)
| |
− | (if (> i n) (break))
| |
− | )
| |
− | </syntaxhighlight>
| |
− | | |
− | breakif
| |
− | | |
− | (breakif expression [n])
| |
− | | |
− | If expression is not FALSE, break out of n levels of loops. If n is not specified, break out of the innermost loop.
| |
− | |-
| |
− | |''example:'' ||Repeat incrementing i until i > n.
| |
− | | |
− | <div class="CodeBlockHeader">Code:</div>
| |
− | <syntaxhighlight lang="sci">
| |
− | (repeat
| |
− | (++ i)
| |
− | (breakif (> i n))
| |
− | )
| |
− | </syntaxhighlight>
| |
− | | |
− | continue
| |
− | | |
− | (continue [n])
| |
− | | |
− | Loop back to the beginning of the nth level loop. If n is not specified, loop to the beginning of the innermost loop.
| |
− | | |
− | | |
− | Page 19
| |
− | | |
− | | |
− | | |
− | | |
− | |-
| |
− | |''example:'' ||Set x =y / i unless i =O.
| |
− | | |
− | (for ((i = -5)) << i 5) ((++ i))
| |
− | (if (== i 0) (continue))
| |
− | (=x (/ y i))
| |
− | )
| |
− | | |
− | contif
| |
− | | |
− | (contif expression [n])
| |
− | | |
− | If expression is not FALSE, loop back to the beginning of the nth level loop. If n is not specified, loop to the beginning of the innermost loop.
| |
− | |-
| |
− | |''example:'' ||Same as "continue" except using the logical NOT to test i.
| |
− | | |
− | <div class="CodeBlockHeader">Code:</div>
| |
− | <syntaxhighlight lang="sci">
| |
− | (for ((= i -5)) << i 5) ((++ i))
| |
− | (contif (not i))
| |
− | (=x(/yi))
| |
− | )
| |
− | </syntaxhighlight>
| |
− | | |
− | return
| |
− | | |
− | (return [expression))
| |
− | | |
− | The return statement returns control to the procedure which called the currently executing procedure. If the optional expression is present, that value is returned as the value of the current procedure. There is an implicit return at the end of all procedures, and the value returned in that case is the value of the last expression evaluated. A return from the main procedure of script 0 returns to the operating system.
| |
− | | |
− | example:
| |
− | | |
− | <div class="CodeBlockHeader">Code:</div>
| |
− | <syntaxhighlight lang="sci">
| |
− | (return
| |
− | (+ x k ) ;optional expression
| |
− | )
| |
− | </syntaxhighlight>
| |
− | | |
− | '''Page 20'''
| |
− | | |
− | | |
− | | |
− | | |
− | Procedures
| |
− | | |
− | 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:
| |
− | | |
− | <div class="CodeBlockHeader">Code:</div>
| |
− | <syntaxhighlight lang="sci">
| |
− | (procedure (MyProc [p1 p2...] [&tmp tl t2...])
| |
− | code
| |
− | )
| |
− | </syntaxhighlight>
| |
− | | |
− | 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.
| |
− | | |
− | <div class="CodeBlockHeader">Code:</div>
| |
− | <syntaxhighlight lang="sci">
| |
− | (procedure (MyProc &tmp [myArray n])
| |
− | code
| |
− | )
| |
− | </syntaxhighlight>
| |
− | | |
− | 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:
| |
− | | |
− | (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.
| |
− | | |
− | <div class="CodeBlockHeader">Code:</div>
| |
− | <syntaxhighlight lang="sci">
| |
− | (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)
| |
− | )
| |
− | )
| |
− | )
| |
− | </syntaxhighlight>
| |
− | | |
− | Following are several examples of procedure constructs.
| |
− | Ta square a number n:
| |
− | | |
− | <div class="CodeBlockHeader">Code:</div>
| |
− | <syntaxhighlight lang="sci">
| |
− | (procedure (MySquare n)
| |
− | (return (* n n))
| |
− | )
| |
− | </syntaxhighlight>
| |
− | | |
− | '''Page 21'''
| |
− | | |
− | | |
− | | |
− | | |
− | | |
− | 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.
| |
− | | |
− | <div class="CodeBlockHeader">Code:</div>
| |
− | <syntaxhighlight lang="sci">
| |
− | (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)
| |
− | )
| |
− | </syntaxhighlight>
| |
− | | |
− | 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:
| |
− | | |
− | <div class="CodeBlockHeader">Code:</div>
| |
− | <syntaxhighlight lang="sci">
| |
− | (procedure
| |
− | ProcedureName1
| |
− | ProcedureName2
| |
− | ...
| |
− | )
| |
− | </syntaxhighlight>
| |
− | | |
− | 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:
| |
− | | |
− | <div class="CodeBlockHeader">Code:</div>
| |
− | <syntaxhighlight lang="sci">
| |
− | ...
| |
− | ...
| |
− | (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.
| |
− | )
| |
− | </syntaxhighlight>
| |
− | | |
− | In the previous example, c should be designated as a temporary value (&tmp c) or left out altogether (return (* a b)).
| |
− | | |
− | | |
− | '''Page 22'''
| |
− | | |
− | | |
− | | |
− | | |
− | | |
− | ====<br /> &rest ====
| |
− | | |
− | &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:
| |
− | | |
− | <div class="CodeBlockHeader">Code:</div>
| |
− | <syntaxhighlight lang="sci">
| |
− | (procedure (MySquare &tmp max) ;no parameters passed to MySquare
| |
− | (= max (MyMax &rest)) ;&rest passes parameters to MyMax
| |
− | (return (* max max ))
| |
− | )
| |
− | </syntaxhighlight>
| |
− | | |
− | &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:
| |
− | | |
− | <div class="CodeBlockHeader">Code:</div>
| |
− | <syntaxhighlight lang="sci">
| |
− | (procedure (MySquare first second &tmp max)
| |
− | (= max (MyMax (&rest first))) ;passes all parameters
| |
− | ;beginning with "first"
| |
− | (return (* max max))
| |
− | )
| |
− | </syntaxhighlight>
| |
− | | |
− | ====<br /> extern ====
| |
− | | |
− | 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:
| |
− | | |
− | <div class="CodeBlockHeader">Code:</div>
| |
− | <syntaxhighlight lang="sci">
| |
− | (extern
| |
− | ProcedureName scriptNumber entryNumber
| |
− | ...
| |
− | )
| |
− | </syntaxhighlight>
| |
− | | |
− | 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.
| |
− | | |
− | ====<br /> public ====
| |
− | | |
− | 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:
| |
− | | |
− | <div class="CodeBlockHeader">Code:</div>
| |
− | <syntaxhighlight lang="sci">
| |
− | (public
| |
− | ProcedureName entryNumber
| |
− | ...
| |
− | )
| |
− | </syntaxhighlight>
| |
− | | |
− | '''Page 23'''
| |
− | | |
− | | |
− | | |
− | | |
− | | |
| | | |
− | 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).
| + | <span style="float: left">[[SCI Programming Language/Data Types and Variables|< Previous: Data Types and Variables]]</span> |
| + | <span style="float: right">[[SCI Programming Language/Control Flow|Next: Control Flow >]]</span> |
| | | |
| + | |
| | | |
− | '''Page 24'''
| + | [[Category:SCI Documentation]] |
| + | [[Category:SCI32]] |
| + | [[Category:Scripting]] |