|
|
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 b
Length: 7229 (0x1c3d)
Types: TextFile
Names: »bas9.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki
└─⟦this⟧ »EUUGD11/euug-87hel/sec1/basic/bas9.c«
/*
* BASIC by Phil Cockcroft
*/
#include "bas.h"
/*
* This file contains subroutines used by many commands
*/
/* stringcompare will compare two strings and return a valid
* logical value
*/
stringcompare()
{
char chblock[256];
register int i;
register char *p,*q;
int cursiz;
int reslt=0;
int c;
checksp();
stringeval(chblock);
cursiz=gcursiz;
if(! (c=getch()) )
error(SYNTAX);
stringeval(gblock);
if(i = ((cursiz > gcursiz) ? gcursiz : cursiz) ){
/*
* make i the minimum of gcursiz and cursiz
*/
gcursiz -= i; cursiz -= i;
p=chblock; q=gblock; /* set pointers */
do{
if(*p++ != *q++){ /* do the compare */
if( (*(p-1) & 0377) > (*(q-1) & 0377) )
reslt++;
else
reslt--;
compare(c,reslt);
return;
}
}while(--i);
}
if(cursiz)
reslt++;
else if(gcursiz)
reslt--;
compare(c,reslt);
}
/* given the comparison operator 'c' then returns a value
* given that 'reslt' has a value of:-
* 0: equal
* 1: greater than
* -1: less than
*/
compare(c,reslt)
register int c;
register int reslt;
{
vartype=01;
if(c==EQL){
if(!reslt)
goto true;
}
else if(c==LTEQ){
if( reslt<=0)
goto true;
}
else if(c==NEQE){
if( reslt)
goto true;
}
else if(c==LTTH){
if( reslt<0)
goto true;
}
else if(c==GTEQ){
if( reslt>=0)
goto true;
}
else if(c==GRTH){
if( reslt>0)
goto true;
}
else
error(SYNTAX);
res.i=0; /* false */
return;
true:
res.i = -1;
}
/* converts a number in 'res' to a string in gblock
* the string will have a space at the start if it is positive
*/
gcvt()
{
int sign, decpt;
int ndigit=9;
register char *p1, *p2;
register int i;
#ifndef SOFTFP
char *ecvt();
#else
char *necvt();
#endif
#ifdef PORTABLE
if(vartype==01 || !res.f){
#else
if(vartype==01 || !res.i){ /* integer deal with them separately */
#endif
lgcvt();
return;
}
#ifndef SOFTFP
p1 = ecvt(res.f, ndigit+2, &decpt, &sign);
#else
p1 = necvt(&res, ndigit+2, &decpt, &sign);
#endif
if (sign)
*gblock = '-';
else
*gblock = ' ';
if(ndigit > 1){
p2 = p1 + ndigit-1;
do {
if(*p2 != '0')
break;
ndigit--;
}while(--p2 > p1);
}
p2 = &gblock[1];
/*
for (i=ndigit-1; i>0 && *(p1+i) =='0'; i--)
ndigit--;
*/
if (decpt < 0 || decpt > 9){
decpt--;
*p2++ = *p1++;
if(ndigit != 1){
*p2++ = '.';
for (i=1; i<ndigit; i++)
*p2++ = *p1++;
}
*p2++ = 'e';
if (decpt<0) {
decpt = -decpt;
*p2++ = '-';
}
if(decpt >= 10){
*p2++ = decpt/10 + '0';
decpt %= 10;
}
*p2++ = decpt + '0';
}
else {
if (!decpt) {
*p2++ = '0';
*p2++ = '.';
}
for (i=1; i<=ndigit; i++) {
*p2++ = *p1++;
if (i==decpt && i != ndigit)
*p2++ = '.';
}
while (ndigit++<decpt)
*p2++ = '0';
}
*p2 =0;
gcursiz= p2 -gblock;
}
/* integer version of above - a very simple algorithm */
lgcvt()
{
static char s[7];
register char *p,*q;
int fl=0;
register unsigned l;
l= res.i;
p= &s[6];
if((int)l <0){
fl++;
l= -l;
}
do{
*p-- = l%10 +'0';
}while(l/=10 );
if(fl)
*p ='-';
else
*p =' ';
q=gblock;
while(*q++ = *p++);
gcursiz= --q - gblock;
}
/* get a linenumber or if no linenumber return a -1
* used by all routines with optional linenumbers
*/
getlin()
{
register unsigned l=0;
register int c;
c=getch();
if(!isnumber(c)){
point--;
return(-1);
}
do{
if(l>=6553 )
error(7);
l= l*10 + (c-'0');
c= *point++;
}while(isnumber(c));
point--;
return(l);
}
/* getline() gets a line number and returns a valid pointer
* to it, if there is no linenumber or the line is not there
* then there is an error. Used by 'goto' etc.
*/
lpoint
getline()
{
register unsigned l=0;
register lpoint p;
register int c;
c=getch();
if(!isnumber(c))
error(5);
do{
if(l>=6553)
error(7);
l= l*10+(c-'0');
c= *point++;
}while(isnumber(c));
point--;
if(runmode && l >= curline) /* speed it up a bit */
p = stocurlin; /* no need to search the whole lot */
else
p = (lpoint)fendcore;
for(; p->linnumb ;p = (lpoint)((memp)p + lenv(p)))
if(p->linnumb == l)
return(p);
error(6);
}
/* printlin() returns a pointer to a string representing the
* the numeric value of the linenumber. linenumbers are unsigned
* quantities.
*/
char *
printlin(l)
register unsigned l;
{
static char ln[7];
register char *p;
p = &ln[5];
do{
*p-- = l %10 + '0';
}while(l/=10);
p++;
return(p);
}
/* routine used to check the type of expression being evaluated
* used by print and eval.
* A string expression returns a value of '1'
* A numeric expression returns a value of '0'
*/
checktype()
{
register char *tpoint;
register int c;
if( (c= *point) & 0200){
if( (c&0377) >= MINFUNC)
goto data;
else goto string;
}
if(isnumber(c) || c=='.' || c== '-' || c=='(')
goto data;
if(c=='"' || c=='`')
goto string;
if(!isletter(c))
error(SYNTAX);
tpoint= point;
do{
c= *++tpoint;
}while(isletter(c) || isnumber(c));
if(c!='$')
data: return(0);
string: return(1);
}
/* print out a message , used for all types of 'basic' messages
*/
prints(s)
char *s;
{
register char *i;
i=s;
while(*i++);
write(1,s,--i-s);
}
/* copy a string from a to b returning the last address used in b
*/
char *
strcpy(a,b)
register char *a,*b;
{
while(*b++ = *a++);
return(--b);
}
#ifndef SOFTFP
/* convert an ascii string into a number. If it is possibly an integer
* return an integer.
* Otherwise return a double ( in res )
* should never overflow. One day I may fix the non floating point one.
*/
#define BIG 1.701411835e37
getop()
{
register double x = 0;
register int exponent = 0;
register int ndigits = 0;
register int c;
register int exp;
char decp = 0;
char lzeros = 0;
int minus;
short xx;
dot: for(c = *point ; isnumber(c) ; c = *++point){
if(!lzeros){
if(c == '0'){ /* ignore leading zeros */
if(decp)
exponent--;
continue;
}
lzeros++;
}
if(ndigits >= 15){ /* ignore insignificant digits */
if(!decp)
exponent++;
continue;
}
if(decp)
exponent--;
ndigits++;
x = x * 10 + c - '0';
}
if(c == '.'){
point++;
if(decp)
return(0);
decp++;
goto dot;
}
if(c == 'e' || c == 'E'){
minus = 0;
if( (c = *++point) == '+')
point++;
else if(c =='-'){
minus++;
point++;
}
else if(c < '0' || c > '9')
return(0);
for(exp = 0, c = *point; c >= '0' && c <= '9' ; c = *++point){
if(exp < 1000)
exp = exp * 10 + c - '0';
}
if(minus)
exponent -= exp;
else
exponent += exp;
}
while(exponent < 0){
exponent++;
x /= 10;
}
while(exponent > 0){
exponent--;
if(x > BIG)
return(0);
x *= 10;
}
xx = x; /* see if x is == an integer */
/*
* shouldn't need a cast below but there is a bug in the 68000
* compiler which does the comparison wrong without it.
*/
if( (double) xx == x){
vartype= 01;
res.i = xx;
} else {
vartype = 0;
res.f = x;
}
return(1);
}
#endif