shell.yacc
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:37k
源码类别:

VxWorks

开发平台:

C/C++

  1. %{
  2. /* shell.yacc - grammar for VxWorks shell */
  3. /* Copyright 1984-2001 Wind River Systems, Inc. */
  4. #include "copyright_wrs.h"
  5. /*
  6. modification history
  7. --------------------
  8. 07m,16oct01,jn   use symFindSymbol for symbol lookups
  9. 07l,27nov01,pch  Provide floating-point exclusion based on _WRS_NO_TGT_SHELL_FP
  10.  definition instead of testing a specific CPU type.
  11. 07k,23oct01,fmk  Do not call symFindByValue and print symbol name if symbol
  12.                  value = -1 SPR 22254
  13. 07j,04sep98,cdp  apply 07i for all ARM CPUs with ARM_THUMB==TRUE.
  14. 07i,30jul97,cdp  for ARM7TDMI_T, force calls to be in Thumb state.
  15. 07h,31may96,ms   added in patch for SPR 4439.
  16. 07g,19mar95,dvs  removed tron references.
  17. 07f,02mar95,yao  removed floating point temporarily for PPC403.
  18. 07e,19mar95,dvs  removed tron references.
  19. 07d,13feb93,kdl  changed cplusLib.h to private/cplusLibP.h (SPR #1917).
  20. 07c,03sep92,wmd  modified addArg() to pass floats correcty for the i960.
  21. 07b,03sep92,rrr  reduced max function arguments from 16 to 12 (for i960).
  22. 07a,31aug92,kdl  fixed passing of more than 10 parameters during funcCall();
  23.  changed MAX_ARGS to MAX_SHELL_ARGS.
  24. 06z,19aug92,jmm  fixed problem with not recognizing <= (SPR 1517)
  25. 06y,01aug92,srh  added C++ demangling idiom to printSym.
  26.                  added include of cplusLib.h.
  27. 06x,20jul92,jmm  added group parameter to symAdd call
  28. 06w,23jun92,kdl  increased max function arguments from 10 to 16.
  29. 06v,22jun92,jmm  backed out 6u change, now identical to gae's 21dec revision
  30. 06u,22jun92,jmm  added group parameter to symAdd
  31. 06t,21dec91,gae  more ANSI cleanups.
  32. 06s,19nov91,rrr  shut up some warnings.
  33. 06r,05oct91,rrr  changed strLib.h to string.h
  34. 06q,02jun91,del  added I960 parameter alignment fixes.
  35. 06p,10aug90,kdl  added forward declarations for functions returning VOID.
  36. 06o,10jul90,dnw  spr 738: removed checking of access (checkAccess, chkLvAccess)
  37.    Access checking did vxMemProbe with 4 byte read, which
  38.    caused problems with memory or devices that couldn't do
  39.    4 byte reads but could do other types of access.
  40.    Access checking was actually a throw-back to a time when
  41.    the shell couldn't recover from bus errors, but it can now.
  42.    So I just deleted the access checking.
  43.  lint clean-up, esp to allow VOID to be void one day.
  44. 06n,10dec89,jcf  symbol table type now a SYM_TYPE.
  45. 06m,09aug89,gae  fixed copyright notice.
  46. 06l,30jul89,gae  changed obsolete sysMemProbe to vxMemProbe. 
  47. 06k,07jul88,jcf  changed malloc to match new declaration.
  48. 06j,30may88,dnw  changed to v4 names.
  49. 06i,01apr88,gae  made it work with I/O system changes -- io{G,S}etGlobalStd().
  50. 06h,20feb88,dnw  lint
  51. 06g,14dec87,dnw  removed checking for odd byte address access.
  52.  changed printing format of doubles from "%f" to "%g". 
  53. 06f,18nov87,gae  made assignment to be of type specified by rhs.
  54. 06e,07nov87,gae  fixed undefined symbol bug.
  55.  fixed history bug by redirecting LED I/O.
  56. 06d,03nov87,ecs  documentation.
  57. 06c,28oct87,gae  got rid of string type.
  58. 06b,06oct87,gae  split off "execution" portion to shellExec.c.
  59.  changed to use conventional C type casting.
  60.  provided more info for invalid yacc operations.
  61.  allowed expressions to be function addresses.
  62. 06a,01jun87,gae  added interpretation of bytes, words, floats, doubles;
  63.    expressions can now be "typed" a la assembler, .[bwfdls].
  64.  fixed redirection bug with ">>" and "<<".
  65. 05i,16jul87,ecs  fixed newSym so that new symbols will be global.
  66. 05h,01apr87,gae  made assign() not print "new value" message (duplicated
  67.    normal "value" message for expressions.
  68. 05g,25apr87,gae  fixed bug in assign() that allowed memory corruption.
  69.  checked h() parameter for greater than or equal to zero.
  70.  improved redirection detection.
  71.  now parse assignments correctly as expressions.
  72. 05f,01apr87,ecs  added include of strLib.h.
  73. 05e,20jan87,jlf  documentation.
  74. 05d,14jan87,gae  got rid of unused curLineNum.  h() now has parameter, if
  75.    non-zero then resets history to that size.
  76. 05c,20dec86,dnw  changed to not get include files from default directories.
  77. 05b,18dec86,gae  made history initialization only happen on first start of
  78.    shell.  Added neStmt to fix empty stmt assignment bug.
  79. 05a,17dec86,gae  use new shCmd() in execShell() to do Korn shell-like input.
  80. 04q,08dec86,dnw  changed shell.slex.c to shell_slex.c for VAX/VMS compatiblity.
  81.     jlf  fixed a couple bugs causing problems mainly on Heurikon port.
  82. 04p,24nov86,llk  deleted SYSTEM conditional compiles.
  83. 04o,08oct86,gae  added C assignment operators; allowed multiple assignment.
  84.  STRINGs are no longer temporary.  Added setShellPrompt().
  85. 04n,27jul86,llk  added standard error fd, setOrigErrFd.
  86. 04m,17jun86,rdc  changed memAllocates to mallocs.
  87. 04l,08apr86,dnw  added call to vxSetTaskBreakable to make shell unbreakable.
  88.  changed sstLib calls to symLib.
  89. 04k,02apr86,rdc  added routines setOrigInFd and setOrigOutFd.
  90. 04j,18jan86,dnw  removed resetting (flushing) for standard in/out upon restarts;
  91.    this is now done more appropriately by the shell restart
  92.    routine in dbgLib.
  93. ...deleted pre 86 history - see RCS
  94. */
  95. /*
  96. DESCRIPTION
  97. This is the parser for the VxWorks shell, written in yacc.
  98. It provides the basic programmer's interface to VxWorks.
  99. It is a C expression interpreter, containing no built-in commands.  
  100. SEE ALSO: "Shell"
  101. */
  102. #include "vxWorks.h"
  103. #include "sysSymTbl.h"
  104. #include "errno.h"
  105. #include "errnoLib.h"
  106. #include "ioLib.h"
  107. #include "taskLib.h"
  108. #include "stdio.h"
  109. #include "private/cplusLibP.h"
  110. #define YYSTYPE VALUE /* type of parse stack */
  111. #define MAX_SHELL_LINE 128 /* max chars on line typed to shell */
  112. #define MAX_SHELL_ARGS 30 /* max number of args on stack */
  113. #define MAX_FUNC_ARGS 12 /* max number of args to any one function */
  114. /*  NOTE: The array indices in funcCall()
  115.  *        must agree with MAX_FUNC_ARGS!!
  116.  */
  117. #define BIN_OP(op) rvOp((getRv(&yypvt[-2], &tmpVal1)), op, 
  118.       getRv(&yypvt[-0], &tmpVal2))
  119. #define RV(value) (getRv (&(value), &tmpVal2))
  120. #define NULLVAL (VALUE *) NULL
  121. #define CHECK if (semError) YYERROR
  122. #define SET_ERROR semError = TRUE
  123. typedef enum /* TYPE */
  124.     {
  125.     T_UNKNOWN,
  126.     T_BYTE,
  127.     T_WORD,
  128. #ifndef _WRS_NO_TGT_SHELL_FP
  129.     T_INT,
  130.     T_FLOAT,
  131.     T_DOUBLE
  132. #else /* _WRS_NO_TGT_SHELL_FP */
  133.     T_INT
  134. #endif /* _WRS_NO_TGT_SHELL_FP */
  135.     } TYPE;
  136. typedef enum /* SIDE */
  137.     {
  138.     LHS,
  139.     RHS,
  140.     FHS /* function: rhs -> lhs */
  141.     } SIDE;
  142. typedef struct /* VALUE */
  143.     {
  144.     SIDE side;
  145.     TYPE type;
  146.     union
  147. {
  148. int *lv; /* pointer to any of the below */
  149. char byte;
  150. short word;
  151. int rv;
  152. char *string;
  153. #ifndef _WRS_NO_TGT_SHELL_FP
  154. float fp;
  155. double dp;
  156. #endif /* _WRS_NO_TGT_SHELL_FP */
  157. } value;
  158.     } VALUE;
  159. IMPORT int redirInFd;
  160. IMPORT int redirOutFd;
  161. LOCAL BOOL semError; /* TRUE = semantic error found */
  162. LOCAL VALUE tmpVal1; /* used by BIN_OP above for expression evaluation */
  163. LOCAL VALUE tmpVal2; /* used by BIN_OP above for expression evaluation */
  164. LOCAL int argStack [MAX_SHELL_ARGS]; /* arguments to functions */
  165. LOCAL int nArgs; /* number of args currently on argStack */
  166. LOCAL BOOL usymFlag; /* TRUE = U_SYMBOL has been seen */
  167. LOCAL VALUE usymVal; /* value of U_SYMBOL which has been seen */
  168. LOCAL BOOL spawnFlag; /* TRUE if spawn is first parameter in argStack[] */
  169. %}
  170. %start line
  171. %token NL 0
  172. %token T_SYMBOL D_SYMBOL U_SYMBOL NUMBER CHAR STRING FLOAT
  173. %token OR AND EQ NE GE LE INCR DECR ROT_LEFT ROT_RIGHT UMINUS PTR TYPECAST
  174. %token ENDFILE LEX_ERROR
  175. %left '=' MULA DIVA MODA ADDA SUBA SHLA SHRA ANDA ORA XORA
  176. %right '?' ':'
  177. %left OR
  178. %left AND
  179. %left '|'
  180. %left '^'
  181. %left '&'
  182. %left EQ NE
  183. %left GE LE '>' '<'
  184. %left ROT_LEFT ROT_RIGHT
  185. %left '+' '-'
  186. %left '*' '/' '%'
  187. %left INCR DECR
  188. %left UNARY /* supplies precedence for unary operators */
  189. %left PTR '[' '('
  190. %left TYPECAST
  191. %%
  192. line : stmt
  193. | stmt ';' line
  194. ;
  195. stmt : /* empty */
  196. | expr { printValue (&$1); CHECK; }
  197. ;
  198. expr : D_SYMBOL
  199. | T_SYMBOL { $1.side = RHS; setRv (&$$, &$1); }
  200. | STRING  { $$ = $1; $$.value.rv = newString((char*)$1.value.rv);
  201.    CHECK; }
  202. | CHAR
  203. | NUMBER
  204. | FLOAT
  205. | '(' expr ')'   { $$ = $2; }
  206. | expr '(' arglist ')'
  207. { $$ = funcCall (&$1, &$3); CHECK; }
  208. | typecast expr %prec TYPECAST
  209. typeConvert (&$2, $1.type, $1.side); $$ = $2;
  210. CHECK;
  211. }
  212. | '*' expr  %prec UNARY { VALUE tmp;
  213.   (void)getRv (&$2, &tmp);
  214.   setLv (&$$, &tmp);
  215.   CHECK;
  216. }
  217. | '&' expr  %prec UNARY { $$.value.rv = (int)getLv (&$2);
  218.   $$.type = T_INT; $$.side = RHS; }
  219. | '-' expr  %prec UNARY { rvOp (RV($2), UMINUS, NULLVAL); }
  220. | '!' expr  %prec UNARY { rvOp (RV($2), '!', NULLVAL); }
  221. | '~' expr  %prec UNARY { rvOp (RV($2), '~', NULLVAL); }
  222. | expr '?' expr ':' expr { setRv (&$$, RV($1)->value.rv ? &$3
  223.        : &$5); }
  224. | expr '[' expr ']' { BIN_OP ('+');
  225.   typeConvert (&$$, T_INT, RHS);
  226.   setLv (&$$, &$$); }
  227. | expr PTR expr { BIN_OP ('+');
  228.   typeConvert (&$$, T_INT, RHS);
  229.   setLv (&$$, &$$); }
  230. | expr '+' expr { BIN_OP ('+'); }
  231. | expr '-' expr { BIN_OP ('-'); }
  232. | expr '*' expr { BIN_OP ('*'); }
  233. | expr '/' expr  { BIN_OP ('/'); }
  234. | expr '%' expr  { BIN_OP ('%'); }
  235. | expr ROT_RIGHT expr  { BIN_OP (ROT_RIGHT); }
  236. | expr ROT_LEFT expr  { BIN_OP (ROT_LEFT); }
  237. | expr '&' expr  { BIN_OP ('&'); }
  238. | expr '^' expr  { BIN_OP ('^'); }
  239. | expr '|' expr  { BIN_OP ('|'); }
  240. | expr AND expr  { BIN_OP (AND); }
  241. | expr OR expr  { BIN_OP (OR); }
  242. | expr EQ expr  { BIN_OP (EQ); }
  243. | expr NE expr  { BIN_OP (NE); }
  244. | expr GE expr  { BIN_OP (GE); }
  245. | expr LE expr  { BIN_OP (LE); }
  246. | expr '>' expr  { BIN_OP ('>'); }
  247. | expr '<' expr  { BIN_OP ('<'); }
  248. | INCR expr %prec UNARY { rvOp (RV($2), INCR, NULLVAL);
  249.   assign (&$2, &$$); CHECK; }
  250. | DECR expr %prec UNARY { rvOp (RV($2), DECR, NULLVAL);
  251.   assign (&$2, &$$); CHECK; }
  252. | expr INCR %prec UNARY { VALUE tmp;
  253.   tmp = $1;
  254.   rvOp (RV($1), INCR, NULLVAL);
  255.   assign (&$1, &$$); CHECK;
  256.   $$ = tmp; }
  257. | expr DECR %prec UNARY { VALUE tmp;
  258.   tmp = $1;
  259.   rvOp (RV($1), DECR, NULLVAL);
  260.   assign (&$1, &$$); CHECK;
  261.   $$ = tmp; }
  262. | expr ADDA expr { BIN_OP (ADDA); assign (&$1, &$$); CHECK;}
  263. | expr SUBA expr { BIN_OP (SUBA); assign (&$1, &$$); CHECK;}
  264. | expr ANDA expr { BIN_OP (ANDA); assign (&$1, &$$); CHECK;}
  265. | expr ORA  expr { BIN_OP (ORA);  assign (&$1, &$$); CHECK;}
  266. | expr MODA expr { BIN_OP (MODA); assign (&$1, &$$); CHECK;}
  267. | expr XORA expr { BIN_OP (XORA); assign (&$1, &$$); CHECK;}
  268. | expr MULA expr { BIN_OP (MULA); assign (&$1, &$$); CHECK;}
  269. | expr DIVA expr { BIN_OP (DIVA); assign (&$1, &$$); CHECK;}
  270. | expr SHLA expr { BIN_OP (SHLA); assign (&$1, &$$); CHECK;}
  271. | expr SHRA expr { BIN_OP (SHRA); assign (&$1, &$$); CHECK;}
  272. | expr '=' expr { assign (&$1, &$3); $$ = $1; }
  273. | U_SYMBOL
  274. /* the following is to allow "undef sym" error msg,
  275.  * instead of "syntax err" when U_SYM is not followed
  276.  * by proper assignment (see yyerror() below) */
  277. { usymFlag = TRUE; usymVal = $1; }
  278. '=' expr 
  279. {
  280. if ($1.type != T_UNKNOWN)
  281.     {
  282.     printf ("typecast of lhs not allowed.n");
  283.     YYERROR;
  284.     }
  285. else
  286.     {
  287.     $$ = newSym ((char *)$1.value.rv, $4.type); CHECK;
  288.     assign (&$$, &$4); CHECK;
  289.     }
  290. usymFlag = FALSE;
  291. }
  292. ;
  293. arglist : /* empty */
  294. { $$ = newArgList (); }
  295. | neArglist
  296. ;
  297. neArglist: expr /* non-empty arglist */
  298. { $$ = newArgList (); addArg (&$$, &$1); CHECK; }
  299. | neArglist ',' expr /* ',' is required */
  300. { addArg (&$1, &$3); CHECK; }
  301. ;
  302. typecast: '(' TYPECAST ')' { $2.side = RHS; $$ = $2; }
  303. | '(' TYPECAST '(' ')' ')' { $2.side = FHS; $$ = $2; }
  304. ;
  305. %%
  306. #include "a_out.h"
  307. #include "ctype.h"
  308. #include "stdlib.h"
  309. #include "string.h"
  310. #include "symLib.h"
  311. #include "shell_slex_c"
  312. /* forward declarations */
  313. LOCAL int newString ();
  314. LOCAL VALUE *getRv ();
  315. LOCAL int *getLv ();
  316. LOCAL VALUE evalExp ();
  317. #ifndef _WRS_NO_TGT_SHELL_FP
  318. LOCAL void doubleToInts ();
  319. #endif /* _WRS_NO_TGT_SHELL_FP */
  320. LOCAL void setRv ();
  321. LOCAL void typeConvert ();
  322. LOCAL BOOL checkLv ();
  323. LOCAL BOOL checkRv ();
  324. /*******************************************************************************
  325. *
  326. * yystart - initialize local variables
  327. *
  328. * NOMANUAL
  329. */
  330. void yystart (line)
  331.     char *line;
  332.     {
  333.     lexNewLine (line);
  334.     semError = FALSE;
  335.     usymFlag = FALSE;
  336.     nArgs = 0;
  337.     spawnFlag = FALSE;
  338.     }
  339. /*******************************************************************************
  340. *
  341. * yyerror - report error
  342. *
  343. * This routine is called by yacc when an error is detected.
  344. */
  345. LOCAL void yyerror (string)
  346.     char *string;
  347.     {
  348.     if (semError) /* semantic errors have already been reported */
  349. return;
  350.     /* print error depending on what look-ahead token is */
  351.     switch (yychar)
  352. {
  353. case U_SYMBOL: /* U_SYM not at beginning of line */
  354.     printf ("undefined symbol: %sn", (char *) yylval.value.rv);
  355.     break;
  356. case LEX_ERROR:      /* lex should have already reported the problem */
  357.     break;
  358. default:
  359.     if (usymFlag)    /* leading U_SYM was followed by invalid assign */
  360. printf ("undefined symbol: %sn", (char *)usymVal.value.rv);
  361.     else
  362. printf ("%sn", string);
  363.     break;
  364. }
  365.     }
  366. /*******************************************************************************
  367. *
  368. * rvOp - sets rhs of yyval to evaluated expression
  369. */
  370. LOCAL void rvOp (pY1, op, pY2)
  371.     VALUE *pY1;
  372.     int op;
  373.     VALUE *pY2;
  374.     {
  375.     VALUE yy;
  376.     yy = evalExp (pY1, op, pY2);
  377.     setRv (&yyval, &yy);
  378.     }
  379. /*******************************************************************************
  380. *
  381. * assign - make assignment of new value to a cell
  382. */
  383. LOCAL void assign (pLv, pRv)
  384.     FAST VALUE *pLv; /* lhs to be assigned into */
  385.     FAST VALUE *pRv; /* rhs value */
  386.     {
  387.     VALUE val;
  388.     /* verify that lv can be assigned to, then make the assignment */
  389.     if (checkLv (pLv) && checkRv (pRv))
  390. {
  391. (void)getRv (pRv, &val);
  392. /* make value agree in type */
  393. pLv->type = pRv->type;
  394. typeConvert (&val, pLv->type, RHS);
  395. switch (pLv->type)
  396.     {
  397.     case T_BYTE:
  398. * (char *)getLv (pLv) = val.value.byte;
  399. break;
  400.     case T_WORD:
  401. * (short *)getLv (pLv) = val.value.word;
  402. break;
  403.     case T_INT:
  404. *getLv (pLv) = val.value.rv;
  405. break;
  406. #ifndef _WRS_NO_TGT_SHELL_FP
  407.     case T_FLOAT:
  408. * (float *)getLv (pLv) = val.value.fp;
  409. break;
  410.     case T_DOUBLE:
  411. * (double *)getLv (pLv) = val.value.dp;
  412. break;
  413. #endif /* _WRS_NO_TGT_SHELL_FP */
  414.     default:
  415. printf ("bad assignment.n");
  416. SET_ERROR;
  417.     }
  418. }
  419.     else
  420. {
  421. printf ("bad assignment.n");
  422. SET_ERROR;
  423. }
  424.     }
  425. /*******************************************************************************
  426. *
  427. * newString - allocate and copy a string
  428. */
  429. LOCAL int newString (string)
  430.     char *string;
  431.     {
  432.     int length    = strlen (string) + 1;
  433.     char *address = (char *) malloc ((unsigned) length);
  434.     if (address == NULL)
  435. {
  436. printf ("not enough memory for new string.n");
  437. SET_ERROR;
  438. }
  439.     else
  440. bcopy (string, address, length);
  441.     return ((int)address);
  442.     }
  443. /*******************************************************************************
  444. *
  445. * newSym - allocate a new symbol and add to symbol table
  446. */
  447. LOCAL VALUE newSym (name, type)
  448.     char *name;
  449.     TYPE type;
  450.     {
  451.     VALUE value;
  452.     void *address = (void *) malloc (sizeof (double));
  453.     if (address == NULL)
  454. {
  455. printf ("not enough memory for new variable.n");
  456. SET_ERROR;
  457. }
  458.     else if (symAdd (sysSymTbl, name, (char *) address, (N_BSS | N_EXT),
  459.                      symGroupDefault) != OK)
  460. {
  461. free ((char *) address);
  462. printf ("can't add '%s' to system symbol table - error = 0x%x.n",
  463. name, errnoGet());
  464. SET_ERROR;
  465. }
  466.     else
  467. {
  468. printf ("new symbol "%s" added to symbol table.n", name);
  469. value.side = LHS;
  470. value.type = type;
  471. value.value.lv = (int *) address;
  472. }
  473.     return (value);
  474.     }
  475. /*******************************************************************************
  476. *
  477. * printSym - print symbolic value
  478. */
  479. LOCAL void printSym (val, prefix, suffix)
  480.     FAST int val;
  481.     char *prefix;
  482.     char *suffix;
  483.     {
  484.     void *    symVal;  /* symbol value      */
  485.     SYMBOL_ID symId;   /* symbol identifier */
  486.     char *    name;    /* symbol name       */
  487.     char      demangled [MAX_SYS_SYM_LEN + 1];
  488.     char *    nameToPrint;
  489.     /* Only search for symbol value and print symbol name if value is not -1 */
  490.     
  491.         if ((val != -1) && 
  492.     (symFindSymbol (sysSymTbl, NULL, (void *)val, 
  493.         SYM_MASK_NONE, SYM_MASK_NONE, &symId) == OK) &&
  494.     (symNameGet (symId, &name) == OK) &&
  495.     (symValueGet (symId, &symVal) == OK) &&
  496.     (symVal != 0) && ((val - (int)symVal) < 0x1000))
  497.     {
  498.     printf (prefix);
  499.     nameToPrint = cplusDemangle(name, demangled, sizeof (demangled));
  500.     if (val == (int) symVal)
  501.         printf ("%s", nameToPrint);
  502.     else
  503.         printf ("%s + 0x%x", nameToPrint, val - (int) symVal);
  504.     printf (suffix);
  505.     }
  506.     
  507.     }
  508. /*******************************************************************************
  509. *
  510. * newArgList - start a new argument list
  511. */
  512. LOCAL VALUE newArgList ()
  513.     {
  514.     VALUE value;
  515.     value.side    = RHS;
  516.     value.type    = T_INT;
  517.     value.value.rv = nArgs;
  518.     return (value);
  519.     }
  520. /*******************************************************************************
  521. *
  522. * addArg - add an argument to an argument list
  523. */
  524. LOCAL void addArg (pArgList, pNewArg)
  525.     VALUE *pArgList;
  526.     FAST VALUE *pNewArg;
  527.     {
  528.     VALUE val;
  529.     int partA;
  530.     int partB;
  531. #if CPU_FAMILY==I960
  532.     int nArgsSave;
  533. #endif
  534. #ifndef _WRS_NO_TGT_SHELL_FP
  535.     BOOL isfloat = pNewArg->type == T_FLOAT || pNewArg->type == T_DOUBLE;
  536. #endif /* _WRS_NO_TGT_SHELL_FP */
  537.     SYMBOL_ID   symId;  /* symbol identifier           */
  538.     SYM_TYPE    sType;  /* place to return symbol type */
  539. #ifndef _WRS_NO_TGT_SHELL_FP
  540.     if (isfloat)
  541. # if CPU_FAMILY!=I960
  542. nArgs++; /* will need an extra arg slot */
  543. # else /* CPU_FAMILY!=I960 */
  544. {
  545. nArgsSave = nArgs;
  546. if (spawnFlag)
  547.     {
  548.     if ((nArgs %2) == 0)
  549.    nArgs++;
  550.     }
  551. else
  552.     {
  553.     nArgs += nArgs % 2; /* conditionally borrow slot to double align */
  554.     nArgs++; /* borrow second slot for double-word value  */
  555.     }
  556. }
  557. # endif /* CPU_FAMILY!=I960 */
  558. #endif /* _WRS_NO_TGT_SHELL_FP */
  559.     if (nArgs == MAX_SHELL_ARGS || 
  560.         (nArgs - pArgList->value.rv) == MAX_FUNC_ARGS)
  561. {
  562. #ifndef _WRS_NO_TGT_SHELL_FP
  563. if (isfloat)
  564. # if CPU_FAMILY!=I960
  565.     nArgs--; /* return borrowed slot */
  566. # else  /* CPU_FAMILY!=I960 */
  567.     nArgs = nArgsSave; /* return borrowed slot(s) */
  568. # endif /* CPU_FAMILY!=I960 */
  569. #endif /* _WRS_NO_TGT_SHELL_FP */
  570. printf ("too many arguments to functions.n");
  571. SET_ERROR;
  572. }
  573.     else
  574. {
  575. /* push arg value on top of arg stack */
  576. (void)getRv (pNewArg, &val);
  577. #ifndef _WRS_NO_TGT_SHELL_FP
  578. if (isfloat)
  579.     {
  580. # if CPU_FAMILY==I960
  581.     if (spawnFlag == FALSE)
  582. # endif /* CPU_FAMILY==I960 */
  583. nArgs--; /* return borrowed slot */
  584.     
  585.     /* put float as integers on argStack */
  586.     doubleToInts (pNewArg->type == T_FLOAT ?
  587.   val.value.fp : val.value.dp,
  588.   &partA, &partB);
  589.     argStack[nArgs++] = partA;
  590.     argStack[nArgs++] = partB;
  591.     }
  592. else if (checkRv (&val))
  593. #else /* _WRS_NO_TGT_SHELL_FP */
  594. if (checkRv (&val))
  595. #endif /* _WRS_NO_TGT_SHELL_FP */
  596.     {
  597.     int rv;
  598.     switch (val.type)
  599. {
  600. case T_BYTE:
  601.     rv = val.value.byte;
  602.     break;
  603. case T_WORD:
  604.     rv = val.value.word;
  605.     break;
  606. case T_INT:
  607.     rv = val.value.rv;
  608.     /* 
  609.      * new symLib api - symbol name lengths are no
  610.      * longer limited 
  611.      */
  612.     if (symFindSymbol (sysSymTbl, NULL, (void *)rv, 
  613.            SYM_MASK_NONE, SYM_MASK_NONE, 
  614.        &symId) == OK)
  615.   symTypeGet (symId, &sType);
  616.     if ((nArgs == 0) && (sType == (N_TEXT + N_EXT)))
  617. spawnFlag = TRUE;
  618.     break;
  619. default:
  620.     rv = 0;
  621.     printf ("addArg: bad type.n");
  622.     SET_ERROR;
  623. }
  624.     argStack[nArgs++] = rv;
  625.     }
  626. }
  627.     }
  628. #ifndef _WRS_NO_TGT_SHELL_FP
  629. /*******************************************************************************
  630. *
  631. * doubleToInts - separate double into two integer parts
  632. */
  633. LOCAL void doubleToInts (d, partA, partB)
  634.     double d;
  635.     int *partA;
  636.     int *partB;
  637.     {
  638.     union 
  639. {
  640. struct
  641.     {
  642.     int a;
  643.     int b;
  644.     } part;
  645. double d;
  646. } val;
  647.     val.d = d;
  648.     *partA = val.part.a;
  649.     *partB = val.part.b;
  650.     }
  651. #endif /* _WRS_NO_TGT_SHELL_FP */
  652. /*******************************************************************************
  653. *
  654. * funcCall - call a function
  655. */
  656. LOCAL VALUE funcCall (pV, pArgList)
  657.     VALUE *pV;
  658.     VALUE *pArgList;
  659.     {
  660.     static int funcStatus; /* status from function calls */
  661.     int a [MAX_FUNC_ARGS];
  662.     VALUE value;
  663.     FAST int i;
  664.     FAST int argNum;
  665.     int oldInFd  = ioGlobalStdGet (STD_IN);
  666.     int oldOutFd = ioGlobalStdGet (STD_OUT);
  667.     FUNCPTR pFunc = (pV->side == LHS) ? (FUNCPTR) (int)getLv (pV)
  668.       : (FUNCPTR) pV->value.rv;
  669. #if ((CPU_FAMILY == ARM) && ARM_THUMB)
  670.     pFunc = (FUNCPTR)((UINT32)pFunc | 1); /* make it a Thumb call */
  671. #endif
  672.     /* get any specified args off stack, or pre-set all args to 0 */
  673.     for (argNum = pArgList->value.rv, i = 0; i < MAX_FUNC_ARGS; argNum++, i++)
  674. {
  675. a [i] = (argNum < nArgs) ? argStack[argNum] : 0;
  676. }
  677.     /* set standard in/out to redirection fds */
  678.     if (redirInFd >= 0)
  679. ioGlobalStdSet (STD_IN, redirInFd);
  680.     if (redirOutFd >= 0)
  681. ioGlobalStdSet (STD_OUT, redirOutFd);
  682.     /* call function and save resulting status */
  683.     errnoSet (funcStatus);
  684.     value.side = RHS;
  685.     value.type = pV->type;
  686.     switch (pV->type)
  687. {
  688. case T_BYTE:
  689. case T_WORD:
  690. case T_INT:
  691.     {
  692.     /* NOTE: THE FOLLOWING ARRAY REFERENCES MUST AGREE WITH THE
  693.      *       MAX_FUNC_ARGS COUNT DEFINED ABOVE IN THIS FILE!
  694.      */
  695.     int rv = (* pFunc) (a[0], a[1], a[2], a[3], a[4], a[5], a[6],
  696. a[7], a[8], a[9], a[10], a[11]);
  697.     switch (pV->type)
  698. {
  699. case T_BYTE:
  700.     value.value.byte = (char) rv;
  701.     break;
  702. case T_WORD:
  703.     value.value.word = (short) rv;
  704.     break;
  705. case T_INT:
  706.     value.value.rv = rv;
  707.     break;
  708. default:
  709.     break;
  710. }
  711.     break;
  712.     }
  713. #ifndef _WRS_NO_TGT_SHELL_FP
  714. case T_FLOAT:
  715.     value.value.fp = (* (float (*)())pFunc) (a[0], a[1], a[2], a[3],
  716. a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11]);
  717.     break;
  718. case T_DOUBLE:
  719.     value.value.dp = (* (double (*)())pFunc) (a[0], a[1], a[2], a[3],
  720. a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11]);
  721.     break;
  722. #endif /* _WRS_NO_TGT_SHELL_FP */
  723. default:
  724.     printf ("funcCall: bad function type.n");
  725.     SET_ERROR;
  726. }
  727.     funcStatus = errnoGet ();
  728.     /* restore original in/out fds */
  729.     if (redirInFd >= 0)
  730. ioGlobalStdSet (STD_IN, oldInFd);
  731.     if (redirOutFd >= 0)
  732. ioGlobalStdSet (STD_OUT, oldOutFd);
  733.     /* arg stack back to previous level */
  734.     nArgs = pArgList->value.rv;
  735.     return (value);
  736.     }
  737. /*******************************************************************************
  738. *
  739. * checkLv - check that a value can be used as left value
  740. */
  741. LOCAL BOOL checkLv (pValue)
  742.     VALUE *pValue;
  743.     {
  744.     if (pValue->side != LHS)
  745. {
  746. printf ("invalid application of 'address of' operator.n");
  747. SET_ERROR;
  748. return (FALSE);
  749. }
  750.     return (TRUE);
  751.     }
  752. /*******************************************************************************
  753. *
  754. * checkRv - check that a value can be used as right value
  755. */
  756. LOCAL BOOL checkRv (pValue)
  757.     VALUE *pValue;
  758.     {
  759.     if (pValue->side == LHS)
  760. return (checkLv (pValue));
  761.     return (TRUE);
  762.     }
  763. /*******************************************************************************
  764. *
  765. * getRv - get a value's right value 
  766. */
  767. LOCAL VALUE *getRv (pValue, pRv)
  768.     FAST VALUE *pValue;
  769.     FAST VALUE *pRv; /* where to put value */
  770.     {
  771.     if (pValue->side == RHS)
  772. *pRv = *pValue;
  773.     else
  774. {
  775. pRv->side = RHS;
  776. pRv->type = pValue->type;
  777. switch (pValue->type)
  778.     {
  779.     case T_BYTE:
  780. pRv->value.byte = *(char *)pValue->value.lv;
  781. break;
  782.     case T_WORD:
  783. pRv->value.word = *(short *)pValue->value.lv;
  784. break;
  785.     case T_INT:
  786. pRv->value.rv = *pValue->value.lv;
  787. break;
  788. #ifndef _WRS_NO_TGT_SHELL_FP
  789.     case T_FLOAT:
  790. pRv->value.fp = *(float *)pValue->value.lv;
  791. break;
  792.     case T_DOUBLE:
  793. pRv->value.dp = *(double *)pValue->value.lv;
  794. break;
  795. #endif /* _WRS_NO_TGT_SHELL_FP */
  796.     default:
  797. printf ("getRv: invalid rhs.");
  798. SET_ERROR;
  799.     }
  800. }
  801.     return (pRv);
  802.     }
  803. /*******************************************************************************
  804. *
  805. * getLv - get a value's left value (address)
  806. */
  807. LOCAL int *getLv (pValue)
  808.     VALUE *pValue;
  809.     {
  810.     return (checkLv (pValue) ? pValue->value.lv : 0);
  811.     }
  812. /*******************************************************************************
  813. *
  814. * setLv - set a lv
  815. */
  816. LOCAL void setLv (pVal1, pVal2)
  817.     FAST VALUE *pVal1;
  818.     FAST VALUE *pVal2;
  819.     {
  820.     if (pVal2->side == LHS)
  821. {
  822. printf ("setLv: invalid lhs.n");
  823. SET_ERROR;
  824. }
  825.     if ((int)pVal2->type != (int)T_INT)
  826. {
  827. printf ("setLv: type conflict.n");
  828. SET_ERROR;
  829. }
  830.     pVal1->side     = LHS;
  831.     pVal1->type     = pVal2->type;
  832.     pVal1->value.lv = (int *)pVal2->value.rv;
  833.     }
  834. /*******************************************************************************
  835. *
  836. * setRv - set the rv
  837. */
  838. LOCAL void setRv (pVal1, pVal2)
  839.     FAST VALUE *pVal1;
  840.     FAST VALUE *pVal2;
  841.     {
  842.     pVal1->side = RHS;
  843.     pVal1->type = pVal2->type;
  844.     switch (pVal2->type)
  845. {
  846. case T_BYTE:
  847.     pVal1->value.byte = (pVal2->side == LHS) ?
  848.     *(char *)pVal2->value.lv : pVal2->value.byte;
  849. case T_WORD:
  850.     pVal1->value.word = (pVal2->side == LHS) ?
  851.     *(short *)pVal2->value.lv : pVal2->value.word;
  852. case T_INT:
  853.     pVal1->value.rv = (pVal2->side == LHS) ?
  854.     *pVal2->value.lv : pVal2->value.rv;
  855.     break;
  856. #ifndef _WRS_NO_TGT_SHELL_FP
  857. case T_FLOAT:
  858.     pVal1->value.fp = (pVal2->side == LHS) ?
  859.     *(float *)pVal2->value.lv : pVal2->value.fp;
  860.     break;
  861. case T_DOUBLE:
  862.     pVal1->value.dp = (pVal2->side == LHS) ?
  863.     *(double *)pVal2->value.lv : pVal2->value.dp;
  864.     break;
  865. #endif /* _WRS_NO_TGT_SHELL_FP */
  866. default:
  867.     printf ("setRv: bad type.n");
  868.     SET_ERROR;
  869. }
  870.     }
  871. /*******************************************************************************
  872. *
  873. * printLv - print left-hand side value
  874. *
  875. * "ssss + xxx = xxxx"
  876. */
  877. LOCAL void printLv (pValue)
  878.     VALUE *pValue;
  879.     {
  880.     FAST int *lv = getLv (pValue);
  881.     printSym ((int) lv, "", " = ");
  882.     printf ("0x%x", (UINT) lv);
  883.     }
  884. /*******************************************************************************
  885. *
  886. * printRv - print right-hand side value
  887. *
  888. * The format for integers is:
  889. *
  890. * "nnnn = xxxx = 'c' = ssss + nnn"
  891. *                           ^ only if nn < LIMIT for some ssss
  892. *                 ^ only if value is printable
  893. */
  894. LOCAL void printRv (pValue)
  895.     VALUE *pValue;
  896.     {
  897.     VALUE val;
  898.     int rv;
  899.     (void)getRv (pValue, &val);
  900.     switch (pValue->type)
  901. {
  902. case T_BYTE:
  903.     rv = val.value.byte;
  904.     goto caseT_INT;
  905. case T_WORD:
  906.     rv = val.value.word;
  907.     goto caseT_INT;
  908. case T_INT:
  909.     rv = val.value.rv;
  910.     /* drop through */
  911. caseT_INT:
  912.     printf ("%d = 0x%x", rv, rv);
  913.     if (isascii (rv) && isprint (rv))
  914. printf (" = '%c'", rv);
  915.     printSym (rv, " = ", "");
  916.     break;
  917. #ifndef _WRS_NO_TGT_SHELL_FP
  918. case T_FLOAT:
  919.     printf ("%g", val.value.fp);
  920.     break;
  921. case T_DOUBLE:
  922.     printf ("%g", val.value.dp);
  923.     break;
  924. #endif /* _WRS_NO_TGT_SHELL_FP */
  925. default:
  926.     printf ("printRv: bad type.n");
  927.     SET_ERROR;
  928. }
  929.     }
  930. /*******************************************************************************
  931. *
  932. * printValue - print out value
  933. */
  934. LOCAL void printValue (pValue)
  935.     FAST VALUE *pValue;
  936.     {
  937.     if (pValue->side == LHS)
  938. {
  939. if (checkLv (pValue) && checkRv (pValue))
  940.     {
  941.     printLv (pValue);
  942.     printf (": value = ");
  943.     printRv (pValue);
  944.     printf ("n");
  945.     }
  946. else
  947.     {
  948.     printf ("invalid lhs.n");
  949.     SET_ERROR;
  950.     }
  951. }
  952.     else if (checkRv (pValue))
  953. {
  954. printf ("value = ");
  955. printRv (pValue);
  956. printf ("n");
  957. }
  958.     else
  959. {
  960. printf ("invalid rhs.n");
  961. SET_ERROR;
  962. }
  963.     }
  964. /* TYPE SUPPORT */
  965. LOCAL VALUE evalUnknown ();
  966. LOCAL VALUE evalByte ();
  967. LOCAL VALUE evalWord ();
  968. LOCAL VALUE evalInt ();
  969. LOCAL VALUE evalFloat ();
  970. LOCAL VALUE evalDouble ();
  971. typedef struct /* EVAL_TYPE */
  972.     {
  973.     VALUE (*eval) ();
  974.     } EVAL_TYPE;
  975. LOCAL EVAL_TYPE evalType [] =
  976.     {
  977.     /* eval type */
  978.     /* --------------- -------------- */
  979.       { evalUnknown, /* T_UNKNOWN*/ },
  980.       { evalByte, /* T_BYTE   */ },
  981.       { evalWord, /* T_WORD   */ },
  982.       { evalInt, /* T_INT    */ },
  983. #ifndef _WRS_NO_TGT_SHELL_FP
  984.       { evalFloat, /* T_FLOAT  */ },
  985.       { evalDouble, /* T_DOUBLE */ },
  986. #endif /* _WRS_NO_TGT_SHELL_FP */
  987.     };
  988. /*******************************************************************************
  989. *
  990. * evalExp - evaluate expression
  991. */
  992. LOCAL VALUE evalExp (pValue1, op, pValue2)
  993.     VALUE *pValue1;
  994.     int op;
  995.     VALUE *pValue2;
  996.     {
  997.     VALUE *p1 = pValue1;
  998.     VALUE *p2 = pValue2;
  999.     if (pValue2 == NULLVAL) /* unary expresions must set pValue2 to something */
  1000. p2 = pValue2 = pValue1;
  1001.     /* make sure values have the same type */
  1002.     if ((int)p1->type > (int)p2->type)
  1003. typeConvert (p2, p1->type, p1->side);
  1004.     else
  1005. typeConvert (p1, p2->type, p2->side);
  1006.     return ((evalType[(int)pValue1->type].eval) (pValue1, op, pValue2));
  1007.     }
  1008. /*******************************************************************************
  1009. *
  1010. * evalUnknown - evaluate for unknown result
  1011. *
  1012. * ARGSUSED
  1013. */
  1014. LOCAL VALUE evalUnknown (pValue1, op, pValue2)
  1015.     VALUE *pValue1;
  1016.     int op;
  1017.     VALUE *pValue2;
  1018.     {
  1019.     printf ("evalUnknown: bad evaluation.n");
  1020.     SET_ERROR;
  1021.     return (*pValue1); /* have to return something */
  1022.     }
  1023. /*******************************************************************************
  1024. *
  1025. * evalByte - evaluate for byte result
  1026. */
  1027. LOCAL VALUE evalByte (pValue1, op, pValue2)
  1028.     VALUE *pValue1;
  1029.     int op;
  1030.     VALUE *pValue2;
  1031.     {
  1032.     VALUE *p1 = pValue1;
  1033.     VALUE *p2 = pValue2;
  1034.     VALUE result;
  1035.     /* evaluate as integers and then convert back */
  1036.     typeConvert (p1, T_INT, RHS);
  1037.     typeConvert (p2, T_INT, RHS);
  1038.     result = evalInt (p1, op, p2);
  1039.     typeConvert (&result, T_BYTE, RHS);
  1040.     return (result);
  1041.     }
  1042. /*******************************************************************************
  1043. *
  1044. * evalWord - evaluate for word result
  1045. */
  1046. LOCAL VALUE evalWord (pValue1, op, pValue2)
  1047.     VALUE *pValue1;
  1048.     int op;
  1049.     VALUE *pValue2;
  1050.     {
  1051.     VALUE *p1 = pValue1;
  1052.     VALUE *p2 = pValue2;
  1053.     VALUE result;
  1054.     /* evaluate as integers and then convert back */
  1055.     typeConvert (p1, T_INT, RHS);
  1056.     typeConvert (p2, T_INT, RHS);
  1057.     result = evalInt (p1, op, p2);
  1058.     typeConvert (&result, T_WORD, RHS);
  1059.     return (result);
  1060.     }
  1061. /*******************************************************************************
  1062. *
  1063. * evalInt - evaluate for integer result
  1064. */
  1065. LOCAL VALUE evalInt (pValue1, op, pValue2)
  1066.     VALUE *pValue1;
  1067.     int op;
  1068.     VALUE *pValue2;
  1069.     {
  1070. #define OP_INT(op) rv = e1 op e2; break
  1071. #define OP_INT_U(op) rv = op e1; break
  1072.     FAST int e1 = pValue1->value.rv;
  1073.     FAST int e2 = pValue2->value.rv;
  1074.     FAST int rv;
  1075.     VALUE result;
  1076.     switch (op)
  1077. {
  1078. case ADDA:
  1079. case '+':
  1080.     OP_INT(+);
  1081. case SUBA:
  1082. case '-':
  1083.     OP_INT(-);
  1084. case MULA:
  1085. case '*':
  1086.     OP_INT(*);
  1087. case DIVA:
  1088. case '/':
  1089.     OP_INT(/);
  1090. case '!':
  1091.     OP_INT_U(!);
  1092. case '~':
  1093.     OP_INT_U(~);
  1094. case MODA:
  1095. case '%':
  1096.     OP_INT(%);
  1097. case ANDA:
  1098. case '&':
  1099.     OP_INT(&);
  1100. case XORA:
  1101. case '^':
  1102.     OP_INT(^);
  1103. case ORA:
  1104. case '|':
  1105.     OP_INT(|);
  1106. case '<':
  1107.     OP_INT(<);
  1108. case '>':
  1109.     OP_INT(>);
  1110. case OR:
  1111.     OP_INT(||);
  1112. case AND:
  1113.     OP_INT(&&);
  1114. case EQ:
  1115.     OP_INT(==);
  1116. case NE:
  1117.     OP_INT(!=);
  1118. case GE:
  1119.     OP_INT(>=);
  1120. case LE:
  1121.     OP_INT(<=);
  1122. case INCR:
  1123.     OP_INT_U(++);
  1124. case DECR:
  1125.     OP_INT_U(--);
  1126. case SHLA:
  1127. case ROT_LEFT:
  1128.     OP_INT(<<);
  1129. case SHRA:
  1130. case ROT_RIGHT:
  1131.     OP_INT(>>);
  1132. case UMINUS:
  1133.     OP_INT_U(-);
  1134. default:
  1135.     rv = 0;
  1136.     printf ("operands have incompatible types.n");
  1137.     SET_ERROR;
  1138. }
  1139.     result.side     = RHS;
  1140.     result.type     = pValue1->type;
  1141.     result.value.rv = rv;
  1142.     return (result);
  1143.     }
  1144. #ifndef _WRS_NO_TGT_SHELL_FP
  1145. /*******************************************************************************
  1146. *
  1147. * evalFloat - evaluate for float result
  1148. */
  1149. LOCAL VALUE evalFloat (pValue1, op, pValue2)
  1150.     VALUE *pValue1;
  1151.     int op;
  1152.     VALUE *pValue2;
  1153.     {
  1154.     VALUE *p1 = pValue1;
  1155.     VALUE *p2 = pValue2;
  1156.     VALUE result;
  1157.     /* evaluate as doubles and then convert back */
  1158.     typeConvert (p1, T_DOUBLE, RHS);
  1159.     typeConvert (p2, T_DOUBLE, RHS);
  1160.     result = evalDouble (p1, op, p2);
  1161.     typeConvert (&result, T_FLOAT, RHS);
  1162.     return (result);
  1163.     }
  1164. /*******************************************************************************
  1165. *
  1166. * evalDouble - evaluate for double result
  1167. */
  1168. LOCAL VALUE evalDouble (pValue1, op, pValue2)
  1169.     VALUE *pValue1;
  1170.     int op;
  1171.     VALUE *pValue2;
  1172.     {
  1173. #define OP_DOUBLE(op) dp = e1 op e2; break
  1174. #define OP_DOUBLE_U(op) dp = op e1; break
  1175.     FAST double e1 = pValue1->value.dp;
  1176.     FAST double e2 = pValue2->value.dp;
  1177.     FAST double dp;
  1178.     VALUE result;
  1179.     switch (op)
  1180. {
  1181. case ADDA:
  1182. case '+':
  1183.     OP_DOUBLE(+);
  1184. case SUBA:
  1185. case '-':
  1186.     OP_DOUBLE(-);
  1187. case MULA:
  1188. case '*':
  1189.     OP_DOUBLE(*);
  1190. case DIVA:
  1191. case '/':
  1192.     OP_DOUBLE(/);
  1193. case '!':
  1194.     OP_DOUBLE_U(!);
  1195. case '<':
  1196.     OP_DOUBLE(<);
  1197. case '>':
  1198.     OP_DOUBLE(>);
  1199. case OR:
  1200.     OP_DOUBLE(||);
  1201. case AND:
  1202.     OP_DOUBLE(&&);
  1203. case EQ:
  1204.     OP_DOUBLE(==);
  1205. case NE:
  1206.     OP_DOUBLE(!=);
  1207. case GE:
  1208.     OP_DOUBLE(>=);
  1209. case LE:
  1210.     OP_DOUBLE(<=);
  1211. case INCR:
  1212.     OP_DOUBLE_U(++);
  1213. case DECR:
  1214.     OP_DOUBLE_U(--);
  1215. case UMINUS:
  1216.     OP_DOUBLE_U(-);
  1217. default:
  1218.     dp = 0;
  1219.     printf ("operands have incompatible types.n");
  1220.     SET_ERROR;
  1221. }
  1222.     result.side     = RHS;
  1223.     result.type     = T_DOUBLE;
  1224.     result.value.dp = dp;
  1225.     return (result);
  1226.     }
  1227. #endif /* _WRS_NO_TGT_SHELL_FP */
  1228. /* TYPE CONVERSION */
  1229. LOCAL void convUnknown ();
  1230. LOCAL void convByte ();
  1231. LOCAL void convWord ();
  1232. LOCAL void convInt ();
  1233. #ifndef _WRS_NO_TGT_SHELL_FP
  1234. LOCAL void convFloat ();
  1235. LOCAL void convDouble ();
  1236. #endif /* _WRS_NO_TGT_SHELL_FP */
  1237. typedef void (*VOID_FUNCPTR) (); /* ptr to a function returning void */
  1238. LOCAL VOID_FUNCPTR convType [] =
  1239.     {
  1240.     /*  conversion type     */
  1241.     /*  ---------- ----------- */
  1242. convUnknown, /* T_UNKNOWN*/
  1243. convByte, /* T_BYTE   */
  1244. convWord, /* T_WORD   */
  1245. convInt, /* T_INT    */
  1246. #ifndef _WRS_NO_TGT_SHELL_FP
  1247. convFloat, /* T_FLOAT  */
  1248. convDouble, /* T_DOUBLE */
  1249. #endif /* _WRS_NO_TGT_SHELL_FP */
  1250.     };
  1251. /*******************************************************************************
  1252. *
  1253. * typeConvert - change value to specified type
  1254. */
  1255. LOCAL void typeConvert (pValue, type, side)
  1256.     FAST VALUE *pValue;
  1257.     TYPE type;
  1258.     SIDE side;
  1259.     {
  1260.     if (side == FHS)
  1261. {
  1262. pValue->side = RHS;
  1263. pValue->type = type;
  1264. }
  1265.     else if (side == RHS)
  1266. {
  1267. if (pValue->side == LHS)
  1268.     pValue->type = type;
  1269. else
  1270.     (convType [(int) type]) (pValue);
  1271. }
  1272.     else if (pValue->side == LHS)
  1273. pValue->type = type;
  1274.     else
  1275. {
  1276. printf ("typeConvert: bad type.n");
  1277. SET_ERROR;
  1278. }
  1279.     }
  1280. /*******************************************************************************
  1281. *
  1282. * convUnknown - convert value to unknown
  1283. *
  1284. * ARGSUSED
  1285. */
  1286. LOCAL void convUnknown (pValue)
  1287.     VALUE *pValue;
  1288.     {
  1289.     printf ("convUnknown: bad type.n");
  1290.     SET_ERROR;
  1291.     }
  1292. /*******************************************************************************
  1293. *
  1294. * convByte - convert value to byte
  1295. */
  1296. LOCAL void convByte (pValue)
  1297.     FAST VALUE *pValue;
  1298.     {
  1299.     char value;
  1300.     if ((int)pValue->type > (int)T_BYTE)
  1301. {
  1302. convWord (pValue);
  1303. value = pValue->value.word;
  1304. pValue->value.byte = value;
  1305. pValue->type = T_BYTE;
  1306. }
  1307.     }
  1308. /*******************************************************************************
  1309. *
  1310. * convWord - convert value to word
  1311. */
  1312. LOCAL void convWord (pValue)
  1313.     FAST VALUE *pValue;
  1314.     {
  1315.     short value;
  1316.     if ((int)pValue->type < (int)T_WORD)
  1317. {
  1318. value = pValue->value.byte;
  1319. pValue->value.word = value;
  1320. pValue->type = T_WORD;
  1321. }
  1322.     else if ((int)pValue->type > (int)T_WORD)
  1323. {
  1324. convInt (pValue);
  1325. value = pValue->value.rv;
  1326. pValue->value.word = value;
  1327. pValue->type = T_WORD;
  1328. }
  1329.     }
  1330. /*******************************************************************************
  1331. *
  1332. * convInt - convert value to integer
  1333. */
  1334. LOCAL void convInt (pValue)
  1335.     FAST VALUE *pValue;
  1336.     {
  1337.     int value;
  1338.     if ((int)pValue->type < (int)T_INT)
  1339. {
  1340. convWord (pValue);
  1341. value = pValue->value.word;
  1342. pValue->value.rv = value;
  1343. pValue->type = T_INT;
  1344. }
  1345.     else if ((int)pValue->type > (int)T_INT)
  1346. {
  1347. #ifndef _WRS_NO_TGT_SHELL_FP
  1348. convFloat (pValue);
  1349. value = pValue->value.fp;
  1350. pValue->value.rv = value;
  1351. pValue->type = T_INT;
  1352. #endif /* _WRS_NO_TGT_SHELL_FP */
  1353. }
  1354.     }
  1355. #ifndef _WRS_NO_TGT_SHELL_FP
  1356. /*******************************************************************************
  1357. *
  1358. * convFloat - convert value to float
  1359. */
  1360. LOCAL void convFloat (pValue)
  1361.     FAST VALUE *pValue;
  1362.     {
  1363.     float value;
  1364.     if ((int)pValue->type < (int)T_FLOAT)
  1365. {
  1366. convInt (pValue);
  1367. value = pValue->value.rv;
  1368. pValue->value.fp = value;
  1369. pValue->type = T_FLOAT;
  1370. }
  1371.     else if ((int)pValue->type > (int)T_FLOAT)
  1372. {
  1373. convDouble (pValue);
  1374. value = pValue->value.dp;
  1375. pValue->value.fp = value;
  1376. pValue->type = T_FLOAT;
  1377. }
  1378.     }
  1379. /*******************************************************************************
  1380. *
  1381. * convDouble - convert value to double
  1382. */
  1383. LOCAL void convDouble (pValue)
  1384.     FAST VALUE *pValue;
  1385.     {
  1386.     double value;
  1387.     if ((int)pValue->type < (int)T_DOUBLE)
  1388. {
  1389. convFloat (pValue);
  1390. value = pValue->value.fp;
  1391. pValue->value.dp = value;
  1392. pValue->type = T_DOUBLE;
  1393. }
  1394.     }
  1395. #endif /* _WRS_NO_TGT_SHELL_FP */