view anagram/agcore/stacks.cpp @ 14:a02e9434072e

Fix friend declaration for gcc10. XXX: did not check it against the IBM compiler, might end up needing XXX: to be conditional.
author David A. Holland
date Tue, 31 May 2022 00:59:42 -0400
parents 57b2cc9b87f7
children
line wrap: on
line source

/*
 * AnaGram, A System for Syntax Directed Programming
 * Copyright 1993-2002 Parsifal Software. All Rights Reserved.
 * See the file COPYING for license and usage terms.
 *
 * stacks.cpp
 */

#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include "port.h"

#ifdef VACLGUI
#include <icritsec.hpp>
#include "resource.h"
#endif

#include "agstring.h"
#include "assert.h"
#include "dict.h"
#include "myalloc.h"
#include "stacks.h"

//#define INCLUDE_LOGGING
#include "log.h"


#define cs char_strings_base
#define ws word_strings_base
#define ls long_strings_base
#define is int_stack_base
#define ni int_stack_top

static char *cs;
static int  *ws;
static int  *is;
static unsigned lcs,lws, lis;
unsigned ni;
unsigned nc;
unsigned nw;
static unsigned lcx;
static unsigned lwx;
static unsigned llx;
char *string_base;
int *list_base;

#ifdef VACLGUI
static AgResource charStackResource;
#endif


void init_stk(void) {
  LOGSECTION("init_stk");
  lcs = 100;
  lws = 100;
  lis = 20;
  cs = (char *) myalloc(lcs);
  ws = (int *) myalloc(lws * sizeof(*ws));
  is = (int *) myalloc((lis+1) * sizeof(*is));
  nc = nw = ni = lcx = lwx = llx = 0;
}

/*
void logStringStack() {
  //LOGSECTION("Stack status");
  log.line() << nc << nw << ni;
  log.line() << lcs << lws << lis;
}
*/
/*
void delete_stack(void) {
  DEALLOCATE(cs);
  DEALLOCATE(ws);
  DEALLOCATE(is);
}
*/
/*
void slide_stack(void) {
  cs = (char *) myrealloc(cs, lcs, __FILE__, __LINE__);
  ws = (int *) myrealloc(ws, lws * sizeof(*ws), __FILE__, __LINE__);
  is = (int *) myrealloc(is, (lis+1) * sizeof(*is), __FILE__, __LINE__);
}
*/
void reset_stk(void) {
  nc = nw = ni = lcx = lwx = llx = 0;
}

/*
void slns(const char *s) {            / * extract line from string * /
  int n;
  const char *sp;

  ics();
  n = 0;
	if (s) for (sp = s; *sp && *sp != '\n'; sp++) {
		if (*sp == '\t') do acs(' '); while (++n % tab_spacing);
		else acs(*sp), n++;
	}
	cs[nc] = 0;
}
*/

char *string_space(int n) {
  if (nc + n >= lcs) {
#ifdef VACLGUI
    AgLock lock(charStackResource);
#endif
    LOGSECTION("string_space::resize");
    LOGV(lcs) LCV(nc) LCV(n);

    unsigned k = lcs + (lcs >> 1) + n + 1;
    if (k > MAX_BYTES) k = (unsigned) MAX_BYTES;
    lcs = k - 1;
    LOGV(lcs) LCV(nc) LCV(n);
    assert(lcs >= nc+n);
    cs = reallocate(cs,k,char);
    string_base = &cs[lcx];
  }
  return &cs[nc];
}

int *list_space(int n) {
  if (nw + n >= lws) {
#ifdef VACLGUI
    AgLock lock(charStackResource);
#endif
    unsigned k = lws + (lws >> 1) + n + 1;
    if (k > MAX_INTS) {
      k = (unsigned) MAX_INTS;
    }
    lws = k - 1;
    LOGSECTION("list_space::resize");
    LOGV(lws) LCV(nw+n);
    assert(lws >= nw+n);
    REALLOCATE_ST(ws,k);
    list_base = &ws[lwx];
  }
  return &ws[nw];
}

void sss(const char *s) {
#ifdef VACLGUI
  AgLock lock(charStackResource);
#endif
  int n;

  assert(s != NULL);
  n = strlen(s);
  if (ni + 1 >= lis) {
    unsigned k = lis + 3 + (lis >> 1);
    if (k > MAX_INTS) {
      k = (unsigned) MAX_INTS;
    }
    lis = k-1;
    LOGSECTION("sss::resize");
    LOGV(lis) LCV(ni+2);
    assert(lis >= ni+2);
    REALLOCATE_ST(is,k);
  }
  is[ni++] = lcx;
  if (nc + n >= lcs) {
    unsigned k = lcs + (lcs >> 1) + n + 1;
    if (k > MAX_BYTES) {
      k = (unsigned) MAX_BYTES;
    }
    lcs = k - 1;
    LOGSECTION("sss::resize");
    LOGV(lcs) LCV(nc+n);
    assert(lcs >= nc + n);
    cs = reallocate(cs,k,char);
  }
  lcx = nc;
  string_base = &cs[lcx];
  memcpy(string_base,s,n);
  nc += is[ni++] = n;
  cs[nc] = 0;
}

void ass(const char *s) {
#ifdef VACLGUI
  AgLock lock(charStackResource);
#endif
  int n;

  assert(s !=NULL);
  assert(ni>=2);
  n = strlen(s);
  if (nc + n >= lcs) {
    unsigned k = lcs + (lcs >> 1) + n + 1;
    if (k > MAX_BYTES) {
      k = (unsigned) MAX_BYTES;
    }
    lcs = k-1;
    LOGSECTION("ass::resize");
    LOGV(lcs) LCV(nc+n);
    assert(lcs >= nc + n);
    cs = reallocate(cs,k,char);
    string_base = &cs[lcx];
  }
  memcpy(&cs[nc], s, n);
  nc += n;
  is[ni-1] += n;
  cs[nc] = 0;
}

/*
static void extend_string(int n) {
  LOGSECTION("extend_string");
  LOGV(nc) LCV(n);
  is[ni-1] += n;
  nc += n;
  assert(nc < lcs);
}
*/

int ssprintf(const char *fs, ...) {
#ifdef VACLGUI
  AgLock lock(charStackResource);
#endif
  va_list ap;
  int n;

  check_stack;
  if (ni + 1 >= lis) {
    unsigned k = lis + 3 + (lis >> 1);
    if (k > MAX_INTS) {
      k = (unsigned) MAX_INTS;
    }
    lis = k - 1;
    LOGSECTION("ssprintf::resize");
    LOGV(lis) LCV(ni+2);
    assert(lis >= ni+2);
    REALLOCATE_ST(is,k);
  }
  is[ni++] = lcx;
  string_space(500);
  lcx = nc;
  string_base = &cs[lcx];
  va_start(ap,fs);
  n = is[ni++] = vsprintf(&cs[nc],fs,ap);
  nc += n;
  assert(nc < lcs);
  va_end(ap);
  return n;
}

int apprintf(const char *fs, ...) {
#ifdef VACLGUI
  AgLock lock(charStackResource);
#endif
  va_list ap;
  int n;

  assert(ni>=2);
  string_space(500);
  va_start(ap,fs);
  is[ni-1] += (n = vsprintf(&cs[nc],fs,ap));
  nc += n;
  assert(nc < lcs);
  va_end(ap);
  return n;
}

void tss(void) {
  cs[nc] = 0;
}

void ics(void) {
#ifdef VACLGUI
  AgLock lock(charStackResource);
#endif
  //check_stack;
  if (ni + 2 > lis) {
    unsigned k = lis + 3 + (lis >> 1);
    if (k > MAX_INTS) {
      k = (unsigned) MAX_INTS;
    }
    lis = k - 1;
    LOGSECTION("ics::resize");
    LOGV(lis) LCV(ni+2);
    assert(lis >= ni+2);
    REALLOCATE_ST(is,k);
  }
  is[ni++] = lcx;
  lcx = nc;
  string_base = &cs[lcx];
  is[ni++] = 0;
  cs[nc] = 0;
}

void scs(int c) {
#ifdef VACLGUI
  AgLock lock(charStackResource);
#endif
  //check_stack;
  if (ni + 1 >= lis) {
    unsigned k = lis + 3 + (lis >> 1);
    if (k > MAX_INTS) {
      k = (unsigned) MAX_INTS;
    }
    lis = k - 1;
    LOGSECTION("scs::resize");
    LOGV(lis) LCV(ni+2);
    assert(lis >= ni+2);
    REALLOCATE_ST(is,k);
  }
  is[ni++] = lcx;
  if (nc + 1 >= lcs) {
    unsigned k = lcs + 2 + (lcs >> 1);
    if (k > MAX_BYTES) {
      k = (unsigned) MAX_BYTES;
    }
    lcs = k - 1;
    LOGSECTION("scs::resize");
    LOGV(lcs) LCV(nc+1);
    assert(lcs >= nc+1);
    cs = reallocate(cs,k,char);
  }
  lcx = nc;
  string_base = &cs[lcx];
  cs[nc++] = (char) c;
  is[ni++] = 1;
  cs[nc] = 0;
}

#if 0 /* NOTUSED */
void ist(void) {                                /* init string table */
  check_stack;
  if (ni + 4 >= lis) {
    unsigned k = lis + 5 + (lis >> 1);
    if (k > MAX_INTS) {
      k = (unsigned) MAX_INTS;
    }
    lis = k - 1;
    assert(lis >= ni+4);
    REALLOCATE_ST(is,k);
  }
  is[ni++] = lwx;
  is[ni++] = lcx;
  lwx = nw;
  list_base = &ws[lwx];
  is[ni++] = nc;
  lcx = nc;
  string_base = &cs[lcx];
  is[ni++] = 0;
  ws[nw++] = 0;
}
#endif /* 0 - NOTUSED */

void iws(void) {                                /* init word stack */
#ifdef VACLGUI
  AgLock lock(charStackResource);
#endif
  //check_stack;
  if (ni + 2 >= lis) {
    unsigned k = lis + 3 + (lis >> 1);
    if (k > MAX_INTS) {
      k = (unsigned) MAX_INTS;
    }
    lis = k - 1;
    LOGSECTION("iws::resize");
    LOGV(lis) LCV(ni+2);
    assert(lis >= ni+2);
    REALLOCATE_ST(is,k);
  }
  is[ni++] = lwx;
  lwx = nw;
  list_base = &ws[lwx];
  is[ni++] = 0;
}

void sws(int c) {                           /* store word on stack */
#ifdef VACLGUI
  AgLock lock(charStackResource);
#endif
  //check_stack;
  if (ni + 1 >= lis) {
    unsigned k = lis + 3 + (lis >> 1);
    if (k > MAX_INTS) {
      k = (unsigned) MAX_INTS;
    }
    lis = k - 1;
    LOGSECTION("sws::resize");
    LOGV(lis) LCV(ni+2);
    assert(lis >= ni+2);
    REALLOCATE_ST(is,k);
  }
  is[ni++] = lwx;
  if (nw >= lws) {
    unsigned k = lws + 2 + (lws >> 1);
    if (k > MAX_INTS) {
      k = (unsigned) MAX_INTS;
    }
    lws = k - 1;
    LOGSECTION("sws::resize");
    LOGV(lws) LCV(nw+2);
    assert(lws >= nw+1);
    REALLOCATE_ST(ws,k);
  }
  lwx = nw;
  list_base = &ws[lwx];
  ws[nw++] = c;
  is[ni++] = 1;
}

int rcs(void) {
#ifdef VACLGUI
  AgLock lock(charStackResource);
#endif
  //LOGSECTION("rcs");
  int n;

  assert(ni >= 2);
  n = is[--ni];
  LOGV(nc) LCV(lcx) LCV(n);
  assert(nc == lcx + n);
  cs[nc] = 0;
  nc = lcx;
  lcx = is[--ni];
  string_base = &cs[lcx];
  return n;
}

int fps(FILE *f) {                         /* put string to file */
  int n;

  char *sb;
  sb = string_base;
  n = rcs();
  fputs(sb,f);
  return n;
}

int rps(void) {
#ifdef VACLGUI
  AgLock lock(charStackResource);
#endif
  int n;

  assert(ni >= 2);
  n = 2*is[--ni];
  assert(nw == lwx + n);
  nw = lwx;
  lwx = is[--ni];
  list_base = &ws[lwx];
  return n;
}

int rws(void) {
#ifdef VACLGUI
  AgLock lock(charStackResource);
#endif
  int n;

  assert(ni >= 2);
  n = is[--ni];
  assert(nw == lwx + n);
  nw = lwx;
  lwx = is[--ni];
  list_base = &ws[lwx];
  return n;
}


void sis(int i) {
#ifdef VACLGUI
  AgLock lock(charStackResource);
#endif
  //check_stack;
  if (ni >= lis) {
    unsigned k = lis + 2 + (lis >> 1);
    if (k > MAX_INTS) {
      k = (unsigned) MAX_INTS;
    }
    lis = k - 1;
    LOGSECTION("sis::resize");
    LOGV(lis) LCV(ni+2);
    assert (lis >= ni+1);
    REALLOCATE_ST(is,k);
  }
  is[ni++] = i;
}


int tis(void) {
  assert(ni >= 1);
  return is[ni-1];
}

int fis(void) {
#ifdef VACLGUI
  AgLock lock(charStackResource);
#endif
  assert(ni >= 1);
  return is[--ni];
}

void concat_string(void) {
#ifdef VACLGUI
  AgLock lock(charStackResource);
#endif
//  check_stack;
  assert(ni >= 4);
  ni -= 2;
  lcx = is[ni];
  string_base = &cs[lcx];
  is[ni-1] += is[ni+1];
}

void concat_list(void) {
#ifdef VACLGUI
  AgLock lock(charStackResource);
#endif
  //check_stack;
  assert(ni >= 2);
  ni -= 2;
  lwx = is[ni];
  list_base = &ws[lwx];
  is[ni-1] += is[ni+1];
}

/*
void its(char c,int n) {
  assert(ni>=2);
  while (n > is[ni-1]) acs(' ');
  if (n == is[ni-1]) {acs(c); return;}
  if (nc + 1 >= lcs) {
    unsigned k = lcs + 1 + (lcs >> 1);
    if (k > MAX_BYTES) {
      k = (unsigned) MAX_BYTES;
    }
    lcs = k - 1;
    assert(lcs > nc);
    cs = reallocate(cs,k,char);
    string_base = &cs[lcx];
  }
  memmove(&cs[lcx+n+1],&cs[lcx+n],sizeof(*cs)*(is[ni-1]-n));
  cs[lcx+n] = c;
  (is[ni-1])++;
  cs[++nc] = 0;
}
*/

void acs(int c) {
#ifdef VACLGUI
  AgLock lock(charStackResource);
#endif
  assert(ni>=2);
  if (nc + 1 >= lcs) {
    unsigned k = lcs + 2 + (lcs >> 1);
    if (k > MAX_BYTES) {
      k = (unsigned) MAX_BYTES;
    }
    lcs = k - 1;
    LOGSECTION("acs::resize");
    LOGV(lcs) LCV(nc);
    assert(lcs > nc);
    cs = reallocate(cs,k,char);
    string_base = &cs[lcx];
  }
  cs[nc++] = (char) c;
  cs[nc] = 0;
  (is[ni-1])++;
}

int isws(int c) {
#ifdef VACLGUI
  AgLock lock(charStackResource);
#endif
  int bx, tx;
  unsigned nx;
  check_stack;
  assert(ni>=2);
  if (nw >= lws) {
    unsigned k = lws + 2 + (lws >> 1);
    if (k > MAX_INTS) {
      k = (unsigned) MAX_INTS;
    }
    lws = k-1;
    LOGSECTION("isws::resize");
    LOGV(lws) LCV(nw);
    assert(lws > nw);
    REALLOCATE_ST(ws,k);
    list_base = &ws[lwx];
  }
  if (nw == lwx) {
    ws[nw++] = c;
    is[ni-1]++;
    return 0;
  }
  bx = lwx;
  tx = nw-1;
  while (bx <= tx) {
    nx = (bx+tx)/2;
    if (ws[nx] > c) {
      tx = nx-1;
    }
    else if (ws[nx] < c) {
      bx = nx + 1;
    }
    else {
      return 1;
    }
  }
  if (nw > (unsigned) bx) {
    memmove(ws+bx+1,ws+bx, (nw-bx)*sizeof(*ws));
  }
  ws[bx] = c;
  nw++;
  (is[ni-1])++;
  return 0;
}

int xws(int c) {
#ifdef VACLGUI
  AgLock lock(charStackResource);
#endif
  int k;
  int *p;

  assert(ni>=2);
  if (nw >= lws) {
    unsigned k = lws + 2 + (lws >> 1);
    if (k > MAX_INTS) {
      k = (unsigned) MAX_INTS;
    }
    lws = k - 1;
    LOGSECTION("xws::resize");
    LOGV(lws) LCV(nw);
    assert(lws > nw);
    REALLOCATE_ST(ws,k);
    list_base = &ws[lwx];
  }
  k = nw - lwx;
  p = list_base;
  while (k--) {
    if (c == *p++) {
      return 1;
    }
  }
  ws[nw++] = c;
  (is[ni-1])++;
  return 0;
}

int xps(int c1,int c2) {
#ifdef VACLGUI
  AgLock lock(charStackResource);
#endif
  unsigned i;
  int *p;
  int flag;

  // some compilers fail to be able to unravel the loop below to show
  // that this isn't necessary
  flag = -1;

  assert(ni>=2);
  if (nw + 2 >= lws) {
    unsigned k = lws + 3 + (lws >> 1);
    if (k > MAX_INTS) {
      k = (unsigned) MAX_INTS;
    }
    lws = k - 1;
    LOGSECTION("xps::resize");
    LOGV(lws) LCV(nw + 2);
    assert(lws >= nw + 2);
    REALLOCATE_ST(ws,k);
    list_base = &ws[lwx];
  }
  for (p = list_base, i = lwx;
       i < nw && ((flag = p[0] - c1) < 0 ||
		  (flag == 0 && (flag = p[1] - c2) < 0));
       p += 2, i += 2);
  if (i < nw && flag == 0) {
    return 1;
  }
  memmove(p+2, p, (nw - i)* sizeof(*p));
  *p++ = c1; *p = c2;
  nw += 2;
  (is[ni-1])++;
  return 0;
}

void aws(int c) {
#ifdef VACLGUI
  AgLock lock(charStackResource);
#endif
  assert(ni>=2);
  if (nw >= lws) {
    unsigned k = lws + 2 + (lws >> 1);
    if (k > MAX_INTS) {
      k = (unsigned) MAX_INTS;
    }
    lws = k - 1;
    LOGSECTION("aws::resize");
    LOGV(lws) LCV(nw);
    assert(lws > nw);
    REALLOCATE_ST(ws,k);
    list_base = &ws[lwx];
  }
  ws[nw++] = c;
  (is[ni-1])++;
}

char *build_string(void) {
#ifdef VACLGUI
  AgLock lock(charStackResource);
#endif
  char *h;
  unsigned n;

  check_stack;
  assert(ni >= 2);
  n = is[--ni];
  lcx = is[--ni];
  string_base = &cs[lcx];
  assert(nc >= n);
  nc -= n;
  h = ALLOCATE(n+1, char);
  memmove(h, cs + nc, n*sizeof(*h));
  h[n] = 0;
  return h;
}

AgString buildAgString(void) {
  char *sb;
  sb = string_base;
  return AgString(sb,rcs());
}

AgArray<int> buildStaticList(void) {
#ifdef VACLGUI
  AgLock lock(charStackResource);
#endif
  unsigned n;

  //check_stack;
  assert(ni >= 1);
  n = is[--ni];
  lwx = is[--ni];
  list_base = &ws[lwx];
  assert(nw >= n);
  nw -= n;
  return AgArray<int>(ws+nw, n);
}

int *build_list(void) {
#ifdef VACLGUI
  AgLock lock(charStackResource);
#endif
  int *h;
  unsigned n;

  //check_stack;
  assert(ni >= 1);
  n = is[--ni];
  lwx = is[ni-1];
  list_base = &ws[lwx];
  assert(nw >= n);
  nw -= n;
  is[ni-1] = n;
  if (n == 0) h = NULL;
  else ALLOCATE_ST(h, n);
  memmove(h,ws + nw, n*sizeof(*ws));
  return h;
}
/*
static void rtbc(void) {
  assert(ni>=2);
  if (cs[nc-1] != ' ') return;
  nc--;
  is[ni-1]--;
  cs[nc] = 0;
}
*/

int idl(list_dict *d) {
#ifdef VACLGUI
  AgLock lock(charStackResource);
#endif
  int k,nsx;
  int *lb;

  check_stack;
  assert(ni>=2);
  nsx = d->nsx;
  lb = list_base;
  k = add_list_dict(lb, rws(), d);
  sis(k);
  return k == nsx;
}

int fws(void) {
#ifdef VACLGUI
  AgLock lock(charStackResource);
#endif
  assert(nw > 0);
  is[ni-1]--;
  return(ws[--nw]);
}

void fdl(list_dict *d,unsigned k) {
#ifdef VACLGUI
  AgLock lock(charStackResource);
#endif
  int n, *l;

  assert(k < d->nsx);
  iws();
  l = d->text + d->ndx[k];
  n = *l++ - 1;
  if (nw + n >= lws) {
    unsigned k = lws + n + 1 + (lws >> 1);
    if (k > MAX_INTS) {
      k = (unsigned) MAX_INTS;
    }
    lws = k - 1;
    LOGSECTION("fdl::resize");
    LOGV(lws) LCV(nw + n);
    assert(lws >= nw+n);
    REALLOCATE_ST(ws,k);
    list_base = &ws[lwx];
  }
  memmove(list_base, l, n*sizeof(*list_base));
  nw += n;
  is[ni-1] = n;
}

//int idsx(string_dict *);
/*
int ids(string_dict *d) {
  rtbc();
  return idsx(d);
}

static int idsx(string_dict *d) {
  int k,nsx;
  char *sb;

  check_stack;
  assert(ni>=2);
  cs[nc] = 0;
  sb = string_base;
  rcs();
  nsx = d->nsx;
  k = add_string_dict(sb, d);
  is[ni++] = k;
  cs[nc] = 0;
  return k == nsx;
}
*/