home *** CD-ROM | disk | FTP | other *** search
- /*
- * 68K/386 32-bit C compiler.
- *
- * copyright (c) 1996, David Lindauer
- *
- * This compiler is intended for educational use. It may not be used
- * for profit without the express written consent of the author.
- *
- * It may be freely redistributed, as long as this notice remains intact
- * and sources are distributed along with any executables derived from them.
- *
- * The author is not responsible for damages, either direct or consequential,
- * that may arise from use of this software.
- *
- * v1.5 August 1996
- * David Lindauer, gclind01@starbase.spd.louisville.edu
- *
- * Credits to Mathew Brandt for original K&R C compiler
- *
- */
- #include <stdio.h>
- #include "expr.h"
- #include "c.h"
- #include "gen.h"
- #include "cglbdec.h"
-
- extern TYP stdint, *head;
- extern int prm_cmangle;
- static long ieprimary(TYP **tp)
- /*
- * PRimary integer
- * defined(MACRO)
- * id
- * iconst
- * (cast )intexpr
- * (intexpr)
- */
- { long temp=0;
- SYM *sp;
- if (tp)
- *tp = &stdint;
- if(lastst == id) {
- char *lid = lastid;
- if (prm_cmangle)
- lid++;
- if (!strcmp(lid,"defined")) {
- getsym();
- needpunc(openpa,0);
- if (lastst != id)
- generror(ERR_IDEXPECT,0,0);
- else {
- if (search(lastid,&defsyms) != 0)
- temp = 1;
- getsym();
- }
- needpunc(closepa,0);
- return(temp);
- }
- else {
- sp = gsearch(lastid);
- if(sp == NULL) {
- gensymerror(ERR_UNDEFINED,lastid);
- getsym();
- return 0;
- }
- if(sp->storage_class != sc_const) {
- generror(ERR_NEEDCONST,0,0);
- getsym();
- return 0;
- }
- getsym();
- return sp->value.i;
- }
- }
- else if(lastst == iconst) {
- temp = ival;
- getsym();
- return temp;
- }
- else if (lastst == openpa) {
- getsym();
- if (castbegin(lastst)) {
- decl(0,0);
- decl1();
- needpunc(closepa,0);
- if (tp)
- *tp = head;
- return intexpr(0);
- }
- else {
- temp = intexpr(tp);
- return(temp);
- }
- }
- getsym();
- generror(ERR_NEEDCONST,0,0);
- return 0;
- }
- /*
- * Integer unary
- * - unary
- * ! unary
- * ~unary
- * primary
- */
- static long ieunary(TYP **tp)
- {
- long temp;
- switch (lastst) {
- case minus:
- getsym();
- temp = -ieunary(tp);
- break;
- case not:
- getsym();
- temp = !ieunary(tp);
- break;
- case compl:
- getsym();
- temp = ~ieunary(tp);
- break;
- default:
- temp = ieprimary(tp);
- break;
- }
- return(temp);
- }
- static long iemultops(TYP **tp)
- /* Multiply ops */
- {
- long val1 = ieunary(tp),val2;
- while (lastst == star || lastst == divide || lastst == modop) {
- long oper = lastst;
- getsym();
- val2 = ieunary(tp);
- switch(oper) {
- case star:
- val1 = val1 * val2;
- break;
- case divide:
- val1 = val1 / val2;
- break;
- case modop:
- val1 = val1 % val2;
- break;
- }
- }
- return(val1);
- }
- static long ieaddops(TYP **tp)
- /* Add ops */
- {
- long val1 = iemultops(tp),val2;
- while (lastst == plus || lastst == minus) {
- long oper = lastst;
- getsym();
- val2 = iemultops(tp);
- if (oper == plus)
- val1 = val1 + val2;
- else
- val1 = val1 - val2;
- }
- return(val1);
- }
- static long ieshiftops(TYP **tp)
- /* Shift ops */
- {
- long val1 = ieaddops(tp), val2;
- while (lastst == lshift || lastst == rshift) {
- long oper = lastst;
- getsym();
- val2 = ieaddops(tp);
- if (oper == lshift)
- val1 <<= val2;
- else
- val1 >>= val2;
- }
- return(val1);
- }
- static long ierelation(TYP **tp)
- /* non-eq relations */
- {
- long val1 = ieshiftops(tp), val2;
- while (lastst == lt || lastst == gt || lastst == leq || lastst == geq) {
- long oper = lastst;
- getsym();
- val2 = ieshiftops(tp);
- switch(oper) {
- case lt:
- val1 = val1 < val2;
- break;
- case gt:
- val1 = val1 > val2;
- break;
- case leq:
- val1 = val1 <= val2;
- break;
- case geq:
- val1 = val1 >= val2;
- break;
- }
- }
- return(val1);
- }
- static long ieequalops(TYP **tp)
- /* eq relations */
- {
- long val1 = ierelation(tp),val2;
- while (lastst == eq || lastst == neq) {
- long oper = lastst;
- getsym();
- val2 = ierelation(tp);
- if (oper == neq)
- val1 = val1 != val2;
- else
- val1 = val1 == val2;
- }
- return(val1);
- }
- static long ieandop(TYP **tp)
- /* and op */
- {
- long val1 = ieequalops(tp),val2;
- while (lastst == and) {
- getsym();
- val2 = ieequalops(tp);
- val1 = val1 & val2;
- }
- return(val1);
- }
- static long iexorop(TYP **tp)
- /* xor op */
- {
- long val1 = ieandop(tp),val2;
- while (lastst == uparrow) {
- getsym();
- val2 = ieandop(tp);
- val1 = val1 ^ val2;
- }
- return(val1);
- }
- static long ieorop(TYP **tp)
- /* or op */
- {
- long val1 = iexorop(tp),val2;
- while (lastst == or) {
- getsym();
- val2 = iexorop(tp);
- val1 = val1 | val2;
- }
- return(val1);
- }
- static long ielandop(TYP **tp)
- /* logical and op */
- {
- long val1 = ieorop(tp),val2;
- while (lastst == land) {
- getsym();
- val2 = ieorop(tp);
- val1 = val1 && val2;
- }
- return(val1);
- }
- static long ielorop(TYP **tp)
- /* logical or op */
- {
- long val1 = ielandop(tp),val2;
- while (lastst == lor) {
- getsym();
- val2 = ielandop(tp);
- val1 = val1 || val2;
- }
- return(val1);
- }
- static long iecondop(TYP **tp)
- /* Hook op */
- {
- long val1 = ielorop(tp),val2, val3;
- if (lastst == hook) {
- getsym();
- val2 = iecondop(tp);
- needpunc(colon,0);
- val3 = iecondop(tp);
- if (val1)
- val1 = val2;
- else
- val1 = val3;
- }
- return(val1);
- }
- long intexpr(TYP **tp)
- /* Integer expressions */
- {
- return(iecondop(tp));
- }