home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / unix / volume26 / calc / part03 < prev    next >
Encoding:
Text File  |  1992-05-09  |  51.3 KB  |  1,847 lines

  1. Newsgroups: comp.sources.unix
  2. From: dbell@pdact.pd.necisa.oz.au (David I. Bell)
  3. Subject: v26i029: CALC - An arbitrary precision C-like calculator, Part03/21
  4. Sender: unix-sources-moderator@pa.dec.com
  5. Approved: vixie@pa.dec.com
  6.  
  7. Submitted-By: dbell@pdact.pd.necisa.oz.au (David I. Bell)
  8. Posting-Number: Volume 26, Issue 29
  9. Archive-Name: calc/part03
  10.  
  11. #! /bin/sh
  12. # This is a shell archive.  Remove anything before this line, then unpack
  13. # it by saving it into a file and typing "sh file".  To overwrite existing
  14. # files, type "sh file -c".  You can also feed this as standard input via
  15. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  16. # will see the following message at the end:
  17. #        "End of archive 3 (of 21)."
  18. # Contents:  calc.1 config.c help/obj lib/ellip.cal lib/surd.cal
  19. #   opcodes.h string.c token.h
  20. # Wrapped by dbell@elm on Tue Feb 25 15:20:56 1992
  21. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  22. if test -f 'calc.1' -a "${1}" != "-c" ; then 
  23.   echo shar: Will not clobber existing file \"'calc.1'\"
  24. else
  25. echo shar: Extracting \"'calc.1'\" \(6494 characters\)
  26. sed "s/^X//" >'calc.1' <<'END_OF_FILE'
  27. X.\"
  28. X.\" Copyright (c) 1992 David I. Bell and Landon Curt Noll
  29. X.\" Permission is granted to use, distribute, or modify this source,
  30. X.\" provided that this copyright notice remains intact.
  31. X.\"
  32. X.\" calculator by David I. Bell
  33. X.\" man page by Landon Noll
  34. X.TH calc 1 "^..^" "22jun91"
  35. X.SH NAME
  36. X\f4calc\f1 \- arbitrary precision calculator
  37. X.SH SYNOPSIS
  38. X\f4calc\fP
  39. X[
  40. X\f4\-h\fP
  41. X] [
  42. X\f4\-q\fP
  43. X] [
  44. X.I calc_cmd
  45. X\&.\|.\|.
  46. X]
  47. X.SH DESCRIPTION
  48. X\&
  49. X.br
  50. XCALC COMMAND LINE
  51. X.PP
  52. X.TP
  53. X\f4 \-h\f1
  54. XPrint a help message.
  55. XThis option implies \f4 \-q\f1.
  56. XThis is equivalent to the calc command \f4help help\fP.
  57. X.TP
  58. X\f4 \-q\f1
  59. XDisable the use of the \f4$CALCRC\f1 startup library scripts.
  60. X.PP
  61. XWithout \f4calc_cmd\fPs, \f4calc\fP operates interactively.
  62. XIf one or more \f4calc_cmd\fPs are given on the command line,
  63. X\f4calc\fP will execute them and exit.
  64. X.PP
  65. XNormally on startup, \f4calc\fP attempts to execute a collection 
  66. Xof library scripts.
  67. XThe environment variable \f4$CALCRC\f1 (if non-existent then
  68. Xa compiled in value) contains a \f4:\fP separated list of
  69. Xstartup library scripts.
  70. XNo error conditions are produced if these startup library scripts
  71. Xare not found.
  72. X.PP
  73. XFilenames are subject to ``~'' expansion (see below).
  74. XThe environment variable \f4$CALCPATH\fP (if non-existent then
  75. Xa compiled in value) contains a \f4:\fP separated list of search
  76. Xdirectories.
  77. XIf a file does not begin with \f4/\fP, \f4~\fP or \f4./\fP,
  78. Xthen it is searched for under each directory listed in the \f4$CALCPATH\fP.
  79. XIt is an error if no such readable file is found.
  80. X.PP
  81. XFor more information use the following calc commands:
  82. X.PP
  83. X.in 1.0i
  84. Xhelp usage
  85. X.br
  86. Xhelp help
  87. X.br
  88. Xhelp environment
  89. X.in -1.0i
  90. X.PP
  91. XOVERVIEW
  92. X.PP
  93. X\f4Calc\fP is arbitrary precision arithmetic system that uses 
  94. Xa C-like language.
  95. X\f4Calc\fP is useful as a calculator, an algorithm prototyped
  96. Xand as a mathematical research tool.
  97. XMore importantly, \f4calc\fP provides one with a machine
  98. Xindependent means of computation.
  99. X.PP
  100. XA rich set of builtin functions is provided.
  101. XA number of library scripts are also provided because they are
  102. Xuseful and to serve as examples of the \f4calc\fP language.
  103. X.PP
  104. XOne may further extend \f4calc\fP permits further thru to
  105. Xuse of calc library scripts.
  106. XWritten in the same C-like language, library scripts may be
  107. Xread in and executed during a \f4calc\fP session.
  108. X.PP
  109. XInternally calc represents numeric values as fractions reduced to their
  110. Xlowest terms.
  111. XThe numerators and denominators of these factions may grow to
  112. Xarbitrarily large values.
  113. XNumeric values read in are automatically converted into rationals.
  114. XThe user need not be aware of this internal representation.
  115. X.PP
  116. XFor more information use the following calc commands:
  117. X.PP
  118. X.in 1.0i
  119. Xhelp intro
  120. X.br
  121. Xhelp builtin
  122. X.br
  123. Xhelp stdlib
  124. X.br
  125. Xhelp define
  126. X.br
  127. Xshow builtins
  128. X.br
  129. Xshow functions
  130. X.in -1.0i
  131. X.PP
  132. XDATA TYPES
  133. X.PP
  134. XFundamental builtin data types include integers, real numbers, 
  135. Xrational numbers, complex numbers and strings.
  136. X.PP
  137. XBy use of an object, one may define an arbitrarily complex
  138. Xdata types.
  139. XOne may define how such objects behave a wide range of
  140. Xoperations such as addition, subtraction,
  141. Xmultiplication, division, negation, squaring, modulus,
  142. Xrounding, exponentiation, equality, comparison, printing
  143. Xand so on.
  144. X.PP
  145. XFor more information use the following calc commands:
  146. X.PP
  147. X.in 1.0i
  148. Xhelp types
  149. X.br
  150. Xhelp obj
  151. X.br
  152. Xshow objfuncs
  153. X.in -1.0i
  154. X.PP
  155. XVARIABLES
  156. X.PP
  157. XVariables in \f4calc\fP are typeless.
  158. XIn other words, the fundamental type of a variable is determined by its content.
  159. XBefore variable is assigned a value is of type ``null''.
  160. X.PP
  161. XThe scope of a variable may be global, or only a local to a procedure.
  162. XValues may be grouped together in a matrix, or into a
  163. Xa list that permits stack and queue style operations.
  164. X.PP
  165. XFor more information use the following calc commands:
  166. X.PP
  167. X.in 1.0i
  168. Xhelp variable
  169. X.br
  170. Xhelp mat
  171. X.br
  172. Xhelp list
  173. X.br
  174. Xshow globals
  175. X.in -1.0i
  176. X.PP
  177. XINPUT/OUTPUT
  178. X.PP
  179. XA leading ``0x'' implies a hexadecimal value,
  180. Xa leading ``0b'' implies a binary value,
  181. Xand a ``0'' followed by a digit implies an octal value.
  182. XComplex numbers are indicated by a trailing ``i'' such as in ``3+4i''.
  183. XStrings may be delimited by either a pair of single or double quotes.
  184. XBy default, \f4calc\fP prints values as if they were floating point numbers.
  185. XOne may change the default to print values in a number of modes
  186. Xincluding fractions, integers and exponentials.
  187. X.PP
  188. XA number of stdio-like file I/O operations are provided.
  189. XOne may open, read, write, seek and close files.
  190. XFilenames are subject to ``\~'' expansion to home directories
  191. Xin a way similar to that of the Korn or C-Shell.
  192. X.PP
  193. XFor example:
  194. X.PP
  195. X.in 1.0i
  196. X~/.calcrc
  197. X.br
  198. X~chongo/lib/fft_multiply.cal
  199. X.in -1.0i
  200. X.PP
  201. XFor more information use the following calc command:
  202. X.PP
  203. X.in 1.0i
  204. Xhelp file
  205. X.in -1.0i
  206. X.PP
  207. XCALC LANGUAGE
  208. X.PP
  209. XThe \f4calc\fP language is a C-like language.
  210. XThe language includes commands such as variable declarations, 
  211. Xexpressions, tests, labels, loops, file operations, function calls.
  212. XThese commands are very similar to their counterparts in C.
  213. X.PP
  214. XThe language also include a number of commands particular
  215. Xto \f4calc\fP itself.
  216. XThese include commands such as function definition, help, 
  217. Xreading in library scripts, dump files to a file, error notification, 
  218. Xconfiguration control and status.
  219. X.PP
  220. XFor more information use the following calc command:
  221. X.PP
  222. X.in 1.0i
  223. Xhelp command
  224. X.br
  225. Xhelp statement
  226. X.br
  227. Xhelp expression
  228. X.br
  229. Xhelp operator
  230. X.br
  231. Xhelp config
  232. X.in -1.0i
  233. X.PP
  234. X.SH FILES
  235. X.PD 0
  236. X.TP 20
  237. X${LIBDIR}
  238. Xlibrary scripts shipped with calc
  239. X.br
  240. X.sp
  241. X.TP 20
  242. X${LIBDIR}/help
  243. Xhelp files
  244. X.br
  245. X.sp
  246. XTypically ${LIBDIR} is /usr/local/lib/calc
  247. X.sp
  248. X.SH CREDIT
  249. XWritten by David I. Bell.
  250. X.sp
  251. XThanks for suggestions and encouragement from Peter Miller,
  252. XNeil Justusson, and Landon Noll.
  253. X.sp
  254. XPortions of this program are derived from an earlier set of
  255. Xpublic domain arbitrarily precision routines which was posted
  256. Xto the net around 1984.  By now, there is almost no recognizable 
  257. Xcode left from that original source.
  258. X.sp
  259. XMost of this source and binary is:
  260. X.sp
  261. X.PP
  262. X.in 1.0i
  263. XCopyright (c) 1992 David I. Bell
  264. X.sp
  265. X.in -1.0i
  266. X.PP
  267. XSome files are a copyrighted David I. Bell and Landon Noll.
  268. X.sp
  269. XPermission is granted to use, distribute, or modify this source,
  270. Xprovided that this copyright notice remains intact.
  271. X.sp
  272. XSend calc comments, suggestions, bug fixes, enhancements
  273. Xand interesting calc scripts that you would like you see included 
  274. Xin future distributions to:
  275. X.sp
  276. X.PP
  277. X.in 1.0i
  278. Xdbell@pdact.pd.necisa.oz.au\ \ and\ \ chongo@toad.com
  279. X.sp
  280. X.in -1.0i
  281. X.PP
  282. X.sp
  283. XEnjoy!
  284. END_OF_FILE
  285. if test 6494 -ne `wc -c <'calc.1'`; then
  286.     echo shar: \"'calc.1'\" unpacked with wrong size!
  287. fi
  288. # end of 'calc.1'
  289. fi
  290. if test -f 'config.c' -a "${1}" != "-c" ; then 
  291.   echo shar: Will not clobber existing file \"'config.c'\"
  292. else
  293. echo shar: Extracting \"'config.c'\" \(5811 characters\)
  294. sed "s/^X//" >'config.c' <<'END_OF_FILE'
  295. X/*
  296. X * Copyright (c) 1992 David I. Bell
  297. X * Permission is granted to use, distribute, or modify this source,
  298. X * provided that this copyright notice remains intact.
  299. X *
  300. X * Configuration routines.
  301. X */
  302. X
  303. X#include "calc.h"
  304. X
  305. X
  306. X/*
  307. X * Configuration parameter name and type.
  308. X */
  309. Xtypedef struct {
  310. X    char *name;    /* name of configuration string */
  311. X    int type;    /* type for configuration */
  312. X} CONFIG;
  313. X
  314. X
  315. X/*
  316. X * Table of configuration types that can be set or read.
  317. X */
  318. Xstatic CONFIG configs[] = {
  319. X    "trace",    CONFIG_TRACE,
  320. X    "display",    CONFIG_DISPLAY,
  321. X    "epsilon",    CONFIG_EPSILON,
  322. X    "mode",        CONFIG_MODE,
  323. X    "maxprint",    CONFIG_MAXPRINT,
  324. X    "mul2",        CONFIG_MUL2,
  325. X    "sq2",        CONFIG_SQ2,
  326. X    "pow2",        CONFIG_POW2,
  327. X    "redc2",    CONFIG_REDC2,
  328. X    NULL,        0
  329. X};
  330. X
  331. X
  332. X/*
  333. X * Possible output modes.
  334. X */
  335. Xstatic CONFIG modes[] = {
  336. X    "frac",        MODE_FRAC,
  337. X    "decimal",    MODE_FRAC,
  338. X    "dec",        MODE_FRAC,
  339. X    "int",        MODE_INT,
  340. X    "real",        MODE_REAL,
  341. X    "exp",        MODE_EXP,
  342. X    "hexadecimal",    MODE_HEX,
  343. X    "hex",        MODE_HEX,
  344. X    "octal",    MODE_OCTAL,
  345. X    "oct",        MODE_OCTAL,
  346. X    "binary",    MODE_BINARY,
  347. X    "bin",        MODE_BINARY,
  348. X    NULL,        0
  349. X};
  350. X
  351. X
  352. X/*
  353. X * Given a string value which represents a configuration name, return
  354. X * the configuration type for that string.  Returns negative type if
  355. X * the string is unknown.
  356. X */
  357. Xconfigtype(name)
  358. X    char *name;        /* configuration name */
  359. X{
  360. X    CONFIG *cp;        /* current config pointer */
  361. X
  362. X    for (cp = configs; cp->name; cp++) {
  363. X        if (strcmp(cp->name, name) == 0)
  364. X            return cp->type;
  365. X    }
  366. X    return -1;
  367. X}
  368. X
  369. X
  370. X/*
  371. X * Given the name of a mode, convert it to the internal format.
  372. X * Returns -1 if the string is unknown.
  373. X */
  374. Xstatic
  375. Xmodetype(name)
  376. X    char *name;        /* mode name */
  377. X{
  378. X    CONFIG *cp;        /* current config pointer */
  379. X
  380. X    for (cp = modes; cp->name; cp++) {
  381. X        if (strcmp(cp->name, name) == 0)
  382. X            return cp->type;
  383. X    }
  384. X    return -1;
  385. X}
  386. X
  387. X
  388. X/*
  389. X * Given the mode type, convert it to a string representing that mode.
  390. X * Where there are multiple strings representing the same mode, the first
  391. X * one in the table is used.  Returns NULL if the node type is unknown.
  392. X * The returned string cannot be modified.
  393. X */
  394. Xstatic char *
  395. Xmodename(type)
  396. X{
  397. X    CONFIG *cp;        /* current config pointer */
  398. X
  399. X    for (cp = modes; cp->name; cp++) {
  400. X        if (type == cp->type)
  401. X            return cp->name;
  402. X    }
  403. X    return NULL;
  404. X}
  405. X
  406. X
  407. X/*
  408. X * Set the specified configuration type to the specified value.
  409. X * An error is generated if the type number or value is illegal.
  410. X */
  411. Xvoid
  412. Xsetconfig(type, vp)
  413. X    VALUE *vp;
  414. X{
  415. X    NUMBER *q;
  416. X    long temp;
  417. X
  418. X    switch (type) {
  419. X        case CONFIG_TRACE:
  420. X            if (vp->v_type != V_NUM)
  421. X                error("Non-numeric for trace");
  422. X            q = vp->v_num;
  423. X            temp = qtoi(q);
  424. X            if (qisfrac(q) || !istiny(q->num) ||
  425. X                ((unsigned long) temp > TRACE_MAX))
  426. X                    error("Bad trace value");
  427. X            traceflags = (FLAG)temp;
  428. X            break;
  429. X
  430. X        case CONFIG_DISPLAY:
  431. X            if (vp->v_type != V_NUM)
  432. X                error("Non-numeric for display");
  433. X            q = vp->v_num;
  434. X            temp = qtoi(q);
  435. X            if (qisfrac(q) || qisneg(q) || !istiny(q->num))
  436. X                temp = -1;
  437. X            setdigits(temp);
  438. X            break;
  439. X
  440. X        case CONFIG_MODE:
  441. X            if (vp->v_type != V_STR)
  442. X                error("Non-string for mode");
  443. X            temp = modetype(vp->v_str);
  444. X            if (temp < 0)
  445. X                error("Unknown mode \"%s\"", vp->v_str);
  446. X            setmode((int) temp);
  447. X            break;
  448. X
  449. X        case CONFIG_EPSILON:
  450. X            if (vp->v_type != V_NUM)
  451. X                error("Non-numeric for epsilon");
  452. X            setepsilon(vp->v_num);
  453. X            break;
  454. X
  455. X        case CONFIG_MAXPRINT:
  456. X            if (vp->v_type != V_NUM)
  457. X                error("Non-numeric for maxprint");
  458. X            q = vp->v_num;
  459. X            temp = qtoi(q);
  460. X            if (qisfrac(q) || qisneg(q) || !istiny(q->num))
  461. X                temp = -1;
  462. X            if (temp < 0)
  463. X                error("Maxprint value is out of range");
  464. X            maxprint = temp;
  465. X            break;
  466. X
  467. X        case CONFIG_MUL2:
  468. X            if (vp->v_type != V_NUM)
  469. X                error("Non-numeric for mul2");
  470. X            q = vp->v_num;
  471. X            temp = qtoi(q);
  472. X            if (qisfrac(q) || qisneg(q))
  473. X                temp = -1;
  474. X            if (temp == 0)
  475. X                temp = MUL_ALG2;
  476. X            if (temp < 2)
  477. X                error("Illegal mul2 value");
  478. X            _mul2_ = temp;
  479. X            break;
  480. X
  481. X        case CONFIG_SQ2:
  482. X            if (vp->v_type != V_NUM)
  483. X                error("Non-numeric for sq2");
  484. X            q = vp->v_num;
  485. X            temp = qtoi(q);
  486. X            if (qisfrac(q) || qisneg(q))
  487. X                temp = -1;
  488. X            if (temp == 0)
  489. X                temp = SQ_ALG2;
  490. X            if (temp < 2)
  491. X                error("Illegal sq2 value");
  492. X            _sq2_ = temp;
  493. X            break;
  494. X
  495. X        case CONFIG_POW2:
  496. X            if (vp->v_type != V_NUM)
  497. X                error("Non-numeric for pow2");
  498. X            q = vp->v_num;
  499. X            temp = qtoi(q);
  500. X            if (qisfrac(q) || qisneg(q))
  501. X                temp = -1;
  502. X            if (temp == 0)
  503. X                temp = POW_ALG2;
  504. X            if (temp < 1)
  505. X                error("Illegal pow2 value");
  506. X            _pow2_ = temp;
  507. X            break;
  508. X
  509. X        case CONFIG_REDC2:
  510. X            if (vp->v_type != V_NUM)
  511. X                error("Non-numeric for redc2");
  512. X            q = vp->v_num;
  513. X            temp = qtoi(q);
  514. X            if (qisfrac(q) || qisneg(q))
  515. X                temp = -1;
  516. X            if (temp == 0)
  517. X                temp = REDC_ALG2;
  518. X            if (temp < 1)
  519. X                error("Illegal redc2 value");
  520. X            _redc2_ = temp;
  521. X            break;
  522. X
  523. X        default:
  524. X            error("Setting illegal config parameter");
  525. X    }
  526. X}
  527. X
  528. X
  529. X/*
  530. X * Get the current value of the specified configuration type.
  531. X * An error is generated if the type number is illegal.
  532. X */
  533. Xvoid
  534. Xgetconfig(type, vp)
  535. X    VALUE *vp;
  536. X{
  537. X    switch (type) {
  538. X        case CONFIG_TRACE:
  539. X            vp->v_type = V_NUM;
  540. X            vp->v_num = itoq((long) traceflags);
  541. X            break;
  542. X
  543. X        case CONFIG_DISPLAY:
  544. X            vp->v_type = V_NUM;
  545. X            vp->v_num = itoq(_outdigits_);
  546. X            break;
  547. X
  548. X        case CONFIG_MODE:
  549. X            vp->v_type = V_STR;
  550. X            vp->v_subtype = V_STRLITERAL;
  551. X            vp->v_str = modename(_outmode_);
  552. X            break;
  553. X
  554. X        case CONFIG_EPSILON:
  555. X            vp->v_type = V_NUM;
  556. X            vp->v_num = qlink(_epsilon_);
  557. X            break;
  558. X
  559. X        case CONFIG_MAXPRINT:
  560. X            vp->v_type = V_NUM;
  561. X            vp->v_num = itoq(maxprint);
  562. X            break;
  563. X
  564. X        case CONFIG_MUL2:
  565. X            vp->v_type = V_NUM;
  566. X            vp->v_num = itoq(_mul2_);
  567. X            break;
  568. X
  569. X        case CONFIG_SQ2:
  570. X            vp->v_type = V_NUM;
  571. X            vp->v_num = itoq(_sq2_);
  572. X            break;
  573. X
  574. X        case CONFIG_POW2:
  575. X            vp->v_type = V_NUM;
  576. X            vp->v_num = itoq(_pow2_);
  577. X            break;
  578. X
  579. X        case CONFIG_REDC2:
  580. X            vp->v_type = V_NUM;
  581. X            vp->v_num = itoq(_redc2_);
  582. X            break;
  583. X
  584. X        default:
  585. X            error("Getting illegal config parameter");
  586. X    }
  587. X}
  588. X
  589. X/* END CODE */
  590. END_OF_FILE
  591. if test 5811 -ne `wc -c <'config.c'`; then
  592.     echo shar: \"'config.c'\" unpacked with wrong size!
  593. fi
  594. # end of 'config.c'
  595. fi
  596. if test -f 'help/obj' -a "${1}" != "-c" ; then 
  597.   echo shar: Will not clobber existing file \"'help/obj'\"
  598. else
  599. echo shar: Extracting \"'help/obj'\" \(6682 characters\)
  600. sed "s/^X//" >'help/obj' <<'END_OF_FILE'
  601. XUsing objects
  602. X
  603. X    Objects are user-defined types which are associated with user-
  604. X    defined functions to manipulate them.  Object types are defined
  605. X    similarly to structures in C, and consist of one or more elements.
  606. X    The advantage of an object is that the user-defined routines are
  607. X    automatically called by the calculator for various operations,
  608. X    such as addition, multiplication, and printing.  Thus they can be
  609. X    manipulated by the user as if they were just another kind of number.
  610. X
  611. X    An example object type is "surd", which represents numbers of the form
  612. X
  613. X        a + b*sqrt(D),
  614. X
  615. X    where D is a fixed integer, and 'a' and 'b' are arbitrary rational
  616. X    numbers.  Addition, subtraction, multiplication, and division can be
  617. X    performed on such numbers, and the result can be put unambiguously
  618. X    into the same form.  (Complex numbers are an example of surds, where
  619. X    D is -1.)
  620. X
  621. X    The "obj" statement defines either an object type or an actual
  622. X    variable of that type.  When defining the object type, the names of
  623. X    its elements are specified inside of a pair of braces.  To define
  624. X    the surd object type, the following could be used:
  625. X
  626. X        obj surd {a, b};
  627. X
  628. X    Here a and b are the element names for the two components of the
  629. X    surd object.
  630. X
  631. X    When an object is created, the elements are all defined with null
  632. X    values.  A user-defined routine should be provided which will place
  633. X    useful values in the elements.  For example, for an object of type
  634. X    'surd', a function called 'surd' can be defined to set the two
  635. X    components as follows:
  636. X    
  637. X        define surd(a, b)
  638. X        {
  639. X            local x;
  640. X
  641. X            obj surd x;
  642. X            x.a = a;
  643. X            x.b = b;
  644. X            return x;
  645. X        }
  646. X
  647. X    When an operation is attempted for an object, user functions with
  648. X    particular names are automatically called to perform the operation.
  649. X    These names are created by concatenating the object type name and
  650. X    the operation name together with an underscore.  For example, when
  651. X    multiplying two objects of type surd, the function "surd_mul" is
  652. X    called.
  653. X
  654. X    The user function is called with the necessary arguments for that
  655. X    operation.  For example, for "surd_mul", there are two arguments,
  656. X    which are the two numbers.  The order of the arguments is always
  657. X    the order of the binary operands.  If only one of the operands to
  658. X    a binary operator is an object, then the user function for that
  659. X    object type is still called.  If the two operands are of different
  660. X    object types, then the user function that is called is the one for
  661. X    the first operand.
  662. X
  663. X    The above rules mean that for full generality, user functions
  664. X    should detect that one of their arguments is not of its own object
  665. X    type by using the 'istype' function, and then handle these cases
  666. X    specially.  In this way, users can mix normal numbers with object
  667. X    types.  (Functions which only have one operand don't have to worry
  668. X    about this.)  The following example of "surd_mul" demonstrates how
  669. X    to handle regular numbers when used together with surds:
  670. X
  671. X        define surd_mul(a, b)
  672. X        {
  673. X            local x;
  674. X
  675. X            obj surd x;
  676. X            if (!istype(a, x)) {    
  677. X                /* a not of type surd */
  678. X                x.a = b.a * a;
  679. X                x.b = b.b * a;
  680. X            } else if (!istype(b, x)) {
  681. X                /* b not of type surd */
  682. X                x.a = a.a * b;
  683. X                x.b = a.b * b;
  684. X            } else {            
  685. X                /* both are surds */
  686. X                x.a = a.a * b.a + D * a.b * b.b;
  687. X                x.b = a.a * b.b + a.b * b.a;
  688. X            }
  689. X            if (x.b == 0)
  690. X                return x.a;    /* normal number */
  691. X            return x;        /* return surd */
  692. X        }
  693. X
  694. X    In order to print the value of an object nicely, a user defined
  695. X    routine can be provided.  For small amounts of output, the print
  696. X    routine should not print a newline.  Also, it is most convenient
  697. X    if the printed object looks like the call to the creation routine.
  698. X    For output to be correctly collected within nested output calls,
  699. X    output should only go to stdout.  This means use the 'print'
  700. X    statement, the 'printf' function, or the 'fprintf' function with
  701. X    'files(1)' as the output file.  For example, for the "surd" object:
  702. X
  703. X        define surd_print(a)
  704. X        {
  705. X            print "surd(" : a.a : "," : a.b : ")" : ;
  706. X        }
  707. X
  708. X    It is not necessary to provide routines for all possible operations
  709. X    for an object, if those operations can be defaulted or do not make
  710. X    sense for the object.  The calculator will attempt meaningful
  711. X    defaults for many operations if they are not defined.  For example,
  712. X    if 'surd_square' is not defined to square a number, then 'surd_mul'
  713. X    will be called to perform the squaring.  When a default is not
  714. X    possible, then an error will be generated.
  715. X
  716. X    Please note: Arguments to object functions are always passed by
  717. X    reference (as if an '&' was specified for each variable in the call).
  718. X    Therefore, the function should not modify the parameters, but should
  719. X    copy them into local variables before modifying them.  This is done
  720. X    in order to make object calls quicker in general.
  721. X
  722. X    The double-bracket operator can be used to reference the elements
  723. X    of any object in a generic manner.  When this is done, index 0
  724. X    corresponds to the first element name, index 1 to the second name,
  725. X    and so on.  The 'size' function will return the number of elements
  726. X    in an object.
  727. X
  728. X    The following is a list of the operations possible for objects.
  729. X    The 'xx' in each function name is replaced with the actual object
  730. X    type name.  This table is displayed by the 'show objfuncs' command.
  731. X
  732. X        Name    Args    Comments
  733. X
  734. X        xx_print    1    print value, default prints elements
  735. X        xx_one      1    multiplicative identity, default is 1
  736. X        xx_test     1    logical test (false,true => 0,1), 
  737. X                    default tests elements
  738. X        xx_add      2    
  739. X        xx_sub      2    subtraction, default adds negative
  740. X        xx_neg      1    negative
  741. X        xx_mul      2    
  742. X        xx_div      2    non-integral division, default multiplies 
  743. X                    by inverse
  744. X        xx_inv      1    multiplicative inverse
  745. X        xx_abs      2    absolute value within given error
  746. X        xx_norm     1    square of absolute value
  747. X        xx_conj     1    conjugate
  748. X        xx_pow      2    integer power, default does multiply, 
  749. X                    square, inverse
  750. X        xx_sgn      1    sign of value (-1, 0, 1)
  751. X        xx_cmp      2    equality (equal,non-equal => 0,1), 
  752. X                    default tests elements
  753. X        xx_rel      2    inequality (less,equal,greater => -1,0,1)
  754. X        xx_quo      2    integer quotient
  755. X        xx_mod      2    remainder of division
  756. X        xx_int      1    integer part
  757. X        xx_frac     1    fractional part
  758. X        xx_inc      1    increment, default adds 1
  759. X        xx_dec      1    decrement, default subtracts 1
  760. X        xx_square   1    default multiplies by itself
  761. X        xx_scale    2    multiply by power of 2
  762. X        xx_shift    2    shift left by n bits (right if negative)
  763. X        xx_round    2    round to given number of decimal places
  764. X        xx_bround   2    round to given number of binary places
  765. X        xx_root     3    root of value within given error
  766. X        xx_sqrt     2    square root within given error
  767. X
  768. X
  769. X    Also see the library files:
  770. X
  771. X        dms.cal
  772. X        mod.cal
  773. X        poly.cal
  774. X        quat.cal
  775. X        surd.cal
  776. END_OF_FILE
  777. if test 6682 -ne `wc -c <'help/obj'`; then
  778.     echo shar: \"'help/obj'\" unpacked with wrong size!
  779. fi
  780. # end of 'help/obj'
  781. fi
  782. if test -f 'lib/ellip.cal' -a "${1}" != "-c" ; then 
  783.   echo shar: Will not clobber existing file \"'lib/ellip.cal'\"
  784. else
  785. echo shar: Extracting \"'lib/ellip.cal'\" \(5027 characters\)
  786. sed "s/^X//" >'lib/ellip.cal' <<'END_OF_FILE'
  787. X/*
  788. X * Copyright (c) 1992 David I. Bell
  789. X * Permission is granted to use, distribute, or modify this source,
  790. X * provided that this copyright notice remains intact.
  791. X *
  792. X * Attempt to factor numbers using elliptic functions.
  793. X *     y^2 = x^3 + a*x + b   (mod N).
  794. X *
  795. X * Many points (x,y) (mod N) are found that solve the above equation,
  796. X * starting from a trivial solution and 'multiplying' that point together
  797. X * to generate high powers of the point, looking for such a point whose
  798. X * order contains a common factor with N.  The order of the group of points
  799. X * varies almost randomly within a certain interval for each choice of a
  800. X * and b, and thus each choice provides an independent opportunity to
  801. X * factor N.  To generate a trivial solution, a is chosen and then b is
  802. X * selected so that (1,1) is a solution.  The multiplication is done using
  803. X * the basic fact that the equation is a cubic, and so if a line hits the
  804. X * curve in two rational points, then the third intersection point must
  805. X * also be rational.  Thus by drawing lines between known rational points
  806. X * the number of rational solutions can be made very large.  When modular
  807. X * arithmetic is used, solving for the third point requires the taking of a
  808. X * modular inverse (instead of division), and if this fails, then the GCD
  809. X * of the failing value and N provides a factor of N.  This description is
  810. X * only an approximation, read "A Course in Number Theory and Cryptography"
  811. X * by Neal Koblitz for a good explanation.
  812. X *
  813. X * factor(iN, ia, B, force)
  814. X *    iN is the number to be factored.
  815. X *    ia is the initial value of a in the equation, and each successive
  816. X *    value of a is an independent attempt at factoring (default 1).
  817. X *    B is the limit of the primes that make up the high power that the
  818. X *    point is raised to for each factoring attempt (default 100).
  819. X *    force is a flag to attempt to factor numbers even if they are
  820. X *    thought to already be prime (default FALSE).
  821. X *
  822. X * Making B larger makes the power the point being raised to contain more
  823. X * prime factors, thus increasing the chance that the order of the point
  824. X * will be made up of those factors.  The higher B is then, the greater
  825. X * the chance that any individual attempt will find a factor.  However,
  826. X * a higher B also slows down the number of independent functions being
  827. X * examined.  The order of the point for any particular function might
  828. X * contain a large prime and so won't succeed even for a really large B,
  829. X * whereas the next function might have an order which is quickly found.
  830. X * So you want to trade off the depth of a particular search with the
  831. X * number of searches made.  For example, for factoring 30 digits, I make
  832. X * B be about 1000 (probably still too small).
  833. X *
  834. X * If you have lots of machines available, then you can run parallel
  835. X * factoring attempts for the same number by giving different starting
  836. X * values of ia for each machine (e.g. 1000, 2000, 3000).
  837. X *
  838. X * The output as the function is running is (occasionally) the value of a
  839. X * when a new function is started, the prime that is being included in the
  840. X * high power being calculated, and the current point which is the result
  841. X * of the powers so far.
  842. X *
  843. X * If a factor is found, it is returned and is also saved in the global
  844. X * variable f.  The number being factored is also saved in the global
  845. X * variable N.
  846. X */
  847. X
  848. Xobj point {x, y};
  849. Xglobal    N;        /* number to factor */
  850. Xglobal    a;        /* first coefficient */
  851. Xglobal    b;        /* second coefficient */
  852. Xglobal    f;        /* found factor */
  853. X
  854. X
  855. Xdefine factor(iN, ia, B, force)
  856. X{
  857. X    local    C, x, p;
  858. X
  859. X    if (!force && ptest(iN, 50))
  860. X        return 1;
  861. X    if (isnull(B))
  862. X        B = 100;
  863. X    if (isnull(ia))
  864. X        ia = 1;
  865. X    obj point x;
  866. X    a = ia;
  867. X    b = -ia;
  868. X    N = iN;
  869. X    C = isqrt(N);
  870. X    C = 2 * C + 2 * isqrt(C) + 1;
  871. X    f = 0;
  872. X    while (f == 0) {
  873. X        print "A =", a;
  874. X        x.x = 1;
  875. X        x.y = 1;
  876. X        print 2, x;
  877. X        x = x ^ (2 ^ (highbit(C) + 1));
  878. X        for (p = 3; ((p < B) && (f == 0)); p += 2) {
  879. X            if (!ptest(p, 1))
  880. X                continue;
  881. X            print p, x;
  882. X            x = x ^ (p ^ ((highbit(C) // highbit(p)) + 1));
  883. X        }
  884. X        a++;
  885. X        b--;
  886. X    }
  887. X    return f;
  888. X}
  889. X
  890. X
  891. Xdefine point_print(p)
  892. X{
  893. X    print "(" : p.x : "," : p.y : ")" :;
  894. X}
  895. X
  896. X
  897. Xdefine point_mul(p1, p2)
  898. X{
  899. X    local    r, m;
  900. X
  901. X    if (p2 == 1)
  902. X        return p1;
  903. X    if (p1 == p2)
  904. X        return point_square(&p1);
  905. X    obj point r;
  906. X    m = (minv(p2.x - p1.x, N) * (p2.y - p1.y)) % N;
  907. X    if (m == 0) {
  908. X        if (f == 0)
  909. X            f = gcd(p2.x - p1.x, N);
  910. X        r.x = 1;
  911. X        r.y = 1;
  912. X        return r;        
  913. X    }
  914. X    r.x = (m^2 - p1.x - p2.x) % N;
  915. X    r.y = ((m * (p1.x - r.x)) - p1.y) % N;
  916. X    return r;
  917. X}
  918. X
  919. X
  920. Xdefine point_square(p)
  921. X{
  922. X    local    r, m;
  923. X
  924. X    obj point r;
  925. X    m = ((3 * p.x^2 + a) * minv(p.y << 1, N)) % N;
  926. X    if (m == 0) {
  927. X        if (f == 0)
  928. X            f = gcd(p.y << 1, N);
  929. X        r.x = 1;
  930. X        r.y = 1;
  931. X        return r;
  932. X    }
  933. X    r.x = (m^2 - p.x - p.x) % N;
  934. X    r.y = ((m * (p.x - r.x)) - p.y) % N;
  935. X    return r;
  936. X}
  937. X
  938. X
  939. Xdefine point_pow(p, pow)
  940. X{
  941. X    local bit, r, t;
  942. X
  943. X    r = 1;
  944. X    if (isodd(pow))
  945. X        r = p;
  946. X    t = p;
  947. X    for (bit = 2; ((bit <= pow) && (f == 0)); bit <<= 1) {
  948. X        t = point_square(&t);
  949. X        if (bit & pow)
  950. X            r = point_mul(&t, &r);
  951. X    }
  952. X    return r;
  953. X}
  954. X
  955. Xglobal lib_debug;
  956. Xif (!isnum(lib_debug) || lib_debug>0) print "factor(N, I, B, force) defined";
  957. END_OF_FILE
  958. if test 5027 -ne `wc -c <'lib/ellip.cal'`; then
  959.     echo shar: \"'lib/ellip.cal'\" unpacked with wrong size!
  960. fi
  961. # end of 'lib/ellip.cal'
  962. fi
  963. if test -f 'lib/surd.cal' -a "${1}" != "-c" ; then 
  964.   echo shar: Will not clobber existing file \"'lib/surd.cal'\"
  965. else
  966. echo shar: Extracting \"'lib/surd.cal'\" \(5041 characters\)
  967. sed "s/^X//" >'lib/surd.cal' <<'END_OF_FILE'
  968. X/*
  969. X * Copyright (c) 1992 David I. Bell
  970. X * Permission is granted to use, distribute, or modify this source,
  971. X * provided that this copyright notice remains intact.
  972. X *
  973. X * Calculate using quadratic surds of the form: a + b * sqrt(D).
  974. X */
  975. X
  976. Xobj surd {a, b};        /* definition of the surd object */
  977. X
  978. Xglobal surd_type;        /* type of surd (value of D) */
  979. Xglobal surd__;            /* example surd for testing against */
  980. X
  981. Xsurd_type = -1;            /* default */
  982. Xobj surd surd__;        /* set object */
  983. X
  984. X
  985. Xdefine surd(a,b)
  986. X{
  987. X    local x;
  988. X
  989. X    obj surd x;
  990. X    x.a = a;
  991. X    x.b = b;
  992. X    return x;
  993. X}
  994. X
  995. X
  996. Xdefine surd_print(a)
  997. X{
  998. X    print "surd(" : a.a : ", " : a.b : ")" :;
  999. X}
  1000. X
  1001. X
  1002. Xdefine surd_conj(a)
  1003. X{
  1004. X    local    x;
  1005. X
  1006. X    obj surd x;
  1007. X    x.a = a.a;
  1008. X    x.b = -a.b;
  1009. X    return x;
  1010. X}
  1011. X
  1012. X
  1013. Xdefine surd_norm(a)
  1014. X{
  1015. X    return a.a^2 + abs(surd_type) * a.b^2;
  1016. X}
  1017. X
  1018. X
  1019. Xdefine surd_value(a, xepsilon)
  1020. X{
  1021. X    local    epsilon;
  1022. X
  1023. X    epsilon = xepsilon;
  1024. X    if (isnull(epsilon))
  1025. X        epsilon = epsilon();
  1026. X    return a.a + a.b * sqrt(surd_type, epsilon);
  1027. X}
  1028. X
  1029. Xdefine surd_add(a, b)
  1030. X{
  1031. X    local x;
  1032. X
  1033. X    obj surd x;
  1034. X    if (!istype(b, x)) {
  1035. X        x.a = a.a + b;
  1036. X        x.b = a.b;
  1037. X        return x;
  1038. X    }
  1039. X    if (!istype(a, x)) {
  1040. X        x.a = a + b.a;
  1041. X        x.b = b.b;
  1042. X        return x;
  1043. X    }
  1044. X    x.a = a.a + b.a;
  1045. X    x.b = a.b + b.b;
  1046. X    if (x.b)
  1047. X        return x;
  1048. X    return x.a;
  1049. X}
  1050. X
  1051. X
  1052. Xdefine surd_sub(a, b)
  1053. X{
  1054. X    local x;
  1055. X
  1056. X    obj surd x;
  1057. X    if (!istype(b, x)) {
  1058. X        x.a = a.a - b;
  1059. X        x.b = a.b;
  1060. X        return x;
  1061. X    }
  1062. X    if (!istype(a, x)) {
  1063. X        x.a = a - b.a;
  1064. X        x.b = -b.b;
  1065. X        return x;
  1066. X    }
  1067. X    x.a = a.a - b.a;
  1068. X    x.b = a.b - b.b;
  1069. X    if (x.b)
  1070. X        return x;
  1071. X    return x.a;
  1072. X}
  1073. X
  1074. X
  1075. Xdefine surd_inc(a)
  1076. X{
  1077. X    local    x;
  1078. X
  1079. X    x = a;
  1080. X    x.a++;
  1081. X    return x;
  1082. X}
  1083. X
  1084. X
  1085. Xdefine surd_dec(a)
  1086. X{
  1087. X    local    x;
  1088. X
  1089. X    x = a;
  1090. X    x.a--;
  1091. X    return x;
  1092. X}
  1093. X
  1094. X
  1095. Xdefine surd_neg(a)
  1096. X{
  1097. X    local    x;
  1098. X
  1099. X    obj surd x;
  1100. X    x.a = -a.a;
  1101. X    x.b = -a.b;
  1102. X    return x;
  1103. X}
  1104. X
  1105. X
  1106. Xdefine surd_mul(a, b)
  1107. X{
  1108. X    local x;
  1109. X
  1110. X    obj surd x;
  1111. X    if (!istype(b, x)) {
  1112. X        x.a = a.a * b;
  1113. X        x.b = a.b * b;
  1114. X    } else if (!istype(a, x)) {
  1115. X        x.a = b.a * a;
  1116. X        x.b = b.b * a;
  1117. X    } else {
  1118. X        x.a = a.a * b.a + surd_type * a.b * b.b;
  1119. X        x.b = a.a * b.b + a.b * b.a;
  1120. X    }
  1121. X    if (x.b)
  1122. X        return x;
  1123. X    return x.a;
  1124. X}
  1125. X
  1126. X
  1127. Xdefine surd_square(a)
  1128. X{
  1129. X    local x;
  1130. X
  1131. X    obj surd x;
  1132. X    x.a = a.a^2 + a.b^2 * surd_type;
  1133. X    x.b = a.a * a.b * 2;
  1134. X    if (x.b)
  1135. X        return x;
  1136. X    return x.a;
  1137. X}
  1138. X
  1139. X
  1140. Xdefine surd_scale(a, b)
  1141. X{
  1142. X    local    x;
  1143. X
  1144. X    obj surd x;
  1145. X    x.a = scale(a.a, b);
  1146. X    x.b = scale(a.b, b);
  1147. X    return x;
  1148. X}
  1149. X
  1150. X
  1151. Xdefine surd_shift(a, b)
  1152. X{
  1153. X    local    x;
  1154. X
  1155. X    obj surd x;
  1156. X    x.a = a.a << b;
  1157. X    x.b = a.b << b;
  1158. X    if (x.b)
  1159. X        return x;
  1160. X    return x.a;
  1161. X}
  1162. X
  1163. X
  1164. Xdefine surd_div(a, b)
  1165. X{
  1166. X    local x, y;
  1167. X
  1168. X    if ((a == 0) && b)
  1169. X        return 0;
  1170. X    obj surd x;
  1171. X    if (!istype(b, x)) {
  1172. X        x.a = a.a / b;
  1173. X        x.b = a.b / b;
  1174. X        return x;
  1175. X    }
  1176. X    y = b;
  1177. X    y.b = -b.b;
  1178. X    return (a * y) / (b.a^2 - surd_type * b.b^2);
  1179. X}
  1180. X
  1181. X
  1182. Xdefine surd_inv(a)
  1183. X{
  1184. X    return 1 / a;
  1185. X}
  1186. X
  1187. X
  1188. Xdefine surd_sgn(a)
  1189. X{
  1190. X    if (surd_type < 0)
  1191. X        quit "Taking sign of complex surd";
  1192. X    if (a.a == 0)
  1193. X        return sgn(a.b);
  1194. X    if (a.b == 0)
  1195. X        return sgn(a.a);
  1196. X    if ((a.a > 0) && (a.b > 0))
  1197. X        return 1;
  1198. X    if ((a.a < 0) && (a.b < 0))
  1199. X        return -1;
  1200. X    return sgn(a.a^2 - a.b^2 * surd_type) * sgn(a.a);
  1201. X}
  1202. X
  1203. X
  1204. Xdefine surd_cmp(a, b)
  1205. X{
  1206. X    if (!istype(a, surd__))
  1207. X        return ((b.b != 0) || (a != b.a));
  1208. X    if (!istype(b, surd__))
  1209. X        return ((a.b != 0) || (b != a.a));
  1210. X    return ((a.a != b.a) || (a.b != b.b));
  1211. X}
  1212. X
  1213. X
  1214. Xdefine surd_rel(a, b)
  1215. X{
  1216. X    local x, y;
  1217. X
  1218. X    if (surd_type < 0)
  1219. X        quit "Relative comparison of complex surds";
  1220. X    if (!istype(a, surd__)) {
  1221. X        x = a - b.a;
  1222. X        y = -b.b;
  1223. X    } else if (!istype(b, surd__)) {
  1224. X        x = a.a - b;
  1225. X        y = a.b;
  1226. X    } else {
  1227. X        x = a.a - b.a;
  1228. X        y = a.b - b.b;
  1229. X    }
  1230. X    if (y == 0)
  1231. X        return sgn(x);
  1232. X    if (x == 0)
  1233. X        return sgn(y);
  1234. X    if ((x < 0) && (y < 0))
  1235. X        return -1;
  1236. X    if ((x > 0) && (y > 0))
  1237. X        return 1;
  1238. X    return sgn(x^2 - y^2 * surd_type) * sgn(x);
  1239. X}
  1240. X
  1241. Xglobal lib_debug;
  1242. Xif (!isnum(lib_debug) || lib_debug>0) print "obj surd {a, b} defined"
  1243. Xif (!isnum(lib_debug) || lib_debug>0) print "surd(a, b) defined"
  1244. Xif (!isnum(lib_debug) || lib_debug>0) print "surd_print(a) defined"
  1245. Xif (!isnum(lib_debug) || lib_debug>0) print "surd_conj(a) defined"
  1246. Xif (!isnum(lib_debug) || lib_debug>0) print "surd_norm(a) defined"
  1247. Xif (!isnum(lib_debug) || lib_debug>0) print "surd_value(a, xepsilon) defined"
  1248. Xif (!isnum(lib_debug) || lib_debug>0) print "surd_add(a, b) defined"
  1249. Xif (!isnum(lib_debug) || lib_debug>0) print "surd_sub(a, b) defined"
  1250. Xif (!isnum(lib_debug) || lib_debug>0) print "surd_inc(a) defined"
  1251. Xif (!isnum(lib_debug) || lib_debug>0) print "surd_dec(a) defined"
  1252. Xif (!isnum(lib_debug) || lib_debug>0) print "surd_neg(a) defined"
  1253. Xif (!isnum(lib_debug) || lib_debug>0) print "surd_mul(a, b) defined"
  1254. Xif (!isnum(lib_debug) || lib_debug>0) print "surd_square(a) defined"
  1255. Xif (!isnum(lib_debug) || lib_debug>0) print "surd_scale(a, b) defined"
  1256. Xif (!isnum(lib_debug) || lib_debug>0) print "surd_shift(a, b) defined"
  1257. Xif (!isnum(lib_debug) || lib_debug>0) print "surd_div(a, b) defined"
  1258. Xif (!isnum(lib_debug) || lib_debug>0) print "surd_inv(a) defined"
  1259. Xif (!isnum(lib_debug) || lib_debug>0) print "surd_sgn(a) defined"
  1260. Xif (!isnum(lib_debug) || lib_debug>0) print "surd_cmp(a, b) defined"
  1261. Xif (!isnum(lib_debug) || lib_debug>0) print "surd_rel(a, b) defined"
  1262. Xif (!isnum(lib_debug) || lib_debug>0) print "surd_type defined"
  1263. Xif (!isnum(lib_debug) || lib_debug>0) print "set surd_type as needed"
  1264. END_OF_FILE
  1265. if test 5041 -ne `wc -c <'lib/surd.cal'`; then
  1266.     echo shar: \"'lib/surd.cal'\" unpacked with wrong size!
  1267. fi
  1268. # end of 'lib/surd.cal'
  1269. fi
  1270. if test -f 'opcodes.h' -a "${1}" != "-c" ; then 
  1271.   echo shar: Will not clobber existing file \"'opcodes.h'\"
  1272. else
  1273. echo shar: Extracting \"'opcodes.h'\" \(5948 characters\)
  1274. sed "s/^X//" >'opcodes.h' <<'END_OF_FILE'
  1275. X/*
  1276. X * Copyright (c) 1992 David I. Bell
  1277. X * Permission is granted to use, distribute, or modify this source,
  1278. X * provided that this copyright notice remains intact.
  1279. X */
  1280. X
  1281. X
  1282. X/*
  1283. X * Opcodes
  1284. X */
  1285. X#define OP_NOP        0L    /* no operation */
  1286. X#define OP_LOCALADDR    1L    /* load address of local variable */
  1287. X#define OP_GLOBALADDR    2L    /* load address of global variable */
  1288. X#define OP_PARAMADDR    3L    /* load address of paramater variable */
  1289. X#define OP_LOCALVALUE    4L    /* load value of local variable */
  1290. X#define OP_GLOBALVALUE    5L    /* load value of global variable */
  1291. X#define OP_PARAMVALUE    6L    /* load value of paramater variable */
  1292. X#define OP_NUMBER    7L    /* load constant real numeric value */
  1293. X#define OP_INDEXADDR    8L    /* load array index address */
  1294. X#define OP_INDEXVALUE    9L    /* load array value */
  1295. X#define OP_ASSIGN    10L    /* assign value to variable */
  1296. X#define OP_ADD        11L    /* add top two values */
  1297. X#define OP_SUB        12L    /* subtract top two values */
  1298. X#define OP_MUL        13L    /* multiply top two values */
  1299. X#define OP_DIV        14L    /* divide top two values */
  1300. X#define OP_MOD        15L    /* take mod of top two values */
  1301. X#define OP_SAVE        16L    /* save value for later use */
  1302. X#define OP_NEGATE    17L    /* negate top value */
  1303. X#define OP_INVERT    18L    /* invert top value */
  1304. X#define OP_INT        19L    /* take integer part of top value */
  1305. X#define OP_FRAC        20L    /* take fraction part of top value */
  1306. X#define OP_NUMERATOR    21L    /* take numerator of top value */
  1307. X#define OP_DENOMINATOR    22L    /* take denominator of top value */
  1308. X#define OP_DUPLICATE    23L    /* duplicate top value on stack */
  1309. X#define OP_POP        24L    /* pop top value from stack */
  1310. X#define OP_RETURN    25L    /* return value of function */
  1311. X#define OP_JUMPEQ    26L    /* jump if top value is zero */
  1312. X#define OP_JUMPNE    27L    /* jump if top value is nonzero */
  1313. X#define OP_JUMP        28L    /* jump unconditionally */
  1314. X#define OP_USERCALL    29L    /* call a user-defined function */
  1315. X#define OP_GETVALUE    30L    /* convert address to value */
  1316. X#define OP_EQ        31L    /* test top two elements for equality */
  1317. X#define OP_NE        32L    /* test top two elements for inequality */
  1318. X#define OP_LE        33L    /* test top two elements for <= */
  1319. X#define OP_GE        34L    /* test top two elements for >= */
  1320. X#define OP_LT        35L    /* test top two elements for < */
  1321. X#define OP_GT        36L    /* test top two elements for > */
  1322. X#define OP_PREINC    37L    /* add one to variable (++x) */
  1323. X#define OP_PREDEC    38L    /* subtract one from variable (--x) */
  1324. X#define OP_POSTINC    39L    /* add one to variable (x++) */
  1325. X#define OP_POSTDEC    40L    /* subtract one from variable (x--) */
  1326. X#define OP_DEBUG    41L    /* debugging point */
  1327. X#define OP_PRINT    42L    /* print value */
  1328. X#define OP_ASSIGNPOP    43L    /* assign to variable and remove it */
  1329. X#define OP_ZERO        44L    /* put zero on the stack */
  1330. X#define OP_ONE        45L    /* put one on the stack */
  1331. X#define OP_PRINTEOL    46L    /* print end of line */
  1332. X#define OP_PRINTSPACE    47L    /* print a space */
  1333. X#define OP_PRINTSTRING    48L    /* print constant string */
  1334. X#define OP_DUPVALUE    49L    /* duplicate value of top value */
  1335. X#define OP_OLDVALUE    50L    /* old calculation value */
  1336. X#define OP_QUO        51L    /* integer quotient of top two values */
  1337. X#define OP_POWER    52L    /* number raised to a power */
  1338. X#define OP_QUIT        53L    /* quit program */
  1339. X#define OP_CALL        54L    /* call built-in routine */
  1340. X#define OP_GETEPSILON    55L    /* get allowed error for calculations */
  1341. X#define OP_AND        56L    /* arithmetic and */
  1342. X#define OP_OR        57L    /* arithmetic or */
  1343. X#define OP_NOT        58L    /* logical not */
  1344. X#define OP_ABS        59L    /* absolute value */
  1345. X#define OP_SGN        60L    /* sign of number */
  1346. X#define OP_ISINT    61L    /* whether top value is integer */
  1347. X#define OP_CONDORJUMP    62L    /* conditional or jump */
  1348. X#define OP_CONDANDJUMP    63L    /* conditional and jump */
  1349. X#define OP_SQUARE    64L    /* square top value */
  1350. X#define OP_STRING    65L    /* load constant string value */
  1351. X#define OP_ISNUM    66L    /* whether top value is a number */
  1352. X#define OP_UNDEF    67L    /* load undefined value on stack */
  1353. X#define OP_ISNULL    68L    /* whether variable is the null value */
  1354. X#define OP_ARGVALUE    69L    /* load value of argument (parameter) n */
  1355. X#define OP_MATINIT    70L    /* initialize matrix */
  1356. X#define OP_ISMAT    71L    /* whether variable is a matrix */
  1357. X#define OP_ISSTR    72L    /* whether variable is a string */
  1358. X#define OP_GETCONFIG    73L    /* get value of configuration parameter */
  1359. X#define OP_LEFTSHIFT    74L    /* left shift of integer */
  1360. X#define OP_RIGHTSHIFT    75L    /* right shift of integer */
  1361. X#define OP_CASEJUMP    76L    /* test case and jump if not matched */
  1362. X#define OP_ISODD    77L    /* whether value is an odd integer */
  1363. X#define OP_ISEVEN    78L    /* whether value is even integer */
  1364. X#define OP_FIADDR    79L    /* 'fast index' matrix value address */
  1365. X#define OP_FIVALUE    80L    /* 'fast index' matrix value */
  1366. X#define OP_ISREAL    81L    /* test value for real number */
  1367. X#define OP_IMAGINARY    82L    /* load imaginary numeric constant */
  1368. X#define OP_RE        83L    /* real part of complex number */
  1369. X#define OP_IM        84L    /* imaginary part of complex number */
  1370. X#define OP_CONJUGATE    85L    /* complex conjugate of complex number */
  1371. X#define OP_OBJINIT    86L    /* initialize object */
  1372. X#define OP_ISOBJ    87L    /* whether value is an object */
  1373. X#define OP_NORM        88L    /* norm of value (square of abs) */
  1374. X#define OP_ELEMADDR    89L    /* address of element of object */
  1375. X#define OP_ELEMVALUE    90L    /* value of element of object */
  1376. X#define OP_ISTYPE    91L    /* whether two values are the same type */
  1377. X#define OP_SCALE    92L    /* scale value by a power of two */
  1378. X#define    OP_ISLIST    93L    /* whether value is a list */
  1379. X#define    OP_SWAP        94L    /* swap values of two variables */
  1380. X#define    OP_ISSIMPLE    95L    /* whether value is a simple type */
  1381. X#define    OP_CMP        96L    /* compare values returning -1, 0, or 1 */
  1382. X#define    OP_QUOMOD    97L    /* calculate quotient and remainder */
  1383. X#define    OP_SETCONFIG    98L    /* set configuration parameter */
  1384. X#define    OP_SETEPSILON    99L    /* set allowed error for calculations */
  1385. X#define    OP_PRINTRESULT    100L    /* print result of top-level expression */
  1386. X#define    OP_ISFILE    101L    /* whether value is a file */
  1387. X#define MAX_OPCODE    101L    /* highest legal opcode */
  1388. X
  1389. X/*
  1390. X * function declarations - most to keep lint happy
  1391. X */
  1392. Xextern void updateoldvalue();
  1393. X
  1394. X/* END CODE */
  1395. END_OF_FILE
  1396. if test 5948 -ne `wc -c <'opcodes.h'`; then
  1397.     echo shar: \"'opcodes.h'\" unpacked with wrong size!
  1398. fi
  1399. # end of 'opcodes.h'
  1400. fi
  1401. if test -f 'string.c' -a "${1}" != "-c" ; then 
  1402.   echo shar: Will not clobber existing file \"'string.c'\"
  1403. else
  1404. echo shar: Extracting \"'string.c'\" \(6676 characters\)
  1405. sed "s/^X//" >'string.c' <<'END_OF_FILE'
  1406. X/*
  1407. X * Copyright (c) 1992 David I. Bell
  1408. X * Permission is granted to use, distribute, or modify this source,
  1409. X * provided that this copyright notice remains intact.
  1410. X *
  1411. X * String list routines.
  1412. X */
  1413. X
  1414. X#include "calc.h"
  1415. X#include "string.h"
  1416. X
  1417. X#define STR_TABLECHUNK    100    /* how often to reallocate string table */
  1418. X#define STR_CHUNK    2000    /* size of string storage allocation */
  1419. X#define STR_UNIQUE    100    /* size of string to allocate separately */
  1420. X
  1421. X
  1422. Xstatic char *chartable;        /* single character string table */
  1423. X
  1424. Xstatic struct {
  1425. X    long l_count;        /* count of strings in table */
  1426. X    long l_maxcount;    /* maximum strings storable in table */
  1427. X    long l_avail;        /* characters available in current string */
  1428. X    char *l_alloc;        /* next available string storage */
  1429. X    char **l_table;        /* current string table */
  1430. X} literals;
  1431. X
  1432. X
  1433. X/*
  1434. X * Initialize or reinitialize a string header for use.
  1435. X */
  1436. Xvoid
  1437. Xinitstr(hp)
  1438. X    register STRINGHEAD *hp;    /* structure to be inited */
  1439. X{
  1440. X    if (hp->h_list == NULL) {
  1441. X        hp->h_list = (char *)malloc(2000);
  1442. X        hp->h_avail = 2000;
  1443. X        hp->h_used = 0;
  1444. X    }
  1445. X    hp->h_avail += hp->h_used;
  1446. X    hp->h_used = 0;
  1447. X    hp->h_count = 0;
  1448. X    hp->h_list[0] = '\0';
  1449. X    hp->h_list[1] = '\0';
  1450. X}
  1451. X
  1452. X
  1453. X/*
  1454. X * Copy a string to the end of a list of strings, and return the address
  1455. X * of the copied string.  Returns NULL if the string could not be copied.
  1456. X * No checks are made to see if the string is already in the list.
  1457. X * The string cannot be null or have imbedded nulls.
  1458. X */
  1459. Xchar *
  1460. Xaddstr(hp, str)
  1461. X    register STRINGHEAD *hp;    /* header of string storage */
  1462. X    char *str;        /* string to be added */
  1463. X{
  1464. X    char *retstr;        /* returned string pointer */
  1465. X    char *list;        /* string list */
  1466. X    long newsize;        /* new size of string list */
  1467. X    long len;        /* length of current string */
  1468. X
  1469. X    if ((str == NULL) || (*str == '\0'))
  1470. X        return NULL;
  1471. X    len = strlen(str) + 1;
  1472. X    if (hp->h_avail <= len) {
  1473. X        newsize = len + 2000 + hp->h_used + hp->h_avail;
  1474. X        list = (char *)realloc(hp->h_list, newsize);
  1475. X        if (list == NULL)
  1476. X            return NULL;
  1477. X        hp->h_list = list;
  1478. X        hp->h_avail = newsize - hp->h_used;
  1479. X    }
  1480. X    retstr = hp->h_list + hp->h_used;
  1481. X    hp->h_used += len;
  1482. X    hp->h_avail -= len;
  1483. X    hp->h_count++;
  1484. X    strcpy(retstr, str);
  1485. X    retstr[len] = '\0';
  1486. X    return retstr;
  1487. X}
  1488. X
  1489. X
  1490. X/*
  1491. X * Return a null-terminated string which consists of a single character.
  1492. X * The table is initialized on the first call.
  1493. X */
  1494. Xchar *
  1495. Xcharstr(ch)
  1496. X{
  1497. X    char *cp;
  1498. X    int i;
  1499. X
  1500. X    if (chartable == NULL) {
  1501. X        cp = (char *)malloc(512);
  1502. X        if (cp == NULL)
  1503. X            error("Cannot allocate character table");
  1504. X        for (i = 0; i < 256; i++) {
  1505. X            *cp++ = (char)i;
  1506. X            *cp++ = '\0';
  1507. X        }
  1508. X        chartable = cp - 512;
  1509. X    }
  1510. X    return &chartable[(ch & 0xff) * 2];
  1511. X}
  1512. X
  1513. X
  1514. X/*
  1515. X * Find a string with the specified name and return its number in the
  1516. X * string list.  The first string is numbered zero.  Minus one is returned
  1517. X * if the string is not found.
  1518. X */
  1519. Xlong
  1520. Xfindstr(hp, str)
  1521. X    STRINGHEAD *hp;        /* header of string storage */
  1522. X    register char *str;    /* string to be added */
  1523. X{
  1524. X    register char *test;    /* string being tested */
  1525. X    long len;        /* length of string being found */
  1526. X    long testlen;        /* length of test string */
  1527. X    long index;        /* index of string */
  1528. X
  1529. X    if ((hp->h_count <= 0) || (str == NULL))
  1530. X        return -1;
  1531. X    len = strlen(str);
  1532. X    test = hp->h_list;
  1533. X    index = 0;
  1534. X    while (*test) {
  1535. X        testlen = strlen(test);
  1536. X        if ((testlen == len) && (*test == *str) && (strcmp(test, str) == 0))
  1537. X            return index;
  1538. X        test += (testlen + 1);
  1539. X        index++;
  1540. X    }
  1541. X    return -1;
  1542. X}
  1543. X
  1544. X
  1545. X/*
  1546. X * Return the name of a string with the given index.
  1547. X * If the index is illegal, a pointer to an empty string is returned.
  1548. X */
  1549. Xchar *
  1550. Xnamestr(hp, n)
  1551. X    STRINGHEAD *hp;        /* header of string storage */
  1552. X    long n;
  1553. X{
  1554. X    register char *str;    /* current string */
  1555. X
  1556. X    if ((unsigned long)n >= hp->h_count)
  1557. X        return "";
  1558. X    str = hp->h_list;
  1559. X    while (*str) {
  1560. X        if (--n < 0)
  1561. X            return str;
  1562. X        str += (strlen(str) + 1);
  1563. X    }
  1564. X    return "";
  1565. X}
  1566. X
  1567. X
  1568. X/*
  1569. X * Useful routine to return the index of one string within another one
  1570. X * which has the format:  "str1\0str2\0str3\0...strn\0\0".  Index starts
  1571. X * at one for the first string.  Returns zero if the string being checked
  1572. X * is not contained in the formatted string.
  1573. X */
  1574. Xlong
  1575. Xstringindex(format, test)
  1576. X    register char *format;    /* string formatted into substrings */
  1577. X    char *test;        /* string to be found in formatted string */
  1578. X{
  1579. X    long index;        /* found index */
  1580. X    long len;        /* length of current piece of string */
  1581. X    long testlen;        /* length of test string */
  1582. X
  1583. X    testlen = strlen(test);
  1584. X    index = 1;
  1585. X    while (*format) {
  1586. X        len = strlen(format);
  1587. X        if ((len == testlen) && (*format == *test) &&
  1588. X            (strcmp(format, test) == 0))
  1589. X                return index;
  1590. X        format += (len + 1);
  1591. X        index++;
  1592. X    }
  1593. X    return 0;
  1594. X}
  1595. X
  1596. X
  1597. X/*
  1598. X * Add a possibly new literal string to the literal string pool.
  1599. X * Returns the new string address which is guaranteed to be always valid.
  1600. X * Duplicate strings will repeatedly return the same address.
  1601. X */
  1602. Xchar *
  1603. Xaddliteral(str)
  1604. X    char *str;
  1605. X{
  1606. X    register char **table;    /* table of strings */
  1607. X    char *newstr;        /* newly allocated string */
  1608. X    long count;        /* number of strings */
  1609. X    long len;        /* length of string to allocate */
  1610. X
  1611. X    len = strlen(str);
  1612. X    if (len <= 1)
  1613. X        return charstr(*str);
  1614. X    /*
  1615. X     * See if the string is already in the table.
  1616. X     */
  1617. X    table = literals.l_table;
  1618. X    count = literals.l_count;
  1619. X    while (count-- > 0) {
  1620. X        if ((str[0] == table[0][0]) && (str[1] == table[0][1]) &&
  1621. X            (strcmp(str, table[0]) == 0))
  1622. X                return table[0];
  1623. X        table++;
  1624. X    }
  1625. X    /*
  1626. X     * Make the table of string pointers larger if necessary.
  1627. X     */
  1628. X    if (literals.l_count >= literals.l_maxcount) {
  1629. X        count = literals.l_maxcount + STR_TABLECHUNK;
  1630. X        if (literals.l_maxcount)
  1631. X            table = (char **) realloc(literals.l_table, count * sizeof(char *));
  1632. X        else
  1633. X            table = (char **) malloc(count * sizeof(char *));
  1634. X        if (table == NULL)
  1635. X            error("Cannot allocate string literal table");
  1636. X        literals.l_table = table;
  1637. X        literals.l_maxcount = count;
  1638. X    }
  1639. X    table = literals.l_table;
  1640. X    /*
  1641. X     * If the new string is very long, allocate it manually.
  1642. X     */
  1643. X    len = (len + 2) & ~1;    /* add room for null and round up to word */
  1644. X    if (len >= STR_UNIQUE) {
  1645. X        newstr = (char *)malloc(len);
  1646. X        if (newstr == NULL)
  1647. X            error("Cannot allocate large literal string");
  1648. X        strcpy(newstr, str);
  1649. X        table[literals.l_count++] = newstr;
  1650. X        return newstr;
  1651. X    }
  1652. X    /*
  1653. X     * If the remaining space in the allocate string is too small,
  1654. X     * then allocate a new one.
  1655. X     */
  1656. X    if (literals.l_avail < len) {
  1657. X        newstr = (char *)malloc(STR_CHUNK);
  1658. X        if (newstr == NULL)
  1659. X            error("Cannot allocate new literal string");
  1660. X        literals.l_alloc = newstr;
  1661. X        literals.l_avail = STR_CHUNK;
  1662. X    }
  1663. X    /*
  1664. X     * Allocate the new string from the allocate string.
  1665. X     */
  1666. X    newstr = literals.l_alloc;
  1667. X    literals.l_avail -= len;
  1668. X    literals.l_alloc += len;
  1669. X    table[literals.l_count++] = newstr;
  1670. X    strcpy(newstr, str);
  1671. X    return newstr;
  1672. X}
  1673. X
  1674. X/* END CODE */
  1675. END_OF_FILE
  1676. if test 6676 -ne `wc -c <'string.c'`; then
  1677.     echo shar: \"'string.c'\" unpacked with wrong size!
  1678. fi
  1679. # end of 'string.c'
  1680. fi
  1681. if test -f 'token.h' -a "${1}" != "-c" ; then 
  1682.   echo shar: Will not clobber existing file \"'token.h'\"
  1683. else
  1684. echo shar: Extracting \"'token.h'\" \(4911 characters\)
  1685. sed "s/^X//" >'token.h' <<'END_OF_FILE'
  1686. X/*
  1687. X * Copyright (c) 1992 David I. Bell
  1688. X * Permission is granted to use, distribute, or modify this source,
  1689. X * provided that this copyright notice remains intact.
  1690. X */
  1691. X
  1692. X
  1693. X/*
  1694. X * Token types
  1695. X */
  1696. X#define T_NULL            0    /* null token */
  1697. X#define T_LEFTPAREN        1    /* left parenthesis "(" */
  1698. X#define T_RIGHTPAREN        2    /* right parenthesis ")" */
  1699. X#define T_LEFTBRACE        3    /* left brace "{" */
  1700. X#define T_RIGHTBRACE        4    /* right brace "}" */
  1701. X#define T_SEMICOLON        5    /* end of statement ";" */
  1702. X#define T_EOF            6    /* end of file */
  1703. X#define T_COLON            7    /* label character ":" */
  1704. X#define T_ASSIGN        8    /* assignment "=" */
  1705. X#define T_PLUS            9    /* plus sign "+" */
  1706. X#define T_MINUS            10    /* minus sign "-" */
  1707. X#define T_MULT            11    /* multiply sign "*" */
  1708. X#define T_DIV            12    /* divide sign "/" */
  1709. X#define T_MOD            13    /* modulo sign "%" */
  1710. X#define T_POWER            14    /* power sign "^" or "**" */
  1711. X#define T_EQ            15    /* equality "==" */
  1712. X#define T_NE            16    /* notequal "!=" */
  1713. X#define T_LT            17    /* less than "<" */
  1714. X#define T_GT            18    /* greater than ">" */
  1715. X#define T_LE            19    /* less than or equals "<=" */
  1716. X#define T_GE            20    /* greater than or equals ">=" */
  1717. X#define T_LEFTBRACKET        21    /* left bracket "[" */
  1718. X#define T_RIGHTBRACKET        22    /* right bracket "]" */
  1719. X#define T_SYMBOL        23    /* symbol name */
  1720. X#define T_STRING        24    /* string value (double quotes) */
  1721. X#define T_NUMBER        25    /* numeric real constant */
  1722. X#define T_PLUSEQUALS        26    /* plus equals "+=" */
  1723. X#define T_MINUSEQUALS        27    /* minus equals "-=" */
  1724. X#define T_MULTEQUALS        28    /* multiply equals "*=" */
  1725. X#define T_DIVEQUALS        29    /* divide equals "/=" */
  1726. X#define T_MODEQUALS        30    /* modulo equals "%=" */
  1727. X#define T_PLUSPLUS        31    /* plusplus "++" */
  1728. X#define T_MINUSMINUS        32    /* minusminus "--" */
  1729. X#define T_COMMA            33    /* comma "," */
  1730. X#define T_ANDAND        34    /* logical and "&&" */
  1731. X#define T_OROR            35    /* logical or "||" */
  1732. X#define T_OLDVALUE        36    /* old value from previous calculation */
  1733. X#define T_SLASHSLASH        37    /* integer divide "//" */
  1734. X#define T_NEWLINE        38    /* newline character */
  1735. X#define T_SLASHSLASHEQUALS    39    /* integer divide equals "//=" */
  1736. X#define T_AND            40    /* arithmetic and "&" */
  1737. X#define T_OR            41    /* arithmetic or "|" */
  1738. X#define T_NOT            42    /* logical not "!" */
  1739. X#define T_LEFTSHIFT        43    /* left shift "<<" */
  1740. X#define T_RIGHTSHIFT        44    /* right shift ">>" */
  1741. X#define T_ANDEQUALS        45    /* and equals "&=" */
  1742. X#define T_OREQUALS        46    /* or equals "|= */
  1743. X#define T_LSHIFTEQUALS        47    /* left shift equals "<<=" */
  1744. X#define T_RSHIFTEQUALS        48    /* right shift equals ">>= */
  1745. X#define T_POWEREQUALS        49    /* power equals "^=" or "**=" */
  1746. X#define T_PERIOD        50    /* period "." */
  1747. X#define T_IMAGINARY        51    /* numeric imaginary constant */
  1748. X#define    T_AMPERSAND        52    /* ampersand "&" */
  1749. X#define    T_QUESTIONMARK        53    /* question mark "?" */
  1750. X
  1751. X
  1752. X/*
  1753. X * Keyword tokens
  1754. X */
  1755. X#define T_IF            101    /* if keyword */
  1756. X#define T_ELSE            102    /* else keyword */
  1757. X#define T_WHILE            103    /* while keyword */
  1758. X#define T_CONTINUE        104    /* continue keyword */
  1759. X#define T_BREAK            105    /* break keyword */
  1760. X#define T_GOTO            106    /* goto keyword */
  1761. X#define T_RETURN        107    /* return keyword */
  1762. X#define T_LOCAL            108    /* local keyword */
  1763. X#define T_GLOBAL        109    /* global keyword */
  1764. X#define T_PRINT            110    /* print keyword */
  1765. X#define T_DO            111    /* do keyword */
  1766. X#define T_FOR            112    /* for keyword */
  1767. X#define T_SWITCH        113    /* switch keyword */
  1768. X#define T_CASE            114    /* case keyword */
  1769. X#define T_DEFAULT        115    /* default keyword */
  1770. X#define T_QUIT            116    /* quit keyword */
  1771. X#define T_DEFINE        117    /* define keyword */
  1772. X#define T_READ            118    /* read keyword */
  1773. X#define T_SHOW            119    /* show keyword */
  1774. X#define T_HELP            120    /* help keyword */
  1775. X#define T_WRITE            121    /* write keyword */
  1776. X#define T_MAT            122    /* mat keyword */
  1777. X#define T_OBJ            123    /* obj keyword */
  1778. X
  1779. X
  1780. X#define iskeyword(n) ((n) > 100)    /* TRUE if token is a keyword */
  1781. X
  1782. X
  1783. X/*
  1784. X * Flags returned describing results of expression parsing.
  1785. X */
  1786. X#define EXPR_RVALUE    0x0001        /* result is an rvalue */
  1787. X#define EXPR_CONST    0x0002        /* result is constant */
  1788. X#define EXPR_ASSIGN    0x0004        /* result is an assignment */
  1789. X
  1790. X#define isrvalue(n)    ((n) & EXPR_RVALUE)    /* TRUE if expression is rvalue */
  1791. X#define islvalue(n)    (((n) & EXPR_RVALUE) == 0)    /* TRUE if expr is lvalue */
  1792. X#define isconst(n)    ((n) & EXPR_CONST)    /* TRUE if expr is constant */
  1793. X#define isassign(n)    ((n) & EXPR_ASSIGN)    /* TRUE if expr is an assignment */
  1794. X
  1795. X
  1796. X/*
  1797. X * Flags for modes for tokenizing.
  1798. X */
  1799. X#define TM_DEFAULT    0x0        /* normal mode */
  1800. X#define TM_NEWLINES    0x1        /* treat any newline as a token */
  1801. X#define TM_ALLSYMS    0x2        /* treat almost everything as a symbol */
  1802. X
  1803. X
  1804. Xextern long errorcount;        /* number of errors found */
  1805. X
  1806. Xextern char *tokenstring();
  1807. Xextern long tokennumber();
  1808. Xextern void inittokens();       /* initialize all token information */
  1809. Xextern void tokenmode();
  1810. Xextern int gettoken();
  1811. Xextern void rescantoken();
  1812. X
  1813. X#ifdef VARARGS
  1814. Xextern void scanerror();
  1815. X#else
  1816. X# ifdef __STDC__
  1817. Xextern void scanerror(int, char *, ...);
  1818. X# else
  1819. Xextern void scanerror();
  1820. X# endif
  1821. X#endif
  1822. X
  1823. X/* END CODE */
  1824. END_OF_FILE
  1825. if test 4911 -ne `wc -c <'token.h'`; then
  1826.     echo shar: \"'token.h'\" unpacked with wrong size!
  1827. fi
  1828. # end of 'token.h'
  1829. fi
  1830. echo shar: End of archive 3 \(of 21\).
  1831. cp /dev/null ark3isdone
  1832. MISSING=""
  1833. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 ; do
  1834.     if test ! -f ark${I}isdone ; then
  1835.     MISSING="${MISSING} ${I}"
  1836.     fi
  1837. done
  1838. if test "${MISSING}" = "" ; then
  1839.     echo You have unpacked all 21 archives.
  1840.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1841. else
  1842.     echo You still need to unpack the following archives:
  1843.     echo "        " ${MISSING}
  1844. fi
  1845. ##  End of shell archive.
  1846. exit 0
  1847.