Scripting Language Syntax
Both NairnFEAMPM and NairnFEAMPMViz have built-in scripting languages for programmatically setting up calculations. This section describes language syntax and all generic commands for programming control.
This sections describes the syntax of command lines and gives the definitions of variables and expressions.
- Command Line Syntax: the format of a single command line.
- Variable Names: the language allows variables and variable arrays.
- Expression Syntax: the language allows expressions for making calculations and setting arguments.
The if, ifStr, ifDef, and ifNDef commands are used to define conditional blocks. The if command is for numeric comparisons; the ifStr commands is for string comparisons; the ifDef and ifNDef commands are to check if variables have been defined. The format of a conditional block is:
if (num1) (op) (num2) (block of commands if numeric comparison is true) . else ifStr (string1) (op) (string2) (block of commands if string comparison is true) . else if (num1) (block of commands if (num1) is not zero) . else ifStr (string1) (block of commands if (string1) is not empty) . else ifDef #varName (block of commands if #varNam is a defined variable) . else ifNDef #varName (block of commands if #varNam is not a defined variable) . else (block of commands if no prior condition is true)<br> endif
where there can be any number of conditionals and each can be of any type. If either arguments to an if conditional are strings instead of numbers, that conditional will automatically be converted to an ifStr command. In other words, there is no need to use ifStr unless you explicit want to compare two strings as strings when they happen to also be valid numbers. The arguments to ifDef and ifNDef must be a single variable name.
Numerical conditionals compare (num1) to (num2) with the following comparison operators for (op):
- = or == or ' is ': true if (num1) is equal to (num2).
- != or <> : true if (num1) is not equal to (num2).
- > : true if (num1) is greater than (num2).
- >= : true if (num1) is greater than or equal to (num2).
- < :true if (num1) is less than (num2).
- <= : true if (num1) is less than or equal to (num2).
String conditionals are nearly the same except ordering is alphabetical order instead of numerical order. Furthermore the two "equals" operators provide case-insensitive or case-sensitive comparisons as follows:
- = or ' is ': true if (string1) is equal to (string2) by case-insensitive comparison.</li>
- == : true if (string1) is equal to (string2) by case-sensitive comparison (i.e., two equals signs means more equal than one equals sign).
Notes on Conditionals
- Some string functions can be used to implement other types of useful string comparisons. For example:
- if offset(s1\string)>0 - is true if the string contains the string s1.</li>
- if chars("\"&length(s1)&"\string")=s1 - is true if string starts with the string s1 (case insensitive, use == to make it case sensitive).
- if chars((length(string)-length(s1)+1)&"\string")=s1 - is true if string ends with the string s1 (case insensitive, use == to make it case sensitive).
- When a numeric conditional has only a single number and no comparison operator (such as
if (num1)), the conditional is true if the number is not equal to zero. If the number is not zero, the conditional is false.
- When a string conditional has only a single string and no comparison operator (such as
ifStr (string1)), the conditional is true if the string is not an empty string. If the string has text, the conditional is false.
The Repeat command can be used to set up loops in the commands. The format for repeat loops, which may be nested, is:
Repeat "#x",start,end,<step> (commands in the loop) ... break ... Repeat "#y",start,end,<step> (commands in nested loop) ... continue ... Repeat (commands in nested continuous loop) ... breakAll ... EndRepeat EndRepeat EndRepeat
- Repeat "#x",min,max,step
This command sets up a repeat loop. The repeat variable appears first and it must be quoted to prevent evaluation as an expression. The subsequent three arguments give the starting and ending values for the loop and the step size to increment the value each pass through the loop. If the step size is not included, it is set to 1. Negative step sizes are allowed. A loop may have zero passes if start is greater than end (for positive step size) or less then end (for negative step size).
- A Repeat with no variables will loop forever. It will cause an endless loop unless some condition within the loop forces a break.
- A break can be used in any loop. It will exit the current loop. If there are nested loops, control will enter the next higher loop.
- A breakAll can be used in any loop. It will exit all current loops and pass control to after the last EndRepeat command.
- A continue command will increment the current loop variable and go back to the start of that loop. If the loop is done, it will exit.
Notes on Repeat Commands
- You cannot permanently change the loop variable during a loop. If you change it, it will be reset to the next loop value at the start of the next pass through the loop. For example:
Repeat "#x",1,5 Write #x #x+=10 EndRepeatwill write 1,2,3,4,5 on successive lines even though #x was changed in the loop. Each pass through the loop resets #x to the next loop value.
The commands can include subroutines. All subroutines must be defined at the start of the commands. The commands that get executed and will call the subroutines must start with the first command after the last subroutine definition.
A subroutine, which can be called with a GoSub command, is defined as follows:
Sub subname #arg1,#arg2,...,#argn (subroutine commands) . . . return . . . EndSub
- subname is the name of the subroutine. The names of all subroutines must be unique.
- #arg1,#arg2,...,#argn are any number of subroutine arguments. The name of each argument must be a valid variable name and must not be in quotes.
- The subroutine ends with the EndSub command and execution will return to the line after the GoSub command that called the subroutine.
- The return command can be used to exit a subroutine at any time before the its end.
The GoSub command is used to call subroutines. The calling format is
GoSub subname #1,#2,...#n
- subname is the name of the subroutine.
- #1,#2,...,#n are any expressions. The total number of expressions must exactly match the number of arguments in the subroutine definition. The variables in the subroutine definition will be set equal to the values passed in the GoSub command.
Notes on Subroutines
- All variables are global variables. Thus subroutines can use variables set in the main commands and the main commands can access variables defined in the subroutines including subroutine arguments. If a subroutine argument matches a variable from the main commands, calling the subroutine will overwrite that value.
- Subroutines can be nested which means subroutines can call any other subroutines with GoSub commands.
Output, Debugging, and Other Commands
These commands print output to the lower field in the input commands window or to an message and one command can stop an analysis in progress. These commands are normally for debugging calculation scripts.
The Write command will write all arguments to the output area.
If any arguments are expressions, they will be evaluated before the output is written. Note that writing output will normally corrupt the subsequent XML commands that are written to the output area, so this command is only useful when debugging scripts. In NairnFEAMPMViz, you will only see the output of Write commands when using the "Interpret..." menu command or when using a Stop command to halt interpretation.
The Lines command divides up a variable by lines:
where #1 is a valid string variable name in quotes (e.g., "#varName$"), #2 and #3 specify the range of lines to extract, and #4 is a string possibly containing multiple lines. #2 and #3 give line numbers (first line is line number 1) or can be <=0 to specify line number relative to the end (0 is last line, -1 is next to last line, etc.).
If #1 is "#varName$", for example, the extracted lines will be in #varName$, #varName$, etc., and the total number of lines will be stored in #varName$.
The Words command divides up a variable by words:
where #1 is a valid string variable name in quotes (e.g., "#varName$"), #2 and #3 specify the range of lines to extract, and #4 is a string possibly containing multiple words. #2 and #3 give word numbers (first word is word number 1) or can be <=0 to specify word number relative to the end (0 is last word, -1 is next to last, etc.)
If #1 is "#varName$", for example, the extracted words will be in #varName$, #varName$, etc., and the total number of words will be stored in #varName$.
If optional #5 is used, the string in #4 is split by occurrences of #5. Note that setting #5 to a space (" ") is not the same as omitting number #5. When #5 is omitted, the words are split by one or more spaces (i.e., any length whitespace). When #5 is a space (" "), each space is a delimiter with words between adjacent spaces become zero-length strings.
The stop command stops the interpretation of commands. The format is:
where the optional #1 argument is an error message. If it is omitted, the command interpretation will just stop. If it is provided, the command interpretation will stop and a window sheet will display the error message to the user.
The Clear command clears the output area. The format is:
The Dump command writes arguments of all commands to the output window (NairnFEAMPM only). Its format is:
where #1 is off, parsed, or evaluated. These options mean:
- off: turns the option off; no arguments written.
- parsed: write arguments after command line has been parsed, but before any expressions in arguments have been evaluated.
- evaluated: write arguments after expressions have been evaluated.
- (no argument): if #1 is not supplied, arguments will be written before and after expressions are evaluated.
The Dump command can have multiple arguments and they will be processed in order. For example,
is the same as Dump with no arguments. The command
will turn off any prior settings and then start the parsed option.
The Message command will write all arguments to the message panel, which is a separate floating palette window (NairnFEAMPM only):
If any arguments are expressions, they will be evaluated before the output is written. When there is more than one argument, they will be separated by tabs. A Message command with no arguments will clear the message panel. The message command is useful for debugging or for displaying progress in a long process.
Differences in the NairnFEAMPMViz Scripting Language
The scripting language in NairnFEAMPMViz is based on the corresponding scripting language in the Mac application NairnFEAMPM, but it is not as fully developed. The key difference in NairnFEAMPMViz are:
- The main command on each line must be separated from arguments by a space and arguments must be delimited by commas. In NairnFEAMPM commands and arguments can be delimited by commas, spaces, or tabs.
- Variables need not begin in a number sign (#), string variables must end in a dollar sign ($), numeric variable must not end in a dollar sign ($), and variable names cannot contain any supported function as a substring in the name. In NairnFEAMPM, all variables must begin in number sign (#) and no distinction need be made between numeric and string variables.
- Numeric expressions can only use exponential numbers (e.g., 4.56e-3) when they are the entire expression (e.g., #x=4.56e-3). In NairnFEAMPM, exponential numbers can be used any place a number can be used.
- All plain-text arguments must be quoted. In NairnFEAMPM, many uses of plain text will be accepted even without quotes
Besides the above difference, some features of the scripting language are not yet available in NairnFEAMPMViz, although they are planned to be added in the future. The unsupported features are:
- Two numeric functions for error functions are not available.
When writing command files to use in both applications, you should avoid anything not supported in both applications. The main recommendations are to
- Start all variables in a number sign (#).
- End all variables with string content with a dollar sign ($).
- Surround all plain text arguments in quotes.
- Do not use exponential numbers in expressions except for simple assignments (e.g., #x=4.56e-3)