#include <stdio.h>
#include <assert.h>
#include "nat.h"

extern kdatum true ();
extern kdatum false ();

int nat= -1;

int eqnat (p1, p2)
  udatum p1, p2;
{
  return p1->ino == p2->ino;
}

char *dnat (n)
  udatum n;
{
  static char buf[10];

  (void) sprintf(buf, "%d", n->ino);
  return buf;
}

int pnat (p, r)
  char **p;
  udatum *r;
{
  int d, l;

  if (sscanf(*p, "%d%n", &d, &l) == 1)
  { *p+= l;                 /* update pointer */
    (*r)= ud_alloc();       /* build result */
    (*r)->ino= d;
    return TRUE;
  }
  else
    return FALSE;
}

udatum zero ()
{
  static udatum v= NULL;

  if (v == NULL)
  { v= ud_alloc();
    v->ino= 0;
    (void) ud_const(nat, v);
  }
  return v;
}

udatum one ()
{
  static udatum v= NULL;

  if (v == NULL)
  { v= ud_alloc();
    v->ino= 1;
    (void) ud_const(nat, v);
  }
  return v;
}

udatum succ (p1)
  udatum p1;
{
  udatum v;

  v= ud_alloc();
  v->ino= p1->ino + 1;
  ud_free(nat, p1);
  return v;
}

udatum pred (p1)
  udatum p1;
{
  udatum v;

  assert(p1->ino > 0);
  v= ud_alloc();
  v->ino= p1->ino - 1;
  ud_free(nat, p1);
  return v;
}

udatum plus (p1, p2)
  udatum p1, p2;
{
  udatum v;

  v= ud_alloc();
  v->ino= p1->ino + p2->ino;
  ud_free(nat, p1);
  ud_free(nat, p2);
  return v;
}

kdatum lt (p1, p2)
  udatum p1, p2;
{
  kdatum v;

  if (p1->ino < p2->ino)
    v= true();
  else
    v= false();
  ud_free(nat, p1);
  ud_free(nat, p2);
  return v;
}
