|
|
BSD 4.3tahoe
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
/* $Header: /var/lib/cvsd/repos/CSRG/43BSDTahoe/new/B/src/bsmall/B1val.c,v 1.1.1.1 2018/04/24 16:12:58 root Exp $ */
/* General operations for objects */
#include "b.h"
#include "b0con.h"
#include "b1obj.h"
#include "b1mem.h"
#include "b2scr.h" /* TEMPORARY for at_nwl */
#include "b2sem.h" /* TEMPORARY for grab */
#ifndef SMALLNUMBERS
#include "b1num.h" /* for ccopy, rrelease, grab, grab_num, grab_rat, grab_approx */
#else
#include "B1num.h" /* For grab */
#endif
#define LL (len < 200 ? 1 : 8)
#define Len (len == 0 ? 0 : ((len-1)/LL+1)*LL)
#define Adj(s) (unsigned) (sizeof(*Vnil)-sizeof(Vnil->cts)+(s))
#define Grabber() {if(len>Maxintlet)syserr("big grabber");}
#define Regrabber() {if(len>Maxintlet)syserr("big regrabber");}
value etxt, elis, etab, elt;
long gr= 0;
Visible Procedure prgr() {at_nwl=No;printf(" gr:%ld",gr);gr=0;}
Hidden value grab(type, len) literal type; intlet len; {
unsigned syze; value v;
Grabber();
switch (type) {
case Num:
#ifdef SMALLNUMBERS
syze= sizeof(number);
#else
if (len >= 0) syze= Len*sizeof(digit); /* Integral */
else if (len == -1) syze= sizeof(double); /* Approximate */
else syze= 2*sizeof(value); /* Rational */
#endif
break;
case Tex: syze= (len+1)*sizeof(char); break; /* one extra for the '\0' */
case Com: syze= len*sizeof(value); break;
case ELT: syze= (len= 0); break;
case Lis:
case Tab: syze= Len*sizeof(value); break;
case Sim: syze= sizeof(simploc); break;
case Tri: syze= sizeof(trimloc); break;
case Tse: syze= sizeof(tbseloc); break;
case How: syze= sizeof(how); break;
case For: syze= sizeof(formal); break;
case Glo: syze= 0; break;
case Per: syze= sizeof(value); break;
case Fun:
case Prd: syze= sizeof(funprd); break;
case Ref: syze= sizeof(ref); break;
default:
printf("\ngrabtype{%c}\n", type);
syserr("grab called with unknown type");
}
v= (value) getmem(Adj(syze));
v->type= type; v->len= len; v->refcnt= 1;
gr+=1;
return v;
}
#ifdef SMALLNUMBERS
Visible value grab_num(len) intlet len; { return grab(Num, len); }
#else
Visible value grab_num(len) register int len; {
integer v;
register int i;
v = (integer) grab(Num, len);
for (i = Length(v)-1; i >= 0; --i) Digit(v, i) = 0;
return (value) v;
}
Visible value grab_rat() {
return (value) grab(Num, -2);
}
Visible value grab_approx() {
return (value) grab(Num, -1);
}
Visible value regrab_num(v, len) value v; register int len; {
register unsigned syze;
syze = Len * sizeof(digit);
regetmem(&v, Adj(syze));
Length(v) = len;
return v;
}
#endif
Visible value grab_tex(len) intlet len; {
if (len == 0) return copy(etxt);
return grab(Tex, len);
}
Visible value grab_com(len) intlet len; { return grab(Com, len); }
Visible value grab_elt() { return copy(elt); }
Visible value grab_lis(len) intlet len; {
if (len == 0) return copy(elis);
return grab(Lis, len);
}
Visible value grab_tab(len) intlet len; {
if (len == 0) return copy(etab);
return grab(Tab, len);
}
Visible value grab_sim() { return grab(Sim, 0); }
Visible value grab_tri() { return grab(Tri, 0); }
Visible value grab_tse() { return grab(Tse, 0); }
Visible value grab_how() { return grab(How, 0); }
Visible value grab_for() { return grab(For, 0); }
Visible value grab_glo() { return grab(Glo, 0); }
Visible value grab_per() { return grab(Per, 0); }
Visible value grab_fun() { return grab(Fun, 0); }
Visible value grab_prd() { return grab(Prd, 0); }
Visible value grab_ref() { return grab(Ref, 0); }
Visible value copy(v) value v; {
if (v != Vnil && v->refcnt < Maxintlet) (v->refcnt)++;
gr+=1;
return v;
}
Visible Procedure release(v) value v; {
intlet *r= &(v->refcnt);
if (v == Vnil) return;
if (*r == 0) syserr("releasing unreferenced value");
if(bugs){printf("releasing: "); if (Type(v) == Num) bugs= No; wri(v,No,No,No); bugs= Yes; line();}
if (*r < Maxintlet && --(*r) == 0) rrelease(v);
gr-=1;
}
Hidden value ccopy(v) value v; {
literal type= v->type; intlet len= Length(v), k; value w;
w= grab(type, len);
switch (type) {
case Num:
#ifdef SMALLNUMBERS
Numerator(w)= Numerator(v);
Denominator(w)= Denominator(v);
#else
if (Integral(v)) {
register int i;
for (i = len-1; i >= 0; --i)
Digit((integer)w, i) = Digit((integer)v, i);
} else if (Approximate(v))
Realval((real)w) = Realval((real)v);
else if (Rational(v)) {
Numerator((rational)w) =
(integer) copy(Numerator((rational)v));
Denominator((rational)w) =
(integer) copy(Denominator((rational)v));
}
#endif
break;
case Tex:
strcpy(Str(w), Str(v));
break;
case Com:
case Lis:
case Tab:
case ELT:
{value *vp= Ats(v), *wp= Ats(w);
Overall *wp++= copy(*vp++);
} break;
case Sim:
{simploc *vv= (simploc *)Ats(v), *ww= (simploc *)Ats(w);
ww->i= copy(vv->i); ww->e= vv->e; /* No copy */
} break;
case Tri:
{trimloc *vv= (trimloc *)Ats(v), *ww= (trimloc *)Ats(w);
ww->R= copy(vv->R); ww->B= vv->B; ww->C= vv->C;
} break;
case Tse:
{tbseloc *vv= (tbseloc *)Ats(v), *ww= (tbseloc *)Ats(w);
ww->R= copy(vv->R); ww->K= copy(vv->K);
} break;
case How:
*((how *)Ats(w)) = *((how *)Ats(v));
break;
case For:
*((formal *)Ats(w)) = *((formal *)Ats(v));
break;
case Glo:
break;
case Per:
*Ats(w)= copy(*Ats(v));
break;
case Fun:
case Prd:
*((funprd *)Ats(w)) = *((funprd *)Ats(v));
break;
case Ref:
*((ref *)Ats(w)) = *((ref *)Ats(v));
break;
default:
syserr("ccopy called with unknown type");
}
return w;
}
Hidden Procedure rrelease(v) value v; {
literal type= v->type; intlet len= Length(v), k;
switch (type) {
case Num:
#ifndef SMALLNUMBERS
if (Rational(v)) {
release(Numerator((rational)v));
release(Denominator((rational)v));
}
break;
#endif
case Tex:
break;
case Com:
case Lis:
case Tab:
case ELT:
{value *vp= Ats(v);
Overall release(*vp++);
} break;
case Sim:
{simploc *vv= (simploc *)Ats(v);
release(vv->i); /* No release of vv->e */
} break;
case Tri:
{trimloc *vv= (trimloc *)Ats(v);
release(vv->R);
} break;
case Tse:
{tbseloc *vv= (tbseloc *)Ats(v);
release(vv->R); release(vv->K);
} break;
case How:
{how *vv= (how *)Ats(v);
freemem((ptr) vv->fux);
release(vv->reftab);
} break;
case For:
case Glo:
break;
case Per:
release(*Ats(v));
break;
case Fun:
case Prd:
{funprd *vv= (funprd *)Ats(v);
if (vv->def == Use) {
freemem((ptr) vv->fux);
release(vv->reftab);
}
} break;
case Ref:
break;
default:
syserr("release called with unknown type");
}
v->type= '\0'; freemem((ptr) v);
}
Visible Procedure uniql(ll) value *ll; {
if (*ll != Vnil && (*ll)->refcnt > 1) {
value c= ccopy(*ll);
release(*ll);
*ll= c;
}
}
Visible Procedure xtndtex(a, d) value *a; intlet d; {
intlet len= Length(*a)+d;
Regrabber();
regetmem(a, Adj((len+1)*sizeof(char)));
(*a)->len= len;
}
Visible Procedure xtndlt(a, d) value *a; intlet d; {
intlet len= Length(*a); intlet l1= Len, l2;
len+= d; l2= Len;
if (l1 != l2) {
Regrabber();
regetmem(a, Adj(l2*sizeof(value)));
}
(*a)->len= len;
}
Visible Procedure initmem() {
etxt= grab(Tex, 0);
elis= grab(Lis, 0);
etab= grab(Tab, 0);
elt= grab(ELT, 0);
notel= grab_lis(0); noting= No;
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.