📄 expr.c
字号:
/*
Copyright 1994-2003 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
This program is derived from the cc68k complier by
Matthew Brandt (mattb@walkingdog.net)
You may contact the author of this derivative at:
mailto::camille@bluegrass.net
or by snail mail at:
David Lindauer
850 Washburn Ave Apt 99
Louisville, KY 40222
*/
/*
* Evaluate expressions very recursive descent. MAke sure your STACK
* is large enough to parse the expressions you want to parse. a 4K stack
* will handle all but the very extreme cases
*/
#include <stdio.h>
#include <string.h>
#include <float.h>
#include "lists.h"
#include "expr.h"
#include "c.h"
#include "ccerr.h"
#include "lists.h"
#include "rtti.h"
#include "diag.h"
extern int inprototype;
extern int prm_c99;
extern int cantnewline;
extern int prm_ansi ;
extern int defaulttype;
extern int stdpragmas;
extern int indefaultinit;
extern SNODE *cbautoinithead, *cbautoinittail;
extern int lineno;
extern int prm_bss;
extern ENODE *block_rundown;
extern int lastch;
extern TYP *head, **headptr;
extern LIST *instantiated_inlines;
extern int stdretblocksize, stdintsize, stddefalignment;
extern int stdshortsize, stdlongsize, stdlonglongsize, stdfloatsize, stddoublesize, stdldoublesize;
extern int block_nesting;
extern int global_flag;
extern enum e_sym lastst;
extern char lastid[], laststr[];
extern TABLE *gsyms, lsyms;
extern LLONG_TYPE ival;
extern long double rval;
extern int skm_declcomma[], skm_declclosepa[];
extern TABLE *tagtable;
extern char declid[100];
extern int goodcode;
extern int prm_cplusplus;
extern int regdsize, regasize, regfsize, stackadd, stackmod;
extern int stdaddrsize;
extern long nextlabel;
extern SYM *declclass;
extern int prm_cmangle;
extern SYM *currentfunc;
extern int stdmemberptrsize;
extern int laststrlen;
extern SYM *typequal;
extern char *cpp_funcname_tab[];
extern int nonslookup;
extern int bssbytes, databytes, constbytes;
extern SYM *dynamic_cast_func;
extern int prm_xcept;
extern SYM *typeinfo_class;
extern SYM *get_typeinfo_func;
extern int skm_declend[];
extern SYM *throw_func;
extern SYM *rethrow_func;
extern int conscount;
SYM *parm_namespaces[20][100];
int parm_ns_counts[20];
int parm_ns_level;
int parsing_params;
ENODE *expr_runup[50];
ENODE *expr_rundown[50];
int expr_updowncount = 0;
/* Default types */
extern TYP stdint, stdlongdouble, stduns, stdstring;
extern TYP stdfloat, stdimaginary, stddouble, stdrimaginary;
extern TYP stdlonglong,stdunsignedlonglong, stdunsigned;
TYP stdvoid =
{
bt_matchall, 0, 0, - 1, - 1, 4
};
TYP stdmatch =
{
bt_matchall, 0, UF_DEFINED | UF_USED, - 1, - 1, 4, 0, &stdvoid
};
TYP stdchar =
{
bt_char, 0, 0, - 1, - 1, 1
};
TYP stdbool =
{
bt_char, 0, 0, - 1, - 1, 1
};
TYP stdfunc =
{
bt_func, 1, UF_DEFINED | UF_USED, - 1, - 1, 0, 0, &stdint
};
TYP stdvoidfunc =
{
bt_func, 1, UF_DEFINED | UF_USED, - 1, - 1, 0, 0, &stdvoid, 0,
{
- 1, 0
}
};
int skm_closepa[] =
{
closepa, comma, semicolon, end, 0
};
int skm_closebr[] =
{
closebr, comma, openbr, semicolon, end, 0
};
SYM undef;
SYM *thissp;
int nodeclfunc;
static int dummyram;
static int dumpos;
static ENODE *thisx;
static SYM *lastsym;
static char regname[] = "processor reg";
static char *nm = 0;
static TABLE defalt_table;
TYP *asntyp = 0, *andtyp = 0;
static int global_deref = 0;
ENODE *thisenode;
int intemplateargs;
void exprini(void)
{
ENODE *newnode;
SYM *sp;
intemplateargs = 0;
andtyp = asntyp = 0;
dumpos = 0;
undef.value.i = 0;
undef.name = "UNDEFINED";
undef.mainsym = &undef;
global_deref = 0;
thissp = sp = makesym(sc_auto);
sp->tp = maketype(bt_int, stdintsize); // dummy so backend is happy
sp->name = "**THIS**";
sp->value.classdata.defalt = 0;
sp->extflag = FALSE;
sp->absflag = FALSE;
sp->intflag = FALSE;
sp->faultflag = FALSE;
sp->pascaldefn = FALSE;
sp->isstdcall = FALSE;
sp->init = 0;
sp->indecltable = 0;
sp->funcparm = 1;
sp->inreg = 0;
sp->staticlabel = FALSE;
sp->value.i = stdretblocksize;
thisenode = makenode(en_autocon, sp, 0);
dummyram = 0;
nodeclfunc = 0;
}
//-------------------------------------------------------------------------
TYP *basictype(TYP *t)
{
while (t->type == bt_cond)
t = t->btp;
return t;
}
//-------------------------------------------------------------------------
int retvalsize(TYP *t)
{
int rv = 0;
if (t->type == bt_ref)
{
t = t->btp;
if (!isstructured(t))
rv = 100000;
// reference return
}
switch (t->type)
{
case bt_void:
return 0;
case bt_farpointer:
return rv + BESZ_FARPTR;
case bt_bool:
return BESZ_BOOL;
case bt_char:
case bt_short:
case bt_int:
case bt_long:
case bt_longlong:
if (t->size == 8)
return rv - BESZ_QWORD;
else
return rv + - (t->size);
case bt_unsignedchar:
case bt_unsignedshort:
case bt_unsigned:
case bt_unsignedlong:
case bt_unsignedlonglong:
if (t->size == 8)
return rv + BESZ_QWORD;
else
return rv + (t->size);
case bt_float:
return rv + BESZ_FLOAT;
case bt_double:
return rv + BESZ_DOUBLE;
case bt_longdouble:
return rv + BESZ_LDOUBLE;
case bt_fimaginary:
return rv + BESZ_IFLOAT;
case bt_rimaginary:
return rv + BESZ_IDOUBLE;
case bt_lrimaginary:
return rv + BESZ_ILDOUBLE;
case bt_fcomplex:
return rv + BESZ_CFLOAT;
case bt_rcomplex:
return rv + BESZ_CDOUBLE;
case bt_lrcomplex:
return rv + BESZ_CLDOUBLE;
default:
return rv - stdintsize;
}
}
//-------------------------------------------------------------------------
ENODE *makenode(enum e_node nt, char *v1, char *v2)
/*
* build an expression node with a node type of nt and values
* v1 and v2.
*/
{
ENODE *ep;
ep = xalloc(sizeof(ENODE));
ep->nodetype = nt;
ep->cflags = 0;
ep->v.p[0] = v1;
ep->v.p[1] = v2;
return ep;
} ENODE *makeintnode(enum e_node nt, LLONG_TYPE val)
{
ENODE *ep;
ep = xalloc(sizeof(ENODE));
ep->nodetype = (char)nt;
ep->cflags = 0;
ep->v.i = val;
return ep;
} TYP *deref(ENODE **node, TYP *tp)
/*
* build the proper dereference operation for a node using the
* type pointer tp.
*/
{
ENODE *onode = *node;
if ((*node)->nodetype == en_placeholder)
return tp;
switch (tp->type)
{
case bt_double:
*node = makenode(en_doubleref, *node, 0);
break;
case bt_longdouble:
*node = makenode(en_longdoubleref, *node, 0);
break;
case bt_float:
*node = makenode(en_floatref, *node, 0);
break;
case bt_fimaginary:
*node = makenode(en_fimaginaryref, *node, 0);
break;
case bt_rimaginary:
*node = makenode(en_rimaginaryref, *node, 0);
break;
case bt_lrimaginary:
*node = makenode(en_lrimaginaryref, *node, 0);
break;
case bt_fcomplex:
*node = makenode(en_fcomplexref, *node, 0);
break;
case bt_rcomplex:
*node = makenode(en_rcomplexref, *node, 0);
break;
case bt_lrcomplex:
*node = makenode(en_lrcomplexref, *node, 0);
break;
case bt_unsignedchar:
*node = makenode(en_ub_ref, *node, 0);
break;
case bt_unsignedshort:
*node = makenode(en_uw_ref, *node, 0);
break;
case bt_char:
*node = makenode(en_b_ref, *node, 0);
break;
case bt_bool:
*node = makenode(en_bool_ref, *node, 0);
break;
case bt_short:
*node = makenode(en_w_ref, *node, 0);
break;
case bt_unsigned:
*node = makenode(en_ui_ref, *node, 0);
break ;
case bt_enum:
case bt_unsignedlong:
*node = makenode(en_ul_ref, *node, 0);
break;
case bt_farpointer:
*node = makenode(en_fp_ref, *node, 0);
break;
case bt_ref:
case bt_pointer:
*node = makenode(en_a_ref, *node, 0);
break;
case bt_int:
*node = makenode(en_i_ref, *node, 0);
break;
case bt_long:
case bt_matchall:
*node = makenode(en_l_ref, *node, 0);
break;
case bt_longlong:
case bt_memberptr:
*node = makenode(en_ll_ref, *node, 0);
break;
case bt_unsignedlonglong:
*node = makenode(en_ull_ref, *node, 0);
break;
case bt_struct:
case bt_union:
case bt_class:
break;
default:
generror(ERR_DEREF, 0, 0);
break;
}
(*node)->cflags = onode->cflags;
return tp;
}
//-------------------------------------------------------------------------
int checkstructconst(TYP *tp)
{
SYM *sp = tp->lst.head;
while (sp)
{
if (isstructured(sp->tp))
{
if (checkstructconst(sp->tp))
return TRUE ;
}
if (sp->tp->type != bt_func && sp->tp->type != bt_defunc)
{
if (sp->tp->cflags &DF_CONST)
{
generror(ERR_MODCONS, 0, 0);
return TRUE;
}
}
sp = sp->next;
}
return FALSE;
}
//-------------------------------------------------------------------------
ENODE *sbll(SYM *sp_in, ENODE *en, ENODE *ep1)
{
ENODE *epx = 0;
if (prm_cplusplus)
{
SYM *sp1 = search(cpp_funcname_tab[CI_CONSTRUCTOR], &sp_in->tp->lst);
if (sp1)
{
SYM *sp;
#ifdef XXXXX
SYM *sm = makesym(0);
TYP tp;
memset(&tp, 0, sizeof(tp));
tp.type = bt_func;
tp.lst.head = tp.lst.tail = sp_in;
tp.sp = sm;
sm->tp = &tp;
#endif
sp = funcovermatch(sp1, sp_in->tp, makenode(en_void, en, 0), FALSE,
FALSE);
if (sp)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -