Annotation of researchv10no/cmd/basic/bas/fns.c, revision 1.1.1.1

1.1       root        1: #include <stdio.h>
                      2: #include "ctype.h"
                      3: #include "typedef.h"
                      4: #include "basic.h"
                      5: #include "tokens.h"
                      6: 
                      7: #define        MAXRAND         2147483647
                      8: 
                      9: double sqrt(), exp(), log(), atan(), sin(), cos(), fabs();
                     10: double popfloat(), cvtnumber();
                     11: static char str[MAXSTRING];
                     12: Stkptr pop(), pushstring();
                     13: char   *allocstr(), *fprint(), *strpop();
                     14: 
                     15: 
                     16: /*
                     17:  * function --- interpret builtin function calls
                     18:  */
                     19: 
                     20: function()
                     21: {
                     22:        switch (*inptr) {
                     23:        case LEFT:
                     24:                fnarg("si");
                     25:                break;
                     26:        case RIGHT:
                     27:                fnarg("si");
                     28:                break;
                     29:        case MID:
                     30:                fnarg("sii");
                     31:                break;
                     32:        case UPSHIFT:
                     33:        case UNBLANK:
                     34:        case SYSTEM:
                     35:        case LEN:
                     36:        case VAL:
                     37:        case ASCII:
                     38:                fnarg("s");
                     39:                break;
                     40:        case RND:
                     41:        case ARG:
                     42:        case CHR:
                     43:        case RAND:
                     44:                fnarg("i");
                     45:                break;
                     46:        case SIN:
                     47:        case COS:
                     48:        case TAN:
                     49:        case ATN:
                     50:        case SQR:
                     51:        case EXPFN:
                     52:        case LOG:
                     53:        case INTFN:
                     54:        case ABS:
                     55:        case STR:
                     56:        case SGN:
                     57:                fnarg("f");
                     58:                break;
                     59:        default:
                     60:                return(0);
                     61:                }
                     62:        return(1);
                     63: }
                     64: 
                     65: 
                     66: /*
                     67:  * fnarg --- do type checking and evaluation of builtin functions
                     68:  */
                     69: 
                     70: fnarg(args)
                     71: char   *args;
                     72: {
                     73:        register int    op, i;
                     74:        register Stkptr s;
                     75:        register char   *q;
                     76:        char            *p;
                     77:        double          x, t;
                     78:        int             k, nc, n, ch, len;
                     79:        
                     80:        op = *inptr++;
                     81:        for (p = args; *p; ) {
                     82:                expr();
                     83:                switch (*p++) {
                     84: 
                     85:                case 's':
                     86:                        if (((Stkptr)stkptr)->k_type != STRINGEXPR)
                     87:                                err("string argument required");
                     88:                        break;
                     89:                case 'i':
                     90:                case 'f':
                     91:                        if (((Stkptr)stkptr)->k_type != FLOATEXPR)
                     92:                                err("numeric argument required");
                     93:                        break;
                     94:                default:
                     95:                        badtype();
                     96:                        }
                     97:                if (*p)
                     98:                        expectc(COMMA);
                     99:                }
                    100:        expectc(RPAR);
                    101:        switch (op) {
                    102:        case SYSTEM:
                    103:                p = strpop();           /* got a string in UNIX format */
                    104:                i = exec("/bin/sh", "sh", "-c", p, 0);
                    105:                pushint(i);
                    106:                break;
                    107:        case LEFT:
                    108:                if ((i = popint()) < 0)
                    109:                        i = 0;
                    110:                s = (Stkptr)stkptr;
                    111:                if (i > s->k_un.k_str.s_len)
                    112:                        i = s->k_un.k_str.s_len;
                    113:                n = 0;
                    114:                goto common;
                    115:        case RIGHT:
                    116:                if ((i = popint()) < 0)
                    117:                        i = 0;
                    118:                s = (Stkptr)stkptr;
                    119:                if (i > s->k_un.k_str.s_len)
                    120:                        i = s->k_un.k_str.s_len;
                    121:                n = s->k_un.k_str.s_len - i;
                    122:                goto common;
                    123:        case MID:
                    124:                if ((i = popint()) < 0)
                    125:                        i = 0;
                    126:                if ((n = popint() - 1) < 0)
                    127:                        n = 0;
                    128:                s = (Stkptr)stkptr;
                    129:                if (n > s->k_un.k_str.s_len)
                    130:                        n = s->k_un.k_str.s_len;
                    131:                if (i > s->k_un.k_str.s_len - n)
                    132:                        i = s->k_un.k_str.s_len - n;
                    133:        common:
                    134:                if (n > 0 || i < s->k_un.k_str.s_len) {
                    135:                        if (isstring(s->k_un.k_str.s_ptr)) {
                    136:                                p = allocstr(NULL, i, 0);
                    137:                                if (i)
                    138:                                        move(i, s->k_un.k_str.s_ptr+n, p);
                    139:                                s->k_un.k_str.s_ptr = p;
                    140:                                }
                    141:                        else
                    142:                                s->k_un.k_str.s_ptr += n;
                    143:                        s->k_un.k_str.s_len = i;
                    144:                        }
                    145:                break;
                    146:        case UPSHIFT:
                    147:                p = strpop();
                    148:                len = strlen(p);
                    149:                for (k = 0; k <= len; k++)
                    150:                        if (!isalpha(*(p+k)) || isupper(*(p+k)))
                    151:                                str[k] = p[k];
                    152:                        else
                    153:                                str[k] = toupper(p[k]);
                    154:                s = pushstring(str, len);
                    155:                s->k_un.k_str.s_ptr = str;
                    156:                s->k_un.k_str.s_len = len;
                    157:                break;
                    158:        case UNBLANK:
                    159:                p = strpop();
                    160:                len = strlen(p);
                    161:                for (k = nc = 0; k <= len; k++)
                    162:                        if (*(p+k) != ' ')
                    163:                                str[nc++] = p[k];
                    164:                s = pushstring(str, nc - 1);
                    165:                s->k_un.k_str.s_ptr = str;
                    166:                s->k_un.k_str.s_len = nc - 1;
                    167:                break;
                    168:        case LEN:
                    169:                s = pop(ANYTYPE);
                    170:                pushint(s->k_un.k_str.s_len);
                    171:                break;
                    172:        case CHR:
                    173:                ch = popint();
                    174:                s = pushstring(&ch, 1);
                    175:                s->k_un.k_str.s_ptr = allocstr(&ch, 1, 1);
                    176:                break;
                    177:        case STR:
                    178:                p = fprint(popfloat());
                    179:                len = strlen(p);
                    180:                s = pushstring(p, len);
                    181:                s->k_un.k_str.s_ptr = allocstr(p, len, len);
                    182:                break;
                    183:        case ARG:
                    184:                len = popint();
                    185:                p = (len > argcnt)? "" : argvec[len];
                    186:                len = strlen(p);
                    187:                s = pushstring(p, len);
                    188:                s->k_un.k_str.s_ptr = allocstr(p, len, len);
                    189:                break;
                    190:        case ASCII:
                    191:                s = pop(ANYTYPE);
                    192:                pushint(*s->k_un.k_str.s_ptr);
                    193:                break;
                    194:        case VAL:
                    195:                s = pop(ANYTYPE);
                    196:                p = q = s->k_un.k_str.s_ptr;
                    197:                i = s->k_un.k_str.s_len;
                    198:                pushfloat(cvtnumber(&p, i));
                    199:                if (p - q != i)
                    200:                        err("invalid number %.*s", i, q);
                    201:                break;
                    202:        case SIN:
                    203:                pushfloat(sin(popfloat()));
                    204:                break;
                    205:        case COS:
                    206:                pushfloat(cos(popfloat()));
                    207:                break;
                    208:        case TAN:
                    209:                x = popfloat();
                    210:                pushfloat(sin(x)/cos(x));
                    211:                break;
                    212:        case SGN:
                    213:                x = popfloat();
                    214:                if (x > 0)
                    215:                        t = 1;
                    216:                else
                    217:                        if (x < 0)
                    218:                                t = -1;
                    219:                        else
                    220:                                t = 0;
                    221:                pushfloat(t);
                    222:                break;
                    223:        case SQR:
                    224:                if ((x = popfloat()) >= 0)
                    225:                        pushfloat(sqrt(x));
                    226:                else
                    227:                        err("sqr of negatives undefined. check");
                    228:                break;
                    229:        case LOG:
                    230:                if ((x = popfloat()) != 0)
                    231:                        pushfloat(log(fabs(x)));
                    232:                else
                    233:                        err("log of zero is undefined. check");
                    234:                break;
                    235:        case EXPFN:
                    236:                pushfloat(exp(popfloat()));
                    237:                break;
                    238:        case ATN:
                    239:                pushfloat(atan(popfloat()));
                    240:                break;
                    241:        case ABS:
                    242:                pushfloat(fabs(popfloat()));
                    243:                break;
                    244:        case INTFN:
                    245:                pushfloat((double)(int)popfloat());
                    246:                break;
                    247:        case RND:
                    248:                if ((i = popint()) != 0)
                    249:                        srand(i);
                    250:                pushfloat((double)rand() / MAXRAND);
                    251:                break;
                    252:        case RAND:
                    253:                i = popint();
                    254:                srand((int)time(0) + i);
                    255:                pushfloat(x = ((double)rand() / MAXRAND));
                    256:                break;
                    257:        default:
                    258:                err("function not found");
                    259:                }
                    260: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.