Source code of Windows XP (NT5)
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.

355 lines
9.1 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 "rc.h"
  22. /************************************************************************/
  23. /* Local Function Prototypes */
  24. /************************************************************************/
  25. long and(void);
  26. long andif(void);
  27. long constant(void);
  28. long constexpr(void);
  29. long eqset(void);
  30. long mult(void);
  31. long or(void);
  32. long orelse(void);
  33. long plus(void);
  34. long prim(void);
  35. long relation(void);
  36. long shift(void);
  37. long xor(void);
  38. /************************************************************************/
  39. /* File Global Variables */
  40. /************************************************************************/
  41. long Currval = 0;
  42. static int Parencnt = 0;
  43. /************************************************************************/
  44. /* do_constexpr() */
  45. /************************************************************************/
  46. long
  47. do_constexpr(
  48. void
  49. )
  50. {
  51. REG long val;
  52. Parencnt = 0;
  53. Currtok = L_NOTOKEN;
  54. val = constexpr();
  55. if( Currtok == L_RPAREN ) {
  56. if( Parencnt-- == 0 ) {
  57. Msg_Temp = GET_MSG(1012);
  58. SET_MSG (Msg_Text, sizeof(Msg_Text), Msg_Temp, "(");
  59. fatal(1012); /* missing left paren */
  60. }
  61. } else if( Currtok != L_NOTOKEN ) {
  62. Msg_Temp = GET_MSG(4067);
  63. SET_MSG (Msg_Text, sizeof(Msg_Text), Msg_Temp, PPifel_str);
  64. warning(4067);
  65. }
  66. if( Parencnt > 0 ) {
  67. Msg_Temp = GET_MSG(4012);
  68. SET_MSG (Msg_Text, sizeof(Msg_Text), Msg_Temp, ")");
  69. fatal(4012); /* missing right paren */
  70. }
  71. return(val);
  72. }
  73. /************************************************************************/
  74. /* constexpr ::= orelse [ '?' orelse ':' orelse ]; */
  75. /************************************************************************/
  76. long
  77. constexpr(
  78. void
  79. )
  80. {
  81. REG long val;
  82. REG long val1;
  83. long val2;
  84. val = orelse();
  85. if( nextis(L_QUEST) ) {
  86. val1 = orelse();
  87. if( nextis(L_COLON) )
  88. val2 = orelse();
  89. return(val ? val1 : val2);
  90. }
  91. return(val);
  92. }
  93. /************************************************************************/
  94. /* orelse ::= andif [ '||' andif ]* ; */
  95. /************************************************************************/
  96. long
  97. orelse(
  98. void
  99. )
  100. {
  101. REG long val;
  102. val = andif();
  103. while(nextis(L_OROR))
  104. val = andif() || val;
  105. return(val);
  106. }
  107. /************************************************************************/
  108. /* andif ::= or [ '&&' or ]* ; */
  109. /************************************************************************/
  110. long
  111. andif(
  112. void
  113. )
  114. {
  115. REG long val;
  116. val = or();
  117. while(nextis(L_ANDAND))
  118. val = or() && val;
  119. return(val);
  120. }
  121. /************************************************************************/
  122. /* or ::= xor [ '|' xor]* ; */
  123. /************************************************************************/
  124. long
  125. or(
  126. void
  127. )
  128. {
  129. REG long val;
  130. val = xor();
  131. while( nextis(L_OR) )
  132. val |= xor();
  133. return(val);
  134. }
  135. /************************************************************************/
  136. /* xor ::= and [ '^' and]* ; */
  137. /************************************************************************/
  138. long
  139. xor(
  140. void
  141. )
  142. {
  143. REG long val;
  144. val = and();
  145. while( nextis(L_XOR) )
  146. val ^= and();
  147. return(val);
  148. }
  149. /************************************************************************/
  150. /* and ::= eqset [ '&' eqset]* ; */
  151. /************************************************************************/
  152. long
  153. and(
  154. void
  155. )
  156. {
  157. REG long val;
  158. val = eqset();
  159. while( nextis(L_AND) )
  160. val &= eqset();
  161. return(val);
  162. }
  163. /************************************************************************/
  164. /* eqset ::= relation [ ('==' | '!=') eqset] ; */
  165. /************************************************************************/
  166. long
  167. eqset(
  168. void
  169. )
  170. {
  171. REG long val;
  172. val = relation();
  173. if( nextis(L_EQUALS) )
  174. return(val == relation());
  175. if( nextis(L_NOTEQ) )
  176. return(val != relation());
  177. return(val);
  178. }
  179. /************************************************************************/
  180. /* relation ::= shift [ ('<' | '>' | '<=' | '>=' ) shift] ; */
  181. /************************************************************************/
  182. long
  183. relation(
  184. void
  185. )
  186. {
  187. REG long val;
  188. val = shift();
  189. if( nextis(L_LT) )
  190. return(val < shift());
  191. if( nextis(L_GT) )
  192. return(val > shift());
  193. if( nextis(L_LTEQ) )
  194. return(val <= shift());
  195. if( nextis(L_GTEQ) )
  196. return(val >= shift());
  197. return(val);
  198. }
  199. /************************************************************************/
  200. /* shift ::= plus [ ('<< | '>>') plus] ; */
  201. /************************************************************************/
  202. long
  203. shift(
  204. void
  205. )
  206. {
  207. REG long val;
  208. val = plus();
  209. if( nextis(L_RSHIFT) )
  210. return(val >> plus());
  211. if( nextis(L_LSHIFT) )
  212. return(val << plus());
  213. return(val);
  214. }
  215. /************************************************************************/
  216. /* plus ::= mult [ ('+' | '-') mult ]* ; */
  217. /************************************************************************/
  218. long
  219. plus(
  220. void
  221. )
  222. {
  223. REG long val;
  224. val = mult();
  225. for(;;) {
  226. if( nextis(L_PLUS) )
  227. val += mult();
  228. else if( nextis(L_MINUS) )
  229. val -= mult();
  230. else
  231. break;
  232. }
  233. return(val);
  234. }
  235. /************************************************************************/
  236. /* mult ::= prim [ ('*' | '/' | '%' ) prim ]* ; */
  237. /************************************************************************/
  238. long
  239. mult(
  240. void
  241. )
  242. {
  243. REG long val;
  244. long PrimVal;
  245. val = prim();
  246. for(;;) {
  247. if( nextis(L_MULT) )
  248. val *= prim();
  249. else if( nextis(L_DIV) ) {
  250. PrimVal = prim();
  251. if (PrimVal)
  252. val /= PrimVal;
  253. else
  254. val = PrimVal;
  255. }
  256. else if( nextis(L_MOD) ) {
  257. PrimVal = prim();
  258. if (PrimVal)
  259. val %= PrimVal;
  260. else
  261. val = 0;
  262. }
  263. else
  264. break;
  265. }
  266. return(val);
  267. }
  268. /************************************************************************/
  269. /* prim ::= constant | ( '!' | '~' | '-' ) constant */
  270. /************************************************************************/
  271. long
  272. prim(
  273. void
  274. )
  275. {
  276. if( nextis(L_EXCLAIM) )
  277. return( ! constant());
  278. else if( nextis(L_TILDE) )
  279. return( ~ constant() );
  280. else if( nextis(L_MINUS) )
  281. return(-constant());
  282. else
  283. return(constant());
  284. }
  285. /************************************************************************/
  286. /* constant - at last, a terminal symbol | '(' constexpr ')' */
  287. /************************************************************************/
  288. long
  289. constant(
  290. void
  291. )
  292. {
  293. REG long val;
  294. if( nextis(L_LPAREN) ) {
  295. Parencnt++;
  296. val = constexpr();
  297. if( nextis(L_RPAREN) ) {
  298. Parencnt--;
  299. return(val);
  300. } else {
  301. Msg_Temp = GET_MSG(1012);
  302. SET_MSG (Msg_Text, sizeof(Msg_Text), Msg_Temp, ")");
  303. fatal (1012);
  304. }
  305. } else if( ! nextis(L_CINTEGER) ) {
  306. Msg_Temp = GET_MSG(1017);
  307. SET_MSG (Msg_Text, sizeof(Msg_Text), Msg_Temp);
  308. fatal(1017); /* invalid integer constant expression */
  309. }
  310. return(Currval);
  311. }