+++ /dev/null
-/* parser.c
- *
- * (C) Copyright Apr 15 1995, Edmond J. Breen.
- * ALL RIGHTS RESERVED.
- * This code may be copied for personal, non-profit use only.
- *
- */
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <limits.h>
-
-#include "MachSet.h"
-#include "global.h"
-#include "lexer.h"
-#include "func.h"
-#include "typemod.h"
-#include "xalloc.h"
-#include "typesets.h"
-#include "cdecl.h"
-#include "error.h"
-#include "symbol.h"
-#include "parser.h"
-
-typedef struct {
- val_t match, loc;
-} pair_t;
-
-static int STRUCT_MEMBER_TYPE =0;
-
-#define out_expr Outexpr
-#define setInst(code,idx,mem,val) do { code_t *C__C = code;\
- if(C__C->binst) \
- C__C->inst[idx].mem = val;\
- } while(0)
-
-
-void EiC_reset_env_pointers(token_t *e1,int bp);
-
-/** PROTOTYPES parser.c **/
-static void correctit(code_t * C, eicstack_t * S, int nxt, int loc);
-static void fixcasestack(token_t * e1, int nxt, int loc);
-static void block(token_t * e1);
-static void addinlocals(token_t * e1,int n);
-static void label_stmt(token_t * e1);
-static void testfortype(token_t *e1, int NoVoid);
-static void genJump(token_t *e1, val_t *v, int t,int T);
-static void select_stmt(token_t * e1);
-static void iter_stmt(token_t * e1);
-static void jump_stmt(token_t * e1);
-static void Outexpr(token_t * e1);
-static void expr(token_t * e1);
-static void log_or_expr(token_t * e1);
-static void log_and_expr(token_t * e1);
-static void inc_or_expr(token_t * e1);
-static void xor_expr(token_t * e1);
-static void and_expr(token_t * e1);
-static void equal_expr(token_t * e1);
-static void rel_expr(token_t * e1);
-static void shift_expr(token_t * e1);
-static void add_expr(token_t * e1);
-static void mult_expr(token_t * e1);
-static void cast_expr(token_t * e1);
-static void f_cast_expr(token_t * e1);
-static void EiC_unary_expr(token_t * e1);
-static void postfix_expr(token_t * e1);
-static void EiC_r_postfix_expr(token_t * e1);
-static int arg_expr_list(token_t * E1, token_t * e1);
-static void primary_expr(token_t * e1);
-static void process_binary(void (*func) (token_t * e),
- token_t * e1, int op);
-static void assignop(void (*func) (token_t * e),
- token_t * e1, int op);
-static int findmem(type_expr * t, char *id);
-static int check4constmem(type_expr * t);
-
-
-int EiC_S_LEVEL;
-
-static int NoPTR = 0;
-
-static eicstack_t breakstack = {0, NULL};
-static eicstack_t contstack = {0, NULL};
-static eicstack_t *casestack;
-
-static int BREAK = 0, CONT = 0, CASEON;
-
-#if 1
-
-void EiCp_freeLabels(Label_t *lab)
-{
- if(lab) {
- EiCp_freeLabels(lab->nxt);
- xfree(lab->name);
- xfree(lab);
- }
-}
-
-Label_t * EiCp_addLabel(Label_t *lab,
- char *name,
- int loc, int chck)
-{
- Label_t *nlab;
-
- if(chck) { /* check 4 duplicated labels */
- nlab = lab;
- while(nlab) {
- if(strcmp(name, nlab->name) == 0)
- EiC_error("Duplicate label %s",name);
- nlab = nlab->nxt;
- }
- }
-
- nlab = xmalloc(sizeof(*nlab));
- nlab->name = xmalloc(strlen(name)+1);
- strcpy(nlab->name,name);
- nlab->loc = loc;
-
- nlab->nxt = lab;
-
- return nlab;
-}
-
-#endif
-
-
-void addoffset(eicstack_t * S, int nxt, int offset)
-{
- unsigned i;
- val_t *v;
- for (i = nxt, v = &S->val[nxt]; i < S->n; ++v, ++i)
- v->ival += offset;
-}
-
-
-static void correctit(code_t * C, eicstack_t * S, int nxt, int loc)
-{
- val_t addr;
- if(!C->binst)
- return;
- while (S->n > nxt) {
- EiC_eicpop(S, &addr);
- C->inst[addr.ival].val.ival = loc-addr.ival;
- }
-}
-
-static int comppair(const void * p1,const void * p2)
-{
- return ((pair_t*)p1)->match.ival -
- ((pair_t*)p2)->match.ival;
-}
-
-void fixcasestack(token_t * e1, int nxt, int loc)
-{
- void qsort(void *base, size_t nm, size_t sz,
- int (*f)());
- int i;
- if (casestack->n > 0) {
- correctit(&e1->Code, &breakstack, nxt, e1->Code.nextinst);
- if (casestack->val[0].ival == 0)
- casestack->val[0].ival = e1->Code.nextinst - loc;
- else
- casestack->val[0].ival -= loc;
- for (i = 2; i < casestack->n; i += 2)
- casestack->val[i].ival -= loc;
- qsort(&casestack->val[1],
- (casestack->n - 1) >> 1,
- sizeof(val_t) << 1,
- comppair);
- } else
- EiC_error("Illegal switch statement");
-}
-
-void EiC_initparser()
-{
- extern int EiC_ErrorRecover;
- EiC_work_tab = stand_tab;
- EiC_ErrorRecover = 0;
-}
-
-void EiC_parse(environ_t * env)
-{
- void EiC_comm_switch(void);
- token_t e1;
-
- val_t v;
- int t;
- EiC_S_LEVEL = 1;
- EiC_inittoken(&e1);
- while ((t = EiC_lexan()) != DONE) {
- EiC_freetoken(&e1);
-
- if (t == ':') { /* get an EiC command */
- int h;
- h = EiC_work_tab;
- EiC_work_tab = eic_tab;
- if (EiC_lexan() == ID) {
- if (EiC_gettype(token->Val.sym->type) == t_eic)
- (*token->Val.sym->val.func) ();
- else {
- EiC_remsym(token->Val.sym);
- EiC_error("Unknown EiC command");
- }
- } else if(token->Tok == '-')
- EiC_comm_switch();
- else
- EiC_error("Expected an EiC command");
- EiC_work_tab = h;
- continue;
- } else if(t == '?') {
- printf("\t If you want help, enter :help\n\n");
- continue;
- }
-
- retractlexan();
-
-#if 1
- switch(t) {
- TYPEQUAL:
- STORECLASS:
- TYPESPEC:
- EiC_ext_decl(&e1);
- break;
- default:
- EiC_stmt(&e1);
- }
-#else
- block(&e1);
-#endif
- EiC_concode(&env->CODE, &e1.Code);
- }
- EiC_concode(&env->CODE, &e1.Code);
-
- if (e1.Type)
- v.p.p = EiC_copytype(e1.Type);
- else
- v.p.p = EiC_addtype(t_void, NULL);
-
- EiC_freetoken(&e1);
- EiC_generate(&env->CODE, halt, &v, 0);
-}
-/*
- * Globals used for
- * local aggregate data
- */
-
-unsigned int EiC_ASPOT = 0;
-static unsigned int MASPOT = 0, ADDLOCALS = 0;
-
-void EiC_updateLocals(void)
-{
- if (EiC_ASPOT > MASPOT)
- MASPOT = EiC_ASPOT;
- if (EiC_ENV->lsp > ADDLOCALS)
- ADDLOCALS = EiC_ENV->lsp;
-}
-
-static void addinlocals(token_t * e1,int n)
-{
- val_t v;
- token_t e2;
-
- EiC_inittoken(&e2);
- v.ival = n + (MASPOT>0);
- EiC_generate(&e2.Code, checkar, &v, 0);
- setCodeLineNo(&e2.Code,e2.Code.nextinst-1,0);
- if (MASPOT) {
- v.ival = MASPOT;
- EiC_generate(&e2.Code, pushint, &v, 0);
- setCodeLineNo(&e2.Code,e2.Code.nextinst-1,0);
- v.ival = n;
-
- { /* correct for AAA location */
- int i, N;
- code_t *c = &e1->Code;
- N = nextinst(c);
- for(i = 0; i < N; ++i)
- if(opcode(c,i) == lda && ivalcode(c,i) == -1)
- ivalcode(c,i) = n;
- }
- EiC_generate(&e2.Code, massign, &v, 1);
- setCodeLineNo(&e2.Code,e2.Code.nextinst-1,0);
- EiC_generate(&e1->Code, fmem, &v, 1);
- setCodeLineNo(&e1->Code,e1->Code.nextinst-1,0);
- v.ival = n;
- }
- EiC_generate(&e1->Code, reducear, &v, 0);
- setCodeLineNo(&e1->Code,e1->Code.nextinst-1,0);
-
- EiC_concode(&e2.Code, &e1->Code);
- e1->Code = e2.Code;
- ADDLOCALS = EiC_ASPOT = MASPOT = 0;
-}
-
-static void block(token_t * e1)
-{
- token_t e2;
- EiC_inittoken(&e2);
- while(EiC_ext_decl(&e2)) {
- EiC_contoken(e1,&e2);
- EiC_inittoken(&e2);
- }
- while (EiC_lexan() != '}' && token->Tok != DONE) {
- retractlexan();
- EiC_stmt(e1);
- }
- if (token->Tok == DONE)
- EiC_error("Expected }");
-}
-
-static void stmt1(token_t * e1)
-{
- void EiC_clearTempories();
- int bp;
- unsigned aspot;
-
- switch (EiC_lexan()) {
- case '{': /* compound statement */
- EiC_S_LEVEL++;
- bp = EiC_ENV->lsp;
-
- aspot = EiC_ASPOT;
-
- block(e1);
-
- EiC_updateLocals();
- EiC_clearTempories();
-
- EiC_ASPOT = aspot;
-
- EiC_reset_env_pointers(e1, bp);
- EiC_remlevel(EiC_S_LEVEL);
- EiC_S_LEVEL--;
- break;
- case casesym:
- case defaultsym:
- label_stmt(e1);
- break;
- case gotosym:
- case breaksym:
- case continuesym:
- case returnsym:
- jump_stmt(e1);
- break;
- case ifsym:
- case switchsym:
- select_stmt(e1);
- break;
- case whilesym:
- case dosym:
- case forsym:
- iter_stmt(e1);
- break;
- TYPEQUAL:
- STORECLASS:
- TYPESPEC:
-
- EiC_error("Unexpected declaration");
- retractlexan();
- EiC_ext_decl(e1);
- break;
-
-#if defined(ILOOKAHEAD) && (MAX_TOKENS > 1)
-
- case ID: /* handle label statements */
- if(EiC_lexan() == ':') {
- extern int EiC_INFUNC;
- retractlexan();
- if(!EiC_INFUNC)
- EiC_error("Misplaced label statement");
- else {
- e1->Code.labels = EiCp_addLabel(e1->Code.labels,
- token->Val.sym->id,
- e1->Code.nextinst, 1);
- EiC_lexan();
- }
- break;
- } else
- retractlexan();
-#endif
-
- default:
- retractlexan();
- out_expr(e1);
- EiC_match(';', " ; ");
- return;
- }
- /* to get here a statement was executed, therefore */
- e1->Type = EiC_addtype(t_void, e1->Type);
- EiC_clearTempories();
-}
-
-void EiC_stmt(token_t *e1)
-{
- static int Stmts = 0;
- Stmts++;
-
- stmt1(e1);
-
- Stmts--;
- if (EiC_S_LEVEL == 1 && Stmts == 0) {
- EiC_updateLocals();
- if(ADDLOCALS > 0)
- addinlocals(e1,ADDLOCALS);
- }
-}
-
-static void label_stmt(token_t * e1)
-{
- if (!CASEON) {
- EiC_error("Illegal label");
- return;
- }
- if (token->Tok == casesym) {
- token_t e2;
- int t;
- val_t v;
-
- EiC_inittoken(&e2);
- EiC_assign_expr(&e2);
- EiC_match(':', " :");
- if (isconst(e2.Type)) {
- t = EiC_gettype(e2.Type);
- if (t >= t_char && t <= t_uint) {
- for (t = 1; t < casestack->n; t += 2)
- if (e2.Val.ival == casestack->val[t].ival)
- EiC_error("Duplicate case in switch");
- EiC_eicpush(casestack, e2.Val);
- v.ival = e1->Code.nextinst;
- EiC_eicpush(casestack, v);
- } else
- EiC_error("Must be integer type");
- } else
- EiC_error("Must be const_expr type");
- EiC_stmt(e1);
- EiC_freetoken(&e2);
- } else { /* default */
- if (casestack->val[0].ival != 0)
- EiC_error("Duplicate default in switch");
- EiC_match(':', " :");
- casestack->val[0].ival = e1->Code.nextinst;
- EiC_stmt(e1);
- }
-}
-
-
-static void select_stmt(token_t * e1)
-{
- int t;
- token_t e2;
- val_t u1;
-
- EiC_inittoken(&e2);
- if (token->Tok == ifsym) {
- EiC_match('(', " ( ");
- out_expr(&e2);
-
- testfortype(&e2,1);
- t = EiC_gettype(e2.Type);
-
- EiC_match(')', " ) ");
- EiC_contoken(e1, &e2);
- u1.ival = e1->Code.nextinst;
- genJump(e1,&u1,t,0);
- EiC_stmt(e1);
-
- if (EiC_lexan() == elsesym) {
- setInst(&e1->Code,u1.ival,val.ival,e1->Code.nextinst-u1.ival+1);
- u1.ival = e1->Code.nextinst;
- EiC_generate(&e1->Code, jmpu, &u1, 0);
- setCodeLineNo(&e1->Code,e1->Code.nextinst-1,0);
- EiC_stmt(e1);
- setInst(&e1->Code,u1.ival,val.ival,e1->Code.nextinst-u1.ival);
- } else {
- setInst(&e1->Code,u1.ival,val.ival,e1->Code.nextinst-u1.ival);
- retractlexan();
- }
-
- } else {/* switchsym */
- int nxtbreak, loc;
- eicstack_t *hold;
-
- BREAK++;
- CASEON++;
- nxtbreak = breakstack.n;
- EiC_match('(', " (");
- out_expr(&e2);
- EiC_match(')', " )");
- hold = casestack;
- casestack = (eicstack_t *) xcalloc(1, sizeof(eicstack_t));
- u1.ival = 0;
- EiC_eicpush(casestack, u1); /* push dummy for default */
- EiC_contoken(e1, &e2);
- u1.p.p = casestack;
- loc = e1->Code.nextinst;
- EiC_generate(&e1->Code, jmptab, &u1, 0);
- EiC_stmt(e1);
- fixcasestack(e1, nxtbreak, loc);
- casestack = hold;
- BREAK--;
- CASEON--;
- }
-}
-
-static void testfortype(token_t *e1, int NoVoid)
-{
- int t = EiC_gettype(e1->Type);
- if(!isArithmetic(t) && t != t_pointer) {
- if(t == t_void) {
- if(NoVoid)
- EiC_error("Void expression");
- }else
- EiC_warningerror("Possible non relational operation");
- }
-}
-
-static void genJump(token_t *e1, val_t *v, int t,int T)
-{
- /* 0 for false and 1 for True */
- static int tab[2][5] = {{ jmpFint,jmpFlng,jmpFdbl,jmpFptr, jmpFllng},
- { jmpTint,jmpTlng,jmpTdbl,jmpTptr, jmpTllng}};
- switch(t) {
- default:
- EiC_error("Undefined type for relational operation");
- case t_char: case t_uchar:
- case t_short:case t_ushort:
- case t_int: case t_uint:
- EiC_generate(&e1->Code, tab[T][0], v, 0);
- break;
- case t_long: case t_ulong:
- EiC_generate(&e1->Code, tab[T][1], v, 0);
- break;
- case t_float: case t_double:
- EiC_generate(&e1->Code, tab[T][2], v, 0);
- break;
- case t_pointer:
- EiC_generate(&e1->Code, tab[T][3], v, 0);
- break;
- case t_llong:
- EiC_generate(&e1->Code, tab[T][4], v, 0);
- break;
-
- }
-}
-
-
-static void iter_stmt(token_t * e1)
-{
- int t, rt,nxtbreak, nxtcont;
- val_t u1;
- token_t e2, e3;
- EiC_inittoken(&e2);
- BREAK++, CONT++;
- nxtbreak = breakstack.n;
- nxtcont = contstack.n;
-
- switch (token->Tok) {
- case dosym:
- u1.ival = e1->Code.nextinst;
- EiC_stmt(e1);
- if (EiC_lexan() != whilesym)
- EiC_error("Missing while in do while statement");
- EiC_match('(', " (");
- correctit(&e1->Code, &contstack, nxtcont, e1->Code.nextinst);
- out_expr(&e2);
- EiC_match(')', ")");
- EiC_match(';', " ;");
-
- testfortype(&e2,1);
- rt = EiC_gettype(e2.Type);
-
- EiC_contoken(e1, &e2);
- u1.ival = u1.ival - e1->Code.nextinst;
- genJump(e1,&u1,rt,1);
- /*EiC_generate(&e1->Code, jmpTint, &u1, 0);*/
- correctit(&e1->Code, &breakstack, nxtbreak, e1->Code.nextinst);
- break;
- case whilesym:
- u1.ival = e1->Code.nextinst;
- EiC_generate(&e1->Code, jmpu, &u1, 0);
- setCodeLineNo(&e1->Code,e1->Code.nextinst-1,0);
- EiC_match('(', " ( ");
- out_expr(&e2); /* <expr> */
-
- testfortype(&e2,1);
- rt = EiC_gettype(e2.Type);
-
- EiC_match(')', " ) ");
- EiC_stmt(e1); /* <stmt> */
- setInst(&e1->Code,u1.ival,val.ival,e1->Code.nextinst-u1.ival);
- t = e1->Code.nextinst;
- EiC_contoken(e1, &e2);
- u1.ival -= e1->Code.nextinst - 1;
- genJump(e1,&u1,rt,1);
- /*EiC_generate(&e1->Code, jmpTint, &u1, 0);*/
- setCodeLineNo(&e1->Code,e1->Code.nextinst-1,0);
- correctit(&e1->Code, &breakstack, nxtbreak, e1->Code.nextinst);
- correctit(&e1->Code, &contstack, nxtcont, t);
- break;
- case forsym:
- EiC_inittoken(&e3);
-
- EiC_match('(', " ( ");
- out_expr(e1); /* expr1 */
- EiC_match(';', " ; ");
- u1.ival = e1->Code.nextinst;
- EiC_generate(&e1->Code, jmpu, &u1, 0);
- out_expr(&e2); /* expr2 */
-
- testfortype(&e2,0);
- rt = EiC_gettype(e2.Type);
-
- EiC_match(';', " ; ");
- out_expr(&e3); /* expr3 */
- EiC_match(')', " ; ");
-
- EiC_stmt(e1);
- correctit(&e1->Code, &contstack,
- nxtcont, e1->Code.nextinst);
-
- EiC_contoken(e1, &e3);
- setInst(&e1->Code,u1.ival,val.ival,e1->Code.nextinst-u1.ival);
- EiC_contoken(e1, &e2);
- u1.ival -= (e1->Code.nextinst - 1);
- if (rt == t_void)
- EiC_generate(&e1->Code, jmpu, &u1, 0);
- else
- genJump(e1,&u1,rt,1);
- /*EiC_generate(&e1->Code, jmpTint, &u1, 0);*/
-
- setCodeLineNo(&e1->Code,e1->Code.nextinst -1, 0);
-
- correctit(&e1->Code, &breakstack, nxtbreak,
- e1->Code.nextinst);
- break;
- }
- BREAK--, CONT--;
-}
-
-static void jump_stmt(token_t * e1)
-{
- extern int EiC_INFUNC;
- extern int EiC_RETURNON;
- extern token_t *EiC_RETURNEXPR;
- val_t v;
- v.ival = e1->Code.nextinst;
- switch (token->Tok) {
- case gotosym:
- if(!EiC_INFUNC)
- EiC_error("Misplaced goto statement");
- else {
- if(EiC_lexan() != ID)
- EiC_error("expected goto label");
- else {
- EiC_generate(&e1->Code, jmpu, &v, 0);
- e1->Code.gotos = EiCp_addLabel(e1->Code.gotos,
- token->Val.sym->id,
- v.ival, 0);
- if(EiC_gettype(token->Val.sym->type) == ID)
- EiC_remsym(token->Val.sym);
- }
- }
- break;
-
-
- case breaksym:
- if (!BREAK)
- EiC_error("Misplaced break statement");
- else
- EiC_eicpush(&breakstack, v);
- EiC_generate(&e1->Code, jmpu, &e1->Val, 0);
- EiC_match(';', " ;");
- break;
- case continuesym:
- if (!CONT)
- EiC_error("Misplaced continue statement");
- else
- EiC_eicpush(&contstack, v);
- EiC_generate(&e1->Code, jmpu, &e1->Val, 0);
- EiC_match(';', " ;");
- break;
- case returnsym:
- if (!EiC_RETURNON)
- EiC_error("Misplaced return statement");
- else {
- token_t e2;
- if (EiC_lexan() != ';') {
- retractlexan();
- EiC_inittoken(&e2);
- expr(&e2);
- /* catch dangling pointers */
- if(EiC_gettype(e2.Type) == t_pointer && e2.Sym)
- if((EiC_gettype(e2.Sym->type) != t_pointer &&
- EiC_gettype(e2.Sym->type) != t_array) && EiC_GI(&e2))
- EiC_warningerror("Possible dangling pointer");
- EiC_match(';', " ;");
- if(EiC_gettype(nextType(EiC_RETURNEXPR->Type)) == t_void &&
- EiC_gettype(e2.Type) != t_void)
- EiC_error("Illegal return type, expected void");
-
- if (isconst(e2.Type)) {
- EiC_castconst(&e2, EiC_RETURNEXPR, 1);
- EiC_output(&e2);
- } else {
- EiC_output(&e2);
- EiC_castvar(&e2, EiC_RETURNEXPR, 0);
- }
- if(EiC_HasHiddenParm(EiC_RETURNEXPR->Type)) {
- val_t v;
- v.ival = -1;
- EiC_generate(&e1->Code,rvalptr,&v,1);
- v.ival = 1;
- EiC_generate(&e1->Code,bump,&v,0);
- EiC_contoken(e1, &e2);
- v.ival = EiC_get_sizeof(nextType(EiC_RETURNEXPR->Type));
- EiC_generate(&e1->Code,refmem,&v,0);
- } else
- EiC_contoken(e1, &e2);
- } else
- if(EiC_gettype(nextType(EiC_RETURNEXPR->Type)) != t_void)
- EiC_warningerror("missing return value");
- EiC_generate(&e1->Code, eicreturn, &e1->Val, 0);
- }
- break;
- }
-}
-
-static void generatePtr(token_t * e1)
-{
- if(!NoPTR && EiC_gettype(e1->Type) == t_array && !e1->Pflag) {
- EiC_exchtype(t_pointer, e1->Type);
- if(!EiC_GI(e1)) { /* static of global variable */
- setConst(e1->Type);
- e1->Val.p = EiC_ENV->AR[e1->Val.ival].v.p;
- }
- }
-}
-
-static void expr(token_t * e1)
-{
- /* really a comma expression */
- token_t e2;
- int c = 0;
- do {
- EiC_inittoken(&e2);
- EiC_assign_expr(&e2);
- if(nextinst(&e1->Code))
- EiC_output(e1);
- EiC_concode(&e1->Code,&e2.Code);
- EiC_freetype(e1->Type);
- e1->Type = EiC_copytype(e2.Type);
- e1->Pflag = e2.Pflag;
- EiC_freetoken(&e2);
- c++;
-
- } while (EiC_lexan() == ',');
- retractlexan();
- e1->Pflag = e2.Pflag;
- e1->Sym = e2.Sym;
- e1->Val = e2.Val;
- if(c > 1)
- setConstp(e1->Type);
-}
-
-static void Outexpr(token_t * e1)
-{
- /* really a comma expression */
- token_t e2;
- int c = 0;
- do {
- EiC_inittoken(&e2);
- EiC_assign_expr(&e2);
- EiC_output(&e2);
- EiC_freetype(e1->Type);
- EiC_concode(&e1->Code,&e2.Code);
- e1->Type = EiC_copytype(e2.Type);
- EiC_freetoken(&e2);
- c++;
-
- } while (EiC_lexan() == ',');
- retractlexan();
- e1->Pflag = e2.Pflag;
- e1->Sym = e2.Sym;
- e1->Val = e2.Val;
- if(c > 1)
- setConstp(e1->Type);
-}
-
-
-void EiC_assign_expr(token_t * e1)
-{
-
-#if 1
- int t = EiC_lexan();
-
- /* handle longjmp and setjmp */
-
- if(t == eiclongjmpsym) {
- EiC_generate(&e1->Code, __eiclongjmp, &e1->Val, EiC_GI(e1));
- e1->Type = EiC_freetype(e1->Type);
- e1->Type = EiC_addtype(t_void, e1->Type);
- e1->Pflag = 1;
- return;
-
- } else if (t == eicsetjmpsym) {
- EiC_generate(&e1->Code, __eicsetjmp, &e1->Val, EiC_GI(e1));
- e1->Type = EiC_freetype(e1->Type);
- e1->Type = EiC_addtype(t_int, e1->Type);
- e1->Pflag = 1;
- return;
- } else
- retractlexan();
-
-#endif
-
- cond_expr(e1);
- while (1)
- switch (EiC_lexan()) {
- case ASS: /* = */
- case ADDEQ: /* += */
- case SUBEQ: /* -= */
- case DIVEQ: /* /= */
- case MULEQ: /* *= */
- case MODEQ: /* %= */
- case RSHTEQ: /* >>= */
- case LSHTEQ: /* <<= */
- case ANDEQ: /* &= */
- case BOREQ: /* |= */
- case XOREQ: /* ^= */
- assignop(EiC_assign_expr, e1, token->Tok);
- break;
- default:
- retractlexan();
- generatePtr(e1);
- return;
- }
-}
-
-extern void cond_expr(token_t * e1)
-{
- log_or_expr(e1);
- if (EiC_lexan() == '?') {
- val_t v;
- int rt;
- token_t e2, e3;
- EiC_inittoken(&e2);
- out_expr(&e2);
- EiC_match(':', " :");
- EiC_inittoken(&e3);
- cond_expr(&e3);
- if(!isconst(e3.Type))
- EiC_output(&e3);
- EiC_cast2comm(&e2, &e3);
- EiC_output(&e3);
- EiC_output(e1);
- rt = EiC_gettype(e1->Type);
- e1->Type = EiC_freetype(e1->Type);
- e1->Type = EiC_copytype(e2.Type);
- v.ival = e2.Code.nextinst + 2;
-#if 0
- EiC_generate(&e1->Code, jmpFint, &v, 0);
-#else
- genJump(e1,&v,rt,0);
-
-#endif
- EiC_contoken(e1, &e2);
-
- v.ival = e1->Code.nextinst;
- EiC_generate(&e1->Code, jmpu, &v, 0);
- setInst(&e1->Code,v.ival,val.ival,e3.Code.nextinst+1);
- EiC_contoken(e1, &e3);
- /* conditional's can't form lvalues */
- setConstp(e1->Type);
- } else
- retractlexan();
-}
-
-static void fixit(code_t *C, int s)
-{
- int i;
- for(i = s; i < C->nextinst;i++)
- switch(C->inst[i].opcode) {
- case jmpFint:
- case jmpFlng:
- case jmpFdbl:
- case jmpFptr:
- case jmpTint:
- case jmpTlng:
- case jmpTdbl:
- case jmpTptr:
- if(C->inst[i].val.ival == INT_MAX)
- C->inst[i].val.ival = C->nextinst - i;
- }
-}
-
-static void log_or_expr(token_t * e1)
-{
- void EiC_do_lor(token_t *, int);
- log_and_expr(e1);
- if(EiC_lexan() == LOR) {
- token_t e2;
- int nxt = e1->Code.nextinst;
- EiC_do_lor(e1, INT_MAX);
- do {
- EiC_inittoken(&e2);
- log_and_expr(&e2);
- EiC_do_lor(&e2,INT_MAX);
- EiC_contoken(e1,&e2);
- } while (EiC_lexan() == LOR);
- fixit(&e1->Code,nxt);
- }
- retractlexan();
-}
-
-static void log_and_expr(token_t * e1)
-{
- void EiC_do_land(token_t *, int);
- inc_or_expr(e1);
- if(EiC_lexan() == LAND) {
- token_t e2;
- int nxt = e1->Code.nextinst;
- EiC_do_land(e1, INT_MAX);
- do {
- EiC_inittoken(&e2);
- inc_or_expr(&e2);
- EiC_do_land(&e2,INT_MAX);
- EiC_contoken(e1,&e2);
- } while (EiC_lexan() == LAND);
- fixit(&e1->Code,nxt);
- }
- retractlexan();
-}
-
-static void inc_or_expr(token_t * e1)
-{
- xor_expr(e1);
- while (EiC_lexan() == BOR)
- process_binary(xor_expr, e1, BOR);
- retractlexan();
-}
-
-static void xor_expr(token_t * e1)
-{
- and_expr(e1);
- while (EiC_lexan() == XOR)
- process_binary(and_expr, e1, XOR);
- retractlexan();
-}
-
-static void and_expr(token_t * e1)
-{
- equal_expr(e1);
- while (EiC_lexan() == AND)
- process_binary(equal_expr, e1, AND);
- retractlexan();
-}
-
-static void equal_expr(token_t * e1)
-{
- rel_expr(e1);
- while (1)
- switch (EiC_lexan()) {
- case EQ:
- case NE:
- process_binary(rel_expr, e1, token->Tok);
- break;
- default:
- retractlexan();
- return;
- }
-}
-
-static void rel_expr(token_t * e1)
-{
- shift_expr(e1);
- while (1)
- switch (EiC_lexan()) {
- case LT:
- case LE:
- case GT:
- case GE:
- process_binary(shift_expr, e1, token->Tok);
- break;
- default:
- retractlexan();
- return;
- }
-}
-
-static void shift_expr(token_t * e1)
-{
- add_expr(e1);
- while (1)
- switch (EiC_lexan()) {
- case LSHT:
- case RSHT:
- process_binary(add_expr, e1, token->Tok);
- break;
- default:
- retractlexan();
- return;
- }
-}
-
-static void add_expr(token_t * e1)
-{
- mult_expr(e1);
- while (1)
- switch (EiC_lexan()) {
- case '+':
- case '-':
- process_binary(mult_expr, e1, token->Tok);
- break;
- default:
- retractlexan();
- return;
- }
-}
-
-static void mult_expr(token_t * e1)
-{
- cast_expr(e1);
- while (1)
- switch (EiC_lexan()) {
- case '*':
- case '/':
- case '%':
- process_binary(cast_expr, e1, token->Tok);
- break;
- default:
- retractlexan();
- return;
- }
-}
-
-static void cast_expr(token_t * e1)
-{
- if (EiC_lexan() != '(') {
- retractlexan();
- EiC_unary_expr(e1);
- } else {
- f_cast_expr(e1);
- }
-}
-
-static void f_cast_expr(token_t * e1)
-{
- token_t e2;
- switch (EiC_lexan()) {
- TYPESPEC:
- TYPEQUAL:
- EiC_inittoken(&e2);
- retractlexan();
- EiC_type_name(e1);
- EiC_match(')', " )");
- cast_expr(&e2);
- if (isconst(e2.Type)) {
- setConst(e1->Type);
- EiC_castconst(&e2, e1, 1);
- e1->Val = e2.Val;
- } else {
- EiC_output(&e2);
- EiC_castvar(&e2, e1, 1);
- e1->Pflag = e2.Pflag;
- e1->Sym = e2.Sym;
- /*e1->Val = e2.Val;*/
- }
- EiC_contoken(e1, &e2);
- break;
- /* cast can't form lvalues */
- setConstp(e1->Type);
- default:
- retractlexan();
- expr(e1);
- EiC_match(')', " )");
- EiC_r_postfix_expr(e1);
- break;
- }
-}
-
-
-static void EiC_unary_expr(token_t * e1)
-{
- int t;
-
- t = EiC_lexan();
- switch (t) {
- case '+': /* unary - */
- case '-': /* unary + */
- case '*': /* indirection */
- case '~': /* ones complement */
- case NOT: /* */
- cast_expr(e1);
- EiC_unaryop(e1, t);
- return;
- case INC: /* ++ lval */
- case DEC: /* -- lval */
- EiC_unary_expr(e1);
- EiC_unaryop(e1, t);
- return;
- case sizeofsym:
- NoPTR++;
- if(EiC_lexan() == '(') {
- switch(EiC_lexan()) {
- TYPESPEC:
- TYPEQUAL:
- retractlexan();
- e1->Type = EiC_freetype(e1->Type);
- EiC_type_name(e1);
- break;
- default: /* must be unary expr, i.e. ( expr ) */
- retractlexan();
- expr(e1);
- }
- EiC_match(')', " )");
- } else {
- retractlexan();
- EiC_unary_expr(e1);
- }
- EiC_freecode(&e1->Code);
- if(isconst(e1->Type) &&
- EiC_gettype(e1->Type) == t_pointer &&
- EiC_gettype(e1->Type->nxt) == t_char) /* hack for char */
- /* constants */
- e1->Val.uival = strlen(e1->Val.p.p) + 1;
- else
- e1->Val.uival = EiC_get_sizeof(e1->Type);
-
- if(!e1->Val.uival || !e1->Type)
- EiC_error("Invalid argument to sizeof");
-
- e1->Type = EiC_freetype(e1->Type);
-
- e1->Type = EiC_addtype(t_uint, e1->Type);
- setConst(e1->Type);
- e1->Pflag = 0;
- NoPTR--;
- return;
-
- case AND:
-#if 0
- /* this section of code is an attempt to
- * to have constant addresses determined
- * at compile time (not finished)
- */
- NoPTR++;
- cast_expr(e1);
- t = EiC_gettype(e1->Type);
- if(e1->Sclass == c_register)
- EiC_error("Cannot apply & to a register variable");
- /* check for global or static variable class */
- if(EiC_GI(e1) == 0 && !isconst(e1->Type) && t != t_lval) {
- void * EiC_getaddress(token_t * e1);
- ptr_t *p;
- if(t == t_union || t == t_struct)
- e1->Type = EiC_addtype(t_pointer,e1->Type);
- p = EiC_getaddress(e1);
- e1->Val.p.sp = e1->Val.p.p = p;
- e1->Val.p.ep = (char *) p + SIZEOFTHETYPE;
- setConst(e1->Type);
- }
-
- if(!isconst(e1->Type)) {
- switch (t) {
- case t_char:
- case t_uchar:
- case t_short:
- case t_ushort:
- case t_int:
- case t_uint:
- CASE_LONG:
- CASE_ULONG:
- CASE_FLOAT:
- case t_pointer:
- if (e1->Pflag)
- EiC_error("Must have lvalue");
- else {
- if(isUnSafe(e1->Type))
- e1->Val.p.ep = (void*)(EiC_get_sizeof(e1->Type));
- EiC_generate(&e1->Code, lval, &e1->Val, EiC_GI(e1));
- }
- break;
- case t_lval:
- e1->Type = EiC_succType(e1->Type);
- break;
- case t_struct:
- case t_union:
- case t_array:
- EiC_generate(&e1->Code, rvalptr, &e1->Val, EiC_GI(e1));
- break;
- case t_funcdec:
- EiC_exchtype(t_func, e1->Type);
- case t_func:
- v.p.p = e1->Sym;
- EiC_generate(&e1->Code, pushptr, &v, 0);
- break;
- default:
- EiC_error("Must have lvalue");
- }
- e1->Type = EiC_addtype(t_pointer, e1->Type);
- e1->Pflag = 1;
- } else /* nothing much to do */
- if(EiC_gettype(e1->Type) != t_pointer)
- EiC_error("Must have lvalue");
- NoPTR--;
- return;
- }
-
-#else
- NoPTR++;
- cast_expr(e1);
- NoPTR--;
- if(e1->Sclass == c_register)
- EiC_error("Cannot apply & to a register variable");
- switch (EiC_gettype(e1->Type)) {
- case t_char:
- case t_uchar:
- case t_short:
- case t_ushort:
- case t_int:
- case t_uint:
- CASE_LONG:
- CASE_ULONG:
- CASE_FLOAT:
- case t_pointer:
- if (e1->Pflag)
- EiC_error("Must have lvalue");
- else {
- e1->Val.p.ep = (void*)(EiC_get_sizeof(e1->Type));
- EiC_generate(&e1->Code, lval, &e1->Val, EiC_GI(e1));
- }
- break;
- case t_lval:
- e1->Type = EiC_succType(e1->Type);
- break;
- case t_struct:
- case t_union:
- case t_array:
- EiC_generate(&e1->Code, rvalptr, &e1->Val, EiC_GI(e1));
- break;
-
- case t_funcdec:
- case t_func:
- case t_builtin:
- EiC_output(e1);
- return;
-
- default:
- EiC_error("Must have lvalue");
- }
- e1->Type = EiC_addtype(t_pointer, e1->Type);
- e1->Pflag = 1;
- return;
- }
-#endif
-
- retractlexan();
- postfix_expr(e1);
-}
-
-static void postfix_expr(token_t * e1)
-{
- primary_expr(e1);
- EiC_r_postfix_expr(e1);
-}
-
-static void EiC_r_postfix_expr(token_t * e1)
-{
- void derefConst(token_t *);
- void EiC_binhlval(int, token_t *, token_t *);
-
- int t,c = 0;
- switch ((t = EiC_lexan())) {
- case INC:
- case DEC:
- EiC_unaryop(e1, t);
- if (t == INC)
- EiC_do_inc_dec(e1, DEC);
- else
- EiC_do_inc_dec(e1, INC);
- EiC_r_postfix_expr(e1);
- break;
- case '[': /* handle array indexing */
-
- process_binary(expr,e1,'+');
- EiC_unaryop(e1, '*');
-
- EiC_match(']', " ]");
- EiC_r_postfix_expr(e1);
-
- break;
-
- case RARROW:
-
-#if 0 /* this section of code was the start
- * of get EiC to determine where possible
- * addresses at compile time.
- */
- if(!isconst(e1->Type))
- EiC_output(e1);
- else /* else delay output */
- ;
-
- if (EiC_gettype(e1->Type) != t_pointer) {
- EiC_error("Pointer required");
- break;
- }
- if(isconst(e1->Type))
- c = 1;
- else if(isconstp(e1->Type))
- c = 2;
- e1->Type = EiC_succType(e1->Type);
- if(c==1)
- setConst(e1->Type);
- else if(c==2)
- setConstp(e1->Type);
-
- case '.':
- if(isconst(e1->Type))
- c = 1;
- else if( isconstp(e1->Type))
- c = 2;
-
- if(!isconst(e1->Type))
- EiC_output(e1);
- if (EiC_gettype(e1->Type) == t_lval) {
- e1->Type = EiC_succType(e1->Type);
- e1->Pflag = 1;
- }
- if (EiC_gettype(e1->Type) == t_struct ||
- EiC_gettype(e1->Type) == t_union) {
- STRUCT_MEMBER_TYPE++;
- if (EiC_lexan() == ID &&
- (t = findmem(e1->Type, token->Val.sym->id)) >= 0) {
- struct_t *S;
- val_t v;
- S = (void *) EiC_getInf(e1->Type);
- if(!isconst(e1->Type)) {
- EiC_output(e1);
- if (S->offset[t] > 0) {
- v.ival = 1;
- EiC_generate(&e1->Code, bump, &v, 0);
- v.ival = S->offset[t];
- EiC_generate(&e1->Code, pushint, &v, 0);
- EiC_generate(&e1->Code, addptr2int, &v, 0);
- }
- } else if (S->offset[t] > 0) {
- /* handle constants */
-
- e1->Val.p.p = (char*) e1->Val.p.p + S->offset[t];
- e1->Val.p.sp = e1->Val.p.p;
- e1->Val.p.ep = (char *) e1->Val.p.p + 1;
-
-
- }
-
- EiC_freetype(e1->Type);
- e1->Type = EiC_copytype(S->type[t]);
- if(c == 1)
- e1->Type = EiC_addtype(t_pointer,e1->Type);
- else
- e1->Type = EiC_addtype(t_lval, e1->Type);
- e1->Pflag = 0;
- if (EiC_gettype(token->Val.sym->type) == ID)
- EiC_remsym(token->Val.sym);
- } else
- EiC_error("Illegal structure operation");
- STRUCT_MEMBER_TYPE--;
- } else
- EiC_error("Illegal structure operation");
- if(c==1)
- setConst(e1->Type);
- else if(c==2)
- setConstp(e1->Type);
-
- EiC_r_postfix_expr(e1);
- break;
-#else
- EiC_output(e1);
- if (EiC_gettype(e1->Type) != t_pointer) {
- EiC_error("Pointer required");
- break;
- }
- if(isconst(e1->Type) || isconstp(e1->Type))
- c = 1;
- e1->Type = EiC_succType(e1->Type);
- if(c)
- setConstp(e1->Type);
- case '.':
- if(isconst(e1->Type) || isconstp(e1->Type))
- c = 1;
- EiC_output(e1);
- if (EiC_gettype(e1->Type) == t_lval) {
- e1->Type = EiC_succType(e1->Type);
- e1->Pflag = 1;
- }
- if (EiC_gettype(e1->Type) == t_struct ||
- EiC_gettype(e1->Type) == t_union) {
- STRUCT_MEMBER_TYPE++;
- if (EiC_lexan() == ID &&
- (t = findmem(e1->Type, token->Val.sym->id)) >= 0) {
- struct_t *S;
- val_t v;
- S = (void *) EiC_getInf(e1->Type);
- EiC_output(e1);
- if (S->offset[t] > 0) {
- v.ival = 1;
- EiC_generate(&e1->Code, bump, &v, 0);
- v.ival = S->offset[t];
- EiC_generate(&e1->Code, pushint, &v, 0);
- EiC_generate(&e1->Code, addptr2int, &v, 0);
- }
- EiC_freetype(e1->Type);
- e1->Type = EiC_copytype(S->type[t]);
- e1->Type = EiC_addtype(t_lval, e1->Type);
- e1->Pflag = 0;
- if (EiC_gettype(token->Val.sym->type) == ID)
- EiC_remsym(token->Val.sym);
- } else
- EiC_error("Illegal structure operation");
- STRUCT_MEMBER_TYPE--;
- } else
- EiC_error("Illegal structure operation");
- if(c)
- setConstp(e1->Type);
- EiC_r_postfix_expr(e1);
- break;
-#endif
- case '(': /* handle function calls */
-
- if(isconst(e1->Type)) {
- EiC_error("Function names cannot be constants");
- EiC_match(')', " )"); /* ignore up to next paren */
- break;
- }
-
- if (EiC_gettype(e1->Type) != t_lval)
- EiC_output(e1);
-
-
- if(nextType(e1->Type))
- e1->Type = EiC_succType(e1->Type);
- t=EiC_gettype(e1->Type);
-
- if(EiC_gettype(e1->Type) == t_pointer) {
- EiC_generate(&e1->Code,
- issafe(e1->Type)?drefptr:drefuptr,
- &e1->Val,0);
- e1->Type = EiC_succType(e1->Type);
- }
-
- t=EiC_gettype(e1->Type);
-
-
- if(t == t_func || t == t_funcdec || t == t_builtin) {
-
- if(EiC_getInf(e1->Type)) {
- val_t v;
- token_t e2;
- int c;
-
- EiC_inittoken(&e2);
-
- c = arg_expr_list(e1,&e2);
-
- v.ival = 1;
- EiC_generate(&e1->Code, bump, &v, 0);
- if (c) {
- v.ival = c;
- EiC_generate(&e1->Code, checkar, &v, 1);
- }
- EiC_contoken(e1, &e2);
-
- e1->Type = EiC_addtype(t_lval, e1->Type);
- e1->Pflag = 0;
- } else
- EiC_error("Incorrect function usage: %s",
- e1->Sym->id);
- } else
- EiC_error("Incorrect function usage: %s",
- e1->Sym->id);
-
- EiC_match(')', " )");
- setConstp(e1->Type);
- EiC_r_postfix_expr(e1);
- break;
- default:
- retractlexan();
- }
-}
-
-
-
-static int arg_expr_list(token_t * E1, token_t * e1)
-{
- int EiC_genCallBackCode(token_t * e1);
- token_t * EiC_genTemporay(type_expr *type, int level);
- token_t e2;
- int t, t2, Svar = 0, aggparm = 0;
- val_t v;
- int ext = 0,count = 0;
- func_t *f;
- token_t *e3;
- int EiC_IsFunc(int);
- int BuiltIn;
-
-
- if(EiC_HasHiddenParm(E1->Type)) {
- /* need to now generate temporary variable */
- e3 = EiC_genTemporay(nextType(E1->Type),EiC_S_LEVEL);
- EiC_output(e3);
- /* concatenate code */
- EiC_concode(&e1->Code,&e3->Code);
- xfree(e3);
- EiC_generate(&e1->Code, stoval, &e1->Val, t_hidden);
- count++;
- ext = -1;
- }
-
- f = EiC_getInf(E1->Type);
- BuiltIn = EiC_gettype(E1->Type) == t_builtin;
-
- do {
- EiC_inittoken(&e2);
- EiC_assign_expr(&e2);
- if(BuiltIn)
- if(EiC_IsFunc(EiC_gettype(e2.Type))) {
- if(EiC_gettype(e2.Type) == t_pointer && EiC_IsFunc(EiC_gettype(nextType(e2.Type))))
- e2.Type = EiC_succType(e2.Type);
- EiC_genCallBackCode(&e2);
- }
-
- if ((t = EiC_gettype(e2.Type)) != t_void) {
-
- e1->Type = getFPty(f,Svar);
-
- t2 = EiC_gettype(e1->Type);
- if(t2 == t_void)
- EiC_error("Illegal parameter no. [%d]",count+1);
-
- if(t == t_struct || t== t_union) {
- if(!isconst(e2.Type) && !IsTemp(e2.Type)) {
- e3 = EiC_genTemporay(e2.Type,EiC_S_LEVEL);
- EiC_output(e3);
- /* concatenate code */
- EiC_concode(&e2.Code,&e3->Code);
- xfree(e3);
- aggparm = 1;
- v.ival = 1;
- EiC_generate(&e2.Code, bump, &v, t_hidden);
- }
- if(t2 == t_var) /* EiC doesn't allow this */
- EiC_error("passing a struct/union to variadic"
- " function `%s'",E1->Sym->id);
- }
-
- if (!isconst(e2.Type)) {
- if(BuiltIn && (EiC_IsFunc(EiC_gettype(e2.Type)))) { /* call back code */
- v.p.p = getFcallBack((func_t*)EiC_getInf(e2.Type));
- EiC_generate(&e2.Code,pushptr,&v,0);
- e2.Type = EiC_addtype(t_pointer, e2.Type);
- } else
- EiC_output(&e2);
- if (t2 != t_var)
- EiC_castvar(&e2, e1, 0);
- } else { /* small bit of optimisation */
- if (t2 != t_var)
- EiC_castconst(&e2, e1, 0);
- EiC_output(&e2);
- }
- if(aggparm) { /* passing a structure or union */
- v.ival = EiC_get_sizeof(e2.Type);
- EiC_generate(&e2.Code,refmem,&v,0);
- aggparm = 0;
- }
- v.ival = count;
- EiC_generate(&e2.Code, stoval, &v, EiC_gettype(e1->Type));
-
-
- /* collect parameters in reverse order */
- EiC_concode(&e2.Code, &e1->Code);
- e1->Code = e2.Code;
- EiC_freetype(e2.Type);
- e1->Type = NULL;
- count++;
- if ((t2 != t_var) && (Svar < getFNp(f)-1))
- Svar++;
- } else {
- EiC_freetype(e2.Type);
- if (count + ext != 0) {
- EiC_error("Illegal void parameter no [%d]",count+1);
- } else
- ext++;
- }
- if (EiC_lexan() != ',') {
- v.ival = count;
- EiC_generate(&e1->Code, pushint, &v, 0);
- }
- } while (token->Tok == ',');
- retractlexan();
-
- t = EiC_gettype(getFPty(f,0));
-
-
- if((count == 0 && t != t_void && t != t_var) ||
- (count+ext != getFNp(f) && !EiC_IsVariadic(f) && t != t_var))
- EiC_error("Wrong number of arguments for %s",
- E1->Sym->id);
-
- return count;
-}
-
-
-static void primary_expr(token_t * e1)
-{
- extern int EiC_RETURNON;
- extern token_t *EiC_RETURNEXPR;
-
- switch (EiC_lexan()) {
- case '(':
- /*EiC_assign_expr(e1);*/
- expr(e1);
- EiC_match(')', " ) ");
- return;
- case CHAR:
- *e1 = *token;
- e1->Type = EiC_addtype(t_char, NULL);
- setConst(e1->Type);
- break;
- case INT:
- *e1 = *token;
- e1->Type = EiC_addtype(t_int, NULL);
- setConst(e1->Type);
- break;
- case UINT:
- *e1 = *token;
- e1->Type = EiC_addtype(t_uint, NULL);
- setConst(e1->Type);
- break;
- case LONG:
- *e1 = *token;
- e1->Type = EiC_addtype(t_long, NULL);
- setConst(e1->Type);
- break;
- case ULONG:
- *e1 = *token;
- e1->Type = EiC_addtype(t_ulong, NULL);
- setConst(e1->Type);
- break;
-
- case DOUBLE:
- *e1 = *token;
- e1->Type = EiC_addtype(t_double, NULL);
- setConst(e1->Type);
- break;
- case FLOAT:
- *e1 = *token;
- e1->Type = EiC_addtype(t_float, NULL);
- setConst(e1->Type);
- break;
- case STR:
- *e1 = *token;
- e1->Type = EiC_addtype(t_pointer, EiC_addtype(t_char,NULL));
- setConst(e1->Type);
- if (!EiC_RETURNON)
- xmark(e1->Val.p.p, eicgstring); /* garbage */
- else /* store string */
- EiC_add_func_str(EiC_getInf(EiC_RETURNEXPR->Type),
- e1->Val.p.p);
- break;
- case ID:
-
- e1->Type = EiC_copytype(token->Val.sym->type);
- e1->Val = token->Val.sym->val;
- e1->Sym = token->Val.sym;
- e1->Sclass = token->Val.sym->sclass;
-
-
- if(EiC_gettype(e1->Type) == t_ref) {
- int t = EiC_gettype(nextType(e1->Type));
- if(t == t_funcdec) {
- /* convert to builtin type
- * happens only once
- */
- e1->Type = EiC_succType(e1->Type);
- e1->Sym->type = EiC_succType(e1->Sym->type);
- EiC_exchtype(t_builtin,e1->Type);
- EiC_exchtype(t_builtin,e1->Sym->type);
- e1->Sym->val.vfunc = EiC_ENV->AR[e1->Val.ival].v.vfunc;
- } else if(t != t_array) { /* treat as an lvalue */
- EiC_output(e1);
- e1->Pflag = 0;
- e1->Type = EiC_succType(e1->Type);
- /*if(EiC_gettype(e1->Type) != t_pointer)*/
- e1->Type = EiC_addtype(t_lval,e1->Type);
- } else { /* make a safe pointer */
- e1->Type = EiC_succType(e1->Type);
- EiC_ENV->AR[e1->Val.ival].v.p.ep =
- (char*) EiC_ENV->AR[e1->Val.ival].v.p.sp + EiC_get_sizeof(e1->Type);
- generatePtr(e1);
- }
- } /*else
- generatePtr(e1);*/
-
- break;
- default:
- retractlexan();
- e1->Pflag = 0;
- e1->Type = EiC_addtype(t_void, e1->Type);
- break;
- }
-}
-
-int EiC_GI(token_t * e1)
-{
- /* returns -1 on error,
- * 1 if the type is automatic
- * 0 otherwise
- */
- if(e1 && e1->Sym)
- return (e1->Sym->level > 1 && !(e1->Sym->sclass & c_static));
- else
- return -1;
-}
-
-
-static void process_binary(void (*func) (token_t * e),
- token_t * e1, int op)
-{
- extern int EiC_checkPeepHole(token_t *e1,int op);
- token_t e2;
- val_t v;
-
-
- EiC_inittoken(&e2);
-
- (*func) (&e2);
-
- generatePtr(&e2);
- generatePtr(e1);
-
- if (!isconst(e1->Type))
- EiC_output(e1);
- if (!isconst(e2.Type))
- EiC_output(&e2);
-
- if(EiC_checkPeepHole(e1,op)) {
- if(EiC_gettype(e2.Type) < EiC_gettype(e1->Type)) {
- if(isconst(e2.Type))
- EiC_castconst(&e2,e1,1);
- else
- EiC_castvar(&e2,e1,1);
- }
- EiC_freetype(e1->Type);
- *e1 = e2;
- return;
- }
- if(EiC_checkPeepHole(&e2,op)) {
- if(EiC_gettype(e2.Type) > EiC_gettype(e1->Type)) {
- if(isconst(e1->Type))
- EiC_castconst(e1,&e2,1);
- else
- EiC_castvar(e1,&e2,1);
- }
- EiC_freetoken(&e2);
- return;
- }
-
- EiC_bin_validate(op, e1, &e2);
-
- if (isconst(e1->Type) && isconst(e2.Type)) {
- EiC_contoken(e1, &e2);
- e1->Pflag = 0;
- return;
- }
- if (/*isconst(e1->Type) && */ !e1->Pflag)
- EiC_output(e1);
-
- if(op != LAND) {
- v.ival = 1;
- EiC_generate(&e1->Code, bump, &v, 0);
- }
- EiC_contoken(e1, &e2);
-}
-
-
-static void assignop(void (*func) (token_t * e),
- token_t * e1, int op)
-{
- int t;
- token_t e2;
- val_t v;
- int op2;
-
- if (e1->Pflag || isconst(e1->Type) || isconstp(e1->Type))
- EiC_error("Illegal assignment operation");
-
- EiC_inittoken(&e2);
-
- generatePtr(&e2);
-
- switch (op) {
- case ADDEQ: op2 = '+'; break;
- case SUBEQ: op2 = '-'; break;
- case DIVEQ: op2 = '/'; break;
- case MULEQ: op2 = '*'; break;
- case MODEQ: op2 = '%'; break;
- case RSHTEQ: op2 = RSHT; break;
- case LSHTEQ: op2 = LSHT; break;
- case ANDEQ: op2 = AND; break;
- case BOREQ: op2 = BOR; break;
- case XOREQ: op2 = XOR; break;
- default: /* do equals */
- op2 = 0;
- (*func) (&e2);
- }
-
- t = EiC_gettype(e1->Type);
- if((t == t_struct || t == t_union) && check4constmem(e1->Type))
- EiC_error("Illegal assignment operation");
-
- if (op2) {
- e2.Type = EiC_copytype(e1->Type);
- e2.Val = e1->Val;
- e2.Sym = e1->Sym;
- if (t == t_lval || t == t_struct || t == t_union) {
- v.ival = 1;
- EiC_generate(&e1->Code, dupval, &v, 0);
- }
- EiC_concode(&e2.Code, &e1->Code);
- process_binary(func, &e2, op2);
- }
-
- /*
- * check 4 assignment of pointer to const X to
- * pointer to X: this is illegal.
- */
- if(t == t_pointer && EiC_gettype(e2.Type) == t_pointer) {
- if(ConstIntegrity(nextType(e1->Type),nextType(e2.Type)))
- EiC_error("Assignment loses a const qualifier");
- if(!EiC_compareSafe(nextType(e1->Type),nextType(e2.Type)))
- EiC_error("Casting between safe and unsafe address");
- }
-
- if (isconst(e2.Type)) {
- void EiC_SaveGlobalString(ptr_t *s);
- extern int EiC_RETURNON;
- EiC_castconst(&e2, e1, 0);
- if(!EiC_RETURNON && EiC_gettype(e2.Type) == t_pointer
- && EiC_gettype(nextType(e2.Type)) == t_char &&
- !e2.Sym) {
- /* got string */
- /* Note: string is markged for garbage collector */
- EiC_SaveGlobalString(&e2.Val.p);
- }
- EiC_output(&e2);
- } else {
- EiC_output(&e2);
- EiC_castvar(&e2, e1, 0);
- }
- if (!e2.Pflag)
- EiC_error("Invalid assignment");
-
- if (t == t_lval || t == t_struct || t == t_union) {
- if(!op2) {
- v.ival = 1;
- if(!e1->Code.nextinst) {
- EiC_output(e1);
- }
- if(t==t_struct || t == t_union) {
- EiC_generate(&e1->Code, bump, &v, 0);
- v.ival = EiC_get_sizeof(e2.Type);
- EiC_generate(&e2.Code,refmem,&v,0);
- } else
- EiC_generate(&e1->Code, bump, &v, 0);
-
-
- } else
- EiC_concode(&e2.Code, &e1->Code);
- }
- EiC_contoken(e1, &e2);
- EiC_do_stooutput(e1);
- /* assignments can't form lvalues */
- setConstp(e1->Type);
-}
-
-static int findmem(type_expr * t, char *id)
-{
- int i;
- struct_t *S = (struct_t *)EiC_getInf(t);
- for (i = 0; i < S->n; i++)
- if (strcmp(id, S->id[i]) == 0)
- return i;
-
- return -1;
-}
-
-static int check4constmem(type_expr *t)
-{
- struct_t *S = (struct_t *)EiC_getInf(t);
- int i;
- for(i=0;i<S->n;i++)
- if(isconstp(S->type[i]))
- return 1;
- return 0;
-}
-
-