#include "forth.h"

/* For linking entries. 
 * The first entry has a null link.
 */
long *last_dp = (long *) NULL;

void add_primitive (struct prim_skel skel)
{
  char *bdp;

  /* It is important that the top bit of length be clear, so we can
   * XOR in the precedence.
   */
  char length =
    ((char) (MIN (ENTRY_MAX_NAME_LENGTH, (strlen (skel.name))))) & 127;
  
  /* Record the previous dp. */
  long *previous_entry = last_dp;

  /* Save this dp. */
  last_dp = dp;

  /* Set the precedence. */
  bdp = (char *) dp;
  *bdp++ = ((char) length ^ (char) skel.precedence);

  /* Set the name. */
  strncpy (bdp, skel.name, length);

  /* Advance dp by the length of a name. */
  bdp += ENTRY_MAX_NAME_LENGTH;

  dp = (long *) bdp;

  /* Set the link field. */
  *dp++ = (unsigned long) previous_entry;

  /* Set the CFA. */
  *dp++ = (unsigned long) (funcptr) skel.func;

  *dp++ = END_OF_PARAMS;
}


/* Initializes a word, up thru the CFA.  Fcolon uses this. */
void
start_word (char *name, char length, char immediate_p)
{
  char *bdp;

  /* Record the previous dp. */
  long *previous_entry = last_dp;

  /* Save this dp. */
  last_dp = dp;

  /* It is important that the top bit of length be clear, so we can
   * XOR in the precedence later.
   */
  if (length)
    length &= 127;
  else
    length = ((char) MIN (strlen (name), ENTRY_MAX_NAME_LENGTH)) & 127;
  
  bdp = (char *) dp;

  /* Set the precedence. */
  *bdp++ = (length ^ immediate_p);

  /* Set the name. */
  strncpy (bdp, name, (int) length);

  /* Advance dp by the length of a name. */
  bdp += ENTRY_MAX_NAME_LENGTH;

  dp = (long *) bdp;

  /* Set the link field. */
  *dp++ = (unsigned long) previous_entry;

  /* Set the CFA. */
  *dp++ = (unsigned long) ((funcptr) address_interpreter);
}
