|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T a
Length: 5172 (0x1434) Types: TextFile Names: »assist.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki └─⟦this⟧ »EUUGD11/euug-87hel/sec1/basic/assist.c«
/* * BASIC by Phil Cockcroft */ #include "bas.h" /* this file contains all the routines that were originally done in assembler * these routines only require a floating point emulator to work. * To speed things up some routines could be put into assembler and some * could be made into macros. the relevent routines are labeled as such */ #ifndef VAX_ASSEM /* if done in assembler don't bring it in */ /* AS */ /* get a single character from the line pointed to by getch() */ getch() { register char *p; p = point; while(*p++ == ' '); point = p; return(*--p & 0377); } /* AS #define ELSE 0351 */ check() /* check to see no garbage at end of command */ { register char *p; register char c; p = point; while(*p++ == ' '); if(! (c = *--p) || c == ':' || (c == (char)ELSE && elsecount)){ point = p; return; } error(SYNTAX); /* not a terminator - error */ } #endif #ifndef SOFTFP fpcrash() { error(34); /* arithmetic overflow */ } #endif int (*fpfunc)(); startfp() { #ifndef SOFTFP fpfunc = fpcrash; /* will call error(34) on overflow */ #else fpfunc = 0; #endif } /* AS */ /* compare two values. return 0 if equal -1 if first less than second * or 1 for vice versa. */ cmp(p,q) register value *p,*q; { if(vartype){ if(p->i == q->i) return(0); else if(p->i < q->i) return(-1); return(1); } if(p->f == q->f) return(0); else if(p->f< q->f ) return(-1); return(1); } /* the arithmetic operation jump table */ /* all the routines below should be put into AS */ int fandor(), andor(), comop(), fads(), ads(), fmdm(), mdm(), fexp(), ex(); int (*mbin[])() = { 0,0, fandor, andor, comop, comop, fads, ads, fmdm, mdm, fexp, ex, }; typedef value *valp; ex(p,q,c) /* integer exponentiation */ valp p,q; { cvt(p); cvt(q); vartype = 0; fexp(p,q,c); } fmdm(p,q,c) /* floating * / mod */ valp p,q; { double floor(),x; if(c == '*'){ fmul(p,q); return; } if(q->f == 0) error(25); if(c=='/') fdiv(p,q); else { /* floating mod - yeuch */ if( (x = p->f/q->f) < 0) q->f = p->f + floor(-x) * q->f; else q->f = p->f - floor(x) * q->f; } } mdm(p,q,c) /* integer * / mod */ valp p,q; { register long l; register short ll; l = p->i; if(c=='*'){ l *= q->i; #ifdef VAX_ASSEM ll = l; { asm("bvc mdmov"); } q->f = l; vartype = 0; { asm("ret"); } /* could be 'return' */ { asm("mdmov: "); } q->i = ll; #else if(l > 32767 || l < -32768){ /* overflow */ q->f = l; vartype = 0; } else q->i = l; #endif return; } if(!q->i) /* zero divisor error */ error(25); ll = p->i % q->i; if(c == '/'){ if(ll){ q->f = (double)l / q->i; vartype = 0; } else q->i = p->i / q->i; } else q->i = ll; } fads(p,q,c) /* floating + - */ valp p,q; { if(c=='+') fadd(p,q); else fsub(p,q); } ads(p,q,c) /* integer + - */ valp p,q; { register long l; #ifdef VAX_ASSEM register short ll; #endif l = p->i; if(c == '+') l += q->i; else l -= q->i; #ifdef VAX_ASSEM ll = l; { asm("bvc adsov"); } q->f = l; vartype = 0; { asm("ret"); } /* could be 'return' */ { asm("adsov: "); } q->i = ll; #else if(l > 32767 || l < -32768){ /* overflow */ q->f = l; vartype = 0; } else q->i = l; #endif } comop(p,q,c) /* comparison operations */ valp p,q; { compare(c,cmp(p,q)); } fandor(p,q,c) /* floating logical AND/OR/XOR */ register valp p,q; { vartype = 01; #ifdef PORTABLE p->i = ((p->f != 0.0) ? -1 : 0); q->i = ((q->f != 0.0) ? -1 : 0); #else p->i = (p->i ? -1 : 0); q->i = (q->i ? -1 : 0); #endif andor(p,q,c); } andor(p,q,c) /* integer logical */ valp p,q; { register i,j; i = p->i; j = q->i; if(c == ANDD) /* and */ i &= j; else if(c == ORR) /* or */ i |= j; else i ^= j; /* xor */ q->i = i; } /* down to about here */ /* MACRO */ putin(p,var) /* convert + put the value in res into p */ memp p; char var; { if(vartype != var){ if(var){ if(conv(&res)) error(35); } else cvt(&res); } if(var) ((value *)p)->i = res.i; else ((value *)p)->f = res.f; } /* MACRO */ negate() /* negate the value in res */ { if(vartype){ if(res.i == -32768){ /* special case */ res.f = 32768; vartype = 0; } else res.i = -res.i; } else res.f = -res.f; } /* MACRO */ notit() /* logical negation */ { if(vartype){ res.i = ~res.i; return; } vartype = 01; #ifdef PORTABLE if(res.f) res.i = 0; else res.i = -1; #else if(res.i) res.i = 0; else res.i = -1; #endif } fexp(p,q,c) /* floating exponentiation */ valp p,q; { double x,log(),exp(); if(p->f < 0) error(41); else if(q->f == 0.0) q->f = 1.0; else if(p->f == 0.0) /* could use pow - but not on v6 */ q->f = 0.0; else { if( (x = log(p->f) * q->f) > 88.02969) /* should be bigger */ error(40); q->f = exp(x); } }