\section{Auxiliary Declarations and Code of C-coded Modules}
\label{declarations}

Most of the types and structs referenced here are defined in {\tt li.h}.

\subsection{Module Header Declarations}

The following declarations are included in every generated module.

\begin{verbatim}
#include <stdio.h>

#define NOINLINE
#include "sysdep.h"
#include "li.h"
#include "storage.h"
#include "accessors.h"
#include "interpform.cd"
#include "predefined.cd"

extern datarep dr_bottom;
extern datarep dr_boolean;
extern datarep dr_integer;
extern datarep dr_enumeration;
extern datarep dr_ord_enumeration;
extern datarep dr_nominal;
extern datarep dr_real;
extern datarep dr_record;
extern datarep dr_variant;
extern datarep dr_table;
extern datarep dr_polymorph;
extern datarep dr_inport;
extern datarep dr_outport;
extern datarep dr_callmessage;
extern datarep dr_program;

extern datarep *datarepmap[];
extern datarep *qdatarepmap[];

#define DEF(X) & data[X]
#define REF(X) data[X]
#define DOT(Y) .value.record->data[Y]
#define QUAL(I) dot(get_elem(qualifiers,I),VARIANT_COMPONENT)

#define FIND TRUE
#define GET FALSE
#define NO_TBL -1

\end{verbatim}

\subsection{Module Entry}
The module entry declaration has the form:

\begin{verbatim}
void CH_<name>(current, sched, cop)
  pcb *current;
  schedblock *sched;
  valcell cop;
{
\end{verbatim}

where {\tt current} is the interpreter's pointer to the current
process control block, {\tt sched} is the corresponding
scheduling block and {\tt cop} is the current operation.

\subsection{Local Declarations}

Following the entry declaration, local declarations are included.  See
Appendix~\ref{instructions} and file {\tt hermes/chcode/chdescriptors}
for references to the declared variables and labels.

\begin{verbatim}
  valcell qualifiers;
  objectp arguments[ARGUMENTS];

  register objectp data;
  register int ch_i;
  register dfd_table *ch_t;
  dfd_enumeration ch_e;
  counter ch_ctr;
  valcell ch_val;
  predef_exception ch_returncode;

  double *ch_real;
  pcb *ch_caller;
  inspect_frame *ch_frame;

  predef_exception che_attributename();
  predef_exception che_block();
  predef_exception che_call();
  predef_exception che_concat();
  predef_exception che_create();
  void che_endblock();
  void che_endprocess();
  predef_exception che_inspect_poly();
  predef_exception che_new_table();
  predef_exception che_procedure();
  predef_exception che_prog_lit();
  predef_exception che_read();
  predef_exception che_receive();
  predef_exception che_remove();
  predef_exception che_select();
  predef_exception che_send();
  predef_exception che_typename();
  predef_exception che_unique();
  predef_exception che_unite();
  predef_exception che_unwrap();
  predef_exception che_wrap();
  predef_exception che_write();
  int chf_iadd();
  int chf_imod();
  int chf_imultiply();
  int chf_irem();
  int chf_isubtract();
  int chf_radd();
  int chf_rdivide();
  int chf_rmultiply();
  int chf_rsubtract();
  int chs_lit();
  predef_exception cp_callmessage();
  predef_exception cp_inport();
  predef_exception cp_nominal();
  predef_exception cp_outport();
  predef_exception cp_polymorph();
  predef_exception cp_program();
  predef_exception cp_real();
  predef_exception cp_record();
  predef_exception cp_table();
  predef_exception cp_variant();
  pcb *do_return();
  int do_table_position();
  predef_exception doCopyOnWrite();
  void end_selector();
  status eq_callmessage();
  status eq_inport();
  status eq_outport();
  status eq_nominal();
  status eq_polymorph();
  status eq_program();
  status eq_record();
  status eq_table();
  status eq_variant();
#ifndef _AIX
  void fflush();
#endif
  status findfunc();
  void fin_callmessage();
  void fin_inport();
  void fin_outport();
  void fin_nominal();
  void fin_polymorph();
  void fin_program();
  void fin_record();
  void fin_table();
  void fin_variant();
  predef_exception get_selected_object();
  inspect_frame *get_selector_frame();
  predef_exception idxfindnext();
  predef_exception init_selector();
  predef_exception insertfunc();
  dfd_inport *make_inport();
  pd_program *make_pgm_copy();
  predef_exception mergefunc();
  dfd_record *new_record();
  void raise_user();
  int raise_exception();
  predef_exception re_copy();
  void re_finalize();
  void re_print();
  void rem_return();
  void rem_return_exception();
  predef_exception remove_at_func();
  predef_exception removefunc();
  void set_error();
  void set_trace_level();

  data = current->ep.h->data;
  qualifiers = dot(dcdot(current->prog,program__LI_PROGRAM),prog__pool);
#ifdef INTERPRET
#define COMPUTE_TARGET goto escape
#define SELECTOR (dot(dot(cop,operation__qualifier),VARIANT_COMPONENT).integer
#else
#define COMPUTE_TARGET goto select
#define SELECTOR current->ip
#endif
\end{verbatim}

\subsection{Initialization Code}

The following code is included following the local declarations.
It completes the initialization for the {\tt escape} function.

\begin{verbatim}

  data = current->ep.h->data;
  selector = dot(dot(cop, operation__qualifier),
                 VARIANT_COMPONENT).integer;
  while (TRUE) {

\end{verbatim}

{\bf labeled code to raise exceptions}

\begin{verbatim}
ch_case_error :
  ch_val.enumeration = CaseError;
  goto ch_builtin_handler;

ch_depletion :
  ch_val.enumeration = Depletion;
  goto ch_builtin_handler;

ch_dividebyzero :
  ch_val.enumeration = DivideByZero;
  goto ch_builtin_handler;

ch_notfound :
  ch_val.enumeration = NotFound;
  goto ch_builtin_handler;

ch_range_error :
  ch_val.enumeration = RangeError;
  goto ch_builtin_handler;

ch_raise_exception :
  ch_val.enumeration = ch_returncode;

ch_builtin_handler :
  ch_e = handler_type__builtin;

ch_exception :
  set_error(current, ch_e, ch_val);
  current->ip = raise_exception(current);
#ifdef INTERPRET
escape:
  cop =  get_elem(dot(dcdot(current->prog, program__LI_PROGRAM), prog__code),
		  current->ip);
  if (dot(cop, operation__opcode).integer != opcode__escape)
    return;
#endif
  goto select;
}
\end{verbatim}
