home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume40 / bwbasic / part06 < prev    next >
Encoding:
Text File  |  1993-10-29  |  70.3 KB  |  2,389 lines

  1. Newsgroups: comp.sources.misc
  2. From: tcamp@delphi.com (Ted A. Campbell)
  3. Subject: v40i057:  bwbasic - Bywater BASIC interpreter version 2.10, Part06/15
  4. Message-ID: <1993Oct29.162551.3698@sparky.sterling.com>
  5. X-Md4-Signature: 64200060318e96eed1483be3c9a4493c
  6. Sender: kent@sparky.sterling.com (Kent Landfield)
  7. Organization: Sterling Software
  8. Date: Fri, 29 Oct 1993 16:25:51 GMT
  9. Approved: kent@sparky.sterling.com
  10.  
  11. Submitted-by: tcamp@delphi.com (Ted A. Campbell)
  12. Posting-number: Volume 40, Issue 57
  13. Archive-name: bwbasic/part06
  14. Environment: UNIX, DOS
  15. Supersedes: bwbasic: Volume 33, Issue 37-47
  16.  
  17. #! /bin/sh
  18. # This is a shell archive.  Remove anything before this line, then feed it
  19. # into a shell via "sh file" or similar.  To overwrite existing files,
  20. # type "sh file -c".
  21. # Contents:  bwbasic-2.10/COPYING bwbasic-2.10/bwb_ops.c
  22. #   bwbasic-2.10/bwbtest/function.bas
  23. # Wrapped by kent@sparky on Thu Oct 21 10:47:49 1993
  24. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  25. echo If this archive is complete, you will see the following message:
  26. echo '          "shar: End of archive 6 (of 15)."'
  27. if test -f 'bwbasic-2.10/COPYING' -a "${1}" != "-c" ; then 
  28.   echo shar: Will not clobber existing file \"'bwbasic-2.10/COPYING'\"
  29. else
  30.   echo shar: Extracting \"'bwbasic-2.10/COPYING'\" \(17984 characters\)
  31.   sed "s/^X//" >'bwbasic-2.10/COPYING' <<'END_OF_FILE'
  32. X
  33. X            GNU GENERAL PUBLIC LICENSE
  34. X               Version 2, June 1991
  35. X
  36. X Copyright (C) 1989, 1991 Free Software Foundation, Inc.
  37. X                          675 Mass Ave, Cambridge, MA 02139, USA
  38. X Everyone is permitted to copy and distribute verbatim copies
  39. X of this license document, but changing it is not allowed.
  40. X
  41. X                Preamble
  42. X
  43. X  The licenses for most software are designed to take away your
  44. Xfreedom to share and change it.  By contrast, the GNU General Public
  45. XLicense is intended to guarantee your freedom to share and change free
  46. Xsoftware--to make sure the software is free for all its users.  This
  47. XGeneral Public License applies to most of the Free Software
  48. XFoundation's software and to any other program whose authors commit to
  49. Xusing it.  (Some other Free Software Foundation software is covered by
  50. Xthe GNU Library General Public License instead.)  You can apply it to
  51. Xyour programs, too.
  52. X
  53. X  When we speak of free software, we are referring to freedom, not
  54. Xprice.  Our General Public Licenses are designed to make sure that you
  55. Xhave the freedom to distribute copies of free software (and charge for
  56. Xthis service if you wish), that you receive source code or can get it
  57. Xif you want it, that you can change the software or use pieces of it
  58. Xin new free programs; and that you know you can do these things.
  59. X
  60. X  To protect your rights, we need to make restrictions that forbid
  61. Xanyone to deny you these rights or to ask you to surrender the rights.
  62. XThese restrictions translate to certain responsibilities for you if you
  63. Xdistribute copies of the software, or if you modify it.
  64. X
  65. X  For example, if you distribute copies of such a program, whether
  66. Xgratis or for a fee, you must give the recipients all the rights that
  67. Xyou have.  You must make sure that they, too, receive or can get the
  68. Xsource code.  And you must show them these terms so they know their
  69. Xrights.
  70. X
  71. X  We protect your rights with two steps: (1) copyright the software, and
  72. X(2) offer you this license which gives you legal permission to copy,
  73. Xdistribute and/or modify the software.
  74. X
  75. X  Also, for each author's protection and ours, we want to make certain
  76. Xthat everyone understands that there is no warranty for this free
  77. Xsoftware.  If the software is modified by someone else and passed on, we
  78. Xwant its recipients to know that what they have is not the original, so
  79. Xthat any problems introduced by others will not reflect on the original
  80. Xauthors' reputations.
  81. X
  82. X  Finally, any free program is threatened constantly by software
  83. Xpatents.  We wish to avoid the danger that redistributors of a free
  84. Xprogram will individually obtain patent licenses, in effect making the
  85. Xprogram proprietary.  To prevent this, we have made it clear that any
  86. Xpatent must be licensed for everyone's free use or not licensed at all.
  87. X
  88. X  The precise terms and conditions for copying, distribution and
  89. Xmodification follow.
  90. X
  91. X            GNU GENERAL PUBLIC LICENSE
  92. X   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
  93. X
  94. X  0. This License applies to any program or other work which contains
  95. Xa notice placed by the copyright holder saying it may be distributed
  96. Xunder the terms of this General Public License.  The "Program", below,
  97. Xrefers to any such program or work, and a "work based on the Program"
  98. Xmeans either the Program or any derivative work under copyright law:
  99. Xthat is to say, a work containing the Program or a portion of it,
  100. Xeither verbatim or with modifications and/or translated into another
  101. Xlanguage.  (Hereinafter, translation is included without limitation in
  102. Xthe term "modification".)  Each licensee is addressed as "you".
  103. X
  104. XActivities other than copying, distribution and modification are not
  105. Xcovered by this License; they are outside its scope.  The act of
  106. Xrunning the Program is not restricted, and the output from the Program
  107. Xis covered only if its contents constitute a work based on the
  108. XProgram (independent of having been made by running the Program).
  109. XWhether that is true depends on what the Program does.
  110. X
  111. X  1. You may copy and distribute verbatim copies of the Program's
  112. Xsource code as you receive it, in any medium, provided that you
  113. Xconspicuously and appropriately publish on each copy an appropriate
  114. Xcopyright notice and disclaimer of warranty; keep intact all the
  115. Xnotices that refer to this License and to the absence of any warranty;
  116. Xand give any other recipients of the Program a copy of this License
  117. Xalong with the Program.
  118. X
  119. XYou may charge a fee for the physical act of transferring a copy, and
  120. Xyou may at your option offer warranty protection in exchange for a fee.
  121. X
  122. X  2. You may modify your copy or copies of the Program or any portion
  123. Xof it, thus forming a work based on the Program, and copy and
  124. Xdistribute such modifications or work under the terms of Section 1
  125. Xabove, provided that you also meet all of these conditions:
  126. X
  127. X    a) You must cause the modified files to carry prominent notices
  128. X    stating that you changed the files and the date of any change.
  129. X
  130. X    b) You must cause any work that you distribute or publish, that in
  131. X    whole or in part contains or is derived from the Program or any
  132. X    part thereof, to be licensed as a whole at no charge to all third
  133. X    parties under the terms of this License.
  134. X
  135. X    c) If the modified program normally reads commands interactively
  136. X    when run, you must cause it, when started running for such
  137. X    interactive use in the most ordinary way, to print or display an
  138. X    announcement including an appropriate copyright notice and a
  139. X    notice that there is no warranty (or else, saying that you provide
  140. X    a warranty) and that users may redistribute the program under
  141. X    these conditions, and telling the user how to view a copy of this
  142. X    License.  (Exception: if the Program itself is interactive but
  143. X    does not normally print such an announcement, your work based on
  144. X    the Program is not required to print an announcement.)
  145. X
  146. XThese requirements apply to the modified work as a whole.  If
  147. Xidentifiable sections of that work are not derived from the Program,
  148. Xand can be reasonably considered independent and separate works in
  149. Xthemselves, then this License, and its terms, do not apply to those
  150. Xsections when you distribute them as separate works.  But when you
  151. Xdistribute the same sections as part of a whole which is a work based
  152. Xon the Program, the distribution of the whole must be on the terms of
  153. Xthis License, whose permissions for other licensees extend to the
  154. Xentire whole, and thus to each and every part regardless of who wrote it.
  155. X
  156. XThus, it is not the intent of this section to claim rights or contest
  157. Xyour rights to work written entirely by you; rather, the intent is to
  158. Xexercise the right to control the distribution of derivative or
  159. Xcollective works based on the Program.
  160. X
  161. XIn addition, mere aggregation of another work not based on the Program
  162. Xwith the Program (or with a work based on the Program) on a volume of
  163. Xa storage or distribution medium does not bring the other work under
  164. Xthe scope of this License.
  165. X
  166. X  3. You may copy and distribute the Program (or a work based on it,
  167. Xunder Section 2) in object code or executable form under the terms of
  168. XSections 1 and 2 above provided that you also do one of the following:
  169. X
  170. X    a) Accompany it with the complete corresponding machine-readable
  171. X    source code, which must be distributed under the terms of Sections
  172. X    1 and 2 above on a medium customarily used for software interchange; or,
  173. X
  174. X    b) Accompany it with a written offer, valid for at least three
  175. X    years, to give any third party, for a charge no more than your
  176. X    cost of physically performing source distribution, a complete
  177. X    machine-readable copy of the corresponding source code, to be
  178. X    distributed under the terms of Sections 1 and 2 above on a medium
  179. X    customarily used for software interchange; or,
  180. X
  181. X    c) Accompany it with the information you received as to the offer
  182. X    to distribute corresponding source code.  (This alternative is
  183. X    allowed only for noncommercial distribution and only if you
  184. X    received the program in object code or executable form with such
  185. X    an offer, in accord with Subsection b above.)
  186. X
  187. XThe source code for a work means the preferred form of the work for
  188. Xmaking modifications to it.  For an executable work, complete source
  189. Xcode means all the source code for all modules it contains, plus any
  190. Xassociated interface definition files, plus the scripts used to
  191. Xcontrol compilation and installation of the executable.  However, as a
  192. Xspecial exception, the source code distributed need not include
  193. Xanything that is normally distributed (in either source or binary
  194. Xform) with the major components (compiler, kernel, and so on) of the
  195. Xoperating system on which the executable runs, unless that component
  196. Xitself accompanies the executable.
  197. X
  198. XIf distribution of executable or object code is made by offering
  199. Xaccess to copy from a designated place, then offering equivalent
  200. Xaccess to copy the source code from the same place counts as
  201. Xdistribution of the source code, even though third parties are not
  202. Xcompelled to copy the source along with the object code.
  203. X
  204. X  4. You may not copy, modify, sublicense, or distribute the Program
  205. Xexcept as expressly provided under this License.  Any attempt
  206. Xotherwise to copy, modify, sublicense or distribute the Program is
  207. Xvoid, and will automatically terminate your rights under this License.
  208. XHowever, parties who have received copies, or rights, from you under
  209. Xthis License will not have their licenses terminated so long as such
  210. Xparties remain in full compliance.
  211. X
  212. X  5. You are not required to accept this License, since you have not
  213. Xsigned it.  However, nothing else grants you permission to modify or
  214. Xdistribute the Program or its derivative works.  These actions are
  215. Xprohibited by law if you do not accept this License.  Therefore, by
  216. Xmodifying or distributing the Program (or any work based on the
  217. XProgram), you indicate your acceptance of this License to do so, and
  218. Xall its terms and conditions for copying, distributing or modifying
  219. Xthe Program or works based on it.
  220. X
  221. X  6. Each time you redistribute the Program (or any work based on the
  222. XProgram), the recipient automatically receives a license from the
  223. Xoriginal licensor to copy, distribute or modify the Program subject to
  224. Xthese terms and conditions.  You may not impose any further
  225. Xrestrictions on the recipients' exercise of the rights granted herein.
  226. XYou are not responsible for enforcing compliance by third parties to
  227. Xthis License.
  228. X
  229. X  7. If, as a consequence of a court judgment or allegation of patent
  230. Xinfringement or for any other reason (not limited to patent issues),
  231. Xconditions are imposed on you (whether by court order, agreement or
  232. Xotherwise) that contradict the conditions of this License, they do not
  233. Xexcuse you from the conditions of this License.  If you cannot
  234. Xdistribute so as to satisfy simultaneously your obligations under this
  235. XLicense and any other pertinent obligations, then as a consequence you
  236. Xmay not distribute the Program at all.  For example, if a patent
  237. Xlicense would not permit royalty-free redistribution of the Program by
  238. Xall those who receive copies directly or indirectly through you, then
  239. Xthe only way you could satisfy both it and this License would be to
  240. Xrefrain entirely from distribution of the Program.
  241. X
  242. XIf any portion of this section is held invalid or unenforceable under
  243. Xany particular circumstance, the balance of the section is intended to
  244. Xapply and the section as a whole is intended to apply in other
  245. Xcircumstances.
  246. X
  247. XIt is not the purpose of this section to induce you to infringe any
  248. Xpatents or other property right claims or to contest validity of any
  249. Xsuch claims; this section has the sole purpose of protecting the
  250. Xintegrity of the free software distribution system, which is
  251. Ximplemented by public license practices.  Many people have made
  252. Xgenerous contributions to the wide range of software distributed
  253. Xthrough that system in reliance on consistent application of that
  254. Xsystem; it is up to the author/donor to decide if he or she is willing
  255. Xto distribute software through any other system and a licensee cannot
  256. Ximpose that choice.
  257. X
  258. XThis section is intended to make thoroughly clear what is believed to
  259. Xbe a consequence of the rest of this License.
  260. X
  261. X  8. If the distribution and/or use of the Program is restricted in
  262. Xcertain countries either by patents or by copyrighted interfaces, the
  263. Xoriginal copyright holder who places the Program under this License
  264. Xmay add an explicit geographical distribution limitation excluding
  265. Xthose countries, so that distribution is permitted only in or among
  266. Xcountries not thus excluded.  In such case, this License incorporates
  267. Xthe limitation as if written in the body of this License.
  268. X
  269. X  9. The Free Software Foundation may publish revised and/or new versions
  270. Xof the General Public License from time to time.  Such new versions will
  271. Xbe similar in spirit to the present version, but may differ in detail to
  272. Xaddress new problems or concerns.
  273. X
  274. XEach version is given a distinguishing version number.  If the Program
  275. Xspecifies a version number of this License which applies to it and "any
  276. Xlater version", you have the option of following the terms and conditions
  277. Xeither of that version or of any later version published by the Free
  278. XSoftware Foundation.  If the Program does not specify a version number of
  279. Xthis License, you may choose any version ever published by the Free Software
  280. XFoundation.
  281. X
  282. X  10. If you wish to incorporate parts of the Program into other free
  283. Xprograms whose distribution conditions are different, write to the author
  284. Xto ask for permission.  For software which is copyrighted by the Free
  285. XSoftware Foundation, write to the Free Software Foundation; we sometimes
  286. Xmake exceptions for this.  Our decision will be guided by the two goals
  287. Xof preserving the free status of all derivatives of our free software and
  288. Xof promoting the sharing and reuse of software generally.
  289. X
  290. X                NO WARRANTY
  291. X
  292. X  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
  293. XFOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
  294. XOTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
  295. XPROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
  296. XOR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  297. XMERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
  298. XTO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
  299. XPROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
  300. XREPAIR OR CORRECTION.
  301. X
  302. X  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
  303. XWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
  304. XREDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
  305. XINCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
  306. XOUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
  307. XTO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
  308. XYOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
  309. XPROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
  310. XPOSSIBILITY OF SUCH DAMAGES.
  311. X
  312. X             END OF TERMS AND CONDITIONS
  313. X
  314. X    Appendix: How to Apply These Terms to Your New Programs
  315. X
  316. X  If you develop a new program, and you want it to be of the greatest
  317. Xpossible use to the public, the best way to achieve this is to make it
  318. Xfree software which everyone can redistribute and change under these terms.
  319. X
  320. X  To do so, attach the following notices to the program.  It is safest
  321. Xto attach them to the start of each source file to most effectively
  322. Xconvey the exclusion of warranty; and each file should have at least
  323. Xthe "copyright" line and a pointer to where the full notice is found.
  324. X
  325. X    <one line to give the program's name and a brief idea of what it does.>
  326. X    Copyright (C) 19yy  <name of author>
  327. X
  328. X    This program is free software; you can redistribute it and/or modify
  329. X    it under the terms of the GNU General Public License as published by
  330. X    the Free Software Foundation; either version 2 of the License, or
  331. X    (at your option) any later version.
  332. X
  333. X    This program is distributed in the hope that it will be useful,
  334. X    but WITHOUT ANY WARRANTY; without even the implied warranty of
  335. X    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  336. X    GNU General Public License for more details.
  337. X
  338. X    You should have received a copy of the GNU General Public License
  339. X    along with this program; if not, write to the Free Software
  340. X    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  341. X
  342. XAlso add information on how to contact you by electronic and paper mail.
  343. X
  344. XIf the program is interactive, make it output a short notice like this
  345. Xwhen it starts in an interactive mode:
  346. X
  347. X    Gnomovision version 69, Copyright (C) 19yy name of author
  348. X    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
  349. X    This is free software, and you are welcome to redistribute it
  350. X    under certain conditions; type `show c' for details.
  351. X
  352. XThe hypothetical commands `show w' and `show c' should show the appropriate
  353. Xparts of the General Public License.  Of course, the commands you use may
  354. Xbe called something other than `show w' and `show c'; they could even be
  355. Xmouse-clicks or menu items--whatever suits your program.
  356. X
  357. XYou should also get your employer (if you work as a programmer) or your
  358. Xschool, if any, to sign a "copyright disclaimer" for the program, if
  359. Xnecessary.  Here is a sample; alter the names:
  360. X
  361. X  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
  362. X  `Gnomovision' (which makes passes at compilers) written by James Hacker.
  363. X
  364. X  <signature of Ty Coon>, 1 April 1989
  365. X  Ty Coon, President of Vice
  366. X
  367. XThis General Public License does not permit incorporating your program into
  368. Xproprietary programs.  If your program is a subroutine library, you may
  369. Xconsider it more useful to permit linking proprietary applications with the
  370. Xlibrary.  If this is what you want to do, use the GNU Library General
  371. XPublic License instead of this License.
  372. X
  373. END_OF_FILE
  374.   if test 17984 -ne `wc -c <'bwbasic-2.10/COPYING'`; then
  375.     echo shar: \"'bwbasic-2.10/COPYING'\" unpacked with wrong size!
  376.   fi
  377.   # end of 'bwbasic-2.10/COPYING'
  378. fi
  379. if test -f 'bwbasic-2.10/bwb_ops.c' -a "${1}" != "-c" ; then 
  380.   echo shar: Will not clobber existing file \"'bwbasic-2.10/bwb_ops.c'\"
  381. else
  382.   echo shar: Extracting \"'bwbasic-2.10/bwb_ops.c'\" \(46972 characters\)
  383.   sed "s/^X//" >'bwbasic-2.10/bwb_ops.c' <<'END_OF_FILE'
  384. X/****************************************************************
  385. X
  386. X        bwb_ops.c       Expression Parsing Operations
  387. X                        for Bywater BASIC Interpreter
  388. X
  389. X                        Copyright (c) 1993, Ted A. Campbell
  390. X                        Bywater Software
  391. X
  392. X                        email: tcamp@delphi.com
  393. X
  394. X        Copyright and Permissions Information:
  395. X
  396. X        All U.S. and international rights are claimed by the author,
  397. X        Ted A. Campbell.
  398. X
  399. X    This software is released under the terms of the GNU General
  400. X    Public License (GPL), which is distributed with this software
  401. X    in the file "COPYING".  The GPL specifies the terms under
  402. X    which users may copy and use the software in this distribution.
  403. X
  404. X    A separate license is available for commercial distribution,
  405. X    for information on which you should contact the author.
  406. X
  407. X****************************************************************/
  408. X
  409. X#include <stdio.h>
  410. X#include <ctype.h>
  411. X#include <math.h>
  412. X
  413. X#include "bwbasic.h"
  414. X#include "bwb_mes.h"
  415. X
  416. X/* declarations for functions visible in this file only */
  417. X
  418. X#if ANSI_C
  419. Xstatic int op_oplevel( int level );
  420. Xstatic int op_add( int level, int precision );
  421. Xstatic int op_subtract( int level, int precision );
  422. Xstatic int op_multiply( int level, int precision );
  423. Xstatic int op_divide( int level, int precision );
  424. Xstatic int op_assign( int level, int precision );
  425. Xstatic int op_equals( int level, int precision );
  426. Xstatic int op_lessthan( int level, int precision );
  427. Xstatic int op_greaterthan( int level, int precision );
  428. Xstatic int op_lteq( int level, int precision );
  429. Xstatic int op_gteq( int level, int precision );
  430. Xstatic int op_notequal( int level, int precision );
  431. Xstatic int op_modulus( int level, int precision );
  432. Xstatic int op_exponent( int level, int precision );
  433. Xstatic int op_intdiv( int level, int precision );
  434. Xstatic int op_or( int level, int precision );
  435. Xstatic int op_and( int level, int precision );
  436. Xstatic int op_not( int level, int precision );
  437. Xstatic int op_xor( int level, int precision );
  438. Xstatic int op_islevelstr( int level );
  439. Xstatic int op_getprecision( int level );
  440. Xstatic int op_isoperator( int operation );
  441. Xstatic int op_pulldown( int how_far );
  442. X#else
  443. Xstatic int op_oplevel();
  444. Xstatic int op_add();
  445. Xstatic int op_subtract();
  446. Xstatic int op_multiply();
  447. Xstatic int op_divide();
  448. Xstatic int op_assign();
  449. Xstatic int op_equals();
  450. Xstatic int op_lessthan();
  451. Xstatic int op_greaterthan();
  452. Xstatic int op_lteq();
  453. Xstatic int op_gteq();
  454. Xstatic int op_notequal();
  455. Xstatic int op_modulus();
  456. Xstatic int op_exponent();
  457. Xstatic int op_intdiv();
  458. Xstatic int op_or();
  459. Xstatic int op_and();
  460. Xstatic int op_not();
  461. Xstatic int op_xor();
  462. Xstatic int op_islevelstr();
  463. Xstatic int op_getprecision();
  464. Xstatic int op_isoperator();
  465. Xstatic int op_pulldown();
  466. X#endif                /* ANSI_C for prototypes */
  467. X
  468. Xstatic int op_level;
  469. X
  470. X/***************************************************************
  471. X
  472. X    FUNCTION:       exp_operation()
  473. X
  474. X    DESCRIPTION:    This function performs whatever operations
  475. X            are necessary at the end of function bwb_exp()
  476. X            (i.e., the end of the parsing of an expression;
  477. X            see file bwb_exp.c).
  478. X
  479. X***************************************************************/
  480. X
  481. X#if ANSI_C
  482. Xint
  483. Xexp_operation( int entry_level )
  484. X#else
  485. Xint
  486. Xexp_operation( entry_level )
  487. X   int entry_level;
  488. X#endif
  489. X   {
  490. X   register int precedence;
  491. X   int operator;
  492. X
  493. X#if INTENSIVE_DEBUG
  494. X   sprintf( bwb_ebuf, "in exp_operation(): entered function." );
  495. X   bwb_debug( bwb_ebuf );
  496. X#endif
  497. X
  498. X   /* cycle through all levels of precedence and perform required
  499. X      operations */
  500. X
  501. X   for ( precedence = 0; precedence <= MAX_PRECEDENCE; ++precedence )
  502. X      {
  503. X
  504. X      /* Operation loop: cycle through every level above entry level
  505. X         and perform required operations as needed */
  506. X
  507. X      op_level = entry_level + 1;
  508. X      while( ( op_level < CURTASK expsc )
  509. X         && ( op_isoperator( CURTASK exps[ op_level ].operation ) == FALSE ))
  510. X         {
  511. X         ++op_level;
  512. X         }
  513. X
  514. X      while ( ( op_level > entry_level ) && ( op_level < CURTASK expsc ) )
  515. X         {
  516. X
  517. X         /* see if the operation at this level is an operator with the
  518. X            appropriate precedence level by running through the table
  519. X            of operators */
  520. X
  521. X         for ( operator = 0; operator < N_OPERATORS; ++operator )
  522. X            {
  523. X
  524. X            if ( exp_ops[ operator ].operation == CURTASK exps[ op_level ].operation )
  525. X               {
  526. X
  527. X               /* check for appropriate level of precedence */
  528. X
  529. X               if ( exp_ops[ operator ].precedence == precedence )
  530. X                  {
  531. X
  532. X#if INTENSIVE_DEBUG
  533. X                  sprintf( bwb_ebuf, "in exp_operation(): level <%d> operation <%d>",
  534. X                     op_level, CURTASK exps[ op_level ].operation );
  535. X                  bwb_debug( bwb_ebuf );
  536. X#endif
  537. X
  538. X                  op_oplevel( op_level );     /* perform the operation */
  539. X
  540. X                  }
  541. X               }
  542. X            }
  543. X
  544. X         /* advance level if appropriate; one must check, however, since
  545. X            the op_oplevel() function may have decremented CURTASK expsc */
  546. X
  547. X         if ( op_level < CURTASK expsc )
  548. X            {
  549. X            ++op_level;
  550. X
  551. X#if INTENSIVE_DEBUG
  552. X            sprintf( bwb_ebuf, "in exp_operation() first increment op_level to <%d>",
  553. X               op_level );
  554. X            bwb_debug( bwb_ebuf );
  555. X#endif
  556. X
  557. X            while ( ( op_isoperator( CURTASK exps [ op_level ].operation ) == FALSE )
  558. X               && ( op_level < CURTASK expsc ) )
  559. X               {
  560. X               ++op_level;
  561. X
  562. X#if INTENSIVE_DEBUG
  563. X               sprintf( bwb_ebuf, "in exp_operation() further increment op_level to <%d>",
  564. X                  op_level );
  565. X               bwb_debug( bwb_ebuf );
  566. X#endif
  567. X
  568. X               }
  569. X            }                           /* end of increment of op_level */
  570. X
  571. X         }                              /* end of for loop for stack levels */
  572. X
  573. X      }                                 /* end of for loop for precedence levels */
  574. X
  575. X   return TRUE;
  576. X
  577. X   }                                    /* end of function exp_operation() */
  578. X
  579. X
  580. X/***************************************************************
  581. X
  582. X    FUNCTION:       op_oplevel()
  583. X
  584. X    DESCRIPTION:    This function performs a specific operation
  585. X            at a specific level as the expression parser
  586. X            resolves its arguments.
  587. X
  588. X***************************************************************/
  589. X
  590. X#if ANSI_C
  591. Xstatic int
  592. Xop_oplevel( int level )
  593. X#else
  594. Xstatic int
  595. Xop_oplevel( level )
  596. X   int level;
  597. X#endif
  598. X   {
  599. X   int precision;
  600. X
  601. X   /* set the precision */
  602. X
  603. X   if ( ( precision = op_getprecision( level ) ) == OP_ERROR )
  604. X      {
  605. X#if PROG_ERRORS
  606. X      sprintf( bwb_ebuf, "exp_operation(): failed to set precision." );
  607. X      bwb_error( bwb_ebuf );
  608. X#else
  609. X      bwb_error( err_mismatch );            /*** ??? ***/
  610. X#endif
  611. X      op_pulldown( 2 );
  612. X      }
  613. X
  614. X   /* precision is set correctly */
  615. X
  616. X   else
  617. X      {
  618. X#if INTENSIVE_DEBUG
  619. X      sprintf( bwb_ebuf, "in op_oplevel(): level <%d>, precision <%c>",
  620. X         level, precision );
  621. X      bwb_debug( bwb_ebuf );
  622. X#endif
  623. X
  624. X      switch ( CURTASK exps[ level ].operation )
  625. X         {
  626. X         case OP_ADD:
  627. X            op_add( level, precision );
  628. X            break;
  629. X
  630. X         case OP_SUBTRACT:
  631. X            op_subtract( level, precision );
  632. X            break;
  633. X
  634. X         case OP_MULTIPLY:
  635. X            op_multiply( level, precision );
  636. X            break;
  637. X
  638. X         case OP_DIVIDE:
  639. X            op_divide( level, precision );
  640. X            break;
  641. X
  642. X         case OP_ASSIGN:
  643. X            op_assign( level, precision );
  644. X            break;
  645. X
  646. X         case OP_EQUALS:
  647. X            op_equals( level, precision );
  648. X            break;
  649. X
  650. X         case OP_LESSTHAN:
  651. X            op_lessthan( level, precision );
  652. X            break;
  653. X
  654. X         case OP_GREATERTHAN:
  655. X            op_greaterthan( level, precision );
  656. X            break;
  657. X
  658. X         case OP_LTEQ:
  659. X            op_lteq( level, precision );
  660. X            break;
  661. X
  662. X         case OP_GTEQ:
  663. X            op_gteq( level, precision );
  664. X            break;
  665. X
  666. X         case OP_NOTEQUAL:
  667. X            op_notequal( level, precision );
  668. X            break;
  669. X
  670. X         case OP_MODULUS:
  671. X            op_modulus( level, precision );
  672. X            break;
  673. X
  674. X         case OP_INTDIVISION:
  675. X            op_intdiv( level, precision );
  676. X            break;
  677. X
  678. X         case OP_OR:
  679. X            op_or( level, precision );
  680. X            break;
  681. X
  682. X         case OP_AND:
  683. X            op_and( level, precision );
  684. X            break;
  685. X
  686. X         case OP_NOT:
  687. X            op_not( level, precision );
  688. X            break;
  689. X
  690. X         case OP_XOR:
  691. X            op_xor( level, precision );
  692. X            break;
  693. X
  694. X         case OP_EXPONENT:
  695. X            op_exponent( level, precision );
  696. X            break;
  697. X
  698. X         default:
  699. X#if PROG_ERRORS
  700. X            sprintf( bwb_ebuf, "PROGRAMMING ERROR: operator <%d> not (yet) supported.", CURTASK exps[ level ].operation );
  701. X            op_pulldown( 2 );
  702. X            bwb_error( bwb_ebuf );
  703. X#else
  704. X            bwb_error( err_syntax );
  705. X#endif
  706. X            break;
  707. X         }                              /* end of case statement for operators */
  708. X      }                                 /* end of else statement, precision set */
  709. X
  710. X   return TRUE;
  711. X
  712. X   }                                    /* end of function op_oplevel() */
  713. X
  714. X/***************************************************************
  715. X
  716. X    FUNCTION:       op_isoperator()
  717. X
  718. X    DESCRIPTION:    This function detects whether its argument
  719. X            is an operator.
  720. X
  721. X***************************************************************/
  722. X
  723. X#if ANSI_C
  724. Xstatic int
  725. Xop_isoperator( int operation )
  726. X#else
  727. Xstatic int
  728. Xop_isoperator( operation )
  729. X   int operation;
  730. X#endif
  731. X   {
  732. X   register int c;
  733. X
  734. X   for( c = 0; c < N_OPERATORS; ++c )
  735. X      {
  736. X      if ( operation == exp_ops[ c ].operation )
  737. X         {
  738. X
  739. X#if INTENSIVE_DEBUG
  740. X         sprintf( bwb_ebuf, "in op_isoperator(): found match <%s>",
  741. X            exp_ops[ c ].symbol );
  742. X         bwb_debug( bwb_ebuf );
  743. X#endif
  744. X
  745. X         return TRUE;
  746. X         }
  747. X      }
  748. X
  749. X   /* test failed; return FALSE */
  750. X
  751. X#if INTENSIVE_DEBUG
  752. X   sprintf( bwb_ebuf, "in op_isoperator(): no match found for operation <%d>",
  753. X      operation );
  754. X   bwb_debug( bwb_ebuf );
  755. X#endif
  756. X
  757. X   return FALSE;
  758. X
  759. X   }
  760. X
  761. X/***************************************************************
  762. X
  763. X        FUNCTION:       op_add()
  764. X
  765. X        DESCRIPTION:      This function adds two numbers or
  766. X                concatenates two strings.
  767. X
  768. X***************************************************************/
  769. X
  770. X#if ANSI_C
  771. Xstatic int
  772. Xop_add( int level, int precision )
  773. X#else
  774. Xstatic int
  775. Xop_add( level, precision )
  776. X   int level;
  777. X   int precision;
  778. X#endif
  779. X   {
  780. X   int error_condition;
  781. X
  782. X   error_condition = FALSE;
  783. X
  784. X   switch( precision )
  785. X      {
  786. X      case STRING:
  787. X
  788. X         /* both sides of the operation should be strings for
  789. X            string addition; if not, report an error */
  790. X
  791. X         if (  ( op_islevelstr( level - 1 ) != TRUE )
  792. X            || ( op_islevelstr( level + 1 ) != TRUE ) )
  793. X            {
  794. X#if PROG_ERRORS
  795. X            sprintf( bwb_ebuf, "in op_add(): Type mismatch in string addition." );
  796. X            bwb_error( bwb_ebuf );
  797. X#else
  798. X            bwb_error( err_mismatch );
  799. X#endif
  800. X            error_condition = TRUE;
  801. X            }
  802. X
  803. X         /* concatenate the two strings */
  804. X
  805. X         if ( error_condition == FALSE )
  806. X            {
  807. X
  808. X#if INTENSIVE_DEBUG
  809. X            sprintf( bwb_ebuf, "in op_add(): try exp_getsval(), level <%d> op <%d> type <%c>:",
  810. X               level - 1, CURTASK exps[ level - 1 ].operation, CURTASK exps[ level - 1 ].type );
  811. X            bwb_debug( bwb_ebuf );
  812. X            exp_getsval( &( CURTASK exps[ level - 1 ] ));
  813. X            sprintf( bwb_ebuf, "in op_add(): try exp_getsval(), level <%d> op <%d> type <%c>:",
  814. X               level + 1, CURTASK exps[ level + 1 ].operation, CURTASK exps[ level + 1 ].type );
  815. X            bwb_debug( bwb_ebuf );
  816. X            exp_getsval( &( CURTASK exps[ level + 1 ] ));
  817. X            sprintf( bwb_ebuf, "in op_add(): string addition, exp_getsval()s completed" );
  818. X            bwb_debug( bwb_ebuf );
  819. X#endif
  820. X
  821. X            str_cat( exp_getsval( &( CURTASK exps[ level - 1 ] ) ), 
  822. X               exp_getsval( &( CURTASK exps[ level + 1 ] ) ) );
  823. X
  824. X#if INTENSIVE_DEBUG
  825. X            sprintf( bwb_ebuf, "in op_add(): str_cat() returns <%d>-byte string to level <%d>",
  826. X               exp_getsval( &( CURTASK exps[ level - 1 ] ) )->length, level - 1 );
  827. X            bwb_debug( bwb_ebuf );
  828. X#endif
  829. X            }
  830. X
  831. X         break;
  832. X
  833. X      case NUMBER:
  834. X         CURTASK exps[ level - 1 ].nval
  835. X            = exp_getnval( &( CURTASK exps[ level - 1 ] ))
  836. X            + exp_getnval( &( CURTASK exps[ level + 1 ] ));
  837. X         CURTASK exps[ level - 1 ].operation = NUMBER;
  838. X         break;
  839. X
  840. X      }
  841. X
  842. X   /* set variable to requested precision */
  843. X
  844. X   CURTASK exps[ level - 1 ].type = (char) precision;
  845. X
  846. X#if INTENSIVE_DEBUG
  847. X   sprintf( bwb_ebuf, "in op_add() returns with operation <%d> type <%c>",
  848. X      CURTASK exps[ level - 1 ].operation, CURTASK exps[ level - 1 ].type );
  849. X   bwb_debug( bwb_ebuf );
  850. X#endif
  851. X
  852. X   /* decrement the stack twice */
  853. X
  854. X   op_pulldown( 2 );
  855. X
  856. X   return TRUE;
  857. X
  858. X   }
  859. X
  860. X/***************************************************************
  861. X
  862. X    FUNCTION:       op_subtract()
  863. X
  864. X    DESCRIPTION:    This function subtracts the number on
  865. X            the left from the number on the right.
  866. X
  867. X***************************************************************/
  868. X
  869. X#if ANSI_C
  870. Xstatic int
  871. Xop_subtract( int level, int precision )
  872. X#else
  873. Xstatic int
  874. Xop_subtract( level, precision )
  875. X   int level;
  876. X   int precision;
  877. X#endif
  878. X   {
  879. X
  880. X   switch( precision )
  881. X      {
  882. X      case STRING:
  883. X
  884. X         /* both sides of the operation should be numbers for
  885. X            string addition; if not, report an error */
  886. X
  887. X#if PROG_ERRORS
  888. X         sprintf( bwb_ebuf, "Strings cannot be subtracted." );
  889. X         bwb_error( bwb_ebuf );
  890. X#else
  891. X         bwb_error( err_mismatch );
  892. X#endif
  893. X
  894. X         break;
  895. X
  896. X      case NUMBER:
  897. X         CURTASK exps[ level - 1 ].nval
  898. X            = exp_getnval( &( CURTASK exps[ level - 1 ] ))
  899. X            - exp_getnval( &( CURTASK exps[ level + 1 ] ));
  900. X         break;
  901. X
  902. X      }
  903. X
  904. X   /* set variable to requested precision */
  905. X
  906. X   CURTASK exps[ level - 1 ].type = (char) precision;
  907. X   CURTASK exps[ level - 1 ].operation = NUMBER;
  908. X
  909. X   /* decrement the stack twice */
  910. X
  911. X   op_pulldown( 2 );
  912. X
  913. X   return TRUE;
  914. X
  915. X   }
  916. X
  917. X/***************************************************************
  918. X
  919. X    FUNCTION:       op_multiply()
  920. X
  921. X    DESCRIPTION:    This function multiplies the number on
  922. X            the left by the number on the right.
  923. X
  924. X***************************************************************/
  925. X
  926. X#if ANSI_C
  927. Xstatic int
  928. Xop_multiply( int level, int precision )
  929. X#else
  930. Xstatic int
  931. Xop_multiply( level, precision )
  932. X   int level;
  933. X   int precision;
  934. X#endif
  935. X   {
  936. X
  937. X   switch( precision )
  938. X      {
  939. X      case STRING:
  940. X
  941. X         /* both sides of the operation should be numbers for
  942. X            string addition; if not, report an error */
  943. X
  944. X#if PROG_ERRORS
  945. X         sprintf( bwb_ebuf, "Strings cannot be multiplied." );
  946. X         bwb_error( bwb_ebuf );
  947. X#else
  948. X         bwb_error( err_mismatch );
  949. X#endif
  950. X
  951. X         break;
  952. X
  953. X      case NUMBER:
  954. X         CURTASK exps[ level - 1 ].nval
  955. X            = exp_getnval( &( CURTASK exps[ level - 1 ] ))
  956. X            * exp_getnval( &( CURTASK exps[ level + 1 ] ));
  957. X         break;
  958. X
  959. X      }
  960. X
  961. X   /* set variable to requested precision */
  962. X
  963. X   CURTASK exps[ level - 1 ].type = (char) precision;
  964. X   CURTASK exps[ level - 1 ].operation = NUMBER;
  965. X
  966. X   /* decrement the stack twice */
  967. X
  968. X   op_pulldown( 2 );
  969. X
  970. X   return TRUE;
  971. X
  972. X   }
  973. X
  974. X/***************************************************************
  975. X
  976. X    FUNCTION:       op_divide()
  977. X
  978. X    DESCRIPTION:    This function divides the number on
  979. X            the left by the number on the right.
  980. X
  981. X***************************************************************/
  982. X
  983. X#if ANSI_C
  984. Xstatic int
  985. Xop_divide( int level, int precision )
  986. X#else
  987. Xstatic int
  988. Xop_divide( level, precision )
  989. X   int level;
  990. X   int precision;
  991. X#endif
  992. X   {
  993. X
  994. X   switch( precision )
  995. X      {
  996. X      case STRING:
  997. X
  998. X         /* both sides of the operation should be numbers for
  999. X            division; if not, report an error */
  1000. X
  1001. X#if PROG_ERRORS
  1002. X         sprintf( bwb_ebuf, "Strings cannot be divided." );
  1003. X         bwb_error( bwb_ebuf );
  1004. X#else
  1005. X         bwb_error( err_mismatch );
  1006. X#endif
  1007. X
  1008. X         break;
  1009. X
  1010. X      case NUMBER:
  1011. X         if ( exp_getnval( &( CURTASK exps[ level + 1 ] ))
  1012. X            == (bnumber) 0 )
  1013. X            {
  1014. X            CURTASK exps[ level - 1 ].nval = (bnumber) -1.0;
  1015. X            op_pulldown( 2 );
  1016. X#if PROG_ERRORS
  1017. X            sprintf( bwb_ebuf, "Divide by 0." );
  1018. X            bwb_error( bwb_ebuf );
  1019. X#else
  1020. X            bwb_error( err_dbz );
  1021. X#endif
  1022. X            return FALSE;
  1023. X            }
  1024. X         CURTASK exps[ level - 1 ].nval
  1025. X            = exp_getnval( &( CURTASK exps[ level - 1 ] ))
  1026. X            / exp_getnval( &( CURTASK exps[ level + 1 ] ));
  1027. X         break;
  1028. X      }
  1029. X
  1030. X   /* set variable to requested precision */
  1031. X
  1032. X   CURTASK exps[ level - 1 ].type = (char) precision;
  1033. X   CURTASK exps[ level - 1 ].operation = NUMBER;
  1034. X
  1035. X   /* decrement the stack twice */
  1036. X
  1037. X   op_pulldown( 2 );
  1038. X
  1039. X   return TRUE;
  1040. X
  1041. X   }
  1042. X
  1043. X/***************************************************************
  1044. X
  1045. X    FUNCTION:       op_assign()
  1046. X
  1047. X    DESCRIPTION:    This function assigns the value in the
  1048. X            right hand side to the variable in the
  1049. X            left hand side.
  1050. X
  1051. X***************************************************************/
  1052. X
  1053. X#if ANSI_C
  1054. Xstatic int
  1055. Xop_assign( int level, int precision )
  1056. X#else
  1057. Xstatic int
  1058. Xop_assign( level, precision )
  1059. X   int level;
  1060. X   int precision;
  1061. X#endif
  1062. X   {
  1063. X
  1064. X   /* Make sure the position one level below is a variable */
  1065. X
  1066. X   if ( CURTASK exps[ level - 1 ].operation != VARIABLE )
  1067. X      {
  1068. X      op_pulldown( 2 );
  1069. X#if PROG_ERRORS
  1070. X      sprintf( bwb_ebuf, "in op_assign(): Assignment must be to variable: level -1 <%d> op <%d>",
  1071. X         level - 1, CURTASK exps[ level - 1 ].operation );
  1072. X      bwb_error( bwb_ebuf );
  1073. X#else
  1074. X      bwb_error( err_syntax );
  1075. X#endif
  1076. X      return FALSE;
  1077. X      }
  1078. X
  1079. X#if INTENSIVE_DEBUG
  1080. X   sprintf( bwb_ebuf, "in op_assign(): entered function level <%d>",
  1081. X      level );
  1082. X   bwb_debug( bwb_ebuf );
  1083. X#endif
  1084. X
  1085. X  /* if the assignment is numerical, then the precision should be set
  1086. X     to that of the variable on the left-hand side of the assignment */
  1087. X
  1088. X   if ( precision != STRING )
  1089. X      {
  1090. X      precision = (int) CURTASK exps[ level - 1 ].type;
  1091. X      }
  1092. X
  1093. X   switch( precision )
  1094. X      {
  1095. X      case STRING:
  1096. X
  1097. X#if INTENSIVE_DEBUG
  1098. X         sprintf( bwb_ebuf, "in op_assign(): try exp_getsval(), level <%d> op <%d> type <%c>:",
  1099. X            level - 1, CURTASK exps[ level - 1 ].operation, CURTASK exps[ level - 1 ].type );
  1100. X         bwb_debug( bwb_ebuf );
  1101. X         exp_getsval( &( CURTASK exps[ level - 1 ] ));
  1102. X         sprintf( bwb_ebuf, "in op_assign(): try exp_getsval(), level <%d> op <%d> type <%c>:",
  1103. X            level + 1, CURTASK exps[ level + 1 ].operation, CURTASK exps[ level + 1 ].type );
  1104. X         bwb_debug( bwb_ebuf );
  1105. X         exp_getsval( &( CURTASK exps[ level + 1 ] ));
  1106. X         sprintf( bwb_ebuf, "in op_assign(): string addition, exp_getsval()s completed" );
  1107. X         bwb_debug( bwb_ebuf );
  1108. X#endif
  1109. X
  1110. X         str_btob( exp_getsval( &( CURTASK exps[ level - 1 ] )),
  1111. X                   exp_getsval( &( CURTASK exps[ level + 1 ] )) );
  1112. X         break;
  1113. X
  1114. X      case NUMBER:
  1115. X         * var_findnval( CURTASK exps[ level - 1 ].xvar, 
  1116. X            CURTASK exps[ level - 1 ].array_pos ) =
  1117. X            CURTASK exps[ level - 1 ].nval = 
  1118. X            exp_getnval( &( CURTASK exps[ level + 1 ] ) );
  1119. X         break;
  1120. X
  1121. X      default:
  1122. X#if PROG_ERRORS
  1123. X         sprintf( bwb_ebuf, "in op_assign(): Variable before assignment operator has unidentified type." );
  1124. X         bwb_error( bwb_ebuf );
  1125. X#else
  1126. X         bwb_error( err_mismatch );
  1127. X#endif
  1128. X         return FALSE;
  1129. X
  1130. X      }
  1131. X
  1132. X   /* set variable to requested precision */
  1133. X
  1134. X   CURTASK exps[ level - 1 ].type = (char) precision;
  1135. X
  1136. X   /* decrement the stack twice */
  1137. X
  1138. X   op_pulldown( 2 );
  1139. X
  1140. X   return TRUE;
  1141. X
  1142. X   }
  1143. X
  1144. X/***************************************************************
  1145. X
  1146. X    FUNCTION:       op_equals()
  1147. X
  1148. X    DESCRIPTION:    This function compares two values and
  1149. X            returns an integer value: TRUE if they are
  1150. X            the same and FALSE if they are not.
  1151. X
  1152. X***************************************************************/
  1153. X
  1154. X#if ANSI_C
  1155. Xstatic int
  1156. Xop_equals( int level, int precision )
  1157. X#else
  1158. Xstatic int
  1159. Xop_equals( level, precision )
  1160. X   int level;
  1161. X   int precision;
  1162. X#endif
  1163. X   {
  1164. X   int error_condition;
  1165. X   static bstring b;
  1166. X   bstring *bp;
  1167. X
  1168. X   error_condition = FALSE;
  1169. X   b.rab = FALSE;
  1170. X
  1171. X   switch( precision )
  1172. X      {
  1173. X      case STRING:
  1174. X
  1175. X         /* both sides of the operation should be strings for
  1176. X            string addition; if not, report an error */
  1177. X
  1178. X         if (  ( op_islevelstr( level - 1 ) != TRUE )
  1179. X            || ( op_islevelstr( level + 1 ) != TRUE ) )
  1180. X            {
  1181. X#if PROG_ERRORS
  1182. X            sprintf( bwb_ebuf, "in op_equals(): Type mismatch in string comparison." );
  1183. X            bwb_error( bwb_ebuf );
  1184. X#else
  1185. X            bwb_error( err_mismatch );
  1186. X#endif
  1187. X            error_condition = TRUE;
  1188. X            }
  1189. X
  1190. X         /* compare the two strings */
  1191. X
  1192. X         if ( error_condition == FALSE )
  1193. X            {
  1194. X            bp = exp_getsval( &( CURTASK exps[ level - 1 ] ));
  1195. X#if OLDWAY
  1196. X        b.length = bp->length;
  1197. X        b.sbuffer = bp->sbuffer;
  1198. X#endif
  1199. X        str_btob( &b, bp );
  1200. X
  1201. X            if ( str_cmp( &b,
  1202. X               exp_getsval( &( CURTASK exps[ level + 1 ] )) ) == 0 )
  1203. X               {
  1204. X               CURTASK exps[ level - 1 ].nval = (bnumber) TRUE;
  1205. X               }
  1206. X            else
  1207. X               {
  1208. X               CURTASK exps[ level - 1 ].nval = (bnumber) FALSE;
  1209. X               }
  1210. X            }
  1211. X         break;
  1212. X
  1213. X      case NUMBER:
  1214. X         if ( exp_getnval( &( CURTASK exps[ level - 1 ] ))
  1215. X            == exp_getnval( &( CURTASK exps[ level + 1 ] )) )
  1216. X            {
  1217. X            CURTASK exps[ level - 1 ].nval = (bnumber) TRUE;
  1218. X            }
  1219. X         else
  1220. X            {
  1221. X            CURTASK exps[ level - 1 ].nval = (bnumber) FALSE;
  1222. X            }
  1223. X         break;
  1224. X
  1225. X      }
  1226. X
  1227. X   /* set variable to integer and operation to NUMBER:
  1228. X      this must be done at the end, since at the beginning it
  1229. X      might cause op_islevelstr() to return a false error */
  1230. X
  1231. X   CURTASK exps[ level - 1 ].type = NUMBER;
  1232. X   CURTASK exps[ level - 1 ].operation = NUMBER;
  1233. X
  1234. X   /* decrement the stack */
  1235. X
  1236. X   op_pulldown( 2 );
  1237. X
  1238. X   return TRUE;
  1239. X
  1240. X   }
  1241. X
  1242. X/***************************************************************
  1243. X
  1244. X    FUNCTION:       op_lessthan()
  1245. X
  1246. X    DESCRIPTION:    This function compares two values and
  1247. X            returns an integer value: TRUE if the
  1248. X            left hand value is less than the right,
  1249. X            and FALSE if it is not.
  1250. X
  1251. X***************************************************************/
  1252. X
  1253. X#if ANSI_C
  1254. Xstatic int
  1255. Xop_lessthan( int level, int precision )
  1256. X#else
  1257. Xstatic int
  1258. Xop_lessthan( level, precision )
  1259. X   int level;
  1260. X   int precision;
  1261. X#endif
  1262. X   {
  1263. X   int error_condition;
  1264. X
  1265. X   error_condition = FALSE;
  1266. X
  1267. X   switch( precision )
  1268. X      {
  1269. X      case STRING:
  1270. X
  1271. X         /* both sides of the operation should be numbers for
  1272. X            string addition; if not, report an error */
  1273. X
  1274. X         if (  ( op_islevelstr( level - 1 ) != TRUE )
  1275. X            || ( op_islevelstr( level + 1 ) != TRUE ) )
  1276. X            {
  1277. X#if PROG_ERRORS
  1278. X            sprintf( bwb_ebuf, "Type mismatch in string comparison." );
  1279. X            bwb_error( bwb_ebuf );
  1280. X#else
  1281. X            bwb_error( err_mismatch );
  1282. X#endif
  1283. X            error_condition = TRUE;
  1284. X            }
  1285. X
  1286. X         /* compare the two strings */
  1287. X
  1288. X         if ( error_condition == FALSE )
  1289. X            {
  1290. X            if ( str_cmp( exp_getsval( &( CURTASK exps[ level - 1 ] )),
  1291. X               exp_getsval( &( CURTASK exps[ level + 1 ] )) ) < 0 )
  1292. X               {
  1293. X               CURTASK exps[ level - 1 ].nval = (bnumber) TRUE;
  1294. X               }
  1295. X            else
  1296. X               {
  1297. X               CURTASK exps[ level - 1 ].nval = (bnumber) FALSE;
  1298. X               }
  1299. X            }
  1300. X         break;
  1301. X
  1302. X      case NUMBER:
  1303. X         if ( exp_getnval( &( CURTASK exps[ level - 1 ] ))
  1304. X            < exp_getnval( &( CURTASK exps[ level + 1 ] )) )
  1305. X            {
  1306. X            CURTASK exps[ level - 1 ].nval = (bnumber) TRUE;
  1307. X            }
  1308. X         else
  1309. X            {
  1310. X            CURTASK exps[ level - 1 ].nval = (bnumber) FALSE;
  1311. X            }
  1312. X         break;
  1313. X
  1314. X      }
  1315. X
  1316. X   /* set variable to integer and operation to NUMBER:
  1317. X      this must be done at the end, since at the beginning it
  1318. X      might cause op_islevelstr() to return a false error */
  1319. X
  1320. X   CURTASK exps[ level - 1 ].type = NUMBER;
  1321. X   CURTASK exps[ level - 1 ].operation = NUMBER;
  1322. X
  1323. X   /* decrement the stack */
  1324. X
  1325. X   op_pulldown( 2 );
  1326. X
  1327. X   return TRUE;
  1328. X
  1329. X   }
  1330. X
  1331. X/***************************************************************
  1332. X
  1333. X    FUNCTION:       op_greaterthan()
  1334. X
  1335. X    DESCRIPTION:    This function compares two values and
  1336. X            returns an integer value: TRUE if the
  1337. X            left hand value is greater than the right,
  1338. X            and FALSE if it is not.
  1339. X
  1340. X***************************************************************/
  1341. X
  1342. X#if ANSI_C
  1343. Xstatic int
  1344. Xop_greaterthan( int level, int precision )
  1345. X#else
  1346. Xstatic int
  1347. Xop_greaterthan( level, precision )
  1348. X   int level;
  1349. X   int precision;
  1350. X#endif
  1351. X   {
  1352. X   int error_condition;
  1353. X
  1354. X   error_condition = FALSE;
  1355. X
  1356. X   switch( precision )
  1357. X      {
  1358. X      case STRING:
  1359. X
  1360. X         /* both sides of the operation should be numbers for
  1361. X            string addition; if not, report an error */
  1362. X
  1363. X         if (  ( op_islevelstr( level - 1 ) != TRUE )
  1364. X            || ( op_islevelstr( level + 1 ) != TRUE ) )
  1365. X            {
  1366. X#if PROG_ERRORS
  1367. X            sprintf( bwb_ebuf, "Type mismatch in string comparison." );
  1368. X            bwb_error( bwb_ebuf );
  1369. X#else
  1370. X            bwb_error( err_mismatch );
  1371. X#endif
  1372. X            error_condition = TRUE;
  1373. X            }
  1374. X
  1375. X         /* compare the two strings */
  1376. X
  1377. X         if ( error_condition == FALSE )
  1378. X            {
  1379. X            if ( str_cmp( exp_getsval( &( CURTASK exps[ level - 1 ] )),
  1380. X               exp_getsval( &( CURTASK exps[ level + 1 ] )) ) > 0 )
  1381. X               {
  1382. X               CURTASK exps[ level - 1 ].nval = (bnumber) TRUE;
  1383. X               }
  1384. X            else
  1385. X               {
  1386. X               CURTASK exps[ level - 1 ].nval = (bnumber) FALSE;
  1387. X               }
  1388. X            }
  1389. X         break;
  1390. X
  1391. X      case NUMBER:
  1392. X         if ( exp_getnval( &( CURTASK exps[ level - 1 ] ))
  1393. X            > exp_getnval( &( CURTASK exps[ level + 1 ] )) )
  1394. X            {
  1395. X            CURTASK exps[ level - 1 ].nval = (bnumber) TRUE;
  1396. X            }
  1397. X         else
  1398. X            {
  1399. X            CURTASK exps[ level - 1 ].nval = (bnumber) FALSE;
  1400. X            }
  1401. X         break;
  1402. X
  1403. X      }
  1404. X
  1405. X   /* set variable to integer and operation to NUMBER:
  1406. X      this must be done at the end, since at the beginning it
  1407. X      might cause op_islevelstr() to return a false error */
  1408. X
  1409. X   CURTASK exps[ level - 1 ].type = NUMBER;
  1410. X   CURTASK exps[ level - 1 ].operation = NUMBER;
  1411. X
  1412. X   /* decrement the stack */
  1413. X
  1414. X   op_pulldown( 2 );
  1415. X
  1416. X   return TRUE;
  1417. X
  1418. X   }
  1419. X
  1420. X/***************************************************************
  1421. X
  1422. X    FUNCTION:       op_lteq()
  1423. X
  1424. X    DESCRIPTION:    This function compares two values and
  1425. X            returns an integer value: TRUE if the
  1426. X            left hand value is less than or equal
  1427. X            to the right, and FALSE if it is not.
  1428. X
  1429. X***************************************************************/
  1430. X
  1431. X#if ANSI_C
  1432. Xstatic int
  1433. Xop_lteq( int level, int precision )
  1434. X#else
  1435. Xstatic int
  1436. Xop_lteq( level, precision )
  1437. X   int level;
  1438. X   int precision;
  1439. X#endif
  1440. X   {
  1441. X   int error_condition;
  1442. X
  1443. X   error_condition = FALSE;
  1444. X
  1445. X   switch( precision )
  1446. X      {
  1447. X      case STRING:
  1448. X
  1449. X         /* both sides of the operation should be numbers for
  1450. X            string addition; if not, report an error */
  1451. X
  1452. X         if (  ( op_islevelstr( level - 1 ) != TRUE )
  1453. X            || ( op_islevelstr( level + 1 ) != TRUE ) )
  1454. X            {
  1455. X#if PROG_ERRORS
  1456. X            sprintf( bwb_ebuf, "Type mismatch in string comparison." );
  1457. X            bwb_error( bwb_ebuf );
  1458. X#else
  1459. X            bwb_error( err_mismatch );
  1460. X#endif
  1461. X            error_condition = TRUE;
  1462. X            }
  1463. X
  1464. X         /* compare the two strings */
  1465. X
  1466. X         if ( error_condition == FALSE )
  1467. X            {
  1468. X            if ( str_cmp( exp_getsval( &( CURTASK exps[ level - 1 ] )),
  1469. X               exp_getsval( &( CURTASK exps[ level + 1 ] )) ) <= 0 )
  1470. X               {
  1471. X               CURTASK exps[ level - 1 ].nval = (bnumber) TRUE;
  1472. X               }
  1473. X            else
  1474. X               {
  1475. X               CURTASK exps[ level - 1 ].nval = (bnumber) FALSE;
  1476. X               }
  1477. X            }
  1478. X         break;
  1479. X
  1480. X      case NUMBER:
  1481. X         if ( exp_getnval( &( CURTASK exps[ level - 1 ] ))
  1482. X            <= exp_getnval( &( CURTASK exps[ level + 1 ] )) )
  1483. X            {
  1484. X            CURTASK exps[ level - 1 ].nval = (bnumber) TRUE;
  1485. X            }
  1486. X         else
  1487. X            {
  1488. X            CURTASK exps[ level - 1 ].nval = (bnumber) FALSE;
  1489. X            }
  1490. X         break;
  1491. X
  1492. X      }
  1493. X
  1494. X   /* set variable to integer and operation to NUMBER:
  1495. X      this must be done at the end, since at the beginning it
  1496. X      might cause op_islevelstr() to return a false error */
  1497. X
  1498. X   CURTASK exps[ level - 1 ].type = NUMBER;
  1499. X   CURTASK exps[ level - 1 ].operation = NUMBER;
  1500. X
  1501. X   /* decrement the stack */
  1502. X
  1503. X   op_pulldown( 2 );
  1504. X
  1505. X   return TRUE;
  1506. X
  1507. X   }
  1508. X
  1509. X/***************************************************************
  1510. X
  1511. X    FUNCTION:       op_gteq()
  1512. X
  1513. X    DESCRIPTION:    This function compares two values and
  1514. X            returns an integer value: TRUE if the
  1515. X            left hand value is greater than or equal
  1516. X            to the right, and FALSE if it is not.
  1517. X
  1518. X***************************************************************/
  1519. X
  1520. X#if ANSI_C
  1521. Xstatic int
  1522. Xop_gteq( int level, int precision )
  1523. X#else
  1524. Xstatic int
  1525. Xop_gteq( level, precision )
  1526. X   int level;
  1527. X   int precision;
  1528. X#endif
  1529. X   {
  1530. X   int error_condition;
  1531. X
  1532. X   error_condition = FALSE;
  1533. X
  1534. X   switch( precision )
  1535. X      {
  1536. X      case STRING:
  1537. X
  1538. X         /* both sides of the operation should be numbers for
  1539. X            string addition; if not, report an error */
  1540. X
  1541. X         if (  ( op_islevelstr( level - 1 ) != TRUE )
  1542. X            || ( op_islevelstr( level + 1 ) != TRUE ) )
  1543. X            {
  1544. X#if PROG_ERRORS
  1545. X            sprintf( bwb_ebuf, "Type mismatch in string comparison." );
  1546. X            bwb_error( bwb_ebuf );
  1547. X#else
  1548. X            bwb_error( err_mismatch );
  1549. X#endif
  1550. X            error_condition = TRUE;
  1551. X            }
  1552. X
  1553. X         /* compare the two strings */
  1554. X
  1555. X         if ( error_condition == FALSE )
  1556. X            {
  1557. X            if ( str_cmp( exp_getsval( &( CURTASK exps[ level - 1 ] )),
  1558. X               exp_getsval( &( CURTASK exps[ level + 1 ] )) ) >= 0 )
  1559. X               {
  1560. X               CURTASK exps[ level - 1 ].nval = (bnumber) TRUE;
  1561. X               }
  1562. X            else
  1563. X               {
  1564. X               CURTASK exps[ level - 1 ].nval = (bnumber) FALSE;
  1565. X               }
  1566. X            }
  1567. X         break;
  1568. X
  1569. X      case NUMBER:
  1570. X         if ( exp_getnval( &( CURTASK exps[ level - 1 ] ))
  1571. X            >= exp_getnval( &( CURTASK exps[ level + 1 ] )) )
  1572. X            {
  1573. X            CURTASK exps[ level - 1 ].nval = (bnumber) TRUE;
  1574. X            }
  1575. X         else
  1576. X            {
  1577. X            CURTASK exps[ level - 1 ].nval = (bnumber) FALSE;
  1578. X            }
  1579. X         break;
  1580. X
  1581. X      }
  1582. X
  1583. X   /* set variable to integer and operation to NUMBER:
  1584. X      this must be done at the end, since at the beginning it
  1585. X      might cause op_islevelstr() to return a false error */
  1586. X
  1587. X   CURTASK exps[ level - 1 ].type = NUMBER;
  1588. X   CURTASK exps[ level - 1 ].operation = NUMBER;
  1589. X
  1590. X   /* decrement the stack */
  1591. X
  1592. X   op_pulldown( 2 );
  1593. X
  1594. X   return TRUE;
  1595. X
  1596. X   }
  1597. X
  1598. X/***************************************************************
  1599. X
  1600. X    FUNCTION:       op_notequal()
  1601. X
  1602. X    DESCRIPTION:    This function compares two values and
  1603. X            returns an integer value: TRUE if they
  1604. X            are not the same and FALSE if they are.
  1605. X
  1606. X***************************************************************/
  1607. X
  1608. X#if ANSI_C
  1609. Xstatic int
  1610. Xop_notequal( int level, int precision )
  1611. X#else
  1612. Xstatic int
  1613. Xop_notequal( level, precision )
  1614. X   int level;
  1615. X   int precision;
  1616. X#endif
  1617. X   {
  1618. X   int error_condition;
  1619. X
  1620. X   error_condition = FALSE;
  1621. X
  1622. X   switch( precision )
  1623. X      {
  1624. X      case STRING:
  1625. X
  1626. X         /* both sides of the operation should be numbers for
  1627. X            string addition; if not, report an error */
  1628. X
  1629. X         if (  ( op_islevelstr( level - 1 ) != TRUE )
  1630. X            || ( op_islevelstr( level + 1 ) != TRUE ) )
  1631. X            {
  1632. X#if PROG_ERRORS
  1633. X            sprintf( bwb_ebuf, "Type mismatch in string comparison." );
  1634. X            bwb_error( bwb_ebuf );
  1635. X#else
  1636. X            bwb_error( err_mismatch );
  1637. X#endif
  1638. X            error_condition = TRUE;
  1639. X            }
  1640. X
  1641. X         /* compare the two strings */
  1642. X
  1643. X         if ( error_condition == FALSE )
  1644. X
  1645. X            {
  1646. X            if ( str_cmp( exp_getsval( &( CURTASK exps[ level - 1 ] )),
  1647. X               exp_getsval( &( CURTASK exps[ level + 1 ] )) ) != 0 )
  1648. X               {
  1649. X               CURTASK exps[ level - 1 ].nval = (bnumber) TRUE;
  1650. X               }
  1651. X            else
  1652. X               {
  1653. X               CURTASK exps[ level - 1 ].nval = (bnumber) FALSE;
  1654. X               }
  1655. X            }
  1656. X         break;
  1657. X
  1658. X      case NUMBER:
  1659. X         if ( exp_getnval( &( CURTASK exps[ level - 1 ] ))
  1660. X            != exp_getnval( &( CURTASK exps[ level + 1 ] )) )
  1661. X            {
  1662. X            CURTASK exps[ level - 1 ].nval = (bnumber) TRUE;
  1663. X            }
  1664. X         else
  1665. X            {
  1666. X            CURTASK exps[ level - 1 ].nval = (bnumber) FALSE;
  1667. X            }
  1668. X         break;
  1669. X
  1670. X      }
  1671. X
  1672. X   /* set variable to integer and operation to NUMBER:
  1673. X      this must be done at the end, since at the beginning it
  1674. X      might cause op_islevelstr() to return a false error */
  1675. X
  1676. X   CURTASK exps[ level - 1 ].type = NUMBER;
  1677. X   CURTASK exps[ level - 1 ].operation = NUMBER;
  1678. X
  1679. X   /* decrement the stack */
  1680. X
  1681. X   op_pulldown( 2 );
  1682. X
  1683. X   return TRUE;
  1684. X
  1685. X   }
  1686. X
  1687. X/***************************************************************
  1688. X
  1689. X    FUNCTION:       op_modulus()
  1690. X
  1691. X    DESCRIPTION:    This function divides the number on
  1692. X            the left by the number on the right
  1693. X            and returns the remainder.
  1694. X
  1695. X***************************************************************/
  1696. X
  1697. X#if ANSI_C
  1698. Xstatic int
  1699. Xop_modulus( int level, int precision )
  1700. X#else
  1701. Xstatic int
  1702. Xop_modulus( level, precision )
  1703. X   int level;
  1704. X   int precision;
  1705. X#endif
  1706. X   {
  1707. X   static double iportion;
  1708. X
  1709. X   switch( precision )
  1710. X      {
  1711. X      case STRING:
  1712. X
  1713. X         /* both sides of the operation should be numbers for
  1714. X            string addition; if not, report an error */
  1715. X
  1716. X#if PROG_ERRORS
  1717. X         sprintf( bwb_ebuf, "Strings cannot be divided." );
  1718. X         bwb_error( bwb_ebuf );
  1719. X#else
  1720. X         bwb_error( err_syntax );
  1721. X#endif
  1722. X
  1723. X         break;
  1724. X
  1725. X      case NUMBER:
  1726. X         if ( exp_getnval( &( CURTASK exps[ level + 1 ] ))
  1727. X            == (bnumber) 0 )
  1728. X            {
  1729. X            CURTASK exps[ level - 1 ].nval = (bnumber) -1;
  1730. X            op_pulldown( 2 );
  1731. X#if PROG_ERRORS
  1732. X            sprintf( bwb_ebuf, "Divide by 0." );
  1733. X            bwb_error( bwb_ebuf );
  1734. X#else
  1735. X            bwb_error( err_dbz );
  1736. X#endif
  1737. X            return FALSE;
  1738. X            }
  1739. X         CURTASK exps[ level ].nval
  1740. X            = exp_getnval( &( CURTASK exps[ level - 1 ] ))
  1741. X            / exp_getnval( &( CURTASK exps[ level + 1 ] ));
  1742. X         modf( (double) CURTASK exps[ level ].nval, &iportion );
  1743. X         CURTASK exps[ level - 1 ].nval
  1744. X            = exp_getnval( &( CURTASK exps[ level - 1 ] ))
  1745. X            - ( exp_getnval( &( CURTASK exps[ level + 1 ] ))
  1746. X            * iportion );
  1747. X         break;
  1748. X
  1749. X      }
  1750. X
  1751. X   /* set variable to requested precision */
  1752. X
  1753. X   CURTASK exps[ level - 1 ].type = (char) precision;
  1754. X   CURTASK exps[ level - 1 ].operation = NUMBER;
  1755. X
  1756. X   /* decrement the stack twice */
  1757. X
  1758. X   op_pulldown( 2 );
  1759. X
  1760. X   return TRUE;
  1761. X
  1762. X   }
  1763. X
  1764. X/***************************************************************
  1765. X
  1766. X    FUNCTION:       op_exponent()
  1767. X
  1768. X    DESCRIPTION:    This function finds the exponential value
  1769. X            of a number (on the left) to the power
  1770. X            indicated on the right-hand side.
  1771. X
  1772. X***************************************************************/
  1773. X
  1774. X#if ANSI_C
  1775. Xstatic int
  1776. Xop_exponent( int level, int precision )
  1777. X#else
  1778. Xstatic int
  1779. Xop_exponent( level, precision )
  1780. X   int level;
  1781. X   int precision;
  1782. X#endif
  1783. X   {
  1784. X
  1785. X#if INTENSIVE_DEBUG
  1786. X   sprintf( bwb_ebuf, "in op_exponent(): entered function level <%d>.",
  1787. X      level );
  1788. X   bwb_debug ( bwb_ebuf );
  1789. X#endif
  1790. X
  1791. X   switch( precision )
  1792. X      {
  1793. X      case STRING:
  1794. X
  1795. X         /* both sides of the operation should be numbers for
  1796. X            string addition; if not, report an error */
  1797. X
  1798. X#if PROG_ERRORS
  1799. X         sprintf( bwb_ebuf, "Strings cannot be taken as exponents." );
  1800. X         bwb_error( bwb_ebuf );
  1801. X#else
  1802. X         bwb_error( err_mismatch );
  1803. X#endif
  1804. X
  1805. X         break;
  1806. X
  1807. X      case NUMBER:
  1808. X         CURTASK exps[ level - 1 ].nval
  1809. X           = (bnumber) pow( (double) exp_getnval( &( CURTASK exps[ level - 1 ] )),
  1810. X                  (double) exp_getnval( &( CURTASK exps[ level + 1 ] )) );
  1811. X         break;
  1812. X
  1813. X      }
  1814. X
  1815. X   /* set variable to requested precision */
  1816. X
  1817. X   CURTASK exps[ level - 1 ].type = (char) precision;
  1818. X   CURTASK exps[ level - 1 ].operation = NUMBER;
  1819. X
  1820. X   /* decrement the stack twice */
  1821. X
  1822. X   op_pulldown( 2 );
  1823. X
  1824. X   return TRUE;
  1825. X
  1826. X   }
  1827. X
  1828. X/***************************************************************
  1829. X
  1830. X    FUNCTION:       op_intdiv()
  1831. X
  1832. X    DESCRIPTION:    This function divides the number on
  1833. X            the left by the number on the right,
  1834. X            returning the result as an integer.
  1835. X
  1836. X***************************************************************/
  1837. X
  1838. X#if ANSI_C
  1839. Xstatic int
  1840. Xop_intdiv( int level, int precision )
  1841. X#else
  1842. Xstatic int
  1843. Xop_intdiv( level, precision )
  1844. X   int level;
  1845. X   int precision;
  1846. X#endif
  1847. X   {
  1848. X
  1849. X   switch( precision )
  1850. X      {
  1851. X      case STRING:
  1852. X
  1853. X         /* both sides of the operation should be numbers for
  1854. X            string addition; if not, report an error */
  1855. X
  1856. X#if PROG_ERRORS
  1857. X         sprintf( bwb_ebuf, "Strings cannot be divided." );
  1858. X         bwb_error( bwb_ebuf );
  1859. X#else
  1860. X         bwb_error( err_mismatch );
  1861. X#endif
  1862. X
  1863. X         break;
  1864. X
  1865. X      default:
  1866. X         if ( exp_getnval( &( CURTASK exps[ level + 1 ] ))
  1867. X            == (bnumber) 0 )
  1868. X            {
  1869. X            CURTASK exps[ level - 1 ].nval = (bnumber) -1;
  1870. X            op_pulldown( 2 );
  1871. X#if PROG_ERRORS
  1872. X            sprintf( bwb_ebuf, "Divide by 0." );
  1873. X            bwb_error( bwb_ebuf );
  1874. X#else
  1875. X            bwb_error( err_dbz );
  1876. X#endif
  1877. X            return FALSE;
  1878. X            }
  1879. X
  1880. X         CURTASK exps[ level - 1 ].nval
  1881. X            = exp_getnval( &( CURTASK exps[ level - 1 ] ))
  1882. X            / exp_getnval( &( CURTASK exps[ level + 1 ] ));
  1883. X         break;
  1884. X      }
  1885. X
  1886. X   /* set variable to requested precision */
  1887. X
  1888. X   CURTASK exps[ level - 1 ].type = NUMBER;
  1889. X   CURTASK exps[ level - 1 ].operation = NUMBER;
  1890. X
  1891. X   /* decrement the stack twice */
  1892. X
  1893. X   op_pulldown( 2 );
  1894. X
  1895. X   return TRUE;
  1896. X
  1897. X   }
  1898. X
  1899. X/***************************************************************
  1900. X
  1901. X    FUNCTION:       op_or()
  1902. X
  1903. X    DESCRIPTION:    This function compares two integers and
  1904. X            performs a logical NOT on them.
  1905. X
  1906. X***************************************************************/
  1907. X
  1908. X#if ANSI_C
  1909. Xstatic int
  1910. Xop_or( int level, int precision )
  1911. X#else
  1912. Xstatic int
  1913. Xop_or( level, precision )
  1914. X   int level;
  1915. X   int precision;
  1916. X#endif
  1917. X   {
  1918. X
  1919. X   switch( precision )
  1920. X      {
  1921. X      case STRING:
  1922. X
  1923. X         /* both sides of the operation should be numbers for
  1924. X            logical comparison; if not, report an error */
  1925. X
  1926. X#if PROG_ERRORS
  1927. X         sprintf( bwb_ebuf, "Strings cannot be compared logically." );
  1928. X         bwb_error( bwb_ebuf );
  1929. X#else
  1930. X         bwb_error( err_mismatch );
  1931. X#endif
  1932. X
  1933. X         break;
  1934. X
  1935. X      case NUMBER:
  1936. X         CURTASK exps[ level - 1 ].nval
  1937. X            = (bnumber) ((int) exp_getnval( &( CURTASK exps[ level - 1 ] ))
  1938. X            | (int) exp_getnval( &( CURTASK exps[ level + 1 ] )));
  1939. X         break;
  1940. X
  1941. X      }
  1942. X
  1943. X   /* set variable type to integer */
  1944. X
  1945. X   CURTASK exps[ level - 1 ].type = NUMBER;
  1946. X   CURTASK exps[ level - 1 ].operation = NUMBER;
  1947. X
  1948. X   /* decrement the stack twice */
  1949. X
  1950. X   op_pulldown( 2 );
  1951. X
  1952. X   return TRUE;
  1953. X
  1954. X   }
  1955. X
  1956. X/***************************************************************
  1957. X
  1958. X    FUNCTION:       op_and()
  1959. X
  1960. X    DESCRIPTION:    This function compares two integers and
  1961. X            performs a logical NOT on them.
  1962. X
  1963. X***************************************************************/
  1964. X
  1965. X#if ANSI_C
  1966. Xstatic int
  1967. Xop_and( int level, int precision )
  1968. X#else
  1969. Xstatic int
  1970. Xop_and( level, precision )
  1971. X   int level;
  1972. X   int precision;
  1973. X#endif
  1974. X   {
  1975. X
  1976. X   switch( precision )
  1977. X      {
  1978. X      case STRING:
  1979. X
  1980. X
  1981. X         /* both sides of the operation should be numbers for
  1982. X            logical comparison; if not, report an error */
  1983. X
  1984. X#if PROG_ERRORS
  1985. X         sprintf( bwb_ebuf, "Strings cannot be compared logically." );
  1986. X         bwb_error( bwb_ebuf );
  1987. X#else
  1988. X         bwb_error( err_mismatch );
  1989. X#endif
  1990. X
  1991. X         break;
  1992. X
  1993. X      case NUMBER:
  1994. X         CURTASK exps[ level - 1 ].nval
  1995. X            = (bnumber) ((int) exp_getnval( &( CURTASK exps[ level - 1 ] ))
  1996. X            & (int) exp_getnval( &( CURTASK exps[ level + 1 ] )));
  1997. X         break;
  1998. X
  1999. X      }
  2000. X
  2001. X   /* set variable type to integer */
  2002. X
  2003. X   CURTASK exps[ level - 1 ].type = NUMBER;
  2004. X   CURTASK exps[ level - 1 ].operation = NUMBER;
  2005. X
  2006. X   /* decrement the stack twice */
  2007. X
  2008. X   op_pulldown( 2 );
  2009. X
  2010. X   return TRUE;
  2011. X
  2012. X   }
  2013. X
  2014. X/***************************************************************
  2015. X
  2016. X    FUNCTION:       op_not()
  2017. X
  2018. X    DESCRIPTION:    This function compares two integers and
  2019. X            performs a logical NOT on them.
  2020. X
  2021. X***************************************************************/
  2022. X
  2023. X#if ANSI_C
  2024. Xstatic int
  2025. Xop_not( int level, int precision )
  2026. X#else
  2027. Xstatic int
  2028. Xop_not( level, precision )
  2029. X   int level;
  2030. X   int precision;
  2031. X#endif
  2032. X   {
  2033. X
  2034. X   switch( precision )
  2035. X      {
  2036. X      case STRING:
  2037. X
  2038. X
  2039. X         /* both sides of the operation should be numbers for
  2040. X            logical comparison; if not, report an error */
  2041. X
  2042. X#if PROG_ERRORS
  2043. X         sprintf( bwb_ebuf, "Strings cannot be compared logically." );
  2044. X         bwb_error( bwb_ebuf );
  2045. X#else
  2046. X         bwb_error( err_mismatch );
  2047. X#endif
  2048. X
  2049. X         break;
  2050. X
  2051. X      default:
  2052. X
  2053. X#if INTENSIVE_DEBUG
  2054. X         sprintf( bwb_ebuf, "in op_not(): argument is <%d>, precision <%c>",
  2055. X            (unsigned int) exp_getnval( &( CURTASK exps[ level + 1 ] )), precision );
  2056. X         bwb_debug( bwb_ebuf );
  2057. X#endif
  2058. X
  2059. X         CURTASK exps[ level ].nval = (bnumber)
  2060. X            ~( (int) exp_getnval( &( CURTASK exps[ level + 1 ] )) );
  2061. X
  2062. X#if INTENSIVE_DEBUG
  2063. X         sprintf( bwb_ebuf, "in op_not(): result is <%d>, precision <%c>",
  2064. X            (int) r, precision );
  2065. X         bwb_debug( bwb_ebuf );
  2066. X#endif
  2067. X
  2068. X         break;
  2069. X      }
  2070. X
  2071. X   /* set variable type to integer */
  2072. X
  2073. X   CURTASK exps[ level ].type = NUMBER;
  2074. X   CURTASK exps[ level ].operation = NUMBER;
  2075. X
  2076. X   /* decrement the stack once */
  2077. X
  2078. X   op_pulldown( 1 );
  2079. X
  2080. X#if INTENSIVE_DEBUG
  2081. X   sprintf( bwb_ebuf, "in op_not(): CURTASK expsc <%d>, level <%d> result <%d>",
  2082. X      CURTASK expsc, level, CURTASK exps[ CURTASK expsc ].nval );
  2083. X   bwb_debug( bwb_ebuf );
  2084. X#endif
  2085. X
  2086. X   return TRUE;
  2087. X
  2088. X   }
  2089. X
  2090. X/***************************************************************
  2091. X
  2092. X    FUNCTION:       op_xor()
  2093. X
  2094. X    DESCRIPTION:    This function compares two integers and
  2095. X            performs a logical NOT on them.
  2096. X
  2097. X***************************************************************/
  2098. X
  2099. X#if ANSI_C
  2100. Xstatic int
  2101. Xop_xor( int level, int precision )
  2102. X#else
  2103. Xstatic int
  2104. Xop_xor( level, precision )
  2105. X   int level;
  2106. X   int precision;
  2107. X#endif
  2108. X   {
  2109. X
  2110. X   switch( precision )
  2111. X      {
  2112. X      case STRING:
  2113. X
  2114. X         /* both sides of the operation should be numbers for
  2115. X            logical comparison; if not, report an error */
  2116. X
  2117. X#if PROG_ERRORS
  2118. X         sprintf( bwb_ebuf, "Strings cannot be compared logically." );
  2119. X         bwb_error( bwb_ebuf );
  2120. X#else
  2121. X         bwb_error( err_mismatch );
  2122. X#endif
  2123. X
  2124. X         break;
  2125. X
  2126. X      case NUMBER:
  2127. X         CURTASK exps[ level - 1 ].nval
  2128. X            = (bnumber) ((int) exp_getnval( &( CURTASK exps[ level - 1 ] ))
  2129. X            ^ (int) exp_getnval( &( CURTASK exps[ level + 1 ] )));
  2130. X         break;
  2131. X
  2132. X      }
  2133. X
  2134. X   /* set variable type to integer */
  2135. X
  2136. X   CURTASK exps[ level - 1 ].type = NUMBER;
  2137. X   CURTASK exps[ level - 1 ].operation = NUMBER;
  2138. X
  2139. X   /* decrement the stack twice */
  2140. X
  2141. X   op_pulldown( 2 );
  2142. X
  2143. X   return TRUE;
  2144. X
  2145. X   }
  2146. X
  2147. X/***************************************************************
  2148. X
  2149. X    FUNCTION:       op_islevelstr()
  2150. X
  2151. X    DESCRIPTION:    This function determines whether the
  2152. X            operation at a specified level involves a
  2153. X            string constant or variable.
  2154. X
  2155. X***************************************************************/
  2156. X
  2157. X#if ANSI_C
  2158. Xstatic int
  2159. Xop_islevelstr( int level )
  2160. X#else
  2161. Xstatic int
  2162. Xop_islevelstr( level )
  2163. X   int level;
  2164. X#endif
  2165. X   {
  2166. X
  2167. X   /* first see if the level holds a string constant */
  2168. X
  2169. X   if ( CURTASK exps[ level ].operation == CONST_STRING )
  2170. X      {
  2171. X
  2172. X#if INTENSIVE_DEBUG
  2173. X      sprintf( bwb_ebuf, "in op_islevelstr(): string detected at level <%d>.",
  2174. X         level );
  2175. X      bwb_debug( bwb_ebuf );
  2176. X#endif
  2177. X
  2178. X      return TRUE;
  2179. X      }
  2180. X
  2181. X   /* see if the level holds a string variable */
  2182. X
  2183. X   if ( CURTASK exps[ level ].operation == VARIABLE )
  2184. X      {
  2185. X      if ( CURTASK exps[ level ].xvar->type == STRING )
  2186. X         {
  2187. X
  2188. X#if INTENSIVE_DEBUG
  2189. X         sprintf( bwb_ebuf, "in op_islevelstr(): string detected at level <%d>.",
  2190. X            level );
  2191. X         bwb_debug( bwb_ebuf );
  2192. X#endif
  2193. X
  2194. X         return TRUE;
  2195. X         }
  2196. X      }
  2197. X
  2198. X   /* test has failed, return FALSE */
  2199. X
  2200. X#if INTENSIVE_DEBUG
  2201. X   sprintf( bwb_ebuf, "in op_islevelstr(): string not detected at level <%d>.",
  2202. X      level );
  2203. X   bwb_debug( bwb_ebuf );
  2204. X#endif
  2205. X
  2206. X   return FALSE;
  2207. X
  2208. X   }
  2209. X
  2210. X/***************************************************************
  2211. X
  2212. X    FUNCTION:       op_getprecision()
  2213. X
  2214. X    DESCRIPTION:    This function finds the precision for
  2215. X            an operation by comparing the precision
  2216. X            at this level and that two levels below.
  2217. X
  2218. X***************************************************************/
  2219. X
  2220. X#if ANSI_C
  2221. Xstatic int
  2222. Xop_getprecision( int level )
  2223. X#else
  2224. Xstatic int
  2225. Xop_getprecision( level )
  2226. X   int level;
  2227. X#endif
  2228. X   {
  2229. X
  2230. X   /* first test for string value */
  2231. X
  2232. X   if (  ( CURTASK exps[ level + 1 ].type == STRING )
  2233. X      || ( CURTASK exps[ level - 1 ].type == STRING ) )
  2234. X      {
  2235. X      return STRING;
  2236. X      }
  2237. X
  2238. X   /* Both are numbers, so we should be able to find a suitable
  2239. X      precision level by starting with the top and moving down;
  2240. X      check first for double precision */
  2241. X
  2242. X   else
  2243. X      {
  2244. X      return NUMBER;
  2245. X      }
  2246. X
  2247. X   }
  2248. X
  2249. X/***************************************************************
  2250. X
  2251. X    FUNCTION:       op_pulldown()
  2252. X
  2253. X    DESCRIPTION:    This function pulls the expression stack
  2254. X            down a specified number of levels, decrementing
  2255. X            the expression stack counter (bycalling dec_esc())
  2256. X            and decrementing the current "level" of operation
  2257. X            processing.
  2258. X
  2259. X***************************************************************/
  2260. X
  2261. X#if ANSI_C
  2262. Xstatic int
  2263. Xop_pulldown( int how_far )
  2264. X#else
  2265. Xstatic int
  2266. Xop_pulldown( how_far )
  2267. X   int how_far;
  2268. X#endif
  2269. X   {
  2270. X   int level;
  2271. X   register int c;
  2272. X
  2273. X#if INTENSIVE_DEBUG
  2274. X   sprintf( bwb_ebuf, "in op_pulldown(): pull down e stack <%d> place(s)",
  2275. X      how_far );
  2276. X   bwb_debug( bwb_ebuf );
  2277. X#endif
  2278. X
  2279. X   /* first pull down the actual variables themselves */
  2280. X
  2281. X   level = op_level + ( 2 - how_far );
  2282. X   while ( CURTASK expsc >= ( level + how_far ) )
  2283. X      {
  2284. X
  2285. X      memcpy( &CURTASK exps[ level ], &CURTASK exps[ level + how_far ],
  2286. X         (size_t) ( sizeof( struct exp_ese )) );
  2287. X      ++level;
  2288. X
  2289. X      }
  2290. X
  2291. X   /* decrement the expression stack counter */
  2292. X
  2293. X   for ( c = 0; c < how_far; ++c )
  2294. X      {
  2295. X
  2296. X      if ( dec_esc() == TRUE )
  2297. X         {
  2298. X         --op_level;
  2299. X         }
  2300. X      else
  2301. X         {
  2302. X         return FALSE;
  2303. X         }
  2304. X
  2305. X      }
  2306. X
  2307. X   return TRUE;
  2308. X
  2309. X   }
  2310. X
  2311. X
  2312. END_OF_FILE
  2313.   if test 46972 -ne `wc -c <'bwbasic-2.10/bwb_ops.c'`; then
  2314.     echo shar: \"'bwbasic-2.10/bwb_ops.c'\" unpacked with wrong size!
  2315.   fi
  2316.   # end of 'bwbasic-2.10/bwb_ops.c'
  2317. fi
  2318. if test -f 'bwbasic-2.10/bwbtest/function.bas' -a "${1}" != "-c" ; then 
  2319.   echo shar: Will not clobber existing file \"'bwbasic-2.10/bwbtest/function.bas'\"
  2320. else
  2321.   echo shar: Extracting \"'bwbasic-2.10/bwbtest/function.bas'\" \(1717 characters\)
  2322.   sed "s/^X//" >'bwbasic-2.10/bwbtest/function.bas' <<'END_OF_FILE'
  2323. X1000 PRINT "ABS(-2.2): "; ABS(-2.2)
  2324. X1010 PRINT "DATE$: <"; DATE$; ">"
  2325. X1020 PRINT "TIME$: <"; TIME$; ">"
  2326. X1030 PRINT "ATN(-2.2): "; ATN(-2.2)
  2327. X1040 PRINT "COS(-2.2): "; COS(-2.2)
  2328. X1050 PRINT "LOG(2.2): "; LOG(2.2)
  2329. X1060 PRINT "SIN(-2.2): "; SIN(-2.2)
  2330. X1070 PRINT "SQR(2.2): "; SQR(2.2)
  2331. X1080 PRINT "TAN(-2.2): "; TAN(-2.2)
  2332. X1090 PRINT "SGN(-2.2): "; SGN(-2.2)
  2333. X1100 PRINT "INT(-2.2): "; INT(-2.2)
  2334. X1102 INPUT "Paused";X$
  2335. X1110 PRINT "RND(-2.2): "; RND(-2.2)
  2336. X1120 PRINT "CHR$(&h60): "; CHR$(&H60)
  2337. X1130 PRINT "TAB(52): <"; TAB(52); ">"
  2338. X1140 PRINT "SPC(5): <"; SPC(5); ">"
  2339. X1150 PRINT "SPACE$(5): <"; SPACE$(5); ">"
  2340. X1160 PRINT "STRING$(5,X): <"; STRING$(5,"X"); ">"
  2341. X1170 PRINT "MID$(0123456789, 5, 4): <"; MID$("0123456789", 5, 4); ">"
  2342. X1180 PRINT "LEFT$(0123456789, 5): <"; LEFT$("0123456789", 5); ">"
  2343. X1190 PRINT "RIGHT$(0123456789, 5): <"; RIGHT$("0123456789", 5); ">"
  2344. X1200 PRINT "TIMER: "; TIMER
  2345. X1202 INPUT "Paused";X$
  2346. X1210 PRINT "VAL(X): "; VAL("X")
  2347. X1230 PRINT "ERR: "; ERR
  2348. X1240 PRINT "ERL: "; ERL
  2349. X1250 PRINT "LEN(0123456789): "; LEN("0123456789")
  2350. X1260 PRINT "CSNG(-2.2): "; CSNG(-2.2)
  2351. X1270 PRINT "EXP(-2.2): "; EXP(-2.2)
  2352. X1280 PRINT "INSTR(0123456789, 234): "; INSTR("0123456789", "234")
  2353. X1290 PRINT "STR$(-2.2): <"; STR$(-2.2); ">"
  2354. X1300 PRINT "HEX$(27): <"; HEX$(27); ">"
  2355. X1302 INPUT "Paused";X$
  2356. X1310 PRINT "OCT$(27): <"; OCT$(27); ">"
  2357. X1320 PRINT "CINT(-2.2): "; CINT(-2.2)
  2358. X1330 PRINT "ASC(0123456789): "; ASC("0123456789")
  2359. X1340 PRINT "ENVIRON$(PATH): <"; ENVIRON$("PATH"); ">"
  2360. X1350 PRINT "MKD$(17): <"; MKD$(17); ">"
  2361. X1360 PRINT "MKI$(17): <"; MKI$(17); ">"
  2362. X1370 PRINT "MKS$(17): <"; MKS$(17); ">"
  2363. X1380 PRINT "CVD(MKD$(17)): "; CVD(MKD$(17))
  2364. X1390 PRINT "CVS(MKS$(17)): "; CVS(MKS$(17))
  2365. X1400 PRINT "CVI(MKI$(17)): "; CVI(MKI$(17))
  2366. END_OF_FILE
  2367.   if test 1717 -ne `wc -c <'bwbasic-2.10/bwbtest/function.bas'`; then
  2368.     echo shar: \"'bwbasic-2.10/bwbtest/function.bas'\" unpacked with wrong size!
  2369.   fi
  2370.   # end of 'bwbasic-2.10/bwbtest/function.bas'
  2371. fi
  2372. echo shar: End of archive 6 \(of 15\).
  2373. cp /dev/null ark6isdone
  2374. MISSING=""
  2375. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ; do
  2376.     if test ! -f ark${I}isdone ; then
  2377.     MISSING="${MISSING} ${I}"
  2378.     fi
  2379. done
  2380. if test "${MISSING}" = "" ; then
  2381.     echo You have unpacked all 15 archives.
  2382.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2383. else
  2384.     echo You still must unpack the following archives:
  2385.     echo "        " ${MISSING}
  2386. fi
  2387. exit 0
  2388. exit 0 # Just in case...
  2389.