Windows NT 4.0 source code leak
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.

304 lines
8.7 KiB

4 years ago
  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 do_constexpr(void)
  47. {
  48. REG long val;
  49. Parencnt = 0;
  50. Currtok = L_NOTOKEN;
  51. val = constexpr();
  52. if( Currtok == L_RPAREN ) {
  53. if( Parencnt-- == 0 ) {
  54. Msg_Temp = GET_MSG(1012);
  55. SET_MSG (Msg_Text, sizeof(Msg_Text), Msg_Temp, "(");
  56. fatal(1012); /* missing left paren */
  57. }
  58. }
  59. else if( Currtok != L_NOTOKEN ) {
  60. Msg_Temp = GET_MSG(4067);
  61. SET_MSG (Msg_Text, sizeof(Msg_Text), Msg_Temp, PPifel_str);
  62. warning(4067);
  63. }
  64. if( Parencnt > 0 ) {
  65. Msg_Temp = GET_MSG(4012);
  66. SET_MSG (Msg_Text, sizeof(Msg_Text), Msg_Temp, ")");
  67. fatal(4012); /* missing right paren */
  68. }
  69. return(val);
  70. }
  71. /************************************************************************/
  72. /* constexpr ::= orelse [ '?' orelse ':' orelse ]; */
  73. /************************************************************************/
  74. long constexpr(void)
  75. {
  76. REG long val;
  77. REG long val1;
  78. long val2;
  79. val = orelse();
  80. if( nextis(L_QUEST) ) {
  81. val1 = orelse();
  82. if( nextis(L_COLON) )
  83. val2 = orelse();
  84. return(val ? val1 : val2);
  85. }
  86. return(val);
  87. }
  88. /************************************************************************/
  89. /* orelse ::= andif [ '||' andif ]* ; */
  90. /************************************************************************/
  91. long orelse(void)
  92. {
  93. REG long val;
  94. val = andif();
  95. while(nextis(L_OROR))
  96. val = andif() || val;
  97. return(val);
  98. }
  99. /************************************************************************/
  100. /* andif ::= or [ '&&' or ]* ; */
  101. /************************************************************************/
  102. long andif(void)
  103. {
  104. REG long val;
  105. val = or();
  106. while(nextis(L_ANDAND))
  107. val = or() && val;
  108. return(val);
  109. }
  110. /************************************************************************/
  111. /* or ::= xor [ '|' xor]* ; */
  112. /************************************************************************/
  113. long or(void)
  114. {
  115. REG long val;
  116. val = xor();
  117. while( nextis(L_OR) )
  118. val |= xor();
  119. return(val);
  120. }
  121. /************************************************************************/
  122. /* xor ::= and [ '^' and]* ; */
  123. /************************************************************************/
  124. long xor(void)
  125. {
  126. REG long val;
  127. val = and();
  128. while( nextis(L_XOR) )
  129. val ^= and();
  130. return(val);
  131. }
  132. /************************************************************************/
  133. /* and ::= eqset [ '&' eqset]* ; */
  134. /************************************************************************/
  135. long and(void)
  136. {
  137. REG long val;
  138. val = eqset();
  139. while( nextis(L_AND) )
  140. val &= eqset();
  141. return(val);
  142. }
  143. /************************************************************************/
  144. /* eqset ::= relation [ ('==' | '!=') eqset] ; */
  145. /************************************************************************/
  146. long eqset(void)
  147. {
  148. REG long val;
  149. val = relation();
  150. if( nextis(L_EQUALS) )
  151. return(val == relation());
  152. if( nextis(L_NOTEQ) )
  153. return(val != relation());
  154. return(val);
  155. }
  156. /************************************************************************/
  157. /* relation ::= shift [ ('<' | '>' | '<=' | '>=' ) shift] ; */
  158. /************************************************************************/
  159. long relation(void)
  160. {
  161. REG long val;
  162. val = shift();
  163. if( nextis(L_LT) )
  164. return(val < shift());
  165. if( nextis(L_GT) )
  166. return(val > shift());
  167. if( nextis(L_LTEQ) )
  168. return(val <= shift());
  169. if( nextis(L_GTEQ) )
  170. return(val >= shift());
  171. return(val);
  172. }
  173. /************************************************************************/
  174. /* shift ::= plus [ ('<< | '>>') plus] ; */
  175. /************************************************************************/
  176. long shift(void)
  177. {
  178. REG long val;
  179. val = plus();
  180. if( nextis(L_RSHIFT) )
  181. return(val >> plus());
  182. if( nextis(L_LSHIFT) )
  183. return(val << plus());
  184. return(val);
  185. }
  186. /************************************************************************/
  187. /* plus ::= mult [ ('+' | '-') mult ]* ; */
  188. /************************************************************************/
  189. long plus(void)
  190. {
  191. REG long val;
  192. val = mult();
  193. for(;;) {
  194. if( nextis(L_PLUS) )
  195. val += mult();
  196. else if( nextis(L_MINUS) )
  197. val -= mult();
  198. else
  199. break;
  200. }
  201. return(val);
  202. }
  203. /************************************************************************/
  204. /* mult ::= prim [ ('*' | '/' | '%' ) prim ]* ; */
  205. /************************************************************************/
  206. long mult(void)
  207. {
  208. REG long val;
  209. val = prim();
  210. for(;;) {
  211. if( nextis(L_MULT) )
  212. val *= prim();
  213. else if( nextis(L_DIV) )
  214. val /= prim();
  215. else if( nextis(L_MOD) )
  216. val %= prim();
  217. else
  218. break;
  219. }
  220. return(val);
  221. }
  222. /************************************************************************/
  223. /* prim ::= constant | ( '!' | '~' | '-' ) constant */
  224. /************************************************************************/
  225. long prim(void)
  226. {
  227. if( nextis(L_EXCLAIM) )
  228. return( ! constant());
  229. else if( nextis(L_TILDE) )
  230. return( ~ constant() );
  231. else if( nextis(L_MINUS) )
  232. return(-constant());
  233. else
  234. return(constant());
  235. }
  236. /************************************************************************/
  237. /* constant - at last, a terminal symbol | '(' constexpr ')' */
  238. /************************************************************************/
  239. long constant(void)
  240. {
  241. REG long val;
  242. if( nextis(L_LPAREN) ) {
  243. Parencnt++;
  244. val = constexpr();
  245. if( nextis(L_RPAREN) ) {
  246. Parencnt--;
  247. return(val);
  248. }
  249. else {
  250. Msg_Temp = GET_MSG(1012);
  251. SET_MSG (Msg_Text, sizeof(Msg_Text), Msg_Temp, ")");
  252. fatal (1012);
  253. }
  254. }
  255. else if( ! nextis(L_CINTEGER) ) {
  256. Msg_Temp = GET_MSG(1017);
  257. SET_MSG (Msg_Text, sizeof(Msg_Text), Msg_Temp);
  258. fatal(1017); /* invalid integer constant expression */
  259. }
  260. return(Currval);
  261. }