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 <Malcolm.Wallace@cs.york.ac.uk></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>-></font> BoolOptions <font color=Blue>-- ^ Options that alter processing style</font>
<font color=Red>-></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>-></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>-></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>-></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>-></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>-></font> String <font color=Red>-></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>-></font> Bool <font color=Red>-></font> Bool <font color=Red>-></font> SymTab HashDefine <font color=Red>-></font> <font color=Red>[</font>WordStyle<font color=Red>]</font>
<font color=Red>-></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>-></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>-></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>-></font> formatCalendarTime defaultTimeLocale <font color=Magenta>"\"%d %b %Y\""</font>
<font color=Cyan>(</font>unsafePerformIO <font color=Cyan>(</font>getClockTime<font color=Cyan>>>=</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>-></font> formatCalendarTime defaultTimeLocale <font color=Magenta>"\"%H:%M:%S\""</font>
<font color=Cyan>(</font>unsafePerformIO <font color=Cyan>(</font>getClockTime<font color=Cyan>>>=</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>-></font>
<font color=Green><u>case</u></font> lookupST x st <font color=Green><u>of</u></font>
Nothing <font color=Red>-></font> x<font color=Red><b>:</b></font> macroProcess pr layout lang st ws
Just hd <font color=Red>-></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>-></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>-></font>
<font color=Green><u>case</u></font> parseMacroCall p ws <font color=Green><u>of</u></font>
Nothing <font color=Red>-></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>-></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>