home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume27 / calc-2.9.0 / part10 < prev    next >
Text File  |  1993-12-07  |  60KB  |  2,523 lines

  1. Newsgroups: comp.sources.unix
  2. From: dbell@canb.auug.org.au (David I. Bell)
  3. Subject: v27i137: calc-2.9.0 - arbitrary precision C-like programmable calculator, Part10/19
  4. References: <1.755316719.21314@gw.home.vix.com>
  5. Sender: unix-sources-moderator@gw.home.vix.com
  6. Approved: vixie@gw.home.vix.com
  7.  
  8. Submitted-By: dbell@canb.auug.org.au (David I. Bell)
  9. Posting-Number: Volume 27, Issue 137
  10. Archive-Name: calc-2.9.0/part10
  11.  
  12. #!/bin/sh
  13. # this is part 10 of a multipart archive
  14. # do not concatenate these parts, unpack them in order with /bin/sh
  15. # file calc2.9.0/string.c continued
  16. #
  17. CurArch=10
  18. if test ! -r s2_seq_.tmp
  19. then echo "Please unpack part 1 first!"
  20.      exit 1; fi
  21. ( read Scheck
  22.   if test "$Scheck" != $CurArch
  23.   then echo "Please unpack part $Scheck next!"
  24.        exit 1;
  25.   else exit 0; fi
  26. ) < s2_seq_.tmp || exit 1
  27. echo "x - Continuing file calc2.9.0/string.c"
  28. sed 's/^X//' << 'SHAR_EOF' >> calc2.9.0/string.c
  29. X
  30. X    testlen = strlen(test);
  31. X    index = 1;
  32. X    while (*format) {
  33. X        len = strlen(format);
  34. X        if ((len == testlen) && (*format == *test) &&
  35. X            (strcmp(format, test) == 0))
  36. X                return index;
  37. X        format += (len + 1);
  38. X        index++;
  39. X    }
  40. X    return 0;
  41. X}
  42. X
  43. X
  44. X/*
  45. X * Add a possibly new literal string to the literal string pool.
  46. X * Returns the new string address which is guaranteed to be always valid.
  47. X * Duplicate strings will repeatedly return the same address.
  48. X */
  49. Xchar *
  50. Xaddliteral(str)
  51. X    char *str;
  52. X{
  53. X    register char **table;    /* table of strings */
  54. X    char *newstr;        /* newly allocated string */
  55. X    long count;        /* number of strings */
  56. X    long len;        /* length of string to allocate */
  57. X
  58. X    len = strlen(str);
  59. X    if (len <= 1)
  60. X        return charstr(*str);
  61. X    /*
  62. X     * See if the string is already in the table.
  63. X     */
  64. X    table = literals.l_table;
  65. X    count = literals.l_count;
  66. X    while (count-- > 0) {
  67. X        if ((str[0] == table[0][0]) && (str[1] == table[0][1]) &&
  68. X            (strcmp(str, table[0]) == 0))
  69. X                return table[0];
  70. X        table++;
  71. X    }
  72. X    /*
  73. X     * Make the table of string pointers larger if necessary.
  74. X     */
  75. X    if (literals.l_count >= literals.l_maxcount) {
  76. X        count = literals.l_maxcount + STR_TABLECHUNK;
  77. X        if (literals.l_maxcount)
  78. X            table = (char **) realloc(literals.l_table, count * sizeof(char *));
  79. X        else
  80. X            table = (char **) malloc(count * sizeof(char *));
  81. X        if (table == NULL)
  82. X            math_error("Cannot allocate string literal table");
  83. X        literals.l_table = table;
  84. X        literals.l_maxcount = count;
  85. X    }
  86. X    table = literals.l_table;
  87. X    /*
  88. X     * If the new string is very long, allocate it manually.
  89. X     */
  90. X    len = (len + 2) & ~1;    /* add room for null and round up to word */
  91. X    if (len >= STR_UNIQUE) {
  92. X        newstr = (char *)malloc(len);
  93. X        if (newstr == NULL)
  94. X            math_error("Cannot allocate large literal string");
  95. X        strcpy(newstr, str);
  96. X        table[literals.l_count++] = newstr;
  97. X        return newstr;
  98. X    }
  99. X    /*
  100. X     * If the remaining space in the allocate string is too small,
  101. X     * then allocate a new one.
  102. X     */
  103. X    if (literals.l_avail < len) {
  104. X        newstr = (char *)malloc(STR_CHUNK);
  105. X        if (newstr == NULL)
  106. X            math_error("Cannot allocate new literal string");
  107. X        literals.l_alloc = newstr;
  108. X        literals.l_avail = STR_CHUNK;
  109. X    }
  110. X    /*
  111. X     * Allocate the new string from the allocate string.
  112. X     */
  113. X    newstr = literals.l_alloc;
  114. X    literals.l_avail -= len;
  115. X    literals.l_alloc += len;
  116. X    table[literals.l_count++] = newstr;
  117. X    strcpy(newstr, str);
  118. X    return newstr;
  119. X}
  120. X
  121. X
  122. X/*
  123. X * Calculate a trivial hash value for a string.
  124. X */
  125. XHASH
  126. Xhashstr(cp)
  127. X    char *cp;
  128. X{
  129. X    int len;
  130. X    HASH hash;
  131. X
  132. X    len = strlen(cp);
  133. X    hash = len * 300007;
  134. X    while (len-- > 0)
  135. X        hash = hash * 300017 + *cp++ + 300043;
  136. X    return hash;
  137. X}
  138. X
  139. X/* END CODE */
  140. SHAR_EOF
  141. echo "File calc2.9.0/string.c is complete"
  142. chmod 0644 calc2.9.0/string.c || echo "restore of calc2.9.0/string.c fails"
  143. set `wc -c calc2.9.0/string.c`;Sum=$1
  144. if test "$Sum" != "6923"
  145. then echo original size 6923, current size $Sum;fi
  146. echo "x - extracting calc2.9.0/string.h (Text)"
  147. sed 's/^X//' << 'SHAR_EOF' > calc2.9.0/string.h &&
  148. X/*
  149. X * Copyright (c) 1993 David I. Bell
  150. X * Permission is granted to use, distribute, or modify this source,
  151. X * provided that this copyright notice remains intact.
  152. X */
  153. X
  154. X#ifndef    CALCSTRING_H
  155. X#define    CALCSTRING_H
  156. X
  157. X#include "zmath.h"
  158. X
  159. X
  160. Xtypedef struct {
  161. X    char *h_list;    /* list of strings separated by nulls */
  162. X    long h_used;    /* characters used so far */
  163. X    long h_avail;    /* characters available for use */
  164. X    long h_count;    /* number of strings */
  165. X} STRINGHEAD;
  166. X
  167. X
  168. Xextern void initstr MATH_PROTO((STRINGHEAD *hp));
  169. Xextern char *addstr MATH_PROTO((STRINGHEAD *hp, char *str));
  170. Xextern char *namestr MATH_PROTO((STRINGHEAD *hp, long n));
  171. Xextern long findstr MATH_PROTO((STRINGHEAD *hp, char *str));
  172. Xextern char *charstr MATH_PROTO((int ch));
  173. Xextern char *addliteral MATH_PROTO((char *str));
  174. Xextern long stringindex MATH_PROTO((char *str1, char *str2));
  175. Xextern HASH hashstr MATH_PROTO((char *cp));
  176. X
  177. X#endif
  178. X
  179. X/* END CODE */
  180. SHAR_EOF
  181. chmod 0644 calc2.9.0/string.h || echo "restore of calc2.9.0/string.h fails"
  182. set `wc -c calc2.9.0/string.h`;Sum=$1
  183. if test "$Sum" != "905"
  184. then echo original size 905, current size $Sum;fi
  185. echo "x - extracting calc2.9.0/symbol.c (Text)"
  186. sed 's/^X//' << 'SHAR_EOF' > calc2.9.0/symbol.c &&
  187. X/*
  188. X * Copyright (c) 1993 David I. Bell
  189. X * Permission is granted to use, distribute, or modify this source,
  190. X * provided that this copyright notice remains intact.
  191. X *
  192. X * Global and local symbol routines.
  193. X */
  194. X
  195. X#include "calc.h"
  196. X#include "token.h"
  197. X#include "symbol.h"
  198. X#include "string.h"
  199. X#include "opcodes.h"
  200. X#include "func.h"
  201. X
  202. X#define HASHSIZE    37    /* size of hash table */
  203. X
  204. X
  205. Xstatic int filescope;        /* file scope level for static variables */
  206. Xstatic int funcscope;        /* function scope level for static variables */
  207. Xstatic STRINGHEAD localnames;    /* list of local variable names */
  208. Xstatic STRINGHEAD globalnames;    /* list of global variable names */
  209. Xstatic STRINGHEAD paramnames;    /* list of parameter variable names */
  210. Xstatic GLOBAL *globalhash[HASHSIZE];    /* hash table for globals */
  211. X
  212. Xstatic void fitprint MATH_PROTO((NUMBER *num, long digits, long width));
  213. Xstatic void unscope MATH_PROTO((void));
  214. X
  215. X
  216. X/*
  217. X * Hash a symbol name so we can find it in the hash table.
  218. X * Args are the symbol name and the symbol name size.
  219. X */
  220. X#define HASHSYM(n, s) ((unsigned)((n)[0]*123 + (n)[s-1]*135 + (s)*157) % HASHSIZE)
  221. X
  222. X
  223. X/*
  224. X * Initialize the global symbol table.
  225. X */
  226. Xvoid
  227. Xinitglobals()
  228. X{
  229. X    int i;        /* index counter */
  230. X
  231. X    for (i = 0; i < HASHSIZE; i++)
  232. X        globalhash[i] = NULL;
  233. X    initstr(&globalnames);
  234. X    filescope = SCOPE_STATIC;
  235. X    funcscope = 0;
  236. X}
  237. X
  238. X
  239. X/*
  240. X * Define a possibly new global variable which may or may not be static.
  241. X * If it did not already exist, it is created with a value of zero.
  242. X * The address of the global symbol structure is returned.
  243. X */
  244. XGLOBAL *
  245. Xaddglobal(name, isstatic)
  246. X    char *name;        /* name of global variable */
  247. X    BOOL isstatic;        /* TRUE if symbol is static */
  248. X{
  249. X    GLOBAL *sp;        /* current symbol pointer */
  250. X    GLOBAL **hp;        /* hash table head address */
  251. X    long len;        /* length of string */
  252. X    int newfilescope;    /* file scope being looked for */
  253. X    int newfuncscope;    /* function scope being looked for */
  254. X
  255. X    newfilescope = SCOPE_GLOBAL;
  256. X    newfuncscope = 0;
  257. X    if (isstatic) {
  258. X        newfilescope = filescope;
  259. X        newfuncscope = funcscope;
  260. X    }
  261. X    len = strlen(name);
  262. X    if (len <= 0)
  263. X        return NULL;
  264. X    hp = &globalhash[HASHSYM(name, len)];
  265. X    for (sp = *hp; sp; sp = sp->g_next) {
  266. X        if ((sp->g_len == len) && (strcmp(sp->g_name, name) == 0)
  267. X            && (sp->g_filescope == newfilescope)
  268. X            && (sp->g_funcscope == newfuncscope))
  269. X                return sp;
  270. X    }
  271. X    sp = (GLOBAL *) malloc(sizeof(GLOBAL));
  272. X    if (sp == NULL)
  273. X        return sp;
  274. X    sp->g_name = addstr(&globalnames, name);
  275. X    sp->g_len = len;
  276. X    sp->g_filescope = newfilescope;
  277. X    sp->g_funcscope = newfuncscope;
  278. X    sp->g_value.v_num = qlink(&_qzero_);
  279. X    sp->g_value.v_type = V_NUM;
  280. X    sp->g_next = *hp;
  281. X    *hp = sp;
  282. X    return sp;
  283. X}
  284. X
  285. X
  286. X/*
  287. X * Look up the name of a global variable and return its address.
  288. X * Since the same variable may appear in different scopes, we search
  289. X * for the one with the highest function scope value within the current
  290. X * file scope level (or which is global).  Returns NULL if the symbol
  291. X * was not found.
  292. X */
  293. XGLOBAL *
  294. Xfindglobal(name)
  295. X    char *name;        /* name of global variable */
  296. X{
  297. X    GLOBAL *sp;        /* current symbol pointer */
  298. X    GLOBAL *bestsp;        /* found symbol with highest scope */
  299. X    long len;        /* length of string */
  300. X
  301. X    bestsp = NULL;
  302. X    len = strlen(name);
  303. X    for (sp = globalhash[HASHSYM(name, len)]; sp; sp = sp->g_next) {
  304. X        if ((sp->g_len != len) || strcmp(sp->g_name, name))
  305. X            continue;
  306. X        if (sp->g_filescope == SCOPE_GLOBAL) {
  307. X            if (bestsp == NULL)
  308. X                bestsp = sp;
  309. X            continue;
  310. X        }
  311. X        if (sp->g_filescope != filescope)
  312. X            continue;
  313. X        if ((bestsp == NULL) || (sp->g_funcscope > bestsp->g_funcscope))
  314. X            bestsp = sp;
  315. X    }
  316. X    return bestsp;
  317. X}
  318. X
  319. X
  320. X/*
  321. X * Return the name of a global variable given its address.
  322. X */
  323. Xchar *
  324. Xglobalname(sp)
  325. X    GLOBAL *sp;        /* address of global pointer */
  326. X{
  327. X    if (sp)
  328. X        return sp->g_name;
  329. X    return "";
  330. X}
  331. X
  332. X
  333. X/*
  334. X * Show the value of all global variables, typing only the head and
  335. X * tail of very large numbers.  Only truly global symbols are shown.
  336. X */
  337. Xvoid
  338. Xshowglobals()
  339. X{
  340. X    GLOBAL **hp;            /* hash table head address */
  341. X    register GLOBAL *sp;        /* current global symbol pointer */
  342. X    long count;            /* number of global variables shown */
  343. X    NUMBER *num, *den;
  344. X    long digits;
  345. X
  346. X    count = 0;
  347. X    for (hp = &globalhash[HASHSIZE-1]; hp >= globalhash; hp--) {
  348. X        for (sp = *hp; sp; sp = sp->g_next) {
  349. X            if (sp->g_value.v_type != V_NUM)
  350. X                continue;
  351. X            if (sp->g_filescope != SCOPE_GLOBAL)
  352. X                continue;
  353. X            if (count++ == 0) {
  354. X                printf("\nName    Digits  Value\n");
  355. X                printf(  "----    ------  -----\n");
  356. X            }
  357. X            printf("%-8s ", sp->g_name);
  358. X            num = qnum(sp->g_value.v_num);
  359. X            digits = qdigits(num);
  360. X            printf("%-7ld ", digits);
  361. X            fitprint(num, digits, 60L);
  362. X            qfree(num);
  363. X            if (!qisint(sp->g_value.v_num)) {
  364. X                den = qden(sp->g_value.v_num);
  365. X                digits = qdigits(den);
  366. X                printf("\n    %-6ld /", digits);
  367. X                fitprint(den, digits, 60L);
  368. X                qfree(den);
  369. X            }
  370. X            printf("\n");
  371. X        }
  372. X    }
  373. X    printf(count ? "\n" : "No global variables defined.\n");
  374. X}
  375. X
  376. X
  377. X/*
  378. X * Print an integer which is guaranteed to fit in the specified number
  379. X * of columns, using imbedded '...' characters if it is too large.
  380. X */
  381. Xstatic void
  382. Xfitprint(num, digits, width)
  383. X    NUMBER *num;        /* number to print */
  384. X    long digits, width;
  385. X{
  386. X    long show, used;
  387. X    NUMBER *p, *t, *div, *val;
  388. X
  389. X    if (digits <= width) {
  390. X        qprintf("%r", num);
  391. X        return;
  392. X    }
  393. X    show = (width / 2) - 2;
  394. X    t = itoq(10L);
  395. X    p = itoq((long) (digits - show));
  396. X    div = qpowi(t, p);
  397. X    val = qquo(num, div);
  398. X    qprintf("%r...", val);
  399. X    qfree(p);
  400. X    qfree(div);
  401. X    qfree(val);
  402. X    p = itoq(show);
  403. X    div = qpowi(t, p);
  404. X    val = qmod(num, div);
  405. X    used = qdigits(val);
  406. X    while (used++ < show) printf("0");
  407. X    qprintf("%r", val);
  408. X    qfree(p);
  409. X    qfree(div);
  410. X    qfree(val);
  411. X    qfree(t);
  412. X}
  413. X
  414. X
  415. X/*
  416. X * Write all normal global variables to an output file.
  417. X * Note: Currently only simple types are saved.
  418. X * Returns nonzero on error.
  419. X */
  420. Xwriteglobals(name)
  421. X    char *name;
  422. X{
  423. X    FILE *fp;
  424. X    GLOBAL **hp;            /* hash table head address */
  425. X    register GLOBAL *sp;        /* current global symbol pointer */
  426. X    int savemode;            /* saved output mode */
  427. X
  428. X    fp = f_open(name, "w");
  429. X    if (fp == NULL)
  430. X        return 1;
  431. X    math_setfp(fp);
  432. X    for (hp = &globalhash[HASHSIZE-1]; hp >= globalhash; hp--) {
  433. X        for (sp = *hp; sp; sp = sp->g_next) {
  434. X            switch (sp->g_value.v_type) {
  435. X                case V_NUM:
  436. X                case V_COM:
  437. X                case V_STR:
  438. X                    break;
  439. X                default:
  440. X                    continue;
  441. X            }
  442. X            math_fmt("%s = ", sp->g_name);
  443. X            savemode = math_setmode(MODE_HEX);
  444. X            printvalue(&sp->g_value, PRINT_UNAMBIG);
  445. X            math_setmode(savemode);
  446. X            math_str(";\n");
  447. X        }
  448. X    }
  449. X    math_setfp(stdout);
  450. X    if (fclose(fp))
  451. X        return 1;
  452. X    return 0;
  453. X}
  454. X
  455. X
  456. X/*
  457. X * Reset the file and function scope levels back to the original values.
  458. X * This is called on errors to forget any static variables which were being
  459. X * defined.
  460. X */
  461. Xvoid
  462. Xresetscopes()
  463. X{
  464. X    filescope = SCOPE_STATIC;
  465. X    funcscope = 0;
  466. X    unscope();
  467. X}
  468. X
  469. X
  470. X/*
  471. X * Enter a new file scope level so that newly defined static variables
  472. X * will have the appropriate scope, and so that previously defined static
  473. X * variables will temporarily be unaccessible.  This should only be called
  474. X * when the function scope level is zero.
  475. X */
  476. Xvoid
  477. Xenterfilescope()
  478. X{
  479. X    filescope++;
  480. X    funcscope = 0;
  481. X}
  482. X
  483. X
  484. X/*
  485. X * Exit from a file scope level.  This deletes from the global symbol table
  486. X * all of the static variables that were defined within this file scope level.
  487. X * The function scope level is also reset to zero.
  488. X */
  489. Xvoid
  490. Xexitfilescope()
  491. X{
  492. X    if (filescope > SCOPE_STATIC)
  493. X        filescope--;
  494. X    funcscope = 0;
  495. X    unscope();
  496. X}
  497. X
  498. X
  499. X/*
  500. X * Enter a new function scope level within the current file scope level.
  501. X * This allows newly defined static variables to override previously defined
  502. X * static variables in the same file scope level.
  503. X */
  504. Xvoid
  505. Xenterfuncscope()
  506. X{
  507. X    funcscope++;
  508. X}
  509. X
  510. X
  511. X/*
  512. X * Exit from a function scope level.  This deletes static symbols which were
  513. X * defined within the current function scope level, and makes previously
  514. X * defined symbols with the same name within the same file scope level
  515. X * accessible again.
  516. X */
  517. Xvoid
  518. Xexitfuncscope()
  519. X{
  520. X    if (funcscope > 0)
  521. X        funcscope--;
  522. X    unscope();
  523. X}
  524. X
  525. X
  526. X/*
  527. X * Remove all the symbols from the global symbol table which have file or
  528. X * function scopes larger than the current scope levels.  Their memory
  529. X * remains allocated since their values still actually exist.
  530. X */
  531. Xstatic void
  532. Xunscope()
  533. X{
  534. X    GLOBAL **hp;            /* hash table head address */
  535. X    register GLOBAL *sp;        /* current global symbol pointer */
  536. X    GLOBAL *prevsp;            /* previous kept symbol pointer */
  537. X
  538. X    for (hp = &globalhash[HASHSIZE-1]; hp >= globalhash; hp--) {
  539. X        prevsp = NULL;
  540. X        for (sp = *hp; sp; sp = sp->g_next) {
  541. X            if ((sp->g_filescope == SCOPE_GLOBAL) ||
  542. X                (sp->g_filescope < filescope) ||
  543. X                ((sp->g_filescope == filescope) &&
  544. X                    (sp->g_funcscope <= funcscope)))
  545. X            {
  546. X                prevsp = sp;
  547. X                continue;
  548. X            }
  549. X
  550. X            /*
  551. X             * This symbol needs removing.
  552. X             */
  553. X            if (prevsp)
  554. X                prevsp->g_next = sp->g_next;
  555. X            else
  556. X                *hp = sp->g_next;
  557. X        }
  558. X    }
  559. X}
  560. X
  561. X
  562. X/*
  563. X * Initialize the local and parameter symbol table information.
  564. X */
  565. Xvoid
  566. Xinitlocals()
  567. X{
  568. X    initstr(&localnames);
  569. X    initstr(¶mnames);
  570. X    curfunc->f_localcount = 0;
  571. X    curfunc->f_paramcount = 0;
  572. X}
  573. X
  574. X
  575. X/*
  576. X * Add a possibly new local variable definition.
  577. X * Returns the index of the variable into the local symbol table.
  578. X * Minus one indicates the symbol could not be added.
  579. X */
  580. Xlong
  581. Xaddlocal(name)
  582. X    char *name;        /* name of local variable */
  583. X{
  584. X    long index;        /* current symbol index */
  585. X
  586. X    index = findstr(&localnames, name);
  587. X    if (index >= 0)
  588. X        return index;
  589. X    index = localnames.h_count;
  590. X    (void) addstr(&localnames, name);
  591. X    curfunc->f_localcount++;
  592. X    return index;
  593. X}
  594. X
  595. X
  596. X/*
  597. X * Find a local variable name and return its index.
  598. X * Returns minus one if the variable name is not defined.
  599. X */
  600. Xlong
  601. Xfindlocal(name)
  602. X    char *name;        /* name of local variable */
  603. X{
  604. X    return findstr(&localnames, name);
  605. X}
  606. X
  607. X
  608. X/*
  609. X * Return the name of a local variable.
  610. X */
  611. Xchar *
  612. Xlocalname(n)
  613. X    long n;
  614. X{
  615. X    return namestr(&localnames, n);
  616. X}
  617. X
  618. X
  619. X/*
  620. X * Add a possibly new parameter variable definition.
  621. X * Returns the index of the variable into the parameter symbol table.
  622. X * Minus one indicates the symbol could not be added.
  623. X */
  624. Xlong
  625. Xaddparam(name)
  626. X    char *name;        /* name of parameter variable */
  627. X{
  628. X    long index;        /* current symbol index */
  629. X
  630. X    index = findstr(¶mnames, name);
  631. X    if (index >= 0)
  632. X        return index;
  633. X    index = paramnames.h_count;
  634. X    (void) addstr(¶mnames, name);
  635. X    curfunc->f_paramcount++;
  636. X    return index;
  637. X}
  638. X
  639. X
  640. X/*
  641. X * Find a parameter variable name and return its index.
  642. X * Returns minus one if the variable name is not defined.
  643. X */
  644. Xlong
  645. Xfindparam(name)
  646. X    char *name;        /* name of parameter variable */
  647. X{
  648. X    return findstr(¶mnames, name);
  649. X}
  650. X
  651. X
  652. X/*
  653. X * Return the name of a parameter variable.
  654. X */
  655. Xchar *
  656. Xparamname(n)
  657. X    long n;
  658. X{
  659. X    return namestr(¶mnames, n);
  660. X}
  661. X
  662. X
  663. X/*
  664. X * Return the type of a variable name.
  665. X * This is either local, parameter, global, static, or undefined.
  666. X */
  667. Xsymboltype(name)
  668. X    char *name;        /* variable name to find */
  669. X{
  670. X    GLOBAL *sp;
  671. X
  672. X    if (findlocal(name) >= 0)
  673. X        return SYM_LOCAL;
  674. X    if (findparam(name) >= 0)
  675. X        return SYM_PARAM;
  676. X    sp = findglobal(name);
  677. X    if (sp) {
  678. X        if (sp->g_filescope == SCOPE_GLOBAL)
  679. X            return SYM_GLOBAL;
  680. X        return SYM_STATIC;
  681. X    }
  682. X    return SYM_UNDEFINED;
  683. X}
  684. X
  685. X/* END CODE */
  686. SHAR_EOF
  687. chmod 0644 calc2.9.0/symbol.c || echo "restore of calc2.9.0/symbol.c fails"
  688. set `wc -c calc2.9.0/symbol.c`;Sum=$1
  689. if test "$Sum" != "11019"
  690. then echo original size 11019, current size $Sum;fi
  691. echo "x - extracting calc2.9.0/symbol.h (Text)"
  692. sed 's/^X//' << 'SHAR_EOF' > calc2.9.0/symbol.h &&
  693. X/*
  694. X * Copyright (c) 1993 David I. Bell
  695. X * Permission is granted to use, distribute, or modify this source,
  696. X * provided that this copyright notice remains intact.
  697. X */
  698. X
  699. X#ifndef    SYMBOL_H
  700. X#define    SYMBOL_H
  701. X
  702. X#include "zmath.h"
  703. X
  704. X
  705. X/*
  706. X * Symbol Declarations.
  707. X */
  708. X#define SYM_UNDEFINED    0    /* undefined symbol */
  709. X#define SYM_PARAM    1    /* parameter symbol */
  710. X#define SYM_LOCAL    2    /* local symbol */
  711. X#define SYM_GLOBAL    3    /* global symbol */
  712. X#define    SYM_STATIC    4    /* static symbol */
  713. X
  714. X#define    SCOPE_GLOBAL    0    /* file scope level for global variables */
  715. X#define    SCOPE_STATIC    1    /* lowest file scope for static variables */
  716. X
  717. X
  718. Xtypedef struct global GLOBAL;
  719. Xstruct global {
  720. X    int g_len;        /* length of symbol name */
  721. X    short g_filescope;    /* file scope level of symbol (0 if global) */
  722. X    short g_funcscope;    /* function scope level of symbol */
  723. X    char *g_name;        /* global symbol name */
  724. X    VALUE g_value;        /* global symbol value */
  725. X    GLOBAL *g_next;        /* next symbol in hash chain */
  726. X};
  727. X
  728. X
  729. X/*
  730. X * Routines to search for global symbols.
  731. X */
  732. Xextern GLOBAL *addglobal MATH_PROTO((char *name, BOOL isstatic));
  733. Xextern GLOBAL *findglobal MATH_PROTO((char *name));
  734. X
  735. X
  736. X/*
  737. X * Routines to return names of variables.
  738. X */
  739. Xextern char *localname MATH_PROTO((long n));
  740. Xextern char *paramname MATH_PROTO((long n));
  741. Xextern char *globalname MATH_PROTO((GLOBAL *sp));
  742. X
  743. X
  744. X/*
  745. X * Routines to handle entering and leaving of scope levels.
  746. X */
  747. Xextern void resetscopes MATH_PROTO((void));
  748. Xextern void enterfilescope MATH_PROTO((void));
  749. Xextern void exitfilescope MATH_PROTO((void));
  750. Xextern void enterfuncscope MATH_PROTO((void));
  751. Xextern void exitfuncscope MATH_PROTO((void));
  752. X
  753. X
  754. X/*
  755. X * Other routines.
  756. X */
  757. Xextern long addlocal MATH_PROTO((char *name));
  758. Xextern long findlocal MATH_PROTO((char *name));
  759. Xextern long addparam MATH_PROTO((char *name));
  760. Xextern long findparam MATH_PROTO((char *name));
  761. Xextern void initlocals MATH_PROTO((void));
  762. Xextern void initglobals MATH_PROTO((void));
  763. Xextern int writeglobals MATH_PROTO((char *name));
  764. Xextern int symboltype MATH_PROTO((char *name));
  765. Xextern void showglobals MATH_PROTO((void));
  766. X
  767. X#endif
  768. X
  769. X/* END CODE */
  770. SHAR_EOF
  771. chmod 0644 calc2.9.0/symbol.h || echo "restore of calc2.9.0/symbol.h fails"
  772. set `wc -c calc2.9.0/symbol.h`;Sum=$1
  773. if test "$Sum" != "2081"
  774. then echo original size 2081, current size $Sum;fi
  775. echo "x - extracting calc2.9.0/token.c (Text)"
  776. sed 's/^X//' << 'SHAR_EOF' > calc2.9.0/token.c &&
  777. X/*
  778. X * Copyright (c) 1993 David I. Bell
  779. X * Permission is granted to use, distribute, or modify this source,
  780. X * provided that this copyright notice remains intact.
  781. X *
  782. X * Read input file characters into tokens
  783. X */
  784. X
  785. X#include "stdarg.h"
  786. X#include "calc.h"
  787. X#include "token.h"
  788. X#include "string.h"
  789. X
  790. X
  791. X#define isletter(ch)    ((((ch) >= 'a') && ((ch) <= 'z')) || \
  792. X                (((ch) >= 'A') && ((ch) <= 'Z')))
  793. X#define isdigit(ch)    (((ch) >= '0') && ((ch) <= '9'))
  794. X#define issymbol(ch)    (isletter(ch) || isdigit(ch) || ((ch) == '_'))
  795. X
  796. X
  797. X/*
  798. X * Current token.
  799. X */
  800. Xstatic struct {
  801. X    short t_type;        /* type of token */
  802. X    char *t_str;        /* string value or symbol name */
  803. X    long t_numindex;    /* index of numeric value */
  804. X} curtoken;
  805. X
  806. X
  807. Xstatic BOOL rescan;        /* TRUE to reread current token */
  808. Xstatic BOOL newlines;        /* TRUE to return newlines as tokens */
  809. Xstatic BOOL allsyms;        /* TRUE if always want a symbol token */
  810. Xstatic STRINGHEAD strings;    /* list of constant strings */
  811. Xstatic char *numbuf;        /* buffer for numeric tokens */
  812. Xstatic long numbufsize;        /* current size of numeric buffer */
  813. X
  814. Xlong errorcount;        /* number of compilation errors */
  815. X
  816. X
  817. X/*
  818. X * Table of keywords
  819. X */
  820. Xstruct keyword {
  821. X    char *k_name;    /* keyword name */
  822. X    int k_token;    /* token number */
  823. X};
  824. X
  825. Xstatic struct keyword keywords[] = {
  826. X    "if",        T_IF,
  827. X    "else",        T_ELSE,
  828. X    "for",        T_FOR,
  829. X    "while",    T_WHILE,
  830. X    "do",        T_DO,
  831. X    "continue",    T_CONTINUE,
  832. X    "break",    T_BREAK,
  833. X    "goto",        T_GOTO,
  834. X    "return",    T_RETURN,
  835. X    "local",    T_LOCAL,
  836. X    "global",    T_GLOBAL,
  837. X    "static",    T_STATIC,
  838. X    "switch",    T_SWITCH,
  839. X    "case",        T_CASE,
  840. X    "default",    T_DEFAULT,
  841. X    "quit",        T_QUIT,
  842. X    "exit",        T_QUIT,
  843. X    "define",    T_DEFINE,
  844. X    "read",        T_READ,
  845. X    "show",        T_SHOW,
  846. X    "help",        T_HELP,
  847. X    "write",    T_WRITE,
  848. X    "mat",        T_MAT,
  849. X    "obj",        T_OBJ,
  850. X    "print",    T_PRINT,
  851. X    NULL,        0
  852. X};
  853. X
  854. X
  855. Xstatic void eatcomment MATH_PROTO((void));
  856. Xstatic void eatstring MATH_PROTO((int quotechar));
  857. Xstatic int eatsymbol MATH_PROTO((void));
  858. Xstatic int eatnumber MATH_PROTO((void));
  859. X
  860. X
  861. X/*
  862. X * Initialize all token information.
  863. X */
  864. Xvoid
  865. Xinittokens()
  866. X{
  867. X    initstr(&strings);
  868. X    newlines = FALSE;
  869. X    allsyms = FALSE;
  870. X    rescan = FALSE;
  871. X    setprompt(PROMPT1);
  872. X}
  873. X
  874. X
  875. X/*
  876. X * Set the new token mode according to the specified flag, and return the
  877. X * previous value of the flag.
  878. X */
  879. Xint
  880. Xtokenmode(flag)
  881. X{
  882. X    int    oldflag;
  883. X
  884. X    oldflag = TM_DEFAULT;
  885. X    if (newlines)
  886. X        oldflag |= TM_NEWLINES;
  887. X    if (allsyms)
  888. X        oldflag |= TM_ALLSYMS;
  889. X    newlines = FALSE;
  890. X    allsyms = FALSE;
  891. X    if (flag & TM_NEWLINES)
  892. X        newlines = TRUE;
  893. X    if (flag & TM_ALLSYMS)
  894. X        allsyms = TRUE;
  895. X    setprompt(newlines ? PROMPT1 : PROMPT2);
  896. X    return oldflag;
  897. X}
  898. X
  899. X
  900. X/*
  901. X * Routine to read in the next token from the input stream.
  902. X * The type of token is returned as a value.  If the token is a string or
  903. X * symbol name, information is saved so that the value can be retrieved.
  904. X */
  905. Xint
  906. Xgettoken()
  907. X{
  908. X    int ch;            /* current input character */
  909. X    int type;        /* token type */
  910. X
  911. X    if (rescan) {        /* rescanning */
  912. X        rescan = FALSE;
  913. X        return curtoken.t_type;
  914. X    }
  915. X    curtoken.t_str = NULL;
  916. X    curtoken.t_numindex = 0;
  917. X    type = T_NULL;
  918. X    while (type == T_NULL) {
  919. X        ch = nextchar();
  920. X        if (allsyms && ((ch!=' ') && (ch!=';') && (ch!='"') && (ch!='\n'))) {
  921. X            reread();
  922. X            type = eatsymbol();
  923. X            break;
  924. X        }
  925. X        switch (ch) {
  926. X        case ' ':
  927. X        case '\t':
  928. X        case '\0':
  929. X            break;
  930. X        case '\n':
  931. X            if (newlines)
  932. X                type = T_NEWLINE;
  933. X            break;
  934. X        case EOF: type = T_EOF; break;
  935. X        case '{': type = T_LEFTBRACE; break;
  936. X        case '}': type = T_RIGHTBRACE; break;
  937. X        case '(': type = T_LEFTPAREN; break;
  938. X        case ')': type = T_RIGHTPAREN; break;
  939. X        case '[': type = T_LEFTBRACKET; break;
  940. X        case ']': type = T_RIGHTBRACKET; break;
  941. X        case ';': type = T_SEMICOLON; break;
  942. X        case ':': type = T_COLON; break;
  943. X        case ',': type = T_COMMA; break;
  944. X        case '?': type = T_QUESTIONMARK; break;
  945. X        case '"':
  946. X        case '\'':
  947. X            type = T_STRING;
  948. X            eatstring(ch);
  949. X            break;
  950. X        case '^':
  951. X            switch (nextchar()) {
  952. X                case '=': type = T_POWEREQUALS; break;
  953. X                default: type = T_POWER; reread();
  954. X            }
  955. X            break;
  956. X        case '=':
  957. X            switch (nextchar()) {
  958. X                case '=': type = T_EQ; break;
  959. X                default: type = T_ASSIGN; reread();
  960. X            }
  961. X            break;
  962. X        case '+':
  963. X            switch (nextchar()) {
  964. X                case '+': type = T_PLUSPLUS; break;
  965. X                case '=': type = T_PLUSEQUALS; break;
  966. X                default: type = T_PLUS; reread();
  967. X            }
  968. X            break;
  969. X        case '-':
  970. X            switch (nextchar()) {
  971. X                case '-': type = T_MINUSMINUS; break;
  972. X                case '=': type = T_MINUSEQUALS; break;
  973. X                default: type = T_MINUS; reread();
  974. X            }
  975. X            break;
  976. X        case '*':
  977. X            switch (nextchar()) {
  978. X                case '=': type = T_MULTEQUALS; break;
  979. X                case '*':
  980. X                    switch (nextchar()) {
  981. X                        case '=': type = T_POWEREQUALS; break;
  982. X                        default: type = T_POWER; reread();
  983. X                    }
  984. X                    break;
  985. X                default: type = T_MULT; reread();
  986. X            }
  987. X            break;
  988. X        case '/':
  989. X            switch (nextchar()) {
  990. X                case '/':
  991. X                    switch (nextchar()) {
  992. X                        case '=': type = T_SLASHSLASHEQUALS; break;
  993. X                        default: reread(); type = T_SLASHSLASH; break;
  994. X                    }
  995. X                    break;
  996. X                case '=': type = T_DIVEQUALS; break;
  997. X                case '*': eatcomment(); break;
  998. X                default: type = T_DIV; reread();
  999. X            }
  1000. X            break;
  1001. X        case '%':
  1002. X            switch (nextchar()) {
  1003. X                case '=': type = T_MODEQUALS; break;
  1004. X                default: type = T_MOD; reread();
  1005. X            }
  1006. X            break;
  1007. X        case '<':
  1008. X            switch (nextchar()) {
  1009. X                case '=': type = T_LE; break;
  1010. X                case '<':
  1011. X                    switch (nextchar()) {
  1012. X                        case '=': type = T_LSHIFTEQUALS; break;
  1013. X                        default:  reread(); type = T_LEFTSHIFT; break;
  1014. X                    }
  1015. X                    break;
  1016. X                default: type = T_LT; reread();
  1017. X            }
  1018. X            break;
  1019. X        case '>':
  1020. X            switch (nextchar()) {
  1021. X                case '=': type = T_GE; break;
  1022. X                case '>':
  1023. X                    switch (nextchar()) {
  1024. X                        case '=': type = T_RSHIFTEQUALS; break;
  1025. X                        default:  reread(); type = T_RIGHTSHIFT; break;
  1026. X                    }
  1027. X                    break;
  1028. X                default: type = T_GT; reread();
  1029. X            }
  1030. X            break;
  1031. X        case '&':
  1032. X            switch (nextchar()) {
  1033. X                case '&': type = T_ANDAND; break;
  1034. X                case '=': type = T_ANDEQUALS; break;
  1035. X                default: type = T_AND; reread(); break;
  1036. X            }
  1037. X            break;
  1038. X        case '|':
  1039. X            switch (nextchar()) {
  1040. X                case '|': type = T_OROR; break;
  1041. X                case '=': type = T_OREQUALS; break;
  1042. X                default: type = T_OR; reread(); break;
  1043. X            }
  1044. X            break;
  1045. X        case '!':
  1046. X            switch (nextchar()) {
  1047. X                case '=': type = T_NE; break;
  1048. X                default: type = T_NOT; reread(); break;
  1049. X            }
  1050. X            break;
  1051. X        case '\\':
  1052. X            switch (nextchar()) {
  1053. X                case '\n': setprompt(PROMPT2); break;
  1054. X                default: scanerror(T_NULL, "Unknown token character '%c'", ch);
  1055. X            }
  1056. X            break;
  1057. X        default:
  1058. X            if (isletter(ch)) {
  1059. X                reread();
  1060. X                type = eatsymbol();
  1061. X                break;
  1062. X            }
  1063. X            if (isdigit(ch) || (ch == '.')) {
  1064. X                reread();
  1065. X                type = eatnumber();
  1066. X                break;
  1067. X            }
  1068. X            scanerror(T_NULL, "Unknown token character '%c'", ch);
  1069. X        }
  1070. X    }
  1071. X    curtoken.t_type = (short)type;
  1072. X    return type;
  1073. X}
  1074. X
  1075. X
  1076. X/*
  1077. X * Continue to eat up a comment string.
  1078. X * The leading slash-asterisk has just been scanned at this point.
  1079. X */
  1080. Xstatic void
  1081. Xeatcomment()
  1082. X{
  1083. X    int ch;
  1084. X
  1085. X    for (;;) {
  1086. X        ch = nextchar();
  1087. X        if (ch == '*') {
  1088. X            ch = nextchar();
  1089. X            if (ch == '/')
  1090. X                return;
  1091. X            reread();
  1092. X        }
  1093. X        if ((ch == EOF) || (ch == '\0') ||
  1094. X            (newlines && (ch == '\n') && inputisterminal())) {
  1095. X                reread();
  1096. X                scanerror(T_NULL, "Unterminated comment");
  1097. X                return;
  1098. X        }
  1099. X    }
  1100. X}
  1101. X
  1102. X
  1103. X/*
  1104. X * Read in a string and add it to the literal string pool.
  1105. X * The leading single or double quote has been read in at this point.
  1106. X */
  1107. Xstatic void
  1108. Xeatstring(quotechar)
  1109. X{
  1110. X    register char *cp;    /* current character address */
  1111. X    int ch;            /* current character */
  1112. X    char buf[MAXSTRING+1];    /* buffer for string */
  1113. X
  1114. X    cp = buf;
  1115. X    for (;;) {
  1116. X        ch = nextchar();
  1117. X        switch (ch) {
  1118. X            case '\0':
  1119. X            case EOF:
  1120. X            case '\n':
  1121. X                reread();
  1122. X                scanerror(T_NULL, "Unterminated string constant");
  1123. X                *cp = '\0';
  1124. X                curtoken.t_str = addliteral(buf);
  1125. X                return;
  1126. X
  1127. X            case '\\':
  1128. X                ch = nextchar();
  1129. X                switch (ch) {
  1130. X                    case 'n': ch = '\n'; break;
  1131. X                    case 'r': ch = '\r'; break;
  1132. X                    case 't': ch = '\t'; break;
  1133. X                    case 'b': ch = '\b'; break;
  1134. X                    case 'f': ch = '\f'; break;
  1135. X                    case '\n':
  1136. X                        setprompt(PROMPT2);
  1137. X                        continue;
  1138. X                    case EOF:
  1139. X                        reread();
  1140. X                        continue;
  1141. X                }
  1142. X                *cp++ = (char)ch;
  1143. X                break;
  1144. X
  1145. X            case '"':
  1146. X            case '\'':
  1147. X                if (ch == quotechar) {
  1148. X                    *cp = '\0';
  1149. X                    curtoken.t_str = addliteral(buf);
  1150. X                    return;
  1151. X                }
  1152. X                /* fall into default case */
  1153. X
  1154. X            default:
  1155. X                *cp++ = (char)ch;
  1156. X        }
  1157. X    }
  1158. X}
  1159. X
  1160. X
  1161. X/*
  1162. X * Read in a symbol name which may or may not be a keyword.
  1163. X * If allsyms is set, keywords are not looked up and almost all chars
  1164. X * will be accepted for the symbol.  Returns the type of symbol found.
  1165. X */
  1166. Xstatic int
  1167. Xeatsymbol()
  1168. X{
  1169. X    register struct keyword *kp;    /* pointer to current keyword */
  1170. X    register char *cp;        /* current character pointer */
  1171. X    int ch;                /* current character */
  1172. X    int cc;                /* character count */
  1173. X    static char buf[SYMBOLSIZE+1];    /* temporary buffer */
  1174. X
  1175. X    cp = buf;
  1176. X    cc = SYMBOLSIZE;
  1177. X    if (allsyms) {
  1178. X        for (;;) {
  1179. X            ch = nextchar();
  1180. X            if ((ch == ' ') || (ch == ';') || (ch == '\n'))
  1181. X                break;
  1182. X            if (cc-- > 0)
  1183. X                *cp++ = (char)ch;
  1184. X        }
  1185. X        reread();
  1186. X        *cp = '\0';
  1187. X        if (cc < 0)
  1188. X            scanerror(T_NULL, "Symbol too long");
  1189. X        curtoken.t_str = buf;
  1190. X        return T_SYMBOL;
  1191. X    }
  1192. X    for (;;) {
  1193. X        ch = nextchar();
  1194. X        if (!issymbol(ch))
  1195. X            break;
  1196. X        if (cc-- > 0)
  1197. X            *cp++ = (char)ch;
  1198. X    }
  1199. X    reread();
  1200. X    *cp = '\0';
  1201. X    if (cc < 0)
  1202. X        scanerror(T_NULL, "Symbol too long");
  1203. X    for (kp = keywords; kp->k_name; kp++)
  1204. X        if (strcmp(kp->k_name, buf) == 0)
  1205. X            return kp->k_token;
  1206. X    curtoken.t_str = buf;
  1207. X    return T_SYMBOL;
  1208. X}
  1209. X
  1210. X
  1211. X/*
  1212. X * Read in and remember a possibly numeric constant value.
  1213. X * The constant is inserted into a constant table so further uses
  1214. X * of the same constant will not take more memory.  This can also
  1215. X * return just a period, which is used for element accesses and for
  1216. X * the old numeric value.
  1217. X */
  1218. Xstatic int
  1219. Xeatnumber()
  1220. X{
  1221. X    register char *cp;    /* current character pointer */
  1222. X    long len;        /* parsed size of number */
  1223. X    long res;        /* result of parsing number */
  1224. X
  1225. X    if (numbufsize == 0) {
  1226. X        numbuf = (char *)malloc(128+1);
  1227. X        if (numbuf == NULL)
  1228. X            math_error("Cannot allocate number buffer");
  1229. X        numbufsize = 128;
  1230. X    }
  1231. X    cp = numbuf;
  1232. X    len = 0;
  1233. X    for (;;) {
  1234. X        if (len >= numbufsize) {
  1235. X            cp = (char *)realloc(numbuf, numbufsize + 1001);
  1236. X            if (cp == NULL)
  1237. X                math_error("Cannot reallocate number buffer");
  1238. X            numbuf = cp;
  1239. X            numbufsize += 1000;
  1240. X            cp = &numbuf[len];
  1241. X        }
  1242. X        *cp = nextchar();
  1243. X        *(++cp) = '\0';
  1244. X        if ((numbuf[0] == '.') && isletter(numbuf[1])) {
  1245. X            reread();
  1246. X            return T_PERIOD;
  1247. X        }
  1248. X        res = qparse(numbuf, QPF_IMAG);
  1249. X        if (res < 0) {
  1250. X            reread();
  1251. X            scanerror(T_NULL, "Badly formatted number");
  1252. X            curtoken.t_numindex = addnumber("0");
  1253. X            return T_NUMBER;
  1254. X        }
  1255. X        if (res != ++len)
  1256. X            break;
  1257. X    }
  1258. X    cp[-1] = '\0';
  1259. X    reread();
  1260. X    if ((numbuf[0] == '.') && (numbuf[1] == '\0')) {
  1261. X        curtoken.t_numindex = 0;
  1262. X        return T_OLDVALUE;
  1263. X    }
  1264. X    cp -= 2;
  1265. X    res = T_NUMBER;
  1266. X    if ((*cp == 'i') || (*cp == 'I')) {
  1267. X        *cp = '\0';
  1268. X        res = T_IMAGINARY;
  1269. X    }
  1270. X    curtoken.t_numindex = addnumber(numbuf);
  1271. X    return res;
  1272. X}
  1273. X
  1274. X
  1275. X/*
  1276. X * Return the string value of the current token.
  1277. X */
  1278. Xchar *
  1279. Xtokenstring()
  1280. X{
  1281. X    return curtoken.t_str;
  1282. X}
  1283. X
  1284. X
  1285. X/*
  1286. X * Return the constant index of a numeric token.
  1287. X */
  1288. Xlong
  1289. Xtokennumber()
  1290. X{
  1291. X    return curtoken.t_numindex;
  1292. X}
  1293. X
  1294. X
  1295. X/*
  1296. X * Push back the token just read so that it will be seen again.
  1297. X */
  1298. Xvoid
  1299. Xrescantoken()
  1300. X{
  1301. X    rescan = TRUE;
  1302. X}
  1303. X
  1304. X
  1305. X/*
  1306. X * Describe an error message.
  1307. X * Then skip to the next specified token (or one more powerful).
  1308. X */
  1309. X#ifdef VARARGS
  1310. X# define VA_ALIST skip, fmt, va_alist
  1311. X# define VA_DCL int skip; char *fmt; va_dcl
  1312. X#else
  1313. X# ifdef __STDC__
  1314. X#  define VA_ALIST int skip, char *fmt, ...
  1315. X#  define VA_DCL
  1316. X# else
  1317. X#  define VA_ALIST skip, fmt
  1318. X#  define VA_DCL int skip; char *fmt;
  1319. X# endif
  1320. X#endif
  1321. X/*VARARGS*/
  1322. Xvoid
  1323. Xscanerror(VA_ALIST)
  1324. X    VA_DCL
  1325. X{
  1326. X    va_list ap;
  1327. X    char *name;        /* name of file with error */
  1328. X    char buf[MAXERROR+1];
  1329. X
  1330. X    errorcount++;
  1331. X    name = inputname();
  1332. X    if (name)
  1333. X        fprintf(stderr, "\"%s\", line %ld: ", name, linenumber());
  1334. X#ifdef VARARGS
  1335. X    va_start(ap);
  1336. X#else
  1337. X    va_start(ap, fmt);
  1338. X#endif
  1339. X    vsprintf(buf, fmt, ap);
  1340. X    va_end(ap);
  1341. X    fprintf(stderr, "%s\n", buf);
  1342. X    switch (skip) {
  1343. X        case T_NULL:
  1344. X            return;
  1345. X        case T_COMMA:
  1346. X            rescan = TRUE;
  1347. X            for (;;) {
  1348. X                switch (gettoken()) {
  1349. X                case T_NEWLINE:
  1350. X                case T_SEMICOLON:
  1351. X                case T_LEFTBRACE:
  1352. X                case T_RIGHTBRACE:
  1353. X                case T_EOF:
  1354. X                case T_COMMA:
  1355. X                    rescan = TRUE;
  1356. X                    return;
  1357. X                }
  1358. X            }
  1359. X        default:
  1360. X            fprintf(stderr, "Unknown skip token for scanerror\n");
  1361. X            /* fall into semicolon case */
  1362. X            /*FALLTHRU*/
  1363. X        case T_SEMICOLON:
  1364. X            rescan = TRUE;
  1365. X            for (;;) switch (gettoken()) {
  1366. X                case T_NEWLINE:
  1367. X                case T_SEMICOLON:
  1368. X                case T_LEFTBRACE:
  1369. X                case T_RIGHTBRACE:
  1370. X                case T_EOF:
  1371. X                    rescan = TRUE;
  1372. X                    return;
  1373. X            }
  1374. X    }
  1375. X}
  1376. X
  1377. X/* END CODE */
  1378. SHAR_EOF
  1379. chmod 0644 calc2.9.0/token.c || echo "restore of calc2.9.0/token.c fails"
  1380. set `wc -c calc2.9.0/token.c`;Sum=$1
  1381. if test "$Sum" != "12451"
  1382. then echo original size 12451, current size $Sum;fi
  1383. echo "x - extracting calc2.9.0/token.h (Text)"
  1384. sed 's/^X//' << 'SHAR_EOF' > calc2.9.0/token.h &&
  1385. X/*
  1386. X * Copyright (c) 1993 David I. Bell
  1387. X * Permission is granted to use, distribute, or modify this source,
  1388. X * provided that this copyright notice remains intact.
  1389. X */
  1390. X
  1391. X#ifndef    TOKEN_H
  1392. X#define    TOKEN_H
  1393. X
  1394. X#include "zmath.h"
  1395. X
  1396. X
  1397. X/*
  1398. X * Token types
  1399. X */
  1400. X#define T_NULL            0    /* null token */
  1401. X#define T_LEFTPAREN        1    /* left parenthesis "(" */
  1402. X#define T_RIGHTPAREN        2    /* right parenthesis ")" */
  1403. X#define T_LEFTBRACE        3    /* left brace "{" */
  1404. X#define T_RIGHTBRACE        4    /* right brace "}" */
  1405. X#define T_SEMICOLON        5    /* end of statement ";" */
  1406. X#define T_EOF            6    /* end of file */
  1407. X#define T_COLON            7    /* label character ":" */
  1408. X#define T_ASSIGN        8    /* assignment "=" */
  1409. X#define T_PLUS            9    /* plus sign "+" */
  1410. X#define T_MINUS            10    /* minus sign "-" */
  1411. X#define T_MULT            11    /* multiply sign "*" */
  1412. X#define T_DIV            12    /* divide sign "/" */
  1413. X#define T_MOD            13    /* modulo sign "%" */
  1414. X#define T_POWER            14    /* power sign "^" or "**" */
  1415. X#define T_EQ            15    /* equality "==" */
  1416. X#define T_NE            16    /* notequal "!=" */
  1417. X#define T_LT            17    /* less than "<" */
  1418. X#define T_GT            18    /* greater than ">" */
  1419. X#define T_LE            19    /* less than or equals "<=" */
  1420. X#define T_GE            20    /* greater than or equals ">=" */
  1421. X#define T_LEFTBRACKET        21    /* left bracket "[" */
  1422. X#define T_RIGHTBRACKET        22    /* right bracket "]" */
  1423. X#define T_SYMBOL        23    /* symbol name */
  1424. X#define T_STRING        24    /* string value (double quotes) */
  1425. X#define T_NUMBER        25    /* numeric real constant */
  1426. X#define T_PLUSEQUALS        26    /* plus equals "+=" */
  1427. X#define T_MINUSEQUALS        27    /* minus equals "-=" */
  1428. X#define T_MULTEQUALS        28    /* multiply equals "*=" */
  1429. X#define T_DIVEQUALS        29    /* divide equals "/=" */
  1430. X#define T_MODEQUALS        30    /* modulo equals "%=" */
  1431. X#define T_PLUSPLUS        31    /* plusplus "++" */
  1432. X#define T_MINUSMINUS        32    /* minusminus "--" */
  1433. X#define T_COMMA            33    /* comma "," */
  1434. X#define T_ANDAND        34    /* logical and "&&" */
  1435. X#define T_OROR            35    /* logical or "||" */
  1436. X#define T_OLDVALUE        36    /* old value from previous calculation */
  1437. X#define T_SLASHSLASH        37    /* integer divide "//" */
  1438. X#define T_NEWLINE        38    /* newline character */
  1439. X#define T_SLASHSLASHEQUALS    39    /* integer divide equals "//=" */
  1440. X#define T_AND            40    /* arithmetic and "&" */
  1441. X#define T_OR            41    /* arithmetic or "|" */
  1442. X#define T_NOT            42    /* logical not "!" */
  1443. X#define T_LEFTSHIFT        43    /* left shift "<<" */
  1444. X#define T_RIGHTSHIFT        44    /* right shift ">>" */
  1445. X#define T_ANDEQUALS        45    /* and equals "&=" */
  1446. X#define T_OREQUALS        46    /* or equals "|= */
  1447. X#define T_LSHIFTEQUALS        47    /* left shift equals "<<=" */
  1448. X#define T_RSHIFTEQUALS        48    /* right shift equals ">>= */
  1449. X#define T_POWEREQUALS        49    /* power equals "^=" or "**=" */
  1450. X#define T_PERIOD        50    /* period "." */
  1451. X#define T_IMAGINARY        51    /* numeric imaginary constant */
  1452. X#define    T_AMPERSAND        52    /* ampersand "&" */
  1453. X#define    T_QUESTIONMARK        53    /* question mark "?" */
  1454. X
  1455. X
  1456. X/*
  1457. X * Keyword tokens
  1458. X */
  1459. X#define T_IF            101    /* if keyword */
  1460. X#define T_ELSE            102    /* else keyword */
  1461. X#define T_WHILE            103    /* while keyword */
  1462. X#define T_CONTINUE        104    /* continue keyword */
  1463. X#define T_BREAK            105    /* break keyword */
  1464. X#define T_GOTO            106    /* goto keyword */
  1465. X#define T_RETURN        107    /* return keyword */
  1466. X#define T_LOCAL            108    /* local keyword */
  1467. X#define T_GLOBAL        109    /* global keyword */
  1468. X#define    T_STATIC        110    /* static keyword */
  1469. X#define T_DO            111    /* do keyword */
  1470. X#define T_FOR            112    /* for keyword */
  1471. X#define T_SWITCH        113    /* switch keyword */
  1472. X#define T_CASE            114    /* case keyword */
  1473. X#define T_DEFAULT        115    /* default keyword */
  1474. X#define T_QUIT            116    /* quit keyword */
  1475. X#define T_DEFINE        117    /* define keyword */
  1476. X#define T_READ            118    /* read keyword */
  1477. X#define T_SHOW            119    /* show keyword */
  1478. X#define T_HELP            120    /* help keyword */
  1479. X#define T_WRITE            121    /* write keyword */
  1480. X#define T_MAT            122    /* mat keyword */
  1481. X#define T_OBJ            123    /* obj keyword */
  1482. X#define T_PRINT            124    /* print keyword */
  1483. X
  1484. X
  1485. X#define iskeyword(n) ((n) > 100)    /* TRUE if token is a keyword */
  1486. X
  1487. X
  1488. X/*
  1489. X * Flags returned describing results of expression parsing.
  1490. X */
  1491. X#define EXPR_RVALUE    0x0001        /* result is an rvalue */
  1492. X#define EXPR_CONST    0x0002        /* result is constant */
  1493. X#define EXPR_ASSIGN    0x0004        /* result is an assignment */
  1494. X
  1495. X#define isrvalue(n)    ((n) & EXPR_RVALUE)    /* TRUE if expression is rvalue */
  1496. X#define islvalue(n)    (((n) & EXPR_RVALUE) == 0)    /* TRUE if expr is lvalue */
  1497. X#define isconst(n)    ((n) & EXPR_CONST)    /* TRUE if expr is constant */
  1498. X#define isassign(n)    ((n) & EXPR_ASSIGN)    /* TRUE if expr is an assignment */
  1499. X
  1500. X
  1501. X/*
  1502. X * Flags for modes for tokenizing.
  1503. X */
  1504. X#define TM_DEFAULT    0x0        /* normal mode */
  1505. X#define TM_NEWLINES    0x1        /* treat any newline as a token */
  1506. X#define TM_ALLSYMS    0x2        /* treat almost everything as a symbol */
  1507. X
  1508. X
  1509. Xextern long errorcount;        /* number of errors found */
  1510. X
  1511. Xextern char *tokenstring MATH_PROTO((void));
  1512. Xextern long tokennumber MATH_PROTO((void));
  1513. Xextern void inittokens MATH_PROTO((void));
  1514. Xextern int tokenmode MATH_PROTO((int flag));
  1515. Xextern int gettoken MATH_PROTO((void));
  1516. Xextern void rescantoken MATH_PROTO((void));
  1517. X
  1518. X#ifdef VARARGS
  1519. Xextern void scanerror();
  1520. X#else
  1521. Xextern void scanerror MATH_PROTO((int, char *, ...));
  1522. X#endif
  1523. X
  1524. X#endif
  1525. X
  1526. X/* END CODE */
  1527. SHAR_EOF
  1528. chmod 0644 calc2.9.0/token.h || echo "restore of calc2.9.0/token.h fails"
  1529. set `wc -c calc2.9.0/token.h`;Sum=$1
  1530. if test "$Sum" != "5031"
  1531. then echo original size 5031, current size $Sum;fi
  1532. echo "x - extracting calc2.9.0/value.c (Text)"
  1533. sed 's/^X//' << 'SHAR_EOF' > calc2.9.0/value.c &&
  1534. X/*
  1535. X * Copyright (c) 1993 David I. Bell
  1536. X * Permission is granted to use, distribute, or modify this source,
  1537. X * provided that this copyright notice remains intact.
  1538. X *
  1539. X * Generic value manipulation routines.
  1540. X */
  1541. X
  1542. X#include "value.h"
  1543. X#include "opcodes.h"
  1544. X#include "func.h"
  1545. X#include "symbol.h"
  1546. X#include "string.h"
  1547. X
  1548. X
  1549. X/*
  1550. X * Free a value and set its type to undefined.
  1551. X */
  1552. Xvoid
  1553. Xfreevalue(vp)
  1554. X    register VALUE *vp;    /* value to be freed */
  1555. X{
  1556. X    int type;        /* type of value being freed */
  1557. X
  1558. X    type = vp->v_type;
  1559. X    vp->v_type = V_NULL;
  1560. X    switch (type) {
  1561. X        case V_NULL:
  1562. X        case V_ADDR:
  1563. X        case V_FILE:
  1564. X            break;
  1565. X        case V_STR:
  1566. X            if (vp->v_subtype == V_STRALLOC)
  1567. X                free(vp->v_str);
  1568. X            break;
  1569. X        case V_NUM:
  1570. X            qfree(vp->v_num);
  1571. X            break;
  1572. X        case V_COM:
  1573. X            comfree(vp->v_com);
  1574. X            break;
  1575. X        case V_MAT:
  1576. X            matfree(vp->v_mat);
  1577. X            break;
  1578. X        case V_LIST:
  1579. X            listfree(vp->v_list);
  1580. X            break;
  1581. X        case V_ASSOC:
  1582. X            assocfree(vp->v_assoc);
  1583. X            break;
  1584. X        case V_OBJ:
  1585. X            objfree(vp->v_obj);
  1586. X            break;
  1587. X        default:
  1588. X            math_error("Freeing unknown value type");
  1589. X    }
  1590. X}
  1591. X
  1592. X
  1593. X/*
  1594. X * Copy a value from one location to another.
  1595. X * This overwrites the specified new value without checking it.
  1596. X */
  1597. Xvoid
  1598. Xcopyvalue(oldvp, newvp)
  1599. X    register VALUE *oldvp;        /* value to be copied from */
  1600. X    register VALUE *newvp;        /* value to be copied into */
  1601. X{
  1602. X    newvp->v_type = V_NULL;
  1603. X    switch (oldvp->v_type) {
  1604. X        case V_NULL:
  1605. X            break;
  1606. X        case V_FILE:
  1607. X            newvp->v_file = oldvp->v_file;
  1608. X            break;
  1609. X        case V_NUM:
  1610. X            newvp->v_num = qlink(oldvp->v_num);
  1611. X            break;
  1612. X        case V_COM:
  1613. X            newvp->v_com = clink(oldvp->v_com);
  1614. X            break;
  1615. X        case V_STR:
  1616. X            newvp->v_str = oldvp->v_str;
  1617. X            if (oldvp->v_subtype == V_STRALLOC) {
  1618. X                newvp->v_str = (char *)malloc(strlen(oldvp->v_str) + 1);
  1619. X                if (newvp->v_str == NULL)
  1620. X                    math_error("Cannot get memory for string copy");
  1621. X                strcpy(newvp->v_str, oldvp->v_str);
  1622. X            }
  1623. X            break;
  1624. X        case V_MAT:
  1625. X            newvp->v_mat = matcopy(oldvp->v_mat);
  1626. X            break;
  1627. X        case V_LIST:
  1628. X            newvp->v_list = listcopy(oldvp->v_list);
  1629. X            break;
  1630. X        case V_ASSOC:
  1631. X            newvp->v_assoc = assoccopy(oldvp->v_assoc);
  1632. X            break;
  1633. X        case V_ADDR:
  1634. X            newvp->v_addr = oldvp->v_addr;
  1635. X            break;
  1636. X        case V_OBJ:
  1637. X            newvp->v_obj = objcopy(oldvp->v_obj);
  1638. X            break;
  1639. X        default:
  1640. X            math_error("Copying unknown value type");
  1641. X    }
  1642. X    newvp->v_subtype = oldvp->v_subtype;
  1643. X    newvp->v_type = oldvp->v_type;
  1644. X
  1645. X}
  1646. X
  1647. X
  1648. X/*
  1649. X * Negate an arbitrary value.
  1650. X * Result is placed in the indicated location.
  1651. X */
  1652. Xvoid
  1653. Xnegvalue(vp, vres)
  1654. X    VALUE *vp, *vres;
  1655. X{
  1656. X    vres->v_type = V_NULL;
  1657. X    switch (vp->v_type) {
  1658. X        case V_NUM:
  1659. X            vres->v_num = qneg(vp->v_num);
  1660. X            vres->v_type = V_NUM;
  1661. X            return;
  1662. X        case V_COM:
  1663. X            vres->v_com = cneg(vp->v_com);
  1664. X            vres->v_type = V_COM;
  1665. X            return;
  1666. X        case V_MAT:
  1667. X            vres->v_mat = matneg(vp->v_mat);
  1668. X            vres->v_type = V_MAT;
  1669. X            return;
  1670. X        case V_OBJ:
  1671. X            *vres = objcall(OBJ_NEG, vp, NULL_VALUE, NULL_VALUE);
  1672. X            return;
  1673. X        default:
  1674. X            math_error("Illegal value for negation");
  1675. X    }
  1676. X}
  1677. X
  1678. X
  1679. X/*
  1680. X * Add two arbitrary values together.
  1681. X * Result is placed in the indicated location.
  1682. X */
  1683. Xvoid
  1684. Xaddvalue(v1, v2, vres)
  1685. X    VALUE *v1, *v2, *vres;
  1686. X{
  1687. X    COMPLEX *c;
  1688. X
  1689. X    vres->v_type = V_NULL;
  1690. X    switch (TWOVAL(v1->v_type, v2->v_type)) {
  1691. X        case TWOVAL(V_NUM, V_NUM):
  1692. X            vres->v_num = qadd(v1->v_num, v2->v_num);
  1693. X            vres->v_type = V_NUM;
  1694. X            return;
  1695. X        case TWOVAL(V_COM, V_NUM):
  1696. X            vres->v_com = caddq(v1->v_com, v2->v_num);
  1697. X            vres->v_type = V_COM;
  1698. X            return;
  1699. X        case TWOVAL(V_NUM, V_COM):
  1700. X            vres->v_com = caddq(v2->v_com, v1->v_num);
  1701. X            vres->v_type = V_COM;
  1702. X            return;
  1703. X        case TWOVAL(V_COM, V_COM):
  1704. X            vres->v_com = cadd(v1->v_com, v2->v_com);
  1705. X            vres->v_type = V_COM;
  1706. X            c = vres->v_com;
  1707. X            if (!cisreal(c))
  1708. X                return;
  1709. X            vres->v_num = qlink(c->real);
  1710. X            vres->v_type = V_NUM;
  1711. X            comfree(c);
  1712. X            return;
  1713. X        case TWOVAL(V_MAT, V_MAT):
  1714. X            vres->v_mat = matadd(v1->v_mat, v2->v_mat);
  1715. X            vres->v_type = V_MAT;
  1716. X            return;
  1717. X        default:
  1718. X            if ((v1->v_type != V_OBJ) && (v2->v_type != V_OBJ))
  1719. X                math_error("Non-compatible values for add");
  1720. X            *vres = objcall(OBJ_ADD, v1, v2, NULL_VALUE);
  1721. X            return;
  1722. X    }
  1723. X}
  1724. X
  1725. X
  1726. X/*
  1727. X * Subtract one arbitrary value from another one.
  1728. X * Result is placed in the indicated location.
  1729. X */
  1730. Xvoid
  1731. Xsubvalue(v1, v2, vres)
  1732. X    VALUE *v1, *v2, *vres;
  1733. X{
  1734. X    COMPLEX *c;
  1735. X
  1736. X    vres->v_type = V_NULL;
  1737. X    switch (TWOVAL(v1->v_type, v2->v_type)) {
  1738. X        case TWOVAL(V_NUM, V_NUM):
  1739. X            vres->v_num = qsub(v1->v_num, v2->v_num);
  1740. X            vres->v_type = V_NUM;
  1741. X            return;
  1742. X        case TWOVAL(V_COM, V_NUM):
  1743. X            vres->v_com = csubq(v1->v_com, v2->v_num);
  1744. X            vres->v_type = V_COM;
  1745. X            return;
  1746. X        case TWOVAL(V_NUM, V_COM):
  1747. X            c = csubq(v2->v_com, v1->v_num);
  1748. X            vres->v_com = cneg(c);
  1749. X            comfree(c);
  1750. X            vres->v_type = V_COM;
  1751. X            return;
  1752. X        case TWOVAL(V_COM, V_COM):
  1753. X            vres->v_com = csub(v1->v_com, v2->v_com);
  1754. X            vres->v_type = V_COM;
  1755. X            c = vres->v_com;
  1756. X            if (!cisreal(c))
  1757. X                return;
  1758. X            vres->v_num = qlink(c->real);
  1759. X            vres->v_type = V_NUM;
  1760. X            comfree(c);
  1761. X            return;
  1762. X        case TWOVAL(V_MAT, V_MAT):
  1763. X            vres->v_mat = matsub(v1->v_mat, v2->v_mat);
  1764. X            vres->v_type = V_MAT;
  1765. X            return;
  1766. X        default:
  1767. X            if ((v1->v_type != V_OBJ) && (v2->v_type != V_OBJ))
  1768. X                math_error("Non-compatible values for subtract");
  1769. X            *vres = objcall(OBJ_SUB, v1, v2, NULL_VALUE);
  1770. X            return;
  1771. X    }
  1772. X}
  1773. X
  1774. X
  1775. X/*
  1776. X * Multiply two arbitrary values together.
  1777. X * Result is placed in the indicated location.
  1778. X */
  1779. Xvoid
  1780. Xmulvalue(v1, v2, vres)
  1781. X    VALUE *v1, *v2, *vres;
  1782. X{
  1783. X    COMPLEX *c;
  1784. X
  1785. X    vres->v_type = V_NULL;
  1786. X    switch (TWOVAL(v1->v_type, v2->v_type)) {
  1787. X        case TWOVAL(V_NUM, V_NUM):
  1788. X            vres->v_num = qmul(v1->v_num, v2->v_num);
  1789. X            vres->v_type = V_NUM;
  1790. X            return;
  1791. X        case TWOVAL(V_COM, V_NUM):
  1792. X            vres->v_com = cmulq(v1->v_com, v2->v_num);
  1793. X            vres->v_type = V_COM;
  1794. X            break;
  1795. X        case TWOVAL(V_NUM, V_COM):
  1796. X            vres->v_com = cmulq(v2->v_com, v1->v_num);
  1797. X            vres->v_type = V_COM;
  1798. X            break;
  1799. X        case TWOVAL(V_COM, V_COM):
  1800. X            vres->v_com = cmul(v1->v_com, v2->v_com);
  1801. X            vres->v_type = V_COM;
  1802. X            break;
  1803. X        case TWOVAL(V_MAT, V_MAT):
  1804. X            vres->v_mat = matmul(v1->v_mat, v2->v_mat);
  1805. X            vres->v_type = V_MAT;
  1806. X            return;
  1807. X        case TWOVAL(V_MAT, V_NUM):
  1808. X        case TWOVAL(V_MAT, V_COM):
  1809. X            vres->v_mat = matmulval(v1->v_mat, v2);
  1810. X            vres->v_type = V_MAT;
  1811. X            return;
  1812. X        case TWOVAL(V_NUM, V_MAT):
  1813. X        case TWOVAL(V_COM, V_MAT):
  1814. X            vres->v_mat = matmulval(v2->v_mat, v1);
  1815. X            vres->v_type = V_MAT;
  1816. X            return;
  1817. X        default:
  1818. X            if ((v1->v_type != V_OBJ) && (v2->v_type != V_OBJ))
  1819. X                math_error("Non-compatible values for multiply");
  1820. X            *vres = objcall(OBJ_MUL, v1, v2, NULL_VALUE);
  1821. X            return;
  1822. X    }
  1823. X    c = vres->v_com;
  1824. X    if (cisreal(c)) {
  1825. X        vres->v_num = qlink(c->real);
  1826. X        vres->v_type = V_NUM;
  1827. X        comfree(c);
  1828. X    }
  1829. X}
  1830. X
  1831. X
  1832. X/*
  1833. X * Square an arbitrary value.
  1834. X * Result is placed in the indicated location.
  1835. X */
  1836. Xvoid
  1837. Xsquarevalue(vp, vres)
  1838. X    VALUE *vp, *vres;
  1839. X{
  1840. X    COMPLEX *c;
  1841. X
  1842. X    vres->v_type = V_NULL;
  1843. X    switch (vp->v_type) {
  1844. X        case V_NUM:
  1845. X            vres->v_num = qsquare(vp->v_num);
  1846. X            vres->v_type = V_NUM;
  1847. X            return;
  1848. X        case V_COM:
  1849. X            vres->v_com = csquare(vp->v_com);
  1850. X            vres->v_type = V_COM;
  1851. X            c = vres->v_com;
  1852. X            if (!cisreal(c))
  1853. X                return;
  1854. X            vres->v_num = qlink(c->real);
  1855. X            vres->v_type = V_NUM;
  1856. X            comfree(c);
  1857. X            return;
  1858. X        case V_MAT:
  1859. X            vres->v_mat = matsquare(vp->v_mat);
  1860. X            vres->v_type = V_MAT;
  1861. X            return;
  1862. X        case V_OBJ:
  1863. X            *vres = objcall(OBJ_SQUARE, vp, NULL_VALUE, NULL_VALUE);
  1864. X            return;
  1865. X        default:
  1866. X            math_error("Illegal value for squaring");
  1867. X    }
  1868. X}
  1869. X
  1870. X
  1871. X/*
  1872. X * Invert an arbitrary value.
  1873. X * Result is placed in the indicated location.
  1874. X */
  1875. Xvoid
  1876. Xinvertvalue(vp, vres)
  1877. X    VALUE *vp, *vres;
  1878. X{
  1879. X    vres->v_type = V_NULL;
  1880. X    switch (vp->v_type) {
  1881. X        case V_NUM:
  1882. X            vres->v_num = qinv(vp->v_num);
  1883. X            vres->v_type = V_NUM;
  1884. X            return;
  1885. X        case V_COM:
  1886. X            vres->v_com = cinv(vp->v_com);
  1887. X            vres->v_type = V_COM;
  1888. X            return;
  1889. X        case V_MAT:
  1890. X            vres->v_mat = matinv(vp->v_mat);
  1891. X            vres->v_type = V_MAT;
  1892. X            return;
  1893. X        case V_OBJ:
  1894. X            *vres = objcall(OBJ_INV, vp, NULL_VALUE, NULL_VALUE);
  1895. X            return;
  1896. X        default:
  1897. X            math_error("Illegal value for inverting");
  1898. X    }
  1899. X}
  1900. X
  1901. X
  1902. X/*
  1903. X * Round an arbitrary value to the specified number of decimal places.
  1904. X * Result is placed in the indicated location.
  1905. X */
  1906. Xvoid
  1907. Xroundvalue(v1, v2, vres)
  1908. X    VALUE *v1, *v2, *vres;
  1909. X{
  1910. X    long places;
  1911. X    NUMBER *q;
  1912. X    COMPLEX *c;
  1913. X
  1914. X    switch (v2->v_type) {
  1915. X        case V_NUM:
  1916. X            q = v2->v_num;
  1917. X            if (qisfrac(q) || zisbig(q->num))
  1918. X                math_error("Bad number of places for round");
  1919. X            places = qtoi(q);
  1920. X            break;
  1921. X        case V_INT:
  1922. X            places = v2->v_int;
  1923. X            break;
  1924. X        default:
  1925. X            math_error("Bad value type for places in round");
  1926. X    }
  1927. X    if (places < 0)
  1928. X        math_error("Negative number of places in round");
  1929. X    vres->v_type = V_NULL;
  1930. X    switch (v1->v_type) {
  1931. X        case V_NUM:
  1932. X            if (qisint(v1->v_num))
  1933. X                vres->v_num = qlink(v1->v_num);
  1934. X            else
  1935. X                vres->v_num = qround(v1->v_num, places);
  1936. X            vres->v_type = V_NUM;
  1937. X            return;
  1938. X        case V_COM:
  1939. X            if (cisint(v1->v_com)) {
  1940. X                vres->v_com = clink(v1->v_com);
  1941. X                vres->v_type = V_COM;
  1942. X                return;
  1943. X            }
  1944. X            vres->v_com = cround(v1->v_com, places);
  1945. X            vres->v_type = V_COM;
  1946. X            c = vres->v_com;
  1947. X            if (cisreal(c)) {
  1948. X                vres->v_num = qlink(c->real);
  1949. X                vres->v_type = V_NUM;
  1950. X                comfree(c);
  1951. X            }
  1952. X            return;
  1953. X        case V_MAT:
  1954. X            vres->v_mat = matround(v1->v_mat, places);
  1955. X            vres->v_type = V_MAT;
  1956. X            return;
  1957. X        case V_OBJ:
  1958. X            *vres = objcall(OBJ_ROUND, v1, v2, NULL_VALUE);
  1959. X            return;
  1960. X        default:
  1961. X            math_error("Illegal value for round");
  1962. X    }
  1963. X}
  1964. X
  1965. X
  1966. X/*
  1967. X * Round an arbitrary value to the specified number of binary places.
  1968. X * Result is placed in the indicated location.
  1969. X */
  1970. Xvoid
  1971. Xbroundvalue(v1, v2, vres)
  1972. X    VALUE *v1, *v2, *vres;
  1973. X{
  1974. X    long places;
  1975. X    NUMBER *q;
  1976. X    COMPLEX *c;
  1977. X
  1978. X    switch (v2->v_type) {
  1979. X        case V_NUM:
  1980. X            q = v2->v_num;
  1981. X            if (qisfrac(q) || zisbig(q->num))
  1982. X                math_error("Bad number of places for bround");
  1983. X            places = qtoi(q);
  1984. X            break;
  1985. X        case V_INT:
  1986. X            places = v2->v_int;
  1987. X            break;
  1988. X        default:
  1989. X            math_error("Bad value type for places in bround");
  1990. X    }
  1991. X    if (places < 0)
  1992. X        math_error("Negative number of places in bround");
  1993. X    vres->v_type = V_NULL;
  1994. X    switch (v1->v_type) {
  1995. X        case V_NUM:
  1996. X            if (qisint(v1->v_num))
  1997. X                vres->v_num = qlink(v1->v_num);
  1998. X            else
  1999. X                vres->v_num = qbround(v1->v_num, places);
  2000. X            vres->v_type = V_NUM;
  2001. X            return;
  2002. X        case V_COM:
  2003. X            if (cisint(v1->v_com)) {
  2004. X                vres->v_com = clink(v1->v_com);
  2005. X                vres->v_type = V_COM;
  2006. X                return;
  2007. X            }
  2008. X            vres->v_com = cbround(v1->v_com, places);
  2009. X            vres->v_type = V_COM;
  2010. X            c = vres->v_com;
  2011. X            if (cisreal(c)) {
  2012. X                vres->v_num = qlink(c->real);
  2013. X                vres->v_type = V_NUM;
  2014. X                comfree(c);
  2015. X            }
  2016. X            return;
  2017. X        case V_MAT:
  2018. X            vres->v_mat = matbround(v1->v_mat, places);
  2019. X            vres->v_type = V_MAT;
  2020. X            return;
  2021. X        case V_OBJ:
  2022. X            *vres = objcall(OBJ_BROUND, v1, v2, NULL_VALUE);
  2023. X            return;
  2024. X        default:
  2025. X            math_error("Illegal value for bround");
  2026. X    }
  2027. X}
  2028. X
  2029. X
  2030. X/*
  2031. X * Take the integer part of an arbitrary value.
  2032. X * Result is placed in the indicated location.
  2033. X */
  2034. Xvoid
  2035. Xintvalue(vp, vres)
  2036. X    VALUE *vp, *vres;
  2037. X{
  2038. X    COMPLEX *c;
  2039. X
  2040. X    vres->v_type = V_NULL;
  2041. X    switch (vp->v_type) {
  2042. X        case V_NUM:
  2043. X            if (qisint(vp->v_num))
  2044. X                vres->v_num = qlink(vp->v_num);
  2045. X            else
  2046. X                vres->v_num = qint(vp->v_num);
  2047. X            vres->v_type = V_NUM;
  2048. X            return;
  2049. X        case V_COM:
  2050. X            if (cisint(vp->v_com)) {
  2051. X                vres->v_com = clink(vp->v_com);
  2052. X                vres->v_type = V_COM;
  2053. X                return;
  2054. X            }
  2055. X            vres->v_com = cint(vp->v_com);
  2056. X            vres->v_type = V_COM;
  2057. X            c = vres->v_com;
  2058. X            if (cisreal(c)) {
  2059. X                vres->v_num = qlink(c->real);
  2060. X                vres->v_type = V_NUM;
  2061. X                comfree(c);
  2062. X            }
  2063. X            return;
  2064. X        case V_MAT:
  2065. X            vres->v_mat = matint(vp->v_mat);
  2066. X            vres->v_type = V_MAT;
  2067. X            return;
  2068. X        case V_OBJ:
  2069. X            *vres = objcall(OBJ_INT, vp, NULL_VALUE, NULL_VALUE);
  2070. X            return;
  2071. X        default:
  2072. X            math_error("Illegal value for int");
  2073. X    }
  2074. X}
  2075. X
  2076. X
  2077. X/*
  2078. X * Take the fractional part of an arbitrary value.
  2079. X * Result is placed in the indicated location.
  2080. X */
  2081. Xvoid
  2082. Xfracvalue(vp, vres)
  2083. X    VALUE *vp, *vres;
  2084. X{
  2085. X    vres->v_type = V_NULL;
  2086. X    switch (vp->v_type) {
  2087. X        case V_NUM:
  2088. X            if (qisint(vp->v_num))
  2089. X                vres->v_num = qlink(&_qzero_);
  2090. X            else
  2091. X                vres->v_num = qfrac(vp->v_num);
  2092. X            vres->v_type = V_NUM;
  2093. X            return;
  2094. X        case V_COM:
  2095. X            if (cisint(vp->v_com)) {
  2096. X                vres->v_num = clink(&_qzero_);
  2097. X                vres->v_type = V_NUM;
  2098. X                return;
  2099. X            }
  2100. X            vres->v_com = cfrac(vp->v_com);
  2101. X            vres->v_type = V_COM;
  2102. X            return;
  2103. X        case V_MAT:
  2104. X            vres->v_mat = matfrac(vp->v_mat);
  2105. X            vres->v_type = V_MAT;
  2106. X            return;
  2107. X        case V_OBJ:
  2108. X            *vres = objcall(OBJ_FRAC, vp, NULL_VALUE, NULL_VALUE);
  2109. X            return;
  2110. X        default:
  2111. X            math_error("Illegal value for frac function");
  2112. X    }
  2113. X}
  2114. X
  2115. X
  2116. X/*
  2117. X * Increment an arbitrary value by one.
  2118. X * Result is placed in the indicated location.
  2119. X */
  2120. Xvoid
  2121. Xincvalue(vp, vres)
  2122. X    VALUE *vp, *vres;
  2123. X{
  2124. X    switch (vp->v_type) {
  2125. X        case V_NUM:
  2126. X            vres->v_num = qinc(vp->v_num);
  2127. X            vres->v_type = V_NUM;
  2128. X            return;
  2129. X        case V_COM:
  2130. X            vres->v_com = caddq(vp->v_com, &_qone_);
  2131. X            vres->v_type = V_COM;
  2132. X            return;
  2133. X        case V_OBJ:
  2134. X            *vres = objcall(OBJ_INC, vp, NULL_VALUE, NULL_VALUE);
  2135. X            return;
  2136. X        default:
  2137. X            math_error("Illegal value for incrementing");
  2138. X    }
  2139. X}
  2140. X
  2141. X
  2142. X/*
  2143. X * Decrement an arbitrary value by one.
  2144. X * Result is placed in the indicated location.
  2145. X */
  2146. Xvoid
  2147. Xdecvalue(vp, vres)
  2148. X    VALUE *vp, *vres;
  2149. X{
  2150. X    switch (vp->v_type) {
  2151. X        case V_NUM:
  2152. X            vres->v_num = qdec(vp->v_num);
  2153. X            vres->v_type = V_NUM;
  2154. X            return;
  2155. X        case V_COM:
  2156. X            vres->v_com = caddq(vp->v_com, &_qnegone_);
  2157. X            vres->v_type = V_COM;
  2158. X            return;
  2159. X        case V_OBJ:
  2160. X            *vres = objcall(OBJ_DEC, vp, NULL_VALUE, NULL_VALUE);
  2161. X            return;
  2162. X        default:
  2163. X            math_error("Illegal value for decrementing");
  2164. X    }
  2165. X}
  2166. X
  2167. X
  2168. X/*
  2169. X * Produce the 'conjugate' of an arbitrary value.
  2170. X * Result is placed in the indicated location.
  2171. X * (Example: complex conjugate.)
  2172. X */
  2173. Xvoid
  2174. Xconjvalue(vp, vres)
  2175. X    VALUE *vp, *vres;
  2176. X{
  2177. X    vres->v_type = V_NULL;
  2178. X    switch (vp->v_type) {
  2179. X        case V_NUM:
  2180. X            vres->v_num = qlink(vp->v_num);
  2181. X            vres->v_type = V_NUM;
  2182. X            return;
  2183. X        case V_COM:
  2184. X            vres->v_com = comalloc();
  2185. X            vres->v_com->real = qlink(vp->v_com->real);
  2186. X            vres->v_com->imag = qneg(vp->v_com->imag);
  2187. X            vres->v_type = V_COM;
  2188. X            return;
  2189. X        case V_MAT:
  2190. X            vres->v_mat = matconj(vp->v_mat);
  2191. X            vres->v_type = V_MAT;
  2192. X            return;
  2193. X        case V_OBJ:
  2194. X            *vres = objcall(OBJ_CONJ, vp, NULL_VALUE, NULL_VALUE);
  2195. X            return;
  2196. X        default:
  2197. X            math_error("Illegal value for conjugation");
  2198. X    }
  2199. X}
  2200. X
  2201. X
  2202. X/*
  2203. X * Take the square root of an arbitrary value within the specified error.
  2204. X * Result is placed in the indicated location.
  2205. X */
  2206. Xvoid
  2207. Xsqrtvalue(v1, v2, vres)
  2208. X    VALUE *v1, *v2, *vres;
  2209. X{
  2210. X    NUMBER *q, *tmp;
  2211. X    COMPLEX *c;
  2212. X
  2213. X    if (v2->v_type != V_NUM)
  2214. X        math_error("Non-real epsilon for sqrt");
  2215. X    q = v2->v_num;
  2216. X    if (qisneg(q) || qiszero(q))
  2217. X        math_error("Illegal epsilon value for sqrt");
  2218. X    switch (v1->v_type) {
  2219. X        case V_NUM:
  2220. X            if (!qisneg(v1->v_num)) {
  2221. X                vres->v_num = qsqrt(v1->v_num, q);
  2222. X                vres->v_type = V_NUM;
  2223. X                return;
  2224. X            }
  2225. X            tmp = qneg(v1->v_num);
  2226. X            c = comalloc();
  2227. X            c->imag = qsqrt(tmp, q);
  2228. X            qfree(tmp);
  2229. X            vres->v_com = c;
  2230. X            vres->v_type = V_COM;
  2231. X            break;
  2232. X        case V_COM:
  2233. X            vres->v_com = csqrt(v1->v_com, q);
  2234. X            vres->v_type = V_COM;
  2235. X            break;
  2236. X        case V_OBJ:
  2237. X            *vres = objcall(OBJ_SQRT, v1, v2, NULL_VALUE);
  2238. X            return;
  2239. X        default:
  2240. X            math_error("Bad value for taking square root");
  2241. X    }
  2242. X    c = vres->v_com;
  2243. X    if (cisreal(c)) {
  2244. X        vres->v_num = qlink(c->real);
  2245. X        vres->v_type = V_NUM;
  2246. X        comfree(c);
  2247. X    }
  2248. X}
  2249. X
  2250. X
  2251. X/*
  2252. X * Take the Nth root of an arbitrary value within the specified error.
  2253. X * Result is placed in the indicated location.
  2254. X */
  2255. Xvoid
  2256. Xrootvalue(v1, v2, v3, vres)
  2257. X    VALUE *v1;        /* value to take root of */
  2258. X    VALUE *v2;        /* value specifying root to take */
  2259. X    VALUE *v3;        /* value specifying error */
  2260. X    VALUE *vres;
  2261. X{
  2262. X    NUMBER *q1, *q2;
  2263. X    COMPLEX ctmp;
  2264. X
  2265. X    if ((v2->v_type != V_NUM) || (v3->v_type != V_NUM))
  2266. X        math_error("Non-real arguments for root");
  2267. X    q1 = v2->v_num;
  2268. X    q2 = v3->v_num;
  2269. X    if (qisneg(q1) || qiszero(q1) || qisfrac(q1))
  2270. X        math_error("Non-positive or non-integral root");
  2271. X    if (qisneg(q2) || qiszero(q2))
  2272. X        math_error("Non-positive epsilon for root");
  2273. X    switch (v1->v_type) {
  2274. X        case V_NUM:
  2275. X            if (!qisneg(v1->v_num) || zisodd(q1->num)) {
  2276. X                vres->v_num = qroot(v1->v_num, q1, q2);
  2277. X                vres->v_type = V_NUM;
  2278. X                return;
  2279. X            }
  2280. X            ctmp.real = v1->v_num;
  2281. X            ctmp.imag = &_qzero_;
  2282. X            ctmp.links = 1;
  2283. X            vres->v_com = croot(&ctmp, q1, q2);
  2284. X            vres->v_type = V_COM;
  2285. X            return;
  2286. X        case V_COM:
  2287. X            vres->v_com = croot(v1->v_com, q1, q2);
  2288. X            vres->v_type = V_COM;
  2289. X            return;
  2290. X        case V_OBJ:
  2291. X            *vres = objcall(OBJ_ROOT, v1, v2, v3);
  2292. X            return;
  2293. X        default:
  2294. X            math_error("Taking root of bad value");
  2295. X    }
  2296. X}
  2297. X
  2298. X
  2299. X/*
  2300. X * Take the absolute value of an arbitrary value within the specified error.
  2301. X * Result is placed in the indicated location.
  2302. X */
  2303. Xvoid
  2304. Xabsvalue(v1, v2, vres)
  2305. X    VALUE *v1, *v2, *vres;
  2306. X{
  2307. X    NUMBER *q, *epsilon;
  2308. X
  2309. X    if (v2->v_type != V_NUM)
  2310. X        math_error("Bad epsilon type for abs");
  2311. X    epsilon = v2->v_num;
  2312. X    if (qiszero(epsilon) || qisneg(epsilon))
  2313. X        math_error("Non-positive epsilon for abs");
  2314. X    switch (v1->v_type) {
  2315. X        case V_NUM:
  2316. X            if (qisneg(v1->v_num))
  2317. X                q = qneg(v1->v_num);
  2318. X            else
  2319. X                q = qlink(v1->v_num);
  2320. X            break;
  2321. X        case V_COM:
  2322. X            q = qhypot(v1->v_com->real, v1->v_com->imag, epsilon);
  2323. X            break;
  2324. X        case V_OBJ:
  2325. X            *vres = objcall(OBJ_ABS, v1, v2, NULL_VALUE);
  2326. X            return;
  2327. X        default:
  2328. X            math_error("Illegal value for absolute value");
  2329. X    }
  2330. X    vres->v_num = q;
  2331. X    vres->v_type = V_NUM;
  2332. X}
  2333. X
  2334. X
  2335. X/*
  2336. X * Calculate the norm of an arbitrary value.
  2337. X * Result is placed in the indicated location.
  2338. X * The norm is the square of the absolute value.
  2339. X */
  2340. Xvoid
  2341. Xnormvalue(vp, vres)
  2342. X    VALUE *vp, *vres;
  2343. X{
  2344. X    NUMBER *q1, *q2;
  2345. X
  2346. X    vres->v_type = V_NULL;
  2347. X    switch (vp->v_type) {
  2348. X        case V_NUM:
  2349. X            vres->v_num = qsquare(vp->v_num);
  2350. X            vres->v_type = V_NUM;
  2351. X            return;
  2352. X        case V_COM:
  2353. X            q1 = qsquare(vp->v_com->real);
  2354. X            q2 = qsquare(vp->v_com->imag);
  2355. X            vres->v_num = qadd(q1, q2);
  2356. X            vres->v_type = V_NUM;
  2357. X            qfree(q1);
  2358. X            qfree(q2);
  2359. X            return;
  2360. X        case V_OBJ:
  2361. X            *vres = objcall(OBJ_NORM, vp, NULL_VALUE, NULL_VALUE);
  2362. X            return;
  2363. X        default:
  2364. X            math_error("Illegal value for norm");
  2365. X    }
  2366. X}
  2367. X
  2368. X
  2369. X/*
  2370. X * Shift a value left or right by the specified number of bits.
  2371. X * Negative shift value means shift the direction opposite the selected dir.
  2372. X * Right shifts are defined to lose bits off the low end of the number.
  2373. X * Result is placed in the indicated location.
  2374. X */
  2375. Xvoid
  2376. Xshiftvalue(v1, v2, rightshift, vres)
  2377. X    VALUE *v1, *v2, *vres;
  2378. X    BOOL rightshift;    /* TRUE if shift right instead of left */
  2379. X{
  2380. X    COMPLEX *c;
  2381. X    long n;
  2382. X    VALUE tmp;
  2383. X
  2384. X    if (v2->v_type != V_NUM)
  2385. X        math_error("Non-real shift value");
  2386. X     if (qisfrac(v2->v_num))
  2387. X        math_error("Non-integral shift value");
  2388. X    if (v1->v_type != V_OBJ) {
  2389. X        if (zisbig(v2->v_num->num))
  2390. X            math_error("Very large shift value");
  2391. X        n = qtoi(v2->v_num);
  2392. X    }
  2393. X    if (rightshift)
  2394. X        n = -n;
  2395. X    switch (v1->v_type) {
  2396. X        case V_NUM:
  2397. X            vres->v_num = qshift(v1->v_num, n);
  2398. X            vres->v_type = V_NUM;
  2399. X            return;
  2400. X        case V_COM:
  2401. X            c = cshift(v1->v_com, n);
  2402. X            if (!cisreal(c)) {
  2403. X                vres->v_com = c;
  2404. X                vres->v_type = V_COM;
  2405. X                return;
  2406. X            }
  2407. X            vres->v_num = qlink(c->real);
  2408. X            vres->v_type = V_NUM;
  2409. X            comfree(c);
  2410. X            return;
  2411. X        case V_MAT:
  2412. X            vres->v_mat = matshift(v1->v_mat, n);
  2413. X            vres->v_type = V_MAT;
  2414. X            return;
  2415. X        case V_OBJ:
  2416. X            if (!rightshift) {
  2417. X                *vres = objcall(OBJ_SHIFT, v1, v2, NULL_VALUE);
  2418. X                return;
  2419. X            }
  2420. X            tmp.v_num = qneg(v2->v_num);
  2421. X            tmp.v_type = V_NUM;
  2422. X            *vres = objcall(OBJ_SHIFT, v1, &tmp, NULL_VALUE);
  2423. X            qfree(tmp.v_num);
  2424. X            return;
  2425. X        default:
  2426. X            math_error("Bad value for shifting");
  2427. X    }
  2428. X}
  2429. X
  2430. X
  2431. X/*
  2432. X * Scale a value by a power of two.
  2433. X * Result is placed in the indicated location.
  2434. X */
  2435. Xvoid
  2436. Xscalevalue(v1, v2, vres)
  2437. X    VALUE *v1, *v2, *vres;
  2438. X{
  2439. X    long n;
  2440. X
  2441. X    if (v2->v_type != V_NUM)
  2442. X        math_error("Non-real scaling factor");
  2443. X    if (qisfrac(v2->v_num))
  2444. X        math_error("Non-integral scaling factor");
  2445. X    if (v1->v_type != V_OBJ) {
  2446. X        if (zisbig(v2->v_num->num))
  2447. X            math_error("Very large scaling factor");
  2448. X        n = qtoi(v2->v_num);
  2449. X    }
  2450. X    switch (v1->v_type) {
  2451. X        case V_NUM:
  2452. X            vres->v_num = qscale(v1->v_num, n);
  2453. X            vres->v_type = V_NUM;
  2454. X            return;
  2455. X        case V_COM:
  2456. X            vres->v_com = cscale(v1->v_com, n);
  2457. X            vres->v_type = V_NUM;
  2458. X            return;
  2459. X        case V_MAT:
  2460. X            vres->v_mat = matscale(v1->v_mat, n);
  2461. X            vres->v_type = V_MAT;
  2462. X            return;
  2463. X        case V_OBJ:
  2464. X            *vres = objcall(OBJ_SCALE, v1, v2, NULL_VALUE);
  2465. X            return;
  2466. X        default:
  2467. X            math_error("Bad value for scaling");
  2468. X    }
  2469. X}
  2470. X
  2471. X
  2472. X/*
  2473. X * Raise a value to an integral power.
  2474. X * Result is placed in the indicated location.
  2475. X */
  2476. Xvoid
  2477. Xpowivalue(v1, v2, vres)
  2478. X    VALUE *v1, *v2, *vres;
  2479. X{
  2480. X    NUMBER *q;
  2481. X    COMPLEX *c;
  2482. X
  2483. X    vres->v_type = V_NULL;
  2484. X    if (v2->v_type != V_NUM)
  2485. X        math_error("Raising value to non-real power");
  2486. X    q = v2->v_num;
  2487. X    if (qisfrac(q))
  2488. X        math_error("Raising value to non-integral power");
  2489. X    switch (v1->v_type) {
  2490. X        case V_NUM:
  2491. X            vres->v_num = qpowi(v1->v_num, q);
  2492. X            vres->v_type = V_NUM;
  2493. X            return;
  2494. X        case V_COM:
  2495. X            vres->v_com = cpowi(v1->v_com, q);
  2496. X            vres->v_type = V_COM;
  2497. X            c = vres->v_com;
  2498. X            if (!cisreal(c))
  2499. X                return;
  2500. X            vres->v_num = qlink(c->real);
  2501. X            vres->v_type = V_NUM;
  2502. X            comfree(c);
  2503. X            return;
  2504. X        case V_MAT:
  2505. X            vres->v_mat = matpowi(v1->v_mat, q);
  2506. X            vres->v_type = V_MAT;
  2507. X            return;
  2508. X        case V_OBJ:
  2509. X            *vres = objcall(OBJ_POW, v1, v2, NULL_VALUE);
  2510. X            return;
  2511. X        default:
  2512. X            math_error("Illegal value for raising to integer power");
  2513. X    }
  2514. X}
  2515. X
  2516. X
  2517. X/*
  2518. SHAR_EOF
  2519. echo "End of part 10"
  2520. echo "File calc2.9.0/value.c is continued in part 11"
  2521. echo "11" > s2_seq_.tmp
  2522. exit 0
  2523.