|
Static Variables
Variables local to a user-defined function can now be made static (i.e., their values persist
across invocations of the function) by prefacing the name of the variable with the characters
"st_".
generic
{
for(x = 0;x < 5;x++)
docount();
}
docount
{
if(!st_value)
st_value = 0;
info(++st_value);
}
Associative Assignments
You can assign multiple values to multiple variables by separating the variables with commas. For example:
main
{
str = "23,-45,69.6,100,-.05,15.34";
(p1,p2,p3,p4,p5,p6) = parse(",",str);
info(p1," ",p2," ",p3);
}
You can also omit variables, so that only the variables specified are assigned to.
Example:
main
{
str = "23,-45,69.6,100,-.05,15.34";
(,p1,,p2,,p3) = parse(",",str);
info(p1," ",p2," ",p3);
}
Inversely,
you can omit values and nil will be assigned in their place, either in
assignments, or in parameter passing to functions.
Example:
main
{
testudf(,"Bob",,15.0,);
}
testudf: p1,p2,p3,p4,p5
{
info(p1," ",p2," ",p3," ",p4," ",p5);
}
Default Assignments
Default value assignments can now be made on function argument
parameters (much like C++). These default value assignments will
trigger if the value passed to the function in that position is 'nil'.
Consider the following example:
main
{
testudf(,"Bob",,15.0,);
}
testudf: p1 = -3.4,p2,p3 = "pretty",p4,p5
{
info(p1," ",p2," ",p3," ",p4," ",p5);
}
This example script would print:
-3.4 Bob pretty 15 (nil)
If you wish to provide for an actual 'nil' value in your function's
processing, then you must either avoid using default value assignments
for that parameter, or use 'nil' as the default value.
main
{
testudf(,"Bob",,15.0,);
}
testudf: p1,p2,p3 = "pretty",p4,p5
{
if(p1) // if 'p1' == nil, nothing will print
info(p1," ",p2," ",p3," ",p4," ",p5);
}
Identifier Construction
Those
identifiers used for variables and function names can now be
"constructed" at run-time using a new language extension. This
extension is triggered by using a "tick" mark or reverse apostrophe (`)
found on the same key as the tilde.
Starting with a base identifier, you add constructors to the end,
preceding each with the "tick" mark. For example, the following
code fragment will assign the integer value 15 to the identifier
"Bob36Hood":
. . .
x = 36;
y = "Hood";
Bob`x`y = 15;
. . .
When this code is executed, 'x' will contain 36, 'y' will hold "Hood",
'Bob' will be nil (ultimately, we are not assigning to 'Bob'), and
the new variable 'Bob36Hood' will be 15.
Pseudo-arrays can be constructed by using this run-time identifier
construction. However, this should only be used for low-count
situations; otherwise, you should employ LScript's integral array
support:
. . .
for(x = 1;x <= 10;x++)
value`x = x * x;
. . .
You can also use this mechanism to build function names (for
invocation, NOT for definition):
. . .
reqbegin("Testing Identifier Construction");
c1 = ctlchoice("Which action?",1,
@"Action1","Action2","Action3"@);
if(!reqpost()) return;
x = getvalue(c1);
reqend();
func`x(); // evaluates to 'func1', 'func2' or 'func3'
. . .
Sequential Assignment
The LScript pre-processor supports a new sequential variable designator. The
constructor is formed by surrounding an elipse ('..') with integer values that
serve as the range of values to generate. The base variable name precedes the
initial integer value, and is used to generate each declared variable.
For instance, this sequential veriable designator:
c1..5;
will be expanded by the pre-processor to:
c1,c2,c3,c4,c5;
Sequential variable designators can be used anywhere in your script code you
would normally declare multiple variables. The following code, for example:
(lex1..5) = parse(" ",line);
info(lex1..5);
is functionally equivalent to:
(lex1,lex2,lex3,lex4,lex5) = parse(" ",line);
info(lex1,lex2,lex3,lex4,lex5);
Item ID information
Layout CS functions that expect an item id as their argument (such as
SelectItem() or GoalItem()) will accept a varying combination of
arguments to aid you in designating the needed Layout object.
- Integer values can be specified that are formatted as
they are in the LightWave scene file. These values
are hexidecimal, so some bit twiddling will be necessary
in order to place values in the correct locations of
the 32-bit integer:
// select the second Mesh object
SelectItem((1 << 28) | 1);
- A string value can be provided that should evaluate
to the name of an object in the current scene.
- An object class can be specified (MESH, LIGHT, CAMERA),
followed by an integer that specifies the linear offset
(1-based) of the object in the list of objects of that
class.
// select the third Light in the scene
SelectItem(LIGHT,3);
Object Masking
This mechanism allows objects of integral data types that support it to
perform a "masking" operation on themselves. The exact result of this
masking function will vary by the data type.
- Floating-point values (numbers, vectors) will
use the masking value to render only that number
of digits to the right of the decimal as significant.
- Character strings will use the masking value to
return that number of characters from the left
(equivalent to strleft()).
- All other data types will evaluate to themselves
(i.e., masking is not applicable).
In order to mask an object, you follow the object operator
('.') with an integer value. For instance, the following
code will print the value "1.34":
...
bob = 1.34398545;
info(bob.2);
...
Masking operators can only be used on variables.
Expression chaining can also be used:
...
bob = 1.34398545;
info(bob.2.asStr().isStr()); // prints 1
...
Global Constants
SCRIPTID
A global constant value called SCRIPTID exists in the LScript operating environment.
This constant holds the full path and filename of the script currently being executed.
Integral data
types (integers, numbers, strings, etc.) respond to the following set
of methods:
Methods
size
size()returns the size of the item.
<integer>
returns
the value itself.
<number>
returns
the value itself.
<string>
returns
the number of characters.
<vector>
returns
1.
<array>
returns
the total elements allocated.
count()
count() returns the count of the item.
<integer> returns 1.
<number> returns 1.
<vector> returns 1.
<string> returns number of characters.
<array> returns number of elements that contain values.
The count() method can now be provided a character argument when applied to string-type objects.When provided, the number of occurances of that character will be returned
to the caller as an integer.
...
s = "1:2:5:38";
info(s.count(':')); // displays 3
...
contains()
This method is now available for integral data types that will, given a data
type and value, search through indexable types (arrays, strings, etc.)
to determine if that type and value exists. It returns a Boolean
true/false value to indicate the presence or absence, respectively, of
the provided value.
...
str = "Now is the time";
info(str.contains("is the")); // displays true (1)
info(str.contains("Bob")); // displays false (0)
...
...
t = @15.87,"Blowfish",<1,9,0.5>@;
info(t.contains(<1,9,0.5>)); // displays true (1)
info(t.contains(15.87)); // displays true (1)
info(t.contains("Blow")); // displays false (0)
...
asInt()
asInt() returns the data interpreted as an integer.
asNum()
asNum() returns the data interpreted as a number.
asStr()
asStr() returns the data interpreted as a character string.
The asStr() method can now be applied to linear arrays. Supported data types will be
concatenated into a single string value. Elements of 'nil' value are ignored. You can
provide an optional character value that will be used to separate values added to the
string.
...
a[1] = "val1";
a[2] = 15;
a[3] = nil;
a[4] = 3.14;
info(a.asStr(':')); // displays "val1:15:3.14"
...
asVec()
asVec() returns the data interpreted as a vector.
asAsc()
asAsc() returns the integer provided interpreted as a character.
if(line[x].asAsc == '\t')
...
asBin()
asBin() returns the integer ASCII value of a character provided to it.
pack()
pack() packs the data and returns a Boolean true or false to indicate whether
or not packing occured.
<integer> does nothing.
<number> does nothing.
<vector> does nothing.
<string> removes leading white space.
<array> packs elements with values down to removeintervening 'nil' values.
It also handles associative arrays.
trunc()
trunc() truncates the data and returns a Boolean true or false value to
indicate whether or not truncating took place.
<integer> does nothing.
<number> does nothing.
<vector> does nothing.
<string> removes trailing white space.
<array> resizes the array, removing trailing elements whose value is 'nil'.
sortA()
sorts the data in ascending order and returns a boolean true or false value
to indicate whether or not sorting took place.
<integer> does nothing.
<number> does nothing.
<vector> does nothing.
<string> sorts
characters in ascending order.
<array> packs, then sorts like elements in ascending order.
Integer, number and string are sortable.
sortD()
sorts the data in descending order and returns a boolean true or false
to indicate whether or not sorting took place.
<integer> does nothing.
<number> does nothing.
<vector> does nothing.
<string>
sorts
characters in ascending order.
<array>
packs, then sorts like elements in descending order.
Integer,
number and string are sortable.
keys()
This method can be applied to an associative array to extract all keys contained
within the array. This allows a script to access all data elements contained in the
associative array in a linear fashion.
isNil()
isNil() tests the data type for 'nil' and returns a Boolean true or false.
Functionally equivalent to performing an equality test (e.g., "data
== nil").
isInt()
isInt() tests the data type for integer and returns a Boolean true or false.
There is no equality test equivalent.
isNum()
isNum() tests the data type for number and returns a Boolean true or false.
There is no equality test equivalent.
isStr()
isStr() tests the data type for string and returns a Boolean true or false
value. There is no equality test equivalent.
isVec()
isVec() tests the data type for vector and returns a Boolean true or false
value. There is no equality test equivalent.
isPrint()
Test the character for printability.
isAlpha()
Test the character for membership in the alphabetic class (i.e., a-z or A-Z).
isAlnum()
Test the character for membership in the alpha-numeric class.
isAscii()
Test the character for membership in the ASCII character set.
isCntrl()
Test the character for membership in the control code character set.
isDigit()
Test the character for membership in the numeric character set (i.e., 0-9).
isPunct()
Test the character for membership in the punctuation character set
(i.e., any printable character that is not a space character, or a character
for which isAlnum() returns true).
isSpace()
Test the character as whitespace (i.e., a space character, or character in the
range 0x09–0x0D).
isUpper()
Test the character for membership in the upper-case alphabetic character set.
isLower()
Test the character for membership in the lower-case alphabetic character set.
isXDigit()
Test the character for membership in the hexidecimal character set (i.e.,
one of "0123456789ABCDEF").
indexOf()
indexOf() can be applied to string, linear array and binary block data types. This
method can be used to locate data within these indexable types. The method returns the index
where the specified data is found. If it is not found, then a value of zero (0) is returned.
In the case of character strings, the provided search value is treated as a displayable character:
...
s = "val1:15:3.14";
ndx = s.indexOf(':'); // returns 5
...
For linear arrays, the value provided must match an element in both type and value in order
to be considered a successful match. Not all data types are supported for searching.
Searches through binary data will treat the provided integer value as an unsigned character,
and should be in the range 0 to 255.
By default, searches begin at the initial index offset of one (1). You can specify a beginning
offset other than one by providing the integer offset before the search value.
...
s = "val1:15:3.14";
ndx = s.indexOf(':'); // returns 5
ndx = s.indexOf(ndx + 1,':'); // returns 8
...
reduce()
The reduce()method will remove duplicate values from the data type (useful
mostly for strings and arrays). Duplicate values are expected to be in
linear order—that is, adjacent to one another. You should probably employ
one of the sort methods before invoking reduce().
The following
is an example of using the reduce() method. A linear series of Polygon
identifiers are gathered into an array in a situation where there is a
high probablity of duplication. Subsequent calls to sortA() and reduce()
remove any duplicate entries from the resulting array:
for(x = 1;x <= pointCnt;x++)
{
rawPolys
= points[x].polygon();
polyCnt
= rawPolys.count();
for(y = 1;y <= polyCnt;y++)
polySelect += rawPolys[y];
}
polySelect.sortA();
polySelect.reduce();
…
Examples
The following
code fragment creates an array of eight elements, and then places values
within it at random. A pack() and a trunc() are then performed on the
array:
q[8] = nil;
q[2] = 1.5;
q[4] = "Bob";
q[5] = <1,2,3>;
info(q.size());
info(q.count());
info(q);
q.pack();
info(q);
q.trunc();
info(q);
This script
code would print the following messages:
8
3
(nil) 1.5 (nil) "Bob" <1,2,3> (nil) (nil) (nil)
1.5 "Bob" <1,2,3> (nil) (nil) (nil) (nil) (nil)
1.5 "Bob" <1,2,3>
While all data
types respond to each message, not all operations have meaning. For instance,
packing or truncating an integer does nothing.
String Commands
hash
This method, useful only with character strings, will return an integer
value that represents a calculated hash value for that string. The
array type also responds to this method, and will calculate a hash
value for all string elements in the array.
mystring="Blah";
mike=mystring.hash();
StatusMsg(mike.asStr());
split
split() works specifically with file path/name character strings. It accepts
a character string, and returns an array of four elements representing
the drive, path, filename, and filename extension that could be derived
from the string argument.
file = getfile(“Select
A Scene...”,”*.lws”);
if(file
== nil)
return;
if(fileexists(file))
{
base
= split(file);
//
get the components (base becomes an array)
…
Components
of the string that do not exist (i.e., no drive designation) are returned
as nil.
strleft
The strleft() function returns a portion of a character string beginning
from the left. It accepts two parameters, where the first is the character
string to be processed, and the second is a number of characters to extract.
value = strleft(“This
string.”,3);
//result:
“Thi”
strright
The strright() function returns a portion of a character string beginning
from the right. It accepts two parameters, where the first is the character
string to be processed, and the second is a number of characters to extract.
value = strright(“This
string.”,3);
… //result:
“ng.”
strsub
strsub() is string extraction function. This function lets you extract
an arbitrary number of characters from within the string starting from
an arbitrary location, instead of starting from one of its ends.
t = strsub(“Ted Philmore”,3,5); // returns: “d Phi”
strupper
The strupper() function returns a copy of the provided string in upper-case
characters.
value = strupper(“upper-case”);
//returns: UPPER-CASE
strlower
The strlower() function returns a copy of the provided string in lower-case
characters.
value = strupper(“LOWER-CASE”);//returns:
lower-case
parse
parse() accepts two parameters: the first is a string of potential token
separators and the second is the character string to process. This function
returns an array of tokens that make up the string (second parameter).
str = “23,45,69.6,100”;
tokens =
parse(“,”,str);
// returns “23”, “45”, “69.9” and “100”
format
A format() function can format a string by performing token substitution
within the string with provided values. This is much like C’s printf()
function. It can be used with individual data elements, but it is intended
for arrays.
format(<template>,<data>[,<data>...])
Tokens are
indicated by a dollar sign ($) followed by the numeric index value to
be taken from the arguments provided. Index value need not be sequential,
nor must you access all elements.
Individual
arguments can be either a list of single data types (variables or
constants), or you can provide a single array value to the used in the
substitution. You cannot provide both.
The function returns a string value that has all substitutions performed:
d = date();
info(format(“Today is $7, $6 $1, $3”,d));
(h,m) = time();
ap = “AM”;
if(h > 11)
{
ap
= “PM”;
h -= 12 if h > 12;
}
h = 12 if h == 0;
info(format(“Time is currently $1:$2” + ap,h,m));
General Commands
store
The store command lets a script retain variable values across invocations.
The store() command takes two parameters: the first parameter is a string
literal (or variable with a character string) that uniquely identifies
the value to be stored, and the second parameter is the actual value itself.
store(“myName”,myName);
…
recall
The recall command lets a script retain
variable values across invocations. recall() retrieves values that have
been previously store()’d. As with store(), it also takes two parameters.
The first parameter is the value identifier that was originally used to
retain the value. The second parameter is a default value to return if
a store() has never been issued for that identifier.
heading = recall(“heading”,15);
globalstore
The globalstore() function works the same as the store() command, however
it functions across different scripts of the same architecture.
globalstore(“heading”,
23);
globalrecall
The globalrecall() function works the same as the recall() command, however
it functions across different scripts.
heading = globalrecall(“heading”,
8);
size command
The size() command determines the size of a particular variable of a particular
data type. For numeric values, it returns 1. For vector types, it returns
3. Character string arguments return the number of characters in the string,
while array arguments return the number of actual elements in the array
(not the total size of the array).
str = “23,45,69.6,100”;
tokens[10]
= nil;
t = size(tokens); // returns 0
tokens = parse(“,”,str); // returns four elements
t = size(tokens); // returns 4
tokens[8] = 1.0;
t = size(tokens); // returns 5
sizeof
The sizeof() function returns the size of an array.
tmp[1] = 1;
tmp[2] =
2;
tmp[3] = 3;
info(sizeof(tmp));
|