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

  1. Newsgroups: comp.sources.misc
  2. From: tcamp@delphi.com (Ted A. Campbell)
  3. Subject: v40i064:  bwbasic - Bywater BASIC interpreter version 2.10, Part13/15
  4. Message-ID: <1993Oct29.162811.4248@sparky.sterling.com>
  5. X-Md4-Signature: fa6c56a5979c58f022071e0260b8ca1c
  6. Sender: kent@sparky.sterling.com (Kent Landfield)
  7. Organization: Sterling Software
  8. Date: Fri, 29 Oct 1993 16:28:11 GMT
  9. Approved: kent@sparky.sterling.com
  10.  
  11. Submitted-by: tcamp@delphi.com (Ted A. Campbell)
  12. Posting-number: Volume 40, Issue 64
  13. Archive-name: bwbasic/part13
  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_elx.c
  22. # Wrapped by kent@sparky on Thu Oct 21 10:47:52 1993
  23. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  24. echo If this archive is complete, you will see the following message:
  25. echo '          "shar: End of archive 13 (of 15)."'
  26. if test -f 'bwbasic-2.10/bwb_elx.c' -a "${1}" != "-c" ; then 
  27.   echo shar: Will not clobber existing file \"'bwbasic-2.10/bwb_elx.c'\"
  28. else
  29.   echo shar: Extracting \"'bwbasic-2.10/bwb_elx.c'\" \(35745 characters\)
  30.   sed "s/^X//" >'bwbasic-2.10/bwb_elx.c' <<'END_OF_FILE'
  31. X/****************************************************************
  32. X
  33. X        bwb_elx.c       Parse Elements of Expressions
  34. X                        for Bywater BASIC Interpreter
  35. X
  36. X                        Copyright (c) 1993, Ted A. Campbell
  37. X                        Bywater Software
  38. X
  39. X                        email: tcamp@delphi.com
  40. X
  41. X        Copyright and Permissions Information:
  42. X
  43. X        All U.S. and international rights are claimed by the author,
  44. X        Ted A. Campbell.
  45. X
  46. X    This software is released under the terms of the GNU General
  47. X    Public License (GPL), which is distributed with this software
  48. X    in the file "COPYING".  The GPL specifies the terms under
  49. X    which users may copy and use the software in this distribution.
  50. X
  51. X    A separate license is available for commercial distribution,
  52. X    for information on which you should contact the author.
  53. X
  54. X****************************************************************/
  55. X
  56. X#include <stdio.h>
  57. X#include <ctype.h>
  58. X#include <math.h>
  59. X
  60. X#include "bwbasic.h"
  61. X#include "bwb_mes.h"
  62. X
  63. X/***************************************************************
  64. X
  65. X    FUNCTION:       exp_paren()
  66. X
  67. X    DESCRIPTION:    This function interprets a parenthetical
  68. X            expression, calling bwb_exp() (recursively)
  69. X            to resolve the internal expression.
  70. X
  71. X***************************************************************/
  72. X
  73. X#if ANSI_C
  74. Xint
  75. Xexp_paren( char *expression )
  76. X#else
  77. Xint
  78. Xexp_paren( expression )
  79. X   char *expression;
  80. X#endif
  81. X   {
  82. X   struct exp_ese *e;
  83. X   int s_pos;                           /* position in build buffer */
  84. X   int loop;
  85. X   int paren_level;
  86. X
  87. X   /* find a string enclosed by parentheses */
  88. X
  89. X   CURTASK exps[ CURTASK expsc ].pos_adv = 1;       /* start beyond open paren */
  90. X   s_pos = 0;
  91. X   loop = TRUE;
  92. X   paren_level = 1;
  93. X   CURTASK exps[ CURTASK expsc ].string[ 0 ] = '\0';
  94. X
  95. X   while( loop == TRUE )
  96. X      {
  97. X
  98. X      /* check the current character */
  99. X
  100. X      switch( expression[ CURTASK exps[ CURTASK expsc ].pos_adv ] )
  101. X         {
  102. X
  103. X         case '\r':                /* these tests added v1.11 */
  104. X         case '\n':
  105. X         case '\0':
  106. X            bwb_error( err_incomplete );
  107. X            loop = FALSE;
  108. X            break;
  109. X
  110. X         case '(':
  111. X            ++paren_level;
  112. X            CURTASK exps[ CURTASK expsc ].string[ s_pos ]
  113. X               = expression[ CURTASK exps[ CURTASK expsc ].pos_adv ];
  114. X            ++s_pos;
  115. X            CURTASK exps[ CURTASK expsc ].string[ s_pos ] = '\0';
  116. X            break;
  117. X
  118. X         case ')':
  119. X
  120. X            --paren_level;
  121. X            if ( paren_level == 0 )
  122. X               {
  123. X               loop = FALSE;
  124. X               }
  125. X            else
  126. X               {
  127. X               CURTASK exps[ CURTASK expsc ].string[ s_pos ]
  128. X                  = expression[ CURTASK exps[ CURTASK expsc ].pos_adv ];
  129. X               ++s_pos;
  130. X               CURTASK exps[ CURTASK expsc ].string[ s_pos ] = '\0';
  131. X               }
  132. X            break;
  133. X
  134. X         case '\"':                             /* embedded string constant */
  135. X            ++CURTASK exps[ CURTASK expsc ].pos_adv;
  136. X            while ( ( expression[ CURTASK exps[ CURTASK expsc ].pos_adv ] != '\"' )
  137. X               && ( expression[ CURTASK exps[ CURTASK expsc ].pos_adv ] != '\0' ) )
  138. X               {
  139. X               CURTASK exps[ CURTASK expsc ].string[ s_pos ]
  140. X                  = expression[ CURTASK exps[ CURTASK expsc ].pos_adv ];
  141. X               ++s_pos;
  142. X               CURTASK exps[ CURTASK expsc ].string[ s_pos ] = '\0';
  143. X               ++CURTASK exps[ CURTASK expsc ].pos_adv;
  144. X               }
  145. X            break;
  146. X
  147. X         default:
  148. X            CURTASK exps[ CURTASK expsc ].string[ s_pos ]
  149. X               = expression[ CURTASK exps[ CURTASK expsc ].pos_adv ];
  150. X            ++s_pos;
  151. X            CURTASK exps[ CURTASK expsc ].string[ s_pos ] = '\0';
  152. X            break;
  153. X         }
  154. X
  155. X      /* advance the counter */
  156. X
  157. X      ++CURTASK exps[ CURTASK expsc ].pos_adv;
  158. X
  159. X      }
  160. X
  161. X#if INTENSIVE_DEBUG
  162. X   sprintf( bwb_ebuf, "in exp_paren() found internal string <%s>",
  163. X      CURTASK exps[ CURTASK expsc ].string );
  164. X   bwb_debug( bwb_ebuf );
  165. X#endif
  166. X
  167. X   /* call bwb_exp() recursively to interpret this expression */
  168. X
  169. X   CURTASK exps[ CURTASK expsc ].rec_pos = 0;
  170. X   e = bwb_exp( CURTASK exps[ CURTASK expsc ].string, FALSE,
  171. X          &( CURTASK exps[ CURTASK expsc ].rec_pos ) );
  172. X
  173. X   /* assign operation and value at this level */
  174. X
  175. X   CURTASK exps[ CURTASK expsc ].type = e->type;
  176. X
  177. X   switch ( e->type )
  178. X      {
  179. X      case STRING:
  180. X         CURTASK exps[ CURTASK expsc ].operation = CONST_STRING;
  181. X         str_btob( exp_getsval( &( CURTASK exps[ CURTASK expsc ] )), exp_getsval( e ) );
  182. X         break;
  183. X      default:
  184. X         CURTASK exps[ CURTASK expsc ].operation = NUMBER;
  185. X         CURTASK exps[ CURTASK expsc ].nval = exp_getnval( e );
  186. X         break;
  187. X      }
  188. X
  189. X   return TRUE;
  190. X
  191. X   }
  192. X
  193. X/***************************************************************
  194. X
  195. X        FUNCTION:       exp_strconst()
  196. X
  197. X        DESCRIPTION:    This function interprets a string
  198. X            constant.
  199. X
  200. X***************************************************************/
  201. X
  202. X#if ANSI_C
  203. Xint
  204. Xexp_strconst( char *expression )
  205. X#else
  206. Xint
  207. Xexp_strconst( expression )
  208. X   char *expression;
  209. X#endif
  210. X   {
  211. X   int e_pos, s_pos;
  212. X
  213. X   /* assign values to structure */
  214. X
  215. X   CURTASK exps[ CURTASK expsc ].type = STRING;
  216. X   CURTASK exps[ CURTASK expsc ].operation = CONST_STRING;
  217. X
  218. X   /* set counters */
  219. X
  220. X   s_pos = 0;
  221. X   CURTASK exps[ CURTASK expsc ].pos_adv = e_pos = 1;
  222. X   CURTASK exps[ CURTASK expsc ].string[ 0 ] = '\0';
  223. X
  224. X   /* read the string up until the next double quotation mark */
  225. X
  226. X   while( expression[ e_pos ] != '\"' )
  227. X      {
  228. X      CURTASK exps[ CURTASK expsc ].string[ s_pos ] = expression[ e_pos ];
  229. X      ++e_pos;
  230. X      ++s_pos;
  231. X      ++CURTASK exps[ CURTASK expsc ].pos_adv;
  232. X      CURTASK exps[ CURTASK expsc ].string[ s_pos ] = '\0';
  233. X      if ( s_pos >= ( MAXSTRINGSIZE - 1 ) )
  234. X         {
  235. X#if PROG_ERRORS
  236. X         sprintf( bwb_ebuf, "string <%s> exceeds maximum size (%d) for string constant.",
  237. X            expression, MAXSTRINGSIZE );
  238. X         bwb_error( bwb_ebuf );
  239. X#else
  240. X         bwb_error( err_overflow );
  241. X#endif
  242. X         return OP_NULL;
  243. X         }
  244. X      }
  245. X
  246. X   /* now write string over to bstring */
  247. X
  248. X   str_ctob( &( CURTASK exps[ CURTASK expsc ].sval ), CURTASK exps[ CURTASK expsc ].string );
  249. X
  250. X   /* advance past last double quotation mark */
  251. X
  252. X   ++CURTASK exps[ CURTASK expsc ].pos_adv;
  253. X
  254. X   /* return */
  255. X
  256. X   return TRUE;
  257. X
  258. X   }
  259. X
  260. X/***************************************************************
  261. X
  262. X        FUNCTION:    exp_numconst()
  263. X
  264. X        DESCRIPTION:    This function interprets a numerical
  265. X            constant.
  266. X
  267. X***************************************************************/
  268. X
  269. X#if ANSI_C
  270. Xint
  271. Xexp_numconst( char *expression )
  272. X#else
  273. Xint
  274. Xexp_numconst( expression )
  275. X   char *expression;
  276. X#endif
  277. X   {
  278. X   int base;                            /* numerical base for the constant */
  279. X   static struct bwb_variable mantissa; /* mantissa of floating-point number */
  280. X   static int init = FALSE;        /* is mantissa variable initialized? */
  281. X   int exponent;                        /* exponent for floating point number */
  282. X   int man_start;                       /* starting point of mantissa */
  283. X   int s_pos;                           /* position in build string */
  284. X   int build_loop;
  285. X   int need_pm;
  286. X   int i;
  287. X   bnumber d;
  288. X#if CHECK_RECURSION
  289. X   static int in_use = FALSE;                   /* boolean: is function in use? */
  290. X
  291. X   /* check recursion status */
  292. X
  293. X   if ( in_use == TRUE )
  294. X      {
  295. X      sprintf( bwb_ebuf, "Recursion error in bwb_exp.c:exp_findop(): recursion violation." );
  296. X      bwb_error( bwb_ebuf );
  297. X      }
  298. X
  299. X   /* reset recursion status indicator */
  300. X
  301. X   else
  302. X      {
  303. X      in_use = TRUE;
  304. X      }
  305. X#endif
  306. X
  307. X   /* initialize the variable if necessary */
  308. X
  309. X#if INTENSIVE_DEBUG
  310. X   strcpy( mantissa.name, "(mantissa)" );
  311. X#endif
  312. X
  313. X   if ( init == FALSE )
  314. X      {
  315. X      init = TRUE;
  316. X      var_make( &mantissa, NUMBER );
  317. X      }
  318. X
  319. X   /* be sure that the array_pos[ 0 ] for mantissa is set to dim_base;
  320. X      this is necessary because mantissa might be used before dim_base
  321. X      is set */
  322. X
  323. X   mantissa.array_pos[ 0 ] = dim_base;
  324. X
  325. X#if INTENSIVE_DEBUG
  326. X   sprintf( bwb_ebuf, "in exp_numconst(): received <%s>, eval <%c>",
  327. X      expression, expression[ 0 ] );
  328. X   bwb_debug( bwb_ebuf );
  329. X#endif
  330. X
  331. X   need_pm = FALSE;
  332. X   CURTASK exps[ CURTASK expsc ].nval = (bnumber) 0;
  333. X
  334. X   /* check the first character(s) to determine numerical base
  335. X      and starting point of the mantissa */
  336. X
  337. X   switch( expression[ 0 ] )
  338. X      {
  339. X      case '-':
  340. X      case '+':
  341. X      case '0':
  342. X      case '1':
  343. X      case '2':
  344. X      case '3':
  345. X      case '4':
  346. X      case '5':
  347. X      case '6':
  348. X      case '7':
  349. X      case '8':
  350. X      case '9':
  351. X      case '.':
  352. X         base = 10;                     /* decimal constant */
  353. X     man_start = 0;                 /* starts at position 0 */
  354. X     need_pm = FALSE;
  355. X         break;
  356. X      case '&':                         /* hex or octal constant */
  357. X         if ( ( expression[ 1 ] == 'H' ) || ( expression[ 1 ] == 'h' ))
  358. X            {
  359. X            base = 16;                  /* hexadecimal constant */
  360. X            man_start = 2;              /* starts at position 2 */
  361. X            }
  362. X         else
  363. X            {
  364. X            base = 8;                   /* octal constant */
  365. X            if ( ( expression[ 1 ] == 'O' ) || ( expression[ 1 ] == 'o' ))
  366. X               {
  367. X               man_start = 2;           /* starts at position 2 */
  368. X               }
  369. X            else
  370. X               {
  371. X               man_start = 1;           /* starts at position 1 */
  372. X               }
  373. X            }
  374. X         break;
  375. X      default:
  376. X
  377. X#if PROG_ERRORS
  378. X         sprintf( bwb_ebuf, "expression <%s> is not a numerical constant.",
  379. X            expression );
  380. X         bwb_error( bwb_ebuf );
  381. X#else
  382. X         bwb_error( err_syntax );
  383. X#endif
  384. X         return OP_NULL;
  385. X      }
  386. X
  387. X   /* now build the mantissa according to the numerical base */
  388. X
  389. X   switch( base )
  390. X      {
  391. X
  392. X      case 10:                          /* decimal constant */
  393. X
  394. X         /* initialize counters */
  395. X
  396. X         CURTASK exps[ CURTASK expsc ].pos_adv = man_start;
  397. X         CURTASK exps[ CURTASK expsc ].type = NUMBER;
  398. X         CURTASK exps[ CURTASK expsc ].string[ 0 ] = '\0';
  399. X         s_pos = 0;
  400. X         exponent = OP_NULL;
  401. X         build_loop = TRUE;
  402. X
  403. X         /* loop to build the string */
  404. X
  405. X         while ( build_loop == TRUE )
  406. X            {
  407. X            switch( expression[ CURTASK exps[ CURTASK expsc ].pos_adv ] )
  408. X               {
  409. X               case '-':                        /* prefixed plus or minus */
  410. X               case '+':
  411. X
  412. X                  /* in the first position, a plus or minus sign can
  413. X                     be added to the beginning of the string to be
  414. X                     scanned */
  415. X
  416. X                  if ( CURTASK exps[ CURTASK expsc ].pos_adv == man_start )
  417. X                     {
  418. X                     CURTASK exps[ CURTASK expsc ].string[ s_pos ] = expression[ CURTASK exps[ CURTASK expsc ].pos_adv ];
  419. X                     ++CURTASK exps[ CURTASK expsc ].pos_adv;  /* advance to next character */
  420. X                     ++s_pos;
  421. X                     CURTASK exps[ CURTASK expsc ].string[ s_pos ] = '\0';
  422. X                     }
  423. X
  424. X                  /* but in any other position, the plus or minus sign
  425. X                     must be taken as an operator and thus as terminating
  426. X                     the string to be scanned */
  427. X
  428. X                  else
  429. X                     {
  430. X                     build_loop = FALSE;
  431. X                     }
  432. X                  break;
  433. X               case '.':                        /* note at least single precision */
  434. X               case '0':                        /* or ordinary digit */
  435. X               case '1':
  436. X               case '2':
  437. X               case '3':
  438. X               case '4':
  439. X               case '5':
  440. X               case '6':
  441. X               case '7':
  442. X               case '8':
  443. X               case '9':
  444. X                  CURTASK exps[ CURTASK expsc ].string[ s_pos ] = expression[ CURTASK exps[ CURTASK expsc ].pos_adv ];
  445. X                  ++CURTASK exps[ CURTASK expsc ].pos_adv;  /* advance to next character */
  446. X                  ++s_pos;
  447. X                  CURTASK exps[ CURTASK expsc ].string[ s_pos ] = '\0';
  448. X                  break;
  449. X
  450. X           case '#':                        /* Microsoft-type precision indicator; ignored but terminates */
  451. X           case '!':                        /* Microsoft-type precision indicator; ignored but terminates */
  452. X          ++CURTASK exps[ CURTASK expsc ].pos_adv;  /* advance to next character */
  453. X          CURTASK exps[ CURTASK expsc ].type = NUMBER;
  454. X          exponent = FALSE;
  455. X          build_loop = FALSE;
  456. X          break;
  457. X
  458. X           case 'E':                        /* exponential, single precision */
  459. X               case 'e':
  460. X                  ++CURTASK exps[ CURTASK expsc ].pos_adv;  /* advance to next character */
  461. X                  CURTASK exps[ CURTASK expsc ].type = NUMBER;
  462. X          exponent = TRUE;
  463. X                  build_loop = FALSE;
  464. X          break;
  465. X
  466. X               case 'D':                        /* exponential, double precision */
  467. X               case 'd':
  468. X                  ++CURTASK exps[ CURTASK expsc ].pos_adv;  /* advance to next character */
  469. X                  CURTASK exps[ CURTASK expsc ].type = NUMBER;
  470. X          exponent = TRUE;
  471. X                  build_loop = FALSE;
  472. X                  break;
  473. X
  474. X               default:                         /* anything else, terminate */
  475. X                  build_loop = FALSE;
  476. X                  break;
  477. X               }
  478. X
  479. X            }
  480. X
  481. X         /* assign the value to the mantissa variable */
  482. X         
  483. X#if NUMBER_DOUBLE
  484. X         sscanf( CURTASK exps[ CURTASK expsc ].string, "%lf", 
  485. X           var_findnval( &mantissa, mantissa.array_pos ));
  486. X#else
  487. X         sscanf( CURTASK exps[ CURTASK expsc ].string, "%f", 
  488. X           var_findnval( &mantissa, mantissa.array_pos ));
  489. X#endif
  490. X
  491. X#if INTENSIVE_DEBUG
  492. X         sprintf( bwb_ebuf, "in exp_numconst(): read mantissa, string <%s> val <%lf>",
  493. X            CURTASK exps[ CURTASK expsc ].string, var_getnval( &mantissa ) );
  494. X         bwb_debug( bwb_ebuf );
  495. X#endif
  496. X
  497. X         /* test if integer bounds have been exceeded */
  498. X
  499. X         if ( CURTASK exps[ CURTASK expsc ].type == NUMBER )
  500. X            {
  501. X            i = (int) var_getnval( &mantissa );
  502. X            d = (bnumber) i;
  503. X            if ( d != var_getnval( &mantissa ))
  504. X               {
  505. X               CURTASK exps[ CURTASK expsc ].type = NUMBER;
  506. X#if INTENSIVE_DEBUG
  507. X               sprintf( bwb_ebuf, "in exp_numconst(): integer bounds violated, promote to NUMBER" );
  508. X               bwb_debug( bwb_ebuf );
  509. X#endif               
  510. X               }
  511. X            }
  512. X
  513. X         /* read the exponent if there is one */
  514. X
  515. X         if ( exponent == TRUE )
  516. X            {
  517. X
  518. X        /* allow a plus or minus once at the beginning */
  519. X
  520. X        need_pm = TRUE;
  521. X
  522. X        /* initialize counters */
  523. X
  524. X            CURTASK exps[ CURTASK expsc ].string[ 0 ] = '\0';
  525. X            s_pos = 0;
  526. X            build_loop = TRUE;
  527. X
  528. X            /* loop to build the string */
  529. X
  530. X            while ( build_loop == TRUE )
  531. X               {
  532. X               switch( expression[ CURTASK exps[ CURTASK expsc ].pos_adv ] )
  533. X                  {
  534. X          case '-':                        /* prefixed plus or minus */
  535. X                  case '+':
  536. X
  537. X             if ( need_pm == TRUE )        /* only allow once */
  538. X            {
  539. X            CURTASK exps[ CURTASK expsc ].string[ s_pos ] = expression[ CURTASK exps[ CURTASK expsc ].pos_adv ];
  540. X            ++CURTASK exps[ CURTASK expsc ].pos_adv;  /* advance to next character */
  541. X            ++s_pos;
  542. X            CURTASK exps[ CURTASK expsc ].string[ s_pos ] = '\0';
  543. X            }
  544. X             else
  545. X            {
  546. X            build_loop = FALSE;
  547. X            }
  548. X             break;
  549. X
  550. X          case '0':                        /* or ordinary digit */
  551. X                  case '1':
  552. X                  case '2':
  553. X                  case '3':
  554. X                  case '4':
  555. X                  case '5':
  556. X                  case '6':
  557. X                  case '7':
  558. X                  case '8':
  559. X                  case '9':
  560. X
  561. X                     CURTASK exps[ CURTASK expsc ].string[ s_pos ] = expression[ CURTASK exps[ CURTASK expsc ].pos_adv ];
  562. X                     ++CURTASK exps[ CURTASK expsc ].pos_adv;  /* advance to next character */
  563. X                     ++s_pos;
  564. X             CURTASK exps[ CURTASK expsc ].string[ s_pos ] = '\0';
  565. X             need_pm = FALSE;
  566. X                     break;
  567. X
  568. X                  default:                         /* anything else, terminate */
  569. X                     build_loop = FALSE;
  570. X                     break;
  571. X                  }
  572. X
  573. X               }                                /* end of build loop for exponent */
  574. X
  575. X            /* assign the value to the user variable */
  576. X
  577. X#if NUMBER_DOUBLE
  578. X            sscanf( CURTASK exps[ CURTASK expsc ].string, "%lf",
  579. X               &( CURTASK exps[ CURTASK expsc ].nval ) );
  580. X#else
  581. X            sscanf( CURTASK exps[ CURTASK expsc ].string, "%f",
  582. X               &( CURTASK exps[ CURTASK expsc ].nval ) );
  583. X#endif
  584. X
  585. X#if INTENSIVE_DEBUG
  586. X        sprintf( bwb_ebuf, "in exp_numconst(): exponent is <%d>",
  587. X               (int) CURTASK exps[ CURTASK expsc ].nval );
  588. X            bwb_debug( bwb_ebuf );
  589. X#endif
  590. X
  591. X            }                           /* end of exponent search */
  592. X
  593. X         if ( CURTASK exps[ CURTASK expsc ].nval == (bnumber) 0 )
  594. X            {
  595. X            CURTASK exps[ CURTASK expsc ].nval = var_getnval( &mantissa );
  596. X            }
  597. X         else
  598. X            {
  599. X            CURTASK exps[ CURTASK expsc ].nval = var_getnval( &mantissa )
  600. X               * pow( (bnumber) 10.0, (bnumber) CURTASK exps[ CURTASK expsc ].nval );
  601. X            }
  602. X
  603. X         break;
  604. X
  605. X      case 8:                           /* octal constant */
  606. X
  607. X         /* initialize counters */
  608. X
  609. X         CURTASK exps[ CURTASK expsc ].pos_adv = man_start;
  610. X         CURTASK exps[ CURTASK expsc ].type = NUMBER;
  611. X         CURTASK exps[ CURTASK expsc ].string[ 0 ] = '\0';
  612. X         s_pos = 0;
  613. X         exponent = OP_NULL;
  614. X         build_loop = TRUE;
  615. X
  616. X         /* loop to build the string */
  617. X
  618. X         while ( build_loop == TRUE )
  619. X            {
  620. X            switch( expression[ CURTASK exps[ CURTASK expsc ].pos_adv ] )
  621. X               {
  622. X               case '0':                        /* or ordinary digit */
  623. X               case '1':
  624. X               case '2':
  625. X               case '3':
  626. X               case '4':
  627. X               case '5':
  628. X               case '6':
  629. X               case '7':
  630. X                  CURTASK exps[ CURTASK expsc ].string[ s_pos ] = expression[ CURTASK exps[ CURTASK expsc ].pos_adv ];
  631. X                  ++CURTASK exps[ CURTASK expsc ].pos_adv;  /* advance to next character */
  632. X                  ++s_pos;
  633. X                  CURTASK exps[ CURTASK expsc ].string[ s_pos ] = '\0';
  634. X                  break;
  635. X
  636. X               default:                         /* anything else, terminate */
  637. X                  build_loop = FALSE;
  638. X                  break;
  639. X               }
  640. X
  641. X            }
  642. X
  643. X         /* now scan the string to determine the number */
  644. X
  645. X         sscanf( CURTASK exps[ CURTASK expsc ].string, "%o", &i );
  646. X         CURTASK exps[ CURTASK expsc ].nval = (bnumber) i;
  647. X
  648. X         break;
  649. X
  650. X      case 16:                          /* hexadecimal constant */
  651. X
  652. X         /* initialize counters */
  653. X
  654. X         CURTASK exps[ CURTASK expsc ].pos_adv = man_start;
  655. X         CURTASK exps[ CURTASK expsc ].type = NUMBER;
  656. X         CURTASK exps[ CURTASK expsc ].string[ 0 ] = '\0';
  657. X         s_pos = 0;
  658. X         exponent = OP_NULL;
  659. X         build_loop = TRUE;
  660. X
  661. X         /* loop to build the string */
  662. X
  663. X         while ( build_loop == TRUE )
  664. X            {
  665. X            switch( expression[ CURTASK exps[ CURTASK expsc ].pos_adv ] )
  666. X               {
  667. X               case '0':                        /* or ordinary digit */
  668. X               case '1':
  669. X               case '2':
  670. X               case '3':
  671. X               case '4':
  672. X               case '5':
  673. X               case '6':
  674. X               case '7':
  675. X               case '8':
  676. X               case '9':
  677. X               case 'A':
  678. X               case 'a':
  679. X               case 'B':
  680. X               case 'b':
  681. X               case 'C':
  682. X               case 'c':
  683. X               case 'D':
  684. X               case 'd':
  685. X               case 'E':
  686. X               case 'e':
  687. X                  CURTASK exps[ CURTASK expsc ].string[ s_pos ] = expression[ CURTASK exps[ CURTASK expsc ].pos_adv ];
  688. X
  689. X                  ++CURTASK exps[ CURTASK expsc ].pos_adv;  /* advance to next character */
  690. X                  ++s_pos;
  691. X                  CURTASK exps[ CURTASK expsc ].string[ s_pos ] = '\0';
  692. X                  break;
  693. X
  694. X               default:                         /* anything else, terminate */
  695. X                  build_loop = FALSE;
  696. X                  break;
  697. X               }
  698. X
  699. X            }
  700. X
  701. X         /* now scan the string to determine the number */
  702. X
  703. X         sscanf( CURTASK exps[ CURTASK expsc ].string, "%x", &i );
  704. X         CURTASK exps[ CURTASK expsc ].nval = (bnumber) i;
  705. X         break;
  706. X      }
  707. X
  708. X   /* note that the operation at this level is now a determined NUMBER */
  709. X
  710. X   CURTASK exps[ CURTASK expsc ].operation = NUMBER;
  711. X
  712. X#if INTENSIVE_DEBUG
  713. X   sprintf( bwb_ebuf, "in exp_numconst(): exit level <%d> precision <%c> value <%lf>",
  714. X      CURTASK expsc, CURTASK exps[ CURTASK expsc ].type, exp_getnval( &( CURTASK exps[ CURTASK expsc ] ) ) );
  715. X   bwb_debug( bwb_ebuf );
  716. X#endif
  717. X
  718. X#if CHECK_RECURSION
  719. X   in_use = FALSE;
  720. X#endif
  721. X
  722. X   return TRUE;
  723. X
  724. X   }
  725. X
  726. X/***************************************************************
  727. X
  728. X    FUNCTION:       exp_function()
  729. X
  730. X    DESCRIPTION:    This function interprets a function,
  731. X            calling bwb_exp() (recursively) to resolve any
  732. X            arguments to the function.
  733. X
  734. X***************************************************************/
  735. X
  736. X#if ANSI_C
  737. Xint
  738. Xexp_function( char *expression )
  739. X#else
  740. Xint
  741. Xexp_function( expression )
  742. X   char *expression;
  743. X#endif
  744. X   {
  745. X   struct exp_ese *e;
  746. X   int s_pos;                           /* position in build buffer */
  747. X   int loop;
  748. X   int paren_level;
  749. X   int n_args;
  750. X   struct bwb_variable *v;
  751. X   struct bwb_variable argv[ MAX_FARGS ];
  752. X   bstring *b;
  753. X#if INTENSIVE_DEBUG
  754. X   char tbuf[ MAXSTRINGSIZE + 1 ];
  755. X
  756. X   sprintf( bwb_ebuf, "in exp_function(): entered function, expression <%s>",
  757. X      expression );
  758. X   bwb_debug( bwb_ebuf );
  759. X#endif
  760. X
  761. X   /* assign pointers to argument stack */
  762. X
  763. X   /* get the function name */
  764. X
  765. X   exp_getvfname( expression, CURTASK exps[ CURTASK expsc ].string );
  766. X
  767. X#if INTENSIVE_DEBUG
  768. X   sprintf( bwb_ebuf, "in exp_function(): name is <%s>.",
  769. X      CURTASK exps[ CURTASK expsc ].string );
  770. X   bwb_debug( bwb_ebuf );
  771. X#endif
  772. X
  773. X   /* now find the function itself */
  774. X
  775. X   CURTASK exps[ CURTASK expsc ].function = fnc_find( CURTASK exps[ CURTASK expsc ].string );
  776. X
  777. X   /* check to see if it is valid */
  778. X
  779. X   if ( CURTASK exps[ CURTASK expsc ].function == NULL )
  780. X      {
  781. X#if PROG_ERRORS
  782. X      sprintf( bwb_ebuf, "Failed to find function <%s>.",
  783. X         CURTASK exps[ CURTASK expsc ].string );
  784. X      bwb_error( bwb_ebuf );
  785. X#else
  786. X      bwb_error( err_uf  );
  787. X#endif
  788. X      return OP_ERROR;
  789. X      }
  790. X
  791. X   /* note that this level is a function */
  792. X
  793. X   CURTASK exps[ CURTASK expsc ].operation = FUNCTION;
  794. X   CURTASK exps[ CURTASK expsc ].pos_adv = strlen( CURTASK exps[ CURTASK expsc ].string );
  795. X
  796. X   /* check for begin parenthesis */
  797. X
  798. X   loop = TRUE;
  799. X   while( loop == TRUE )
  800. X      {
  801. X      switch( expression[ CURTASK exps[ CURTASK expsc ].pos_adv ] )
  802. X         {
  803. X
  804. X         case ' ':                              /* whitespace */
  805. X         case '\t':
  806. X            ++CURTASK exps[ CURTASK expsc ].pos_adv;        /* advance */
  807. X            break;
  808. X
  809. X         case '(':                              /* begin paren */
  810. X
  811. X#if INTENSIVE_DEBUG
  812. X            sprintf( bwb_ebuf, "in exp_function(): found begin parenthesis." );
  813. X            bwb_debug( bwb_ebuf );
  814. X#endif
  815. X
  816. X            ++CURTASK exps[ CURTASK expsc ].pos_adv;        /* advance beyond it */
  817. X            paren_level = 1;                    /* set paren_level */
  818. X            loop = FALSE;                       /* and break out */
  819. X            break;
  820. X
  821. X         default:                               /* anything else */
  822. X            loop = FALSE;
  823. X            paren_level = 0;                    /* do not look for arguments */
  824. X            break;
  825. X         }
  826. X      }
  827. X
  828. X   /* find arguments within parentheses */
  829. X   /* for each argument, find a string ending with ',' or with end parenthesis */
  830. X
  831. X   n_args = 0;
  832. X   s_pos = 0;
  833. X   CURTASK exps[ CURTASK expsc ].string[ 0 ] = '\0';
  834. X
  835. X   while( paren_level > 0 )
  836. X      {
  837. X
  838. X      /* check the current character */
  839. X
  840. X      switch( expression[ CURTASK exps[ CURTASK expsc ].pos_adv ] )
  841. X         {
  842. X
  843. X         case ',':                      /* end of an argument */
  844. X
  845. X            if ( paren_level == 1 )     /* ignore ',' within parentheses */
  846. X               {
  847. X
  848. X               /* call bwb_exp() recursively to resolve the argument */
  849. X
  850. X               if ( exp_validarg( CURTASK exps[ CURTASK expsc ].string ) == TRUE )
  851. X                  {
  852. X#if INTENSIVE_DEBUG
  853. X          sprintf( bwb_ebuf,
  854. X             "in exp_function(): valid argument (not last)." );
  855. X                  bwb_debug( bwb_ebuf );
  856. X#endif
  857. X
  858. X                  CURTASK exps[ CURTASK expsc ].rec_pos = 0;
  859. X                  e = bwb_exp( CURTASK exps[ CURTASK expsc ].string, FALSE,
  860. X                     &( CURTASK exps[ CURTASK expsc ].rec_pos ) );
  861. X
  862. X                  /* assign operation and value at this level */
  863. X
  864. X                  var_make( &( argv[ n_args ] ), e->type );
  865. X
  866. X                  switch( argv[ n_args ].type )
  867. X                     {
  868. X                     case NUMBER:
  869. X                        * var_findnval( &( argv[ n_args ] ), argv[ n_args ].array_pos )
  870. X                            = exp_getnval( e );
  871. X                        break;
  872. X                     case STRING:
  873. X                        str_btob( var_findsval( &( argv[ n_args ] ),
  874. X                           argv[ n_args ].array_pos ), exp_getsval( e ) );
  875. X                        break;
  876. X                     }
  877. X
  878. X                  ++n_args;                /* increment number of arguments */
  879. X
  880. X                  }
  881. X
  882. X               s_pos = 0;               /* reset counter */
  883. X               CURTASK exps[ CURTASK expsc ].string[ 0 ] = '\0';
  884. X               }
  885. X
  886. X            else
  887. X               {
  888. X               CURTASK exps[ CURTASK expsc ].string[ s_pos ]
  889. X                  = expression[ CURTASK exps[ CURTASK expsc ].pos_adv ];
  890. X               ++s_pos;
  891. X               CURTASK exps[ CURTASK expsc ].string[ s_pos ] = '\0';
  892. X               }
  893. X            break;
  894. X
  895. X         case '(':
  896. X            ++paren_level;
  897. X            CURTASK exps[ CURTASK expsc ].string[ s_pos ]
  898. X               = expression[ CURTASK exps[ CURTASK expsc ].pos_adv ];
  899. X            ++s_pos;
  900. X            CURTASK exps[ CURTASK expsc ].string[ s_pos ] = '\0';
  901. X            break;
  902. X
  903. X         case ')':
  904. X            --paren_level;
  905. X
  906. X#if INTENSIVE_DEBUG
  907. X            sprintf( bwb_ebuf,
  908. X               "in exp_function(): hit close parenthesis." );
  909. X            bwb_debug( bwb_ebuf );
  910. X#endif
  911. X
  912. X            if ( paren_level == 0 )
  913. X               {
  914. X
  915. X#if INTENSIVE_DEBUG
  916. X               sprintf( bwb_ebuf,
  917. X                  "in exp_function(): paren level 0." );
  918. X               bwb_debug( bwb_ebuf );
  919. X#endif
  920. X
  921. X               /* call bwb_exp() recursively to resolve the argument */
  922. X
  923. X               if ( exp_validarg( CURTASK exps[ CURTASK expsc ].string ) == TRUE )
  924. X                  {
  925. X#if INTENSIVE_DEBUG
  926. X          sprintf( bwb_ebuf,
  927. X             "in exp_function(): valid argument (last)." );
  928. X          bwb_debug( bwb_ebuf );
  929. X#endif
  930. X
  931. X                  CURTASK exps[ CURTASK expsc ].rec_pos = 0;
  932. X                  e = bwb_exp( CURTASK exps[ CURTASK expsc ].string, FALSE,
  933. X                     &( CURTASK exps[ CURTASK expsc ].rec_pos ) );
  934. X
  935. X#if INTENSIVE_DEBUG
  936. X          sprintf( bwb_ebuf,
  937. X             "in exp_function(): return from bwb_exp(), last arg, type <%c> op <%d>",
  938. X             e->type, e->operation );
  939. X          bwb_debug( bwb_ebuf );
  940. X#endif
  941. X
  942. X                  /* assign operation and value at this level */
  943. X
  944. X                  var_make( &( argv[ n_args ] ), e->type );
  945. X
  946. X                  switch( argv[ n_args ].type )
  947. X                     {
  948. X                     case NUMBER:
  949. X                        * var_findnval( &( argv[ n_args ] ), argv[ n_args ].array_pos )
  950. X                            = exp_getnval( e );
  951. X                        break;
  952. X                     case STRING:
  953. X                        str_btob( var_findsval( &( argv[ n_args ] ),
  954. X                           argv[ n_args ].array_pos ), exp_getsval( e ) );
  955. X                        break;
  956. X                     }
  957. X
  958. X                  ++n_args;                /* increment number of arguments */
  959. X
  960. X                  }
  961. X
  962. X               s_pos = 0;               /* reset counter */
  963. X               CURTASK exps[ CURTASK expsc ].string[ 0 ] = '\0';
  964. X               }
  965. X
  966. X            else
  967. X               {
  968. X               CURTASK exps[ CURTASK expsc ].string[ s_pos ]
  969. X                  = expression[ CURTASK exps[ CURTASK expsc ].pos_adv ];
  970. X               ++s_pos;
  971. X               CURTASK exps[ CURTASK expsc ].string[ s_pos ] = '\0';
  972. X               }
  973. X            break;
  974. X
  975. X         case '\"':                             /* embedded string constant */
  976. X
  977. X            /* add the initial quotation mark */
  978. X
  979. X            CURTASK exps[ CURTASK expsc ].string[ s_pos ]
  980. X               = expression[ CURTASK exps[ CURTASK expsc ].pos_adv ];
  981. X            ++s_pos;
  982. X            CURTASK exps[ CURTASK expsc ].string[ s_pos ] = '\0';
  983. X            ++CURTASK exps[ CURTASK expsc ].pos_adv;
  984. X
  985. X            /* add intervening characters */
  986. X
  987. X            while ( ( expression[ CURTASK exps[ CURTASK expsc ].pos_adv ] != '\"' )
  988. X               && ( expression[ CURTASK exps[ CURTASK expsc ].pos_adv ] != '\0' ) )
  989. X               {
  990. X               CURTASK exps[ CURTASK expsc ].string[ s_pos ]
  991. X                  = expression[ CURTASK exps[ CURTASK expsc ].pos_adv ];
  992. X               ++s_pos;
  993. X               CURTASK exps[ CURTASK expsc ].string[ s_pos ] = '\0';
  994. X               ++CURTASK exps[ CURTASK expsc ].pos_adv;
  995. X               }
  996. X
  997. X            /* add the concluding quotation mark */
  998. X
  999. X            CURTASK exps[ CURTASK expsc ].string[ s_pos ]
  1000. X               = expression[ CURTASK exps[ CURTASK expsc ].pos_adv ];
  1001. X            ++s_pos;
  1002. X            CURTASK exps[ CURTASK expsc ].string[ s_pos ] = '\0';
  1003. X            /* the following bracketed out 14 July 1992; since this counter */
  1004. X            /* incremented at the end of the switch statement, this may */
  1005. X            /* increment it past the next character needed */
  1006. X            /* ++CURTASK exps[ CURTASK expsc ].pos_adv; */
  1007. X            break;
  1008. X
  1009. X         default:
  1010. X            CURTASK exps[ CURTASK expsc ].string[ s_pos ]
  1011. X               = expression[ CURTASK exps[ CURTASK expsc ].pos_adv ];
  1012. X            ++s_pos;
  1013. X            CURTASK exps[ CURTASK expsc ].string[ s_pos ] = '\0';
  1014. X#if INTENSIVE_DEBUG
  1015. X            sprintf( bwb_ebuf, "in exp_function(): new char <%d>=<%c>",
  1016. X               expression[ CURTASK exps[ CURTASK expsc ].pos_adv ],
  1017. X               expression[ CURTASK exps[ CURTASK expsc ].pos_adv ] );
  1018. X            bwb_debug( bwb_ebuf );
  1019. X            sprintf( bwb_ebuf, "in exp_function(): building <%s>.",
  1020. X               CURTASK exps[ CURTASK expsc ].string );
  1021. X            bwb_debug( bwb_ebuf );
  1022. X#endif
  1023. X            break;
  1024. X         }
  1025. X
  1026. X      /* advance the counter */
  1027. X
  1028. X      ++CURTASK exps[ CURTASK expsc ].pos_adv;
  1029. X
  1030. X      }
  1031. X
  1032. X#if INTENSIVE_DEBUG
  1033. X   sprintf( bwb_ebuf, "in exp_function(): ready to call function vector" );
  1034. X   bwb_debug( bwb_ebuf );
  1035. X#endif
  1036. X
  1037. X   /* call the function vector */
  1038. X
  1039. X#if INTENSIVE_DEBUG
  1040. X   sprintf( bwb_ebuf, "in exp_function(): calling preset function" );
  1041. X   bwb_debug( bwb_ebuf );
  1042. X#endif
  1043. X
  1044. X   v = CURTASK exps[ CURTASK expsc ].function->vector ( n_args, &( argv[ 0 ] ),
  1045. X      CURTASK exps[ CURTASK expsc ].function->id );
  1046. X
  1047. X#if INTENSIVE_DEBUG
  1048. X   sprintf( bwb_ebuf, "in exp_function(): return from function vector, type <%c>",
  1049. X      v->type );
  1050. X   bwb_debug( bwb_ebuf );
  1051. X#endif
  1052. X
  1053. X   /* assign the value at this level */
  1054. X
  1055. X   CURTASK exps[ CURTASK expsc ].type = (char) v->type;
  1056. X   
  1057. X   switch( v->type )
  1058. X      {
  1059. X      case STRING:
  1060. X         CURTASK exps[ CURTASK expsc ].operation = CONST_STRING;
  1061. X
  1062. X#if INTENSIVE_DEBUG
  1063. X         sprintf( bwb_ebuf, "in exp_function(): ready to assign STRING" );
  1064. X         bwb_debug( bwb_ebuf );
  1065. X#endif
  1066. X
  1067. X         b = var_findsval( v, v->array_pos );
  1068. X         str_btob( exp_getsval( &( CURTASK exps[ CURTASK expsc ] )), b );
  1069. X
  1070. X#if INTENSIVE_DEBUG
  1071. X         str_btoc( tbuf, b );
  1072. X         sprintf( bwb_ebuf, "in exp_function(): string assigned <%s>", tbuf );
  1073. X         bwb_debug( bwb_ebuf );
  1074. X#endif
  1075. X
  1076. X         break;
  1077. X
  1078. X      default:
  1079. X         CURTASK exps[ CURTASK expsc ].operation = NUMBER;
  1080. X         CURTASK exps[ CURTASK expsc ].nval = var_getnval( v );
  1081. X         break;
  1082. X      }
  1083. X
  1084. X#if INTENSIVE_DEBUG
  1085. X   sprintf( bwb_ebuf, "in exp_function(): end of function" );
  1086. X   bwb_debug( bwb_ebuf );
  1087. X#endif
  1088. X
  1089. X   /* return */
  1090. X
  1091. X   return TRUE;
  1092. X
  1093. X   }
  1094. X
  1095. X/***************************************************************
  1096. X
  1097. X    FUNCTION:       exp_variable()
  1098. X
  1099. X    DESCRIPTION:    This function interprets a variable.
  1100. X
  1101. X***************************************************************/
  1102. X
  1103. X#if ANSI_C
  1104. Xint
  1105. Xexp_variable( char *expression )
  1106. X#else
  1107. Xint
  1108. Xexp_variable( expression )
  1109. X   char *expression;
  1110. X#endif
  1111. X   {
  1112. X   int pos;
  1113. X   int *pp;
  1114. X   int n_params;
  1115. X   register int n;
  1116. X   struct bwb_variable *v;
  1117. X   bstring *b;
  1118. X   int p;
  1119. X
  1120. X#if INTENSIVE_DEBUG
  1121. X   sprintf( bwb_ebuf, "in exp_variable(): entered function." );
  1122. X   bwb_debug( bwb_ebuf );
  1123. X#endif
  1124. X
  1125. X   /* get the variable name */
  1126. X
  1127. X   exp_getvfname( expression, CURTASK exps[ CURTASK expsc ].string );
  1128. X
  1129. X   /* now find the variable itself */
  1130. X
  1131. X   v = CURTASK exps[ CURTASK expsc ].xvar = var_find( CURTASK exps[ CURTASK expsc ].string );
  1132. X
  1133. X#if INTENSIVE_DEBUG
  1134. X   sprintf( bwb_ebuf, "in exp_variable(): level <%d>, found variable name <%s>",
  1135. X      CURTASK expsc, CURTASK exps[ CURTASK expsc ].xvar->name );
  1136. X   bwb_debug( bwb_ebuf );
  1137. X#endif
  1138. X
  1139. X   /* note that this level is a variable */
  1140. X
  1141. X   CURTASK exps[ CURTASK expsc ].operation = VARIABLE;
  1142. X
  1143. X   /* read subscripts */
  1144. X
  1145. X   pos = strlen( CURTASK exps[ CURTASK expsc ].string );
  1146. X   if ( ( v->dimensions == 1 ) && ( v->array_sizes[ 0 ] == 1 ))
  1147. X      {
  1148. X#if INTENSIVE_DEBUG
  1149. X      sprintf( bwb_ebuf, "in exp_variable(): variable <%s> has 1 dimension",
  1150. X         CURTASK exps[ CURTASK expsc ].xvar->name );
  1151. X      bwb_debug( bwb_ebuf );
  1152. X#endif
  1153. X      pos = strlen( v->name );
  1154. X      n_params = 1;
  1155. X      pp = &p;
  1156. X      pp[ 0 ] = dim_base;
  1157. X      }
  1158. X   else
  1159. X      {
  1160. X#if INTENSIVE_DEBUG
  1161. X      sprintf( bwb_ebuf, "in exp_variable(): variable <%s> has > 1 dimensions",
  1162. X         CURTASK exps[ CURTASK expsc ].xvar->name );
  1163. X      bwb_debug( bwb_ebuf );
  1164. X#endif
  1165. X      dim_getparams( expression, &pos, &n_params, &pp );
  1166. X      }
  1167. X
  1168. X   CURTASK exps[ CURTASK expsc ].pos_adv = pos;
  1169. X   for ( n = 0; n < v->dimensions; ++n )
  1170. X      {
  1171. X      CURTASK exps[ CURTASK expsc ].array_pos[ n ] = v->array_pos[ n ] = pp[ n ];
  1172. X      }
  1173. X
  1174. X#if INTENSIVE_DEBUG
  1175. X   for ( n = 0; n < v->dimensions; ++ n )
  1176. X      {
  1177. X      sprintf( bwb_ebuf, "in exp_variable(): var <%s> array_pos element <%d> is <%d>.",
  1178. X         v->name, n, v->array_pos[ n ] );
  1179. X      bwb_debug( bwb_ebuf );
  1180. X      }
  1181. X#endif
  1182. X
  1183. X   /* assign the type and value at this level */
  1184. X
  1185. X   CURTASK exps[ CURTASK expsc ].type = (char) v->type;
  1186. X   
  1187. X   switch( v->type )
  1188. X      {
  1189. X      case STRING:
  1190. X         b = var_findsval( v, v->array_pos );
  1191. X#if TEST_BSTRING
  1192. X         sprintf( bwb_ebuf, "in exp_variable(): b string name is <%s>",
  1193. X            b->name );
  1194. X         bwb_debug( bwb_ebuf );
  1195. X#endif
  1196. X#if OLDWAY
  1197. X     CURTASK exps[ CURTASK expsc ].sval.length = b->length;
  1198. X     CURTASK exps[ CURTASK expsc ].sval.sbuffer = b->sbuffer;
  1199. X#endif
  1200. X     str_btob( &( CURTASK exps[ CURTASK expsc ].sval ), b );
  1201. X         break;
  1202. X      default:
  1203. X         CURTASK exps[ CURTASK expsc ].nval = var_getnval( v );
  1204. X         break;
  1205. X      }
  1206. X
  1207. X#if INTENSIVE_DEBUG
  1208. X   sprintf( bwb_ebuf, "in exp_variable(): exit, name <%s>, level <%d>, op <%d>",
  1209. X      v->name, CURTASK expsc, CURTASK exps[ CURTASK expsc ].operation  );
  1210. X   bwb_debug( bwb_ebuf );
  1211. X#endif
  1212. X
  1213. X   /* return */
  1214. X
  1215. X   return TRUE;
  1216. X
  1217. X   }
  1218. X
  1219. X
  1220. X
  1221. END_OF_FILE
  1222.   if test 35745 -ne `wc -c <'bwbasic-2.10/bwb_elx.c'`; then
  1223.     echo shar: \"'bwbasic-2.10/bwb_elx.c'\" unpacked with wrong size!
  1224.   fi
  1225.   # end of 'bwbasic-2.10/bwb_elx.c'
  1226. fi
  1227. echo shar: End of archive 13 \(of 15\).
  1228. cp /dev/null ark13isdone
  1229. MISSING=""
  1230. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ; do
  1231.     if test ! -f ark${I}isdone ; then
  1232.     MISSING="${MISSING} ${I}"
  1233.     fi
  1234. done
  1235. if test "${MISSING}" = "" ; then
  1236.     echo You have unpacked all 15 archives.
  1237.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1238. else
  1239.     echo You still must unpack the following archives:
  1240.     echo "        " ${MISSING}
  1241. fi
  1242. exit 0
  1243. exit 0 # Just in case...
  1244.