Sindbad~EG File Manager

Current Path : /usr/home/beeson/Otter-Lambda/otter/
Upload File :
Current File : /usr/home/beeson/Otter-Lambda/otter/lisp.c

#include "lisp.h"

#define MAX_WORD 100
static char Word[MAX_WORD];
static int Gets, Frees;

#if 0
    NOTE: the purpose of the /**/ comments before the function
    definitions is to prevent the prototype-making scripts from
    making prototypes for the functions.
#endif

/*************************************************************************/

static BOOLEAN str_ident(char *s, char *t)
{
  return (strcmp(s, t) == 0);
}  /* str_ident */

/*************************************************************************/

static char *new_str_copy(char *str)
{
  char *p = (void *) malloc((size_t) strlen(str)+1);
  strcpy(p, str);
  return p;
}  /* new_str_copy */

/*************************************************************************/

static Bnode get_bnode(void)
{
  Bnode p = (void *) malloc((size_t) sizeof(struct bnode));
  Gets++;
  p->car = NULL;
  p->cdr = NULL;
  p->label = NULL;
  p->atom = TRUE;
  return p;
}  /* get_bnode */

/*************************************************************************/

static void free_bnode(Bnode p)
{
  Frees++;
  if (p->atom)
    free(p->label);
  free(p);
}  /* get_bnode */

/*************************************************************************/

/**/ void zap_btree(Bnode p)
{
  if (!p->atom) {
    zap_btree(p->car);
    zap_btree(p->cdr);
  }
  free_bnode(p);
}  /* get_bnode */

/*************************************************************************/

/**/ BOOLEAN true_listp(Bnode p)
{
  if (p->atom)
    return str_ident(p->label, "nil");
  else
    return true_listp(p->cdr);
}  /* true_listp */

/*************************************************************************/

/**/ void fprint_btree(FILE *fp, Bnode p)
{
  if (p->atom)
    fprintf(fp, "%s", p->label);
  else if (true_listp(p)) {
    Bnode p2;
    fprintf(fp,"(");
    for (p2 = p; p2->cdr != NULL; p2 = p2->cdr) {
      fprint_btree(fp, p2->car);
      if (p2->cdr->cdr)
	fprintf(fp," ");
    }
    fprintf(fp,")");
  }
  else {
    fprintf(fp,"(");
    fprint_btree(fp, p->car);
    fprintf(fp," . ");
    fprint_btree(fp, p->cdr);
    fprintf(fp,")");
  }
}  /* fprint_btree */

/*************************************************************************/

/**/ void p_btree(Bnode p)
{
  fprint_btree(stdout, p);
  printf("\n");
  fflush(stdout);
}  /* p_btree */

/*************************************************************************/

static BOOLEAN white_char(char c)
{
  return (c == ' '  ||
          c == '\t' ||  /* tab */
          c == '\n' ||  /* newline */
          c == '\v' ||  /* vertical tab */
          c == '\r' ||  /* carriage return */
          c == '\f');   /* form feed */
}  /* white_char */

static BOOLEAN paren(char c)
{
  return (c == '('  ||
          c == ')');
}  /* paren */

/*************************************************************************/

static int fill_word(FILE *fp)
{
  int c;
  int i = 0;
  c = getc(fp);
  while (c != EOF && white_char((char) c))    // cast added by Beeson, 7.23.02
    c = getc(fp);
  if (c != EOF) {
    while (c != EOF && !white_char((char)c) && !paren((char)c)) {  // casts added by Beeson, 7.23.02
      Word[i] = c;
      i++;
      if (i == MAX_WORD) {
	Word[i] = '\0';
	fprintf(stderr, "fill_word, word too big: |%s|\n", Word);
	exit(2);
      }
      c = getc(fp);
    }
    if (c == ')' || (i != 0 && c == '('))
      ungetc(c, fp);
  }
  Word[i] = '\0';
  return(c);
}  /* fill_word */

/*************************************************************************/

/**/ BOOLEAN nullp(Bnode p)
{
  return (p->atom && str_ident(p->label,"nil"));
}  /* nullp */

static BOOLEAN dotp(Bnode p)
{
  return (p->atom && str_ident(p->label,"."));
}  /* nullp */

/*************************************************************************/

static void dot_trans (Bnode p)
{
  Bnode curr = p;
  Bnode prev = NULL;
  while (!curr->atom) {
    if (dotp(curr->car)) {
      if (!curr->cdr->atom &&
	  nullp(curr->cdr->cdr) &&
	  prev != NULL &&
	  !dotp(curr->cdr->car)) {
	prev->cdr = curr->cdr->car;
	free_bnode(curr->cdr->cdr);
	free_bnode(curr->cdr);
	free_bnode(curr->car);
	free_bnode(curr);
      }
      else {
	fprintf(stderr, "dot_trans, bad dot notation\n");
	exit(2);
      }
    }
    prev = curr;
    curr = curr->cdr;
  }
}  /* dot_trans */

/*************************************************************************/

/**/ Bnode parse_lisp(FILE *fp)
{
  int c;
  c = fill_word(fp);
  if (!str_ident(Word, "")) {
    Bnode p = get_bnode();
    p->atom = TRUE;
    p->label = new_str_copy(Word);
    return p;
  }
  else if (c == ')' )
    return NULL;
  else if (c == '(') {
    Bnode top = get_bnode();
    Bnode curr = top;
    Bnode p = parse_lisp(fp);
    while (p != NULL) {
      curr->atom = FALSE;
      curr->car = p;
      curr->cdr = get_bnode();
      curr = curr->cdr;
      p = parse_lisp(fp);
    }
    c = getc(fp);  /* step past ')' */
    curr->label = new_str_copy("nil");
    curr->atom = TRUE;
    dot_trans(top);
    return top;
  }
  else
    return NULL;
}  /* parse_lisp */

/*************************************************************************/

/**/ int atom(Bnode p)
{ return p->atom; }  /* atom */

/*************************************************************************/

/**/ Bnode car(Bnode p)
{ return p->car;}  /* car */

/*************************************************************************/

/**/ Bnode cdr(Bnode p)
{ return p->cdr;}  /* cdr */

/*************************************************************************/

/**/ Bnode cadr(Bnode p)
{ return p->cdr->car;}  /* cadr */

/*************************************************************************/

/**/ Bnode caddr(Bnode p)
{ return p->cdr->cdr->car;}  /* caddr */

/*************************************************************************/

/**/ int length(Bnode p)
{
  return (atom(p) ? 0 : length(cdr(p)) + 1);
}  /* length */

/*************************************************************************/

#ifdef SOLO

/**/ int main(int argc, char **argv)
{
  Bnode p;

  p = parse_lisp(stdin);
  fprint_btree(stdout, p);
  printf("length = %d\n", length(p));
  zap_btree(p);
  printf("Gets=%d, Frees=%d.\n", Gets, Frees);
}  /* main */

#endif

Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists