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

  1. Newsgroups: comp.sources.misc
  2. From: tcamp@delphi.com (Ted A. Campbell)
  3. Subject: v40i059:  bwbasic - Bywater BASIC interpreter version 2.10, Part08/15
  4. Message-ID: <1993Oct29.162641.3863@sparky.sterling.com>
  5. X-Md4-Signature: 31612def64a7ab03536e6e1c1ee6a33e
  6. Sender: kent@sparky.sterling.com (Kent Landfield)
  7. Organization: Sterling Software
  8. Date: Fri, 29 Oct 1993 16:26:41 GMT
  9. Approved: kent@sparky.sterling.com
  10.  
  11. Submitted-by: tcamp@delphi.com (Ted A. Campbell)
  12. Posting-number: Volume 40, Issue 59
  13. Archive-name: bwbasic/part08
  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/bwb_int.c bwbasic-2.10/bwb_mth.c
  22. #   bwbasic-2.10/bwbtest/mlifthen.bas
  23. # Wrapped by kent@sparky on Thu Oct 21 10:47:50 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 8 (of 15)."'
  27. if test -f 'bwbasic-2.10/bwb_int.c' -a "${1}" != "-c" ; then 
  28.   echo shar: Will not clobber existing file \"'bwbasic-2.10/bwb_int.c'\"
  29. else
  30.   echo shar: Extracting \"'bwbasic-2.10/bwb_int.c'\" \(20961 characters\)
  31.   sed "s/^X//" >'bwbasic-2.10/bwb_int.c' <<'END_OF_FILE'
  32. X/***************************************************************f
  33. X
  34. X        bwb_int.c       Line Interpretation Routines
  35. X                        for Bywater BASIC Interpreter
  36. X
  37. X                        Copyright (c) 1993, Ted A. Campbell
  38. X                        Bywater Software
  39. X
  40. X                        email: tcamp@delphi.com
  41. X
  42. X        Copyright and Permissions Information:
  43. X
  44. X        All U.S. and international rights are claimed by the author,
  45. X        Ted A. Campbell.
  46. X
  47. X    This software is released under the terms of the GNU General
  48. X    Public License (GPL), which is distributed with this software
  49. X    in the file "COPYING".  The GPL specifies the terms under
  50. X    which users may copy and use the software in this distribution.
  51. X
  52. X    A separate license is available for commercial distribution,
  53. X    for information on which you should contact the author.
  54. X
  55. X***************************************************************/
  56. X
  57. X#include <stdio.h>
  58. X#include <ctype.h>
  59. X
  60. X#include "bwbasic.h"
  61. X#include "bwb_mes.h"
  62. X
  63. X/***************************************************************
  64. X
  65. X        FUNCTION:       adv_element()
  66. X
  67. X        DESCRIPTION:    This function reads characters in <buffer>
  68. X                        beginning at <pos> and advances past a
  69. X                        line element, incrementing <pos> appropri-
  70. X                        ately and returning the line element in
  71. X                        <element>.
  72. X
  73. X***************************************************************/
  74. X
  75. X#if ANSI_C
  76. Xint
  77. Xadv_element( char *buffer, int *pos, char *element )
  78. X#else
  79. Xint
  80. Xadv_element( buffer, pos, element )
  81. X   char *buffer;
  82. X   int *pos;
  83. X   char *element;
  84. X#endif
  85. X   {
  86. X   int loop;                                    /* control loop */
  87. X   int e_pos;                                   /* position in element buffer */
  88. X   int str_const;                               /* boolean: building a string constant */
  89. X
  90. X   /* advance beyond any initial whitespace */
  91. X
  92. X   adv_ws( buffer, pos );
  93. X
  94. X#if INTENSIVE_DEBUG
  95. X   sprintf( bwb_ebuf, "in adv_element(): receieved <%s>.", &( buffer[ *pos ] ));
  96. X   bwb_debug( bwb_ebuf );
  97. X#endif
  98. X
  99. X   /* now loop while building an element and looking for an
  100. X      element terminator */
  101. X
  102. X   loop = TRUE;
  103. X   e_pos = 0;
  104. X   element[ e_pos ] = '\0';
  105. X   str_const = FALSE;
  106. X
  107. X   while ( loop == TRUE )
  108. X      {
  109. X      switch( buffer[ *pos ] )
  110. X         {
  111. X         case ',':                      /* element terminators */
  112. X         case ';':
  113. X#if MULTISEG_LINES
  114. X         case ':':
  115. X#endif
  116. X         case '=':
  117. X         case ' ':
  118. X         case '\t':
  119. X         case '\0':
  120. X         case '\n':
  121. X         case '\r':
  122. X            if ( str_const == TRUE )
  123. X               {
  124. X               element[ e_pos ] = buffer[ *pos ];
  125. X               ++e_pos;
  126. X               ++( *pos );
  127. X               element[ e_pos ] = '\0';
  128. X               }
  129. X            else
  130. X               {
  131. X               return TRUE;
  132. X               }
  133. X            break;
  134. X
  135. X         case '\"':                     /* string constant */
  136. X            element[ e_pos ] = buffer[ *pos ];
  137. X            ++e_pos;
  138. X            ++( *pos );
  139. X            element[ e_pos ] = '\0';
  140. X            if ( str_const == TRUE )    /* termination of string constant */
  141. X               {
  142. X               return TRUE;
  143. X               }
  144. X            else                        /* beginning of string constant */
  145. X               {
  146. X               str_const = TRUE;
  147. X               }
  148. X            break;
  149. X
  150. X         default:
  151. X            element[ e_pos ] = buffer[ *pos ];
  152. X            ++e_pos;
  153. X            ++( *pos );
  154. X            element[ e_pos ] = '\0';
  155. X            break;
  156. X         }
  157. X      }
  158. X
  159. X   /* This should not happen */
  160. X
  161. X   return FALSE;
  162. X
  163. X   }
  164. X
  165. X/***************************************************************
  166. X
  167. X        FUNCTION:       adv_ws()
  168. X
  169. X        DESCRIPTION:    This function reads characters in <buffer>
  170. X                        beginning at <pos> and advances past any
  171. X                        whitespace, incrementing <pos> appropri-
  172. X                        ately.
  173. X
  174. X***************************************************************/
  175. X
  176. X#if ANSI_C
  177. Xint
  178. Xadv_ws( char *buffer, int *pos )
  179. X#else
  180. Xint
  181. Xadv_ws( buffer, pos )
  182. X   char *buffer;
  183. X   int *pos;
  184. X#endif
  185. X   {
  186. X   int loop;
  187. X
  188. X   loop = TRUE;
  189. X   while ( loop == TRUE )
  190. X      {
  191. X      switch( buffer[ *pos ] )
  192. X         {
  193. X         case ' ':
  194. X         case '\t':
  195. X            ++( *pos );
  196. X            break;
  197. X         default:
  198. X            return TRUE;
  199. X         }
  200. X      }
  201. X
  202. X   /* This should not happen */
  203. X
  204. X   return FALSE;
  205. X
  206. X   }
  207. X
  208. X/***************************************************************
  209. X
  210. X    FUNCTION:       adv_eos()
  211. X
  212. X    DESCRIPTION:    This function reads characters in <buffer>
  213. X            beginning at <pos> and advances to the
  214. X            end of a segment delimited by ':',
  215. X            incrementing <pos> appropriately.
  216. X
  217. X***************************************************************/
  218. X
  219. X#if MULTISEG_LINES
  220. X#if ANSI_C
  221. Xint
  222. Xadv_eos( char *buffer, int *pos )
  223. X#else
  224. Xint
  225. Xadv_eos( buffer, pos )
  226. X   char *buffer;
  227. X   int *pos;
  228. X#endif
  229. X   {
  230. X   int loop;
  231. X
  232. X   loop = TRUE;
  233. X   while ( loop == TRUE )
  234. X      {
  235. X
  236. X      if ( is_eol( buffer, pos ) == TRUE )
  237. X     {
  238. X     return FALSE;
  239. X     }
  240. X
  241. X      switch( buffer[ *pos ] )
  242. X     {
  243. X     case ':':              /* end of segment marker */
  244. X        ++( *pos );
  245. X        return TRUE;
  246. X
  247. X     case '\"':             /* begin quoted string */
  248. X
  249. X        ++( *pos );
  250. X
  251. X        while ( buffer[ *pos ] != '\"' )
  252. X           {
  253. X           if ( is_eol( buffer, pos ) == TRUE )
  254. X          {
  255. X          return FALSE;
  256. X          }
  257. X           else
  258. X          {
  259. X          ++( *pos );
  260. X          }
  261. X           }
  262. X
  263. X        break;
  264. X
  265. X     default:
  266. X        ++( *pos );
  267. X     }
  268. X      }
  269. X
  270. X   /* This should not happen */
  271. X
  272. X   return FALSE;
  273. X
  274. X   }
  275. X
  276. X#endif                          /* MULTISEG_LINES */
  277. X
  278. X/***************************************************************
  279. X
  280. X        FUNCTION:       bwb_strtoupper()
  281. X
  282. X        DESCRIPTION:    This function converts the string in
  283. X                        <buffer> to upper-case characters.
  284. X
  285. X***************************************************************/
  286. X
  287. X#if ANSI_C
  288. Xint
  289. Xbwb_strtoupper( char *buffer )
  290. X#else
  291. Xint
  292. Xbwb_strtoupper( buffer )
  293. X   char *buffer;
  294. X#endif
  295. X   {
  296. X   char *p;
  297. X
  298. X   p = buffer;
  299. X   while ( *p != '\0' )
  300. X      {
  301. X      if ( islower( *p ) != FALSE )
  302. X         {
  303. X         *p = (char) toupper( *p );
  304. X         }
  305. X      ++p;
  306. X      }
  307. X
  308. X   return TRUE;
  309. X
  310. X   }
  311. X
  312. X/***************************************************************
  313. X
  314. X        FUNCTION:       line_start()
  315. X
  316. X        DESCRIPTION:    This function reads a line buffer in
  317. X                        <buffer> beginning at the position
  318. X                        <pos> and attempts to determine (a)
  319. X                        the position of the line number in the
  320. X                        buffer (returned in <lnpos>), (b) the
  321. X                        line number at this position (returned
  322. X                        in <lnum>), (c) the position of the
  323. X                        BASIC command in the buffer (returned
  324. X                        in <cmdpos>), (d) the position of this
  325. X                        BASIC command in the command table
  326. X                        (returned in <cmdnum>), and (e) the
  327. X                        position of the beginning of the rest
  328. X                        of the line (returned in <startpos>).
  329. X                        Although <startpos> must be returned
  330. X                        as a positive integer, the other
  331. X                        searches may fail, in which case FALSE
  332. X                        will be returned in their positions.
  333. X                        <pos> is not incremented.
  334. X
  335. X***************************************************************/
  336. X
  337. X#if ANSI_C
  338. Xint
  339. Xline_start( char *buffer, int *pos, int *lnpos, int *lnum, int *cmdpos,
  340. X   int *cmdnum, int *startpos )
  341. X#else
  342. Xint
  343. Xline_start( buffer, pos, lnpos, lnum, cmdpos, cmdnum, startpos )
  344. X   char *buffer;
  345. X   int *pos;
  346. X   int *lnpos;
  347. X   int *lnum;
  348. X   int *cmdpos;
  349. X   int *cmdnum;
  350. X   int *startpos;
  351. X#endif
  352. X   {
  353. X   static int position;
  354. X   static char *tbuf;
  355. X   static int init = FALSE;
  356. X
  357. X   /* get memory for temporary buffer if necessary */
  358. X
  359. X   if ( init == FALSE )
  360. X      {
  361. X      init = TRUE;
  362. X      if ( ( tbuf = calloc( MAXSTRINGSIZE + 1, sizeof( char ) )) == NULL )
  363. X         {
  364. X#if PROG_ERRORS
  365. X     bwb_error( "in line_start(): failed to get memory for tbuf" );
  366. X#else
  367. X     bwb_error( err_getmem );
  368. X#endif
  369. X     }
  370. X      }
  371. X
  372. X#if INTENSIVE_DEBUG
  373. X   sprintf( bwb_ebuf, "in line_start(): pos <%d> buffer <%s>", *pos,
  374. X      buffer );
  375. X   bwb_debug( bwb_ebuf );
  376. X#endif
  377. X
  378. X   /* set initial values */
  379. X
  380. X   *startpos = position = *pos;
  381. X   *cmdpos = *lnpos = *pos;
  382. X   *cmdnum = *lnum = -1;
  383. X
  384. X   /* check for null line */
  385. X
  386. X   adv_ws( buffer, &position );
  387. X   if ( buffer[ position ] == '\0' )
  388. X      {
  389. X#if INTENSIVE_DEBUG
  390. X      bwb_debug( "in line_start(): found NULL line" );
  391. X#endif
  392. X      *cmdnum = getcmdnum( CMD_REM );
  393. X      return TRUE;
  394. X      }
  395. X
  396. X   /* advance beyond the first element */
  397. X
  398. X   *lnpos = position;
  399. X   scan_element( buffer, &position, tbuf );
  400. X   adv_ws( buffer, &position );
  401. X
  402. X   /* test for a line number in the first element */
  403. X
  404. X   if ( is_numconst( tbuf ) == TRUE )               /* a line number */
  405. X      {
  406. X
  407. X      *lnum = atoi( tbuf );
  408. X      *startpos = position;                             /* temp */
  409. X      *cmdpos = position;
  410. X
  411. X      scan_element( buffer, &position, tbuf );       /* advance past next element */
  412. X
  413. X#if INTENSIVE_DEBUG
  414. X      sprintf( bwb_ebuf, "in line_start(): new element is <%s>", tbuf );
  415. X      bwb_debug( bwb_ebuf );
  416. X#endif
  417. X
  418. X#if STRUCT_CMDS
  419. X      if ( is_label( tbuf ) == TRUE )
  420. X         {
  421. X         *cmdnum = getcmdnum( CMD_LABEL );
  422. X         adv_ws( buffer, &position );
  423. X         *startpos = position;
  424. X         }
  425. X
  426. X      else if ( is_cmd( tbuf, cmdnum ) == TRUE )
  427. X#else
  428. X      if ( is_cmd( tbuf, cmdnum ) == TRUE )
  429. X#endif
  430. X         {
  431. X         adv_ws( buffer, &position );
  432. X         *startpos = position;
  433. X         }
  434. X
  435. X      else if ( is_let( &( buffer[ *cmdpos ] ), cmdnum ) == TRUE )
  436. X         {
  437. X         *cmdpos = -1;
  438. X         }
  439. X
  440. X      else
  441. X         {
  442. X         *cmdpos = *cmdnum = -1;
  443. X         }
  444. X      }
  445. X
  446. X   /* not a line number */
  447. X
  448. X   else
  449. X      {
  450. X      *lnum = -1;
  451. X      *lnpos = -1;
  452. X
  453. X#if INTENSIVE_DEBUG
  454. X      sprintf( bwb_ebuf, "in line_start(): no line number, element <%s>.",
  455. X         tbuf );
  456. X      bwb_debug( bwb_ebuf );
  457. X#endif
  458. X
  459. X#if STRUCT_CMDS
  460. X      if ( is_label( tbuf ) == TRUE )
  461. X         {
  462. X
  463. X#if INTENSIVE_DEBUG
  464. X     sprintf( bwb_ebuf, "in line_start(): label detected <%s>.",
  465. X        tbuf );
  466. X     bwb_debug( bwb_ebuf );
  467. X#endif
  468. X
  469. X         *cmdnum = getcmdnum( CMD_LABEL );
  470. X         adv_ws( buffer, &position );
  471. X         *startpos = position;
  472. X         }
  473. X
  474. X      else if ( is_cmd( tbuf, cmdnum ) == TRUE )
  475. X#else
  476. X      if ( is_cmd( tbuf, cmdnum ) == TRUE )
  477. X#endif
  478. X         {
  479. X         adv_ws( buffer, &position );
  480. X         *startpos = position;
  481. X         }
  482. X
  483. X      else if ( is_let( &( buffer[ position ] ), cmdnum ) == TRUE )
  484. X         {
  485. X         adv_ws( buffer, &position );
  486. X         *cmdpos = -1;
  487. X         }
  488. X
  489. X      else
  490. X         {
  491. X         *cmdpos = *cmdnum = -1;
  492. X         }
  493. X      }
  494. X
  495. X#if INTENSIVE_DEBUG
  496. X   sprintf( bwb_ebuf, "in line_start(): lnpos <%d> lnum <%d>",
  497. X      *lnpos, *lnum );
  498. X   bwb_debug( bwb_ebuf );
  499. X   sprintf( bwb_ebuf, "in line_start(): cmdpos <%d> cmdnum <%d> startpos <%d>",
  500. X      *cmdpos, *cmdnum, *startpos );
  501. X   bwb_debug( bwb_ebuf );
  502. X#endif
  503. X
  504. X   /* return */
  505. X
  506. X   return TRUE;
  507. X
  508. X   }
  509. X
  510. X/***************************************************************
  511. X
  512. X        FUNCTION:       is_cmd()
  513. X
  514. X    DESCRIPTION:    This function determines whether the
  515. X            string in 'buffer' is a BASIC command
  516. X            statement, returning TRUE or FALSE,
  517. X            and if TRUE returning the command number
  518. X            in the command lookup table in the
  519. X            integer pointed to by 'cmdnum'.
  520. X
  521. X***************************************************************/
  522. X
  523. X#if ANSI_C
  524. Xint
  525. Xis_cmd( char *buffer, int *cmdnum )
  526. X#else
  527. Xint
  528. Xis_cmd( buffer, cmdnum )
  529. X   char *buffer;
  530. X   int *cmdnum;
  531. X#endif
  532. X   {
  533. X   register int n;
  534. X
  535. X   /* Convert the command name to upper case */
  536. X
  537. X   bwb_strtoupper( buffer );
  538. X
  539. X   /* Go through the command table and search for a match. */
  540. X
  541. X   for ( n = 0; n < COMMANDS; ++n )
  542. X      {
  543. X      if ( strcmp( bwb_cmdtable[ n ].name, buffer ) == 0 )
  544. X         {
  545. X         *cmdnum = n;
  546. X         return TRUE;
  547. X         }
  548. X      }
  549. X
  550. X   /* No command name was found */
  551. X
  552. X   *cmdnum = -1;
  553. X   return FALSE;
  554. X
  555. X   }
  556. X
  557. X/***************************************************************
  558. X
  559. X        FUNCTION:       is_let()
  560. X
  561. X        DESCRIPTION:    This function tries to determine if the
  562. X                        expression in <buffer> is a LET statement
  563. X                        without the LET command specified.
  564. X
  565. X***************************************************************/
  566. X
  567. X#if ANSI_C
  568. Xint
  569. Xis_let( char *buffer, int *cmdnum )
  570. X#else
  571. Xint
  572. Xis_let( buffer, cmdnum )
  573. X   char *buffer;
  574. X   int *cmdnum;
  575. X#endif
  576. X   {
  577. X   register int n, i;
  578. X
  579. X#if INTENSIVE_DEBUG
  580. X   sprintf( bwb_ebuf, "in is_let(): buffer <%s>", buffer );
  581. X   bwb_debug( bwb_ebuf );
  582. X#endif
  583. X
  584. X   /* Go through the expression and search for an assignment operator. */
  585. X
  586. X   for ( n = 0; buffer[ n ] != '\0'; ++n )
  587. X      {
  588. X      switch( buffer[ n ] )
  589. X         {
  590. X         case '\"':                     /* string constant */
  591. X            ++n;
  592. X            while( buffer[ n ] != '\"' )
  593. X               {
  594. X               ++n;
  595. X               if ( buffer[ n ] == '\0' )
  596. X                  {
  597. X#if PROG_ERRORS
  598. X                  sprintf( bwb_ebuf, "Incomplete string constant" );
  599. X                  bwb_error( bwb_ebuf );
  600. X#else
  601. X                  bwb_error( err_syntax );
  602. X#endif
  603. X                  *cmdnum = -1;
  604. X                  return FALSE;
  605. X                  }
  606. X               }
  607. X            ++n;
  608. X            break;
  609. X         case '=':
  610. X
  611. X#if INTENSIVE_DEBUG
  612. X            sprintf( bwb_ebuf, "in is_let(): implied LET found." );
  613. X            bwb_debug( bwb_ebuf );
  614. X#endif
  615. X
  616. X            for ( i = 0; i < COMMANDS; ++i )
  617. X               {
  618. X               if ( strncmp( bwb_cmdtable[ i ].name, "LET", (size_t) 3 ) == 0 )
  619. X                  {
  620. X                  *cmdnum = i;
  621. X                  }
  622. X               }
  623. X            return TRUE;
  624. X         }
  625. X      }
  626. X
  627. X   /* No command name was found */
  628. X
  629. X   *cmdnum = -1;
  630. X   return FALSE;
  631. X
  632. X   }
  633. X
  634. X/***************************************************************
  635. X
  636. X        FUNCTION:       bwb_stripcr()
  637. X
  638. X    DESCRIPTION:    This function strips the carriage return
  639. X            or line-feed from the end of a string.
  640. X
  641. X***************************************************************/
  642. X
  643. X#if ANSI_C
  644. Xint
  645. Xbwb_stripcr( char *s )
  646. X#else
  647. Xint
  648. Xbwb_stripcr( s )
  649. X   char *s;
  650. X#endif
  651. X   {
  652. X   char *p;
  653. X
  654. X   p = s;
  655. X   while ( *p != 0 )
  656. X      {
  657. X      switch( *p )
  658. X         {
  659. X
  660. X
  661. X         case '\r':
  662. X         case '\n':
  663. X            *p = 0;
  664. X            return TRUE;
  665. X         }
  666. X      ++p;
  667. X      }
  668. X   *p = 0;
  669. X   return TRUE;
  670. X   }
  671. X
  672. X/***************************************************************
  673. X
  674. X        FUNCTION:       is_numconst()
  675. X
  676. X        DESCRIPTION:    This function reads the string in <buffer>
  677. X                        and returns TRUE if it is a numerical
  678. X                        constant and FALSE if it is not. At
  679. X                        this point, only decimal (base 10)
  680. X                        constants are detected.
  681. X
  682. X***************************************************************/
  683. X
  684. X#if ANSI_C
  685. Xint
  686. Xis_numconst( char *buffer )
  687. X#else
  688. Xint
  689. Xis_numconst( buffer )
  690. X   char *buffer;
  691. X#endif
  692. X   {
  693. X   char *p;
  694. X
  695. X#if INTENSIVE_DEBUG
  696. X   sprintf( bwb_ebuf, "in is_numconst(): received string <%s>.", buffer );
  697. X   bwb_debug( bwb_ebuf );
  698. X#endif
  699. X
  700. X   /* Return FALSE for empty buffer */
  701. X
  702. X   if ( buffer[ 0 ] == '\0' )
  703. X      {
  704. X      return FALSE;
  705. X      }
  706. X
  707. X   /* else check digits */
  708. X
  709. X   p = buffer;
  710. X   while( *p != '\0' )
  711. X      {
  712. X      switch( *p )
  713. X         {
  714. X         case '0':
  715. X         case '1':
  716. X         case '2':
  717. X         case '3':
  718. X         case '4':
  719. X         case '5':
  720. X         case '6':
  721. X         case '7':
  722. X         case '8':
  723. X         case '9':
  724. X            break;
  725. X         default:
  726. X            return FALSE;
  727. X         }
  728. X      ++p;
  729. X      }
  730. X
  731. X   /* only numerical characters detected */
  732. X
  733. X   return TRUE;
  734. X
  735. X   }
  736. X
  737. X/***************************************************************
  738. X
  739. X        FUNCTION:       bwb_numseq()
  740. X
  741. X    DESCRIPTION:    This function reads in a sequence of
  742. X            numbers (e.g., "10-120"), returning
  743. X            the first and last numbers in the sequence
  744. X            in the integers pointed to by 'start' and
  745. X            'end'.
  746. X
  747. X***************************************************************/
  748. X
  749. X#if ANSI_C
  750. Xint
  751. Xbwb_numseq( char *buffer, int *start, int *end )
  752. X#else
  753. Xint
  754. Xbwb_numseq( buffer, start, end )
  755. X   char *buffer;
  756. X   int *start;
  757. X   int *end;
  758. X#endif
  759. X   {
  760. X   register int b, n;
  761. X   int numbers;
  762. X   static char *tbuf;
  763. X   static int init = FALSE;
  764. X
  765. X   /* get memory for temporary buffer if necessary */
  766. X
  767. X   if ( init == FALSE )
  768. X      {
  769. X      init = TRUE;
  770. X      if ( ( tbuf = calloc( MAXSTRINGSIZE + 1, sizeof( char ) )) == NULL )
  771. X         {
  772. X#if PROG_ERRORS
  773. X     bwb_error( "in bwb_numseq(): failed to find memory for tbuf" );
  774. X#else
  775. X     bwb_error( err_getmem );
  776. X#endif
  777. X     }
  778. X      }
  779. X
  780. X   if ( buffer[ 0 ] == 0 )
  781. X      {
  782. X      *start = *end = 0;
  783. X      return FALSE;
  784. X      }
  785. X
  786. X   numbers = n = b = 0;
  787. X   tbuf[ 0 ] = 0;
  788. X   while( TRUE )
  789. X      {
  790. X      switch( buffer[ b ] )
  791. X         {
  792. X         case 0:                           /* end of string */
  793. X         case '\n':
  794. X         case '\r':
  795. X            if ( n > 0 )
  796. X               {
  797. X               if ( numbers == 0 )
  798. X                  {
  799. X                  *end = 0;
  800. X                  *start = atoi( tbuf );
  801. X                  ++numbers;
  802. X                  }
  803. X               else
  804. X                  {
  805. X
  806. X                  *end = atoi( tbuf );
  807. X                  return TRUE;
  808. X                  }
  809. X               }
  810. X            else
  811. X               {
  812. X               if ( numbers == 0 )
  813. X                  {
  814. X                  *start = *end = 0;
  815. X                  }
  816. X               else if ( numbers == 1 )
  817. X                  {
  818. X                  *end = 0;
  819. X                  }
  820. X               else if ( ( numbers == 2 ) && ( tbuf[ 0 ] == 0 ))
  821. X                  {
  822. X                  *end = 0;
  823. X                  }
  824. X               }
  825. X            return TRUE;
  826. X
  827. X#ifdef ALLOWWHITESPACE
  828. X         case ' ':                         /* whitespace */
  829. X         case '\t':
  830. X#endif
  831. X
  832. X         case '-':                         /* or skip to next number */
  833. X            if ( n > 0 )
  834. X               {
  835. X               if ( numbers == 0 )
  836. X                  {
  837. X                  *start = atoi( tbuf );
  838. X                  ++numbers;
  839. X                  }
  840. X               else
  841. X                  {
  842. X                  *end = atoi( tbuf );
  843. X                  return TRUE;
  844. X                  }
  845. X               }
  846. X            ++b;
  847. X            n = 0;
  848. X            break;
  849. X         case '0':
  850. X         case '1':
  851. X         case '2':
  852. X         case '3':
  853. X         case '4':
  854. X         case '5':
  855. X         case '6':
  856. X         case '7':
  857. X         case '8':
  858. X         case '9':
  859. X            tbuf[ n ] = buffer[ b ];
  860. X            ++n;
  861. X            tbuf[ n ] = 0;
  862. X            ++b;
  863. X            break;
  864. X         default:
  865. X#if PROG_ERRORS
  866. X            sprintf( bwb_ebuf,
  867. X               "ERROR: character <%c> unexpected in numerical sequence",
  868. X               buffer[ b ] );
  869. X            ++b;
  870. X            bwb_error( bwb_ebuf );
  871. X#else
  872. X            bwb_error( err_syntax );
  873. X#endif
  874. X            break;
  875. X         }
  876. X      }
  877. X
  878. X   }
  879. X
  880. X/***************************************************************
  881. X
  882. X        FUNCTION:       bwb_freeline()
  883. X
  884. X    DESCRIPTION:    This function frees memory associated
  885. X            with a program line in memory.
  886. X
  887. X***************************************************************/
  888. X
  889. X#if ANSI_C
  890. Xint
  891. Xbwb_freeline( struct bwb_line *l )
  892. X#else
  893. Xint
  894. Xbwb_freeline( l )
  895. X   struct bwb_line *l;
  896. X#endif
  897. X   {
  898. X
  899. X   /* free arguments if there are any */
  900. X
  901. X   free( l );
  902. X
  903. X   return TRUE;
  904. X   }
  905. X
  906. X/***************************************************************
  907. X
  908. X        FUNCTION:       int_qmdstr()
  909. X
  910. X    DESCRIPTION:    This function returns a string delimited
  911. X            by quotation marks.
  912. X
  913. X***************************************************************/
  914. X
  915. X#if ANSI_C
  916. Xint
  917. Xint_qmdstr( char *buffer_a, char *buffer_b )
  918. X#else
  919. Xint
  920. Xint_qmdstr( buffer_a, buffer_b )
  921. X   char *buffer_a;
  922. X   char *buffer_b;
  923. X#endif
  924. X   {
  925. X   char *a, *b;
  926. X
  927. X   a = buffer_a;
  928. X   ++a;                         /* advance beyond quotation mark */
  929. X   b = buffer_b;
  930. X
  931. X   while( *a != '\"' )
  932. X      {
  933. X      *b = *a;
  934. X      ++a;
  935. X      ++b;
  936. X      *b = '\0';
  937. X      }
  938. X
  939. X   return TRUE;
  940. X
  941. X   }
  942. X
  943. X/***************************************************************
  944. X
  945. X    FUNCTION:       is_eol()
  946. X
  947. X    DESCRIPTION:    This function determines whether the buffer
  948. X            is at the end of a line.
  949. X
  950. X***************************************************************/
  951. X
  952. X#if ANSI_C
  953. Xextern int
  954. Xis_eol( char *buffer, int *position )
  955. X#else
  956. Xint
  957. Xis_eol( buffer, position )
  958. X   char *buffer;
  959. X   int *position;
  960. X#endif
  961. X   {
  962. X
  963. X   adv_ws( buffer, position );
  964. X
  965. X#if INTENSIVE_DEBUG
  966. X   sprintf( bwb_ebuf, "in is_eol(): character is <0x%x> = <%c>",
  967. X      buffer[ *position ], buffer[ *position ] );
  968. X   bwb_debug( bwb_ebuf );
  969. X#endif
  970. X
  971. X   switch( buffer[ *position ] )
  972. X      {
  973. X      case '\0':
  974. X      case '\n':
  975. X      case '\r':
  976. X#if MULTISEG_LINES
  977. X      case ':':
  978. X#endif
  979. X         return TRUE;
  980. X      default:
  981. X         return FALSE;
  982. X      }
  983. X
  984. X   }
  985. X
  986. END_OF_FILE
  987.   if test 20961 -ne `wc -c <'bwbasic-2.10/bwb_int.c'`; then
  988.     echo shar: \"'bwbasic-2.10/bwb_int.c'\" unpacked with wrong size!
  989.   fi
  990.   # end of 'bwbasic-2.10/bwb_int.c'
  991. fi
  992. if test -f 'bwbasic-2.10/bwb_mth.c' -a "${1}" != "-c" ; then 
  993.   echo shar: Will not clobber existing file \"'bwbasic-2.10/bwb_mth.c'\"
  994. else
  995.   echo shar: Extracting \"'bwbasic-2.10/bwb_mth.c'\" \(45044 characters\)
  996.   sed "s/^X//" >'bwbasic-2.10/bwb_mth.c' <<'END_OF_FILE'
  997. X/****************************************************************
  998. X
  999. X        bwb_mth.c       Mathematical Functions
  1000. X                        for Bywater BASIC Interpreter
  1001. X
  1002. X                        Copyright (c) 1993, Ted A. Campbell
  1003. X                        Bywater Software
  1004. X
  1005. X                        email: tcamp@delphi.com
  1006. X
  1007. X        Copyright and Permissions Information:
  1008. X
  1009. X        All U.S. and international rights are claimed by the author,
  1010. X        Ted A. Campbell.
  1011. X
  1012. X    This software is released under the terms of the GNU General
  1013. X    Public License (GPL), which is distributed with this software
  1014. X    in the file "COPYING".  The GPL specifies the terms under
  1015. X    which users may copy and use the software in this distribution.
  1016. X
  1017. X    A separate license is available for commercial distribution,
  1018. X    for information on which you should contact the author.
  1019. X
  1020. X****************************************************************/
  1021. X
  1022. X#include <stdio.h>
  1023. X#include <ctype.h>
  1024. X#include <math.h>
  1025. X#include <time.h>
  1026. X
  1027. X#include "bwbasic.h"
  1028. X#include "bwb_mes.h"
  1029. X
  1030. X#ifndef RAND_MAX            /* added in v1.11 */
  1031. X#define RAND_MAX    32767
  1032. X#endif
  1033. X
  1034. X#if ANSI_C
  1035. Xbnumber round_int( bnumber x );
  1036. X#else
  1037. Xbnumber round_int();
  1038. X#endif
  1039. X
  1040. X#if MS_FUNCS
  1041. Xunion un_integer
  1042. X   {
  1043. X   int the_integer;
  1044. X   unsigned char the_chars[ sizeof( int ) ];
  1045. X   } an_integer;
  1046. X
  1047. Xunion un_single
  1048. X   {
  1049. X   float the_float;
  1050. X   unsigned char the_chars[ sizeof( float) ];
  1051. X   } a_float;
  1052. X
  1053. Xunion un_double
  1054. X   {
  1055. X   double the_double;
  1056. X   unsigned char the_chars[ sizeof( double ) ];
  1057. X   } a_double;
  1058. X#endif
  1059. X
  1060. X#if COMPRESS_FUNCS
  1061. X
  1062. X/***************************************************************
  1063. X
  1064. X    FUNCTION:       fnc_core()
  1065. X
  1066. X    DESCRIPTION:    This C function implements all core
  1067. X            BASIC functions if COMPRESS_FUNCS is
  1068. X            TRUE.  This method saves program space.
  1069. X
  1070. X***************************************************************/
  1071. X
  1072. X#if ANSI_C
  1073. Xstruct bwb_variable *
  1074. Xfnc_core( int argc, struct bwb_variable *argv, int unique_id  )
  1075. X#else
  1076. Xstruct bwb_variable *
  1077. Xfnc_core( argc, argv, unique_id  )
  1078. X   int argc;
  1079. X   struct bwb_variable *argv;
  1080. X   int unique_id;
  1081. X#endif
  1082. X   {
  1083. X   static struct bwb_variable nvar;
  1084. X   static int init = FALSE;
  1085. X   bnumber nval;
  1086. X
  1087. X#if INTENSIVE_DEBUG
  1088. X   sprintf( bwb_ebuf, "in fnc_core(): entered function" );
  1089. X   bwb_debug( bwb_ebuf );
  1090. X#endif
  1091. X
  1092. X   /* initialize the variable if necessary */
  1093. X
  1094. X   if ( init == FALSE )
  1095. X      {
  1096. X      init = TRUE;
  1097. X      strncpy( nvar.name, "(core var)", MAXVARNAMESIZE );
  1098. X#if INTENSIVE_DEBUG
  1099. X      sprintf( bwb_ebuf, "in fnc_core(): ready to make local variable <%s>",
  1100. X     nvar.name );
  1101. X      bwb_debug( bwb_ebuf );
  1102. X#endif
  1103. X      var_make( &nvar, NUMBER );
  1104. X      }
  1105. X
  1106. X#if INTENSIVE_DEBUG
  1107. X   sprintf( bwb_ebuf, "in fnc_core(): received f_arg <%f> nvar type <%c>",
  1108. X      var_getnval( &( argv[ 0 ] ) ), nvar.type );
  1109. X   bwb_debug( bwb_ebuf );
  1110. X#endif
  1111. X
  1112. X   /* check for number of arguments as appropriate */
  1113. X
  1114. X   switch ( unique_id )
  1115. X      {
  1116. X      case F_RND:                       /* no arguments necessary for RND */
  1117. X     break;
  1118. X      default:
  1119. X#if PROG_ERRORS
  1120. X     if ( argc < 1 )
  1121. X        {
  1122. X        sprintf( bwb_ebuf, "Not enough parameters (%d) to core function.",
  1123. X           argc );
  1124. X        bwb_error( bwb_ebuf );
  1125. X        return NULL;
  1126. X        }
  1127. X     else if ( argc > 1 )
  1128. X        {
  1129. X        sprintf( bwb_ebuf, "Too many parameters (%d) to core function.",
  1130. X           argc );
  1131. X        bwb_error( bwb_ebuf );
  1132. X        return NULL;
  1133. X        }
  1134. X#else
  1135. X     if ( fnc_checkargs( argc, argv, 1, 1 ) == FALSE )
  1136. X        {
  1137. X        return NULL;
  1138. X        }
  1139. X#endif
  1140. X      }
  1141. X
  1142. X   /* assign values */
  1143. X
  1144. X#if INTENSIVE_DEBUG
  1145. X   sprintf( bwb_ebuf, "in fnc_core(): nvar type <%c>; calling findnval()",
  1146. X      nvar.type );
  1147. X   bwb_debug( bwb_ebuf );
  1148. X#endif
  1149. X
  1150. X   switch( unique_id )
  1151. X      {
  1152. X      case F_ABS:
  1153. X     * var_findnval( &nvar, nvar.array_pos ) =
  1154. X        (bnumber) fabs( var_getnval( &( argv[ 0 ] ) ) );
  1155. X     break;
  1156. X      case F_ATN:
  1157. X     * var_findnval( &nvar, nvar.array_pos )
  1158. X        = (bnumber) atan( (double) var_getnval( &( argv[ 0 ] ) ) );
  1159. X     break;
  1160. X      case F_COS:
  1161. X     * var_findnval( &nvar, nvar.array_pos )
  1162. X        = (bnumber) cos( (double) var_getnval( &( argv[ 0 ] ) ) );
  1163. X     break;
  1164. X      case F_EXP:
  1165. X     * var_findnval( &nvar, nvar.array_pos )
  1166. X        = (bnumber) exp( var_getnval( &( argv[ 0 ] ) ) );
  1167. X     break;
  1168. X      case F_INT:
  1169. X     * var_findnval( &nvar, nvar.array_pos )
  1170. X        = (bnumber) floor( (double) var_getnval( &( argv[ 0 ] ) ) );
  1171. X     break;
  1172. X      case F_LOG:
  1173. X     * var_findnval( &nvar, nvar.array_pos )
  1174. X        = (bnumber) log( (double) var_getnval( &( argv[ 0 ] ) ) );
  1175. X     break;
  1176. X      case F_RND:
  1177. X     * var_findnval( &nvar, nvar.array_pos ) = (float) rand() / RAND_MAX;
  1178. X     break;
  1179. X      case F_SGN:
  1180. X     nval = var_getnval( &( argv[ 0 ] ));
  1181. X     if ( nval == (bnumber) 0.0 )
  1182. X        {
  1183. X        * var_findnval( &nvar, nvar.array_pos ) = (bnumber) 0;
  1184. X        }
  1185. X     else if ( nval > (bnumber) 0.0 )
  1186. X        {
  1187. X        * var_findnval( &nvar, nvar.array_pos ) = (bnumber) 1;
  1188. X        }
  1189. X     else
  1190. X        {
  1191. X        * var_findnval( &nvar, nvar.array_pos ) = (bnumber) -1;
  1192. X        }
  1193. X     break;
  1194. X      case F_SIN:
  1195. X     * var_findnval( &nvar, nvar.array_pos )
  1196. X        = (bnumber) sin( (double) var_getnval( &( argv[ 0 ] ) ) );
  1197. X     break;
  1198. X      case F_SQR:
  1199. X     * var_findnval( &nvar, nvar.array_pos )
  1200. X        = (bnumber) sqrt( (double) var_getnval( &( argv[ 0 ] ) ) );
  1201. X     break;
  1202. X      case F_TAN:
  1203. X     * var_findnval( &nvar, nvar.array_pos )
  1204. X        = (bnumber) tan( (double) var_getnval( &( argv[ 0 ] ) ) );
  1205. X     break;
  1206. X      }
  1207. X
  1208. X   return &nvar;
  1209. X
  1210. X   }
  1211. X
  1212. X#else
  1213. X
  1214. X/***************************************************************
  1215. X
  1216. X        FUNCTION:       fnc_abs()
  1217. X
  1218. X        DESCRIPTION:    This C function implements the BASIC
  1219. X                        predefined ABS function, returning the
  1220. X                        absolute value of the argument.
  1221. X
  1222. X    SYNTAX:        ABS( number )
  1223. X
  1224. X***************************************************************/
  1225. X
  1226. X#if ANSI_C
  1227. Xstruct bwb_variable *
  1228. Xfnc_abs( int argc, struct bwb_variable *argv, int unique_id  )
  1229. X#else
  1230. Xstruct bwb_variable *
  1231. Xfnc_abs( argc, argv, unique_id  )
  1232. X   int argc;
  1233. X   struct bwb_variable *argv;
  1234. X   int unique_id;
  1235. X#endif
  1236. X   {
  1237. X   static struct bwb_variable nvar;
  1238. X   static int init = FALSE;
  1239. X
  1240. X#if INTENSIVE_DEBUG
  1241. X   sprintf( bwb_ebuf, "in fnc_abs(): entered function" );
  1242. X   bwb_debug( bwb_ebuf );
  1243. X#endif
  1244. X
  1245. X   /* initialize the variable if necessary */
  1246. X
  1247. X   if ( init == FALSE )
  1248. X      {
  1249. X      init = TRUE;
  1250. X      strncpy( nvar.name, "(abs var)", MAXVARNAMESIZE );
  1251. X#if INTENSIVE_DEBUG
  1252. X      sprintf( bwb_ebuf, "in fnc_abs(): ready to make local variable <%s>",
  1253. X         nvar.name );
  1254. X      bwb_debug( bwb_ebuf );
  1255. X#endif
  1256. X      var_make( &nvar, NUMBER );
  1257. X      }
  1258. X
  1259. X#if INTENSIVE_DEBUG
  1260. X   sprintf( bwb_ebuf, "in fnc_abs(): received f_arg <%f> nvar type <%c>",
  1261. X      var_getnval( &( argv[ 0 ] ) ), nvar.type );
  1262. X   bwb_debug( bwb_ebuf );
  1263. X#endif
  1264. X
  1265. X#if PROG_ERRORS
  1266. X   if ( argc < 1 )
  1267. X      {
  1268. X      sprintf( bwb_ebuf, "Not enough parameters (%d) to function ABS().",
  1269. X         argc );
  1270. X      bwb_error( bwb_ebuf );
  1271. X      return NULL;
  1272. X      }
  1273. X   else if ( argc > 1 )
  1274. X      {
  1275. X      sprintf( bwb_ebuf, "Too many parameters (%d) to function ABS().",
  1276. X         argc );
  1277. X      bwb_error( bwb_ebuf );
  1278. X      return NULL;
  1279. X      }
  1280. X#else
  1281. X   if ( fnc_checkargs( argc, argv, 1, 1 ) == FALSE )
  1282. X      {
  1283. X      return NULL;
  1284. X      }
  1285. X#endif
  1286. X
  1287. X   /* assign values */
  1288. X
  1289. X#if INTENSIVE_DEBUG
  1290. X   sprintf( bwb_ebuf, "in fnc_abs(): nvar type <%c>; calling finnval()",
  1291. X      nvar.type );
  1292. X   bwb_debug( bwb_ebuf );
  1293. X#endif
  1294. X
  1295. X   * var_findnval( &nvar, nvar.array_pos ) = 
  1296. X      (bnumber) fabs( var_getnval( &( argv[ 0 ] ) ) );
  1297. X
  1298. X   return &nvar;
  1299. X
  1300. X   }
  1301. X
  1302. X/***************************************************************
  1303. X
  1304. X        FUNCTION:       fnc_rnd()
  1305. X
  1306. X        DESCRIPTION:    This C function implements the BASIC
  1307. X                        predefined RND function, returning a
  1308. X                        pseudo-random number in the range
  1309. X                        0 to 1.  It is affected by the RANDOMIZE
  1310. X                        command statement.
  1311. X
  1312. X    SYNTAX:        RND( number )
  1313. X
  1314. X***************************************************************/
  1315. X
  1316. X#if ANSI_C
  1317. Xstruct bwb_variable *
  1318. Xfnc_rnd( int argc, struct bwb_variable *argv, int unique_id  )
  1319. X#else
  1320. Xstruct bwb_variable *
  1321. Xfnc_rnd( argc, argv, unique_id  )
  1322. X   int argc;
  1323. X   struct bwb_variable *argv;
  1324. X   int unique_id;
  1325. X#endif
  1326. X   {
  1327. X   static struct bwb_variable nvar;
  1328. X   static int init = FALSE;
  1329. X
  1330. X   /* initialize the variable if necessary */
  1331. X
  1332. X   if ( init == FALSE )
  1333. X      {
  1334. X      init = TRUE;
  1335. X      var_make( &nvar, NUMBER );
  1336. X      }
  1337. X
  1338. X   * var_findnval( &nvar, nvar.array_pos ) = (float) rand() / RAND_MAX;
  1339. X
  1340. X   return &nvar;
  1341. X   }
  1342. X
  1343. X/***************************************************************
  1344. X
  1345. X        FUNCTION:       fnc_atn()
  1346. X
  1347. X    DESCRIPTION:    This C function implements the BASIC
  1348. X                        predefined ATN function, returning the
  1349. X                        arctangent of the argument.
  1350. X
  1351. X    SYNTAX:        ATN( number )
  1352. X
  1353. X***************************************************************/
  1354. X
  1355. X#if ANSI_C
  1356. Xstruct bwb_variable *
  1357. Xfnc_atn( int argc, struct bwb_variable *argv, int unique_id  )
  1358. X#else
  1359. Xstruct bwb_variable *
  1360. Xfnc_atn( argc, argv, unique_id  )
  1361. X   int argc;
  1362. X   struct bwb_variable *argv;
  1363. X   int unique_id;
  1364. X#endif
  1365. X   {
  1366. X   static struct bwb_variable nvar;
  1367. X   static int init = FALSE;
  1368. X
  1369. X   /* initialize the variable if necessary */
  1370. X
  1371. X   if ( init == FALSE )
  1372. X      {
  1373. X      init = TRUE;
  1374. X      var_make( &nvar, NUMBER );
  1375. X      }
  1376. X
  1377. X#if INTENSIVE_DEBUG
  1378. X   sprintf( bwb_ebuf, "in fnc_atn(): received f_arg <%f> ",
  1379. X      var_getnval( &( argv[ 0 ] ) ) );
  1380. X   bwb_debug( bwb_ebuf );
  1381. X#endif
  1382. X
  1383. X#if PROG_ERRORS
  1384. X   if ( argc < 1 )
  1385. X      {
  1386. X      sprintf( bwb_ebuf, "Not enough parameters (%d) to function ATN().",
  1387. X         argc );
  1388. X      bwb_error( bwb_ebuf );
  1389. X      return NULL;
  1390. X      }
  1391. X   else if ( argc > 1 )
  1392. X      {
  1393. X      sprintf( bwb_ebuf, "Too many parameters (%d) to function ATN().",
  1394. X         argc );
  1395. X      bwb_error( bwb_ebuf );
  1396. X      return NULL;
  1397. X      }
  1398. X#else
  1399. X   if ( fnc_checkargs( argc, argv, 1, 1 ) == FALSE )
  1400. X      {
  1401. X      return NULL;
  1402. X      }
  1403. X#endif
  1404. X
  1405. X   /* assign values */
  1406. X
  1407. X   * var_findnval( &nvar, nvar.array_pos ) 
  1408. X      = (bnumber) atan( (double) var_getnval( &( argv[ 0 ] ) ) );
  1409. X
  1410. X   return &nvar;
  1411. X
  1412. X   }
  1413. X
  1414. X/***************************************************************
  1415. X
  1416. X        FUNCTION:       fnc_cos()
  1417. X
  1418. X        DESCRIPTION:    This C function implements the BASIC
  1419. X                        predefined COS function, returning the
  1420. X                        cosine of the argument.
  1421. X
  1422. X    SYNTAX:        COS( number )
  1423. X
  1424. X***************************************************************/
  1425. X
  1426. X#if ANSI_C
  1427. Xstruct bwb_variable *
  1428. Xfnc_cos( int argc, struct bwb_variable *argv, int unique_id  )
  1429. X#else
  1430. Xstruct bwb_variable *
  1431. Xfnc_cos( argc, argv, unique_id  )
  1432. X   int argc;
  1433. X   struct bwb_variable *argv;
  1434. X   int unique_id;
  1435. X#endif
  1436. X   {
  1437. X   static struct bwb_variable nvar;
  1438. X   static int init = FALSE;
  1439. X
  1440. X   /* initialize the variable if necessary */
  1441. X
  1442. X   if ( init == FALSE )
  1443. X      {
  1444. X      init = TRUE;
  1445. X      var_make( &nvar, NUMBER );
  1446. X      }
  1447. X
  1448. X#if INTENSIVE_DEBUG
  1449. X   sprintf( bwb_ebuf, "in fnc_cos(): received f_arg <%f> ",
  1450. X      var_getnval( &( argv[ 0 ] ) ) );
  1451. X   bwb_debug( bwb_ebuf );
  1452. X#endif
  1453. X
  1454. X#if PROG_ERRORS
  1455. X   if ( argc < 1 )
  1456. X      {
  1457. X      sprintf( bwb_ebuf, "Not enough parameters (%d) to function COS().",
  1458. X         argc );
  1459. X      bwb_error( bwb_ebuf );
  1460. X      return NULL;
  1461. X      }
  1462. X   else if ( argc > 1 )
  1463. X      {
  1464. X      sprintf( bwb_ebuf, "Too many parameters (%d) to function COS().",
  1465. X         argc );
  1466. X      bwb_error( bwb_ebuf );
  1467. X      return NULL;
  1468. X      }
  1469. X#else
  1470. X   if ( fnc_checkargs( argc, argv, 1, 1 ) == FALSE )
  1471. X      {
  1472. X      return NULL;
  1473. X      }
  1474. X#endif
  1475. X
  1476. X   /* assign values */
  1477. X
  1478. X   * var_findnval( &nvar, nvar.array_pos ) 
  1479. X      = (bnumber) cos( (double) var_getnval( &( argv[ 0 ] ) ) );
  1480. X
  1481. X   return &nvar;
  1482. X
  1483. X   }
  1484. X
  1485. X/***************************************************************
  1486. X
  1487. X        FUNCTION:       fnc_log()
  1488. X
  1489. X        DESCRIPTION:    This C function implements the BASIC
  1490. X                        predefined LOG function, returning the
  1491. X                        natural logarithm of the argument.
  1492. X
  1493. X    SYNTAX:        LOG( number )
  1494. X
  1495. X***************************************************************/
  1496. X
  1497. X#if ANSI_C
  1498. Xstruct bwb_variable *
  1499. Xfnc_log( int argc, struct bwb_variable *argv, int unique_id  )
  1500. X#else
  1501. Xstruct bwb_variable *
  1502. Xfnc_log( argc, argv, unique_id  )
  1503. X   int argc;
  1504. X   struct bwb_variable *argv;
  1505. X   int unique_id;
  1506. X#endif
  1507. X   {
  1508. X   static struct bwb_variable nvar;
  1509. X   static int init = FALSE;
  1510. X
  1511. X   /* initialize the variable if necessary */
  1512. X
  1513. X   if ( init == FALSE )
  1514. X      {
  1515. X      init = TRUE;
  1516. X      var_make( &nvar, NUMBER );
  1517. X      }
  1518. X
  1519. X#if INTENSIVE_DEBUG
  1520. X   sprintf( bwb_ebuf, "in fnc_log(): received f_arg <%f> ",
  1521. X      var_getnval( &( argv[ 0 ] ) ) );
  1522. X   bwb_debug( bwb_ebuf );
  1523. X#endif
  1524. X
  1525. X#if PROG_ERRORS
  1526. X   if ( argc < 1 )
  1527. X      {
  1528. X      sprintf( bwb_ebuf, "Not enough parameters (%d) to function LOG().",
  1529. X         argc );
  1530. X      bwb_error( bwb_ebuf );
  1531. X      return NULL;
  1532. X      }
  1533. X   else if ( argc > 1 )
  1534. X      {
  1535. X      sprintf( bwb_ebuf, "Too many parameters (%d) to function LOG().",
  1536. X         argc );
  1537. X      bwb_error( bwb_ebuf );
  1538. X      return NULL;
  1539. X      }
  1540. X#else
  1541. X   if ( fnc_checkargs( argc, argv, 1, 1 ) == FALSE )
  1542. X      {
  1543. X      return NULL;
  1544. X      }
  1545. X#endif
  1546. X
  1547. X   /* assign values */
  1548. X
  1549. X   * var_findnval( &nvar, nvar.array_pos ) 
  1550. X      = (bnumber) log( (double) var_getnval( &( argv[ 0 ] ) ) );
  1551. X
  1552. X   return &nvar;
  1553. X   }
  1554. X
  1555. X/***************************************************************
  1556. X
  1557. X        FUNCTION:       fnc_sin()
  1558. X
  1559. X        DESCRIPTION:    This C function implements the BASIC
  1560. X                        predefined SIN function, returning
  1561. X                        the sine of the argument.
  1562. X
  1563. X    SYNTAX:        SIN( number )
  1564. X
  1565. X***************************************************************/
  1566. X
  1567. X#if ANSI_C
  1568. Xstruct bwb_variable *
  1569. Xfnc_sin( int argc, struct bwb_variable *argv, int unique_id  )
  1570. X#else
  1571. Xstruct bwb_variable *
  1572. Xfnc_sin( argc, argv, unique_id  )
  1573. X   int argc;
  1574. X   struct bwb_variable *argv;
  1575. X   int unique_id;
  1576. X#endif
  1577. X   {
  1578. X   static struct bwb_variable nvar;
  1579. X   static int init = FALSE;
  1580. X
  1581. X   /* initialize the variable if necessary */
  1582. X
  1583. X   if ( init == FALSE )
  1584. X      {
  1585. X      init = TRUE;
  1586. X      var_make( &nvar, NUMBER );
  1587. X      }
  1588. X
  1589. X#if INTENSIVE_DEBUG
  1590. X   sprintf( bwb_ebuf, "in fnc_sin(): received f_arg <%f> ",
  1591. X      var_getnval( &( argv[ 0 ] ) ) );
  1592. X   bwb_debug( bwb_ebuf );
  1593. X#endif
  1594. X
  1595. X#if PROG_ERRORS
  1596. X   if ( argc < 1 )
  1597. X      {
  1598. X      sprintf( bwb_ebuf, "Not enough parameters (%d) to function SIN().",
  1599. X         argc );
  1600. X      bwb_error( bwb_ebuf );
  1601. X      return NULL;
  1602. X      }
  1603. X
  1604. X   else if ( argc > 1 )
  1605. X      {
  1606. X      sprintf( bwb_ebuf, "Too many parameters (%d) to function SIN().",
  1607. X         argc );
  1608. X      bwb_error( bwb_ebuf );
  1609. X      return NULL;
  1610. X      }
  1611. X#else
  1612. X   if ( fnc_checkargs( argc, argv, 1, 1 ) == FALSE )
  1613. X      {
  1614. X      return NULL;
  1615. X      }
  1616. X#endif
  1617. X
  1618. X   /* assign values */
  1619. X
  1620. X   * var_findnval( &nvar, nvar.array_pos ) 
  1621. X      = (bnumber) sin( (double) var_getnval( &( argv[ 0 ] ) ) );
  1622. X
  1623. X   return &nvar;
  1624. X
  1625. X   }
  1626. X
  1627. X
  1628. X/***************************************************************
  1629. X
  1630. X        FUNCTION:       fnc_sqr()
  1631. X
  1632. X        DESCRIPTION:    This C function implements the BASIC
  1633. X                        predefined SQR function, returning
  1634. X                        the square root of the argument.
  1635. X
  1636. X    SYNTAX:        SQR( number )
  1637. X
  1638. X***************************************************************/
  1639. X
  1640. X#if ANSI_C
  1641. Xstruct bwb_variable *
  1642. Xfnc_sqr( int argc, struct bwb_variable *argv, int unique_id  )
  1643. X#else
  1644. Xstruct bwb_variable *
  1645. Xfnc_sqr( argc, argv, unique_id  )
  1646. X   int argc;
  1647. X   struct bwb_variable *argv;
  1648. X   int unique_id;
  1649. X#endif
  1650. X   {
  1651. X   static struct bwb_variable nvar;
  1652. X   static int init = FALSE;
  1653. X
  1654. X   /* initialize the variable if necessary */
  1655. X
  1656. X   if ( init == FALSE )
  1657. X      {
  1658. X      init = TRUE;
  1659. X      var_make( &nvar, NUMBER );
  1660. X      }
  1661. X
  1662. X#if INTENSIVE_DEBUG
  1663. X   sprintf( bwb_ebuf, "in fnc_sqr(): received f_arg <%f> ",
  1664. X      var_getnval( &( argv[ 0 ] ) ) );
  1665. X   bwb_debug( bwb_ebuf );
  1666. X#endif
  1667. X
  1668. X#if PROG_ERRORS
  1669. X   if ( argc < 1 )
  1670. X      {
  1671. X      sprintf( bwb_ebuf, "Not enough parameters (%d) to function SQR().",
  1672. X         argc );
  1673. X      bwb_error( bwb_ebuf );
  1674. X      return NULL;
  1675. X      }
  1676. X   else if ( argc > 1 )
  1677. X      {
  1678. X      sprintf( bwb_ebuf, "Too many parameters (%d) to function SQR().",
  1679. X         argc );
  1680. X      bwb_error( bwb_ebuf );
  1681. X      return NULL;
  1682. X      }
  1683. X#else
  1684. X   if ( fnc_checkargs( argc, argv, 1, 1 ) == FALSE )
  1685. X      {
  1686. X      return NULL;
  1687. X      }
  1688. X#endif
  1689. X
  1690. X   /* assign values */
  1691. X
  1692. X   * var_findnval( &nvar, nvar.array_pos ) 
  1693. X      = (bnumber) sqrt( (double) var_getnval( &( argv[ 0 ] ) ) );
  1694. X
  1695. X   return &nvar;
  1696. X
  1697. X   }
  1698. X
  1699. X/***************************************************************
  1700. X
  1701. X        FUNCTION:       fnc_tan()
  1702. X
  1703. X        DESCRIPTION:    This C function implements the BASIC
  1704. X                        predefined TAN function, returning the
  1705. X                        tangent of the argument.
  1706. X
  1707. X    SYNTAX:        TAN( number )
  1708. X
  1709. X***************************************************************/
  1710. X
  1711. X#if ANSI_C
  1712. Xstruct bwb_variable *
  1713. Xfnc_tan( int argc, struct bwb_variable *argv, int unique_id  )
  1714. X#else
  1715. Xstruct bwb_variable *
  1716. Xfnc_tan( argc, argv, unique_id  )
  1717. X   int argc;
  1718. X   struct bwb_variable *argv;
  1719. X   int unique_id;
  1720. X#endif
  1721. X   {
  1722. X   static struct bwb_variable nvar;
  1723. X   static int init = FALSE;
  1724. X
  1725. X   /* initialize the variable if necessary */
  1726. X
  1727. X   if ( init == FALSE )
  1728. X      {
  1729. X      init = TRUE;
  1730. X      var_make( &nvar, NUMBER );
  1731. X      }
  1732. X
  1733. X#if INTENSIVE_DEBUG
  1734. X   sprintf( bwb_ebuf, "in fnc_tan(): received f_arg <%f> ",
  1735. X      var_getnval( &( argv[ 0 ] ) ) );
  1736. X   bwb_debug( bwb_ebuf );
  1737. X#endif
  1738. X
  1739. X#if PROG_ERRORS
  1740. X   if ( argc < 1 )
  1741. X      {
  1742. X      sprintf( bwb_ebuf, "Not enough parameters (%d) to function TAN().",
  1743. X         argc );
  1744. X      bwb_error( bwb_ebuf );
  1745. X      return NULL;
  1746. X      }
  1747. X   else if ( argc > 1 )
  1748. X      {
  1749. X      sprintf( bwb_ebuf, "Too many parameters (%d) to function TAN().",
  1750. X         argc );
  1751. X      bwb_error( bwb_ebuf );
  1752. X      return NULL;
  1753. X      }
  1754. X#else
  1755. X   if ( fnc_checkargs( argc, argv, 1, 1 ) == FALSE )
  1756. X      {
  1757. X      return NULL;
  1758. X      }
  1759. X#endif
  1760. X
  1761. X   /* assign values */
  1762. X
  1763. X   * var_findnval( &nvar, nvar.array_pos ) 
  1764. X      = (bnumber) tan( (double) var_getnval( &( argv[ 0 ] ) ) );
  1765. X
  1766. X   return &nvar;
  1767. X
  1768. X   }
  1769. X
  1770. X
  1771. X/***************************************************************
  1772. X
  1773. X        FUNCTION:       fnc_sgn()
  1774. X
  1775. X        DESCRIPTION:    This C function implements the BASIC
  1776. X                        predefined SGN function, returning 0
  1777. X                        if the argument is 0, -1 if the argument
  1778. X                        is less than 0, or 1 if the argument
  1779. X                        is more than 0.
  1780. X
  1781. X    SYNTAX:        SGN( number )
  1782. X
  1783. X***************************************************************/
  1784. X
  1785. X#if ANSI_C
  1786. Xstruct bwb_variable *
  1787. Xfnc_sgn( int argc, struct bwb_variable *argv, int unique_id  )
  1788. X#else
  1789. Xstruct bwb_variable *
  1790. Xfnc_sgn( argc, argv, unique_id  )
  1791. X   int argc;
  1792. X   struct bwb_variable *argv;
  1793. X   int unique_id;
  1794. X#endif
  1795. X   {
  1796. X   static struct bwb_variable nvar;
  1797. X   bnumber nval;
  1798. X   static int init = FALSE;
  1799. X
  1800. X   /* initialize the variable if necessary */
  1801. X
  1802. X   if ( init == FALSE )
  1803. X      {
  1804. X      init = TRUE;
  1805. X      var_make( &nvar, NUMBER );
  1806. X      }
  1807. X
  1808. X#if INTENSIVE_DEBUG
  1809. X   sprintf( bwb_ebuf, "in fnc_sgn(): received f_arg <%f> ",
  1810. X      var_getnval( &( argv[ 0 ] ) ) );
  1811. X   bwb_debug( bwb_ebuf );
  1812. X#endif
  1813. X
  1814. X#if PROG_ERRORS
  1815. X   if ( argc < 1 )
  1816. X      {
  1817. X      sprintf( bwb_ebuf, "Not enough parameters (%d) to function SGN().",
  1818. X         argc );
  1819. X      bwb_error( bwb_ebuf );
  1820. X      return NULL;
  1821. X      }
  1822. X   else if ( argc > 1 )
  1823. X      {
  1824. X      sprintf( bwb_ebuf, "Too many parameters (%d) to function SGN().",
  1825. X         argc );
  1826. X      bwb_error( bwb_ebuf );
  1827. X      return NULL;
  1828. X      }
  1829. X#else
  1830. X   if ( fnc_checkargs( argc, argv, 1, 1 ) == FALSE )
  1831. X      {
  1832. X      return NULL;
  1833. X      }
  1834. X#endif
  1835. X
  1836. X   /* assign values */
  1837. X
  1838. X   nval = var_getnval( &( argv[ 0 ] ));
  1839. X
  1840. X   if ( nval == (bnumber) 0.0 )
  1841. X      {
  1842. X      * var_findnval( &nvar, nvar.array_pos ) = (bnumber) 0;
  1843. X      }
  1844. X   else if ( nval > (bnumber) 0.0 )
  1845. X      {
  1846. X      * var_findnval( &nvar, nvar.array_pos ) = (bnumber) 1;
  1847. X      }
  1848. X   else
  1849. X      {
  1850. X      * var_findnval( &nvar, nvar.array_pos ) = (bnumber) -1;
  1851. X      }
  1852. X
  1853. X   return &nvar;
  1854. X   }
  1855. X
  1856. X/***************************************************************
  1857. X
  1858. X        FUNCTION:       fnc_int()
  1859. X
  1860. X        DESCRIPTION:    This C function implements the BASIC
  1861. X                        predefined INT function, returning an
  1862. X                        integer value less then or equal to the 
  1863. X            argument.
  1864. X
  1865. X    SYNTAX:        INT( number )
  1866. X
  1867. X***************************************************************/
  1868. X
  1869. X#if ANSI_C
  1870. Xstruct bwb_variable *
  1871. Xfnc_int( int argc, struct bwb_variable *argv, int unique_id  )
  1872. X#else
  1873. Xstruct bwb_variable *
  1874. Xfnc_int( argc, argv, unique_id  )
  1875. X   int argc;
  1876. X   struct bwb_variable *argv;
  1877. X   int unique_id;
  1878. X#endif
  1879. X   {
  1880. X   static struct bwb_variable nvar;
  1881. X   static int init = FALSE;
  1882. X
  1883. X   /* initialize the variable if necessary */
  1884. X
  1885. X   if ( init == FALSE )
  1886. X      {
  1887. X      init = TRUE;
  1888. X      var_make( &nvar, NUMBER );
  1889. X      }
  1890. X
  1891. X#if INTENSIVE_DEBUG
  1892. X   sprintf( bwb_ebuf, "in fnc_int(): received f_arg <%f> ",
  1893. X      var_getnval( &( argv[ 0 ] ) ) );
  1894. X   bwb_debug( bwb_ebuf );
  1895. X#endif
  1896. X
  1897. X#if PROG_ERRORS
  1898. X   if ( argc < 1 )
  1899. X      {
  1900. X      sprintf( bwb_ebuf, "Not enough parameters (%d) to function INT().",
  1901. X         argc );
  1902. X      bwb_error( bwb_ebuf );
  1903. X      return NULL;
  1904. X      }
  1905. X   else if ( argc > 1 )
  1906. X      {
  1907. X      sprintf( bwb_ebuf, "Too many parameters (%d) to function INT().",
  1908. X         argc );
  1909. X      bwb_error( bwb_ebuf );
  1910. X      return NULL;
  1911. X      }
  1912. X#else
  1913. X   if ( fnc_checkargs( argc, argv, 1, 1 ) == FALSE )
  1914. X      {
  1915. X      return NULL;
  1916. X      }
  1917. X#endif
  1918. X
  1919. X   /* assign values */
  1920. X
  1921. X   * var_findnval( &nvar, nvar.array_pos ) 
  1922. X      = (bnumber) floor( (double) var_getnval( &( argv[ 0 ] ) ) );
  1923. X
  1924. X   return &nvar;
  1925. X   }
  1926. X
  1927. X/***************************************************************
  1928. X
  1929. X        FUNCTION:       fnc_exp()
  1930. X
  1931. X    DESCRIPTION:    This C function implements the BASIC
  1932. X            EXP() function, returning the exponential
  1933. X            value of the argument.
  1934. X
  1935. X    SYNTAX:        EXP( number )
  1936. X
  1937. X***************************************************************/
  1938. X
  1939. X#if ANSI_C
  1940. Xstruct bwb_variable *
  1941. Xfnc_exp( int argc, struct bwb_variable *argv, int unique_id )
  1942. X#else
  1943. Xstruct bwb_variable *
  1944. Xfnc_exp( argc, argv, unique_id )
  1945. X   int argc;
  1946. X   struct bwb_variable *argv;
  1947. X   int unique_id;
  1948. X#endif
  1949. X   {
  1950. X   static struct bwb_variable nvar;
  1951. X   static int init = FALSE;
  1952. X
  1953. X   /* initialize the variable if necessary */
  1954. X
  1955. X   if ( init == FALSE )
  1956. X      {
  1957. X      init = TRUE;
  1958. X      var_make( &nvar, NUMBER );
  1959. X      }
  1960. X
  1961. X#if PROG_ERRORS
  1962. X   if ( argc < 1 )
  1963. X      {
  1964. X      sprintf( bwb_ebuf, "Not enough parameters (%d) to function EXP().",
  1965. X         argc );
  1966. X      bwb_error( bwb_ebuf );
  1967. X      return NULL;
  1968. X      }
  1969. X
  1970. X   else if ( argc > 1 )
  1971. X      {
  1972. X      sprintf( bwb_ebuf, "Too many parameters (%d) to function EXP().",
  1973. X         argc );
  1974. X      bwb_error( bwb_ebuf );
  1975. X      return NULL;
  1976. X      }
  1977. X#else
  1978. X   if ( fnc_checkargs( argc, argv, 1, 1 ) == FALSE )
  1979. X      {
  1980. X      return NULL;
  1981. X      }
  1982. X#endif
  1983. X
  1984. X   /* assign values */
  1985. X
  1986. X   * var_findnval( &nvar, nvar.array_pos ) 
  1987. X      = (bnumber) exp( var_getnval( &( argv[ 0 ] ) ) );
  1988. X
  1989. X   return &nvar;
  1990. X   }
  1991. X
  1992. X#endif                          /* COMPRESS_FUNCS */
  1993. X
  1994. X#if COMMON_FUNCS
  1995. X
  1996. X/***************************************************************
  1997. X
  1998. X        FUNCTION:       fnc_val()
  1999. X
  2000. X    DESCRIPTION:    This C function implements the BASIC
  2001. X            VAL() function, returning the numerical
  2002. X            value of its string argument.
  2003. X
  2004. X    SYNTAX:        VAL( string$ )
  2005. X
  2006. X***************************************************************/
  2007. X
  2008. X#if ANSI_C
  2009. Xstruct bwb_variable *
  2010. Xfnc_val( int argc, struct bwb_variable *argv, int unique_id )
  2011. X#else
  2012. Xstruct bwb_variable *
  2013. Xfnc_val( argc, argv, unique_id )
  2014. X   int argc;
  2015. X   struct bwb_variable *argv;
  2016. X   int unique_id;
  2017. X#endif
  2018. X   {
  2019. X   static struct bwb_variable nvar;
  2020. X   static char *tbuf;
  2021. X   static int init = FALSE;
  2022. X
  2023. X   /* initialize the variable if necessary */
  2024. X
  2025. X   if ( init == FALSE )
  2026. X      {
  2027. X      init = TRUE;
  2028. X      var_make( &nvar, NUMBER );
  2029. X      if ( ( tbuf = calloc( MAXSTRINGSIZE + 1, sizeof( char ) )) == NULL )
  2030. X         {
  2031. X#if PROG_ERRORS
  2032. X         bwb_error( "in fnc_val(): failed to get memory for tbuf" );
  2033. X#else
  2034. X         bwb_error( err_getmem );
  2035. X#endif
  2036. X         }
  2037. X      }
  2038. X
  2039. X   /* check arguments */
  2040. X
  2041. X#if PROG_ERRORS
  2042. X   if ( argc < 1 )
  2043. X      {
  2044. X      sprintf( bwb_ebuf, "Not enough arguments to function VAL()" );
  2045. X      bwb_error( bwb_ebuf );
  2046. X      return NULL;
  2047. X      }
  2048. X   else if ( argc > 1 )
  2049. X      {
  2050. X      sprintf( bwb_ebuf, "Too many parameters (%d) to function VAL().",
  2051. X         argc );
  2052. X      bwb_error( bwb_ebuf );
  2053. X      return NULL;
  2054. X      }
  2055. X
  2056. X#else
  2057. X   if ( fnc_checkargs( argc, argv, 1, 1 ) == FALSE )
  2058. X      {
  2059. X      return NULL;
  2060. X      }
  2061. X#endif
  2062. X
  2063. X   if ( argv[ 0 ].type != STRING )
  2064. X      {
  2065. X#if PROG_ERRORS
  2066. X      sprintf( bwb_ebuf, "Argument to function VAL() must be a string." );
  2067. X      bwb_error( bwb_ebuf );
  2068. X#else
  2069. X      bwb_error( err_mismatch );
  2070. X#endif
  2071. X      return NULL;
  2072. X      }
  2073. X
  2074. X   /* read the value */
  2075. X
  2076. X   str_btoc( tbuf, var_getsval( &( argv[ 0 ] ) ));
  2077. X#if NUMBER_DOUBLE
  2078. X   sscanf( tbuf, "%lf",
  2079. X       var_findnval( &nvar, nvar.array_pos ) );
  2080. X#else
  2081. X   sscanf( tbuf, "%f",
  2082. X       var_findnval( &nvar, nvar.array_pos ) );
  2083. X#endif
  2084. X
  2085. X   return &nvar;
  2086. X   }
  2087. X
  2088. X/***************************************************************
  2089. X
  2090. X        FUNCTION:       fnc_str()
  2091. X
  2092. X    DESCRIPTION:    This C function implements the BASIC
  2093. X            STR$() function, returning an ASCII string
  2094. X            with the decimal value of the numerical argument.
  2095. X
  2096. X    SYNTAX:        STR$( number )
  2097. X
  2098. X***************************************************************/
  2099. X
  2100. X#if ANSI_C
  2101. Xstruct bwb_variable *
  2102. Xfnc_str( int argc, struct bwb_variable *argv, int unique_id )
  2103. X#else
  2104. Xstruct bwb_variable *
  2105. Xfnc_str( argc, argv, unique_id )
  2106. X   int argc;
  2107. X   struct bwb_variable *argv;
  2108. X   int unique_id;
  2109. X#endif
  2110. X   {
  2111. X   static struct bwb_variable nvar;
  2112. X   static char *tbuf;
  2113. X   static int init = FALSE;
  2114. X
  2115. X   /* initialize the variable if necessary */
  2116. X
  2117. X   if ( init == FALSE )
  2118. X      {
  2119. X      init = TRUE;
  2120. X      var_make( &nvar, STRING );
  2121. X      if ( ( tbuf = calloc( MAXSTRINGSIZE + 1, sizeof( char ) )) == NULL )
  2122. X         {
  2123. X#if PROG_ERRORS
  2124. X         bwb_error( "in fnc_str(): failed to get memory for tbuf" );
  2125. X#else
  2126. X         bwb_error( err_getmem );
  2127. X#endif
  2128. X         }
  2129. X      }
  2130. X
  2131. X   /* check parameters */
  2132. X
  2133. X#if PROG_ERRORS
  2134. X   if ( argc < 1 )
  2135. X      {
  2136. X      sprintf( bwb_ebuf, "Not enough parameters (%d) to function STR$().",
  2137. X         argc );
  2138. X      bwb_error( bwb_ebuf );
  2139. X      return NULL;
  2140. X      }
  2141. X   else if ( argc > 1 )
  2142. X      {
  2143. X      sprintf( bwb_ebuf, "Too many parameters (%d) to function STR$().",
  2144. X         argc );
  2145. X      bwb_error( bwb_ebuf );
  2146. X      return NULL;
  2147. X      }
  2148. X#else
  2149. X   if ( fnc_checkargs( argc, argv, 1, 1 ) == FALSE )
  2150. X      {
  2151. X      return NULL;
  2152. X      }
  2153. X#endif
  2154. X
  2155. X   /* format as decimal number */
  2156. X
  2157. X   sprintf( tbuf, " %.*f", prn_precision( &( argv[ 0 ] ) ), 
  2158. X      var_getnval( &( argv[ 0 ] ) ) ); 
  2159. X   str_ctob( var_findsval( &nvar, nvar.array_pos ), tbuf );
  2160. X
  2161. X   return &nvar;
  2162. X   }
  2163. X
  2164. X#endif                          /* COMMON_FUNCS */
  2165. X
  2166. X#if MS_FUNCS
  2167. X
  2168. X/***************************************************************
  2169. X
  2170. X        FUNCTION:       fnc_hex()
  2171. X
  2172. X    DESCRIPTION:    This C function implements the BASIC
  2173. X            HEX$() function, returning a string
  2174. X            containing the hexadecimal value of
  2175. X            the numerical argument.
  2176. X
  2177. X    SYNTAX:        HEX$( number )
  2178. X
  2179. X***************************************************************/
  2180. X
  2181. X#if ANSI_C
  2182. Xstruct bwb_variable *
  2183. Xfnc_hex( int argc, struct bwb_variable *argv, int unique_id )
  2184. X#else
  2185. Xstruct bwb_variable *
  2186. Xfnc_hex( argc, argv, unique_id )
  2187. X   int argc;
  2188. X   struct bwb_variable *argv;
  2189. X   int unique_id;
  2190. X#endif
  2191. X   {
  2192. X   static struct bwb_variable nvar;
  2193. X   static char *tbuf;
  2194. X   static int init = FALSE;
  2195. X
  2196. X   /* initialize the variable if necessary */
  2197. X
  2198. X   if ( init == FALSE )
  2199. X      {
  2200. X      init = TRUE;
  2201. X      var_make( &nvar, STRING );
  2202. X      if ( ( tbuf = calloc( MAXSTRINGSIZE + 1, sizeof( char ) )) == NULL )
  2203. X         {
  2204. X#if PROG_ERRORS
  2205. X         bwb_error( "in fnc_hex(): failed to get memory for tbuf" );
  2206. X#else
  2207. X         bwb_error( err_getmem );
  2208. X#endif
  2209. X         }
  2210. X      }
  2211. X
  2212. X   /* check parameters */
  2213. X
  2214. X#if PROG_ERRORS
  2215. X   if ( argc < 1 )
  2216. X      {
  2217. X      sprintf( bwb_ebuf, "Not enough parameters (%d) to function HEX$().",
  2218. X         argc );
  2219. X      bwb_error( bwb_ebuf );
  2220. X      return NULL;
  2221. X      }
  2222. X   else if ( argc > 1 )
  2223. X      {
  2224. X      sprintf( bwb_ebuf, "Too many parameters (%d) to function HEX$().",
  2225. X         argc );
  2226. X      bwb_error( bwb_ebuf );
  2227. X      return NULL;
  2228. X      }
  2229. X#else
  2230. X   if ( fnc_checkargs( argc, argv, 1, 1 ) == FALSE )
  2231. X      {
  2232. X      return NULL;
  2233. X      }
  2234. X#endif
  2235. X
  2236. X   /* format as hex integer */
  2237. X
  2238. X   sprintf( tbuf, "%X", (int) trnc_int( (bnumber) var_getnval( &( argv[ 0 ] )) ) );
  2239. X   str_ctob( var_findsval( &nvar, nvar.array_pos ), tbuf );
  2240. X   return &nvar;
  2241. X   }
  2242. X
  2243. X/***************************************************************
  2244. X
  2245. X        FUNCTION:       fnc_oct()
  2246. X
  2247. X        DESCRIPTION:    This C function implements the BASIC
  2248. X            OCT$() function, returning a string
  2249. X            with the octal value of the numerical
  2250. X            argument.
  2251. X
  2252. X    SYNTAX:        OCT$( number )
  2253. X
  2254. X***************************************************************/
  2255. X
  2256. X#if ANSI_C
  2257. Xstruct bwb_variable *
  2258. Xfnc_oct( int argc, struct bwb_variable *argv, int unique_id )
  2259. X#else
  2260. Xstruct bwb_variable *
  2261. Xfnc_oct( argc, argv, unique_id )
  2262. X   int argc;
  2263. X   struct bwb_variable *argv;
  2264. X   int unique_id;
  2265. X#endif
  2266. X   {
  2267. X   static struct bwb_variable nvar;
  2268. X   static char *tbuf;
  2269. X   static int init = FALSE;
  2270. X
  2271. X   /* initialize the variable if necessary */
  2272. X
  2273. X   if ( init == FALSE )
  2274. X      {
  2275. X      init = TRUE;
  2276. X      var_make( &nvar, STRING );
  2277. X      if ( ( tbuf = calloc( MAXSTRINGSIZE + 1, sizeof( char ) )) == NULL )
  2278. X         {
  2279. X#if PROG_ERRORS
  2280. X         bwb_error( "in fnc_oct(): failed to get memory for tbuf" );
  2281. X#else
  2282. X         bwb_error( err_getmem );
  2283. X#endif
  2284. X         }
  2285. X      }
  2286. X
  2287. X   /* check parameters */
  2288. X
  2289. X#if PROG_ERRORS
  2290. X   if ( argc < 1 )
  2291. X      {
  2292. X      sprintf( bwb_ebuf, "Not enough parameters (%d) to function OCT$().",
  2293. X         argc );
  2294. X      bwb_error( bwb_ebuf );
  2295. X      return NULL;
  2296. X      }
  2297. X   else if ( argc > 1 )
  2298. X      {
  2299. X      sprintf( bwb_ebuf, "Too many parameters (%d) to function OCT$().",
  2300. X         argc );
  2301. X      bwb_error( bwb_ebuf );
  2302. X      return NULL;
  2303. X      }
  2304. X#else
  2305. X   if ( fnc_checkargs( argc, argv, 1, 1 ) == FALSE )
  2306. X      {
  2307. X      return NULL;
  2308. X      }
  2309. X#endif
  2310. X
  2311. X   /* format as octal integer */
  2312. X
  2313. X   sprintf( tbuf, "%o", (int) var_getnval( &( argv[ 0 ] ) ) );
  2314. X   str_ctob( var_findsval( &nvar, nvar.array_pos ), tbuf );
  2315. X   return &nvar;
  2316. X   }
  2317. X
  2318. X/***************************************************************
  2319. X
  2320. X        FUNCTION:       fnc_mki()
  2321. X
  2322. X        DESCRIPTION:    This C function implements the BASIC
  2323. X                        predefined MKI$() function.
  2324. X
  2325. X    NOTE:        As implemented in bwBASIC, this is a
  2326. X            pseudo-function, since bwBASIC does
  2327. X            not recognize precision levels.
  2328. X
  2329. X    SYNTAX:        MKI$( number )
  2330. X
  2331. X***************************************************************/
  2332. X
  2333. X#if ANSI_C
  2334. Xstruct bwb_variable *
  2335. Xfnc_mki( int argc, struct bwb_variable *argv, int unique_id  )
  2336. X#else
  2337. Xstruct bwb_variable *
  2338. Xfnc_mki( argc, argv, unique_id  )
  2339. X   int argc;
  2340. X   struct bwb_variable *argv;
  2341. X   int unique_id;
  2342. X#endif
  2343. X   {
  2344. X   register int i;
  2345. X   static struct bwb_variable nvar;
  2346. X   bstring *b;
  2347. X   static char tbuf[ sizeof( int ) ];
  2348. X   static int init = FALSE;
  2349. X
  2350. X   /* initialize the variable if necessary */
  2351. X
  2352. X   if ( init == FALSE )
  2353. X      {
  2354. X      init = TRUE;
  2355. X      var_make( &nvar, STRING );
  2356. X      }
  2357. X
  2358. X#if PROG_ERRORS
  2359. X   if ( argc < 1 )
  2360. X      {
  2361. X      sprintf( bwb_ebuf, "Not enough parameters (%d) to function MKI$().",
  2362. X         argc );
  2363. X      bwb_error( bwb_ebuf );
  2364. X      return NULL;
  2365. X      }
  2366. X   else if ( argc > 1 )
  2367. X      {
  2368. X      sprintf( bwb_ebuf, "Too many parameters (%d) to function MKI$().",
  2369. X         argc );
  2370. X      bwb_error( bwb_ebuf );
  2371. X      return NULL;
  2372. X      }
  2373. X#else
  2374. X   if ( fnc_checkargs( argc, argv, 1, 1 ) == FALSE )
  2375. X      {
  2376. X      return NULL;
  2377. X      }
  2378. X#endif
  2379. X
  2380. X   /* assign values */
  2381. X
  2382. X   an_integer.the_integer = (int) var_getnval( &( argv[ 0 ] ) );
  2383. X
  2384. X   for ( i = 0; i < sizeof( int ); ++i )
  2385. X      {
  2386. X      tbuf[ i ] = an_integer.the_chars[ i ];
  2387. X      }
  2388. X   b = var_getsval( &nvar );
  2389. X   b->length = sizeof( int );
  2390. X   b->sbuffer = tbuf;
  2391. X   b->rab = FALSE;
  2392. X
  2393. X   return &nvar;
  2394. X   }
  2395. X
  2396. X/***************************************************************
  2397. X
  2398. X        FUNCTION:       fnc_mkd()
  2399. X
  2400. X        DESCRIPTION:    This C function implements the BASIC
  2401. X                        predefined MKD$() function.
  2402. X
  2403. X    NOTE:        As implemented in bwBASIC, this is a
  2404. X            pseudo-function, since bwBASIC does
  2405. X            not recognize precision levels.
  2406. X
  2407. X    SYNTAX:        MKD$( number )
  2408. X
  2409. X***************************************************************/
  2410. X
  2411. X#if ANSI_C
  2412. Xstruct bwb_variable *
  2413. Xfnc_mkd( int argc, struct bwb_variable *argv, int unique_id  )
  2414. X#else
  2415. Xstruct bwb_variable *
  2416. Xfnc_mkd( argc, argv, unique_id  )
  2417. X   int argc;
  2418. X   struct bwb_variable *argv;
  2419. X   int unique_id;
  2420. X#endif
  2421. X   {
  2422. X   register int i;
  2423. X   static struct bwb_variable nvar;
  2424. X   bstring *b;
  2425. X   static char tbuf[ sizeof ( double ) ];
  2426. X   static int init = FALSE;
  2427. X
  2428. X   /* initialize the variable if necessary */
  2429. X
  2430. X   if ( init == FALSE )
  2431. X      {
  2432. X      init = TRUE;
  2433. X      var_make( &nvar, STRING );
  2434. X      }
  2435. X
  2436. X#if PROG_ERRORS
  2437. X   if ( argc < 1 )
  2438. X      {
  2439. X      sprintf( bwb_ebuf, "Not enough parameters (%d) to function MKD$().",
  2440. X         argc );
  2441. X      bwb_error( bwb_ebuf );
  2442. X      return NULL;
  2443. X      }
  2444. X   else if ( argc > 1 )
  2445. X      {
  2446. X      sprintf( bwb_ebuf, "Too many parameters (%d) to function MKD$().",
  2447. X         argc );
  2448. X      bwb_error( bwb_ebuf );
  2449. X      return NULL;
  2450. X      }
  2451. X#else
  2452. X   if ( fnc_checkargs( argc, argv, 1, 1 ) == FALSE )
  2453. X      {
  2454. X      return NULL;
  2455. X      }
  2456. X#endif
  2457. X
  2458. X   /* assign values */
  2459. X
  2460. X   a_double.the_double = var_getnval( &( argv[ 0 ] ) );
  2461. X
  2462. X   for ( i = 0; i < sizeof ( double ); ++i )
  2463. X      {
  2464. X      tbuf[ i ] = a_double.the_chars[ i ];
  2465. X      tbuf[ i + 1 ] = '\0';
  2466. X      }
  2467. X   b = var_getsval( &nvar );
  2468. X   b->length = sizeof( double );
  2469. X   b->sbuffer = tbuf;
  2470. X   b->rab = FALSE;
  2471. X
  2472. X   return &nvar;
  2473. X   }
  2474. X
  2475. X/***************************************************************
  2476. X
  2477. X        FUNCTION:       fnc_mks()
  2478. X
  2479. X        DESCRIPTION:    This C function implements the BASIC
  2480. X                        predefined MKS$() function.
  2481. X
  2482. X    NOTE:        As implemented in bwBASIC, this is a
  2483. X            pseudo-function, since bwBASIC does
  2484. X            not recognize precision levels.
  2485. X
  2486. X    SYNTAX:        MKS$( number )
  2487. X
  2488. X***************************************************************/
  2489. X
  2490. X#if ANSI_C
  2491. Xstruct bwb_variable *
  2492. Xfnc_mks( int argc, struct bwb_variable *argv, int unique_id  )
  2493. X#else
  2494. Xstruct bwb_variable *
  2495. Xfnc_mks( argc, argv, unique_id  )
  2496. X   int argc;
  2497. X   struct bwb_variable *argv;
  2498. X   int unique_id;
  2499. X#endif
  2500. X   {
  2501. X   register int i;
  2502. X   static struct bwb_variable nvar;
  2503. X   static char tbuf[ 5 ];
  2504. X   bstring *b;
  2505. X   static int init = FALSE;
  2506. X
  2507. X   /* initialize the variable if necessary */
  2508. X
  2509. X   if ( init == FALSE )
  2510. X      {
  2511. X      init = TRUE;
  2512. X      var_make( &nvar, STRING );
  2513. X      }
  2514. X
  2515. X#if PROG_ERRORS
  2516. X   if ( argc < 1 )
  2517. X      {
  2518. X      sprintf( bwb_ebuf, "Not enough parameters (%d) to function MKS$().",
  2519. X         argc );
  2520. X      bwb_error( bwb_ebuf );
  2521. X      return NULL;
  2522. X      }
  2523. X   else if ( argc > 1 )
  2524. X      {
  2525. X      sprintf( bwb_ebuf, "Too many parameters (%d) to function MKS$().",
  2526. X         argc );
  2527. X      bwb_error( bwb_ebuf );
  2528. X      return NULL;
  2529. X      }
  2530. X#else
  2531. X   if ( fnc_checkargs( argc, argv, 1, 1 ) == FALSE )
  2532. X      {
  2533. X      return NULL;
  2534. X      }
  2535. X#endif
  2536. X
  2537. X   /* assign values */
  2538. X
  2539. X   a_float.the_float = var_getnval( &( argv[ 0 ] ) );
  2540. X
  2541. X   for ( i = 0; i < sizeof( float ); ++i )
  2542. X      {
  2543. X      tbuf[ i ] = a_float.the_chars[ i ];
  2544. X      }
  2545. X   b = var_getsval( &nvar );
  2546. X   b->length = sizeof( float );
  2547. X   b->sbuffer = tbuf;
  2548. X   b->rab = FALSE;
  2549. X
  2550. X#if INTENSIVE_DEBUG
  2551. X   sprintf( bwb_ebuf, "in fnc_mks(): string <%s> hex vals <%X><%X><%X><%X>",
  2552. X      tbuf, tbuf[ 0 ], tbuf[ 1 ], tbuf[ 2 ], tbuf[ 3 ] );
  2553. X   bwb_debug( bwb_ebuf );
  2554. X#endif
  2555. X
  2556. X   return &nvar;
  2557. X   }
  2558. X
  2559. X/***************************************************************
  2560. X
  2561. X        FUNCTION:       fnc_cvi()
  2562. X
  2563. X        DESCRIPTION:    This C function implements the BASIC
  2564. X                        predefined CVI() function.
  2565. X
  2566. X    NOTE:        As implemented in bwBASIC, this is a
  2567. X            pseudo-function, since bwBASIC does
  2568. X            not recognize precision levels.
  2569. X
  2570. X    SYNTAX:        CVI( string$ )
  2571. X
  2572. X***************************************************************/
  2573. X
  2574. X#if ANSI_C
  2575. Xstruct bwb_variable *
  2576. Xfnc_cvi( int argc, struct bwb_variable *argv, int unique_id  )
  2577. X#else
  2578. Xstruct bwb_variable *
  2579. Xfnc_cvi( argc, argv, unique_id  )
  2580. X   int argc;
  2581. X   struct bwb_variable *argv;
  2582. X   int unique_id;
  2583. X#endif
  2584. X   {
  2585. X   register int i;
  2586. X   struct bwb_variable *v;
  2587. X   bstring *b;
  2588. X   static struct bwb_variable nvar;
  2589. X   static int init = FALSE;
  2590. X
  2591. X   /* initialize the variable if necessary */
  2592. X
  2593. X   if ( init == FALSE )
  2594. X      {
  2595. X      init = TRUE;
  2596. X      var_make( &nvar, NUMBER );
  2597. X      }
  2598. X
  2599. X#if PROG_ERRORS
  2600. X   if ( argc < 1 )
  2601. X      {
  2602. X      sprintf( bwb_ebuf, "Not enough parameters (%d) to function CVI().",
  2603. X         argc );
  2604. X      bwb_error( bwb_ebuf );
  2605. X      return NULL;
  2606. X      }
  2607. X   else if ( argc > 1 )
  2608. X      {
  2609. X      sprintf( bwb_ebuf, "Too many parameters (%d) to function CVI().",
  2610. X         argc );
  2611. X      bwb_error( bwb_ebuf );
  2612. X      return NULL;
  2613. X      }
  2614. X#else
  2615. X   if ( fnc_checkargs( argc, argv, 1, 1 ) == FALSE )
  2616. X      {
  2617. X      return NULL;
  2618. X      }
  2619. X#endif
  2620. X
  2621. X   /* assign values */
  2622. X
  2623. X   v = &( argv[ 0 ] );
  2624. X   b = var_findsval( v, v->array_pos );
  2625. X
  2626. X   for ( i = 0; i < sizeof( int ); ++i )
  2627. X      {
  2628. X      an_integer.the_chars[ i ] = b->sbuffer[ i ];
  2629. X      }
  2630. X
  2631. X   * var_findnval( &nvar, nvar.array_pos ) = (bnumber) an_integer.the_integer;
  2632. X
  2633. X   return &nvar;
  2634. X   }
  2635. X
  2636. X/***************************************************************
  2637. X
  2638. X        FUNCTION:       fnc_cvd()
  2639. X
  2640. X        DESCRIPTION:    This C function implements the BASIC
  2641. X                        predefined CVD() function.
  2642. X
  2643. X    NOTE:        As implemented in bwBASIC, this is a
  2644. X            pseudo-function, since bwBASIC does
  2645. X            not recognize precision levels.
  2646. X
  2647. X    SYNTAX:        CVD( string$ )
  2648. X
  2649. X***************************************************************/
  2650. X
  2651. X#if ANSI_C
  2652. Xstruct bwb_variable *
  2653. Xfnc_cvd( int argc, struct bwb_variable *argv, int unique_id  )
  2654. X#else
  2655. Xstruct bwb_variable *
  2656. Xfnc_cvd( argc, argv, unique_id  )
  2657. X   int argc;
  2658. X   struct bwb_variable *argv;
  2659. X   int unique_id;
  2660. X#endif
  2661. X   {
  2662. X   register int i;
  2663. X   struct bwb_variable *v;
  2664. X   bstring *b;
  2665. X   static struct bwb_variable nvar;
  2666. X   static int init = FALSE;
  2667. X
  2668. X   /* initialize the variable if necessary */
  2669. X
  2670. X   if ( init == FALSE )
  2671. X      {
  2672. X      init = TRUE;
  2673. X      var_make( &nvar, NUMBER );
  2674. X      }
  2675. X
  2676. X#if PROG_ERRORS
  2677. X   if ( argc < 1 )
  2678. X      {
  2679. X      sprintf( bwb_ebuf, "Not enough parameters (%d) to function CVD().",
  2680. X         argc );
  2681. X      bwb_error( bwb_ebuf );
  2682. X      return NULL;
  2683. X      }
  2684. X   else if ( argc > 1 )
  2685. X      {
  2686. X      sprintf( bwb_ebuf, "Too many parameters (%d) to function CVD().",
  2687. X         argc );
  2688. X      bwb_error( bwb_ebuf );
  2689. X      return NULL;
  2690. X      }
  2691. X#else
  2692. X   if ( fnc_checkargs( argc, argv, 1, 1 ) == FALSE )
  2693. X      {
  2694. X      return NULL;
  2695. X      }
  2696. X#endif
  2697. X
  2698. X   /* assign values */
  2699. X
  2700. X   v = &( argv[ 0 ] );
  2701. X   b = var_findsval( v, v->array_pos );
  2702. X
  2703. X   for ( i = 0; i < sizeof( double ); ++i )
  2704. X      {
  2705. X      a_double.the_chars[ i ] = b->sbuffer[ i ];
  2706. X      }
  2707. X
  2708. X   * var_findnval( &nvar, nvar.array_pos ) = (bnumber) a_double.the_double;
  2709. X
  2710. X   return &nvar;
  2711. X
  2712. X   }
  2713. X
  2714. X/***************************************************************
  2715. X
  2716. X        FUNCTION:       fnc_cvs()
  2717. X
  2718. X        DESCRIPTION:    This C function implements the BASIC
  2719. X                        predefined CVS() function.
  2720. X
  2721. X    NOTE:        As implemented in bwBASIC, this is a
  2722. X            pseudo-function, since bwBASIC does
  2723. X            not recognize precision levels.
  2724. X
  2725. X    SYNTAX:        CVS( string$ )
  2726. X
  2727. X***************************************************************/
  2728. X
  2729. X#if ANSI_C
  2730. Xstruct bwb_variable *
  2731. Xfnc_cvs( int argc, struct bwb_variable *argv, int unique_id  )
  2732. X#else
  2733. Xstruct bwb_variable *
  2734. Xfnc_cvs( argc, argv, unique_id  )
  2735. X   int argc;
  2736. X   struct bwb_variable *argv;
  2737. X   int unique_id;
  2738. X#endif
  2739. X   {
  2740. X   register int i;
  2741. X   struct bwb_variable *v;
  2742. X   bstring *b;
  2743. X   static struct bwb_variable nvar;
  2744. X   static int init = FALSE;
  2745. X
  2746. X   /* initialize the variable if necessary */
  2747. X
  2748. X   if ( init == FALSE )
  2749. X      {
  2750. X      init = TRUE;
  2751. X      var_make( &nvar, NUMBER );
  2752. X      }
  2753. X
  2754. X#if PROG_ERRORS
  2755. X   if ( argc < 1 )
  2756. X      {
  2757. X      sprintf( bwb_ebuf, "Not enough parameters (%d) to function CVS().",
  2758. X         argc );
  2759. X      bwb_error( bwb_ebuf );
  2760. X      return NULL;
  2761. X      }
  2762. X   else if ( argc > 1 )
  2763. X      {
  2764. X      sprintf( bwb_ebuf, "Too many parameters (%d) to function CVS().",
  2765. X         argc );
  2766. X      bwb_error( bwb_ebuf );
  2767. X      return NULL;
  2768. X      }
  2769. X#else
  2770. X   if ( fnc_checkargs( argc, argv, 1, 1 ) == FALSE )
  2771. X      {
  2772. X      return NULL;
  2773. X      }
  2774. X#endif
  2775. X
  2776. X   /* assign values */
  2777. X
  2778. X   v = &( argv[ 0 ] );
  2779. X   b = var_findsval( v, v->array_pos );
  2780. X
  2781. X   for ( i = 0; i < sizeof( float ); ++i )
  2782. X      {
  2783. X      a_float.the_chars[ i ] = b->sbuffer[ i ];
  2784. X      }
  2785. X
  2786. X#if INTENSIVE_DEBUG
  2787. X   sprintf( bwb_ebuf, "in fnc_cvs(): string <%s> hex vals <%X><%X><%X><%X>",
  2788. X      a_float.the_chars, a_float.the_chars[ 0 ], a_float.the_chars[ 1 ], 
  2789. X      a_float.the_chars[ 2 ], a_float.the_chars[ 3 ] );
  2790. X   bwb_debug( bwb_ebuf );
  2791. X#endif
  2792. X
  2793. X   * var_findnval( &nvar, nvar.array_pos ) = a_float.the_float;
  2794. X
  2795. X   return &nvar;
  2796. X
  2797. X   }
  2798. X
  2799. X/***************************************************************
  2800. X
  2801. X        FUNCTION:       fnc_csng()
  2802. X
  2803. X    DESCRIPTION:    This C function implements the BASIC
  2804. X            function CSNG().  As implemented,
  2805. X            this is a pseudo-function, since
  2806. X            all bwBASIC numerial values have the
  2807. X            same precision.
  2808. X
  2809. X    SYNTAX:        CSNG( number )
  2810. X
  2811. X***************************************************************/
  2812. X
  2813. X#if ANSI_C
  2814. Xstruct bwb_variable *
  2815. Xfnc_csng( int argc, struct bwb_variable *argv, int unique_id )
  2816. X#else
  2817. Xstruct bwb_variable *
  2818. Xfnc_csng( argc, argv, unique_id )
  2819. X   int argc;
  2820. X   struct bwb_variable *argv;
  2821. X   int unique_id;
  2822. X#endif
  2823. X   {
  2824. X   static struct bwb_variable nvar;
  2825. X   static int init = FALSE;
  2826. X
  2827. X   /* initialize the variable if necessary */
  2828. X
  2829. X   if ( init == FALSE )
  2830. X      {
  2831. X      init = TRUE;
  2832. X      var_make( &nvar, NUMBER );
  2833. X      }
  2834. X
  2835. X   /* check parameters */
  2836. X
  2837. X#if PROG_ERRORS
  2838. X   if ( argc < 1 )
  2839. X      {
  2840. X      sprintf( bwb_ebuf, "Not enough parameters (%d) to function CINT().",
  2841. X         argc );
  2842. X      bwb_error( bwb_ebuf );
  2843. X      return NULL;
  2844. X      }
  2845. X   else if ( argc > 1 )
  2846. X      {
  2847. X      sprintf( bwb_ebuf, "Too many parameters (%d) to function CINT().",
  2848. X         argc );
  2849. X      bwb_error( bwb_ebuf );
  2850. X      return NULL;
  2851. X      }
  2852. X#else
  2853. X   if ( fnc_checkargs( argc, argv, 1, 1 ) == FALSE )
  2854. X      {
  2855. X      return NULL;
  2856. X      }
  2857. X#endif
  2858. X
  2859. X   /* get truncated integer value */
  2860. X
  2861. X   * var_findnval( &nvar, nvar.array_pos )
  2862. X      = (bnumber) var_getnval( &( argv[ 0 ] ) );
  2863. X
  2864. X   return &nvar;
  2865. X   }
  2866. X
  2867. X/***************************************************************
  2868. X
  2869. X        FUNCTION:       fnc_cint()
  2870. X
  2871. X    DESCRIPTION:    This C function returns the truncated
  2872. X            rounded integer value of its numerical
  2873. X            argument.
  2874. X
  2875. X    SYNTAX:        CINT( number )
  2876. X
  2877. X***************************************************************/
  2878. X
  2879. X#if ANSI_C
  2880. Xstruct bwb_variable *
  2881. Xfnc_cint( int argc, struct bwb_variable *argv, int unique_id )
  2882. X#else
  2883. Xstruct bwb_variable *
  2884. Xfnc_cint( argc, argv, unique_id )
  2885. X   int argc;
  2886. X   struct bwb_variable *argv;
  2887. X   int unique_id;
  2888. X#endif
  2889. X   {
  2890. X   static struct bwb_variable nvar;
  2891. X   static int init = FALSE;
  2892. X
  2893. X   /* initialize the variable if necessary */
  2894. X
  2895. X   if ( init == FALSE )
  2896. X      {
  2897. X      init = TRUE;
  2898. X      var_make( &nvar, NUMBER );
  2899. X      }
  2900. X
  2901. X   /* check parameters */
  2902. X
  2903. X#if PROG_ERRORS
  2904. X   if ( argc < 1 )
  2905. X      {
  2906. X      sprintf( bwb_ebuf, "Not enough parameters (%d) to function CINT().",
  2907. X         argc );
  2908. X      bwb_error( bwb_ebuf );
  2909. X      return NULL;
  2910. X      }
  2911. X   else if ( argc > 1 )
  2912. X      {
  2913. X      sprintf( bwb_ebuf, "Too many parameters (%d) to function CINT().",
  2914. X         argc );
  2915. X      bwb_error( bwb_ebuf );
  2916. X      return NULL;
  2917. X      }
  2918. X#else
  2919. X   if ( fnc_checkargs( argc, argv, 1, 1 ) == FALSE )
  2920. X      {
  2921. X      return NULL;
  2922. X      }
  2923. X#endif
  2924. X
  2925. X   /* get rounded integer value */
  2926. X
  2927. X   * var_findnval( &nvar, nvar.array_pos )
  2928. X      = round_int( var_getnval( &( argv[ 0 ] ) ));
  2929. X
  2930. X   return &nvar;
  2931. X   }
  2932. X
  2933. X#endif                /* MS_FUNCS */
  2934. X
  2935. X/***************************************************************
  2936. X
  2937. X    FUNCTION:       trnc_int()
  2938. X
  2939. X    DESCRIPTION:    This function returns the truncated
  2940. X            truncated integer value of its numerical
  2941. X            argument.
  2942. X
  2943. X***************************************************************/
  2944. X
  2945. X#if ANSI_C
  2946. Xbnumber
  2947. Xtrnc_int( bnumber x )
  2948. X#else
  2949. Xbnumber
  2950. Xtrnc_int( x )
  2951. X   bnumber x;
  2952. X#endif
  2953. X   {
  2954. X   bnumber sign;
  2955. X
  2956. X   if ( x < (bnumber) 0.0 )
  2957. X      {
  2958. X      sign = (bnumber) -1.0;
  2959. X      }
  2960. X   else
  2961. X      {
  2962. X      sign = (bnumber) 1.0;
  2963. X      }
  2964. X
  2965. X   return (bnumber) ( floor( fabs( x )) * sign );
  2966. X   }
  2967. X
  2968. X/***************************************************************
  2969. X
  2970. X    FUNCTION:       round_int()
  2971. X
  2972. X    DESCRIPTION:    This function returns the truncated
  2973. X            rounded integer value of its numerical
  2974. X            argument.
  2975. X
  2976. X***************************************************************/
  2977. X
  2978. X#if ANSI_C
  2979. Xbnumber
  2980. Xround_int( bnumber x )
  2981. X#else
  2982. Xbnumber
  2983. Xround_int( x )
  2984. X   bnumber x;
  2985. X#endif
  2986. X   {
  2987. X
  2988. X   if ( x < (bnumber) 0.00 )
  2989. X      {
  2990. X      if ( (bnumber) fabs( (bnumber) floor( x ) - x ) < (bnumber) 0.500 )
  2991. X     {
  2992. X     return (bnumber) floor( x );
  2993. X     }
  2994. X      else
  2995. X     {
  2996. X     return (bnumber) ceil( x );
  2997. X     }
  2998. X      }
  2999. X   else
  3000. X      {
  3001. X      if ( ( x - (bnumber) floor( x )) < (bnumber) 0.500 )
  3002. X     {
  3003. X     return (bnumber) floor( x );
  3004. X     }
  3005. X      else
  3006. X     {
  3007. X     return (bnumber) ceil( x );
  3008. X     }
  3009. X      }
  3010. X   }
  3011. X
  3012. X
  3013. END_OF_FILE
  3014.   if test 45044 -ne `wc -c <'bwbasic-2.10/bwb_mth.c'`; then
  3015.     echo shar: \"'bwbasic-2.10/bwb_mth.c'\" unpacked with wrong size!
  3016.   fi
  3017.   # end of 'bwbasic-2.10/bwb_mth.c'
  3018. fi
  3019. if test -f 'bwbasic-2.10/bwbtest/mlifthen.bas' -a "${1}" != "-c" ; then 
  3020.   echo shar: Will not clobber existing file \"'bwbasic-2.10/bwbtest/mlifthen.bas'\"
  3021. else
  3022.   echo shar: Extracting \"'bwbasic-2.10/bwbtest/mlifthen.bas'\" \(426 characters\)
  3023.   sed "s/^X//" >'bwbasic-2.10/bwbtest/mlifthen.bas' <<'END_OF_FILE'
  3024. X
  3025. Xrem -------------------------------------------------
  3026. Xrem mlifthen.bas -- Test MultiLine IF-THEN statement
  3027. Xrem -------------------------------------------------
  3028. X
  3029. XPrint "MLIFTHEN.BAS -- Test MultiLine IF-THEN-ELSE Constructions"
  3030. X
  3031. XIf 3 = 4 then
  3032. X   Print "The Condition is true."
  3033. X   Print "And it still is true."
  3034. XElse
  3035. X   Print "The condition is false."
  3036. X   Print "And it still is false."
  3037. XEnd If
  3038. X
  3039. XPrint "This concludes our test."
  3040. END_OF_FILE
  3041.   if test 426 -ne `wc -c <'bwbasic-2.10/bwbtest/mlifthen.bas'`; then
  3042.     echo shar: \"'bwbasic-2.10/bwbtest/mlifthen.bas'\" unpacked with wrong size!
  3043.   fi
  3044.   # end of 'bwbasic-2.10/bwbtest/mlifthen.bas'
  3045. fi
  3046. echo shar: End of archive 8 \(of 15\).
  3047. cp /dev/null ark8isdone
  3048. MISSING=""
  3049. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ; do
  3050.     if test ! -f ark${I}isdone ; then
  3051.     MISSING="${MISSING} ${I}"
  3052.     fi
  3053. done
  3054. if test "${MISSING}" = "" ; then
  3055.     echo You have unpacked all 15 archives.
  3056.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  3057. else
  3058.     echo You still must unpack the following archives:
  3059.     echo "        " ${MISSING}
  3060. fi
  3061. exit 0
  3062. exit 0 # Just in case...
  3063.