packages feed

cpphs-1.5: docs/cpphs/Language/Preprocessor/Cpphs/MacroPass.html

<pre><font color=Blue>-----------------------------------------------------------------------------</font>
<font color=Blue>-- |</font>
<font color=Blue>-- Module      :  MacroPass</font>
<font color=Blue>-- Copyright   :  2004 Malcolm Wallace</font>
<font color=Blue>-- Licence     :  LGPL</font>
<font color=Blue>--</font>
<font color=Blue>-- Maintainer  :  Malcolm Wallace &lt;Malcolm.Wallace@cs.york.ac.uk&gt;</font>
<font color=Blue>-- Stability   :  experimental</font>
<font color=Blue>-- Portability :  All</font>
<font color=Blue>--</font>
<font color=Blue>-- Perform a cpp.second-pass, accumulating \#define's and \#undef's,</font>
<font color=Blue>-- whilst doing symbol replacement and macro expansion.</font>
<font color=Blue>-----------------------------------------------------------------------------</font>

<font color=Green><u>module</u></font> Language<font color=Cyan>.</font>Preprocessor<font color=Cyan>.</font>Cpphs<font color=Cyan>.</font>MacroPass
  <font color=Cyan>(</font> macroPass
  <font color=Cyan>,</font> preDefine
  <font color=Cyan>,</font> defineMacro
  <font color=Cyan>)</font> <font color=Green><u>where</u></font>

<font color=Green><u>import</u></font> Language<font color=Cyan>.</font>Preprocessor<font color=Cyan>.</font>Cpphs<font color=Cyan>.</font>HashDefine <font color=Cyan>(</font>HashDefine<font color=Cyan>(</font><font color=Red>..</font><font color=Cyan>)</font><font color=Cyan>,</font> expandMacro<font color=Cyan>)</font>
<font color=Green><u>import</u></font> Language<font color=Cyan>.</font>Preprocessor<font color=Cyan>.</font>Cpphs<font color=Cyan>.</font>Tokenise   <font color=Cyan>(</font>tokenise<font color=Cyan>,</font> WordStyle<font color=Cyan>(</font><font color=Red>..</font><font color=Cyan>)</font>
                                              <font color=Cyan>,</font> parseMacroCall<font color=Cyan>)</font>
<font color=Green><u>import</u></font> Language<font color=Cyan>.</font>Preprocessor<font color=Cyan>.</font>Cpphs<font color=Cyan>.</font>SymTab     <font color=Cyan>(</font>SymTab<font color=Cyan>,</font> lookupST<font color=Cyan>,</font> insertST
                                              <font color=Cyan>,</font> emptyST<font color=Cyan>)</font>
<font color=Green><u>import</u></font> Language<font color=Cyan>.</font>Preprocessor<font color=Cyan>.</font>Cpphs<font color=Cyan>.</font>Position   <font color=Cyan>(</font>Posn<font color=Cyan>,</font> newfile<font color=Cyan>,</font> filename<font color=Cyan>,</font> lineno<font color=Cyan>)</font>
<font color=Green><u>import</u></font> Language<font color=Cyan>.</font>Preprocessor<font color=Cyan>.</font>Cpphs<font color=Cyan>.</font>Options    <font color=Cyan>(</font>BoolOptions<font color=Cyan>(</font><font color=Red>..</font><font color=Cyan>)</font><font color=Cyan>)</font>
<font color=Green><u>import</u></font> System<font color=Cyan>.</font>IO<font color=Cyan>.</font>Unsafe <font color=Cyan>(</font>unsafePerformIO<font color=Cyan>)</font>
<font color=Green><u>import</u></font> Time       <font color=Cyan>(</font>getClockTime<font color=Cyan>,</font> toCalendarTime<font color=Cyan>,</font> formatCalendarTime<font color=Cyan>)</font>
<font color=Green><u>import</u></font> Locale     <font color=Cyan>(</font>defaultTimeLocale<font color=Cyan>)</font>

noPos <font color=Red>::</font> Posn
<a name="noPos"></a>noPos <font color=Red>=</font> newfile <font color=Magenta>"preDefined"</font>

<font color=Blue>-- | Walk through the document, replacing calls of macros with the expanded RHS.</font>
macroPass <font color=Red>::</font> <font color=Red>[</font><font color=Cyan>(</font>String<font color=Cyan>,</font>String<font color=Cyan>)</font><font color=Red>]</font>	<font color=Blue>-- ^ Pre-defined symbols and their values</font>
          <font color=Red>-&gt;</font> BoolOptions	<font color=Blue>-- ^ Options that alter processing style</font>
          <font color=Red>-&gt;</font> <font color=Red>[</font><font color=Cyan>(</font>Posn<font color=Cyan>,</font>String<font color=Cyan>)</font><font color=Red>]</font>	<font color=Blue>-- ^ The input file content</font>
          <font color=Red>-&gt;</font> String		<font color=Blue>-- ^ The file after processing</font>
<a name="macroPass"></a>macroPass syms options <font color=Red>=</font>
    safetail		<font color=Blue>-- to remove extra "\n" inserted below</font>
    <font color=Cyan>.</font> concat
    <font color=Cyan>.</font> macroProcess <font color=Cyan>(</font>pragma options<font color=Cyan>)</font> <font color=Cyan>(</font>layout options<font color=Cyan>)</font> <font color=Cyan>(</font>lang options<font color=Cyan>)</font>
                   <font color=Cyan>(</font>preDefine options syms<font color=Cyan>)</font>
    <font color=Cyan>.</font> tokenise <font color=Cyan>(</font>strip options<font color=Cyan>)</font> <font color=Cyan>(</font>ansi options<font color=Cyan>)</font> <font color=Cyan>(</font>lang options<font color=Cyan>)</font>
    <font color=Cyan>.</font> <font color=Cyan>(</font><font color=Cyan>(</font>noPos<font color=Cyan>,</font><font color=Magenta>""</font><font color=Cyan>)</font><font color=Red><b>:</b></font><font color=Cyan>)</font>	<font color=Blue>-- ensure recognition of "\n#" at start of file</font>
  <font color=Green><u>where</u></font>
    safetail <font color=Red>[</font><font color=Red>]</font> <font color=Red>=</font> <font color=Red>[</font><font color=Red>]</font>
    safetail <font color=Cyan>(</font><font color=Green><u>_</u></font><font color=Red><b>:</b></font>xs<font color=Cyan>)</font> <font color=Red>=</font> xs


<font color=Blue>-- | Turn command-line definitions (from @-D@) into 'HashDefine's.</font>
preDefine <font color=Red>::</font> BoolOptions <font color=Red>-&gt;</font> <font color=Red>[</font><font color=Cyan>(</font>String<font color=Cyan>,</font>String<font color=Cyan>)</font><font color=Red>]</font> <font color=Red>-&gt;</font> SymTab HashDefine
<a name="preDefine"></a>preDefine options defines <font color=Red>=</font>
    foldr <font color=Cyan>(</font>insertST <font color=Cyan>.</font> defineMacro options <font color=Cyan>.</font> <font color=Cyan>(</font><font color=Red>\</font> <font color=Cyan>(</font>s<font color=Cyan>,</font>d<font color=Cyan>)</font><font color=Red>-&gt;</font> s<font color=Cyan>++</font><font color=Magenta>" "</font><font color=Cyan>++</font>d<font color=Cyan>)</font><font color=Cyan>)</font>
          emptyST defines

<font color=Blue>-- | Turn a string representing a macro definition into a 'HashDefine'.</font>
defineMacro <font color=Red>::</font> BoolOptions <font color=Red>-&gt;</font> String <font color=Red>-&gt;</font> <font color=Cyan>(</font>String<font color=Cyan>,</font>HashDefine<font color=Cyan>)</font>
<a name="defineMacro"></a>defineMacro opts s <font color=Red>=</font>
    <font color=Green><u>let</u></font> <font color=Cyan>(</font>Cmd <font color=Cyan>(</font>Just hd<font color=Cyan>)</font><font color=Red><b>:</b></font><font color=Green><u>_</u></font><font color=Cyan>)</font> <font color=Red>=</font> tokenise True <font color=Cyan>(</font>ansi opts<font color=Cyan>)</font> <font color=Cyan>(</font>lang opts<font color=Cyan>)</font>
                                     <font color=Red>[</font><font color=Cyan>(</font>noPos<font color=Cyan>,</font><font color=Magenta>"\n#define "</font><font color=Cyan>++</font>s<font color=Cyan>++</font><font color=Magenta>"\n"</font><font color=Cyan>)</font><font color=Red>]</font>
    <font color=Green><u>in</u></font> <font color=Cyan>(</font>name hd<font color=Cyan>,</font> hd<font color=Cyan>)</font>


<font color=Blue>-- | Trundle through the document, one word at a time, using the WordStyle</font>
<font color=Blue>--   classification introduced by 'tokenise' to decide whether to expand a</font>
<font color=Blue>--   word or macro.  Encountering a \#define or \#undef causes that symbol to</font>
<font color=Blue>--   be overwritten in the symbol table.  Any other remaining cpp directives</font>
<font color=Blue>--   are discarded and replaced with blanks, except for \#line markers.</font>
<font color=Blue>--   All valid identifiers are checked for the presence of a definition</font>
<font color=Blue>--   of that name in the symbol table, and if so, expanded appropriately.</font>
<font color=Blue>--   (Bool arguments are: keep pragmas?  retain layout?  haskell language?)</font>
macroProcess <font color=Red>::</font> Bool <font color=Red>-&gt;</font> Bool <font color=Red>-&gt;</font> Bool <font color=Red>-&gt;</font> SymTab HashDefine <font color=Red>-&gt;</font> <font color=Red>[</font>WordStyle<font color=Red>]</font>
             <font color=Red>-&gt;</font> <font color=Red>[</font>String<font color=Red>]</font>
<a name="macroProcess"></a>macroProcess <font color=Green><u>_</u></font> <font color=Green><u>_</u></font> <font color=Green><u>_</u></font> <font color=Green><u>_</u></font>         <font color=Red>[</font><font color=Red>]</font>               <font color=Red>=</font> <font color=Red>[</font><font color=Red>]</font>
macroProcess p y l st <font color=Cyan>(</font>Other x<font color=Red><b>:</b></font> ws<font color=Cyan>)</font>           <font color=Red>=</font> x<font color=Red><b>:</b></font>    macroProcess p y l st ws
macroProcess p y l st <font color=Cyan>(</font>Cmd Nothing<font color=Red><b>:</b></font> ws<font color=Cyan>)</font>       <font color=Red>=</font> <font color=Magenta>"\n"</font><font color=Red><b>:</b></font> macroProcess p y l st ws
macroProcess p y l st <font color=Cyan>(</font>Cmd <font color=Cyan>(</font>Just <font color=Cyan>(</font>LineDrop x<font color=Cyan>)</font><font color=Cyan>)</font><font color=Red><b>:</b></font> ws<font color=Cyan>)</font>
                                              <font color=Red>=</font> <font color=Magenta>"\n"</font><font color=Red><b>:</b></font>x<font color=Red><b>:</b></font>macroProcess p y l st ws
macroProcess pragma y l st <font color=Cyan>(</font>Cmd <font color=Cyan>(</font>Just <font color=Cyan>(</font>Pragma x<font color=Cyan>)</font><font color=Cyan>)</font><font color=Red><b>:</b></font> ws<font color=Cyan>)</font>
                             <font color=Red>|</font> pragma    <font color=Red>=</font> <font color=Magenta>"\n"</font><font color=Red><b>:</b></font>x<font color=Red><b>:</b></font>macroProcess pragma y l st ws
                             <font color=Red>|</font> otherwise <font color=Red>=</font> <font color=Magenta>"\n"</font><font color=Red><b>:</b></font>  macroProcess pragma y l st ws
macroProcess p layout lang st <font color=Cyan>(</font>Cmd <font color=Cyan>(</font>Just hd<font color=Cyan>)</font><font color=Red><b>:</b></font> ws<font color=Cyan>)</font> <font color=Red>=</font>
    <font color=Green><u>let</u></font> n <font color=Red>=</font> <font color=Magenta>1</font> <font color=Cyan>+</font> linebreaks hd <font color=Green><u>in</u></font>
    replicate n <font color=Magenta>"\n"</font> <font color=Cyan>++</font>macroProcess p layout lang <font color=Cyan>(</font>insertST <font color=Cyan>(</font>name hd<font color=Cyan>,</font> hd<font color=Cyan>)</font> st<font color=Cyan>)</font> ws
macroProcess pr layout lang st <font color=Cyan>(</font>Ident p x<font color=Red><b>:</b></font> ws<font color=Cyan>)</font> <font color=Red>=</font>
    <font color=Green><u>case</u></font> x <font color=Green><u>of</u></font>
      <font color=Magenta>"__FILE__"</font> <font color=Red>-&gt;</font> show <font color=Cyan>(</font>filename p<font color=Cyan>)</font><font color=Red><b>:</b></font> macroProcess pr layout lang st ws
      <font color=Magenta>"__LINE__"</font> <font color=Red>-&gt;</font> show <font color=Cyan>(</font>lineno p<font color=Cyan>)</font><font color=Red><b>:</b></font>   macroProcess pr layout lang st ws
      <font color=Magenta>"__DATE__"</font> <font color=Red>-&gt;</font> formatCalendarTime defaultTimeLocale <font color=Magenta>"\"%d %b %Y\""</font>
                        <font color=Cyan>(</font>unsafePerformIO <font color=Cyan>(</font>getClockTime<font color=Cyan>&gt;&gt;=</font>toCalendarTime<font color=Cyan>)</font><font color=Cyan>)</font><font color=Red><b>:</b></font>
                                       macroProcess pr layout lang st ws
      <font color=Magenta>"__TIME__"</font> <font color=Red>-&gt;</font> formatCalendarTime defaultTimeLocale <font color=Magenta>"\"%H:%M:%S\""</font>
                        <font color=Cyan>(</font>unsafePerformIO <font color=Cyan>(</font>getClockTime<font color=Cyan>&gt;&gt;=</font>toCalendarTime<font color=Cyan>)</font><font color=Cyan>)</font><font color=Red><b>:</b></font>
                                       macroProcess pr layout lang st ws
      <font color=Green><u>_</u></font> <font color=Red>-&gt;</font>
        <font color=Green><u>case</u></font> lookupST x st <font color=Green><u>of</u></font>
            Nothing <font color=Red>-&gt;</font> x<font color=Red><b>:</b></font> macroProcess pr layout lang st ws
            Just hd <font color=Red>-&gt;</font>
                <font color=Green><u>case</u></font> hd <font color=Green><u>of</u></font>
                    SymbolReplacement <font color=Cyan>{</font>replacement<font color=Red>=</font>r<font color=Cyan>}</font> <font color=Red>-&gt;</font>
                        <font color=Green><u>let</u></font> r' <font color=Red>=</font> <font color=Green><u>if</u></font> layout <font color=Green><u>then</u></font> r <font color=Green><u>else</u></font> filter <font color=Cyan>(</font><font color=Cyan>/=</font><font color=Magenta>'\n'</font><font color=Cyan>)</font> r <font color=Green><u>in</u></font>
                        <font color=Blue>-- one-level expansion only:</font>
                        <font color=Blue>-- r' : macroProcess layout st ws</font>
                        <font color=Blue>-- multi-level expansion:</font>
                        macroProcess pr layout lang st
                                     <font color=Cyan>(</font>tokenise True False lang <font color=Red>[</font><font color=Cyan>(</font>p<font color=Cyan>,</font>r'<font color=Cyan>)</font><font color=Red>]</font>
                                      <font color=Cyan>++</font> ws<font color=Cyan>)</font>
                    MacroExpansion <font color=Cyan>{</font><font color=Cyan>}</font> <font color=Red>-&gt;</font>
                        <font color=Green><u>case</u></font> parseMacroCall p ws <font color=Green><u>of</u></font>
                            Nothing <font color=Red>-&gt;</font> x<font color=Red><b>:</b></font> macroProcess pr layout lang st ws
                            Just <font color=Cyan>(</font>args<font color=Cyan>,</font>ws'<font color=Cyan>)</font> <font color=Red>-&gt;</font>
                                <font color=Green><u>if</u></font> length args <font color=Cyan>/=</font> length <font color=Cyan>(</font>arguments hd<font color=Cyan>)</font> <font color=Green><u>then</u></font>
                                     x<font color=Red><b>:</b></font> macroProcess pr layout lang st ws
                                <font color=Green><u>else</u></font> <font color=Green><u>let</u></font> args' <font color=Red>=</font> map <font color=Cyan>(</font>concat
                                                     <font color=Cyan>.</font> macroProcess pr layout
                                                                    lang st<font color=Cyan>)</font>
                                                     args <font color=Green><u>in</u></font>
                                     <font color=Blue>-- one-level expansion only:</font>
                                     <font color=Blue>-- expandMacro hd args' layout:</font>
                                     <font color=Blue>--         macroProcess layout st ws'</font>
                                     <font color=Blue>-- multi-level expansion:</font>
                                     macroProcess pr layout lang st
                                         <font color=Cyan>(</font>tokenise True False lang
                                              <font color=Red>[</font><font color=Cyan>(</font>p<font color=Cyan>,</font>expandMacro hd args' layout<font color=Cyan>)</font><font color=Red>]</font>
                                         <font color=Cyan>++</font> ws'<font color=Cyan>)</font>

</pre>