Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

308 lines
7.7 KiB

  1. /************************************************************************/
  2. /* */
  3. /* RCPP - Resource Compiler Pre-Processor for NT system */
  4. /* */
  5. /* P0EXPR.C - Expression routines for Pre-Processor */
  6. /* */
  7. /* AUTHOR - Ralph Ryan, Sept. 16, 1982 */
  8. /* 06-Dec-90 w-BrianM Update for NT from PM SDK RCPP */
  9. /* */
  10. /************************************************************************/
  11. /*
  12. * DESCRIPTION
  13. * Evaluate the constant expression. Since these routines are
  14. * all recursively coupled, it is clearer NOT to document them
  15. * with the standard header. Instead, BML (British Meta Language,
  16. * a BNF like meta language) will be given for each "production"
  17. * of this recursive descent parser.
  18. *
  19. * Note - Sure, yeah, right. Frankly, I'm frightened! (w-BrianM)
  20. ************************************************************************/
  21. #include <stdio.h>
  22. #include "rcpptype.h"
  23. #include "rcppdecl.h"
  24. #include "rcppext.h"
  25. #include "grammar.h"
  26. /************************************************************************/
  27. /* Local Function Prototypes */
  28. /************************************************************************/
  29. long and(void);
  30. long andif(void);
  31. long constant(void);
  32. long constexpr(void);
  33. long eqset(void);
  34. long mult(void);
  35. long or(void);
  36. long orelse(void);
  37. long plus(void);
  38. long prim(void);
  39. long relation(void);
  40. long shift(void);
  41. long xor(void);
  42. /************************************************************************/
  43. /* File Global Variables */
  44. /************************************************************************/
  45. long Currval = 0;
  46. static int Parencnt = 0;
  47. /************************************************************************/
  48. /* do_constexpr() */
  49. /************************************************************************/
  50. long do_constexpr(void)
  51. {
  52. REG long val;
  53. Parencnt = 0;
  54. Currtok = L_NOTOKEN;
  55. val = constexpr();
  56. if( Currtok == L_RPAREN ) {
  57. if( Parencnt-- == 0 ) {
  58. Msg_Temp = GET_MSG(1012);
  59. SET_MSG (Msg_Text, Msg_Temp, "(");
  60. fatal(1012); /* missing left paren */
  61. }
  62. }
  63. else if( Currtok != L_NOTOKEN ) {
  64. Msg_Temp = GET_MSG(4067);
  65. SET_MSG (Msg_Text, Msg_Temp, PPifel_str);
  66. warning(4067);
  67. }
  68. if( Parencnt > 0 ) {
  69. Msg_Temp = GET_MSG(4012);
  70. SET_MSG (Msg_Text, Msg_Temp, ")");
  71. fatal(4012); /* missing right paren */
  72. }
  73. return(val);
  74. }
  75. /************************************************************************/
  76. /* constexpr ::= orelse [ '?' orelse ':' orelse ]; */
  77. /************************************************************************/
  78. long constexpr(void)
  79. {
  80. REG long val;
  81. REG long val1;
  82. long val2;
  83. val = orelse();
  84. if( nextis(L_QUEST) ) {
  85. val1 = orelse();
  86. if( nextis(L_COLON) )
  87. val2 = orelse();
  88. return(val ? val1 : val2);
  89. }
  90. return(val);
  91. }
  92. /************************************************************************/
  93. /* orelse ::= andif [ '||' andif ]* ; */
  94. /************************************************************************/
  95. long orelse(void)
  96. {
  97. REG long val;
  98. val = andif();
  99. while(nextis(L_OROR))
  100. val = andif() || val;
  101. return(val);
  102. }
  103. /************************************************************************/
  104. /* andif ::= or [ '&&' or ]* ; */
  105. /************************************************************************/
  106. long andif(void)
  107. {
  108. REG long val;
  109. val = or();
  110. while(nextis(L_ANDAND))
  111. val = or() && val;
  112. return(val);
  113. }
  114. /************************************************************************/
  115. /* or ::= xor [ '|' xor]* ; */
  116. /************************************************************************/
  117. long or(void)
  118. {
  119. REG long val;
  120. val = xor();
  121. while( nextis(L_OR) )
  122. val |= xor();
  123. return(val);
  124. }
  125. /************************************************************************/
  126. /* xor ::= and [ '^' and]* ; */
  127. /************************************************************************/
  128. long xor(void)
  129. {
  130. REG long val;
  131. val = and();
  132. while( nextis(L_XOR) )
  133. val ^= and();
  134. return(val);
  135. }
  136. /************************************************************************/
  137. /* and ::= eqset [ '&' eqset]* ; */
  138. /************************************************************************/
  139. long and(void)
  140. {
  141. REG long val;
  142. val = eqset();
  143. while( nextis(L_AND) )
  144. val &= eqset();
  145. return(val);
  146. }
  147. /************************************************************************/
  148. /* eqset ::= relation [ ('==' | '!=') eqset] ; */
  149. /************************************************************************/
  150. long eqset(void)
  151. {
  152. REG long val;
  153. val = relation();
  154. if( nextis(L_EQUALS) )
  155. return(val == relation());
  156. if( nextis(L_NOTEQ) )
  157. return(val != relation());
  158. return(val);
  159. }
  160. /************************************************************************/
  161. /* relation ::= shift [ ('<' | '>' | '<=' | '>=' ) shift] ; */
  162. /************************************************************************/
  163. long relation(void)
  164. {
  165. REG long val;
  166. val = shift();
  167. if( nextis(L_LT) )
  168. return(val < shift());
  169. if( nextis(L_GT) )
  170. return(val > shift());
  171. if( nextis(L_LTEQ) )
  172. return(val <= shift());
  173. if( nextis(L_GTEQ) )
  174. return(val >= shift());
  175. return(val);
  176. }
  177. /************************************************************************/
  178. /* shift ::= plus [ ('<< | '>>') plus] ; */
  179. /************************************************************************/
  180. long shift(void)
  181. {
  182. REG long val;
  183. val = plus();
  184. if( nextis(L_RSHIFT) )
  185. return(val >> plus());
  186. if( nextis(L_LSHIFT) )
  187. return(val << plus());
  188. return(val);
  189. }
  190. /************************************************************************/
  191. /* plus ::= mult [ ('+' | '-') mult ]* ; */
  192. /************************************************************************/
  193. long plus(void)
  194. {
  195. REG long val;
  196. val = mult();
  197. for(;;) {
  198. if( nextis(L_PLUS) )
  199. val += mult();
  200. else if( nextis(L_MINUS) )
  201. val -= mult();
  202. else
  203. break;
  204. }
  205. return(val);
  206. }
  207. /************************************************************************/
  208. /* mult ::= prim [ ('*' | '/' | '%' ) prim ]* ; */
  209. /************************************************************************/
  210. long mult(void)
  211. {
  212. REG long val;
  213. val = prim();
  214. for(;;) {
  215. if( nextis(L_MULT) )
  216. val *= prim();
  217. else if( nextis(L_DIV) )
  218. val /= prim();
  219. else if( nextis(L_MOD) )
  220. val %= prim();
  221. else
  222. break;
  223. }
  224. return(val);
  225. }
  226. /************************************************************************/
  227. /* prim ::= constant | ( '!' | '~' | '-' ) constant */
  228. /************************************************************************/
  229. long prim(void)
  230. {
  231. if( nextis(L_EXCLAIM) )
  232. return( ! constant());
  233. else if( nextis(L_TILDE) )
  234. return( ~ constant() );
  235. else if( nextis(L_MINUS) )
  236. return(-constant());
  237. else
  238. return(constant());
  239. }
  240. /************************************************************************/
  241. /* constant - at last, a terminal symbol | '(' constexpr ')' */
  242. /************************************************************************/
  243. long constant(void)
  244. {
  245. REG long val;
  246. if( nextis(L_LPAREN) ) {
  247. Parencnt++;
  248. val = constexpr();
  249. if( nextis(L_RPAREN) ) {
  250. Parencnt--;
  251. return(val);
  252. }
  253. else {
  254. Msg_Temp = GET_MSG(1012);
  255. SET_MSG (Msg_Text, Msg_Temp, ")");
  256. fatal (1012);
  257. }
  258. }
  259. else if( ! nextis(L_CINTEGER) ) {
  260. Msg_Temp = GET_MSG(1017);
  261. SET_MSG (Msg_Text, Msg_Temp);
  262. fatal(1017); /* invalid integer constant expression */
  263. }
  264. return(Currval);
  265. }