/***********************************************************************
     "nat.o": manual implementation of sort Nat
***********************************************************************/

/***********************************
  (C) Copyright 1994; dit/upm
   Distributed under the conditions stated in the
   TOPO General Public License (see file LICENSE)
 ***********************************/

/* LINTLIBRARY */

#define nat_IMP

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

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

PUBLIC char *
NATdraw(p)
  udatum p;
{
  static char r[20];

  (void) sprintf(r, "%d", p->ino);
  return r;
}

PUBLIC int
NATparse(ptr, r)
  char **ptr;
  udatum *r;
{
  int d, l;

  if (sscanf(*ptr, "%d%n", &d, &l) == 1)
  { *ptr+= l;
    (*r)= ud_alloc();
    (*r)->ino= d;
    return TRUE;
  }
  else
    return FALSE;
}

PUBLIC udatum
NATdatum (v)
  int v;
{
  static udatum buf[50]= { NULL };

  assert(v >= 0);
  if (v >= sizeof(buf) / sizeof(buf[0]))
  { udatum p;

    p= ud_alloc();
    p->ino= v;
    return p;
  }
  if (buf[v] == NULL)
  { buf[v]= ud_alloc();
    buf[v]->ino= v;
    (void) ud_const(Nat, buf[v]);
  }
  return buf[v];
}

PUBLIC int
NATvalue (p)
  udatum p;
{
  int v;

  v= p->ino;
  assert(v >= 0);
  ud_free(Nat, p);
  return v;
}

PUBLIC udatum
NATpower (p1, p2)
  udatum p1, p2;
{
  int v1, v2;
  int r;
  int i;

  v1= NATvalue(p1);
  v2= NATvalue(p2);
  r= 1;
  for (i= 0; i < v2; ++i)
    r*= v1;
  return NATdatum(r);
}

PUBLIC udatum
NATdivision (p1, p2)
  udatum p1, p2;
{
  int v1, v2;
  int r;

  v1= NATvalue(p1);
  v2= NATvalue(p2);
  assert(v2 != 0);
  r= v1 / v2;
  return NATdatum(r);
}

PUBLIC udatum
NATmodulus (p1, p2)
  udatum p1, p2;
{
  int v1, v2;
  int r;

  v1= NATvalue(p1);
  v2= NATvalue(p2);
  assert(v2 != 0);
  r= v1 % v2;
  return NATdatum(r);
}
