============ Preprocessor ============ .. Modified: 2018-10-23/05:38-0400 btiffin .. Copyright 2016 Brian Tiffin .. GPL 3.0+ :ref:`license` .. This file is part of the Unicon Programming documentation .. image:: images/unicon.png :align: center .. only:: html :ref:`genindex` :floatright:`Unicon` Unicon features a simple preprocessor, supporting file inclusion, conditional compilation, symbolic constants, source line number (and reported filename) override, and an error messaging directive. .. index:: ipp The internal Unicon preprocessor does not support the list of features included in the :ref:`ipl` program ``ipp.icn``. There is no ``$elif`` for instance, nor ``$if`` *constant-expression*. The macro substitution features are also not supported. ``ipp`` will work with most, if not all, Unicon sources, but it is not the same as the internal Unicon preprocessor. ``ipp`` may have more features, but the simpler, internal Unicon preprocessor is more accessible, built into the compiler. As a Unicon programmer, you have the option of using ``ipp`` (it ships with the Unicon source kit along with the :ref:`ipl`), but it is probably best to stick with the internal mechanisms. .. index:: preprocessor .. _preprocessor: Unicon preprocessor =================== Preprocessor directives are lines that begin with a dollar sign and are processed *before* the translation stage begins. *Please note, that all of the code examples for the Unicon preprocessor are short, and contrived.* .. index:: $define .. _$define: $define ------- ``$define`` *symbol* [*value*] Define a preprocessor symbol, for testing with :ref:`$ifdef`, :ref:`$ifndef` and as a text replacement. Occurrences of *symbol* will be replaced by *value*. Note the values cannot have arguments, the replacement is literal. .. literalinclude:: examples/preproc-define.icn :language: unicon :start-after: ##+ .. only:: html .. rst-class:: rightalign :download:`examples/preproc-define.icn` Sample output: .. command-output:: unicon -E -s preproc-define.icn :cwd: examples .. index:: $else .. _$else: $else ----- ``$else`` ``$else`` marks the beginning of an optional, alternate source code block for processing an :ref:`$ifdef` or :ref:`$ifndef` conditional compile directive sequence. As nesting is allowed, ``$else`` matches to the closest previous :ref:`$ifdef` or :ref:`$ifndef`. See :ref:`$ifdef`, :ref:`$ifndef` for examples. .. index:: $endif .. _$endif: $endif ------ ``$endif`` ``$endif`` marks the end of a conditional compile source block when processing an :ref:`$ifdef` or :ref:`$ifndef` sequence. As nesting is allowed, ``$endif`` closes the closest previous :ref:`$ifdef`, :ref:`$ifndef` sequence. See :ref:`$ifdef`, :ref:`$ifndef` for examples. .. index:: $error .. _$error: $error ------ ``$error`` *text* ``$error`` causes the compiler to output an error with the supplied text as the message. .. literalinclude:: examples/preproc-error.icn :language: unicon :start-after: ##+ .. only:: html .. rst-class:: rightalign :download:`examples/preproc-error.icn` Sample output: .. command-output:: unicon -E -s preproc-error.icn :cwd: examples :returncode: 1 .. index:: $ifdef .. _$ifdef: $ifdef ------ ``$ifdef`` *symbol* ``$ifdef`` tests for a preprocessor symbol and, if defined, will emit source lines up to the next matching :ref:`$else` (or :ref:`$endif`, when no else directive is present). If not defined, the preprocessor will scan ahead to a matching :ref:`$else`, if present, and then output source lines up to the matching :ref:`$endif` directive. Nesting is allowed. All ``$ifdef`` directives must end with an :ref:`$endif`. .. literalinclude:: examples/preproc-ifdef.icn :language: unicon :start-after: ##+ .. only:: html .. rst-class:: rightalign :download:`examples/preproc-ifdef.icn` Sample output: .. command-output:: unicon -E -s preproc-ifdef.icn :cwd: examples .. command-output:: unicon -s preproc-ifdef.icn -x :cwd: examples .. attention:: Please be advised that this contrived example is not a preferred way to do feature testing in Unicon. The builtin :ref:`&features` keyword can be used at runtime for these type of conditional code fragments. .. sourcecode:: unicon if &features == "ms windows" then ... .. sourcecode:: unicon procedure main() if &features == "POSIX" then write("POSIX available, pid is ", getpid()) else write("No POSIX features with this ", &version) end The runtime penalty is slight, and ``.u`` code is highly portable. Runtime platform tests are encouraged, preprocessor conditionals (for feature testing) less so. .. index:: $ifndef .. _$ifndef: $ifndef ------- ``$ifndef`` *symbol* ``$ifndef`` is the opposite of :ref:`$ifdef`. The ``$ifndef`` directive tests for a preprocessor symbol and if *not* defined, will emit source lines up to the next matching :ref:`$else` (or :ref:`$endif`, when no else directive is present). If the symbol is defined, the preprocessor will scan ahead to a matching :ref:`$else`, if present, and then output source lines up to the matching :ref:`$endif` directive. Nesting is allowed. All ``$ifndef`` directives must end with an :ref:`$endif`. .. literalinclude:: examples/preproc-ifndef.icn :language: unicon :start-after: ##+ .. only:: html .. rst-class:: rightalign :download:`examples/preproc-ifndef.icn` Sample output: .. command-output:: unicon -E -s preproc-ifndef.icn :cwd: examples .. command-output:: unicon -s preproc-ifndef.icn -x :cwd: examples .. note:: Please be advised that this contrived example is not a preferred way to do feature testing in Unicon. The builtin :ref:`&features` keyword can be used at runtime for these type of conditional code fragments. See the :ref:`$ifdef` entry for a runtime alternative. .. index:: $include .. _$include: $include -------- ``$include`` *filename* Include another source file. .. literalinclude:: examples/preproc-include.icn :language: unicon :start-after: ##+ .. only:: html .. rst-class:: rightalign :download:`examples/preproc-include.icn` Sample output: .. command-output:: unicon -E -s preproc-include.icn :cwd: examples .. index:: $line .. _$line: $line ----- ``$line`` *line-number* [*"filename"*] Override view of current source line (and optionally file). Subsequent lines are treated by the compiler as commencing at the given line number in the current or given filename, *which must be quoted*. This directive is mainly of use for machine generated sources; for programs that generate (or manipulate) source programs, such as ``ulex`` or ``flex/bison``. This first sample is a compile time override example: .. literalinclude:: examples/preproc-line.icn :language: unicon :start-after: ##+ .. only:: html .. rst-class:: rightalign :download:`examples/preproc-line.icn` Sample output: .. command-output:: unicon -E -s preproc-line.icn :cwd: examples :returncode: 1 Now to see how it effects the runtime reporting: .. literalinclude:: examples/preproc-line-2.icn :language: unicon :start-after: ##+ .. only:: html .. rst-class:: rightalign :download:`examples/preproc-line-2.icn` Sample preprocessor output: .. command-output:: unicon -E -s preproc-line-2.icn :cwd: examples There will a runtime error reported when this program runs, with the reported line number influenced by ``$line`` directive. .. command-output:: unicon -s preproc-line-2.icn -x :cwd: examples :returncode: 1 One last time; the ``$line`` directive is of most use with machine generated sources. .. index:: $undef .. _$undef: $undef ------ ``$undef`` *symbol* Undefine a preprocessor symbol. .. literalinclude:: examples/preproc-undef.icn :language: unicon :start-after: ##+ .. only:: html .. rst-class:: rightalign :download:`examples/preproc-undef.icn` Sample output: .. command-output:: unicon -E -s preproc-undef.icn :cwd: examples .. index:: #line .. _#line: #line ----- ``#line`` *line-number* *filename* ``#line`` is an internal (not meant for programmers at the source level) directive keyword that manages post preprocessor line and filename semantics for the compiler proper. You will see the directive with ``unicon -E`` output but it is not for general use. .. index:: predefined symbols .. _predefined symbols: Predefined symbols ================== Predefined symbols (for use with :ref:`$ifdef`, and :ref:`$ifndef`) are provided for each platform, and for any optional features compiled into the running version of Unicon. Testable symbols include: =================== ======================== Symbol Feature =================== ======================== _MULTITASKING *multiple programs* _X_WINDOW_SYSTEM *X Windows* _GRAPHICS *graphics* _PIPES *pipes* _ARM_FUNCTIONS *Archimedes extensions* _MS_WINDOWS *MS Windows* _MVS *MVS* _MSDOS_386 *MS-DOS/386* _EVENT_MONITOR *event monitoring* _POSIX *POSIX* _KEYBOARD_FUNCTIONS *keyboard functions* _OS2 *OS/2* _MACINTOSH *Macintosh* _VMS *VMS* _DYNAMIC_LOADING *dynamic loading* _EBCDIC *EBCDIC* _EXTERNAL_FUNCTIONS *external functions* _SYSTEM_FUNCTION *system function* _CMS *CMS* _MSDOS *MS-DOS* _PORT *PORT* _V9 *Version 9* _CONSOLE_WINDOW *console window* _DOS_FUNCTIONS *MS-DOS extensions* _MESSAGING *messaging* _MS_WINDOWS_NT *MS Windows NT* _RECORD_IO *record I/O* _ACORN *Acorn Archimedes* _DBM *DBM* _CO_EXPRESSIONS *co-expressions* _AMIGA *Amiga* _ASCII *ASCII* _WIN32 *Win32* _UNIX *UNIX* _PRESENTATION_MGR *Presentation Manager* _LARGE_INTEGERS *large integers* =================== ======================== .. index:: preprocessor substitutions .. _substitutions: Substitution symbols -------------------- There some predfined symbols that will cause substitution during the preprocessor pass. ========= =================================== Symbol Replacement ========= =================================== __DATE__ Current date in ``YYYY/MM/DD`` form __TIME__ Current time is ``hh:mm:ss`` form ========= =================================== .. literalinclude:: examples/preproc-symbols.icn :language: unicon :start-after: ##+ .. only:: html .. rst-class:: rightalign :download:`examples/preproc-symbols.icn` Sample output: .. command-output:: unicon -E -s preproc-symbols.icn :cwd: examples .. index:: transliterations .. _transliteration: EBCDIC transliterations ======================= Some legacy keyboards do not include ``{``, ``}``, ``[``, or ``]`` characters, vital for Unicon programming. The preprocessor will replace: - ``$(`` with ``{`` - ``$)`` with ``}`` - ``$<`` with ``[`` - ``$>`` with ``]`` This transliteration only applies to EBCDIC system builds. .. only:: html .. -------- :ref:`genindex` | Previous: :doc:`keywords` | Next: :doc:`tools` |