a68g-genie.h

     
   1  //! @file a68g-genie.h
   2  //! @author J. Marcel van der Veer
   3  //!
   4  //! @section Copyright
   5  //!
   6  //! This file is part of Algol68G - an Algol 68 compiler-interpreter.
   7  //! Copyright 2001-2023 J. Marcel van der Veer [algol68g@xs4all.nl].
   8  //!
   9  //! @section License
  10  //!
  11  //! This program is free software; you can redistribute it and/or modify it 
  12  //! under the terms of the GNU General Public License as published by the 
  13  //! Free Software Foundation; either version 3 of the License, or 
  14  //! (at your option) any later version.
  15  //!
  16  //! This program is distributed in the hope that it will be useful, but 
  17  //! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
  18  //! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 
  19  //! more details. You should have received a copy of the GNU General Public 
  20  //! License along with this program. If not, see [http://www.gnu.org/licenses/].
  21  
  22  #if !defined (__A68G_GENIE_H__)
  23  #define __A68G_GENIE_H__
  24  
  25  //! @brief PROC VOID gc heap
  26  
  27  // Prelude errors can also occur in the constant folder
  28  
  29  #define CHECK_INT_SHORTEN(p, i)\
  30    PRELUDE_ERROR (((i) > INT_MAX || (i) < -INT_MAX), p, ERROR_MATH, M_INT)
  31  
  32  #define CHECK_INT_ADDITION(p, i, j)\
  33    PRELUDE_ERROR (\
  34      ((j) > 0 && (i) > (A68_MAX_INT - (j))) || ((j) < 0 && (i) < (-A68_MAX_INT - (j))),\
  35      p, "M overflow", M_INT)
  36  
  37  #define CHECK_INT_MULTIPLICATION(p, i, j)\
  38    PRELUDE_ERROR (\
  39      (j) != 0 && ABS (i) > A68_MAX_INT / ABS (j),\
  40      p, "M overflow", M_INT)
  41  
  42  #define CHECK_BITS_ADDITION(p, i, j)\
  43    if (!MODULAR_MATH (p)) {\
  44      PRELUDE_ERROR (((i) > (A68_MAX_BITS - (j))), p, ERROR_MATH, M_BITS);\
  45    }
  46  
  47  #define CHECK_BITS_SUBTRACTION(p, i, j)\
  48    if (!MODULAR_MATH (p)) {\
  49      PRELUDE_ERROR (((j) > (i)), p, ERROR_MATH, M_BITS);\
  50    }
  51  
  52  #define CHECK_BITS_MULTIPLICATION(p, i, j)\
  53    if (!MODULAR_MATH (p)) {\
  54      PRELUDE_ERROR ((j) != 0 && (i) > A68_MAX_BITS / (j), p, ERROR_MATH, M_BITS);\
  55    }
  56  
  57  #define CHECK_INT_DIVISION(p, i, j)\
  58    PRELUDE_ERROR ((j) == 0, p, ERROR_DIVISION_BY_ZERO, M_INT)
  59  
  60  #define PRELUDE_ERROR(cond, p, txt, add)\
  61    if (cond) {\
  62      if (A68 (in_execution)) {\
  63        diagnostic (A68_RUNTIME_ERROR, p, txt, add);\
  64        exit_genie (p, A68_RUNTIME_ERROR);\
  65      } else {\
  66        diagnostic (A68_MATH_ERROR, p, txt, add);\
  67      }}
  68  
  69  // Check on a NIL name
  70  
  71  #define CHECK_REF(p, z, m)\
  72    if (! INITIALISED (&z)) {\
  73      diagnostic (A68_RUNTIME_ERROR, (p), ERROR_EMPTY_VALUE_FROM, (m));\
  74      exit_genie ((p), A68_RUNTIME_ERROR);\
  75    } else if (IS_NIL (z)) {\
  76      diagnostic (A68_RUNTIME_ERROR, (p), ERROR_ACCESSING_NIL, (m));\
  77      exit_genie ((p), A68_RUNTIME_ERROR);\
  78    }
  79  
  80  // Macros for row-handling
  81  
  82  #define DESCRIPTOR_SIZE(n) (SIZE_ALIGNED (A68_ARRAY) + (n) * SIZE_ALIGNED (A68_TUPLE))
  83  
  84  #define NEW_ROW_1D(des, row, arr, tup, row_m, mod, upb)\
  85    (des) = heap_generator (p, (row_m), DESCRIPTOR_SIZE (1));\
  86    (row) = heap_generator (p, (row_m), (upb) * SIZE (mod));\
  87    DIM (&(arr)) = 1;\
  88    MOID (&(arr)) = (mod);\
  89    ELEM_SIZE (&(arr)) = SIZE (mod);\
  90    SLICE_OFFSET (&(arr)) = 0;\
  91    FIELD_OFFSET (&(arr)) = 0;\
  92    ARRAY (&(arr)) = (row);\
  93    LWB (&(tup)) = 1;\
  94    UPB (&(tup)) = (upb);\
  95    SHIFT (&(tup)) = LWB (&(tup));\
  96    SPAN (&(tup)) = 1;\
  97    K (&(tup)) = 0;\
  98    PUT_DESCRIPTOR ((arr), (tup), &(des));
  99  
 100  #define GET_DESCRIPTOR(a, t, p)\
 101    a = (A68_ARRAY *) ARRAY_ADDRESS (p);\
 102    t = (A68_TUPLE *) & (((BYTE_T *) (a)) [SIZE_ALIGNED (A68_ARRAY)]);
 103  
 104  #define GET_DESCRIPTOR2(a, t1, t2, p)\
 105    a = (A68_ARRAY *) ARRAY_ADDRESS (p);\
 106    t1 = (A68_TUPLE *) & (((BYTE_T *) (a)) [SIZE_ALIGNED (A68_ARRAY)]);\
 107    t2 = (A68_TUPLE *) & (((BYTE_T *) (a)) [SIZE_ALIGNED (A68_ARRAY) + sizeof (A68_TUPLE)]);
 108  
 109  #define PUT_DESCRIPTOR(a, t1, p) {\
 110    BYTE_T *a_p = ARRAY_ADDRESS (p);\
 111    *(A68_ARRAY *) a_p = (a);\
 112    *(A68_TUPLE *) &(((BYTE_T *) (a_p)) [SIZE_ALIGNED (A68_ARRAY)]) = (t1);\
 113    }
 114  
 115  #define PUT_DESCRIPTOR2(a, t1, t2, p) {\
 116    BYTE_T *a_p = ARRAY_ADDRESS (p);\
 117    *(A68_ARRAY *) a_p = (a);\
 118    *(A68_TUPLE *) &(((BYTE_T *) (a_p)) [SIZE_ALIGNED (A68_ARRAY)]) = (t1);\
 119    *(A68_TUPLE *) &(((BYTE_T *) (a_p)) [SIZE_ALIGNED (A68_ARRAY) + sizeof (A68_TUPLE)]) = (t2);\
 120    }
 121  
 122  #define ROW_SIZE(t) ((LWB (t) <= UPB (t)) ? (UPB (t) - LWB (t) + 1) : 0)
 123  #define ROW_ELEMENT(a, k) (((ADDR_T) k + SLICE_OFFSET (a)) * ELEM_SIZE (a) + FIELD_OFFSET (a))
 124  #define INDEX_1_DIM(a, t, k) ROW_ELEMENT (a, (SPAN (t) * (int) (k) - SHIFT (t)))
 125  
 126  #define VECTOR_OFFSET(a, t)\
 127    ((LWB (t) * SPAN (t) - SHIFT (t) + SLICE_OFFSET (a)) * ELEM_SIZE (a) + FIELD_OFFSET (a))
 128  
 129  #define MATRIX_OFFSET(a, t1, t2)\
 130    ((LWB (t1) * SPAN (t1) - SHIFT (t1) + LWB (t2) * SPAN (t2) - SHIFT (t2) + SLICE_OFFSET (a)) * ELEM_SIZE (a) + FIELD_OFFSET (a))
 131  
 132  // Execution
 133  
 134  #define EXECUTE_UNIT_2(p, dest) {\
 135    PROP_T *_prop_ = &GPROP (p);\
 136    A68 (f_entry) = p;\
 137    dest = (*(UNIT (_prop_))) (SOURCE (_prop_));}
 138  
 139  #define EXECUTE_UNIT(p) {\
 140    PROP_T *_prop_ = &GPROP (p);\
 141    A68 (f_entry) = p;\
 142    (void) (*(UNIT (_prop_))) (SOURCE (_prop_));}
 143  
 144  #define EXECUTE_UNIT_TRACE(p) {\
 145    if (STATUS_TEST (p, (BREAKPOINT_MASK | BREAKPOINT_TEMPORARY_MASK | \
 146        BREAKPOINT_INTERRUPT_MASK | BREAKPOINT_WATCH_MASK | BREAKPOINT_TRACE_MASK))) {\
 147      single_step ((p), STATUS (p));\
 148    }\
 149    EXECUTE_UNIT (p);}
 150  
 151  // Stuff for the garbage collector
 152  
 153  // Check whether the heap fills
 154  
 155  #define DEFAULT_PREEMPTIVE 0.8
 156  
 157  // Save a handle from the GC
 158  
 159  #define BLOCK_GC_HANDLE(z) {\
 160    if (IS_IN_HEAP (z)) {\
 161      STATUS_SET (REF_HANDLE(z), BLOCK_GC_MASK);\
 162    }}
 163  
 164  #define UNBLOCK_GC_HANDLE(z) {\
 165    if (IS_IN_HEAP (z)) {\
 166      STATUS_CLEAR (REF_HANDLE (z), BLOCK_GC_MASK);\
 167    }}
 168  
 169  // Tests for objects of mode INT
 170  
 171  #define CHECK_INDEX(p, k, t) {\
 172    if (VALUE (k) < LWB (t) || VALUE (k) > UPB (t)) {\
 173      diagnostic (A68_RUNTIME_ERROR, p, ERROR_INDEX_OUT_OF_BOUNDS);\
 174      exit_genie (p, A68_RUNTIME_ERROR);\
 175    }}
 176  
 177  // Tests for objects of mode REAL
 178  
 179  #if defined (HAVE_IEEE_754)
 180  #define CHECK_REAL(p, u) PRELUDE_ERROR (!finite (u), p, ERROR_INFINITE, M_REAL)
 181  #define CHECK_COMPLEX(p, u, v) PRELUDE_ERROR (!finite (u) || !finite (v), p, ERROR_INFINITE, M_COMPLEX)
 182  #else
 183  #define CHECK_REAL(p, u) {;}
 184  #define CHECK_COMPLEX(p, u, v) {;}
 185  #endif
 186  
 187  #define MATH_RTE(p, z, m, t) PRELUDE_ERROR (z, (p), (t == NO_TEXT ? ERROR_MATH : t), (m))
 188  
 189  // Macros.
 190  
 191  #define C_FUNCTION(p, f)\
 192    A68 (f_entry) = p;\
 193    A68_REAL *x;\
 194    POP_OPERAND_ADDRESS (p, x, A68_REAL);\
 195    errno = 0;\
 196    VALUE (x) = f (VALUE (x));\
 197    MATH_RTE (p, errno != 0, M_REAL, NO_TEXT);
 198  
 199  #define OWN_FUNCTION(p, f)\
 200    A68 (f_entry) = p;\
 201    A68_REAL *x;\
 202    POP_OPERAND_ADDRESS (p, x, A68_REAL);\
 203    errno = 0;\
 204    VALUE (x) = f (p, VALUE (x));\
 205    MATH_RTE (p, errno != 0, M_REAL, NO_TEXT);
 206  
 207  // Macro's for standard environ
 208  
 209  #define A68_ENV_INT(n, k) void n (NODE_T *p) {PUSH_PRIMAL (p, (k), INT);}
 210  #define A68_ENV_REAL(n, z) void n (NODE_T *p) {PUSH_PRIMAL (p, (z), REAL);}
 211  
 212  // Macros for the evaluation stack
 213  
 214  #define INCREMENT_STACK_POINTER(err, i)\
 215    {A68_SP += (ADDR_T) A68_ALIGN (i); (void) (err);}
 216  
 217  #define DECREMENT_STACK_POINTER(err, i)\
 218    {A68_SP -= A68_ALIGN (i); (void) (err);}
 219  
 220  #define PUSH(p, addr, size) {\
 221    BYTE_T *_sp_ = STACK_TOP;\
 222    INCREMENT_STACK_POINTER ((p), (int) (size));\
 223    COPY (_sp_, (BYTE_T *) (addr), (int) (size));\
 224    }
 225  
 226  #define POP(p, addr, size) {\
 227    DECREMENT_STACK_POINTER((p), (int) (size));\
 228    COPY ((BYTE_T *) (addr), STACK_TOP, (int) (size));\
 229    }
 230  
 231  #define POP_ALIGNED(p, addr, size) {\
 232    DECREMENT_STACK_POINTER((p), (int) (size));\
 233    COPY_ALIGNED ((BYTE_T *) (addr), STACK_TOP, (int) (size));\
 234    }
 235  
 236  #define POP_ADDRESS(p, addr, type) {\
 237    DECREMENT_STACK_POINTER((p), (int) SIZE_ALIGNED (type));\
 238    (addr) = (type *) STACK_TOP;\
 239    }
 240  
 241  #define POP_OPERAND_ADDRESS(p, i, type) {\
 242    (void) (p);\
 243    (i) = (type *) (STACK_OFFSET (-SIZE_ALIGNED (type)));\
 244    }
 245  
 246  #define POP_OPERAND_ADDRESSES(p, i, j, type) {\
 247    DECREMENT_STACK_POINTER ((p), (int) SIZE_ALIGNED (type));\
 248    (j) = (type *) STACK_TOP;\
 249    (i) = (type *) (STACK_OFFSET (-SIZE_ALIGNED (type)));\
 250    }
 251  
 252  #define POP_3_OPERAND_ADDRESSES(p, i, j, k, type) {\
 253    DECREMENT_STACK_POINTER ((p), (int) (2 * SIZE_ALIGNED (type)));\
 254    (k) = (type *) (STACK_OFFSET (SIZE_ALIGNED (type)));\
 255    (j) = (type *) STACK_TOP;\
 256    (i) = (type *) (STACK_OFFSET (-SIZE_ALIGNED (type)));\
 257    }
 258  
 259  #define PUSH_VALUE(p, z, mode) {\
 260    mode *_x_ = (mode *) STACK_TOP;\
 261    STATUS (_x_) = INIT_MASK;\
 262    VALUE (_x_) = (z);\
 263    INCREMENT_STACK_POINTER ((p), SIZE_ALIGNED (mode));\
 264    }
 265  
 266  #define PUSH_PRIMAL(p, z, m) {\
 267    A68_##m *_x_ = (A68_##m *) STACK_TOP;\
 268    int _size_ = SIZE_ALIGNED (A68_##m);\
 269    STATUS (_x_) = INIT_MASK;\
 270    VALUE (_x_) = (z);\
 271    INCREMENT_STACK_POINTER ((p), _size_);\
 272    }
 273  
 274  #define PUSH_OBJECT(p, z, mode) {\
 275    *(mode *) STACK_TOP = (z);\
 276    INCREMENT_STACK_POINTER (p, SIZE_ALIGNED (mode));\
 277    }
 278  
 279  #define POP_OBJECT(p, z, mode) {\
 280    DECREMENT_STACK_POINTER((p), SIZE_ALIGNED (mode));\
 281    (*(z)) = *((mode *) STACK_TOP);\
 282    }
 283  
 284  #define PUSH_COMPLEX(p, re, im) {\
 285    PUSH_PRIMAL (p, re, REAL);\
 286    PUSH_PRIMAL (p, im, REAL);\
 287    }
 288  
 289  #define POP_COMPLEX(p, re, im) {\
 290    POP_OBJECT (p, im, A68_REAL);\
 291    POP_OBJECT (p, re, A68_REAL);\
 292    }
 293  
 294  #define PUSH_BYTES(p, k) {\
 295    A68_BYTES *_z_ = (A68_BYTES *) STACK_TOP;\
 296    STATUS (_z_) = INIT_MASK;\
 297    a68_memmove (VALUE (_z_), k, BYTES_WIDTH);\
 298    INCREMENT_STACK_POINTER((p), SIZE_ALIGNED (A68_BYTES));\
 299    }
 300  
 301  #define PUSH_LONG_BYTES(p, k) {\
 302    A68_LONG_BYTES *_z_ = (A68_LONG_BYTES *) STACK_TOP;\
 303    STATUS (_z_) = INIT_MASK;\
 304    a68_memmove (VALUE (_z_), k, LONG_BYTES_WIDTH);\
 305    INCREMENT_STACK_POINTER((p), SIZE_ALIGNED (A68_LONG_BYTES));\
 306    }
 307  
 308  #define PUSH_REF(p, z) PUSH_OBJECT (p, z, A68_REF)
 309  #define PUSH_PROCEDURE(p, z) PUSH_OBJECT (p, z, A68_PROCEDURE)
 310  #define PUSH_FORMAT(p, z) PUSH_OBJECT (p, z, A68_FORMAT)
 311  
 312  #define POP_REF(p, z) POP_OBJECT (p, z, A68_REF)
 313  #define POP_PROCEDURE(p, z) POP_OBJECT (p, z, A68_PROCEDURE)
 314  
 315  #define PUSH_UNION(p, z) {\
 316    A68_UNION *_x_ = (A68_UNION *) STACK_TOP;\
 317    STATUS (_x_) = INIT_MASK;\
 318    VALUE (_x_) = (z);\
 319    INCREMENT_STACK_POINTER ((p), SIZE_ALIGNED (A68_UNION));\
 320    }
 321  
 322  // Interpreter macros
 323  
 324  #define INITIALISED(z)  ((BOOL_T) (STATUS (z) & INIT_MASK))
 325  #define MODULAR_MATH(z) ((BOOL_T) (STATUS (z) & MODULAR_MASK))
 326  #define LHS_MODE(p) (MOID (PACK (MOID (p))))
 327  #define RHS_MODE(p) (MOID (NEXT (PACK (MOID (p)))))
 328  
 329  // Transput related macros
 330  
 331  #define IS_NIL_FORMAT(f) ((BOOL_T) (BODY (f) == NO_NODE && ENVIRON (f) == 0))
 332  
 333  // Macros for check on initialisation of values
 334  
 335  #define CHECK_INIT(p, c, q)\
 336    if (!(c)) {\
 337      diagnostic (A68_RUNTIME_ERROR, (p), ERROR_EMPTY_VALUE_FROM, (q));\
 338      exit_genie ((p), A68_RUNTIME_ERROR);\
 339    }
 340  
 341  #define CHECK_DNS2(p, scope, limit, mode)\
 342    if (scope > limit) {\
 343      BUFFER txt;\
 344      ASSERT (snprintf (txt, SNPRINTF_SIZE, ERROR_SCOPE_DYNAMIC_1) >= 0);\
 345      diagnostic (A68_RUNTIME_ERROR, p, txt, mode);\
 346      exit_genie (p, A68_RUNTIME_ERROR);\
 347    }
 348  
 349  #define CHECK_DNS(p, m, w, limit)\
 350    if (NEED_DNS (GINFO (p))) {\
 351      ADDR_T _lim = ((limit) < A68_GLOBALS ? A68_GLOBALS : (limit));\
 352      if (IS ((m), REF_SYMBOL)) {\
 353        CHECK_DNS2 (p, (REF_SCOPE ((A68_REF *) (w))), _lim, (m));\
 354      } else if (IS ((m), PROC_SYMBOL)) {\
 355        CHECK_DNS2 (p, ENVIRON ((A68_PROCEDURE *) (w)), _lim, (m));\
 356      } else if (IS ((m), FORMAT_SYMBOL)) {\
 357        CHECK_DNS2 (p, ENVIRON ((A68_FORMAT *) w), _lim, (m));\
 358    }}
 359  
 360  // 
 361  // The void * cast in next macro is to stop warnings about dropping a volatile
 362  // qualifier to a pointer. This is safe here.
 363  
 364  #define STACK_DNS(p, m, limit)\
 365    if (p != NO_NODE && GINFO (p) != NO_GINFO) {\
 366      CHECK_DNS ((NODE_T *)(void *)(p), (m),\
 367                 (STACK_OFFSET (-SIZE (m))), (limit));\
 368    }
 369  
 370  // Genie routines.
 371  
 372  extern PROP_T genie_column_function (NODE_T *);
 373  extern PROP_T genie_diagonal_function (NODE_T *);
 374  extern PROP_T genie_row_function (NODE_T *);
 375  extern PROP_T genie_transpose_function (NODE_T *);
 376  
 377  extern PROP_T genie_and_function (NODE_T *);
 378  extern PROP_T genie_assertion (NODE_T *);
 379  extern PROP_T genie_assignation_constant (NODE_T *);
 380  extern PROP_T genie_assignation (NODE_T *);
 381  extern PROP_T genie_assignation_quick (NODE_T * p);
 382  extern PROP_T genie_call (NODE_T *);
 383  extern PROP_T genie_cast (NODE_T *);
 384  extern PROP_T genie_closed (volatile NODE_T *);
 385  extern PROP_T genie_coercion (NODE_T *);
 386  extern PROP_T genie_collateral (NODE_T *);
 387  extern PROP_T genie_conditional (volatile NODE_T *);
 388  extern PROP_T genie_constant (NODE_T *);
 389  extern PROP_T genie_denotation (NODE_T *);
 390  extern PROP_T genie_deproceduring (NODE_T *);
 391  extern PROP_T genie_dereference_frame_identifier (NODE_T *);
 392  extern PROP_T genie_dereference_generic_identifier (NODE_T *);
 393  extern PROP_T genie_dereference_selection_name_quick (NODE_T *);
 394  extern PROP_T genie_dereference_slice_name_quick (NODE_T *);
 395  extern PROP_T genie_dereferencing (NODE_T *);
 396  extern PROP_T genie_dereferencing_quick (NODE_T *);
 397  extern PROP_T genie_dyadic (NODE_T *);
 398  extern PROP_T genie_dyadic_quick (NODE_T *);
 399  extern PROP_T genie_enclosed (volatile NODE_T *);
 400  extern PROP_T genie_field_selection (NODE_T *);
 401  extern PROP_T genie_format_text (NODE_T *);
 402  extern PROP_T genie_formula (NODE_T *);
 403  extern PROP_T genie_frame_identifier (NODE_T *);
 404  extern PROP_T genie_identifier (NODE_T *);
 405  extern PROP_T genie_identifier_standenv (NODE_T *);
 406  extern PROP_T genie_identifier_standenv_proc (NODE_T *);
 407  extern PROP_T genie_identity_relation (NODE_T *);
 408  extern PROP_T genie_int_case (volatile NODE_T *);
 409  extern PROP_T genie_loop (volatile NODE_T *);
 410  extern PROP_T genie_loop (volatile NODE_T *);
 411  extern PROP_T genie_monadic (NODE_T *);
 412  extern PROP_T genie_nihil (NODE_T *);
 413  extern PROP_T genie_or_function (NODE_T *);
 414  extern PROP_T genie_routine_text (NODE_T *);
 415  extern PROP_T genie_rowing (NODE_T *);
 416  extern PROP_T genie_rowing_ref_row_of_row (NODE_T *);
 417  extern PROP_T genie_rowing_ref_row_row (NODE_T *);
 418  extern PROP_T genie_rowing_row_of_row (NODE_T *);
 419  extern PROP_T genie_rowing_row_row (NODE_T *);
 420  extern PROP_T genie_selection_name_quick (NODE_T *);
 421  extern PROP_T genie_selection (NODE_T *);
 422  extern PROP_T genie_selection_value_quick (NODE_T *);
 423  extern PROP_T genie_skip (NODE_T *);
 424  extern PROP_T genie_slice_name_quick (NODE_T *);
 425  extern PROP_T genie_slice (NODE_T *);
 426  extern PROP_T genie_united_case (volatile NODE_T *);
 427  extern PROP_T genie_uniting (NODE_T *);
 428  extern PROP_T genie_unit (NODE_T *);
 429  extern PROP_T genie_voiding_assignation_constant (NODE_T *);
 430  extern PROP_T genie_voiding_assignation (NODE_T *);
 431  extern PROP_T genie_voiding (NODE_T *);
 432  extern PROP_T genie_widen_int_to_real (NODE_T *);
 433  extern PROP_T genie_widen (NODE_T *);
 434  
 435  extern A68_REF genie_clone (NODE_T *, MOID_T *, A68_REF *, A68_REF *);
 436  extern A68_REF genie_make_ref_row_of_row (NODE_T *, MOID_T *, MOID_T *, ADDR_T);
 437  extern A68_REF genie_make_ref_row_row (NODE_T *, MOID_T *, MOID_T *, ADDR_T);
 438  extern A68_REF genie_make_rowrow (NODE_T *, MOID_T *, int, ADDR_T);
 439  
 440  extern void genie_clone_stack (NODE_T *, MOID_T *, A68_REF *, A68_REF *);
 441  extern void genie_serial_units_no_label (NODE_T *, ADDR_T, NODE_T **);
 442  
 443  #endif