/* >REKEN */ #include #include #include #include #include #include #ifdef ARM #define SHL 16 #define ops flgs #else #define SHL 0 #endif #define POSITIEF 1 #define NUL 0 #define NEGATIEF -1 #define MAXLEN 1000 #define TRUE 1 #define FALSE 0 #define KLEINER -1 #define GELIJK 0 #define GROTER 1 #define PUSH 0x00687370 /*'psh'*/ #define POP 0x00706F70 /*'pop'*/ #define MOD 0x00646F6D /*'mod'*/ #define DIV 0x00766964 /*'div'*/ #define LIST 0x0074736C /*'lst'*/ #define LOAD 0x00746567 /*'get'*/ #define TYPE 0x00747570 /*'put'*/ #define TABL 0x006C6274 /*'tbl'*/ #define TSET 0x006C6573 /*'sel'*/ #define FLAG 0x00676C66 /*'flg'*/ #define FAC 0x00636166 /*'fac' in flg$fac */ #define PI 0x00006970 /*'pi' */ #define IM 0x00000069 /*'i' */ #define XX 0x00000065 /*'e' */ #define MINEEN 0x0000312D /*'-1'*/ /* vlaggen in knoop */ #define NOT 1 #define SNIJAF (1<< 1) #define SUCCES (1<< 2) #define KLAAR (1<< 3) #define DUBBEL_GEBRUIKT (1<< 4) #define KLEINER_DAN (1<< 5) #define GROTER_DAN (1<< 6) #define UNIFY (1<< 7) #define INDIRECT (1<< 8) #define NUMBER (1<< 9) #define BREUK (1<<10) #define ATOM (1<<11) #define NONIDENT (1<<12) #define DUBBEL_INDIRECT (1<<13) #define IDENT (1<<14) #define BEZET (1<<15) #define WORDT (1<ops & OPERATOR) #define klopcode(kn) (kop(kn) >> SHL) struct knoop { #ifdef ARM unsigned long flgs; #else unsigned short flgs; unsigned short ops; #endif union { struct { struct knoop *links,*rechts; } p; long lobj; int iobj; char obj; } u; } voorbeeld,*nulknoop,*eenknoop,*nilknoop,*hknoop,*jknoop,*adr[10], knopen[4],*m0=NULL,*m1=NULL,*f0=NULL,*f1=NULL,*f4=NULL,*f5=NULL; typedef struct knoop sk; typedef sk *psk; typedef psk *ppsk; typedef char *qgetal; typedef char *ngetal; typedef char **ppchar; typedef char *pchar; typedef int *pint; struct kknoop { #ifdef ARM unsigned long flgs; #else unsigned short flgs; unsigned short ops; #endif psk links,rechts; }; char *soperator[16]= {"?","=",",","|","&",":",".","+","*","^","L","D","$","?","?","?"}, niks[]="", min[]="-", streep[]="/", maalmineen[]="*-1)", nul[]="0", een[]="1", mineen[]="-1", twee[]="2", mintwee[]="-2", vier[]="4", hekje1[]="\t1", hekje2[]="\t2", hekje3[]="\t3", hekje4[]="\t4", hekje7[]="\t7", plus[]="+", maal[]="*", macht[]="^", haakjeopen[]="(", haakjesluit[]=")", op[2]={0,0}, resteken(pchar,pchar), *koncat(char**), *concat(char *plijst,...), *opb(ppsk pkn,pchar), lijst[MAXLEN+1], redlijst[MAXLEN+1], tx, ty; struct deelres { ngetal quot; ngetal rest; }; qgetal geheeldelen(qgetal,qgetal), modulo(qgetal,qgetal), qdema(ngetal,ngetal,ngetal,ngetal), qmaal(qgetal,qgetal), qndeel(ngetal,ngetal), qplus(qgetal,qgetal), qqdeel(qgetal,qgetal); ngetal cyfer(int n), nmaal(ngetal,ngetal), nplus(ngetal,ngetal), ox, oy, px, py; void *alloc4(void), *alloc8(void), *alloc12(void), *bmalloc(int n), a_bc_to_ab_ac(ppsk pkn,char*), ab_c_to_ac_bc(ppsk pkn,char*,psk lknoop), bezetting(void), bfree(void *p), copyflags(psk bron,ppsk pkn), eindknoop(psk wortel), evalnaam(ppsk pkn), flinkertak(ppsk pkn), hresult(psk), init_ruimte(void), init_variabelen(void), init_opcode(void), linkertak(ppsk pkn), lst(psk kn), nndeel(ngetal,ngetal,struct deelres *), nuldelen(void), numboom(ppsk pkn,psk linksopknoop,pchar conc[]), opaf(char**,char*,char*,char*,char*,int), opmaak(psk ,int,int opc), rechtertak(ppsk pkn), result(psk), splits(qgetal,ngetal *,ngetal *), supernul(ngetal,char), tbw(ppsk ,pchar,pchar), trac(void), vgl(psk kn1,psk kn2), vrijopb(ppsk pkn,char **), vrijtbw(ppsk pkn,pchar conc[]), wis(psk), xyinit(ngetal,ngetal); int assign(ppsk pkn), bereken_verschil(qgetal s,qgetal p), casemacht(ppsk pkn), compare(psk s,psk p), complic_term(ppsk pkn), copy_insert(char *string,psk pknoop), delete(char *string), differentieren(ppsk pkn), eindnum(char*,char**,char**,char*), evalueer(ppsk pkn), find_w(psk naamknoop,ppsk pknoop), functies(ppsk pkn), getalcheck(qgetal s), insert(char *string,psk pknoop), is_afhankelyk_van(psk el,psk lijst), is_constant(psk), is_digit(int kar), kngetalcheck(psk), knis_qgetal(psk),is_qgetal(qgetal s), linksbrengen(ppsk pkn), machtbuitenhaakjes(ppsk pkn), match(psk sub,psk pat), match_verschil(int versch,psk s,psk p), naamwoord_w(psk bron,ppsk pknoop), output(ppsk pkn,void (*hoe)()), psh(char *string,psk pknoop,psk hoe), rechtsbrengen(ppsk pkn), samenvoegen_of_sorteren(ppsk pkn,psk(*sorteerdeel)(),char *hogere_operator), sel(psk naamknoop,psk selector), stapelmacht(ppsk pkn), startboom_w(char *lijst,ppsk pkn), substdiff(ppsk pkn), substlog(ppsk pkn), substmaal(ppsk pkn), substmacht(ppsk pkn), substplus(ppsk pkn), try_le_elq(psk fun,ppsk pkn), tryq(ppsk pkn,psk fun), vergelijk(qgetal,qgetal), zoeknaam(char *string,struct vars **pvoorvar,struct vars **pnavar); psk base(psk pknoop), copievan(psk ,pchar), eerste(psk kn), nonnumfactor(psk pknoop), quotient_w(psk s,psk p), rest(psk kn), subboomcopie(psk), verschil_w(psk s,psk p), zelfde_als_w(psk kn); ppsk linkeroperand(ppsk pkn); struct byte4 { #ifdef ARM unsigned long flgs; #else unsigned short flgs; unsigned short ops; #endif } *p4,*p4start,*p4end; struct byte8 { #ifdef ARM unsigned long flgs; #else unsigned short flgs; unsigned short ops; #endif long rest1; } *p8,*p8start,*p8end; struct byte12 { #ifdef ARM unsigned long flgs; #else unsigned short flgs; unsigned short ops; #endif long rest1; long rest2; } *p12,*p12start,*p12end; unsigned xlengte, ylengte; long globalloc=0, alloc_cnt=0, cnts[256], totcnt=0, al4=PROMILLAGE4*KILOKNOPEN, al8=PROMILLAGE8*KILOKNOPEN, al12=PROMILLAGE12*KILOKNOPEN; int carry, evaldiepte=0, abseen, factorize=FALSE, geheel, optab[256], teken, trace=FALSE, dummy_op=PLUS, ind, is_groter, is_gelyk; struct vars { char *name; struct vars *next; long n; long selector; psk value[1]; /* arraysize wordt door psh veranderd */ } *variabelen[256]; FILE *fpi, *fpo; int main() { #ifdef ARM clock_t time0; #endif #ifdef MAPSTORE extern int _mapstore(void); #endif psk anker; init_variabelen(); init_ruimte(); init_opcode(); anker=NULL; fpi=stdin; fpo=stdout; voorbeeld.flgs = SUCCES | BEZET; voorbeeld.u.obj=0; nulknoop = &knopen[1]; nulknoop->flgs = SUCCES | BEZET | IDENT; nulknoop->u.obj = '0'; *(&(nulknoop->u.obj)+1) = 0; eenknoop = &knopen[2]; eenknoop->flgs = SUCCES | BEZET | IDENT; eenknoop->u.obj = '1'; *(&(eenknoop->u.obj)+1) = 0; nilknoop = &knopen[3]; nilknoop->flgs = SUCCES | BEZET | IDENT; nilknoop->u.obj = 0; lijst[0]=0; opb(&m0,"?*(%+%)^?*?"); opb(&m1,"?*(%+%)*?"); opb(&f0,"pop$(arg,psh$(b,c,d,e,n),\\,!arg:?b*(%?c+%?d)^(?n&!n:>1&!n:~/)*?e&!b*pow$((!c+!d)^!n)*!e)"); opb(&f1,"pop$(arg,psh$(b,c,d,e),\\,!arg:?b*(%?c+%?d)*?e&!b*!c*!e+!b*!d*!e)"); opb(&f4,"pop$(arg,psh$l,\\,!arg:?l^(?+?*!lL?*?+?)&!_03)"); opb(&f5,"pop$(arg,psh$l,\\,!arg:?lL(?*!l^?*?)&!_04)"); startboom_w( "_01=pop$(psh$(l,r),\\,!arg:!x&!v|!arg:?%l.?%r&_01$!l._01$!r|!arg)", &anker); startboom_w("_02=!cnt:!tot&!res|!res+(sbs$(!xD!f:?f,!x,0))*((!fac*(!cnt+1:?cnt)):?fac)^-1*!x^!cnt:?res&!_02",&anker); startboom_w("_03=pop$(psh$(a,b,c,d,e),!arg:?l^(?a+?b*!lL?c*?d+?e)&!l^(!a+!e)*!c^(!b*!d))",&anker); startboom_w("_04=pop$(psh$(a,b,c),!arg:?lL(?a*!l^?b*?c)&!lL(!a*!c)+!b)",&anker); startboom_w( "_05=pop$(psh$(l,r),\\,(!arg:!!x&!!v:%?l.%?r|!arg:%?l.%?r)&_05$!l._05$!r|!arg)", &anker); startboom_w("taylor=pop$(psh$(f,tot,x,fac,cnt,res),\\,!arg:(?%f,?%x,?%tot)&(fac=1)&(cnt=0)&((sbs$(!f,!x,0)):?res)&!_02)",&anker); startboom_w("_sn=e^(!arg*i)*i*-1/2+e^(!arg*i*-1)*i*1/2",&anker); startboom_w("_cs=e^(!arg*i)*1/2+e^(!arg*i*-1)*1/2",&anker); startboom_w("pow=pop$(psh$(a,b,n),\\,!arg:(?%a+?%b)^(?n&!n:>1)&(!n:2&!a^2+!b^2+!a*!b*2|!n:3&!a^3+!b^3+!a^2*!b*3+!a*!b^2*3|mod$(!n,2):0&pow$((!a+!b)^(!n*1/2))^2|pow$((!a+!b)^((!n+-1)*1/2))^2*(!a+!b)))",&anker); startboom_w("sbs=pop$(psh$(e,x,v,l,r),\\,!arg:(?%e,?%x,?%v)&_01$!e)", &anker); /* sbs$(expressie,patroon,substitutie) , substitutie wordt bij aanroep van sbs geevalueerd */ startboom_w("sb2=pop$(psh$(e,x,v,l,r),\\,!arg:(?%x,?%v,?%e)&_05$!e)", &anker); /* sb2$(expressie,patroon,substitutie) , patroon en substitutie worden "laat" geevalueerd */ for(;;) { strcpy(redlijst,lijst); scanf(" %1000s",lijst); switch(lijst[0]) { case '.' : exit(0); case ',' : break; case '\"' : printf(redlijst); break; case '+' : trace=!trace; break; default : #ifdef ARM time0=clock(); #endif if(startboom_w(lijst,&anker)) { result(anker); printf("\nja\n"); } else printf("nee\n"); wis(anker); #ifdef ARM printf("%d centiseconden\n",clock()-time0); #endif anker=NULL; printf("Gealloceerd:%d\n",globalloc); bezetting(); #ifdef MAPSTORE _mapstore(); #endif } } } void trac() { psk anker; char lijst[1000]; trace=FALSE; anker=NULL; do { printf("Voer expressie in:\n"); lijst[0]=0; scanf(" %1000s",lijst); if(lijst[0]!=',') { if(startboom_w(lijst,&anker)) { result(anker); printf("\nja\n"); } else printf("nee\n"); } printf("Gealloceerd:%d\n",globalloc); } while(lijst[0]!=','); trace=TRUE; if(anker) wis(anker); } int startboom_w(lijst,pkn) char *lijst; ppsk pkn; { if(*pkn) wis(*pkn); *pkn=NULL; tbw(pkn,lijst,lijst+strlen(lijst)-1); return evalueer(pkn); } int is_constant(kn) psk kn; { if(kop(kn)) return is_constant(kn->u.p.links) && is_constant(kn->u.p.rechts); else if(knis_qgetal(kn) || kn->u.lobj==IM || kn->u.lobj==PI || kn->u.lobj==XX) return TRUE; else return FALSE; } int knis_qgetal(kn) psk kn; { return !kop(kn) && is_qgetal(&(kn->u.obj)); } int is_qgetal(s) qgetal s; { return isdigit(*s) || *s == '-'; } void init_opcode() { int tel; for(tel=0;tel<256;tel++) { cnts[tel]=0; switch (tel) { case '=' : optab[tel] = WORDT;break; case ',' : optab[tel] = KOMMA;break; case '|' : optab[tel] = OF ;break; case '&' : optab[tel] = EN ;break; case ':' : optab[tel] = MATCH;break; case '.' : optab[tel] = DOT ;break; /* dummy */ case '+' : optab[tel] = PLUS ;break; case '*' : optab[tel] = MAAL ;break; case '^' : optab[tel] = EXP ;break; case 'L' : optab[tel] = LOG ;break; case 'D' : optab[tel] = DIF ;break; case '$' : optab[tel] = FUN ;break; default : optab[tel] = OPERATOR;break; }; } } psk copievan(kn,string) psk kn; pchar string; { psk ret; ret = bmalloc(sizeof(unsigned long)+strlen(string)+1); ret->flgs = kn->flgs; #ifndef ARM ret->ops = kn->ops; #endif ret->u.lobj=0; strcpy(&(ret->u.obj),string); return ret; } void vrijopb(pkn,conc) ppsk pkn; pchar conc[]; { bfree(opb(pkn,koncat(conc))); } void vrijtbw(pkn,conc) ppsk pkn; pchar conc[]; { char *lijst; if(*pkn) wis(*pkn); lijst=koncat(conc); tbw(pkn,lijst,lijst+strlen(lijst)-1); bfree(lijst); } psk zelfde_als_w(kn) psk kn; { if(kn->flgs & DUBBEL_GEBRUIKT) return subboomcopie(kn); else { kn->flgs |= DUBBEL_GEBRUIKT; return kn; } } char *opb(pkn,lijst) ppsk pkn; pchar lijst; { static int adrs[11],ind; char *py; int *padr,succes; if((py=strchr(lijst,'\t')) != NULL) { for(padr=adrs;py;) { py++; ind=*py-'0'; *padr++=ind; if(adr[ind]->flgs & DUBBEL_GEBRUIKT) { printf("adr[%d]->flgs & DUBBEL_GEBRUIKT\n",ind); result(adr[ind]); printf("\nFOUT DUS in %s",lijst); } adr[ind]->flgs |= DUBBEL_GEBRUIKT; py=strchr(py,'\t'); } *padr=0; if(*pkn) { succes=(*pkn)->flgs & SUCCES; wis(*pkn); } else succes=SUCCES; for(padr=adrs;*padr;padr++) adr[*padr]->flgs &=~DUBBEL_GEBRUIKT; } else if(*pkn) { succes=(*pkn)->flgs & SUCCES; wis(*pkn); } else succes=SUCCES; tbw(pkn,lijst,lijst+strlen(lijst)-1); (*pkn)->flgs ^=(succes ^ SUCCES); return lijst; } void wis(top) psk top; { if(!(top->flgs & DUBBEL_GEBRUIKT)) { if(kop(top)) { wis(top->u.p.links); wis(top->u.p.rechts); } bfree(top); } else top->flgs &=~DUBBEL_GEBRUIKT; } void tbw(pkn,start,finish) ppsk pkn; pchar start,finish; { register char *px; char *wortel; int teken; register int aantal_haakjes; int overtollige_haakjes; aantal_haakjes = 0; teken = OPOP; overtollige_haakjes = INT_MAX; for(px=finish;px >= start;px--) { switch(*px) { case ')' : aantal_haakjes++; break; case '(' : aantal_haakjes--; break; default : { if(overtollige_haakjes > aantal_haakjes) { register int hteken; overtollige_haakjes = aantal_haakjes; if((hteken = optab[*px]) < OPERATOR) { teken = hteken; wortel = px; } } else { if(overtollige_haakjes == aantal_haakjes) { register int hteken; if((hteken = optab[*px]) <= teken) { if(teken > hteken) { teken = hteken; wortel = px; } else { if(hteken != PLUS && hteken != MAAL && hteken != MATCH) wortel = px; } } } } } } } if(teken == OPOP) { register char *begin; begin=start+overtollige_haakjes; if(*begin > ('\v'|'\t')) { register int vlag; wortel = finish - overtollige_haakjes + 1; teken = *wortel; *wortel = 0; vlag=SUCCES | BEZET; for(;*begin;begin++) { switch(*begin) { case '~' : vlag ^=NOT; vlag ^=SUCCES; continue; case '!' : if(vlag & INDIRECT) vlag |= DUBBEL_INDIRECT; else vlag |= INDIRECT; continue; case '?' : vlag |= UNIFY; continue; case '<' : vlag |= KLEINER_DAN; continue; case '>' : vlag |= GROTER_DAN; continue; case '#' : vlag |= NUMBER; continue; case '/' : vlag |= BREUK; continue; case '@' : vlag |= ATOM; continue; case '%' : vlag |= NONIDENT; continue; default : *pkn = copievan(&voorbeeld,begin); (*pkn)->flgs=vlag; *wortel = teken; return; } } *pkn = copievan(&voorbeeld,begin); (*pkn)->flgs=vlag; *wortel = teken; } else { if(*begin == '\v') *pkn = subboomcopie(adr[*++begin-'0']); else *pkn = adr[*++begin-'0']; } } else { *pkn = bmalloc(sizeof(struct kknoop)); #ifdef ARM (*pkn)->flgs = teken | (BEZET | SUCCES); #else (*pkn)->flgs = (BEZET | SUCCES); (*pkn)->ops = teken; #endif tbw(&((*pkn)->u.p.links),start+overtollige_haakjes,wortel-1); tbw(&((*pkn)->u.p.rechts),wortel+1,finish-overtollige_haakjes); } } int evalueer(pkn) ppsk pkn; { while(!((*pkn)->flgs & KLAAR)) { if((*pkn)->flgs & DUBBEL_GEBRUIKT) { (*pkn)->flgs &=~DUBBEL_GEBRUIKT; *pkn=subboomcopie(*pkn); } if(trace) { result(*pkn); putc('\n',fpo); } (*pkn)->flgs |=KLAAR; switch(kop(*pkn)) { case WORDT : if(evalueer(&((*pkn)->u.p.links)) && assign(pkn)) linkertak(pkn); else flinkertak(pkn); continue; case KOMMA : /* rechtsbrengen(pkn); KAN HIER NIET*/ evalueer(&((*pkn)->u.p.links)); evalueer(&((*pkn)->u.p.rechts)); rechtsbrengen(pkn); if(!kop((*pkn)->u.p.links) && !((*pkn)->u.p.links->u.obj)) rechtertak(pkn); else if(!kop((*pkn)->u.p.rechts) && !((*pkn)->u.p.rechts->u.obj)) linkertak(pkn); continue; case PLUS : if(evalueer(&((*pkn)->u.p.links)) && evalueer(&((*pkn)->u.p.rechts))) { if(linksbrengen(pkn) || substplus(pkn) || samenvoegen_of_sorteren(pkn,&nonnumfactor,maal) || factorize /* als er gefactorizeerd moet worden, dan complic_term niet uitvoeren */ || complic_term(pkn) ); } else (*pkn)->flgs ^=SUCCES; continue; case MAAL : if(evalueer(&((*pkn)->u.p.links)) && evalueer(&((*pkn)->u.p.rechts))) { if(linksbrengen(pkn) || substmaal(pkn) || samenvoegen_of_sorteren(pkn,&base,macht)); } else (*pkn)->flgs ^=SUCCES; continue; case EXP : if(evalueer(&((*pkn)->u.p.links)) && evalueer(&((*pkn)->u.p.rechts))) { if(stapelmacht(pkn) /* (a^b)^c->a^(b*c) */ || substmacht(pkn) /* 0^a 1^a a^0 a^1 n^-1 i^n */ || machtbuitenhaakjes(pkn) /* (a+b)^(c+n)->(a+b)^c*(a+b)^n */ /* (a*b)^c->a^c*b^c */ || casemacht(pkn) || try_le_elq(f4,pkn)); } else (*pkn)->flgs ^=SUCCES; continue; case LOG : if(evalueer(&((*pkn)->u.p.links)) && evalueer(&((*pkn)->u.p.rechts))) { if(substlog(pkn) || try_le_elq(f5,pkn)); } else (*pkn)->flgs ^=SUCCES; continue; case DIF : if(evalueer(&((*pkn)->u.p.links)) && evalueer(&((*pkn)->u.p.rechts))) { if(!substdiff(pkn)) { if(!differentieren(pkn)) (*pkn)->flgs ^=SUCCES; /*??????*/ } } else (*pkn)->flgs ^=SUCCES; continue; case FUN : if(evalueer(&((*pkn)->u.p.links)) && evalueer(&((*pkn)->u.p.rechts))) { rechtsbrengen(pkn); if(!functies(pkn)) (*pkn)->flgs ^=SUCCES; } else (*pkn)->flgs ^=SUCCES; continue; case MATCH : if(evalueer(&((*pkn)->u.p.links)) && match((*pkn)->u.p.links,(*pkn)->u.p.rechts)) linkertak(pkn); else flinkertak(pkn); continue; case EN : rechtsbrengen(pkn); if(evalueer(&((*pkn)->u.p.links))) rechtertak(pkn); else flinkertak(pkn); continue; case OF : rechtsbrengen(pkn); if(evalueer(&((*pkn)->u.p.links))) linkertak(pkn); else rechtertak(pkn); continue; case DOT : #ifdef ARM (*pkn)->flgs &=(~OPERATOR & ~KLAAR); #else (*pkn)->flgs &=~KLAAR; (*pkn)->ops &=~OPERATOR; #endif (*pkn)->ops |=dummy_op; continue; default : if((*pkn)->flgs & INDIRECT) evalnaam(pkn); } } if(trace) { if((*pkn)->flgs & SUCCES) printf("S:"); else printf("F:"); result(*pkn); putc('\n',fpo); trac(); } return (*pkn)->flgs & SUCCES; } void evalnaam(pkn) ppsk pkn; { psk adr; adr=NULL; if(naamwoord_w(*pkn,&adr)) { if(adr->flgs & DUBBEL_GEBRUIKT) { adr->flgs &=~DUBBEL_GEBRUIKT; adr=subboomcopie(adr); } wis(*pkn); *pkn=adr; } else (*pkn)->flgs ^=SUCCES; } int tryq(pkn,fun) ppsk pkn; psk fun; { psk anker; psh("arg",*pkn,NULL); (*pkn)->flgs |=KLAAR; anker=subboomcopie(fun); if(evalueer(&anker)) { wis(*pkn); *pkn=anker; return TRUE; } else { wis(anker); return FALSE; } } int complic_term(pkn) ppsk pkn; { ppsk hulp; hulp=linkeroperand(pkn); switch(kop(*hulp)) { case MAAL : case EXP : if((match(*hulp,m0) && tryq(hulp,f0)) || (match(*hulp,m1) && tryq(hulp,f1))) { (*pkn)->flgs &=~KLAAR; (*pkn)->u.p.links->flgs &=~KLAAR; return TRUE; } /* "doorvallen" is de bedoeling */ default : { hulp=&((*pkn)->u.p.rechts); switch(kop(*hulp)) { case MAAL : case EXP : if((match(*hulp,m0) && tryq(hulp,f0)) || (match(*hulp,m1) && tryq(hulp,f1))) { (*pkn)->flgs &=~KLAAR; return TRUE; } else return FALSE; } } } return FALSE; } int try_le_elq(fun,pkn) psk fun; ppsk pkn; { if(!kop((*pkn)->u.p.rechts)) return FALSE; else return tryq(pkn,fun); } int assign(pkn) ppsk pkn; { register psk lknoop; return !kop(lknoop=(*pkn)->u.p.links) && insert(&(lknoop->u.obj),(*pkn)->u.p.rechts); } void init_variabelen() { int tel; for(tel=0;tel<256;variabelen[tel++]=NULL); } int psh(string,pknoop,dim) char *string; psk pknoop; psk dim; { struct vars *navar,*voorvar,*nieuwvar; long oldn; if(!*string || *string=='\\' || (dim && !(kngetalcheck(dim) && geheel && teken==POSITIEF))) return FALSE; if(!zoeknaam(string,&voorvar,&navar)) { insert(string,pknoop); if(dim) zoeknaam(string,&voorvar,&navar); else return TRUE; } if(dim) { navar->n=atoi(&dim->u.obj)-1; navar->selector=0; oldn=-1; } else { oldn=navar->n; navar->n++; navar->selector=navar->n; } nieuwvar=bmalloc(sizeof(struct vars) + navar->n*sizeof(psk)); memcpy(nieuwvar, navar, sizeof(struct vars) + navar->n*sizeof(psk)); if(voorvar==NULL) variabelen[*string]=nieuwvar; else voorvar->next=nieuwvar; bfree(navar); for(;++oldn <= nieuwvar->n;) nieuwvar->value[oldn]=zelfde_als_w(pknoop); if(trace) { printf("psh %s=",nieuwvar->name); result(nieuwvar->value[nieuwvar->n]); putc('\n',fpo); } return TRUE; } int copy_insert(string,pknoop) char *string; psk pknoop; { int res; psk kn; kn=subboomcopie(pknoop); res=insert(string,kn); wis(kn); return res; } int insert(string,pknoop) char *string; psk pknoop; { struct vars *navar,*voorvar,*nieuwvar; if(!*string || *string=='\\') return FALSE; if(zoeknaam(string,&voorvar,&navar)) { if(navar->selector <= navar->n) { wis(navar->value[navar->selector]); navar->value[navar->selector]=zelfde_als_w(pknoop); } else return FALSE; if(trace) { printf("wijzig %s=",navar->name); result(navar->value[navar->n]); putc('\n',fpo); } } else { nieuwvar=bmalloc(sizeof(struct vars)); nieuwvar->name=strcpy(bmalloc(strlen(string)+1),string); nieuwvar->next=navar; nieuwvar->n=0; nieuwvar->selector=0; if(voorvar==NULL) variabelen[*string]=nieuwvar; else voorvar->next=nieuwvar; nieuwvar->value[0]=zelfde_als_w(pknoop); if(trace) { printf("nieuw %s=",nieuwvar->name); result(nieuwvar->value[nieuwvar->n]); putc('\n',fpo); } } return TRUE; } int zoeknaam(string,pvoorvar,pnavar) char *string; struct vars **pvoorvar,**pnavar; { struct vars *navar,*voorvar; for(voorvar=NULL,navar=variabelen[*string]; navar && (strcmp(navar->name,string) < 0); voorvar=navar,navar=navar->next); /* voorvar < string <= navar */ *pvoorvar=voorvar; *pnavar=navar; return navar && !strcmp(navar->name,string); } int find_w(naamknoop,pknoop) psk naamknoop; ppsk pknoop; { struct vars *navar; for(navar=variabelen[naamknoop->u.obj]; navar && (strcmp(navar->name,&(naamknoop->u.obj)) < 0); navar=navar->next); if(navar && !strcmp(navar->name,&(naamknoop->u.obj)) && navar->selector <= navar->n && pknoop) { if(*pknoop) wis(*pknoop); *pknoop=zelfde_als_w(navar->value[navar->selector]); return TRUE; } else return FALSE; } int sel(naamknoop,selector) psk naamknoop; psk selector; { struct vars *navar; for(navar=variabelen[naamknoop->u.obj]; navar && (strcmp(navar->name,&(naamknoop->u.obj)) < 0); navar=navar->next); /* eerste naam in een rij gelijke wordt gevonden */ if(navar && !strcmp(navar->name,&(naamknoop->u.obj)) && kngetalcheck(selector) && geheel && teken!=NEGATIEF) { navar->selector=atoi(&selector->u.obj); return TRUE; } else return FALSE; } int delete(string) char *string; { struct vars *navar,*voorvar,*nieuwvar; if(zoeknaam(string,&voorvar,&navar)) { if(trace) { printf("del %s=",navar->name); result(navar->value[navar->n]); putc('\n',fpo); } wis(navar->value[navar->n]); if(navar->n) { nieuwvar=bmalloc(sizeof(struct vars) + --(navar->n)*sizeof(psk)); memcpy(nieuwvar, navar, sizeof(struct vars) + navar->n*sizeof(psk)); if(voorvar) voorvar->next=nieuwvar; else variabelen[*string]=nieuwvar; if(nieuwvar->n < nieuwvar->selector) nieuwvar->selector=nieuwvar->n; } else { if(voorvar) voorvar->next=navar->next; else variabelen[*string]=navar->next; bfree(navar->name); } bfree(navar); return TRUE; } else return FALSE; } int is_afhankelyk_van(el,lijst) psk el,lijst; { psk hlp,hlp2; if(!lijst) return FALSE; vgl(el,(hlp=eerste(lijst))); if(is_gelyk) return TRUE; if(kop(hlp)) { if(is_afhankelyk_van(el,hlp->u.p.links) || is_afhankelyk_van(el,hlp->u.p.rechts)) return TRUE; } else { hlp2=NULL; if(find_w(hlp,&hlp2)) { if(is_afhankelyk_van(el,hlp2)) { wis(hlp2); return TRUE; } else wis(hlp2); } } return is_afhankelyk_van(el,rest(lijst)); } int functies(pkn) ppsk pkn; { char *wijzer; static pchar conc[]={NULL,NULL,NULL,NULL,NULL}; int ikar; register psk lknoop; psk rknoop,rrknoop,rlknoop,rrlknoop; if(kop(lknoop=(*pkn)->u.p.links)) return TRUE; rknoop=(*pkn)->u.p.rechts; if(kop(rknoop)) { rrknoop=rknoop->u.p.rechts; rlknoop=rknoop->u.p.links; } #ifdef ARM switch(lknoop->u.lobj) { case PUSH : #else wijzer=&lknoop->u.obj; if(!strcmp(wijzer,"psh")) #endif { for(rrknoop=rknoop; kop(rrknoop) == KOMMA && !kop(rrlknoop=rrknoop->u.p.links) && psh(&(rrlknoop->u.obj),rrlknoop,NULL); rrknoop=rrknoop->u.p.rechts); if(!kop(rrknoop)) psh(&(rrknoop->u.obj),rrknoop,NULL); rechtertak(pkn); return TRUE; } #ifdef ARM case POP : #else else if(!strcmp(wijzer,"pop")) #endif { while(kop(rknoop) == KOMMA && !kop(rknoop->u.p.links) && delete(&(rknoop->u.p.links->u.obj))) rknoop=rknoop->u.p.rechts; if(kop(rknoop)==KOMMA) { adr[2]=rknoop->u.p.rechts; } else adr[2]=rknoop; opb(pkn,hekje2); return TRUE; } #ifdef ARM case MOD : #else else if(!strcmp(wijzer,"mod")) #endif { if(knis_qgetal(rlknoop) && knis_qgetal(rrknoop)) { conc[0]=modulo(&(rlknoop->u.obj), &(rrknoop->u.obj)); conc[1]=NULL; vrijtbw(pkn,conc); bfree(conc[0]); } return TRUE; } #ifdef ARM case DIV : #else else if(!strcmp(wijzer,"div")) #endif { if(knis_qgetal(rlknoop) && knis_qgetal(rrknoop)) { conc[0]=geheeldelen(&(rlknoop->u.obj), &(rrknoop->u.obj)); conc[1]=NULL; vrijtbw(pkn,conc); bfree(conc[0]); } return TRUE; } #ifdef ARM case LIST : #else else if(!strcmp(wijzer,"lst")) #endif { output(pkn,lst); return TRUE; } #ifdef ARM case LOAD :/* get$file */ #else else if(!strcmp(wijzer,"get")) #endif { if(kop(rknoop)) return FALSE; else { fpi=fopen(&(rknoop->u.obj),"r"); if(fpi==NULL) { printf("openen %s mislukt\n",&(rknoop->u.obj)); return FALSE; } for(wijzer=lijst;(ikar=getc(fpi))!=EOF;) { putchar(ikar); if(ikar==';') { *wijzer=0; if(lijst[0]) { startboom_w(lijst,pkn); } wijzer=lijst; } else if(ikar > ' ') *wijzer++=ikar; } fclose(fpi); } return TRUE; } #ifdef ARM case TYPE : /* put$(file,mode,knoop) of put$knoop */ #else else if(!strcmp(wijzer,"put")) #endif { output(pkn,result); return TRUE; } #ifdef ARM case TABL : /* tbl$(varnaam,lengte) */ #else else if(!strcmp(wijzer,"tbl")) #endif { if(kop(rknoop)) return psh(&(rlknoop->u.obj),nulknoop,rrknoop); else return FALSE; } #ifdef ARM case TSET : /* sel$(varnaam,pos) */ /* tabelelementselectie */ #else else if(!strcmp(wijzer,"sel")) #endif { if(kop(rknoop) && sel(rlknoop,rrknoop)) { adr[2]=rlknoop; opb(pkn,hekje2); return TRUE; } else return FALSE; } #ifdef ARM case FLAG : /* flg$fac */ #else else if(!strcmp(wijzer,"flg")) #endif { if(rknoop->u.lobj==FAC) factorize=TRUE; else factorize=FALSE; return TRUE; } #ifdef ARM default : #else else #endif { adr[1]=NULL; if(find_w((*pkn)->u.p.links,&adr[1])) { if(adr[1]->flgs & DUBBEL_GEBRUIKT) { adr[1]->flgs &=~DUBBEL_GEBRUIKT; adr[1]=subboomcopie(adr[1]); } psh("arg",(*pkn)->u.p.rechts,NULL); opb(pkn,"pop$(arg,\\,\t1)"); return TRUE; } else return TRUE; /*FALSE; ???????? */ } } } int output(pkn,hoe) ppsk pkn; void (*hoe)(); { #define NEW "w" #define APP "a" FILE *redfpo; psk rknoop,rrknoop; char *mode; if(kop(rknoop=(*pkn)->u.p.rechts)==KOMMA && kop(rrknoop=rknoop->u.p.rechts)==KOMMA && !kop(rrknoop->u.p.links) && (mode=&(rrknoop->u.p.rechts->u.obj), !strcmp(mode,"NEW")||!strcmp(mode,"APP"))) { redfpo=fpo; fpo=fopen(&(rrknoop->u.p.links->u.obj),!strcmp(mode,"NEW") ? NEW : APP); if(fpo==NULL) { printf("%s kan niet geopend worden\n",&(rrknoop->u.p.links->u.obj)); return FALSE; } (*hoe)(rknoop->u.p.links,99); putc(';',fpo); putc('\n',fpo); fclose(fpo); fpo=redfpo; adr[2]=rknoop->u.p.links; opb(pkn,hekje2); } else { (*hoe)(rknoop,99); putc('\n',fpo); rechtertak(pkn); } return TRUE; } void lst(kn) psk kn; { struct vars *navar; char *naam; int tel,alfabet,n; if(kop(kn)) return; tel=0; naam=&(kn->u.obj); for(alfabet=0;alfabet<256;alfabet++) for(navar=variabelen[alfabet]; navar; navar=navar->next) { tel++; if((kn->u.obj == '\\') || !strcmp(navar->name,naam)) { for(n=navar->n;n>=0;n--) { printf("%d %d ",n,navar->selector); putc('(',fpo); fprintf(fpo,"%s=",navar->name); result(navar->value[n]); putc(')',fpo); putc(';',fpo); putc('\n',fpo); } } } printf("Totaal %d variabelen",tel); } int bereken_verschil(s,p) qgetal s,p; { qgetal prod,verschil; prod = qmaal(mineen,p); verschil = qplus(s,prod); getalcheck(verschil); bfree(prod); bfree(verschil); return teken; } psk verschil_w(s,p) psk s,p; { psk res; qgetal prod,verschil; prod = qmaal(mineen,&(p->u.obj)); res = copievan(&voorbeeld,(verschil=qplus(&(s->u.obj),prod))); bfree(prod); bfree(verschil); return res; } psk quotient_w(s,p) psk s,p; { psk res; qgetal quotient; res = copievan(&voorbeeld,(quotient=qqdeel(&(s->u.obj),&(p->u.obj)))); bfree(quotient); return res; } int match(sub,pat) psk sub,pat; { /* FAAL = TRUE als NOT-vlag aan staat. Infixoperatoren hebben geen flgs */ #undef FAAL #define FAAL (pat->flgs & NOT) psk loc; if(kop(sub)) { if(sub->u.p.links->flgs & SNIJAF) return match(sub->u.p.rechts,pat); else if(sub->u.p.rechts->flgs & SNIJAF) return match(sub->u.p.links,pat); } switch(kop(pat)) { case 0 : if(pat->flgs & NONIDENT) { if((sub->flgs & IDENT) ^ FAAL) return FALSE; } if(pat->flgs & ATOM) { if(kop(sub) ^ FAAL) return FALSE; } if(pat->flgs & (BREUK | NUMBER)) { if((kop(sub) || !getalcheck(&(sub->u.obj)) || (geheel && pat->flgs & BREUK)) ^ FAAL) return FALSE; } if(pat->flgs & UNIFY) /* ? */ { if(pat->u.obj) { if(pat->flgs & INDIRECT) /* ?! of ?!! */ { loc=NULL; if(naamwoord_w(pat,&loc)) { if(!evalueer(&loc) ^ (kop(loc) || !insert(&(loc->u.obj),sub)) ^ FAAL) { wis(loc); return FALSE; } else { wis(loc); return TRUE; } } else return FAAL; } else { return copy_insert(&(pat->u.obj),sub) ^ FAAL; } } else return !FAAL; } if(pat->flgs & INDIRECT) /* ! of !! */ { loc=NULL; if(naamwoord_w(pat,&loc)) { if( !match(sub,loc) /* ^ (loc->flgs & NOT)*/ ^ FAAL) { wis(loc); return FALSE; } else { wis(loc); return TRUE; } } else return FAAL; } if(pat->u.obj) return compare(sub,pat); else return TRUE; case PLUS : if(match(sub,pat->u.p.links) && match(nulknoop,pat->u.p.rechts)) return TRUE; #if 0 if(knis_qgetal(pat->u.p.links) && knis_qgetal(sub)) { if(match((loc=verschil_w(sub,pat->u.p.links)),pat->u.p.rechts)) { wis(loc); return TRUE; } else { wis(loc); return FALSE; } } #endif if(kop(sub)==PLUS) { for(loc=sub->u.p.links;;loc=loc->u.p.links) { loc->flgs |=SNIJAF; if(match(loc,pat->u.p.links) && match(sub,pat->u.p.rechts)) { loc->flgs &=~SNIJAF; return TRUE; } loc->flgs &=~SNIJAF; if(pat->u.p.rechts->flgs & ATOM) return FALSE; if(kop(loc)!=PLUS) break; } } return match(nulknoop,pat->u.p.links) && match(sub,pat->u.p.rechts); case MAAL : if(match(sub,pat->u.p.links) && match(eenknoop,pat->u.p.rechts)) return TRUE; #if 0 if(knis_qgetal(pat->u.p.links) && knis_qgetal(sub)) { if(match((loc=quotient_w(sub,pat->u.p.links)),pat->u.p.rechts)) { wis(loc); return TRUE; } else { wis(loc); return FALSE; } } #endif if(kop(sub)==MAAL) { for(loc=sub->u.p.links;;loc=loc->u.p.links) { loc->flgs |=SNIJAF; if(match(loc,pat->u.p.links) && match(sub,pat->u.p.rechts)) { loc->flgs &=~SNIJAF; return TRUE; } loc->flgs &=~SNIJAF; if(pat->u.p.rechts->flgs & ATOM) return FALSE; if(kop(loc)!=MAAL) break; } } return match(eenknoop,pat->u.p.links) && match(sub,pat->u.p.rechts); case DOT : if(kop(sub) && match(sub->u.p.links,pat->u.p.links) && match(sub->u.p.rechts,pat->u.p.rechts)) { dummy_op=kop(sub); return TRUE; } else return FALSE; case KOMMA : if(match(nilknoop,pat->u.p.links) && match(sub,pat->u.p.rechts)) return TRUE; if(kop(sub)==KOMMA) { for(loc=sub->u.p.rechts;;loc=loc->u.p.rechts) { loc->flgs |=SNIJAF; if(match(sub,pat->u.p.links) && match(loc,pat->u.p.rechts)) { loc->flgs &=~SNIJAF; return TRUE; } loc->flgs &=~SNIJAF; if(pat->u.p.links->flgs & ATOM) return FALSE; if(kop(loc)!=KOMMA) break; } } return match(sub,pat->u.p.links) && match(nilknoop,pat->u.p.rechts); case EN : if(match(sub,pat->u.p.links)) { loc=subboomcopie(pat->u.p.rechts); if(evalueer(&loc)) { wis(loc); return TRUE; } else wis(loc); } return FALSE; case OF : return match(sub,pat->u.p.links) || match(sub,pat->u.p.rechts); default : return kop(sub)==kop(pat) && match(sub->u.p.links,pat->u.p.links) && match(sub->u.p.rechts,pat->u.p.rechts); } } int compare(s,p) psk s,p; { #undef FAAL #define FAAL (p->flgs & NOT) int teken; if(knis_qgetal(s)) { if(knis_qgetal(p)) return match_verschil(bereken_verschil(&(s->u.obj),&(p->u.obj)),s,p); else return FAAL; } else { if(kop(s)) return FAAL; teken=strcmp(&(s->u.obj),&(p->u.obj)); if(teken>0) teken=POSITIEF; else if(teken<0) teken=NEGATIEF; return match_verschil(teken,s,p); } } int match_verschil(versch,s,p) int versch; psk s,p; { #undef FAAL #define FAAL (p->flgs & NOT) #define PGRT (p->flgs & GROTER_DAN) #define PKLN (p->flgs & KLEINER_DAN) #define PONG (PGRT && PKLN) #define EPGRT (PGRT && !PKLN) #define EPKLN (PKLN && !PGRT) switch(versch) { case POSITIEF : if(s->flgs & KLEINER_DAN) return FALSE; return FAAL ^ (PGRT && 1); /* if(FAAL) return !PGRT; else return EPGRT;*/ case NUL : switch(s->flgs & (GROTER_DAN|KLEINER_DAN)) { case GROTER_DAN|KLEINER_DAN : return FAAL ^ PONG; case GROTER_DAN : return FAAL ^ PONG ^ EPGRT; case KLEINER_DAN : return FAAL ^ PONG ^ EPKLN; default : return !FAAL ^ (PGRT || PKLN); } default : if(s->flgs & GROTER_DAN) return FALSE; return FAAL ^ (PKLN && 1); /* if(FAAL) return !PKLN; else return EPKLN;*/ } } int naamwoord_w(bron,pkn) psk bron; ppsk pkn; { if(find_w(bron,pkn) && (!((*pkn)->flgs & INDIRECT) || naamwoord_w(*pkn,pkn))) { if(!(bron->flgs & DUBBEL_INDIRECT)) { copyflags(bron,pkn); return TRUE; } else { if(!kop(*pkn) || (evalueer(pkn) && !kop(*pkn))) { if(naamwoord_w(*pkn,pkn)) { copyflags(bron,pkn); return TRUE; } else return FALSE; } } } if(*pkn) wis(*pkn); return FALSE; } void copyflags(bron,pkn) psk bron; ppsk pkn; { if((bron->flgs & (KLEINER_DAN | GROTER_DAN)) || !(bron->flgs & SUCCES)) { if((*pkn)->flgs & DUBBEL_GEBRUIKT) { (*pkn)->flgs &=~DUBBEL_GEBRUIKT; *pkn=subboomcopie(*pkn); } (*pkn)->flgs|=bron->flgs & (KLEINER_DAN | GROTER_DAN); (*pkn)->flgs^=(bron->flgs & SUCCES) ^ SUCCES; } } psk eerste(kn) psk kn; { if(kop(kn)==KOMMA) return kn->u.p.links; else return kn; } psk rest(kn) psk kn; { if(kop(kn)==KOMMA) return kn->u.p.rechts; else return NULL; } int samenvoegen_of_sorteren(pkn,sorteerdeel,hogere_operator) ppsk pkn; psk(*sorteerdeel)(); char *hogere_operator; { static char *conc[]={NULL,NULL,NULL,NULL}, hekjetweepluseen[]="(\t2+1)", hekjetweezes[]="(\t2+\t6)"; psk iknoop,lknoop,rknoop,temp; iknoop=*pkn; lknoop=*linkeroperand(pkn); rknoop=iknoop->u.p.rechts; hknoop=(*sorteerdeel)(lknoop); jknoop=(*sorteerdeel)(rknoop); vgl(hknoop,jknoop); if(is_gelyk) { /* a*n+a*m */ /* a^n*a^m */ if(hknoop != lknoop) { adr[1]=hknoop; adr[2]=lknoop->u.p.rechts; conc[0]=hekje1; conc[1]=soperator[klopcode(lknoop)]; if(jknoop==rknoop) { /* a*n+a */ /* a^n*a */ conc[2]=hekjetweepluseen; /* a*(n+1) */ /* a^(n+1) */ } else { /* a*n+a*m */ /* a^n*a^m */ adr[6]=rknoop->u.p.rechts; conc[2]=hekjetweezes; /* a*(n+m) */ /* a^(n+m) */ } } else { if(jknoop != rknoop) { /* a+a*m */ /* a*a^m */ adr[1]=jknoop; adr[2]=rknoop->u.p.rechts; conc[0]=hekje1; conc[1]=soperator[klopcode(rknoop)]; conc[2]=hekjetweepluseen; /* a*(m+1) */ /* a^(m+1) */ } else { /* a+a */ /* a*a */ adr[7]=jknoop; conc[0]=hekje7; conc[1]=hogere_operator; conc[2]=twee; /* a*2 */ /* a^2 */ } } conc[3]=NULL; if(lknoop != (temp=iknoop->u.p.links)) { conc[2]=koncat(conc); adr[4] = temp->u.p.links; conc[0]=hekje4; conc[1]=soperator[klopcode(iknoop)]; vrijopb(pkn,conc); bfree(conc[2]); } else vrijopb(pkn,conc); return TRUE; } else { if((is_groter || knis_qgetal(hknoop)) && !knis_qgetal(jknoop)) { /* b*n+a*m */ /* b^n*a^m */ /* l*n+a*m */ /* l^n*a^m */ adr[1]=rknoop; conc[0]=hekje1; conc[1]=soperator[klopcode(iknoop)]; conc[2]=hekje2; if(iknoop->u.p.links==lknoop) { adr[2]=lknoop; vrijopb(pkn,conc); } else { conc[2]=koncat(conc); adr[2]=lknoop; adr[3]=iknoop->u.p.links->u.p.links; conc[0]=hekje3; conc[1]=soperator[klopcode(iknoop)]; vrijopb(pkn,conc); bfree(conc[2]); } return TRUE; /* a*m+b*n */ /* a^m*b^n */ /* a*m+l*n */ /* a^m*l^n */ } } return FALSE; } psk nonnumfactor(pknoop) psk pknoop; { if(kop(pknoop)==MAAL && knis_qgetal(pknoop->u.p.rechts)) return pknoop->u.p.links; else return pknoop; } psk base(pknoop) psk pknoop; { if(kop(pknoop)==EXP) return pknoop->u.p.links; else return pknoop; } int casemacht(pkn) ppsk pkn; { static char *conc[]={NULL,NULL,NULL,NULL,NULL}, haakmineen[]=")^-1", haakhekje1macht[]="(\t1^", macht2maaleenmacht[]=")^2*\v1^"; psk iknoop,lknoop,rknoop; if(!kngetalcheck((*pkn)->u.p.links)) return FALSE; iknoop=*pkn; lknoop=iknoop->u.p.links; if(kngetalcheck(rknoop=iknoop->u.p.rechts) && teken != NUL && !abseen && geheel) { adr[1]=lknoop; if(teken==NEGATIEF) { /* (a+b)^-n = ((a+b)^n)^-1 */ conc[0]=haakhekje1macht; conc[1]=qmaal(mineen,&(rknoop->u.obj)); conc[2]=haakmineen; vrijopb(pkn,conc); bfree(conc[1]); } else { if(vergelijk(twee,&(rknoop->u.obj))==KLEINER) { /* (a+b)^n = (a+b)^(n\2)*(a+b)^(n mod 2) */ conc[0]=haakhekje1macht; conc[1]=geheeldelen(&(rknoop->u.obj),twee); conc[2]=macht2maaleenmacht; conc[3]=modulo(&(rknoop->u.obj),twee); vrijopb(pkn,conc); bfree(conc[1]); bfree(conc[3]); } else { /* (a+b)^2 = (a+b)*(a+b) */ conc[0]="(\t1*\v1)"; conc[1]=NULL; vrijopb(pkn,conc); } } return TRUE; } return FALSE; } int differentieren(pkn) ppsk pkn; { psk lknoop,rknoop; rknoop=(*pkn)->u.p.rechts; if(knis_qgetal(lknoop=(*pkn)->u.p.links) || kop(lknoop)) return FALSE; if(knis_qgetal(rknoop)) opb(pkn,nul); else if(kop(rknoop) == PLUS) a_bc_to_ab_ac(pkn,plus); else { if(kop(rknoop)) { adr[2]=rknoop->u.p.links; adr[1]=lknoop; adr[3]=rknoop->u.p.rechts; switch(kop(rknoop)) { case MAAL : opb(pkn,"(\v1D\v2*\v3+\t2*\t1D\t3)"); break; case EXP: opb(pkn, "(\t2^(\t3+-1)*\v3*\t1D\v2+\v2^\v3*eL\v2*\v1D\v3)"); break; case LOG : opb(pkn, "(\t2^-1*eL\v2^-2*eL\t3*\t1D\v2+\v3^-1*eL\v2^-1*\v1D\v3)"); break; } } else return FALSE; } return TRUE; } int machtbuitenhaakjes(pkn) ppsk pkn; { psk iknoop,lknoop,rknoop; iknoop=*pkn; rknoop=iknoop->u.p.rechts; lknoop=iknoop->u.p.links; if(kop(rknoop)==PLUS && kop(lknoop)==PLUS && kngetalcheck(rknoop->u.p.rechts) && geheel && teken==POSITIEF) { a_bc_to_ab_ac(pkn,maal); return TRUE; } else if(kop(lknoop)==MAAL) { ab_c_to_ac_bc(pkn,maal,lknoop); return TRUE; } return FALSE; } void a_bc_to_ab_ac(pkn,pkar) ppsk pkn; char *pkar; { static pchar conc[]={"((\t1",NULL,"\t2)",NULL,"(\v1",NULL,"\t3))",NULL}; psk iknoop,rknoop; iknoop=*pkn; rknoop=iknoop->u.p.rechts; adr[1]=iknoop->u.p.links; adr[2]=rknoop->u.p.links; adr[3]=rknoop->u.p.rechts; conc[1]=soperator[klopcode(iknoop)]; conc[3]=pkar; conc[5]=soperator[klopcode(iknoop)]; vrijopb(pkn,conc); } void ab_c_to_ac_bc(pkn,pkar,lknoop) ppsk pkn; char *pkar; psk lknoop; { static pchar conc[]={hekje1,NULL,hekje3,NULL,hekje2,NULL,"\v3",NULL}; adr[1]=lknoop->u.p.links; adr[2]=lknoop->u.p.rechts; adr[3]=(*pkn)->u.p.rechts; conc[1]=soperator[klopcode(*pkn)]; conc[3]=pkar; conc[5]=soperator[klopcode(*pkn)]; vrijopb(pkn,conc); } int linksbrengen(pkn) ppsk pkn; { register psk rknoop; register int gedaan; gedaan = FALSE; for(;kop(rknoop=(*pkn)->u.p.rechts)==kop(*pkn);) { gedaan=TRUE; rknoop->flgs &=~KLAAR; (*pkn)->u.p.rechts=rknoop->u.p.rechts; rknoop->u.p.rechts=rknoop->u.p.links; rknoop->u.p.links=(*pkn)->u.p.links; (*pkn)->u.p.links=rknoop; } if(gedaan) (*pkn)->flgs &=~KLAAR; return gedaan; } int rechtsbrengen(pkn) ppsk pkn; { register psk lknoop; register int gedaan; gedaan = FALSE; for(;kop(lknoop=(*pkn)->u.p.links)==kop(*pkn);) { gedaan=TRUE; lknoop->flgs &=~KLAAR; (*pkn)->u.p.links=lknoop->u.p.links; lknoop->u.p.links=lknoop->u.p.rechts; lknoop->u.p.rechts=(*pkn)->u.p.rechts; (*pkn)->u.p.rechts=lknoop; } if(gedaan) (*pkn)->flgs &=~KLAAR; return gedaan; } int stapelmacht(pkn) ppsk pkn; { psk lknoop; int gedaan; gedaan = FALSE; for(; ( (lknoop=(*pkn)->u.p.links)->flgs & KLAAR ) && kop(lknoop)== EXP && ( ( kop((*pkn)->u.p.rechts) || (*pkn)->u.p.rechts->u.lobj!=MINEEN || ( !kop(lknoop->u.p.rechts) && lknoop->u.p.rechts->u.obj == '-' ) ) || kop(lknoop->u.p.links) != PLUS );) { gedaan=TRUE; #ifdef ARM lknoop->flgs &=~KLAAR & ~OPERATOR; /* KLAAR vlag uitzetten */ #else lknoop->flgs &=~KLAAR; /* KLAAR vlag uitzetten */ lknoop->ops &=~OPERATOR; #endif lknoop->ops |=MAAL; adr[1]=lknoop->u.p.links; adr[2]=lknoop->u.p.rechts; adr[3]=(*pkn)->u.p.rechts; opb(pkn,"(\t1^(\t2*\t3))"); } return gedaan; } int substplus(pkn) ppsk pkn; { static pchar conc[]={NULL,NULL,NULL,NULL}; psk lknoop,rknoop; if(!kop(rknoop=(*pkn)->u.p.rechts) && rknoop->u.obj=='0') { linkertak(pkn); return TRUE; } else { lknoop=*linkeroperand(pkn); if(knis_qgetal(lknoop) && knis_qgetal(rknoop)) { conc[1]=plus; conc[2]=qplus(&(lknoop->u.obj),&(rknoop->u.obj)); numboom(pkn,lknoop,conc); return TRUE; } else return FALSE; } } int substmaal(pkn) ppsk pkn; { static pchar conc[]={NULL,NULL,NULL,NULL}; psk lknoop,rknoop; qgetal linkervar,rechtervar; if(kop(lknoop=*linkeroperand(pkn))) linkervar=NULL; else { linkervar=&(lknoop->u.obj); if(*linkervar=='0') { opb(pkn,nul); return TRUE; } } if(kop(rknoop=(*pkn)->u.p.rechts)) return FALSE; else { rechtervar=&(rknoop->u.obj); if(*rechtervar=='0') { opb(pkn,nul); return TRUE; } } if(rknoop->u.lobj=='1') linkertak(pkn); else if(linkervar && is_qgetal(linkervar) && is_qgetal(rechtervar)) { conc[1]=maal; conc[2]=qmaal(linkervar,rechtervar); numboom(pkn,lknoop,conc); } else return FALSE; return TRUE; } int substmacht(pkn) ppsk pkn; { static char *conc[]={NULL,NULL,NULL,NULL}, haakjei[]="(i^"; qgetal iexponent,rechtervar,hiexponent; psk lknoop,rknoop; if(!kop(rknoop=(*pkn)->u.p.rechts)) { switch(rknoop->u.iobj) { case '0' : opb(pkn,een); return TRUE; case '1' : linkertak(pkn); return TRUE; } } if(kop(lknoop=(*pkn)->u.p.links)) return FALSE; switch(lknoop->u.iobj) { case '0' : case '1' : linkertak(pkn); return TRUE; } if(kop(rknoop) || !kngetalcheck(rknoop)) return FALSE; if(knis_qgetal(lknoop)) { if(teken==NEGATIEF && abseen) { conc[2]=qqdeel(een,&(lknoop->u.obj)); numboom(pkn,lknoop,conc); return TRUE; } else return FALSE; } if(lknoop->u.lobj==IM && (vergelijk((rechtervar=&(rknoop->u.obj)),nul)==KLEINER || vergelijk(twee,rechtervar)<=GELIJK)) { iexponent=modulo(rechtervar,vier); if(*iexponent=='0') opb(pkn,een); else if(!strcmp(iexponent,twee)) opb(pkn,mineen); else { conc[0]=haakjei; if(vergelijk(iexponent,twee)==GROTER) { hiexponent=iexponent; iexponent=qplus(hiexponent,mintwee); bfree(hiexponent); conc[2]=maalmineen; } else conc[2]=haakjesluit; conc[1]=iexponent; vrijtbw(pkn,conc); } bfree(iexponent); return TRUE; } return FALSE; } int kngetalcheck(pknoop) psk pknoop; { if(!kop(pknoop) && getalcheck(&(pknoop->u.obj))) { pknoop->flgs |= NUMBER; if(geheel) pknoop->flgs &=~BREUK; else pknoop->flgs |= BREUK; return TRUE; } else { pknoop->flgs &=~NUMBER; pknoop->flgs &=~BREUK; return FALSE; } } int getalcheck(s) qgetal s; { char *wyzer; if(!is_qgetal(s)) return FALSE; wyzer=s; geheel=TRUE; abseen=FALSE; switch(*wyzer) { case '-' : wyzer++; teken=NEGATIEF; break; case '0' : teken=NUL; return TRUE; default : teken=POSITIEF; } if(*wyzer == '1') if(*++wyzer == 0) { abseen=TRUE; return TRUE; } for(;*wyzer;wyzer++) { if(*wyzer == '/') { geheel=FALSE; return TRUE; } } return TRUE; } int substlog(pkn) ppsk pkn; { static char *conc[]={NULL,NULL,NULL,NULL}, pluseen[]="+1)",hekje1L[]="(\t1L",Lhekje1maalmineen[]="L\t1*-1)"; qgetal linkervar,rechtervar; psk lknoop,rknoop; if(kop(rknoop=(*pkn)->u.p.rechts)) { vgl((*pkn)->u.p.links,rknoop); if(is_gelyk) { opb(pkn,een); return TRUE; } else return FALSE; } if(kop(lknoop=(*pkn)->u.p.links)) return FALSE; if(!strcmp(rechtervar=&(rknoop->u.obj), linkervar=&(lknoop->u.obj))) { opb(pkn,een); return TRUE; } if(rknoop->u.lobj=='1') { opb(pkn,nul); return TRUE; } else { if(knis_qgetal(rknoop) && knis_qgetal(lknoop=(*pkn)->u.p.links)) { linkervar=&(lknoop->u.obj); if(vergelijk(linkervar,een)==KLEINER) { /* (1/n)Lm = nLm*-1 */ adr[1]=rknoop; conc[0]=haakjeopen; conc[1]=qqdeel(een,linkervar); conc[2]=Lhekje1maalmineen; vrijopb(pkn,conc); bfree(conc[1]); return TRUE; } if(vergelijk(linkervar,rechtervar)==KLEINER) { /* nLm = nL(m/n)+1 */ conc[0]=hekje1L; adr[1]=lknoop; conc[1]=qqdeel(rechtervar,linkervar); conc[2]=pluseen; vrijopb(pkn,conc); bfree(conc[1]); return TRUE; } } } return FALSE; } int substdiff(pkn) ppsk pkn; { static pchar conc[]={NULL,NULL,NULL,NULL}; psk lknoop,rknoop; lknoop=(*pkn)->u.p.links; rknoop=(*pkn)->u.p.rechts; if(knis_qgetal(lknoop) && knis_qgetal(rknoop)) { conc[2]=cyfer('0'); numboom(pkn,lknoop,conc); return TRUE; } else { if(is_constant(lknoop) || is_constant(rknoop)) { opb(pkn,nul); return TRUE; } else { vgl(lknoop,rknoop); if(is_gelyk) { opb(pkn,een); return TRUE; } else if((kop(rknoop) == FUN || !kop(rknoop)) && is_afhankelyk_van(lknoop,rknoop)) { return TRUE; } else if(!kop(rknoop)) { opb(pkn,nul); } } } return FALSE; } void numboom(pkn,lknoop,conc) ppsk pkn; psk lknoop; pchar conc[]; { if(lknoop==(*pkn)->u.p.links) { conc[0]=niks; conc[1]=niks; } else { conc[0]=hekje1; adr[1]=(*pkn)->u.p.links->u.p.links; } vrijopb(pkn,conc); bfree(conc[2]); } void linkertak(pkn) ppsk pkn; { psk lknoop; lknoop=(*pkn)->u.p.links; lknoop->flgs ^= ((*pkn)->flgs & SUCCES) ^ SUCCES; wis((*pkn)->u.p.rechts); bfree(*pkn); *pkn=lknoop; } void flinkertak(pkn) ppsk pkn; { psk lknoop; lknoop=(*pkn)->u.p.links; lknoop->flgs &=~SUCCES; lknoop->flgs |=((*pkn)->flgs & SUCCES) ^ SUCCES; wis((*pkn)->u.p.rechts); bfree(*pkn); *pkn=lknoop; } void rechtertak(pkn) ppsk pkn; { psk rknoop; rknoop=(*pkn)->u.p.rechts; rknoop->flgs ^= ((*pkn)->flgs & SUCCES) ^ SUCCES; wis((*pkn)->u.p.links); bfree(*pkn); *pkn=rknoop; } ppsk linkeroperand(pkn) ppsk pkn; { ppsk temp; int teken; temp=&((*pkn)->u.p.links); return((teken=kop(*pkn))==kop(*temp) && (teken==PLUS || teken==MAAL) ? &(*temp)->u.p.rechts : temp); } void result(wortel) psk wortel; { static int ouder,kind; if(kop(wortel)) { ouder=kop(wortel); kind=kop(wortel->u.p.links); if(ouder > kind || (ouder==kind && ouder > MAAL)) hresult(wortel->u.p.links); else result(wortel->u.p.links); putc(*soperator[klopcode(wortel)],fpo); ouder=kop(wortel); kind=kop(wortel->u.p.rechts); if(ouder > kind || (ouder==kind && ouder > MAAL)) hresult(wortel->u.p.rechts); else result(wortel->u.p.rechts); } else eindknoop(wortel); } void hresult(wortel) psk wortel; { static int ouder,kind; if(kop(wortel)) { putc('(',fpo); ouder=kop(wortel); kind=kop(wortel->u.p.links); if(ouder > kind || (ouder==kind && ouder > MAAL)) hresult(wortel->u.p.links); else result(wortel->u.p.links); putc(*soperator[klopcode(wortel)],fpo); ouder=kop(wortel); kind=kop(wortel->u.p.rechts); if(ouder > kind || (ouder==kind && ouder > MAAL)) hresult(wortel->u.p.rechts); else result(wortel->u.p.rechts); putc(')',fpo); } else eindknoop(wortel); } void eindknoop(wortel) psk wortel; { if(wortel->flgs & NOT) putc('~',fpo); if(wortel->flgs & KLEINER_DAN) putc('<',fpo); if(wortel->flgs & GROTER_DAN) putc('>',fpo); if(wortel->flgs & BREUK) putc('/',fpo); else if(wortel->flgs & NUMBER) putc('#',fpo); if(wortel->flgs & ATOM) putc('@',fpo); if(wortel->flgs & NONIDENT) putc('%',fpo); if(wortel->flgs & UNIFY) putc('?',fpo); if(wortel->flgs & INDIRECT) putc('!',fpo); if(wortel->flgs & DUBBEL_INDIRECT) putc('!',fpo); fprintf(fpo,&(wortel->u.obj)); } char *koncat(pplijst) char **pplijst; { char *toe,*point,**argp,*ret; int totlengte; totlengte=0; for(argp=pplijst;*argp;totlengte += strlen(*argp++)); ret=point=bmalloc(totlengte+1); for(;*pplijst;pplijst++) { for(toe=*pplijst;*toe;) *point++ = *toe++; *point=0; } return ret; } char *concat(plijst #ifdef ARM ,... #endif ) char *plijst; { char *toe,*point,**argp,*ret; int totlengte; totlengte=0; for(argp=&plijst;*argp;totlengte += strlen(*argp++)); ret=point=bmalloc(totlengte+1); for(argp=&plijst;*argp;argp++) { for(toe=*argp;*toe;) *point++ = *toe++; *point=0; } return ret; } psk subboomcopie(src) psk src; { psk goal; if(kop(src)) { if(src->u.p.links->flgs & SNIJAF) return subboomcopie(src->u.p.rechts); else if(src->u.p.rechts->flgs & SNIJAF) return subboomcopie(src->u.p.links); else { goal = bmalloc(sizeof(struct kknoop)); goal->flgs = src->flgs; #ifndef ARM goal->ops = src->ops; #endif goal->u.p.links = subboomcopie(src->u.p.links); goal->u.p.rechts = subboomcopie(src->u.p.rechts); } } else goal = copievan(src,&(src->u.obj)); goal->flgs &=~(SNIJAF | DUBBEL_GEBRUIKT); return goal; } qgetal qplus(qx,qy) qgetal qx,qy; { ngetal xt,xn,yt,yn,pa,pb,som; qgetal res; splits(qx,&xt,&xn); splits(qy,&yt,&yn); pa=nmaal(xt,yn); bfree(xt); pb=nmaal(yt,xn); bfree(yt); som=nplus(pa,pb); bfree(pa); bfree(pb); pa=nmaal(xn,yn); bfree(xn); bfree(yn); res=qndeel(som,pa); bfree(som); bfree(pa); return res; } qgetal qmaal(qx,qy) qgetal qx,qy; { ngetal xt,xn,yt,yn; splits(qx,&xt,&xn); splits(qy,&yt,&yn); return qdema(xt,xn,yt,yn); } qgetal qqdeel(qx,qy) qgetal qx,qy; { ngetal xt,xn,yt,yn; splits(qx,&xt,&xn); splits(qy,&yt,&yn); return qdema(xt,xn,yn,yt); } void splits(qget,ptel,pnoem) qgetal qget; ngetal *ptel,*pnoem; { ngetal on,pn; for(on=qget;*on && *on != '/';on++); if(*on) { *on='\0'; *ptel=strcpy(bmalloc(on-qget+1),qget); *on++='/'; for(pn=on;*pn;pn++); *pnoem=strcpy(bmalloc(pn-on+1),on); } else { *ptel=strcpy(bmalloc(on-qget+1),qget); *pnoem=cyfer('1'); } } qgetal qdema(x1,x2,y1,y2) ngetal x1,x2,y1,y2; { ngetal pa,pb; qgetal res; pa=nmaal(x1,y1); bfree(x1); bfree(y1); pb=nmaal(x2,y2); bfree(x2); bfree(y2); res=qndeel(pa,pb); bfree(pa); bfree(pb); return(res); } qgetal qndeel(x,y) ngetal x,y; { char *res,teken; struct deelres resx,resy; ngetal ggd,hrest; if(*x=='0') return cyfer('0'); else if(*y=='0') { nuldelen(); return cyfer('0'); } ggd=x; hrest=y; do { nndeel(ggd,hrest,&resx); if(ggd != x && ggd != y) bfree(ggd); ggd=hrest; hrest=resx.rest; bfree(resx.quot); } while(*hrest != '0'); if(hrest!=y) bfree(hrest); nndeel(x,ggd,&resx); bfree(resx.rest); nndeel(y,ggd,&resy); bfree(resy.rest); if(ggd!=y) bfree(ggd); teken=resteken(resx.quot,resy.quot); res=concat((teken=='+'?niks:min), (resx.quot+1), ((*(resy.quot+1)=='1' && !*(resy.quot+2)) ? NULL : streep), (resy.quot+1), NULL); bfree(resx.quot); bfree(resy.quot); return res; } void nndeel(x,y,pres) ngetal x,y; struct deelres *pres; { ngetal i1,i2,i3; char *wyzer; ngetal hquot,hrest; xyinit(x,y); if(*oy=='0') nuldelen(); hrest=bmalloc(2+xlengte); *hrest='0'; i1=ox; for(wyzer=hrest+1;wyzer<=hrest+xlengte;*wyzer++=*i1++); *wyzer=0; if(xlengte>=ylengte) hquot=bmalloc(3+xlengte-ylengte); else hquot=bmalloc(2); *hquot='0'; i3=hquot; for(i1=hrest+ylengte;i1<=hrest+xlengte;i1++) { *++i3='0'-1; do { i2=i1; opaf(&i2,hrest+1,i1,oy,py,-1); (*i3)++; } while(!carry); i2=i1; opaf(&i2,hrest+1,i1,oy,py,1); } *++i3=0; supernul(hrest,tx); supernul(hquot,resteken(x,y)); pres->rest=hrest; pres->quot=hquot; } void nuldelen() { printf("\ndelen door nul!\n"); } ngetal cyfer(n) int n; { ngetal res; res=bmalloc(4); *(int*)res=n; return res; } ngetal nmaal(x,y) ngetal x,y; { ngetal res,i1,i2; int lengte; char *wyzer,*tussen; xyinit(x,y); res=bmalloc((lengte=1+xlengte+ylengte)+1); for(wyzer=res;wyzer=ox;i1--) { tussen=--wyzer; for(i2=py;i2>=oy;i2--) { register int prod,karry; register char *tussen2; prod=(*i1-'0')*(*i2-'0'); *tussen += prod%10; karry=prod/10; tussen2=tussen--; do { if(*tussen2 > '9') { karry++; *tussen2 -=10; } *--tussen2+=karry; karry=0; } while(*tussen2 > '9'); } } supernul(res,resteken(x,y)); return res; } char resteken(k1,k2) char *k1,*k2; { return *k1=='-' ^ *k2=='-' ? '-' : '+'; } ngetal nplus(x,y) ngetal x,y; { ngetal hp,res,hres; char ht; int maxlen,xgrotery; xyinit(x,y); res=bmalloc(1+(maxlen=2+(xlengte>ylengte ? xlengte : ylengte))); *res=*(res+1)='0'; hres=res+maxlen; *hres-- =0; if(xlengte==ylengte) xgrotery=strncmp(ox,oy,maxlen); else if(xlengte>ylengte) xgrotery=1; else xgrotery=-1; if(xgrotery<0) { ht=ty; ty=tx; tx=ht; hp=py; py=px; px=hp; hp=oy; oy=ox; ox=hp; } if(tx==ty) { opaf(&hres,ox,px,oy,py,1); if(carry) *--hres='1'; } else opaf(&hres,ox,px,oy,py,-1); supernul(res,tx); return res; } void opaf(pres,bx,ex,by,ey,act) char **pres,*bx,*ex,*by,*ey; int act; { register char *i1,*i2,*wyzer; register int lcarry; lcarry=0; i1=*pres; i2=ex; wyzer=ey; do { *i1 = *i2 + lcarry + act * (*wyzer-'0'); if(*i1 > '9') { lcarry = 1; *i1 -=10; } else if(*i1 < '0') { lcarry = -1; *i1 +=10; } else lcarry = 0; i1--; i2--; wyzer--; } while(wyzer>=by); for(;i2>=bx;) { *i1 = *i2 + lcarry; if(*i1 > '9') { lcarry = 1; *i1 -=10; } else if(*i1 < '0') { lcarry = -1; *i1 +=10; } else lcarry = 0; i1--; i2--; } *pres=i1+1; carry=lcarry; } void xyinit(x,y) ngetal x,y; { xlengte=eindnum(&tx,&ox,&px,x); ylengte=eindnum(&ty,&oy,&py,y); } int eindnum(pteken,ppkarb,ppkare,pkar) char *pteken,**ppkarb,**ppkare,*pkar; { register char *pb,*pe; pe=*ppkare; pb=*ppkarb= is_digit(*pkar) ? pkar : pkar+1; *pteken= pb==pkar ? '+' : *pkar; for(pe = pb;is_digit(*++pe);); *ppkare=pe-1; return pe - pb; } int is_digit(k) int k; { return k >= '0' && k <= '9'; } void supernul(nget,teken) ngetal nget; char teken; { ngetal pnget,pnget1; for(pnget=nget;*pnget=='0';pnget++); if(*pnget) { pnget1=nget; *pnget1++ = teken; for(;*pnget;*pnget1++ = *pnget++); *pnget1=0; } else { *nget='0'; *(nget+1)=0; } } void vgl(kn1,kn2) psk kn1,kn2; { static int hulp; if(kop(kn1)) { if(kop(kn2)) { if((hulp=kop(kn1) - kop(kn2))!=0) { is_gelyk=FALSE; is_groter=(hulp>0); return; } else { vgl(kn1->u.p.links,kn2->u.p.links); if(is_gelyk) vgl(kn1->u.p.rechts,kn2->u.p.rechts); } } else { is_gelyk=FALSE; is_groter=TRUE; return; } } else { if(kop(kn2)) { is_gelyk=FALSE; is_groter=FALSE; return; } else { if((hulp=strcmp(&(kn1->u.obj),&(kn2->u.obj)))!=0) { is_gelyk=FALSE; is_groter=(hulp>0); return; } else { is_groter=FALSE; is_gelyk =TRUE; } } } } int vergelijk(qx,qy) qgetal qx,qy; { qgetal minqy,som; int res; minqy=qmaal(mineen,qy); som=qplus(qx,minqy); bfree(minqy); switch(*som) { case '0' : res=GELIJK; break; case '-' : res=KLEINER; break; default : res=GROTER; } bfree(som); return res; } #if FALSE qgetal absoluut(qx) qgetal qx; { switch(*qx) { case '-' : return qmaal(mineen,qx); default : return qmaal(een,qx); } } #endif qgetal modulo(qx,qy) qgetal qx; qgetal qy; { struct deelres deling; qgetal res,hres,p1,p2; qgetal xt,xn,yt,yn; splits(qx,&xt,&xn); splits(qy,&yt,&yn); nndeel((p1=nmaal(xt,yn)),(p2=nmaal(xn,yt)),&deling); bfree(xt); bfree(yt); bfree(p1); bfree(p2); bfree(deling.quot); res=qqdeel((p1=qqdeel(deling.rest,xn)),yn); bfree(xn); bfree(yn); bfree(p1); bfree(deling.rest); if((*res=='-' && *qy!='-') || (*res!='-' && *qy=='-')) { hres=res; res=qplus(hres,qy); bfree(hres); } return res; } qgetal geheeldelen(qx,qy) qgetal qx,qy; { struct deelres deling; qgetal xt,xn,yt,yn,res,p1,p2; splits(qx,&xt,&xn); splits(qy,&yt,&yn); nndeel((p1=nmaal(xt,yn)),(p2=nmaal(xn,yt)),&deling); bfree(xt); bfree(yt); bfree(xn); bfree(yn); bfree(p1); bfree(p2); bfree(deling.rest); res=qplus(nul,deling.quot); bfree(deling.quot); return res; } void init_ruimte() { long *i; p4start=malloc(PROMILLAGE4*sizeof(struct byte4)*KILOKNOPEN); p4end=p4start+PROMILLAGE4*KILOKNOPEN; p4=p4start; for(i=(long*)p4start; i<(long*)p4end; i+=sizeof(struct byte4)/sizeof(long)) *i=0; p8start=malloc(PROMILLAGE8*sizeof(struct byte8)*KILOKNOPEN); p8end=p8start+PROMILLAGE8*KILOKNOPEN; p8=p8start; for(i=(long*)p8start; i<(long*)p8end; i+=sizeof(struct byte8)/sizeof(long)) *i=0; p12start=malloc(PROMILLAGE12*sizeof(struct byte12)*KILOKNOPEN); p12end=p12start+PROMILLAGE12*KILOKNOPEN; p12=p12start; for(i=(long*)p12start; i<(long*)p12end; i+=sizeof(struct byte12)/sizeof(long)) *i=0; printf("p4 %p - %p p8 %p - %p p12 %p - %p\n", p4start,p4end, p8start,p8end, p12start,p12end); } void bfree(p) void *p; { globalloc--; if(p >= (void*)p4start && p < (void*)p4end) { *(long*)p=0; if(!al4++) p4=p; } else if(p >= (void*)p8start && p < (void*)p8end) { *(long*)p=0; if(!al8++) p8=p; } else if(p >= (void*)p12start && p < (void*)p12end) { *(long*)p=0; if(!al12++) p12=p; } else free(p); } void *bmalloc(n) int n; { int tel,tel1; void *res; globalloc++; alloc_cnt++; if(n<256) cnts[n]++; totcnt+=n; switch((n+3)/4) { case 1 : if(al4 && (res=alloc4())!= NULL) return res; case 2 : if(al8 && (res=alloc8())!= NULL) return res; case 3 : if(al12 && (res=alloc12())!= NULL) return res; } res=malloc(n); if(res) return res; printf("GEHEUGEN VOL NA %d ALLOCATIES MET GEMIDDELDE LENGTE %d\n", globalloc,totcnt/alloc_cnt); for(tel=0;tel<16;tel++) { for(tel1=0;tel1<256;tel1+=16) printf("%d ",(cnts[tel+tel1]*1000+500)/alloc_cnt); putchar('\n'); } bezetting(); exit(0); return NULL; } void *alloc4() { register struct byte4 *start,*rp4,*rp4end; rp4=start=p4; rp4end=p4end; while(rp4->flgs) { if(++rp4 >= rp4end) rp4=p4start; if(rp4==start) return NULL; } al4--; /* if(!al4) bezetting(); */ rp4->flgs=BEZET; return p4=rp4; } void *alloc8() { register struct byte8 *start,*rp8,*rp8end; rp8=start=p8; rp8end=p8end; while(rp8->flgs) { if(++rp8 >= rp8end) rp8=p8start; if(rp8==start) return NULL; } al8--; /* if(!al8) bezetting(); */ rp8->flgs=BEZET; return p8=rp8; } void *alloc12() { register struct byte12 *start,*rp12,*rp12end; rp12=start=p12; rp12end=p12end; while(rp12->flgs) { if(++rp12 >= rp12end) rp12=p12start; if(rp12==start) return NULL; } al12--; /* if(!al12) bezetting(); */ rp12->flgs=BEZET; return p12=rp12; } void bezetting() { printf("bezet (promilles) 1 woord : %d, 2 woorden : %d, 3 woorden : %d\n", 1000-(al4 *1000)/(PROMILLAGE4 *KILOKNOPEN), 1000-(al8 *1000)/(PROMILLAGE8 *KILOKNOPEN), 1000-(al12*1000)/(PROMILLAGE12*KILOKNOPEN)); printf("meer dan 3 woorden (absoluut): %d\n", globalloc+al4+al8+al12-1000*KILOKNOPEN); }