% Copyright 2012-2024, Alexander Shibakov
% This file is part of SPLinT
%
% SPLinT is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% SPLinT is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with SPLinT.  If not, see <http://www.gnu.org/licenses/>.

% prototypes of all the macros produced by the ld parser
% we will follow the convention: 12string is a string of category 12 characters and spaces, tex_string: a string
% of TeX tokens; sptr is a pointer to the stash stream, fptr is a pointer to the format stream

\def\yyuniontag{\ldunion}
\def\parserstrictnamespace{ld-parser-strict} % expands to an error message
\def\parserprototypesnamespace{ld-parser-strict:headers} % the parameter strings
\def\parserdebugnamespace{ld-parser-debug} % control sequences are \let...=\relax for debugging 

\def\ldunion{\currentyyunionnamespace}
\def\currentyyunionnamespace{ld-generic}

% types returned by the lexer (* marks the types that get removed by the parser in some cases)

\defp\anint#1#2#3{} % integer :: \anint{integer}{fptr}{sptr}
\defp\bint#1#2#3{} % integer in a specifix radix :: \bint{integer}{fptr}{sptr}
\defp\hexint#1#2#3{} % hex integer :: \hexint{integer}{fptr}{sptr}

% ld commands

\defp\ldor{} % item separator :: \ldor, is only needed here for debugging (in the ld-parser-debug namespace)
\defp\ldregexp#1{} % name pattern :: \ldregexp{{name}{name11}{fptr}{sptr}}
\defp\ldregop#1{} % name pattern :: \ldregop{name}
\defp\ldspace{} % space separator :: \ldspace
\defp\ldattrstring#1#2#3#4{} % attributes string :: \ldattrstring{name}{name11}{fptr}{sptr}
\defp\ldattrstringneg#1#2#3#4{} % complemented attributes string :: \ldattrstring{name}{name11}{fptr}{sptr}
\defp\ldfilename#1{} % file name :: \ldfilename{name}
\defp\ldcommandseparator#1#2#3#4{} % command separator :: \ldcommandseparator{fptr}{sptr}{prev command}{next command}
\defp\ldassignment#1#2#3{} % assignment :: \ldassignment{lhs}{op}{rhs}
\defp\ldhidden#1#2{} % hidden :: \ldhidden{lhs}{rhs}
\defp\ldprovide#1#2{} % provide :: \ldprovide{lhs}{rhs}
\defp\ldprovidehid#1#2{} % provide hidden :: \ldprovidehid{lhs}{rhs}
\defp\ldkeep#1{} % keep :: \ldkeep{list}
\defp\ldentry#1{} % entry :: \ldentry{name}
\defp\ldinclude#1{} % file inclusion :: \ldinclude{file name}
\defp\ldmemory#1{} % memory specification :: \ldmemory{memory spcification}
\defp\ldfill#1{} % fill expression :: \ldfill{expression}
\defp\ldmemoryspec#1#2#3#4{} % memory item :: \ldmemoryspec{name}{attributes}{origin}{length}
\defp\ldmemspecstash#1#2{} % memory spec stash :: \ldmemspecstash{fptr}{sptr}
\defp\ldmemspecseparator#1#2{} % memory spec separator :: \ldmemspecseparator{fptr}{sptr}
\defp\ldoriginspec#1{} % origin :: \ldoriginspec{expression}
\defp\ldlengthspec#1{} % length :: \ldlengthspec{expression}
\defp\ldsections#1{} % ld sections :: \ldsections{sections}
\defp\ldsectionseparator#1#2{} % section separator :: \ldsectionseparator{fptr}{sptr}
\defp\ldtype#1{} % section type :: \ldtype{type}
\defp\ldstatement#1{} % statement :: \ldstatement{statement}
\defp\ldfreestmt#1{} % statement in a section :: \ldfreestmt{\ldstatement{statement}}
\defp\ldsecspec#1{} % section spec :: \ldsecspec{section spec}
\defp\ldinsertcweb#1#2#3#4{} % insert accumulated \CWEB\ material :: \ldinsertcweb
                             % {fptr}{sptr}{command}{parsed segment} : never defined
\defp\ldnamedsection#1#2#3#4#5#6#7{} % named section :: \ldnamedsection{name}
                                     %                                 {expression}{type}}{at}
                                     %                                 {{}{}{}:alignment}
                                     %                                 {constraint}{statements}
                                     %                                 {{}{}{}{}:placement}
\defp\ldoverlay#1#2#3#4#5#6{} % overlay section list :: \ldoverlay{expression}{crossrefs}{at}{subalign}
                              %                                   {sections}
                              %                                   {{memspec}{memspec_at}{phdr}{fill}}
\defp\ldoverlaysection#1#2#3#4{} % overlay section :: \ldoverlaysection{name}{statements}{phdr}{fill}
\defp\ldsectionstash#1#2{} % sections spec stash :: \ldsectionstash{fptr}{sptr}

\savecslist{ld-parser-prototypes}\ldunion % these consume parameters and expand to nothing

\input ldint.sty

\def\ldidxdomain{L}

\let\writeldidxentry\writeidxentry    % mix the \ld\ index with the
\let\writeldidxhentry\writeidxhentry % \bison\ index for now

\def\writeldidxhentry#1{%
      \indxe\gindex{{\secno}{{}{\hostparsernamespace}}{\ldidxdomain}{\headeridxrank}#1}%
}

\def\writeldidxentry#1{%
      \indxe\gindex{{\secno}{{}{\hostparsernamespace}}{\ldidxdomain}{\termidxrank}#1}%
}

\def\bigbracedel{\delimiter"4266308}

\newtoks\lddisplay

\restorecslist{ld-parser-strict}\ldunion

\defc\ldinclude{%
    \toksa={&##\cr\ttl include\ &}#1%
    \concat\toksa\toksc
    \toksc{\cr}
    \concat\toksa\toksc
    \edef\next{\lddisplay{\the\lddisplay\halign{\the\toksa}}}\next
}

\defc\ldmemory{%
    \savecslist{local-namespace}{\ldunion}%
    \restorecslist{ld-parser:memory-spec}\ldunion
    \toksa{}#1%
    \toksc{%
        \hfil##\qquad&##\hfil&\qquad##\hfil\quad&\hfil##&\qquad\hfil##\cr
        \ttl memory&\hfil&\ttl attributes&\ttl starts at&\ttl length\cr
        \noalign{\smallskip}%
    }%
    \edef\next{\lddisplay{\the\lddisplay\halign{\the\toksc\the\toksa}}}\next
    \restorecslist{local-namespace}{\ldunion}%
}

\defc\ldsections{%
    \savecslist{local-namespace}{\ldunion}%
    \restorecslist{ld-parser:sections}\ldunion
    \toksa{}\def\sections@header{\ttl sections}%
    #1%
    \toksc{%
        &##\hfil\quad\cr
    }%
    \edef\next{\lddisplay{\the\lddisplay\halign{\the\toksc\the\toksa}}}\next
    \restorecslist{local-namespace}{\ldunion}%
}

\def\ldextractname#1#2#3#4{%
    \edef\next{\toksc{\gidxentry{\termttstring}{#2}{}{\ntt #2}}}\next
}

\def\ldextractattrs#1#2#3#4{%
    \edef\next{\toksc{{\ntt #2}}}\next
}

\def\ldextractmemname#1#2#3#4{%
    {%
        \expandafter\let\expandafter\tosmallparser\csname to\stripbrackets\cwebclinknamespace parser\endcsname
        \let\optstrextra\optstrextraesc
        \def\hostparsernamespace{[none]}%
        \nameproc{#2}\with\parsebin
        \edef\next{\toksc{\gidxentry{\termvstring}{#2}{}{\let\idxfont\nx\empty\ntt\the\toksa}}}%
        \expandafter
    }\next%

}

% the grammar of ld scripts is very uniform so the separator form
% below should be more than adequate; if a more sophisticated spacing
% strategy is required, one may consult the design of
% \separatorswitcheq and \separatorswitchneq in yyunion.sty

\defc\ldcommandseparator{%
    \expandafter\ifx\csname ldstashentry[#2]\endcsname\relax
        \yyifsamestring{#3}{#4}{}{\appendrnx\lddisplay{\medskip}}%
    \else
        \expandafter\expandafter\expandafter\yystashlocal\expandafter\expandafter\expandafter{\csname ldstashentry[#2]\endcsname}%
        \edef\next{\toksc{\toksa{}\the\yystashlocal
            \noexpand\ldmakestashbox{}}}\next
        \appendrnx\lddisplay{\smallskip\noindent}%
        \concat\lddisplay\toksc
        \appendrnx\lddisplay{\smallskip}%
    \fi
}

\defc\ldcommandseparator{% new version; TODO: remove the duplicates after the macros have been tested
    \expandafter\ifx\csname ldstashentry[#2]\endcsname\relax
        \yyifsamestring{#3}{#4}{}{\appendrnx\lddisplay{\medskip}}%
    \else
        \expandafter\expandafter\expandafter\yystashlocal\expandafter\expandafter\expandafter{\csname ldstashentry[#2]\endcsname}%
        \appendrnx\lddisplay{\smallskip\noindent}%
        \appendr  \lddisplay{\toksa{\the\yystashlocal}}%
        \appendrnx\lddisplay{\ldmakestashbox{}\smallskip}%
    \fi
}

\defc\ldstatement{\toksc{\hbox{$#1$}}\concat\lddisplay\toksc}

\let\ldsecspec\ldstatement

\defc\ldassignment{%
    #1#2#3%
}

\defc\ldhidden{%
    \mathop{\hbox{\ssf hidden}}\hbox{$\langle\,$}#1\K#2\hbox{$\,\rangle$}%
}

\defc\ldprovide{%
    \mathop{\hbox{\ssf provide}}\hbox{$\langle\,$}#1\K#2\hbox{$\,\rangle$}%
}

\defc\ldprovidehid{%
     \mathop{\hbox{\ssf provide$_{h}$}}\hbox{$\langle\,$}#1\K#2\hbox{$\,\rangle$}%
}

\defc\anint{%
    \uppercase{\ldsciinteger{#1}}%
}

\defc\hexint{%
    \ldsciinteger{#1}%
}

\defc\bint{%
    \uppercase{\ldbasedinteger{#1}}%
}

\defc\ldregexp{%
        \ldreg@xp#1%
}

\def\ldreg@xp#1#2#3#4{%
  \expandafter\ifx\csname ldvarname[#2]\endcsname\relax
      {%
          \let\termindex\writeldidxentry
          \let\hostparsernamespace\cwebclinknamespace% process the variable names as in \CWEB            
          \edef\next{\toksc{\gidxentry{\termttstring}{#1}{}}}\next
          \hbox{\ntt@#1}%
          \expandafter
      }\the\toksc
  \else
      \yyifsamestring{#2}{.}{% special . name
          {%
              \let\termindex\writeldidxentry
              \let\hostparsernamespace\cwebclinknamespace% for consistency
              \edef\next{\toksc{\gidxentry{\termexception}{.origin&}{.}}}\next
              \hbox{\csname\prettynamecs\hostparsernamespace{.origin&}\endcsname{}}%
              \expandafter
          }\the\toksc
      }{%
          {%
              \let\termindex\writeldidxentry
              \let\hostparsernamespace\cwebclinknamespace% process the variable names as in \CWEB
              \edef\next{\toksc{\gidxentry{\termhostidstring}{#1}{}}}\next
              \hbox{%
                  \expandafter\let\expandafter\tosmallparser\csname to\stripbrackets\cwebclinknamespace parser\endcsname
                  \let\optstrextra\optstrextraesc
                  \nameproc{#2}\with\parsebin
                  \\{\the\toksa}%
              }%
              \expandafter
          }\the\toksc
      }%
  \fi
}

\defc\ldregop{%
        \ldreg@p#1%
}

\def\ldreg@p#1#2#3#4{%
  \hbox{\ntt@#1}%
}

\defc\ldfill{%
    #1%
}

\defc\ldentry{% this command survives till the table time
    \hbox{\ttl entry{\rm: }} #1%
}

\defc\ldkeep{%
    \mathop{\hbox{\ssf keep}}(#1)%
}

\defc\ldfilename{\ldextractname#1}

\savecslist{ld-display}\ldunion

% memory specifications

\restorecslist{ld-parser-strict}\ldunion

\defc\ldmemoryspec{%
    \toksb{\hfil&}%
    \let\termindex\writeldidxhentry
        \ldextractmemname#1\concat\toksb\toksc
    \let\termindex\eatone
    \appendrnx\toksb{&}%
    \toksc{}#2\appendrnx\toksc{&}\concat\toksb\toksc% attributes
    \toksc{}#3\appendrnx\toksc{&}\concat\toksb\toksc
    \toksc{}#4\concat\toksb\toksc
    \concat\toksa\toksb
    \toksb{\cr}\concat\toksa\toksb
}

\defc\ldattrstring{%
    \appendrnx\toksc{{\ntt@ #2}}%
}

\defc\ldattrstringneg{%
    \appendrnx\toksc{\hbox{$\neg$}{\ntt@ #2}}%
}

\defc\ldspace{%
}

\defc\ldlengthspec{%
    \toksc{$#1$}%
}

\defc\ldoriginspec{%
    \toksc{#1}%
}

\defc\ldinclude{%
    \toksc={\hfil&\ttl include }%
    \concat\toksa\toksc#1%
    \concat\toksa\toksc
    \toksc{&\hfil&\hfil&\hfil\cr}%
    \concat\toksa\toksc
}

% TODO: change the code to use linked lists

\defc\ldmemspecseparator{%
    \expandafter\ifx\csname ldstashentry[#2]\endcsname\relax
    \else
        \expandafter\expandafter\expandafter\yystashlocal\expandafter\expandafter\expandafter{\csname ldstashentry[#2]\endcsname}%
        \appendr\toksa{&\nx\multispan4\toksa{\the\yystashlocal}\nx\ldmakestashbox{\nx\cdotfill}\nx\quad\cr}%
    \fi
}

\defc\ldmemspecstash{%
    \expandafter\ifx\csname ldstashentry[#2]\endcsname\relax
    \else
        \expandafter\expandafter\expandafter\yystashlocal\expandafter\expandafter\expandafter{\csname ldstashentry[#2]\endcsname}%
        \appendr\toksa{&\nx\multispan4\toksa{\the\yystashlocal}\nx\ldmakestashbox{\nx\cdotfill}\nx\quad\cr}%
    \fi
}

\restorecs{ld-display}{\ldfilename\ldentry}
\toyyunion{ld-parser:memory-spec}

% sections commands

\restorecslist{ld-parser-strict}\ldunion

\newif\ifplacementpushed
\newif\ifsectioncomplete
\newif\iffillextracted

\defc\ldnamedsection{ % named section :: \ldnamedsection{name}
                      %                                 {{bind?}{expression}{block?}{expression}{type}}{at}
                      %                                 {{}{}{}:alignment}
                      %                                 {constraint}{statements}
                      %                                 {{}{}{}{}:placement}
    \tempca=\z@ % line counter
    \tempcb=\z@ % alignment line counter
    \placementpushedfalse
    \sectioncompletefalse
    \fillextractedfalse
    \bloop
        \toksb{}%
        \ifnum\tempca=\z@
            \toksb\expandafter{\sections@header&}% section header
            \ldextractname#1% section name
            \concat\toksb\toksc
            \appendrnx\toksb{&}%
            \ldexpwithtype#2% location and type
            \concat\toksb\toksc
            \appendrnx\toksb{&}%
            \yystringempty{#3}{\ldpushalignment#4}{\toksc{{\ttl at }$#3$}}% alignment            
            \concat\toksb\toksc
            \appendrnx\toksb{&}%
            \yystringempty{#5}{\ldpushplacement#7}{\toksc{{\ttl #5}}}% constraint
            \concat\toksb\toksc
            \appendrnx\toksb{&}%
            \ldstartpheaders#7% possible pheaders
            \concat\toksb\toksc
            \appendrnx\toksb{\cr}%
            \def\sections@header{}%
       \else
            \toksb\expandafter{&}% section header
            \advance\tempca\m@ne
            \ldextractitem\tempca{#6}% next statement
            \advance\tempca\@ne
            \yytoksempty\toksc{%
                \ldextractfill#7%
                \iffillextracted
                    \ifnum\tempcb<\tw@
                    \else
                        \sectioncompletetrue
                    \fi
                \fi
                \fillextractedtrue
            }{%
                 \toksc\expandafter{\expandafter\qquad\the\toksc{}}%
            }%
            \concat\toksb\toksc
            \appendrnx\toksb{&}%
%            \ldexpwithtype#2% location and type
%            \concat\toksa\toksc
            \appendrnx\toksb{&}%
            \ldpushalignment#4% alignment            
            \concat\toksb\toksc
            \appendrnx\toksb{&}%
            \ldpushplacement#7% placement
            \concat\toksb\toksc
            \appendrnx\toksb{&}%
            \ldpushpheaders#7% possible pheaders
            \concat\toksb\toksc
            \appendrnx\toksb{\cr}%
            \def\sections@header{}%
        \fi
    \ifsectioncomplete
    \else 
        \concat\toksa\toksb
        \advance\tempca\@ne
    \repeat 
}


% named section :: \ldnamedsection{name}
                      %                                 {{bind?}{expression}{block?}{expression}{type}}{at}
                      %                                 {{}{}{}:alignment}
                      %                                 {constraint}{statements}
                      %                                 {{memspec}{memspec_at}{phdr}{fill}}

\defc\ldoverlay{% overlay sections :: \ldoverlay{expression}{crossrefs}{at}{subalign}
                %                               {sections}
                %                               {{memspec}{memspec_at}{phdr}{fill}}
    \yystringempty{#1}{\tokse{}}{\tokse{ $#1$}}%
    \yystringempty{#2}{\toksf{}}{\toksf{{ \ttl noxrefs}}}%
    \yystringempty{#3}{\toksg{}\toksc{}}{\toksg{{\ttl at} $#3$}\toksc{ }}%
    \yystringempty{#4}{\toksh{}}{\toksh\expandafter{\expandafter{\the\tokc\ttl subalign} $#4$}}%
    \appendr\toksa{&\hskip-1em\noexpand\ttl overlay\the\tokse\the\toksf&&\the\toksg\the\toksh}%
    \ldwrapoverlay#6%
    \appendr\toksa{&\the\toksc&\cr}%
    #5%
    \ldoverlayfill#6%
    \yytoksempty\toksd{}{\appendr\toksa{&\the\toksd&&&&&\cr}}% attach the fill at the end
    \appendr\toksa{&\hskip-1em{\ttl overlay end}&&&&&\cr}%
}

\defc\ldoverlaysection{% overlay section :: \ldoverlaysection{name}{statements}{phdr}{fill}
    \ldnamedsection{#1}%
                   {{}{}{}{}{}}{}%
                   {{}{}{}}%
                   {}{#2}%
                   {{}{}{#3}{#4}}%
}

\def\ldwrapoverlay#1#2#3#4{% puts memspec... in \toksc and fill in \toksd 
    \toksc{}%
    \yystringempty{#1}{% any > ?
    }{%
        \ldextractname#1%
        \toksd{{\ttl in }}%
        \concatl\toksd\toksc
    }%
    \yystringempty{#2}{% any AT > ?
    }{%
        \yytoksempty\toksc{\toksc{{\ttl as }}}{\appendrnx\toksc{ {\ttl as }}}%
        \toksd=\toksc
        \ldextractname#2%
        \concat\toksd\toksc
        \toksc=\toksd
    }%
}

\def\ldoverlayfill#1#2#3#4{%
    \ld@xtractfill{#4}%
}

\def\ldextractitem#1#2{% #1 is a counter, #2 is a list separated by \ldor
    \yystringempty{#2}{%
        \toksc{}%
    }{%
        \let\ldor\or
        \toksc=\ifcase#1#2\else{}\fi
        \let\ldor\relax
    }%
}

\def\ldpushalignment#1#2#3{%
    \toksd=\ifcase\tempcb{#1}\or{#2}\or{#3}\else{}\fi
    \yytoksempty\toksd{%
        \advance\tempcb\@ne
        \ifnum\tempcb<\tw@
            \yybreak{\ldpushalignment{#1}{#2}{#3}}%
        \else
            \yybreak{\toksc{}}%
        \yycontinue
    }{%
        \toksc=\ifcase\tempcb{{\ttl align }}\concat\toksc\toksd\or
                             {{\ttl align\_with\_input}}\or
                             {{\ttl subalign }}\concat\toksc\toksd\fi
        \advance\tempcb\@ne
    }%
}

\def\ldpushplacement#1#2#3#4{%
    \ifplacementpushed
        \toksc{}%
    \else
        \yystringempty{#1}{% any > ?
            \toksc{}%
        }{%
            \ldextractname#1%
            \toksd{{\ttl in }}%
            \concatl\toksd\toksc
        }%
        \yystringempty{#2}{% any AT > ?
        }{%
            \yytoksempty\toksc{\toksc{{\ttl as }}}{\appendrnx\toksc{ {\ttl as }}}%
            \toksd=\toksc
            \ldextractname#2%
            \concat\toksd\toksc
            \toksc=\toksd
        }%
        \placementpushedtrue
    \fi
}

\def\ldstartpheaders#1#2#3#4{%
    \tempcc=\z@
    \yystringempty{#3}{\toksc{}}{\toksc{{\ttl phdrs}}}%
}

\def\ldextractfill#1#2#3#4{%
    \toksc{}%
    \yystringempty{#4}{%
        \fillextractedtrue
    }{%
        \iffillextracted
        \else
            \ld@xtractfill{#4}%
            \appendr\toksc{\noexpand\qquad{\noexpand\ttl fill }$\the\toksd$}%
        \fi
    }%
}

\def\ld@xtractfill#1{% #1 must be \ldfill{expression}
\toksf{#1}%
    \toksd\expandafter{#1}%
}

\def\ldpushpheaders#1#2#3#4{%
    \ldextractitem\tempcc{#3}%
    \advance\tempcc\@ne
    \yytoksempty\toksc{}{\expandafter\ldextractname\the\toksc}%
}

\def\ldexpwithtype#1#2#3#4#5{% TODO
    \yystringempty{#2}{\toksc{$}}{\toksc{$#2}}%$
    \yystringempty{#5}{\toksd{{}$}}{#5\appendlnx\toksd{[}\appendrnx\toksd{]$}}%
    \concat\toksc\toksd
}

\defc\ldtype{%
    \toksd{\hbox{\ttl #1}}%
}

\defc\ldstatement{{\let\ldrlap\relax\let\ldintfont\ntt@$#1$}} % the braces form the group for a \toks assignment
\defc\ldfreestmt{\toksb\expandafter{#1}\appendr\toksa{&\the\toksb\cr}}

\defc\ldsecspec{{$#1$}}

\def\ldboxstash#1{%
  \ifchecktrim\errmessage{stash contents: \the\toksa}\fi
  {\setbox0 \vbox{\the\toksa}\ifdim\ht0=\z@\aftergroup\toksa\else\aftergroup\eatone\fi}{}%
  \yytoksempty\toksa{#1}{%
      $\vtop{\activateinlinec\tabskip\z@\halign{\strut\ignorespaces##\hfil\cr\the\toksa\crcr}}$\hfill}}

\def\ldmakestashbox#1{\cleanstash\stripstash\ldboxstash{#1}}

\defc\ldsectionseparator{%
    \expandafter\ifx\csname ldstashentry[#2]\endcsname\relax
    \else
        \expandafter\expandafter\expandafter\yystashlocal\expandafter\expandafter\expandafter{\csname ldstashentry[#2]\endcsname}%
        \appendr\toksa{&\nx\multispan5\toksa{\the\yystashlocal}\nx\ldmakestashbox{\nx\cdotfill}\nx\quad\cr}%
    \fi
}

\defc\ldsectionstash{%
    \expandafter\ifx\csname ldstashentry[#2]\endcsname\relax
    \else
        \expandafter\expandafter\expandafter\yystashlocal\expandafter\expandafter\expandafter{\csname ldstashentry[#2]\endcsname}%
        \appendr\toksa{\sections@header&\nx\multispan5\toksa{\the\yystashlocal}\nx\ldmakestashbox{\nx\cdotfill}\nx\quad\cr}%
        \let\sections@header\empty
    \fi
}

\restorecs{ld-display}{\ldregexp\ldassignment\ldfill\ldinsertcweb\ldentry}
\toyyunion{ld-parser:sections}

% preprocessing macros: collecting stash and marking variables
% currently these macros do not get inside expressions to extract
% variable names, consequently if the variable is used before it
% appears in an assignment, it will not be displayed properly 
% (is this even legal in linker scripts?) although the index will 
% show it correctly

\restorecslist{ld-parser-prototypes}\ldunion
\restorecs{ld-parser-strict}{\insertcweb}

\defc\ldmemory{#1} % memory specification :: \ldmemory{memory spcification}

\defc\ldmemspecstash{%
    \readstash{#2}%
    \setbox0 \vbox{\toksa\expandafter{\the\yystashlocal}\cleanstash\stripstash\the\toksa}%
    \ifdim\ht0=\z@
        \expandafter\let\csname ldstashentry[#2]\endcsname\relax % this is redundant but we may change \relax to 
                                                                 % something else later
    \else
        \expandafter\edef\csname ldstashentry[#2]\endcsname{\the\yystashlocal}%
    \fi
} % memory spec stash :: \ldmemspecstash{fptr}{sptr}

\defc\ldmemspecseparator{%
    \readstash{#2}%
    \setbox0 \vbox{\toksa\expandafter{\the\yystashlocal}\cleanstash\stripstash\the\toksa}%
    \ifdim\ht0=\z@
        \expandafter\let\csname ldstashentry[#2]\endcsname\relax
    \else
        \expandafter\edef\csname ldstashentry[#2]\endcsname{\the\yystashlocal}%
    \fi
} % memory spec separator :: \ldmemspecseparator{fptr}{sptr}

\defc\ldsections{#1} % ld sections :: \ldsections{sections}

\defc\ldoverlay{% overlay section :: \ldoverlay{expression}{crossrefs}{at}{subalign}
                %                              {sections}
                %                              {{memspec}{memspec_at}{phdr}{fill}}
    #3#5%
} % TODO: add handling of subalign, memmspec, and memspec_at

\defc\ldsectionseparator{%
    \readstash{#2}%
    \setbox0 \vbox{\toksa\expandafter{\the\yystashlocal}\cleanstash\stripstash\the\toksa}%
    \ifdim\ht0=\z@
        \expandafter\let\csname ldstashentry[#2]\endcsname\relax
    \else
        \expandafter\edef\csname ldstashentry[#2]\endcsname{\the\yystashlocal}%
    \fi
} % section separator :: \ldsectionseparator{fptr}{sptr}

\defc\ldsectionstash{%
    \readstash{#2}%
    \setbox0 \vbox{\toksa\expandafter{\the\yystashlocal}\cleanstash\stripstash\the\toksa}%
    \ifdim\ht0=\z@
        \expandafter\let\csname ldstashentry[#2]\endcsname\relax
    \else
        \expandafter\edef\csname ldstashentry[#2]\endcsname{\the\yystashlocal}%
    \fi
} % sections spec stash :: \ldsectionstash{fptr}{sptr}

\defc\ldcommandseparator{%
    \readstash{#2}%
    \setbox0 \vbox{\toksa\expandafter{\the\yystashlocal}\cleanstash\stripstash\the\toksa}%
    \ifdim\ht0=\z@
        \expandafter\let\csname ldstashentry[#2]\endcsname\relax
    \else
        \expandafter\edef\csname ldstashentry[#2]\endcsname{\the\yystashlocal}%
    \fi
} % command separator :: \ldcommandseparator{fptr}{sptr}{prev command}{next command}

\defc\ldstatement{#1}
\defc\ldfreestmt{#1}
\defc\ldassignment{#1}
\defc\ldprovide{#1}
\defc\ldentry{#1}
\let\ldhidden\ldprovide
\let\ldprovidehid\ldprovide
\defc\ldnamedsection{\let\ldor\empty#6}

\defc\ldregexp{%
     \ldr@gexprestash#1%
}

\def\ldr@gexprestash#1#2#3#4{
     \expandafter\def\csname ldvarname[#2]\endcsname{\errmessage{Not an \\ldregexp!, maybe change the parser namespace?}}%
}

\toyyunion{ld-parser:restash}