Programmer Guide/Source code: Difference between revisions

From STX Wiki
Jump to navigationJump to search
No edit summary
 
(66 intermediate revisions by 4 users not shown)
Line 1: Line 1:
{{DISPLAYTITLE:{{SUBPAGENAME}}}}
{{DISPLAYTITLE:{{SUBPAGENAME}}}}
==Source code==
The '''source code''' is the text which is loaded by the {{STX}} source code loader and which is interpreted and executed by an instance of the {{STx}} command interpreter (called [[Programmer_Guide/Concepts/Shell|shell]]). A '''source file''' is a text file containing source code. By convention, source files end with the extension <code>stx</code> (for library packages and applications) or <code>sts</code> (for scripts to be loaded and executed via [[Programmer_Guide/BScript|BScript]]). Examples of scripts can be found in the directory '''scripts\examples''' in the {{Stx}} installation directory. {{STX|caps}} source files use a '''section file format''', where each section starts with a [[#Section Header|section header]]. Each source section delineates a section of source code. The code runs from the header to the next header, or to the end of the file.


The '''source code''' is the text which is loaded by the STx source code loader into a global environment and interpreted and executed by an instance of the STx command interpreter (called '''shell'''). A '''source file''' is a text file containing source code. By convention, source files end with the extension <code>stx</code> (for libraries packages and application) or <code>sts</code> (for scripts to be loaded and executed via [[Programmer_Guide/Programming#BScript|BScript]]). Examples of scripts can be found in the directory '''scripts\examples''' in the S_TOOLS-STx installation directory. S_TOOLS-STx source files use a '''section file format''', where each section starts with a section header. Each source section delineates a section of source code. The code runs from the header to the next header, or to the end of the file.  
==Section Header==
The section header starts a new section, defining the scope, type and the name of the source code contained in the body of the respective section. The section header must be enclosed within square brackets, and the opening bracket must be the first character in the line. There must not be any text behind the closing bracket except, optionally, a comment.


==Section header==
[{<var>scope</var>:}<var>sstype</var> <var>ssname</var> {<var>ssargs</var>}]
The section header defines the visibility, type and the name of the source code contained in the source section. The section header must be enclosed within square brackets, where the opening bracket must be the first character in the line and there must not be any text behind the closing bracket expect comments.


<code>[{<var>visiblity</var>:}<var>sstype</var> <var>ssname</var> {<var>ssargs</var>}]</code>
;<var>scope</var>: The scope of a section defines from where the source code object can be accessed, instantiated or called. Source headers without an explitic scope are GLOBAL. The following scope keywords are currently supported.
:;<code>GLOBAL</code>: The section code is visible everywhere. This is the default.
:;<code>LOCAL</code>: The section code is visible only for code inside the same source file. A local [[#Definition_of_macros|macro]] can only be called, and a local [[#Definition_of_classes|CLASS]] or [[#Definition_of_SPUs|SPU]] can only be instantiated, from macros defined in the same source file.
:;<code>MAIN</code>: Defines the respective section (which must be defining a macro) as the main macro of an {{STx}} application. A main macro must be called by the system macro [[Programmer_Guide/Macro_Library/APPMAIN|AppMain]]. This keyword is applicable to [[#Define_a_Macro|macro]] and [[#Define_a_Class|class]] sections only, and should only be used for the main function of an {{Stx}} application but not for scripts.
:;<code>SHELL</code>: Defines the section code as a shell startup code, meaning that the macro implements the startup code of a command interpreter instance (shell) and can only be used in the [[Programmer_Guide/Command_Reference/MACRO_and_SHELL|shell]]. This keyword is applicable to [[#Definition_of_macros|macro]] and [[#Definition_of_Classes|class]] sections only.
:;<code>MSGHANDLER</code>: Defines a message handler macro, which can only be called from the system macros [[Programmer_Guide/Macro_Library/GETMESSAGE|GetMessage]] or [[Programmer_Guide/Macro_Library/DISPATCHMSG|DispatchMsg]].


;<var>visibility</var>: The visibilty of a section defines from where the source code object can be accessed, instantiated or called. The following visibility keywords are currently supported.
;<var>sstype</var>: Defines the type of source code in the section. The types [[#Definition_of_macros|<code>macro</code>]], [[#Definition_of_classes|<code>class</code>]] and [[#Definition_of_SPUs|<code>SPU</code>]] have a defined meaning in the {{STX}} scripting language. Other, user-defined, types may also be used (e.g. to store data). Such user-defined sections will be ignored by {{Stx}}. They may be accessed via the [[Programmer_Guide/Macro_Library/SECTIONFILE|SectionFile]] macro or directly with the [[Programmer_Guide/Shell_Items/File|file item]] functions. The section script processing application uses the special types [[Programmer_Guide/Programming#BScript|libraries]] and [[Programmer_Guide/Programming#BScript|scripts]]. If an unknown section type is detected by the loader, the section is ignored.
::;GLOBAL: The section code is visible everywhere. This is the default.
::;LOCAL: The section code is visible only for code inside the same source file. A local [[#Definition_of_macros|macro]] can only be called, and a local [[#Definition_of_classes|CLASS]] or [[#Definition_of_SPUs|SPU]] can only be instantiated from macros defined in the same source file.
::;MAIN: Defines the section code as the main macro of an STx application. A main macro must be called by the system macro [[Programmer_Guide/Macro_Library/APPMAIN|AppMain]]. This keyword is defined for [[#Define_a_Macro|macro]] and [[#Define_a_Class|class]] sections only, and should only be used for the main function of an STx application but not for scripts.
::;SHELL: Defines the section code as a shell startup code. This means, the macro implements the startup code of a command interpreter instance (shell) and can only be used in the [[Programmer_Guide/Command_Reference/MACRO_and_SHELL|shell]]. This keyword is defined for  [[#Definition_of_macros|macro]] and [[#Definition_of_Classes|class]] sections only.
::;MSGHANDLER: Defines a message handler macro, which can only be called from the system macros [[Programmer_Guide/Macro_Library/GETMESSAGE|GetMessage]] or [[Programmer_Guide/Macro_Library/DISPATCHMSG|DispatchMsg]].


;<var>sstype</var>: Defines the type of source code in the section. The types [[#Definition_of_macros|macro]], [[#Definition_of_classes|class]] and [[#Definition_of_SPUs|SPU]] are meaningful for the STx scripting language. Other types can also be used (e.g. to store data) and accessed via the [[Programmer_Guide/Macro_Library/SECTIONFILE|SectionFile]] macro or directly with the [[Programmer_Guide/Shell_Items/File|file item]] functions. The section script processing application uses the special types [[Programmer_Guide/Programming#BScript|libraries]] and [[Programmer_Guide/Programming#BScript|scripts]]. If an unknown section type is detected by the loader, the section is ignored.
;<var>ssname</var>: The name identifying this source code section. This is used to access the source code later on (e.g. to call a [[Programmer_Guide/Command_Reference/MACRO_and_SHELL|macro]], to create an [[Programmer_Guide/Shell_Items/SPU|SPU item]], to create a [[Programmer_Guide/Shell_Items/Instance|instance item]] of a class, to derive a class,&hellip;). The name must be unique in the namespace where the source code is loaded, as defined by the section type, <var>sstype</var>. Source sections of type [[#Definition_of_macros|<code>macro</code>]] and [[#Definition_of_slasses|<code>class</code>]] are loaded into the same namespace. A separate namespace is used for [[#Definition_of_SPUs|SPU]] items.
 
;<var>ssname</var>: The name identifying this source code section. This is used to access the source code later on (e.g. to call a [[Programmer_Guide/Command_Reference/MACRO_and_SHELL|macro]], to create an [[Programmer_Guide/Shell_Items/SPU|spu item]], to create a [[Programmer_Guide/Shell_Items/Instance|instance item]] of a class, to derive a class, ...). . The name must be unique in the namespace where the source code is loaded, which is selected by the section type. Source sections of type [[#Definition_of_macros|macro]] and [[#Definition_of_slasses|class]] are loaded into the same namespace. A separate namespace is used for [[#Definition_of_SPUs|SPU]] items.


;<var>ssargs</var>: The meaning of this part of the header depends on the type of the source section.
;<var>ssargs</var>: The meaning of this part of the header depends on the type of the source section.


The parameters <var>sstype</var> and <var>ssname</var> are mandatory for the types [[#Definition_of_macros|macro]], [[#Definition_of_classes|class]] and [[#Definition_of_SPUs|SPU]], whilst <var>visibility</var> and <var>ssargs</var> are optional and depending on <var>sstype</var>. All keywords, names and other parts of the header are not case-sensitive.
The parameters <var>sstype</var> and <var>ssname</var> are mandatory for the types [[#Definition_of_macros|<code>macro</code>]], [[#Definition_of_classes|<code>class</code>]] and [[#Definition_of_SPUs|<code>SPU</code>]], whilst <var>scope</var> and <var>ssargs</var> are optional, and depend on <var>sstype</var>. All keywords, names and other parts of the header are not case-sensitive.


Examples:
=== Examples ===


<code>[LOCAL:MACRO MacroExample1]<br>[MACRO MacroExample2 #args]<br>[SPU DSPCircuit1 #in1 #in2 OUT #out1]</code>
[LOCAL:MACRO MacroExample1]
    // This macro called "MacroExample1" will be visible only locally
    &hellip;
[MACRO MacroExample2 #args]
    // This macro called "MacroExample2" will be globally visible
    &hellip;
[SPU DSPCircuit1 #in1 #in2 OUT #out1]
    &hellip;


==Section body==
==Section body==
The section body consists of statements (at least one is mandatory), empty lines (are ignored) and comments. The section body ends at the next section header or the end of the file.  
The section body consists of statements (actually, there must be at least one statement per section), of empty lines (which are ignored) and of comments (which are also ignored). The section body ends with the next section header or with the end of the file.


;comments: A comment is part of the source code which is used for documentation purposes and is ignored by the loader. A comment can be placed anywhere, where a whitespace character is allowed. The standard C++ comment tags can be used in S_TOOLS-STx source code.
;comments: A comment is part of the source code that is there for documentation purposes. It is ignored by the loader. A comment can be placed wherever a whitespace character is allowed. The standard C++ comment tags "<code>//</code>" and "<code>/* &hellip; */</code>" can be used in {{STx}} source code.
:;line comment: starts with the tag '''//''' and ends at the end of the same line.
:;line comment: starts with the tag "<code>//</code>" and ends at the end of the same line.
:;block comment: is opened with the tag '''/*''' and closed with the tag '''*/'''. A block comment can be spanned over more than one line. If the begin and end tag of a block comment is on the same line, the comment is treated like a whitespace character, otherwise like a ''end of line''.  
:;block comment: is opened with the tag "<code>/*</code>" and closed with the tag "<code>*/</code>". A block comment can be spanned over more than one line. If the begin and end tag of a block comment is on the same line, the comment is treated like a whitespace character, otherwise like an end of a line.
:Note that a comment open tag ('''//''' or '''/*''') in a quoted string is interpreted as normal text and not as tag. Its also possible to escape one character of a comment tag (like: <code>`//</code>) to avoid its interpretation.
:In a quoted string, the comment tags are interpreted as normal text and not as tag, which is probably the expected behaviour. It is also possible to escape one character of a comment tag (like: <code>`//</code>) to avoid its interpretation.


;statements: A statement is the part of a line which remains after removing comments, and leading and trailing white space. In macros and classes, statements are label definitions, definitions of local functions or member functions and/or commands. In SPUs, the statements are used to define and connect the circuit elements.
;statements: A statement is that part of a line which remains after removing comments, and leading and trailing white space. In macros and classes, statements are label definitions, definitions of local functions or member functions and/or commands. In SPUs, the statements are used to define and connect the circuit elements.


==Definition of Macros==
==Definition of Macros==
====Header====
===Header===
A macro is defined by one of the following section headers. The possible formats differ only in the type of argument parsing supplied before the first macro statement is executed. The optional visibility tag is omitted in this description, because it described in detail in the chapter [[#Section_header|section header]].
A macro is defined by one of the section headers listed below. The possible formats differ only in how arguments are processed or parsed before the first macro statement is executed. The optional scope tag is omitted in this description, because it described in detail in the chapter [[#Section_Header|section header]].


<code>[MACRO <var>macroname</var>]</code>
[MACRO <var>macroname</var>]
:No argument parsing. The argument parsing must be implemented in the macro body using the [[Programmer_Guide/Command_Reference/READ|READVAR]]and/or the [[Programmer_Guide/Command_Reference/ARG|ARG]] command.
:Arguments are stored in the variables <var>#ARGV</var> and <var>#QARGV</var>, without further processing or parsing. The user program is free further to process these data, e.g. by using the [[Programmer_Guide/Command_Reference/READ|READVAR]] and/or the [[Programmer_Guide/Command_Reference/ARG|ARG]] command.
:important variables: '''#ARGV''', '''#QARGV'''
:important variables: <var>#ARGV</var>, <var>#QARGV</var>


<code>[MACRO <var>macroname</var> {READ:} <var>argname1</var>{=<var>defaultvalue1</var>} {seperator1} ...]</code>
[MACRO <var>macroname</var> {READ:} <var>argname<sub>1</sub></var>{=<var>defaultvalue<sub>1</sub></var>} {separator<sub>1</sub>} &hellip;]
:READ-style argument parsing. The arguments are parsed as strings, using the [[Programmer_Guide/Command_Reference/READ|READVAR]] command befor the first statement is executed. The programmer can select arbitrary argument seperators. If an argument value is specified in the call, it is assigned to the argument, otherwise the default value defined in the header is assigned to the argument. A default value must not contain whitespace characters. If more arguments are passed in a macro call than defined in the header, the last argument contains all remaining arguments. If no default value is assigned to an argument, the default value is the '''empty string'''. If no seperator is spezified between two arguments, all whitespace characters are used as seperator.
:''<code>READ</code>-style'' argument parsing: The arguments are parsed as strings, internally using the [[Programmer_Guide/Command_Reference/READ|READVAR]] command before the first macro statement is executed. The programmer can select arbitrary separators by supplying the <code>separator<sub>n</sub></code> arguments. If an argument value is specified in the call, it is assigned to the argument, otherwise the default value defined in the header is assigned to the argument. A default value must not contain whitespace characters. If more arguments are passed in a macro call than defined in the header, the last argument contains all remaining arguments. If no default value is assigned to an argument, its value is the empty string. If no separator is specified between two arguments, all whitespace characters are considered separators.
:important variables: '''#ARGV''', '''#ARGC'''
:important variables: <var>#ARGV</var>, <var>#ARGC</var>


<code>[MACRO <var>macroname</var> ARG: <var>argname1</var>{=<var>defaultvalue1</var>} ...]<BR>[MACRO macroname ARGS: <var>argname1</var>{=<var>defaultvalue1</var>} ...]</code>
[MACRO <var>macroname</var> ARG: <var>argname1</var>{=<var>defaultvalue1</var>} ...]
:ARG-style argument parsing. This form uses the ARG command, and stores each argument in the i-th argument variable. The parsing rulses are the same as for build-in commands without options.
[MACRO <var>macroname</var> ARGS: <var>argname1</var>{=<var>defaultvalue1</var>} ...]
:ARG-style argument parsing. This form uses the [[Programmer_Guide/Command_Reference/ARG|ARG]] command, and stores each argument in the i-th argument variable. The parsing rules are the same as for build-in commands without options.


<code>[MACRO <var>macroname</var> ARGOPT: <var>argname1</var>{=<var>defaultvalue1</var>} ...]</code>
[MACRO <var>macroname</var> ARGOPT: <var>argname1</var>{=<var>defaultvalue1</var>} ...]
:ARGOPT-style argument parsing. This form uses the [[Programmer_Guide/Command_Reference/ARG|ARG]] command, and stores each argument in the i-th argument variable. The parsing rulses are the same as for build-in commands with options. The [[Programmer_Guide/Command_Reference/ARG|ARG]] command ca be used to access/check options and option values.
:ARGOPT-style argument parsing. This form uses the [[Programmer_Guide/Command_Reference/ARG|ARG]] command, and stores each argument in the i-th argument variable. The parsing rules are the same as for build-in commands with options. The [[Programmer_Guide/Command_Reference/ARG|ARG]] command ca be used to access/check options and option values.
:important variables: '''#QARGV''', '''#QARGC'''
:important variables: '''#QARGV''', '''#QARGC'''


For some examples of macros using different argument parsing styles, see the scirpt <code>script\examples\macro argument_parsing_example.sts</code>.
For some examples of macros using different argument parsing styles, see the script <code>script\examples\macro argument_parsing_example.sts</code>.


====Statements====
===Statements===
Each macro statement contains one command and/or a <var>label</var>. The command consists of the <var>commandstring</var> and the optional <var>targetstring</var>. The statements are processed line by line. Special [[#Control_statements|control statements]] can be used to change the processing order. The syntax of a statement is as follows:
Each macro statement contains one command and/or a <var><span id="labels">label</span></var>. The command consists of the <var>commandstring</var> and the optional <var>targetstring</var>. The statements are processed line by line. Special [[#Control_statements|control statements]] can be used to change the processing order. The syntax of a statement is as follows:


<code>{<var>label</var>'':''}{{<var>targetstring</var> :=} <var>commandstring</var>}</code>
<code>{<var>label</var>'':''}{{<var>targetstring</var> :=} <var>commandstring</var>}</code>


;<var>label</var>: A label defines a target which can be used to change the program flow. A label is a string without whitespace and must start with a letter or the underline character (''_''). It must be unique within the enclosing macro. If a label is used to define a local subroutine/function that can be called using the ([[Programmer_Guide/Command_Reference/GOTO_and_GOSUB|GOSUB]] command, its definition can also define whether parameters passed by the caller are processed or not. The argument parsing is defined in brackets with the same syntax and rules as for the macro header.
;<var>label</var>: A label defines a target which can be used to change the program flow. A label is a string without whitespace and must start with a letter or the underline character (''_''). It must be unique within the enclosing macro. If a label is used to define a local subroutine/function that can be called using the ([[Programmer_Guide/Command_Reference/GOSUB|GOSUB]] command, its definition can also define whether parameters passed by the caller are processed or not. The argument parsing is defined in brackets with the same syntax and rules as for the macro header.
::Examples:
::Examples:
::<code>jumpToMe:<br>callMe(read: #arg1';'#arg2):<br>callMeWithOptions(argopt: #arg1=1 #arg2 #arg3):</code>
::<code>jumpToMe:<br>callMe(read: #arg1';'#arg2):<br>callMeWithOptions(argopt: #arg1=1 #arg2 #arg3):</code>
Line 81: Line 89:


==Definition of Classes==
==Definition of Classes==
S_TOOLS-STx classes are actually macros with built-in functionality for instantiation, destruction and message handling. The implementation of classes and object oriented programming is based on the class source code (described here) and the [[Programmer_Guide/Shell_Items/Instance|instance items]], which implements the runtime instance of a class.
{{Stx}} classes are actually macros with built-in functionality for instantiation, destruction and message handling. The implementation of classes and object oriented programming is based on the class source code (described here) and the [[Programmer_Guide/Shell_Items/Instance|instance items]], which implements the runtime instance of a class.


====Header====
====Header====
A class is defined by one of the following section header.
A class is defined by the following section header.


<code>[{<var>visiblity</var>:}CLASS classname {parentclass}]</code>
<code>[{<var>visiblity</var>:}CLASS classname {parentclass}]</code>


;visibility: The [[#Section_header|visibilty]] defines from where the class can be instantiated or called.
;<var>visibility</var>: The [[#Section_header|visibilty]] defines from where the class can be instantiated or called.


;classname: The name of the class.
;<var>classname</var>: The name of the class.


;parentclass: The name of the parent class. If not specified, the class has no parent class. It is recommened that classes are directly or indirectly derived from [[Programmer_Guide/Class_Library/CObj|CObj]]. If [[Programmer_Guide/Class_Library/CObj|CObj]] is not used as base class, some standard functionalities (like message handling, serialisation, ..) are not available to the class.
;<var>parentclass</var>: The name of the parent class. If not specified, the class has no parent class. It is recommended that classes are directly or indirectly derived from [[Programmer_Guide/Class_Library/CObj|CObj]]. If [[Programmer_Guide/Class_Library/CObj|CObj]] is not used as base class, some standard functionalities (like message handling, serialisation, ..) are not available to the class.


====Statements====
====Statements====
In STx a class is a [[#Definition_of_macros|macro]] with some special features. Therefore the statements are defined and processed in the same way as for [[#Definition_of_macros|macro]]. The only (but big) difference is, that the class source code contains the definitions of the member functions. The member functions define the behaviour of the instances of a class. Member functions are defined as follows.
In {{STX}} a class is a [[#Definition_of_macros|macro]] with some special features. Therefore the statements are defined and processed in the same way as for [[#Definition_of_macros|macro]]. The only (but big) difference is, that the class source code contains the definitions of the member functions. The member functions define the behaviour of the instances of a class. Member functions are defined as follows.


<code><var>scope</var>_<var>functionname</var></code>:
<code><var>scope</var>_<var>functionname</var></code>:


;scope: The scope defines from the the member function can be called. The following scopes are defined:
;<var>scope</var>: The scope defines from where a member function can be called. The following scopes are defined:
::*public: The function is visible everywhere. It can be called from macros and instances of all other classes.
:*'''public''': The function can be called from macros and from instances of all other classes.
::*proteced: The function can be called from instances of same class and from instances of classes derived from this class.
:*'''proteced''': The function can be called from instances of same class and from instances of classes derived from this class.
::*private: The function can only be called from instances of the same class.
:*'''private''': The function can only be called from instances of the same class.


;functionname: This is the name of member function which must be specified in the call.
;functionname: This is the name of member function which must be specified in the call.
Line 111: Line 119:
*It is possible to include the defintion of the argument parsing in the definition of a member function as described for local subroutines of [[#Definition_of_macros|macros].
*It is possible to include the defintion of the argument parsing in the definition of a member function as described for local subroutines of [[#Definition_of_macros|macros].
*Like local subroutines, a member function must be terminated with an [[Programmer_Guide/Command_Reference/EXIT|EXIT]].
*Like local subroutines, a member function must be terminated with an [[Programmer_Guide/Command_Reference/EXIT|EXIT]].
*A class can be used like a macro. This means if the name of a class is specified as command it is called like a macro. This feature can be used to implement ''static'' functions.


==Definition of SPUs==
A signal processing unit (SPU) defines a circuit consisting of elements and connections that can be used to perform a signal processing task. Like a class, the SPU source code defines the prototype of a circuit. The corresponding runtime instance is the [[Programmer_Guide/Shell_Items/SPU|SPU item]].


====Header====
<code>[SPU <var>name</var> {<var>arg1</var> ...} OUT {<var>out1</var> ...}]</code>


;<var>name</var>: The name (''class'') of the SPU. This name is used to refer to this circuit in other SPU sources and for the [[Programmer_Guide/Shell_Items/SPU#SPU_Item_Creation|instantiation of SPU items]].


<code>[CLASS <var>name</var> {<var>parent</var>}]</code>
;<var>arg1, ...</var>: The argument list. Each argument is separated from the previous one by a whitespace. The arguments provide the SPU with parameters. Parameters can be either numeric constants or strings (e.g. the name of a soundfile or a data file, the name of a wave-item, the id of a shell-item output, the output name of a value- or spu-item etc.). A list of arguments is optional (i.e. an SPUnit does not necessarily have to act on input data; e.g. signal/data sources like a noise generator)
 
<code>CLASS</code>
 
The mandatory keyword to define a class section<var>class</var>
 
The class name<var>parent</var>
 
The name of the parent class'''Class Functions'''
 
Classes can be used in two ways:
 
*First a class can be called like a macro. In this case the execution begins with the first statement. This feature can be used to implement static functions. Static functions are class functions which can be called directly without creating an instance. The static functions must be defined before the first member function. If a class does not implement any static functions, the first statement in the sourcecode must the an <code>EXIT</code> command, to avoid execution of member functions on instantiation.
<pre>
[class simple cobj]
// no static functions
exit
</pre>
*Classes can be used as objects. In this case, first an instance of the class must be created (a shell instance-item) and than the member functions of the instance can be called. The member functions are defined in the class sourcecode with special label names.
<pre>
// instantiate the CDlgMap class
#dmap := cobj new cdlgmap
if '$#dmap[?]' != 'instance' em -1 ; Failed to create instance of CDlgMap
</pre>
or alternatively
 
<pre>
// You can also instantiate the CDlgMap class as follows,
// if the class calls the cobj constructor itself
// (e.g. the class exits using the following command:
// exit 1 set $(CObj new CDlgMap $#argv)
#dmap := cdlgmap
if '$#dmap[?]' != 'instance' em -1 ; Failed to create instance of CDlgMap
</pre>
 
 
'''Member function labels'''
 
Class member functions can be defined as public, protected or private.
 
public_<code><name></code>:
 
Defines the public member function <code><name></code> which can be called from every interface.protected_<code><name></code>:
 
Defines the protected member function <code><name></code> which can be called by member functions of the class and its derived classes.private_<code><name></code>:
 
Defines the private member function <code><name></code> which can only be called by member functions of the class itself.The keywords <code>public_</code>, <code>protected_</code> or <code>private_</code> are mandatory when defining a member function.
The name must be formatted according to the label name rules and must be unique.
All public and protected member functions are virtual, with the consequence that they can be overridden in derived classes.'''Member function parameters'''
 
The way that parameters passed to a member function are parsed, depends on how the function is defined.
 
The basic function with no specified parameter will store the passed parameters in the variable <code>#argv</code>.
 
The parameters can, however, also be specified in the function definition, and automatically parsed accordingly.
 
E.g.:
 
<pre>
public_simple:
        // arguments are automatically stored as a string in #argv
        // arguments can also be parsed using the ARG command.
exit
public_advancedread(read: #arg1=10';'#arg2=text';'#arg3):
        // arguments parsed using semi-colon as separator.
        // arguments stored in #arg1, #arg2 and #arg3
        // default values specified for #arg1 and #arg2
        // arguments are all available in #argv and also accessible using the <code>ARG</code> command.
exit
public_advancedarg(arg: #arg1 #arg2 #arg3):
        // arguments are parsed using ARG
exit
</pre>
'''Member function source'''
 
A member function begins with the first statement following the member function label and ends with an <code>EXIT</code> statement. The member function source code has the same syntax as a macro with the following exceptions:
 
*When a member is called, execution starts directly at the member function label. Therefore, each member function must implement its own argument parsing (like a subroutine).
*On entry to a member function the variables <code>#ARGV</code> (argument string), <code>#THIS</code> (name of the instance item) and <code>#MAC</code> (name of macro/class) are defined.
*From inside a member function, the instance environment of the instance used in the call command can be accessed directly.
'''Class Function Call'''
 
If a class name is used in a macro call, the class code is executed like a macro. This feature can be used to implement 'static functions' of a class. If you do not want static functions, your class source code must start with an EXIT statement.
 
=====static functions:=====
 
<code>classname {argumentstring}</code>
 
classname
 
Name of a class.
 
argumentstring
 
Argumentstring to passed to the class. The same processing as for macro calls is applied.Member functions of a class can only be called for an instance of a class. Therefore it is necessary to create a shell instance-item before the instance member functions can be used.
 
=====member functions:=====
 
<code>instancename functionname argumentstring</code>
 
<code>instancename classname::functionname argumentstring</code>
 
instancename
 
Name of a shell instance-item.functionname
 
Name of a member function of the class or of a parentclass of the class.classname
 
Name of a parentclass of the class.
 
argumentstring
 
Argumentstring to passed to the member function. The same processing as for macro calls is applied.Notes:
 
The return value of all types of class functions is stored in the variable RESULT.
 
'''Class - A simple example'''
 
<pre>
///////////////////////////////////////////////////////////////////////////////
//
//  File:          simple_class.sts
//  Description:    Example class implementation and instantiation.
//  Author:        Jonnie White
//  History:        2006-02-23  created
//
///////////////////////////////////////////////////////////////////////////////
 
///////////////////////////////////////////////////////////////////////////////
//  Class:          simple
//  Description:    Display basic class functionality (instantiation, output,
//                  destruction).
[class simple cobj]
 
// no static functions
 
exit
 
// member functions
 
public_construct:
    // assign parameters to member variable &text
    &text := 'simple class'
    readvar #argv &text
    exit 1 int 0 // note that the construct MUST return 0
   
public_destruct:
    // do nothing
    exit
 
public_print:
    // print parameter as text in a dialog box or
    // print the contents of the member variable &text
    #text := '$&text'
    readvar #argv #text
    um $#text
exit
 
///////////////////////////////////////////////////////////////////////////////
// macro to test the class
[macro main]
 
// instantiate
#t := cobj new simple
if '$#t[?]' != 'instance' em -1 ; Failed to instatiate the class
// call print function
$#t print
// destroy the class
$#t destroy
 
exit
</pre>
 
 


 
;<var>out1, ...</var>: The outputs list declares the names of all the outputs of the SPU. Each name is separated from the next by a whitespace. The type of data assigned to each output is defined in the output assignments where they are connected to element outputs.
Local sub-routines
A local sub-routine is a part of a macro which begins at a label (E.g. MySubRoutine:) and ends with an EXIT command. Sub-routines can only be called from within that macro. The return value of a sub-routine call is stored in the shell variable RESULT.
 
The syntax for calling a local subroutine is as follows:
 
GOSUB label {argumentstring}
 
or
 
GOSUBX label {argumentstring}
 
Where GOSUB is an in-built command which calls a sub-routine, GOSUBX is identical to GOSUB, except that it uses the caller's local variable namespace. The argumentstring is passed to the sub-routine as it would be to a macro (E.g. it is available by default in the local variable #argv).
 
Built-in commands
Built-in commands are commands which are executed directly by the interpreter. A list of built-in commands can be found in the Command Reference.
 
The parsing of the argument string differs from that of other command types.
 
The syntax is as follows:
 
command {argument1 {argument2 … {options}}
 
Where command is the name of an in-built command (see the Command Reference). It must be the first word on the line and must not be a quoted string.
 
Where argumentX is the x-th argument for the command. The meaning of arguments depends on its place in the command line. There are two formats for arguments:
 
normal arguments - strings containing no white spaces and are not enclosed in quotes. They are separated from other arguments by a white space or a quote.
quoted arguments - strings enclosed in quotes containing any possible character
Where options are strings which are not enclosed in quotes and start with an slash ('/'). An option can be used as switch (/optionname) or to specify a value (/optionname=optionvalue). Only the first letter of optionname is used to identify the option. In some cases (depending on the command) the optionname is case sensitive. Both types of option formats must not contain white spaces. The meaning of an option depends only on the optionname and not on the placement of the option. This means that options can be specified anywhere on in a command string, but may not be specified in quoted strings.
 
Program Flow Control
GOTO:
 
GOTO target {alternatetarget}
 
GOTO
 
Continue execution at specified label (build-in command)
 
target
 
Name of the label where the execution should continue
 
alternatetarget
 
Name of the label where the execution should continue if label target do not exist.


Notes:
Notes:
*The names of arguments, outputs and elements must be unique within the SPU source code (i.e. you cannot use an argument name for an output name).
*Either the argument list or the output list can be empty, but not both.


If the label target do not exist and no alternate target is specified or it is also not found, the execution of the macro ends.
====Statements====
IF:
The statements of the SPU source code can be grouped into four categories.
 
IF condition command
 
IFNOT condition command
 
IF
 
Execute command if condition is true (build-in command)
 
IFNOT
 
Execute command if condition is false (build-in command)


condition
;default argument assignments:
:<code><var>argX</var> = <var>valueX</var></code>
:This statement assigns the default value <var>valueX</var> to the argument <var>argX</var>. This value is used if no value is given for this argument on instantiation. The default value must be a numeric constant or a string (e.g. 5 or 'a string'). Assigning default values is optional. An argument without a default value, however, must be passed. Default values are used in reverse order. If two arguments are passed, where four have been defined, the third and fourth arguments are assigned their default values. The default values must be assigned before the argument is used (e.g. in a function statement).
:;{{STx}} 4.0: The default values can be assigned in the header using the syntax <code><var>argX</var>=<var>valueX</var></code>. The whole assignment must not contain a whitespace, because whitespaces are used for argument seperation.


Condition to be evaluated and tested. A detailed description can be found in the command reference
;definition statement:
:<code>elementX = typeX</code>
:A definition statement defines the name <var>elementX</var> and the type (class) <var>typeX</var> of a element of an SPU. This element is local to this SPU (i.e. is not visible outside of the SPU). Any signal processing atom or SPU can be used for <var>typeY</var>. All SPU used in the source code must be loaded before instantiating an SPU item. Once an element is defined it can be used in the function statements and output assignments.


command
;function statement:
:<code><var>elementX arguments</var></code>
:The function statements interconnect and 'execute' the elements. The arguments passed to the element are processed within the element and returned to the element's outputs. The element's arguments can be numerical constants, strings, the outputs from other elements, or the SPU's input arguments. They must be passed in the same sequence as defined in the element type's declaration. The function statements implement the interconnection between the SPU elements. Elements must be defined before they can be used. Parsing rules for element arguments:
::*'''$'''<var>argX</var> is replaced by the value of <var>argX</var> (where <var>argX</var> is a name from the argument list)
::*arguments passed to an element are separated by blank spaces
::*arguments enclosed in quotes can themselves contain spaces
:;{{STX}} 4.0: It is now possible to use input assignments in the function statements, instead of the ordered list of input values.
::<code><var>elementX inY=argument</var> ... </code>
::Both function statement formats can be used inside a SPUnit source section, but the new should be prefered. If the assignment format is used, it is not necessary to specify the inputs in the right order.


Conditional command. Can be any type of command except an inline-command (see commanline string replacement described below)
;output assignment:
:<code><var>outX</var> = <var>elementY.outZ</var></code>
:The output assignments determine which element outputs are made available at the SPU outputs (to be connected to shell items or used in other SPU's using this SPU as an element). Every SPU output must have one output statement. An element output, however, can be assigned to more than one SPUnit output. Elements must be defined before they can be connected to outputs.
:;{{Stx}} 4.0: The outputs can be assigned in the header using the syntax <code><var>outX</var>=<var>elementY.outZ</var></code>. The whole assignment must not contain a whitespace, because whitespaces are used for  seperation. This is the only case where an element can be used before it is defined!


block IF:
==Escape and Continuation Character==
In some cases tag or parsing characters should be used as normal characters (e.g. arguments for commands or a part of a string). In this case the '''escape character''' ''`'' (back-quote) can be used to suppress the interpretation of the following character.


IF condition THEN
The escape character has a special meaning if it is the last character on a line. In this case it is interpreted as '''continuation character''' and the next line is concatenated to the current. This feature can be used to concatenate two or more lines. Concatenation applies to statements but also to section headers.


command block
==Preprocessing==
The {{STx}} preprocessor may be used for conditionally skipping or including parts of an {{STX}} source file depending on which preprocessor constants have been defined (and which haven't). In the directory script\examples, you will find a script called '''preprocessor.sts''' showing several ways of using the preprocessor.


{ELSE IF condition THEN
Every preprocessor command must start either with the character '''!''' (exclamation mark), or with the character ''']''' (closed square bracket). Although not strictly enforced (the preprocessor only issues a warning otherwise), either character should be placed in the very first column of the respective line.


command block
For defining and undefining a preprocessor constant, there are the preprocessor commands '''define''' and '''undef''':
<pre>! define CONSTANT1
! define CONSTANT2
! undef CONSTANT1</pre>
:*Like the most other keywords and names used in {{Stx}}, preprocessor statements and constants are case-insensitive, meaning that '''CONSTANT1''', '''constant1''', and '''CoNsTaNt1''' are the same constant.
:*Note that (for the time being), the only property of preprocessor constants is their being defined or being undefined. It is currently not possible (since it would currently make no sense) to assign a value to a constant.


}
The conditional '''ifdef''', '''elif''', '''else''', and '''endif''' preprocessor statements cause the macro interpreter conditionally to skip part of the macro source code. See for yourself:
 
<pre>! ifdef CONSTANT
{ELSE
writelog 'This statement will be executed if CONSTANT is defined'
 
! else
command block
writelog 'This statement will be executed unless CONSTANT is defined'
 
! endif</pre>
}
 
END
 
A block if is a construct which consists of an IF-THEN clause (mandatory), one or more ELSE-IF-THEN clauses (optinal), one ELSE clause (optional) and is closed with an END statement (mandatory). The command block of the first clause where the condition is true is excuted. If no condition is true and an ELSE clause exists, the command block of the ELSE clause is executed.
 
Notes:


For the conditions in block ifs the same syntax as for the normal IF is used.
With the '''if''' command, there is also support for complex conditions:
If no END statement can be found for a block if, the macro can not be loaded.
<pre>! if defined(CONS1) || defined(CONS2) && defined(CONS3)
DO loop:
writelog 'This statement will be executed if either CONS1 or both of CONS2 and CONS3 are defined'
! elif defined CONS4 && ! defined CONS5
writelog 'This statement will be executed if the preceding statement is not, and if CONS4 is defined and CONS5 is not
! else
writelog 'This statement will be executed if neither of the preceding statements were'
! endif</pre>
:*You may, but need not enclose the argument of the '''defined''' function (i.e. the name of a constant) in brackets.  
:*You may build up complex expressions with the '''&&''' (and), '''||''' (or), and the '''!''' (not) operator.


A loop begins with the DO WHILE or DO UNTIL statement and is closed with an END statement. The command block is executed while (DO WHILE) or until (DO UNTIL) the condition specified in the DO statement is true.
Unlike in other conditional expressions used in {{STX}} (e.g. the [[Programmer_Guide/Command_Reference/IF|IF command]]) which are evaluated strictly from left to right, you can group expressions with brackets. If you do not use brackets, '''&&''' will take precedence over '''||''', as it normally does (and contrary to what {{STx}} normally does due to historical reasons).
<pre>! if (defined(CONS1) || defined CONS2) && (defined(CONS3) ||defined(CONS4))</pre>


DO WHILE condition
There are a few additional preprocessor statements you may find useful:


command block
:;<code>!include <var>filepath</var></code>: With the include statement, you may textually merge some other files into the current macro (just like with the "#include" preprocessor statement in C, or with COBOL copy books). Note that it is (for obvious reasons) not possible for a file to include itself, or to include a file that includes a file that, in turn, includes a file including the first file. If you try to, macro interpretation will abort with an error message. If the file name supplied to the include statement is not an absolute path, the preprocessor will first look for the respective relative path in the current directory and, on failure, will look for it in directory where the including file is situated. Note that, for the time being, file inclusion may not be nested for more than forty-two levels.
:;<code>!showdef</code> or <code>!showdef <var>constant</var></code>: Without arguments, this command will print a list of all preprocessor constants currently defined. With an argument supplied, the command will show if the argument is a preprocessor constant that is currently defined.
:;<code>!warn <var>msg</var></code>: This statement causes the script loader to display a user-defined warning message. Execution of the script is not impaired by issuing a warning.
:;<code>!error <var>msg</var></code>: This statement causes the {{STX}} script loader to issue a user-defined error message and to cancel loading the source file.


END
==Other Source File Sections==
The standard sections of a source file (<code>macro</code>, <code>class</code>, <code>spu</code>) contain the code which is loaded and interpreted by {{STx}}.


DO UNTIL condition
===Libraries===
[Libraries]
libfile1
libfile2
...
The <code>Libraries</code> section can be used to specify other source files (libraries), to be loaded '''after''' the script file. Files listed in this section must be {{STX}} script files located in the ''current directory'' or the directoy of the main script file (variable <code>ScriptFileDirectory</code>). This section is processed when a script is loaded into the [[Programmer_Guide/BScript|script runtime environment]].
* Note: The <Code>Libraries</code> section can not be used to load the '''parents''' of classes defined in a script file, because parents must be loaded before derived classes!


command block
===Scripts===
[Scripts]
name1 text1
name2 text2
...
The <code>Scripts</code> section defines the macro- and class-sections which should be displayed in the [[User_Guide/The_Script_Controller|Script Controller]].
:If a <code>Scripts</code> section exists, the lines of this section are listed in the combo box '''Macro''' of the [[User_Guide/The_Script_Controller|Script Controller]] and the first word of each line is used as macro-name,
:otherwise the headers of all global macros and classes of a script file are displayed in the macro list.
This section is processed by the Script Controller dialog.


END
===User Defined===
A source file may also contain other sections that can be used for many purposes. e.g.:
:* initialize data tables
:* define the standard (default) values of a setup dialog
:* define a dialog template
:* ...


In a loop the special control commands can be used:


BREAK -> leave the loop and continue with the first command after the loop
The sections of a source file should only be loaded. Do not save dynamic data (like ''current settings'') in a source file. If a section is written to a source file (e.g. via the macro [Programmer_Guide/Macro_Library/SECTIONFILE|SectionFile]), the content is not destroyed, but the text formatting is changed and all comments are removed.
CONTINUE -> skip the rest of the command block and continue with the DO statement
© 2009 The Austrian Academy of Sciences Acoustics Research Institute

Latest revision as of 08:50, 16 August 2019

The source code is the text which is loaded by the STx source code loader and which is interpreted and executed by an instance of the STx command interpreter (called shell). A source file is a text file containing source code. By convention, source files end with the extension stx (for library packages and applications) or sts (for scripts to be loaded and executed via BScript). Examples of scripts can be found in the directory scripts\examples in the STx installation directory. STx source files use a section file format, where each section starts with a section header. Each source section delineates a section of source code. The code runs from the header to the next header, or to the end of the file.

Section Header

The section header starts a new section, defining the scope, type and the name of the source code contained in the body of the respective section. The section header must be enclosed within square brackets, and the opening bracket must be the first character in the line. There must not be any text behind the closing bracket except, optionally, a comment.

[{scope:}sstype ssname {ssargs}]
scope
The scope of a section defines from where the source code object can be accessed, instantiated or called. Source headers without an explitic scope are GLOBAL. The following scope keywords are currently supported.
GLOBAL
The section code is visible everywhere. This is the default.
LOCAL
The section code is visible only for code inside the same source file. A local macro can only be called, and a local CLASS or SPU can only be instantiated, from macros defined in the same source file.
MAIN
Defines the respective section (which must be defining a macro) as the main macro of an STx application. A main macro must be called by the system macro AppMain. This keyword is applicable to macro and class sections only, and should only be used for the main function of an STx application but not for scripts.
SHELL
Defines the section code as a shell startup code, meaning that the macro implements the startup code of a command interpreter instance (shell) and can only be used in the shell. This keyword is applicable to macro and class sections only.
MSGHANDLER
Defines a message handler macro, which can only be called from the system macros GetMessage or DispatchMsg.
sstype
Defines the type of source code in the section. The types macro, class and SPU have a defined meaning in the STx scripting language. Other, user-defined, types may also be used (e.g. to store data). Such user-defined sections will be ignored by STx. They may be accessed via the SectionFile macro or directly with the file item functions. The section script processing application uses the special types libraries and scripts. If an unknown section type is detected by the loader, the section is ignored.
ssname
The name identifying this source code section. This is used to access the source code later on (e.g. to call a macro, to create an SPU item, to create a instance item of a class, to derive a class,…). The name must be unique in the namespace where the source code is loaded, as defined by the section type, sstype. Source sections of type macro and class are loaded into the same namespace. A separate namespace is used for SPU items.
ssargs
The meaning of this part of the header depends on the type of the source section.

The parameters sstype and ssname are mandatory for the types macro, class and SPU, whilst scope and ssargs are optional, and depend on sstype. All keywords, names and other parts of the header are not case-sensitive.

Examples

[LOCAL:MACRO MacroExample1]
   // This macro called "MacroExample1" will be visible only locally
   …

[MACRO MacroExample2 #args]
   // This macro called "MacroExample2" will be globally visible
   …

[SPU DSPCircuit1 #in1 #in2 OUT #out1]
   …

Section body

The section body consists of statements (actually, there must be at least one statement per section), of empty lines (which are ignored) and of comments (which are also ignored). The section body ends with the next section header or with the end of the file.

comments
A comment is part of the source code that is there for documentation purposes. It is ignored by the loader. A comment can be placed wherever a whitespace character is allowed. The standard C++ comment tags "//" and "/* … */" can be used in STx source code.
line comment
starts with the tag "//" and ends at the end of the same line.
block comment
is opened with the tag "/*" and closed with the tag "*/". A block comment can be spanned over more than one line. If the begin and end tag of a block comment is on the same line, the comment is treated like a whitespace character, otherwise like an end of a line.
In a quoted string, the comment tags are interpreted as normal text and not as tag, which is probably the expected behaviour. It is also possible to escape one character of a comment tag (like: `//) to avoid its interpretation.
statements
A statement is that part of a line which remains after removing comments, and leading and trailing white space. In macros and classes, statements are label definitions, definitions of local functions or member functions and/or commands. In SPUs, the statements are used to define and connect the circuit elements.

Definition of Macros

Header

A macro is defined by one of the section headers listed below. The possible formats differ only in how arguments are processed or parsed before the first macro statement is executed. The optional scope tag is omitted in this description, because it described in detail in the chapter section header.

[MACRO macroname]
Arguments are stored in the variables #ARGV and #QARGV, without further processing or parsing. The user program is free further to process these data, e.g. by using the READVAR and/or the ARG command.
important variables: #ARGV, #QARGV
[MACRO macroname {READ:} argname1{=defaultvalue1} {separator1} …]
READ-style argument parsing: The arguments are parsed as strings, internally using the READVAR command before the first macro statement is executed. The programmer can select arbitrary separators by supplying the separatorn arguments. If an argument value is specified in the call, it is assigned to the argument, otherwise the default value defined in the header is assigned to the argument. A default value must not contain whitespace characters. If more arguments are passed in a macro call than defined in the header, the last argument contains all remaining arguments. If no default value is assigned to an argument, its value is the empty string. If no separator is specified between two arguments, all whitespace characters are considered separators.
important variables: #ARGV, #ARGC
[MACRO macroname ARG: argname1{=defaultvalue1} ...]
[MACRO macroname ARGS: argname1{=defaultvalue1} ...]
ARG-style argument parsing. This form uses the ARG command, and stores each argument in the i-th argument variable. The parsing rules are the same as for build-in commands without options.
[MACRO macroname ARGOPT: argname1{=defaultvalue1} ...]
ARGOPT-style argument parsing. This form uses the ARG command, and stores each argument in the i-th argument variable. The parsing rules are the same as for build-in commands with options. The ARG command ca be used to access/check options and option values.
important variables: #QARGV, #QARGC

For some examples of macros using different argument parsing styles, see the script script\examples\macro argument_parsing_example.sts.

Statements

Each macro statement contains one command and/or a label. The command consists of the commandstring and the optional targetstring. The statements are processed line by line. Special control statements can be used to change the processing order. The syntax of a statement is as follows:

{label:}{{targetstring :=} commandstring}

label
A label defines a target which can be used to change the program flow. A label is a string without whitespace and must start with a letter or the underline character (_). It must be unique within the enclosing macro. If a label is used to define a local subroutine/function that can be called using the (GOSUB command, its definition can also define whether parameters passed by the caller are processed or not. The argument parsing is defined in brackets with the same syntax and rules as for the macro header.
Examples:
jumpToMe:
callMe(read: #arg1';'#arg2):
callMeWithOptions(argopt: #arg1=1 #arg2 #arg3):
Note: To get a more readable source code, labels and commands should be placed on separated lines.
commandstring
A command string is the command to be executed. It can be a built-in command, a local subroutine call, a macro call, a member function call or a program flow control command. Normally commands are executed in the order of appearance. Program flow control commands can be used to change this order. Before a command string is parsed and the command is executed, three pre-processing steps are applied.
Variable replacement
A part with the format $name is replaced by the value of the variable name or removed if no value is assigned to this variable. The tag character $ may occur anywhere in the string. The variable name must be delimited by a non-name character. Multiple or recursive variable replacement is currently not implemented (e.g. it is not possible to replace $$name by the value of the variable referenced by the variable name).
Inline command
If a part with the format $(text) is detected, the command line part text is separated and treated as a command. The format of the inline command text is: {targetstring :=} commandstring. At the end of the execution of the inline command, the string $(text) is replaced by the result of the inline command. Inline commands can be nested.
Shell item replacement
  • Any part of a command string with the format name[?] is replaced by the type of the shell item name. The name must be delimited by a non-name character. This format is often used to select functions according to the type of an item.
  • Any part of the command string with the format name[] is replaced by the number of attributes of the item name. This syntax element is mainly used to retrieve the number of entries stored in a table item.
  • Any part of the command string with the format name[!attrid{,subid,...}] is replaced by the value of the addressed attribute of the shell item name. Data and status values or the configuration settings of items can be retrieved using this syntax. Item attributes are replaced after the processing of variables and inline commands in order to provide the possibility of using variables for addressing and identifying an item or attribute.
After applying all replacement rules, the resulting command line is a string with the format: cmd or cmd args, where cmd is a non-quoted string separated from args by whitespaces. The string cmd must be an executable command and args contains the arguments and options for the command.
targetstring
If this optional part is specified, it is used as target for the result of the commandstring. The same replacement rules as described above are applied, but the resulting string is used as name/id of a target and not as executable command. This means the result of the command defined by the commandstring is assigned to the target defined by the targetstring. The assignment format can not be used with the most control commands (like IF, FOR, GOTO), because they do not have a result value.

Definition of Classes

STx classes are actually macros with built-in functionality for instantiation, destruction and message handling. The implementation of classes and object oriented programming is based on the class source code (described here) and the instance items, which implements the runtime instance of a class.

Header

A class is defined by the following section header.

[{visiblity:}CLASS classname {parentclass}]

visibility
The visibilty defines from where the class can be instantiated or called.
classname
The name of the class.
parentclass
The name of the parent class. If not specified, the class has no parent class. It is recommended that classes are directly or indirectly derived from CObj. If CObj is not used as base class, some standard functionalities (like message handling, serialisation, ..) are not available to the class.

Statements

In STx a class is a macro with some special features. Therefore the statements are defined and processed in the same way as for macro. The only (but big) difference is, that the class source code contains the definitions of the member functions. The member functions define the behaviour of the instances of a class. Member functions are defined as follows.

scope_functionname:

scope
The scope defines from where a member function can be called. The following scopes are defined:
  • public: The function can be called from macros and from instances of all other classes.
  • proteced: The function can be called from instances of same class and from instances of classes derived from this class.
  • private: The function can only be called from instances of the same class.
functionname
This is the name of member function which must be specified in the call.

Notes:

  • All public and protected' member functions are virtual. This means they can be overridden in derived classes.
  • The definition of a member function looks like a label in a macro, but can not be used as label. It defines the entry of a member function but not a target for GOTO or GOSUB commands.
  • It is possible to include the defintion of the argument parsing in the definition of a member function as described for local subroutines of [[#Definition_of_macros|macros].
  • Like local subroutines, a member function must be terminated with an EXIT.
  • A class can be used like a macro. This means if the name of a class is specified as command it is called like a macro. This feature can be used to implement static functions.

Definition of SPUs

A signal processing unit (SPU) defines a circuit consisting of elements and connections that can be used to perform a signal processing task. Like a class, the SPU source code defines the prototype of a circuit. The corresponding runtime instance is the SPU item.

Header

[SPU name {arg1 ...} OUT {out1 ...}]

name
The name (class) of the SPU. This name is used to refer to this circuit in other SPU sources and for the instantiation of SPU items.
arg1, ...
The argument list. Each argument is separated from the previous one by a whitespace. The arguments provide the SPU with parameters. Parameters can be either numeric constants or strings (e.g. the name of a soundfile or a data file, the name of a wave-item, the id of a shell-item output, the output name of a value- or spu-item etc.). A list of arguments is optional (i.e. an SPUnit does not necessarily have to act on input data; e.g. signal/data sources like a noise generator)
out1, ...
The outputs list declares the names of all the outputs of the SPU. Each name is separated from the next by a whitespace. The type of data assigned to each output is defined in the output assignments where they are connected to element outputs.

Notes:

  • The names of arguments, outputs and elements must be unique within the SPU source code (i.e. you cannot use an argument name for an output name).
  • Either the argument list or the output list can be empty, but not both.

Statements

The statements of the SPU source code can be grouped into four categories.

default argument assignments
argX = valueX
This statement assigns the default value valueX to the argument argX. This value is used if no value is given for this argument on instantiation. The default value must be a numeric constant or a string (e.g. 5 or 'a string'). Assigning default values is optional. An argument without a default value, however, must be passed. Default values are used in reverse order. If two arguments are passed, where four have been defined, the third and fourth arguments are assigned their default values. The default values must be assigned before the argument is used (e.g. in a function statement).
STx 4.0
The default values can be assigned in the header using the syntax argX=valueX. The whole assignment must not contain a whitespace, because whitespaces are used for argument seperation.
definition statement
elementX = typeX
A definition statement defines the name elementX and the type (class) typeX of a element of an SPU. This element is local to this SPU (i.e. is not visible outside of the SPU). Any signal processing atom or SPU can be used for typeY. All SPU used in the source code must be loaded before instantiating an SPU item. Once an element is defined it can be used in the function statements and output assignments.
function statement
elementX arguments
The function statements interconnect and 'execute' the elements. The arguments passed to the element are processed within the element and returned to the element's outputs. The element's arguments can be numerical constants, strings, the outputs from other elements, or the SPU's input arguments. They must be passed in the same sequence as defined in the element type's declaration. The function statements implement the interconnection between the SPU elements. Elements must be defined before they can be used. Parsing rules for element arguments:
  • $argX is replaced by the value of argX (where argX is a name from the argument list)
  • arguments passed to an element are separated by blank spaces
  • arguments enclosed in quotes can themselves contain spaces
STx 4.0
It is now possible to use input assignments in the function statements, instead of the ordered list of input values.
elementX inY=argument ...
Both function statement formats can be used inside a SPUnit source section, but the new should be prefered. If the assignment format is used, it is not necessary to specify the inputs in the right order.
output assignment
outX = elementY.outZ
The output assignments determine which element outputs are made available at the SPU outputs (to be connected to shell items or used in other SPU's using this SPU as an element). Every SPU output must have one output statement. An element output, however, can be assigned to more than one SPUnit output. Elements must be defined before they can be connected to outputs.
STx 4.0
The outputs can be assigned in the header using the syntax outX=elementY.outZ. The whole assignment must not contain a whitespace, because whitespaces are used for seperation. This is the only case where an element can be used before it is defined!

Escape and Continuation Character

In some cases tag or parsing characters should be used as normal characters (e.g. arguments for commands or a part of a string). In this case the escape character ` (back-quote) can be used to suppress the interpretation of the following character.

The escape character has a special meaning if it is the last character on a line. In this case it is interpreted as continuation character and the next line is concatenated to the current. This feature can be used to concatenate two or more lines. Concatenation applies to statements but also to section headers.

Preprocessing

The STx preprocessor may be used for conditionally skipping or including parts of an STx source file depending on which preprocessor constants have been defined (and which haven't). In the directory script\examples, you will find a script called preprocessor.sts showing several ways of using the preprocessor.

Every preprocessor command must start either with the character ! (exclamation mark), or with the character ] (closed square bracket). Although not strictly enforced (the preprocessor only issues a warning otherwise), either character should be placed in the very first column of the respective line.

For defining and undefining a preprocessor constant, there are the preprocessor commands define and undef:

! define CONSTANT1
! define CONSTANT2
! undef CONSTANT1
  • Like the most other keywords and names used in STx, preprocessor statements and constants are case-insensitive, meaning that CONSTANT1, constant1, and CoNsTaNt1 are the same constant.
  • Note that (for the time being), the only property of preprocessor constants is their being defined or being undefined. It is currently not possible (since it would currently make no sense) to assign a value to a constant.

The conditional ifdef, elif, else, and endif preprocessor statements cause the macro interpreter conditionally to skip part of the macro source code. See for yourself:

! ifdef CONSTANT
writelog 'This statement will be executed if CONSTANT is defined'
! else
writelog 'This statement will be executed unless CONSTANT is defined'
! endif

With the if command, there is also support for complex conditions:

! if defined(CONS1) || defined(CONS2) && defined(CONS3)	
writelog 'This statement will be executed if either CONS1 or both of CONS2 and CONS3 are defined' 
! elif defined CONS4 && ! defined CONS5	
writelog 'This statement will be executed if the preceding statement is not, and if CONS4 is defined and CONS5 is not 
! else	
writelog 'This statement will be executed if neither of the preceding statements were' 
! endif
  • You may, but need not enclose the argument of the defined function (i.e. the name of a constant) in brackets.
  • You may build up complex expressions with the && (and), || (or), and the ! (not) operator.

Unlike in other conditional expressions used in STx (e.g. the IF command) which are evaluated strictly from left to right, you can group expressions with brackets. If you do not use brackets, && will take precedence over ||, as it normally does (and contrary to what STx normally does due to historical reasons).

! if (defined(CONS1) || defined CONS2) && (defined(CONS3) ||defined(CONS4))

There are a few additional preprocessor statements you may find useful:

!include filepath
With the include statement, you may textually merge some other files into the current macro (just like with the "#include" preprocessor statement in C, or with COBOL copy books). Note that it is (for obvious reasons) not possible for a file to include itself, or to include a file that includes a file that, in turn, includes a file including the first file. If you try to, macro interpretation will abort with an error message. If the file name supplied to the include statement is not an absolute path, the preprocessor will first look for the respective relative path in the current directory and, on failure, will look for it in directory where the including file is situated. Note that, for the time being, file inclusion may not be nested for more than forty-two levels.
!showdef or !showdef constant
Without arguments, this command will print a list of all preprocessor constants currently defined. With an argument supplied, the command will show if the argument is a preprocessor constant that is currently defined.
!warn msg
This statement causes the script loader to display a user-defined warning message. Execution of the script is not impaired by issuing a warning.
!error msg
This statement causes the STx script loader to issue a user-defined error message and to cancel loading the source file.

Other Source File Sections

The standard sections of a source file (macro, class, spu) contain the code which is loaded and interpreted by STx.

Libraries

[Libraries]
libfile1
libfile2
...

The Libraries section can be used to specify other source files (libraries), to be loaded after the script file. Files listed in this section must be STx script files located in the current directory or the directoy of the main script file (variable ScriptFileDirectory). This section is processed when a script is loaded into the script runtime environment.

  • Note: The Libraries section can not be used to load the parents of classes defined in a script file, because parents must be loaded before derived classes!

Scripts

[Scripts]
name1 text1
name2 text2
...

The Scripts section defines the macro- and class-sections which should be displayed in the Script Controller.

If a Scripts section exists, the lines of this section are listed in the combo box Macro of the Script Controller and the first word of each line is used as macro-name,
otherwise the headers of all global macros and classes of a script file are displayed in the macro list.

This section is processed by the Script Controller dialog.

User Defined

A source file may also contain other sections that can be used for many purposes. e.g.:

  • initialize data tables
  • define the standard (default) values of a setup dialog
  • define a dialog template
  • ...


The sections of a source file should only be loaded. Do not save dynamic data (like current settings) in a source file. If a section is written to a source file (e.g. via the macro [Programmer_Guide/Macro_Library/SECTIONFILE|SectionFile]), the content is not destroyed, but the text formatting is changed and all comments are removed.

Navigation menu

Personal tools