home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 13 / 13.iso / p / p024 / 12.img / ADS1.LIB / CALEXPR.C < prev    next >
Encoding:
C/C++ Source or Header  |  1992-09-10  |  23.2 KB  |  937 lines

  1. /*****************************************************************************
  2.       CALEXPR.C
  3.       (C) ¬⌐┼v 1988-1992  Autodesk ñ╜Ñq
  4.  
  5.       Ñ╗╡{ªíñwÑ╤ Autodesk ñ╜Ñq╡∙ÑU¬⌐┼v, ╢╚⌐≤ñU¡z▒í¬pñUÑi▒┬╗P▒zíu│\ÑiívíC
  6.       ╗╒ñUñú▒oÑHÑ⌠ª≤º╬ªí╡oªµ⌐╬ÑX¬⌐ª╣╡{ªí¬║íu¡∞⌐l╜Xív; ª²ñ╣│\▒zªb»S⌐w¡lÑ═
  7.       ¬║ñuº@ñW╡▓ªXª╣╡{ªí¬║íuÑ╪¬║╜Xív¿╧Ñ╬íCª│├÷│o├■¡lÑ═ñuº@¬║▒°Ñ≤ªpñU:
  8.  
  9.       ( i)  │]¡pñW╗Pñuº@ñW¼╥»┬║Θ░w╣∩ Autodesk ñ╜Ñq¬║▓ú½~íC
  10.       (ii)  ╕ⁿª│íu¬⌐┼v  (C) 1988-1992  Autodesk ñ╜Ñqív¬║¬⌐┼v│qºiíC
  11.  
  12.  
  13.  
  14.       AUTODESKñ╜Ñq┤ú¿╤ª╣╡{ªí╢╚¿╤º@íu├■ªⁿív¬║░╤ª╥, ª╙ÑBñú▒╞░úª│Ñ⌠ª≤┐∙╗~¬║
  15.       Ñi»αíCAUTODESKñ╜Ñq»Sª╣º_╗{Ñ⌠ª≤»S⌐wÑ╬│~ñº╛A║┘⌐╩, ÑHñ╬░╙╖~╛P░Γ⌐╥┴⌠ºt
  16.       ÑX¿π¬║½O├╥íCAUTODESKñ╜ÑqªP«╔ÑτñúÑX¿πª╣╡{ªí░⌡ªµ«╔ñ@⌐wñú╖|íuññ┬_ív⌐╬
  17.       íuº╣Ñ■╡L╗~ív¬║½O├╥íC
  18.  
  19.  
  20.   Description: The syntactic analysis of the expression based on
  21.                the context-free LL(1) grammar.
  22.  
  23.   Notes:
  24.  
  25.   The syntax of the expression:
  26.  
  27.   EXPR   = TERM   + TERM    ...
  28.   TERM   = POWER  * POWER  *...
  29.   POWER  = FACTOR ^ FACTOR ^...
  30.   FACTOR = +- NUMBER
  31.               VECTOR
  32.               (EXPR)
  33.               FUNC(EXPR,EXPR,...)
  34.               ......
  35.  
  36.   VECTOR = [EXPR,EXPR,EXPR]
  37.  
  38. *****************************************************************************/
  39.  
  40.  
  41. /****************************************************************************/
  42. /*  INCLUDES                                                                */
  43. /****************************************************************************/
  44.  
  45. #define R12_EXTLISPADS 1              /* Enable extended AutoLISP/ADS funcs */
  46.  
  47. #include "cal.h"
  48.  
  49.  
  50. /****************************************************************************/
  51. /*  STATIC FUNCTIONS                                                        */
  52. /****************************************************************************/
  53.  
  54. static int  check_overflow    _((vector_real_int *value, int n));
  55. static void vector            _((vector_real_int *value));
  56. static void AutoLISP_variable _((vector_real_int *value));
  57. static void factor            _((vector_real_int *value));
  58. static void power             _((vector_real_int *value));
  59. static void term              _((vector_real_int *value));
  60. static void expr              _((vector_real_int *value));
  61.  
  62.  
  63. /****************************************************************************/
  64. /*.doc check_overflow(internal)*/
  65. /*+
  66.   Check whether overflow occured.
  67. -*/
  68. /****************************************************************************/
  69.  
  70.  
  71. static int
  72. /*FCN*/check_overflow(value, n)
  73.  
  74.   vector_real_int *value;             /* The value to check           */
  75.   int             n;                  /* Error to display if overflow */
  76.                                       /* 0=Default error message      */
  77. {
  78.     if (cal_err)
  79.         return(FALSE);
  80.  
  81.     if (n == 0) {
  82.         n = 23;                       /* Default error message */
  83.     }
  84.  
  85.     if ((errno == EDOM) || (errno == ERANGE)) {
  86.         error(n, NULL);
  87.         return(FALSE);
  88.     }
  89.     if (value->type == vector_type) {
  90.         if ((value->v[X] == HUGE_VAL) ||
  91.             (value->v[Y] == HUGE_VAL) ||
  92.             (value->v[Z] == HUGE_VAL))   {
  93.             error(n, NULL);
  94.             return(FALSE);
  95.         } else {
  96.             return(TRUE);
  97.         }
  98.     } else if (value->r == HUGE_VAL) {
  99.         error(n, NULL);
  100.         return(FALSE);
  101.     } else {
  102.         return(TRUE);
  103.     }
  104. } /*check_overflow*/
  105.  
  106.  
  107. /****************************************************************************/
  108. /*.doc vector(internal)*/
  109. /*+
  110.   Parsing the nonterminal symbol VECTOR=[EXPR,EXPR,EXPR].
  111. -*/
  112. /****************************************************************************/
  113.  
  114.  
  115. static void
  116. /*FCN*/vector(value)
  117.  
  118.   vector_real_int *value;
  119. {
  120.     ads_point       v, c;
  121.     double          r, fi, theta;
  122.     vector_real_int sub_expr;
  123.     int             cylindrical_cs, spherical_cs, relative_cs, world_cs;
  124.     struct resbuf   buff;
  125.  
  126.     if (cal_err)
  127.         return;
  128.  
  129.     cylindrical_cs = spherical_cs = relative_cs = world_cs = FALSE;
  130.     v[X] = v[Y] = v[Z] = 0.0;
  131.  
  132.     cal_next_symbol();
  133.  
  134.     if (cal_lex.sym == at_sym) {
  135.         relative_cs = TRUE;
  136.         cal_next_symbol();
  137.     }
  138.  
  139.     if (cal_lex.sym == asterisk_sym) {
  140.         world_cs = TRUE;
  141.         cal_next_symbol();
  142.     }
  143.  
  144.     if ((cal_lex.sym != comma_sym)    &&
  145.         (cal_lex.sym != lessthan_sym) &&
  146.         (cal_lex.sym != rbracket_sym)) {
  147.  
  148.         expr(&sub_expr);
  149.         if (cal_err)
  150.             return;
  151.  
  152.         if ((sub_expr.type != real_type) &&
  153.             (sub_expr.type != int_type)) {
  154.             error(6, NULL);
  155.             return;
  156.         }
  157.         v[X] = sub_expr.r;
  158.     }
  159.  
  160.     if ((cal_lex.sym == comma_sym) || (cal_lex.sym == lessthan_sym)) {
  161.         cylindrical_cs = (cal_lex.sym == lessthan_sym);
  162.         cal_next_symbol();
  163.  
  164.     } else if (cal_lex.sym == rbracket_sym) {
  165.         goto Vector_completed;
  166.     } else {
  167.         error(7, NULL);
  168.         return;
  169.     }
  170.  
  171.     if ((cal_lex.sym != comma_sym)    &&
  172.         (cal_lex.sym != lessthan_sym) &&
  173.         (cal_lex.sym != rbracket_sym)) {
  174.  
  175.         expr(&sub_expr);
  176.         if (cal_err)
  177.             return;
  178.  
  179.         if ((sub_expr.type != real_type) &&
  180.             (sub_expr.type != int_type)) {
  181.             error(6, NULL);
  182.             return;
  183.         }
  184.         v[Y] = sub_expr.r;
  185.     }
  186.  
  187.     if ((cal_lex.sym == comma_sym) || (cal_lex.sym == lessthan_sym)) {
  188.  
  189.         spherical_cs = (cal_lex.sym == lessthan_sym);
  190.         cal_next_symbol();
  191.  
  192.     } else if (cal_lex.sym == rbracket_sym) {
  193.         goto Vector_completed;
  194.     } else {
  195.         error(7, NULL);
  196.         return;
  197.     }
  198.  
  199.     if (cal_lex.sym != rbracket_sym) {
  200.  
  201.         expr(&sub_expr);
  202.  
  203.         if (cal_err)
  204.             return;
  205.  
  206.         if ((sub_expr.type != real_type) &&
  207.             (sub_expr.type != int_type)) {
  208.             error(6, NULL);
  209.             return;
  210.         }
  211.         v[Z] = sub_expr.r;
  212.     }
  213.  
  214. Vector_completed:
  215.  
  216.     if (cal_lex.sym == rbracket_sym) {
  217.         cal_next_symbol();
  218.     } else  {
  219.         error(8, NULL);
  220.         return;
  221.     }
  222.  
  223.     value->type = vector_type;
  224.  
  225.     if (relative_cs) {
  226.         ads_getvar("LASTPOINT", &buff);
  227.  
  228.         if (world_cs) {
  229.             sa_u2w(buff.resval.rpoint, c);
  230.         } else {
  231.             CPY_PNT(c, buff.resval.rpoint);
  232.         }
  233.     } else {
  234.         c[X] = c[Y] = c[Z] = 0.0;;
  235.     }
  236.  
  237.     if (!cylindrical_cs && !spherical_cs) {
  238.         ADD_PNT(v, c, v);
  239.  
  240.     } else if (cylindrical_cs && !spherical_cs) {
  241.         r  = v[X];
  242.         fi = v[Y] * DEGRAD;
  243.  
  244.         v[X] = c[X] + r * cos(fi);
  245.         v[Y] = c[Y] + r * sin(fi);
  246.         v[Z] = c[Z] + v[Z];
  247.  
  248.     } else if (cylindrical_cs && spherical_cs) {
  249.         r     = v[X];
  250.         fi    = v[Y] * DEGRAD;
  251.         theta = v[Z] * DEGRAD;
  252.  
  253.         v[X] = c[X] + r * cos(fi) * cos(theta);
  254.         v[Y] = c[Y] + r * sin(fi) * cos(theta);
  255.         v[Z] = c[Z] + r * sin(theta);
  256.     } else {
  257.         error(35, NULL);
  258.         return;
  259.     }
  260.  
  261.     if (world_cs) {
  262.         sa_w2u(v, v);
  263.     }
  264.  
  265.     CPY_PNT(value->v, v);
  266.     check_overflow(value, 0);
  267.  
  268. } /*vector*/
  269.  
  270.  
  271. /****************************************************************************/
  272. /*.doc AutoLISP_variable(internal)*/
  273. /*+
  274.   Get value of AutoLISP variable.
  275. -*/
  276. /****************************************************************************/
  277.  
  278.  
  279. static void
  280. /*FCN*/AutoLISP_variable(value)
  281.  
  282.   vector_real_int *value;
  283. {
  284.     struct resbuf *rb = NULL;
  285.     int           success;
  286.  
  287.     if (cal_err)
  288.         return;
  289.  
  290.     success = ads_getsym(cal_lex.id, &rb);
  291.  
  292.     if ((success != RTNORM) || (rb == NULL)) {
  293.         error(45, cal_lex.id);
  294.         return;
  295.     }
  296.  
  297.     /* Check the resbuf type */
  298.  
  299.     switch (rb->restype) {
  300.  
  301.     case RTSHORT:
  302.         value->type = int_type;
  303.         value->r    = (double)rb->resval.rint;
  304.         break;
  305.     case RTREAL:
  306.         value->type = real_type;
  307.         value->r    = rb->resval.rreal;
  308.         break;
  309.     case RTPOINT:
  310.     case RT3DPOINT:
  311.         value->type = vector_type;
  312.         CPY_PNT(value->v, rb->resval.rpoint);
  313.         break;
  314.     default:
  315.         error(43, cal_lex.id);
  316.         return;
  317.     } /*switch*/
  318.  
  319.     ads_relrb(rb);
  320.     cal_next_symbol();
  321.  
  322. } /*AutoLISP_variable*/
  323.  
  324.  
  325. /****************************************************************************/
  326. /*.doc factor(internal)*/
  327. /*+
  328.   Parsing the nonterminal symbol FACTOR = NUMBER | FUNC() | VARIABLE |...
  329. -*/
  330. /****************************************************************************/
  331.  
  332.  
  333. static void
  334. /*FCN*/factor(value)
  335.  
  336.   vector_real_int *value;
  337. {
  338.     vector_real_int f;
  339.     int             success;
  340.     int             is_minus;
  341.  
  342.     if (cal_err)
  343.         return;
  344.  
  345.     /* Check the leading unary plus or minus */
  346.  
  347.     if (cal_lex.sym == minus_sym) {
  348.         is_minus = TRUE;
  349.         cal_next_symbol();
  350.     } else if (cal_lex.sym == plus_sym) {
  351.         cal_next_symbol();
  352.     } else {
  353.         is_minus = FALSE;
  354.     }
  355.  
  356.     if (cal_lex.sym == ident_sym) {
  357.         AutoLISP_variable(&f);
  358.  
  359.     } else if (cal_lex.sym == func_sym) {
  360.  
  361.         vector_real_int par[MAX_FUNC_PARAM];
  362.         int             nop;
  363.         void            (*func_ptr)();
  364.         char            func_name[MAX_SYMBOL_LENGTH+1];
  365.         int             i;
  366.  
  367.         func_ptr = cal_lex.func_ptr;
  368.         strcpy(func_name, cal_lex.id);
  369.         nop = 0;
  370.         cal_next_symbol();
  371.  
  372.         if (cal_lex.sym == lparent_sym) {
  373.             cal_next_symbol();
  374.  
  375.             while (!cal_err                     &&
  376.                    (cal_lex.sym != rparent_sym) &&
  377.                    (nop < MAX_FUNC_PARAM)) {
  378.  
  379.                 expr(&par[nop++]);
  380.  
  381.                 if (cal_lex.sym == comma_sym) {
  382.                     cal_next_symbol();
  383.                 } else if (cal_lex.sym != rparent_sym) {
  384.                     error(49, func_name);
  385.                     return;
  386.                 }
  387.             } /*while*/
  388.  
  389.             if (cal_lex.sym != rparent_sym) {
  390.                 error(50, func_name);
  391.                 return;
  392.             } else {
  393.                 cal_next_symbol();
  394.             }
  395.         } /*if*/
  396.  
  397.         if (cal_err)
  398.             return;
  399.  
  400.         /* Pass the actual function arguments */
  401.  
  402.         no_of_params = nop;
  403.         for (i = 0; i < nop; i++) {
  404.             params[i] = par[i];
  405.         }
  406.  
  407.         /* Call the function */
  408.  
  409.         (*func_ptr)();
  410.         if (cal_err)
  411.             return;
  412.  
  413.         f = result;
  414.  
  415.     } else if (cal_lex.sym == real_sym) {
  416.         f.type = real_type;
  417.         f.r    = cal_lex.real_num;
  418.         cal_next_symbol();
  419.  
  420.     } else if (cal_lex.sym == int_sym) {
  421.         f.type = int_type;
  422.         f.r    = cal_lex.real_num;
  423.         cal_next_symbol();
  424.  
  425.     } else if (cal_lex.sym == pi_sym) {
  426.         f.type = real_type;
  427.         f.r    = PI;
  428.         cal_next_symbol();
  429.  
  430.     } else if (cal_lex.sym == getvar_sym) {
  431.         struct resbuf buff;
  432.  
  433.         cal_next_symbol();
  434.         if (cal_lex.sym != lparent_sym) {
  435.             error(26, "GETVAR(AutoCAD_system_variable)");
  436.             return;
  437.         }
  438.  
  439.         cal_next_symbol();
  440.         if (cal_lex.sym != ident_sym) {
  441.             error(26, "GETVAR(AutoCAD_system_variable)");
  442.             return;
  443.         }
  444.         success = ads_getvar(cal_lex.id, &buff);
  445.         if (success != RTNORM) {
  446.             error(32, cal_lex.id);
  447.             return;
  448.         }
  449.  
  450.         switch (buff.restype) {
  451.  
  452.         case RTPOINT:
  453.         case RT3DPOINT:
  454.             f.type = vector_type;
  455.             CPY_PNT(f.v, buff.resval.rpoint);
  456.             break;
  457.         case RTREAL:
  458.         case RTANG:
  459.         case RTORINT:
  460.             f.type = real_type;
  461.             f.r    = buff.resval.rreal;
  462.             break;
  463.         case RTSHORT:
  464.             f.type = int_type;
  465.             f.r    = buff.resval.rint;
  466.             break;
  467.         case RTLONG:
  468.             f.type = int_type;
  469.             f.r    = buff.resval.rlong;
  470.             break;
  471.         default:
  472.             if (buff.restype == RTSTR)
  473.                 free(buff.resval.rstring);
  474.             error(33, NULL);
  475.             return;
  476.         } /*switch*/
  477.  
  478.         cal_next_symbol();
  479.         if (cal_lex.sym != rparent_sym) {
  480.             error(5, NULL);
  481.             return;
  482.         }
  483.         cal_next_symbol();
  484.  
  485.     } else if (cal_lex.sym == cvunit_sym) {
  486.         char from_unit[MAX_LINE_LENGTH];
  487.         char to_unit[MAX_LINE_LENGTH];
  488.  
  489.         cal_next_symbol();
  490.         if (cal_lex.sym != lparent_sym) {
  491.             error(63, NULL);
  492.             return;
  493.         }
  494.         cal_next_symbol();
  495.  
  496.         expr(&f);
  497.         if (cal_err)
  498.             return;
  499.  
  500.         if (cal_lex.sym != comma_sym) {
  501.             error(63, NULL);
  502.             return;
  503.         }
  504.  
  505.         cal_next_symbol();
  506.         if (cal_lex.sym != ident_sym) {
  507.             error(63, NULL);
  508.             return;
  509.         }
  510.  
  511.         strcpy(from_unit, cal_lex.id);
  512.  
  513.         cal_next_symbol();
  514.         if (cal_lex.sym != comma_sym) {
  515.             error(63, NULL);
  516.             return;
  517.         }
  518.  
  519.         cal_next_symbol();
  520.         if (cal_lex.sym != ident_sym) {
  521.             error(63, NULL);
  522.             return;
  523.         }
  524.  
  525.         strcpy(to_unit, cal_lex.id);
  526.  
  527.         cal_next_symbol();
  528.         if (cal_lex.sym != rparent_sym) {
  529.             error(63, NULL);
  530.             return;
  531.         }
  532.  
  533.         switch (f.type) {
  534.  
  535.         case real_type:
  536.         case int_type:
  537.             f.type = real_type;
  538.             success = ads_cvunit(f.r, from_unit, to_unit, &f.r);
  539.             break;
  540.         case vector_type:
  541.             success = ads_cvunit(f.v[X], from_unit, to_unit, &f.v[X]);
  542.             if (success != RTNORM)
  543.                 break;
  544.             success = ads_cvunit(f.v[Y], from_unit, to_unit, &f.v[Y]);
  545.             if (success != RTNORM)
  546.                 break;
  547.             success = ads_cvunit(f.v[Z], from_unit, to_unit, &f.v[Z]);
  548.             if (success != RTNORM)
  549.                 break;
  550.             break;
  551.         default:
  552.             return;
  553.         } /*switch*/
  554.  
  555.         if (success != RTNORM) {
  556.             error(64, NULL);
  557.             return;
  558.         }
  559.         cal_next_symbol();
  560.  
  561.     } else if (cal_lex.sym == at_sym) {
  562.         struct resbuf buff;
  563.  
  564.         f.type = vector_type;
  565.         ads_getvar("LASTPOINT", &buff);
  566.         CPY_PNT(f.v, buff.resval.rpoint);
  567.         cal_next_symbol();
  568.  
  569.     } else if (cal_lex.sym == lparent_sym) {
  570.         cal_next_symbol();
  571.         expr(&f);
  572.         if (cal_err)
  573.             return;
  574.         if (cal_lex.sym == rparent_sym) {
  575.             cal_next_symbol();
  576.         } else {
  577.             error(5, NULL);
  578.             return;
  579.         }
  580.  
  581.     } else if (cal_lex.sym == lbracket_sym) {
  582.         vector(&f);
  583.     } else if (cal_lex.sym == no_sym) {
  584.         error(9, NULL);
  585.         return;
  586.     } else {
  587.         error(10, NULL);
  588.         return;
  589.     }
  590.  
  591.     check_overflow(&f, 0);
  592.  
  593.     if (cal_err)
  594.         return;
  595.  
  596.     if (is_minus) {
  597.         if (f.type == vector_type) {
  598.             f.v[X] = -f.v[X];
  599.             f.v[Y] = -f.v[Y];
  600.             f.v[Z] = -f.v[Z];
  601.         } else {
  602.             f.r = -f.r;
  603.         }
  604.     }
  605.  
  606.     *value = f;
  607. } /*factor*/
  608.  
  609.  
  610. /****************************************************************************/
  611. /*.doc power(internal)*/
  612. /*+
  613.   Parsing the nonterminal symbol POWER = FACTOR^FACTOR^...
  614. -*/
  615. /****************************************************************************/
  616.  
  617.  
  618. static void
  619. /*FCN*/power(value)
  620.  
  621.   vector_real_int *value;
  622. {
  623.     vector_real_int p, f;
  624.  
  625.     if (cal_err)
  626.         return;
  627.  
  628.     factor(&p);
  629.  
  630.     if (cal_err)
  631.         return;
  632.  
  633.     while (cal_lex.sym == caret_sym) {
  634.         cal_next_symbol();
  635.         factor(&f);
  636.         if (cal_err)
  637.             return;
  638.         if ((p.type == vector_type) || (f.type == vector_type)) {
  639.             error(16, NULL);
  640.             return;
  641.         }
  642.  
  643.         p.type = real_type;
  644.  
  645.         if (p.r == 0.0) {
  646.             ;                         /*p.r = 0.0*/
  647.         } else if (f.r == 0.0) {
  648.             p.r = 1.0;
  649.         } else {
  650.             if ((p.r < 0.0) && (f.r != (int)f.r)) {
  651.                 error(17, NULL);
  652.                 return;
  653.             }
  654.             p.r = pow(p.r, f.r);
  655.             if (!check_overflow(&p, 25))
  656.                 return;
  657.         }
  658.     } /*while*/
  659.  
  660.     check_overflow(&p, 0);
  661.  
  662.     *value = p;
  663. } /*power*/
  664.  
  665.  
  666. /****************************************************************************/
  667. /*.doc term(internal)*/
  668. /*+
  669.   Parsing the nonterminal symbol TERM = POWER*POWER*...
  670. -*/
  671. /****************************************************************************/
  672.  
  673.  
  674. static void
  675. /*FCN*/term(value)
  676.  
  677.   vector_real_int *value;
  678. {
  679.     vector_real_int t, p, tmp;
  680.     symbol_type     oper;
  681.  
  682.     if (cal_err)
  683.         return;
  684.  
  685.     power(&t);
  686.     if (cal_err)
  687.         return;
  688.  
  689.     while ((cal_lex.sym == asterisk_sym) ||
  690.            (cal_lex.sym == slash_sym)    ||
  691.            (cal_lex.sym == ampersand_sym)) {
  692.  
  693.         oper = cal_lex.sym;
  694.         cal_next_symbol();
  695.         power(&p);
  696.  
  697.         if (cal_err)
  698.             return;
  699.  
  700.         switch (oper) {
  701.  
  702.         case asterisk_sym:
  703.             if ((t.type != vector_type) && (p.type != vector_type)) {
  704.                 if (p.type == real_type) {
  705.                     t.type = real_type;
  706.                 }
  707.                 t.r *= p.r;
  708.  
  709.             } else if ((t.type == vector_type) && (p.type == vector_type)) {
  710.                 t.type = real_type;
  711.                 t.r    = DOTPROD(t.v, p.v);
  712.  
  713.             } else if ((t.type == vector_type) && (p.type != vector_type)) {
  714.                 t.type = vector_type;
  715.                 t.v[X] *= p.r;
  716.                 t.v[Y] *= p.r;
  717.                 t.v[Z] *= p.r;
  718.             } else {
  719.                 t.type = vector_type;
  720.                 t.v[X] = p.v[X] * t.r;
  721.                 t.v[Y] = p.v[Y] * t.r;
  722.                 t.v[Z] = p.v[Z] * t.r;
  723.             }
  724.             break;
  725.  
  726.         case slash_sym:
  727.             if (fabs(p.r) < EPS) {
  728.                 error(18, NULL);
  729.                 return;
  730.             }
  731.             if ((t.type != vector_type) && (p.type != vector_type)) {
  732.                 t.type = real_type;
  733.                 t.r /= p.r;
  734.  
  735.             } else if ((t.type == vector_type) && (p.type != vector_type)) {
  736.                 t.v[X] /= p.r;
  737.                 t.v[Y] /= p.r;
  738.                 t.v[Z] /= p.r;
  739.             } else {
  740.                 error(19, NULL);
  741.                 return;
  742.             }
  743.             break;
  744.  
  745.         case ampersand_sym:           /*Cross product*/
  746.             if ((t.type == vector_type) && (p.type == vector_type)) {
  747.                 tmp.type = vector_type;
  748.                 tmp.v[X] = t.v[Y] * p.v[Z] - t.v[Z] * p.v[Y];
  749.                 tmp.v[Y] = t.v[Z] * p.v[X] - t.v[X] * p.v[Z];
  750.                 tmp.v[Z] = t.v[X] * p.v[Y] - t.v[Y] * p.v[X];
  751.                 t = tmp;
  752.             } else {
  753.                 error(20, NULL);
  754.                 return;
  755.             }
  756.             break;
  757.         } /*switch*/
  758.  
  759.         if(!check_overflow(&t, 0))
  760.             return;
  761.     } /*while*/
  762.  
  763.     check_overflow(&t, 0);
  764.  
  765.     *value = t;
  766. } /*term*/
  767.  
  768.  
  769. /****************************************************************************/
  770. /*.doc expr(internal)*/
  771. /*+
  772.     Parsing the nonterminal symbol EXPR = TERM+TERM+...
  773. -*/
  774. /****************************************************************************/
  775.  
  776.  
  777. static void
  778. /*FCN*/expr(value)
  779.  
  780.   vector_real_int *value;
  781. {
  782.     vector_real_int e, t;
  783.     symbol_type     oper;
  784.  
  785.     if (cal_err)
  786.         return;
  787.  
  788.     term(&e);
  789.     if (cal_err)
  790.         return;
  791.  
  792.     while ((cal_lex.sym == plus_sym) || (cal_lex.sym == minus_sym)) {
  793.  
  794.         oper = cal_lex.sym;
  795.         cal_next_symbol();
  796.  
  797.         term(&t);
  798.  
  799.         if (cal_err)
  800.             return;
  801.  
  802.         switch (oper) {
  803.  
  804.         case plus_sym:
  805.             if ((e.type != vector_type) && (t.type != vector_type)) {
  806.                 if (t.type == real_type) {
  807.                     e.type = real_type;
  808.                 }
  809.                 e.r += t.r;
  810.  
  811.             } else if ((e.type == vector_type) && (t.type == vector_type)) {
  812.                 ADD_PNT(e.v, e.v, t.v);
  813.             } else {
  814.                 error(21, NULL);
  815.                 return;
  816.             }
  817.             break;
  818.  
  819.         case minus_sym:
  820.             if ((e.type != vector_type) && (t.type != vector_type)) {
  821.                 if (t.type == real_type) {
  822.                     e.type = real_type;
  823.                 }
  824.                 e.r -= t.r;
  825.  
  826.             } else if ((e.type == vector_type) && (t.type == vector_type)) {
  827.                 SUB_PNT(e.v, e.v, t.v);
  828.             } else {
  829.                 error(21, NULL);
  830.                 return;
  831.             }
  832.         } /*switch*/
  833.  
  834.         if (!check_overflow(&e, 0))
  835.             return;
  836.     } /*while*/
  837.  
  838.     check_overflow(&e, 0);
  839.  
  840.     *value = e;
  841. } /*expr*/
  842.  
  843.  
  844. /****************************************************************************/
  845. /*.doc cal_evaluate_expression(external)*/
  846. /*+
  847.   The top-level expression-evalution function.
  848.  
  849.   The function returns TRUE if succeeds, or FALSE if it fails.
  850. -*/
  851. /****************************************************************************/
  852.  
  853.  
  854. int
  855. /*FCN*/cal_evaluate_expression(line, value)
  856.  
  857.   char            *line;              /* Input expression as a string */
  858.   vector_real_int *value;             /* Returned value of expression */
  859. {
  860.     vector_real_int val;
  861.     char            id[MAX_SYMBOL_LENGTH+1];
  862.     struct resbuf   rb;
  863.     int             success;
  864.  
  865.     cal_lex_start(line);
  866.  
  867.     /* Check whether the expression begins with 'VAR=' assignment */
  868.  
  869.     id[0] = EOS;
  870.     if (cal_lex.sym == ident_sym) {
  871.         strcpy(id, cal_lex.id);       /* It might be assignment */
  872.         cal_next_symbol();
  873.         if (cal_err)
  874.             return(FALSE);
  875.  
  876.         if (cal_lex.sym != equal_sym) {
  877.             id[0] = EOS;              /* No, it isn't assignment */
  878.             cal_lex_start(line);
  879.         } else {
  880.             cal_next_symbol();
  881.         }
  882.     }
  883.     if (cal_err)
  884.         return(FALSE);
  885.  
  886.     expr(&val);                       /* Start the expression evaluation */
  887.  
  888.     if (cal_err)
  889.         return(FALSE);
  890.  
  891.     if (cal_lex.sym != no_sym) {
  892.         error(10, NULL);
  893.         return(FALSE);
  894.     }
  895.  
  896.     if ((val.type == int_type) &&
  897.         ((val.r > 32767) || (val.r < -32768))) {
  898.         error(41, NULL);
  899.         return(FALSE);
  900.     }
  901.  
  902.     /* Assign value of expression to AutoLISP variable, if available */
  903.  
  904.     if (id[0] != EOS) {
  905.         switch (val.type) {
  906.         case int_type:
  907.             rb.restype = RTSHORT;
  908.             rb.resval.rint = (int)val.r;
  909.             break;
  910.         case real_type:
  911.             rb.restype = RTREAL;
  912.             rb.resval.rreal = val.r;
  913.             break;
  914.         case vector_type:
  915.             rb.restype = RT3DPOINT;
  916.             CPY_PNT(rb.resval.rpoint, val.v);
  917.             break;
  918.         default:
  919.             error(-443, NULL);
  920.             return(FALSE);
  921.         } /*switch*/
  922.  
  923.         rb.rbnext = NULL;
  924.  
  925.         success = ads_putsym(id, &rb);
  926.         if (success != RTNORM) {
  927.             error(29, id);
  928.             return(FALSE);
  929.         }
  930.     } /*if*/
  931.  
  932.     *value = val;
  933.     return(TRUE);
  934. } /*evaluate_expression*/
  935.  
  936.  
  937.