INTEXPR.C
上传用户:hlzzc88
上传日期:2007-01-06
资源大小:220k
文件大小:7k
源码类别:

编译器/解释器

开发平台:

Others

  1. /*
  2.  * 68K/386 32-bit C compiler.
  3.  *
  4.  * copyright (c) 1997, David Lindauer
  5.  * 
  6.  * This compiler is intended for educational use.  It may not be used
  7.  * for profit without the express written consent of the author.
  8.  *
  9.  * It may be freely redistributed, as long as this notice remains intact
  10.  * and either the original sources or derived sources 
  11.  * are distributed along with any executables derived from the originals.
  12.  *
  13.  * The author is not responsible for any damages that may arise from use
  14.  * of this software, either idirect or consequential.
  15.  *
  16.  * v1.35 March 1997
  17.  * David Lindauer, gclind01@starbase.spd.louisville.edu
  18.  *
  19.  * Credits to Mathew Brandt for original K&R C compiler
  20.  *
  21.  */
  22. /*
  23.  * Evaluate an expression which should be known at compile time.
  24.  * This uses recursive descent.  It is roughly analogous to the
  25.  * primary expression handler except it returns a value rather than
  26.  * an enode list
  27.  */
  28. #include        <stdio.h>
  29. #include        "expr.h"
  30. #include        "c.h"
  31. #include "errors.h"
  32. extern enum e_sym lastst;
  33. extern char lastid[];
  34. extern long ival;
  35. extern TABLE defsyms;
  36. extern TYP stdint, stdchar,stduns, stdunsigned, stdlong, *head;
  37. extern int prm_cmangle;
  38. static long ieprimary(TYP **tp)   
  39. /*
  40.  * PRimary integer
  41.  *    defined(MACRO)
  42.  *    id
  43.  *    iconst
  44.  *    (cast )intexpr
  45.  *    (intexpr)
  46.  */
  47. {       long     temp=0;
  48.         SYM     *sp;
  49. if (tp)
  50. *tp = &stdint;
  51.         if(lastst == id) {
  52. char *lid = lastid;
  53. if (prm_cmangle)
  54. lid++;
  55.                  sp = gsearch(lastid);
  56.                  if(sp == NULL) {
  57. gensymerror(ERR_UNDEFINED,lastid);
  58.                         getsym();
  59.                         return 0;
  60.                         }
  61.                  if(sp->storage_class != sc_const && sp->tp->type != bt_enum) {
  62.                         generror(ERR_NEEDCONST,0,0);
  63.                         getsym();
  64.                         return 0;
  65.                         }
  66.                  getsym();
  67.                  return sp->value.i;
  68.         }
  69.         else if(lastst == iconst) {
  70.                 temp = ival;
  71.                 getsym();
  72.                 return temp;
  73.                 }
  74.         else if(lastst == lconst) {
  75. if (tp)
  76. *tp = &stdlong;
  77.                 temp = ival;
  78.                 getsym();
  79.                 return temp;
  80.                 }
  81.         else if(lastst == iuconst) {
  82. if (tp)
  83. *tp = &stduns;
  84.                 temp = ival;
  85.                 getsym();
  86.                 return temp;
  87.                 }
  88.         else if(lastst == luconst) {
  89. if (tp)
  90. *tp = &stdunsigned;
  91.                 temp = ival;
  92.                 getsym();
  93.                 return temp;
  94.                 }
  95.         else if(lastst == cconst) {
  96. if (tp)
  97. *tp = &stdchar;
  98.                 temp = ival;
  99.                 getsym();
  100.                 return temp;
  101.                 }
  102. else if (lastst == openpa) {
  103. getsym();
  104. if (castbegin(lastst)) {
  105. decl(0);
  106. decl1();
  107. needpunc(closepa,0);
  108. if (tp)
  109.   *tp = head;
  110. return intexpr(0);
  111. }
  112. else {
  113.    temp = intexpr(tp);
  114. return(temp);
  115. }
  116. }
  117.         getsym();
  118.         generror(ERR_NEEDCONST,0,0);
  119.         return 0;
  120. }
  121. /*
  122.  * Integer unary
  123.  *   - unary
  124.  *   ! unary
  125.  *   ~unary
  126.  *   primary
  127.  */
  128. static long ieunary(TYP **tp)
  129. {
  130. long temp;
  131. switch (lastst) {
  132. case minus:
  133. getsym();
  134. temp = -ieunary(tp);
  135. break;
  136. case not:
  137. getsym();
  138. temp = !ieunary(tp);
  139. break;
  140. case compl:
  141. getsym();
  142. temp = ~ieunary(tp);
  143. break;
  144. default:
  145. temp = ieprimary(tp);
  146. break;
  147. }
  148. return(temp);
  149. }
  150. static long iemultops(TYP **tp)
  151. /* Multiply ops */
  152. {
  153. long val1 = ieunary(tp),val2;
  154. while (lastst == star || lastst == divide || lastst == modop) {
  155. TYP *tp1;
  156. long oper = lastst;
  157. getsym();
  158. val2 = ieunary(&tp1);
  159. switch(oper) {
  160. case star:
  161. val1 = val1 * val2;
  162. break;
  163. case divide:
  164. val1 = val1 / val2;
  165. break;
  166. case modop:
  167. val1 = val1 % val2;
  168. break;
  169. }
  170. if (tp)
  171. *tp = maxsize(*tp,tp1);
  172. }
  173. return(val1);
  174. }
  175. static long ieaddops(TYP **tp)
  176. /* Add ops */
  177. {
  178. long val1 = iemultops(tp),val2;
  179. while (lastst == plus || lastst == minus) {
  180. long oper = lastst;
  181. TYP *tp1;
  182. getsym();
  183. val2 = iemultops(&tp1);
  184. if (oper == plus) 
  185. val1 = val1 + val2;
  186. else
  187. val1 = val1 - val2;
  188. if (tp)
  189. *tp = maxsize(*tp,tp1);
  190. }
  191. return(val1);
  192. }
  193. static long ieshiftops(TYP **tp)
  194. /* Shift ops */
  195. {
  196. long val1 = ieaddops(tp), val2;
  197. while (lastst == lshift || lastst == rshift) {
  198. long oper = lastst;
  199. TYP *tp1;
  200. getsym();
  201. val2 = ieaddops(&tp1);
  202. if (oper == lshift)
  203. val1 <<= val2;
  204. else
  205. val1 >>= val2;
  206. if (tp)
  207. *tp = maxsize(*tp,tp1);
  208. }
  209. return(val1);
  210. }
  211. static long ierelation(TYP **tp)
  212. /* non-eq relations */
  213. {
  214. long val1 = ieshiftops(tp), val2;
  215. while (lastst == lt || lastst == gt || lastst == leq || lastst == geq) {
  216. long oper = lastst;
  217. TYP *tp1;
  218. getsym();
  219. val2 = ieshiftops(&tp1);
  220. switch(oper) {
  221. case lt:
  222. val1 = val1 < val2;
  223. break;
  224. case gt:
  225. val1 = val1 > val2;
  226. break;
  227. case leq:
  228. val1 = val1 <= val2;
  229. break;
  230. case geq:
  231. val1 = val1 >= val2;
  232. break;
  233. }
  234. if (tp)
  235. *tp = maxsize(*tp,tp1);
  236. }
  237. return(val1);
  238. }
  239. static long ieequalops(TYP **tp)
  240. /* eq relations */
  241. {
  242. long val1 = ierelation(tp),val2;
  243. while (lastst == eq || lastst == neq) {
  244. long oper = lastst;
  245. TYP *tp1;
  246. getsym();
  247. val2 = ierelation(&tp1);
  248. if (oper == neq)
  249. val1 = val1 != val2;
  250. else
  251. val1 = val1 == val2;
  252. if (tp)
  253. *tp = maxsize(*tp,tp1);
  254. }
  255. return(val1);
  256. }
  257. static long ieandop(TYP **tp)
  258. /* and op */
  259. {
  260. long val1 = ieequalops(tp),val2;
  261. while (lastst == and) {
  262. TYP *tp1;
  263. getsym();
  264. val2 = ieequalops(&tp1);
  265. val1 = val1 & val2;
  266. if (tp)
  267. *tp = maxsize(*tp,tp1);
  268. }
  269. return(val1);
  270. }
  271. static long iexorop(TYP **tp)
  272. /* xor op */
  273. {
  274. long val1 = ieandop(tp),val2;
  275. while (lastst == uparrow) {
  276. TYP *tp1;
  277. getsym();
  278. val2 = ieandop(&tp1);
  279. val1 = val1 ^ val2;
  280. if (tp)
  281. *tp = maxsize(*tp,tp1);
  282. }         
  283. return(val1);
  284. }
  285. static long ieorop(TYP **tp)
  286. /* or op */
  287. {
  288. long val1 = iexorop(tp),val2;
  289. while (lastst == or) {
  290. TYP *tp1;
  291. getsym();
  292. val2 = iexorop(&tp1);
  293. val1 = val1 | val2;
  294. if (tp)
  295. *tp = maxsize(*tp,tp1);
  296. }
  297. return(val1);
  298. }
  299. static long ielandop(TYP **tp)
  300. /* logical and op */
  301. {
  302. long val1 = ieorop(tp),val2;
  303. while (lastst == land) {
  304. TYP *tp1;
  305. getsym();
  306. val2 = ieorop(&tp1);
  307. val1 = val1 && val2;
  308. if (tp)
  309. *tp = maxsize(*tp,tp1);
  310. }
  311. return(val1);
  312. }
  313. static long ielorop(TYP **tp)
  314. /* logical or op */
  315. {
  316. long val1 = ielandop(tp),val2;
  317. while (lastst == lor) {
  318. TYP *tp1;
  319. getsym();
  320. val2 = ielandop(&tp1);
  321. val1 = val1 || val2;
  322. if (tp)
  323. *tp = maxsize(*tp,tp1);
  324. }
  325. return(val1);
  326. }
  327. static long iecondop(TYP **tp)
  328. /* Hook op */
  329. {
  330. long val1 = ielorop(tp),val2, val3;
  331. if (lastst == hook) {
  332. TYP *tp1, *tp2;
  333. getsym();
  334. val2 = iecondop(&tp1);
  335. needpunc(colon,0);
  336. val3 = iecondop(&tp2);
  337. if (val1)
  338. val1 = val2;
  339. else
  340. val1 = val3;
  341. if (tp)
  342. *tp = maxsize(tp2,tp1);
  343. }
  344. return(val1);
  345. }
  346. long intexpr(TYP **tp)
  347. /* Integer expressions */
  348. {
  349. return(iecondop(tp));
  350. }