\section{Instruction Descriptors}
\label{descriptors}

The table, {\tt descriptors}, is an array of static information about
{\bf li}-code instructions, used in constructing {\tt statements} and
{\tt operands} (see subsection~\ref{algorithms}).  It contains
information which is used in the improvement and generation of the
associated {\bf C}-code.  The file {\tt chdescriptors} is {\em
construct}ed, producing Hermes object file {\tt chdescriptors.ho}.

The definitions of {\tt execution{\uline}locus} and of {\tt
instruction{\uline}flow} appear in subsection~\ref{algorithms}.

\subsection{Definitions}

\begin{verbatim}
  descriptors : table_descriptors;

  statement_descriptors : table of statement_descriptor
                                   {full} KEYS(opcode);
  statement_descriptor : record(
    opcode : opcode,             -- lookup key
    flow : instruction_flow,     -- post operation behavior
    locus : execution_locus,     -- li-code partition control
    destination : assignment,    -- first operand status
    families : families,         -- principle operand class
    improve : improvement,       -- kind of optimization to try
    choose : choice,             -- initial choice for code generation
                                 --   'null' <= no 'choice'
                                 --   'pure' <= no 'choice' or 'nest'
    operations : template_operations,
                                 -- C-code generation program
    parameters : template_parameters
                                 -- basis of program parameter list
  );

  assignment : enumeration('referenced', 'modified', 'assigned');
    
  improvement : enumeration(
    'cbranch', 'convert', 'discard',
    'eliminate1', 'eliminate2', 'literal', 'move', 'select',
    'null'
  );
    
  choice : enumeration(
    'pure',
    'branch', 'compare', 'ubiquitous',
    'multiple', 'select',
    'zero_test',
    'null'
  );
   
  template_opcode : ordered enumeration (
    'char', 'string', 'operand', 'qualifier', 'parameter', 'variable',
    'line', 'choice', 'nest', 'iterate'
  );
    
  template_programs : table of template_program {full} KEYS(opcode);

  template_program : record(
    opcode : opcode,
    choose : choice,
    operations: template_operations
  );
    
  template_procedure : record(
    choose : choice,
    operations: template_operations
  );
    
  template_array : table of template_set {full} KEYS(name);

  template_set : record(
    name : charstring,
    operations : template_operations
  );
    
  template_operations : ordered table of template_operation {init};

  template_operation : variant of template_opcode(
    'char' -> char : char {init},
    'string' -> string : charstring {init},
    'operand' -> operand : template_operand {full},
    'qualifier' -> qualifier : empty {},
    'parameter' -> parameter : parameter_type {init},
    'variable' -> item : template_variable {init},
    'line' -> line : template_line {full},
    'choice' -> array : template_array {init},
    'nest' -> nested : template_procedure {full},
    'iterate' -> iterate : empty {}
  );
    
  template_operand : record(
    macro : operand_macro,
    index : integer
  );
    
  operand_macro : enumeration(
    'ADDRESS', 'OBJECT',  'VALCELL', 'TSDR', 'SCALAR'
  );
    
  template_parameters : table of template_parameter {full} KEYS(type);
    template_parameter : record(
    type : parameter_type,
    string : charstring
  );
    
  parameter_type : enumeration(
    'opcode',               -- opcode name (all)
    'modifier',             -- usually "!" or ""
    'operator',             -- for inline unary/binary/relation
    'function',             -- for unary/binary function call
    'tsdr',                 -- operand(s) representaion
    'tag',                  -- operand(s) value tag
    'value'                 -- operand's value (scalar/name)
  );
    
  template_line : record(
      newline : boolean,  -- emit newline now
      indent : integer    -- positive, zero, negative
  );
    
  template_variable : enumeration(
    -- side-effect only
    'increment',            -- increment encoding index
    'counter',              -- value of encoding index
    'int_one',              -- value of (first) integer (in pair)
    'int_two',              -- value of (second) integer (in pair)
                     -- obtain statement label from (indexed) qualifier 
    'target_ccode',         -- original position of statement
    'target_statement       -- execution position of statement
  );
\end{verbatim}

Phase 1 constructs {\tt statements} from {\tt descriptors} and
original {\bf li}-code.  Phase 2 uses the {\tt destination} and the
{\tt improvement} to improve {\tt cblocks}.  The {\tt choice}, {\tt
operations} and {\tt parameters} are used during Phase 3 to generate
{\bf C}-code.

\subsection{{\bf C}-code generation}

Associated with each instruction to be encoded, are a selector {\tt
choose}, a set {\tt parameters} and a list {\tt operations} of code
templates.  All three are initialized from the {\tt descriptors}.

The {\tt parameters} are keyed character strings.  In some cases
parameters are added, depending on the instruction and on
information included in its {\tt statement} and in the associated
{\tt operand} structures by previous phases.

The {\tt operations} are interpreted to produce concatenated strings
of {\bf C}-code.  Some effort is made to generate readable {\bf
C}-code.  For details see processes {\tt chencodings}, {\tt chencode},
{\tt choperand}, {\tt chqualifer}
\begin{itemize}
\item {\tt 'char'} adds the character {\tt char} to the end of the code.
\item {\tt 'string} adds string  to the end of the current line.\footnote{
For {\tt 'string'}, {\tt 'operand'}, {\tt 'qualifier'},
{\tt 'parameter'} the corresponding character string is concatenated
to the {\bf C}-code, if there is enough room for it in the current
line.  If there is insufficient room, the line is terminated and the
token begins the next line, suitably indented.}
\item {\tt 'operand'} - the {\tt index}ed {\tt operand.Id} is
transformed into a {\bf C}-code reference to the operand,
according to the selected {\tt macro}.  For a {\tt 'SCALAR'} {\tt operand}
{\tt macro}, the {\tt value} field name is the {\tt 'tag'}
{\tt string}.
\item {\tt 'qualifier'} adds the encoded {\tt operand}
{\tt qualifier} field to the current.  For a {\tt 'string'} {\tt
qualifier}, extra back-slashes are inserted as necessary.
\item {\tt 'variable'} (except in one case) adds an integer value
converted to a string to the end of the code.
\begin{itemize}
\item {\tt 'counter'} refers to an auxilliary counter used in the
encoding of a {\tt statement} which has a variable number of
arguments.
\item {\tt 'increment'} does not produce code; it simply increments
the auxilliary counter.
\item {\tt 'int{\uline}one'} refers to the first field of an {\tt
integer{\uline}pair} qualifier (see {\tt interpform} definitions).
\item {\tt 'int{\uline}one'} refers to the second field of an {\tt
integer{\uline}pair} qualifier.
\item {\tt 'target{\uline}ccode'} refers to the original {\tt statement}
{\tt position} of the target of the current branch.
\item {\tt 'target{\uline}statement} refers to the index of the
residual {\bf li}-code {\tt escape} instruction which is the target
of the current branch (its {\em instruction pointer}).
\end{itemize}
\item {\tt 'line'} modifies initial indentation for the next
line; it usually terminates the current line.
\item {\tt choice} selects one of its {\tt array} elements to
continue {\tt operations} according to the current {\tt choose}.
\item {\tt nest} pushes an {\tt operations} list and a new {\tt choose};
{\tt choose} is popped following the last new {\tt operation}.
\end{itemize}

\subsection{Cautions}

The generated {\bf C}-code is strongly related to the code of the
Hermes interpreter.  Those parts which are expanded in-line are
modelled on the corresponding {\tt o{\uline}}$\ldots$ procedures.
Changes to the interpreter source may imply changes to the
{\tt chdescriptors} file.

The code for integer division, mod, remainder does not check for
first operand MININT and second operand 1 (this is not done in the
interpreter code, {\tt o{\uline}idivide}, {\tt o{\uline}irem},
{\tt o{\uline}imod}, either).
