diff --git a/documentation/Compiling.txt b/documentation/Compiling.txt index b747a1fabc645a5901583acc47803c4259afa096..a3c4817644700dcc2e3c672c29f614a433c833a9 100644 --- a/documentation/Compiling.txt +++ b/documentation/Compiling.txt @@ -1,10 +1,10 @@ Compiling SNL Programs ====================== -*snc*, the SNL to C Compiler ----------------------------- +:program:`snc`, the SNL to C Compiler +------------------------------------- -The SNL to C compiler *snc* compiles the state notation +The SNL to C compiler :program:`snc` compiles the state notation language into C code. The resulting file can then be compiled with a C compiler. @@ -17,40 +17,49 @@ SNC options start by a plus or minus sign, followed by a single character. A plus sign turns the option on, and a minus turns the option off. -====== =============================================================== -Option Description -====== =============================================================== - +a Asynchronous ``pvGet``: the program continues without - waiting for completion of the ``pvGet`` operation. - -a Synchronous ``pvGet``: the program waits for completion. - This is the default if an option is not specified. - +c Wait for process variables to connect before allowing the - program to begin execution. This is the default. - -c Allow the program to begin execution before connections - are established to all channel. - +d Turn on run-time debug messages. - -d Turn off run-time debug messages. This is the default. - +e Use the new event flag mode. This is the default. - -e Use the old event flag mode (clear flags after executing a - when statement). - +i Generate registrar procedure that registers shell commands - and programs with an IOC shell. This is the default. - -i Do not generate registrar procedure. - +l Add line markers to the generated code, so that C compiler - messages refer to the SNL source file. This is the default. - -l Do not produce line markers. - +m Include main procedure (seqMain.c) for a stand-alone program. - -m Do not include seqMain.c. This is the default. - +s :ref:`Safe mode`: variables are local to state set - and must be communicated explicitly. Implies +r. - -s Traditional (non-safe) mode. This is the default for - compatibility. - +r Make the generated code reentrant, thus allowing more than one - instance of the program to run on an IOC. - -r Generated code is not reentrant. This is the default. - +w Display SNC warning messages. This is the default. - -w Suppress SNC warnings. -====== =============================================================== +============== =============================================================== +Option Description +============== =============================================================== +.. option:: +a Asynchronous ``pvGet``: the program continues without + waiting for completion of the ``pvGet`` operation. +.. option:: -a Synchronous ``pvGet``: the program waits for completion. + This is the default if an option is not specified. +.. option:: +c Wait for process variables to connect before allowing the + program to begin execution. This is the default. +.. option:: -c Allow the program to begin execution before connections + are established to all channel. +.. option:: +d Turn on run-time debug messages. +.. option:: -d Turn off run-time debug messages. This is the default. +.. option:: +e Use the new event flag mode. This is the default. +.. option:: -e Use the old event flag mode (clear flags after executing a + when statement). +.. option:: +i Generate registrar procedure that registers shell commands + and programs with an IOC shell. This is the default. +.. option:: -i Do not generate registrar procedure. +.. option:: +l Add line markers to the generated code, so that C compiler + messages refer to the SNL source file. This is the default. +.. option:: -l Do not produce line markers. +.. option:: +m Include main procedure (seqMain.c) for a stand-alone program. +.. option:: -m Do not include seqMain.c. This is the default. +.. option:: +s :ref:`Safe mode`: variables are local to state set + and must be communicated explicitly. Implies +r. +.. option:: -s Traditional (non-safe) mode. This is the default for + compatibility. +.. option:: +r Make the generated code reentrant, thus allowing more than one + instance of the program to run on an IOC. +.. option:: -r Generated code is not reentrant. This is the default. +.. option:: +w Display warning messages. This is the default. +.. option:: -w Suppress warnings. +============== =============================================================== + +.. versionadded:: 2.2 + +============== =============================================================== +Option Description +============== =============================================================== +.. option:: +W Display extra warnings for undefined objects. +.. option:: -W Suppress extra warnings. This is the default. +============== =============================================================== Note that :option:`+a` and :option:`-a` are ignored for calls to :c:func:`pvGet` that explicitly specify ``SYNC`` or ``ASYNC`` in the @@ -81,26 +90,26 @@ compiler option overrides. Errors ^^^^^^ -If *snc* detects an error, it displays a message describing the error +If :program:`snc` detects an error, it displays a message describing the error and the location in the source file and aborts further compilation. -Note, however, that *snc* does *not* contain a type checker: all it +Note, however, that :program:`snc` does *not* contain a type checker: all it knows (and cares) about C is the syntax. This means that many errors will only be found only during the C compilation phase. The C compiler will attributed these to the corresponding location in the SNL source -file, since by default *snc* generates line markers in the output that +file, since by default :program:`snc` generates line markers in the output that point back to the original source. This can be turned off with the :option:`-l` ("ell") compiler switch. Warnings ^^^^^^^^ -In certain cases *snc* cannot ultimately decide whether the code is +In certain cases :program:`snc` cannot ultimately decide whether the code is erroneous. In such cases it will issue a warning message and continue. The most prominent example is the use of a variable or CPP macro that has not been declared in the SNL code, but could well be defined when compiling the generated C code (for example if the declaration has been -in embedded C code, which *snc* does not interpret at all). Warnings +in embedded C code, which :program:`snc` does not interpret at all). Warnings can be suppressed with the :option:`-w` compiler option. Note that since version 2.1 you can avoid these warnings by declaring @@ -110,16 +119,17 @@ C Pre-processor --------------- Depending on the application, it might be useful to pre-process the SNL -source with a C pre-processor (*cpp*). Using the C pre-processor allows -you to include other SNL files, define macros, and perform conditional -compilation. *snc* supports this by interpreting *cpp*-generated line -markers, so that error and warning messages refer to the line numbers -in the un-pre-processed SNL source. +source with a C pre-processor (:program:`cpp`). Using the C +pre-processor allows you to include other SNL files, define macros, and +perform conditional compilation. :program:`snc` supports this by +interpreting :program:`cpp`-generated line markers, so that error and +warning messages refer to the line numbers in the un-pre-processed SNL +source. Complete Build -------------- -The C code generated by *snc* from an SNL program is not a complete +The C code generated by :program:`snc` from an SNL program is not a complete program, but merely a collection of procedures, data types, and variables. The generated procedures are supposed to be called by the sequencer library, which must be linked to the program. Furthermore, diff --git a/documentation/Installation.txt b/documentation/Installation.txt index a9946b847430f4bd7aecdb8bba7c6536f823e437..22f859dd92ff92095c89d6996a2b265406f7675b 100644 --- a/documentation/Installation.txt +++ b/documentation/Installation.txt @@ -342,7 +342,7 @@ program to your application, write something like :: into your Makefile. Here, ``xyz.st`` is the name of your SNL program, and ``abc`` is the name of the library or binary to produce. Note that ``.st`` -files are run through the C preprocessor (*cpp*) before giving them to +files are run through the C preprocessor (:program:`cpp`) before giving them to the SNL compiler. Use the extension ``.stt`` to avoid this. For details, see Chapter 4 of the `EPICS Application Developer's Guide`_. diff --git a/documentation/Introduction.txt b/documentation/Introduction.txt index bcc6b832782fbc64269a812b03397bec1d243a2c..18288b683ffdffff02504e12006d75b43f54e5b3 100644 --- a/documentation/Introduction.txt +++ b/documentation/Introduction.txt @@ -45,7 +45,7 @@ of its syntax and semantics are directly inherited from C. The language is designed for seamless integration with C code; for instance, you can directly call C procedures in SNL action blocks and state transition conditions, and the types of variables you can declare in SNL map directly -to C types. The compiler for SNL (called *snc*, see :doc:`Compiling`) takes +to C types. The compiler for SNL (called :program:`snc`, see :doc:`Compiling`) takes a very minimalistic approach to compilation by generating portable standard C89/90 code that works on all platforms supported by EPICS. In fact, most of the SNL action code is compiled almost verbatim to C, and the generated code diff --git a/documentation/Reference.txt b/documentation/Reference.txt index 917ac1ed951a3a6640f0052dba64e10d471f91ed..1fd830d2fb307388345382c8d0bd2f8a9ff0d009 100644 --- a/documentation/Reference.txt +++ b/documentation/Reference.txt @@ -100,7 +100,7 @@ any) at the given line. :token:`file_name` must be a single string (no automatic string concatenation). -Line markers are typically generated by preprocessors, such as *cpp*. +Line markers are typically generated by preprocessors, such as :program:`cpp`. Program ------- @@ -212,35 +212,38 @@ Variable Declarations init_declarators: `init_declarators` "," `init_declarator` init_declarator: `declarator` init_declarator: `declarator` "=" `init_expr` + declarator: `variable` + declarator: "(" `declarator` ")" + declarator: `declarator` `subscript` + declarator: `declarator` "(" `param_decls` ")" declarator: "*" `declarator` - declarator: `direct_declarator` - direct_declarator: `variable` - direct_declarator: "(" `declarator` ")" - direct_declarator: `direct_declarator` `subscript` - init_expr: "(" `type_expr` ")" "{" `init_exprs` "}" + variable: `identifier` init_expr: "{" `init_exprs` "}" + init_expr: "(" `type_expr` ")" "{" `init_exprs` "}" init_expr: `expr` init_exprs: `init_exprs` "," `init_expr` init_exprs: `init_expr` init_exprs: - variable: `identifier` - -Variable declarations are quite similar to C. .. versionadded:: 2.1 You can declare more than one variable in a single declaration (comma -separated) and add pointer and array markers (subscripts) ad libitum as well -as initializers. +separated) and add pointer and array markers (subscripts) ad libitum as +well as initializers. -The remain some limitations: +.. versionadded:: 2.2 + +Function declarations and initializers with type casts. -* arrays must have a defined size (i.e. the integer in the - subscript brackets is not optional as in C) +The still remain some limitations: + +* arrays must have a defined size: the expression inside the subscript + brackets is not optional as in C; it must also be an integer literal, + not a constant expression as in C. * you cannot declare new types or type synonyms -* you cannot declare functions -* no qualifiers ("static", "extern", "const" etc.) -* only certain types are allowed, see below +* no type qualifiers ("const", "volatile") +* no storage specifiers ("static", "extern", "auto", register") +* only certain base types are allowed, see below Some of these restrictions may be lifted in future versions. @@ -250,24 +253,37 @@ Some of these restrictions may be lifted in future versions. Foreign Declarations ~~~~~~~~~~~~~~~~~~~~ +.. warning:: + + Foreign declarations are now deprecated. They might be removed in future + versions. + .. productionlist:: - declaration: "foreign" `declarators` ";" - declarators: `declarator` - declarators: `declarators` "," `declarator` + declaration: "foreign" `variables` ";" + variables: `variable` + variables: `variables` "," `variable` .. versionadded:: 2.1 -Foreign declarations are used let the SNL compiler know about the existence -of C variables or C preprocessor macros (without arguments) that have been -defined outside the SNL program or in escaped C code. No warning will be -issued if such a variable or macro is used in the program even if warnings -are enabled. +Foreign declarations are used to let the SNL compiler know about the +existence of C variables or C preprocessor macros (without arguments) +that have been defined outside the SNL program or in escaped C code. No +warning will be issued if such a variable or macro is used in the +program even if warnings are enabled. .. versionadded:: 2.2 It is no longer needed to declare struct or union members as foreign entities, since the parser no longer confuses them with variables. See -section `Primary Expression Operators`_ below. +section `Postfix Operators`_ below. + +Also, warnings for undefined entities are now disabled by default. You +can use the "extra warnings" option :option:`+W` to enable them. In +contrast to older versions, this will also warn about foreign functions +when called from SNL code. Note that enabling extra warnings is normally +not needed: if a variable or function is actually undefined in the +generated C code, the C compiler will issue a warning (or an error) +anyway. .. _Types: @@ -342,25 +358,31 @@ not yet support 64 bit integers. Type Expressions ~~~~~~~~~~~~~~~~ +.. versionadded:: 2.2 + .. productionlist:: - type_expr: `basetype` `opt_abstract_declarator` - opt_abstract_declarator: - opt_abstract_declarator: `abstract_declarator` - abstract_declarator: "*" - abstract_declarator: "*" `direct_abstract_declarator` - abstract_declarator: `direct_abstract_declarator` - direct_abstract_declarator: "(" `abstract_declarator` ")" - direct_abstract_declarator: `direct_abstract_declarator` `subscript` - direct_abstract_declarator: `subscript` - -Type expressions closely follow declaration syntax just as in C. They are -used for type casts (`Unary Prefix Operators`_) and the special sizeof -operator (`Primary Expression Operators`_). + type_expr: `basetype` + type_expr: `basetype` `abs_decl` + abs_decl: "*" + abs_decl: "(" `abs_decl` ")" + abs_decl: "*" `abs_decl` + abs_decl: `abs_decl` "(" `param_decls` ")" + abs_decl: `abs_decl` `subscript` + abs_decl: "(" `param_decls` ")" + abs_decl: `subscript` + param_decls: `param_decl` + param_decls: `param_decls` "," `param_decl` + param_decl: `basetype` `declarator` + param_decl: `type_expr` + +Type expressions closely follow declaration syntax just as in C. They +are used for parameter declarations as well as type casts and the +special sizeof operator (see `Prefix Operators`_). Strings ~~~~~~~ -The type :token:`string` is defined in C as:: +The type ``string`` is defined in C as:: typedef char string[MAX_STRING_SIZE]; @@ -373,7 +395,7 @@ recommend not to rely too much on the numeric value. (You can use .. note:: In contrast to C, in SNL ``string s`` is *not* a synonym for - ``char s[MAX_STRING_SIZE]``, since variables of type :token:`string` + ``char s[MAX_STRING_SIZE]``, since variables of type ``string`` are treated differently when it comes to interacting with PVs: the former gets requested with type DBR_STRING and a count of one, while the latter gets requested with type DBR_CHAR and a count of @@ -905,7 +927,7 @@ Statements statement: "continue" ";" statement: "state" `identifier` ";" statement: `c_code` - statement: "{" `block_defns` `statements` "}" + statement: `block` statement: "if" "(" `comma_expr` ")" `statement` statement: "if" "(" `comma_expr` ")" `statement` "else" `statement` statement: "while" "(" `comma_expr` ")" `statement` @@ -927,10 +949,11 @@ Expressions ^^^^^^^^^^^ Formation rules for expressions are listed in groups of descending order -of precedence. +of precedence. Precedence is determined by the standard C operator +precedence table. -Atomic Expression -~~~~~~~~~~~~~~~~~ +Primary Expressions +~~~~~~~~~~~~~~~~~~~ .. productionlist:: expr: `integer_literal` @@ -938,23 +961,16 @@ Atomic Expression expr: `string` expr: `variable` string: `string_literal` - -These are literals and variables. - -Parenthesized Expression -~~~~~~~~~~~~~~~~~~~~~~~~ - -.. productionlist:: expr: "(" `comma_expr` ")" -Primary Expression Operators -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +These are literals, variables, and parenthesized expressions. + +Postfix Operators +~~~~~~~~~~~~~~~~~ .. productionlist:: - expr: `identifier` "(" `args` ")" + expr: `expr` "(" `args` ")" expr: "exit" "(" `args` ")" - expr: "sizeof" "(" `expr` ")" - expr: "sizeof" "(" `type_expr` ")" expr: `expr` "[" `expr` "]" expr: `expr` "." `member` expr: `expr` "->" `member` @@ -962,24 +978,21 @@ Primary Expression Operators expr: `expr` "--" member: `identifier` -These are: function call, array subscript, record selection, pointer to -record selection, and postfix operators (increment and decrement). +These are all left associative. .. note:: - :token:`exit` is listed explicitly because it is a keyword, not an - identifier, but can also be used as a function. + ``exit`` must be listed explicitly because in SNL it is a keyword, + not an identifier. The extra rule allows calls to the standard + library function ``exit``. -.. note:: +.. versionadded:: 2.2 - SNL makes no use of the semantics of structure member access and - struct tags are treated as if they were expressions (variables, in - fact). A side-effect is that *snc* will warn that structure tags are - "used but not declared", which can be silenced with a :ref:`foreign - entities` declaration, just as with variables. +.. productionlist:: + expr: "sizeof" "(" `type_expr` ")" -Unary Prefix Operators -~~~~~~~~~~~~~~~~~~~~~~ +Prefix Operators +~~~~~~~~~~~~~~~~ .. productionlist:: expr: "+" `expr` @@ -991,44 +1004,69 @@ Unary Prefix Operators expr: "++" `expr` expr: "--" `expr` +Prefix operators are right-associative. + .. versionadded:: 2.2 -Type casts: +Type casts and sizeof operator: .. productionlist:: expr: "(" `type_expr` ")" `expr` + expr: "sizeof" `expr` -Left-associative Binary Operators -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Binary Operators +~~~~~~~~~~~~~~~~ .. productionlist:: expr: `expr` "-" `expr` expr: `expr` "+" `expr` + +.. productionlist:: + expr: `expr` "<<" `expr` + expr: `expr` ">>" `expr` + +.. productionlist:: expr: `expr` "*" `expr` expr: `expr` "/" `expr` + +.. productionlist:: expr: `expr` ">" `expr` expr: `expr` ">=" `expr` - expr: `expr` "==" `expr` - expr: `expr` "!=" `expr` expr: `expr` "<=" `expr` expr: `expr` "<" `expr` + +.. productionlist:: + expr: `expr` "==" `expr` + expr: `expr` "!=" `expr` + +.. productionlist:: + expr: `expr` "&" `expr` + +.. productionlist:: + expr: `expr` "^" `expr` + +.. productionlist:: + expr: `expr` "|" `expr` + +.. productionlist:: expr: `expr` "||" `expr` + +.. productionlist:: expr: `expr` "&&" `expr` - expr: `expr` "<<" `expr` - expr: `expr` ">>" `expr` - expr: `expr` "|" `expr` - expr: `expr` "^" `expr` - expr: `expr` "&" `expr` + +.. productionlist:: expr: `expr` "%" `expr` +All binary operators associate to the left. + .. note:: - Like in most programming languages, evaluation of conditional - expressions using ``&&`` and ``||`` is done *lazily*: the second operand - is not evaluated if evaluation of the first already determines the - result. This particularly applies to the boolean expressions in - :token:`transition` clauses. See the built-in function :c:func:`pvGetQ` - for an extended discussion. + Like in most programming languages, including C, evaluation of + conditional expressions using ``&&`` and ``||`` is done *lazily*: the + second operand is not evaluated if evaluation of the first already + determines the result. This particularly applies to the boolean + expressions in :token:`transition` clauses. See the built-in function + :c:func:`pvGetQ` for an extended discussion. Ternary Operator ~~~~~~~~~~~~~~~~ @@ -1164,9 +1202,9 @@ compType .. note:: - Only ``SYNC`` and ``ASYNC`` are SNL built-in constants (i.e. - known to *snc*). The constant ``DEFAULT`` is for use in C code - (to represent a missing optional argument). + Only ``SYNC`` and ``ASYNC`` are SNL built-in constants (i.e. known to + :program:`snc`). The constant ``DEFAULT`` is for use in C code (to + represent a missing optional argument). seqBool @@ -1211,10 +1249,10 @@ statically checked by the compiler. Several of these functions are intended to be called only from :token:`transition` clauses or only from action code. It is safe to call -them in another context, but the effect is probably not what you want. For -instance, calling :c:func:`delay` in action code does *not* introduce a -delay at this point. Later versions of *snc* may output a warning or even -stop with an error. +them in another context, but the effect is probably not what you want. +For instance, calling :c:func:`delay` in action code does *not* +introduce a delay at this point. Later versions of :program:`snc` may +output a warning or even stop with an error. .. todo:: What about changing this so that :c:func:`delay` in action code *does* introduce a delay? In other words, compile 'delay(<expr>)' to @@ -2208,9 +2246,9 @@ by adding a line :: This uses the one-line-escape syntax explained in the next section. -For historical reasons, *snc* complains with a warning if you use a -foreign variable or preprocessor macro in SNL code (but not for foreign -function calls). This can be suppressed by adding a foreign +For historical reasons, :program:`snc` complains with a warning if you +use a foreign variable or preprocessor macro in SNL code (but not for +foreign function calls). This can be suppressed by adding a foreign declaration (see `Foreign Entities`_). @@ -2218,9 +2256,9 @@ Escape to C Code ^^^^^^^^^^^^^^^^ Because the SNL does not support the full C language, C code may be -escaped in the program. The escaped code is not compiled by *snc*, -instead it is literally copied to the generated C code. There are two -escape methods: +escaped in the program. The escaped code is not compiled by +:program:`snc`, instead it is literally copied to the generated C code. +There are two escape methods: #. Any code between ``%%`` and the next newline character is escaped. Example:: @@ -2265,10 +2303,10 @@ here. For instance, if the header contains macro definitions, these will not be in effect when the rest of the C code block gets compiled. -You can defer interpretation of a preprocessor directive until -after *snc* has compiled the code to C, by ensuring that some extra -non-blank characters appear in front of the ``#`` sign, so *cpp* does -not recognize the directive. For instance :: +You can defer interpretation of a preprocessor directive until after +:program:`snc` has compiled the code to C, by ensuring that some extra +non-blank characters appear in front of the ``#`` sign, so +:program:`cpp` does not recognize the directive. For instance :: %%#include <abcLib.h> @@ -2340,8 +2378,8 @@ file is always included by the generated C code. Variable Modification for Reentrant Option ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -If the reentrant option (:option:`+r`) is specified to *snc* then all -variables are made part of a structure. Suppose we have the +If the reentrant option (:option:`+r`) is specified to :program:`snc` +then all variables are made part of a structure. Suppose we have the following top-level declarations in the SNL program:: int sw1; @@ -2366,7 +2404,7 @@ Reference to variable ``sw1`` is made as :: pVar->sw1 -This conversion is automatically performed by *snc* for all SNL +This conversion is automatically performed by :program:`snc` for all SNL statements, but you will have to handle escaped C code yourself. .. note::