Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
b1fb36c56This file is pinned to the selected release. Download the original to open it in your design tool.
/* $VER: vbcc (parse_expr.c) $Revision: 1.18 $ */
#include "vbcc_cpp.h"
#include "vbc.h"
static char FILE_[]=__FILE__;
np new_node(void)
{
np p=mymalloc(NODES);
p->flags=0;
p->lvalue=0;
p->sidefx=0;
p->ntyp=0;
p->left=0;
p->right=0;
p->alist=0;
p->identifier=0;
p->o.flags=0;
return p;
}
np expression(void)
/* Komma-Ausdruecke */
{
np left,right,new;
left=assignment_expression();
if(!left->flags) return 0;
killsp();
while(ctok->type==COMMA){
#ifdef HAVE_MISRA
/* removed */
#endif
next_token();
killsp();
right=assignment_expression();
new=new_node();
new->left=left;
new->right=right;
new->ntyp=0;
new->flags=KOMMA;
left=new;
killsp();
}
return left;
}
np assignment_expression(void)
/* Zuweisungsausdruecke */
{
np left,new;int c=ASSIGNOP,op;
left=conditional_expression();
killsp();
switch(ctok->type){
case ASGN: c=ASSIGN;break;
case ASSTAR: op=MULT;break;
case ASSLASH: op=DIV;break;
case ASPCT: op=MOD;break;
case ASPLUS: op=ADD;break;
case ASMINUS: op=SUB;break;
case ASAND: op=AND;break;
case ASCIRC: op=XOR;break;
case ASOR: op=OR;break;
case ASLSH: op=LSHIFT;break;
case ASRSH: op=RSHIFT;break;
default:
return left;
}
next_token();
new=new_node();
new->left=left;
new->ntyp=0;
if(c==ASSIGN){
new->right=assignment_expression();
new->flags=ASSIGN;
}else{
/* ASSIGNOP(a,b)->ASSIGN(a,OP(a,b)) */
new->flags=ASSIGNOP; /* nur um zum Merken, dass nur einmal */
/* ausgewertet werden darf */
new->right=new_node();
new->right->left=left;
new->right->right=assignment_expression();
new->right->ntyp=0;
new->right->flags=op;
}
return new;
}
np conditional_expression(void)
/* Erledigt ? : */
{
np left,new;
left=logical_or_expression();
killsp();
if(ctok->type==QUEST){
next_token();killsp();
new=new_node();
new->flags=COND;
new->ntyp=0;
new->left=left;
new->right=new_node();
new->right->flags=COLON;
new->right->ntyp=0;
new->right->left=expression();
killsp();
if(ctok->type==T_COLON){next_token();killsp();} else error(70);
new->right->right=conditional_expression();
left=new;
killsp();
}
return left;
}
np logical_or_expression(void)
/* Erledigt || */
{
np left,right,new;int bra;
if(ctok->type==LPAR) bra=1; else bra=0;
left=logical_and_expression();
killsp();
while(ctok->type==T_LOR){
#ifdef HAVE_MISRA
/* removed */
#endif
next_token();
killsp();
if(ctok->type==LPAR) bra=1; else bra=0;
right=logical_and_expression();
#ifdef HAVE_MISRA
/* removed */
#endif
new=new_node();
new->left=left;
new->right=right;
new->flags=LOR;
new->ntyp=0;
left=new;
killsp();
if(ctok->type==T_LAND) error(222);
}
return left;
}
np logical_and_expression(void)
/* Erledigt && */
{
np left,right,new;int bra;
if(ctok->type==LPAR) bra=1; else bra=0;
left=inclusive_or_expression();
killsp();
while(ctok->type==T_LAND){
#ifdef HAVE_MISRA
/* removed */
#endif
next_token();
killsp();
if(ctok->type==LPAR) bra=1; else bra=0;
right=inclusive_or_expression();
#ifdef HAVE_MISRA
/* removed */
#endif
new=new_node();
new->left=left;
new->right=right;
new->flags=LAND;
new->ntyp=0;
left=new;
killsp();
if(ctok->type==T_LOR) error(222);
}
return left;
}
np inclusive_or_expression(void)
/* Erledigt | */
{
np left,right,new;
left=exclusive_or_expression();
killsp();
while(ctok->type==T_OR){
next_token();
killsp();
right=exclusive_or_expression();
new=new_node();
new->left=left;
new->right=right;
new->flags=OR;
new->ntyp=0;
left=new;
killsp();
}
return left;
}
np exclusive_or_expression(void)
/* Erledigt ^ */
{
np left,right,new;
left=and_expression();
killsp();
while(ctok->type==CIRC){
next_token();
killsp();
right=and_expression();
new=new_node();
new->left=left;
new->right=right;
new->flags=XOR;
new->ntyp=0;
left=new;
killsp();
}
return left;
}
np and_expression(void)
/* Erledigt & */
{
np left,right,new;
left=equality_expression();
killsp();
while(ctok->type==T_AND){
next_token();
killsp();
right=equality_expression();
new=new_node();
new->left=left;
new->right=right;
new->flags=AND;
new->ntyp=0;
left=new;
killsp();
}
return left;
}
np equality_expression(void)
/* Erledigt == und != */
{
np left,right,new;int c;
left=relational_expression();
killsp();
while(ctok->type==SAME||ctok->type==NEQ){
if(ctok->type==NEQ) c=INEQUAL; else c=EQUAL;
next_token();
killsp();
right=relational_expression();
new=new_node();
new->left=left;
new->right=right;
new->flags=c;
new->ntyp=0;
left=new;
killsp();
}
return left;
}
np relational_expression(void)
/* Erledigt <,>,<=,>= */
{
np left,right,new;int c;
left=shift_expression();
killsp();
while(ctok->type==LT||ctok->type==GT||ctok->type==LEQ||ctok->type==GEQ){
if(ctok->type==LT) c=LESS;
else if(ctok->type==GT) c=GREATER;
else if(ctok->type==LEQ) c=LESSEQ;
else c=GREATEREQ;
next_token();
killsp();
right=shift_expression();
new=new_node();
new->left=left;
new->right=right;
new->flags=c;
new->ntyp=0;
left=new;
killsp();
}
return left;
}
np shift_expression(void)
/* Erledigt <<,>> */
{
np left,right,new;int c;
left=additive_expression();
killsp();
while(ctok->type==LSH||ctok->type==RSH){
if(ctok->type==LSH)
c=LSHIFT;
else
c=RSHIFT;
next_token();
killsp();
right=additive_expression();
new=new_node();
new->left=left;
new->right=right;
new->flags=c;
new->ntyp=0;
left=new;
killsp();
}
return left;
}
np additive_expression(void)
/* Erledigt +,- */
{
np left,right,new;int c;
left=multiplicative_expression();
killsp();
while(ctok->type==PLUS||ctok->type==T_MINUS){
if(ctok->type==PLUS) c=ADD; else c=SUB;
next_token();killsp();
right=multiplicative_expression();
new=new_node();
new->left=left;
new->right=right;
new->flags=c;
new->ntyp=0;
left=new;
killsp();
}
return left;
}
np multiplicative_expression(void)
/* Erledigt *,/,% */
{
np left,right,new;int c;
left=cast_expression();
killsp();
while(ctok->type==STAR||ctok->type==SLASH||ctok->type==PCT){
if(ctok->type==STAR) c=MULT;
else if(ctok->type==SLASH) c=DIV;
else c=MOD;
next_token();killsp();
right=cast_expression();
new=new_node();
new->left=left;
new->right=right;
new->flags=c;
new->ntyp=0;
left=new;
killsp();
}
return left;
}
np cast_expression(void)
/* Erledigt (typ) */
{
np new;char *imerk,buff[MAXI];
killsp();
if(ctok->type!=LPAR||!declaration(1)) return unary_expression();
next_token();killsp();
new=new_node();
new->right=0;
buff[0]=0;
imerk=ident;ident=buff;
new->ntyp=declarator(declaration_specifiers());
ident=imerk;
if(buff[0]) error(356);
killsp();
if(ctok->type!=RPAR) error(59); else next_token();
killsp();
if(c99&&ctok->type==LBRA){
/* compund literals */
init_dyn_cnt=0;
new->cl=initialization(new->ntyp,nesting!=0,0,0,0,0);
killsp();
if(new->cl){
if(ISARRAY(new->ntyp->flags)&&zmeqto(new->ntyp->size,l2zm(0L))){
const_list *p=new->cl;
while(p){new->ntyp->size=zmadd(p->idx,l2zm(1L));p=p->next;}
}
}
new->flags=LITERAL;
new->left=0;
new->val.vmax=l2zm((long)init_dyn_cnt);
}else{
new->flags=CAST;
new->left=cast_expression();
}
return new;
}
np unary_expression(void)
/* Erledigt !,~,++,--,+,-,*,&,sizeof,__typeof */
{
np new;char *merk;
killsp();
if(ctok->type!=NAME&&ctok->type!=PLUS&&ctok->type!=PPLUS&&ctok->type!=T_MINUS&&ctok->type!=MMINUS&&ctok->type!=T_AND&&ctok->type!=STAR&&ctok->type!=NOT&&ctok->type!=LNOT)
return postfix_expression();
if(ctok->type==NAME){
enum {SIZEOF,TYPEOF,ALIGNOF,OFFSETOF} op;
if(strcmp("sizeof",ctok->name)&&strcmp("__typeof",ctok->name)&&strcmp("__alignof",ctok->name)&&strcmp("__offsetof",ctok->name)){
return postfix_expression();
}else{
if(*ctok->name=='s')
op=SIZEOF;
else if(ctok->name[2]=='a')
op=ALIGNOF;
else if(ctok->name[2]=='t')
op=TYPEOF;
else
op=OFFSETOF;
next_token();
killsp();
new=new_node();
new->flags=CEXPR;
new->ntyp=new_typ();
if(op==SIZEOF||op==OFFSETOF){
if(HAVE_INT_SIZET)
new->ntyp->flags=(UNSIGNED|INT);
else
new->ntyp->flags=(UNSIGNED|LONG);
}else
new->ntyp->flags=INT;
new->right=0;
new->left=0;
if(ctok->type==LPAR&&declaration(1)){
type *t;
next_token();killsp();
buff[0]=0;
merk=ident;ident=buff;
t=declarator(declaration_specifiers());
if(type_uncomplete(t)) error(176);
ident=merk;
if(buff[0]) error(356);
if(op==OFFSETOF){
if(ctok->type==COMMA)
next_token();
else
error(57);
if(ctok->type!=NAME) error(76);
if(t->flags!=STRUCT){
error(310);
vumax=ul2zum(0UL);
}else
vumax=zm2zum(struct_offset(t->exact,ctok->name));
next_token();
if(HAVE_INT_SIZET)
new->val.vuint=zum2zui(vumax);
else
new->val.vulong=zum2zul(vumax);
}else if(op==SIZEOF){
if(is_vlength(t)){
new->dsize=vlength_szof(t);
new->flags=IDENTIFIER;
new->val.vmax=l2zm(0L);
new->sidefx=0;
new->identifier=empty;
}else{
if(HAVE_INT_SIZET)
new->val.vuint=zum2zui(zm2zum(szof(t)));
else
new->val.vulong=zum2zul(zm2zum(szof(t)));
}
}else if(op==ALIGNOF){
new->val.vint=zm2zi(falign(t));
}else if(op==TYPEOF){
new->val.vint=zm2zi(l2zm(t->flags));
}
freetyp(t);
killsp();
if(ctok->type!=RPAR) error(59); else next_token();
}else{
np tree;
if(op==OFFSETOF) error(0);
killsp();
tree=unary_expression();
if(!tree||!type_expression(tree,0)){
if(op==SIZEOF){
if(HAVE_INT_SIZET)
new->val.vuint=zum2zui(ul2zum(0UL));
else
new->val.vulong=zum2zul(ul2zum(0UL));
error(73);
}else{
new->val.vint=zm2zi(l2zm(-1L));
}
}else{
if(op==SIZEOF){
#ifdef HAVE_MISRA
/* removed */
#endif
if(type_uncomplete(tree->ntyp)) error(176);
if(is_vlength(tree->ntyp)){
new->dsize=vlength_szof(tree->ntyp);
new->flags=IDENTIFIER;
new->val.vmax=l2zm(0L);
new->sidefx=0;
new->identifier=empty;
}else{
if(HAVE_INT_SIZET)
new->val.vuint=zum2zui(zm2zum(szof(tree->ntyp)));
else
new->val.vulong=zum2zul(zm2zum(szof(tree->ntyp)));
}
}else{
if(op==ALIGNOF)
new->val.vint=zm2zi(falign(tree->ntyp));
else
new->val.vint=zm2zi(l2zm(tree->ntyp->flags));
}
}
if(tree) free_expression(tree);killsp();
}
return new;
}
}
new=new_node();
new->right=0;
new->ntyp=0;
if(ctok->type==PLUS){
next_token();
free(new);
return cast_expression();
}else if(ctok->type==T_MINUS){
next_token();
new->left=cast_expression();
new->flags=MINUS;
}else if(ctok->type==PPLUS){
next_token();
new->left=unary_expression();
new->flags=PREINC;
}else if(ctok->type==MMINUS){
next_token();
new->left=unary_expression();
new->flags=PREDEC;
}else if(ctok->type==T_AND){
next_token();
new->left=cast_expression();
new->flags=ADDRESS;
}else if(ctok->type==STAR){
next_token();
new->left=cast_expression();
new->flags=CONTENT;
}else if(ctok->type==NOT){
next_token();
new->left=cast_expression();
new->flags=KOMPLEMENT;
}else if(ctok->type==LNOT){
next_token();
new->left=cast_expression();
new->flags=NEGATION;
}
new->right=0;
new->ntyp=0;
return new;
}
np postfix_expression(void)
/* Erledigt [],(),.,->,++,-- */
{
np new,left;
left=primary_expression();
killsp();
while(ctok->type==LBRK||ctok->type==LPAR||ctok->type==DOT||ctok->type==ARROW||ctok->type==PPLUS||ctok->type==MMINUS){
new=new_node();
new->ntyp=0;
new->right=0;
new->left=left;
if(ctok->type==MMINUS){
next_token();
new->flags=POSTDEC;
}else if(ctok->type==ARROW){
next_token(); killsp();
new->flags=DSTRUCT;
new->right=identifier_expression();
new->right->flags=MEMBER;
new->left=new_node();
new->left->ntyp=0;
new->left->left=left;
new->left->right=0;
new->left->flags=CONTENT;
}else if(ctok->type==LBRK){
next_token(); killsp();
new->flags=CONTENT;
new->left=new_node();
new->left->flags=ADD;
new->left->ntyp=0;
new->left->left=left;
new->left->right=expression();
killsp();
if(ctok->type!=RBRK) error(62); else next_token();
}else if(ctok->type==PPLUS){
next_token();
new->flags=POSTINC;
}else if(ctok->type==DOT){
next_token();killsp();
new->right=identifier_expression();
new->flags=DSTRUCT;
new->right->flags=MEMBER;
}else if(ctok->type==LPAR){
argument_list *al,*first_alist=0,*last_alist=0;np n;
#ifdef HAVE_MISRA
/* removed */
/* removed */
/* removed */
/* removed */
/* removed */
/* removed */
/* removed */
/* removed */
/* removed */
/* removed */
/* removed */
/* removed */
/* removed */
/* removed */
/* removed */
/* removed */
#endif
new->left=left;
new->flags=CALL;
new->right=0;
new->alist=argument_list_expression();
}
left=new;
killsp();
}
return left;
}
argument_list *argument_list_expression(void)
/* returns CALL node with alist attached, but without identifier */
{
argument_list *al,*first_alist=0,*last_alist=0;np n;
if(ctok->type!=LPAR)ierror(0);
next_token();killsp();
while(ctok->type!=RPAR){
n=assignment_expression();
al=mymalloc(sizeof(argument_list));
al->arg=n;al->next=0;
if(last_alist){
last_alist->next=al;
last_alist=al;
}else{
last_alist=first_alist=al;
}
killsp();
if(ctok->type==COMMA){
next_token();killsp();
if(ctok->type==RPAR) error(59);
}else if(ctok->type!=RPAR) error(57);
}
if(ctok->type!=RPAR) error(59); else next_token();
return first_alist;
}
np primary_expression(void)
/* primary-expressions (Konstanten,Strings,(expr),Identifier) */
{
np new;token mtok;
if(ctok->type==NUMBER) return constant_expression();
if(ctok->type==T_STRING||ctok->type==T_CHAR) return string_expression();
if(ctok->type==LPAR){
next_token();killsp();
new=expression();
killsp();
if(ctok->type!=RPAR) error(59); else next_token();
return new;
}
return identifier_expression();
}
const_list *cl_from_string(char *start, char *end)
{
const_list *r,*cl,**prev;int i;
prev=&r;
for(i=0;i<end-start+1;i++){
cl=mymalloc(CLS);
cl->next=0;
cl->tree=0;
cl->idx=l2zm((long)i);
cl->val.vmax=l2zm(0L);
cl->other=mymalloc(CLS);
cl->other->next=cl->other->other=0;
cl->other->tree=0;
cl->other->idx=l2zm(0L);
cl->other->val.vchar=zm2zc(l2zm((long)start[i]));
*prev=cl;
prev=&cl->next;
}
return r;
}
np string_expression(void)
/* Gibt Zeiger auf string oder Zeichenkonstante zurueck */
{
np new; char f,*s,*p;int flag,val;
zmax zm;zumax zum;
static char *string;
static size_t slen;
p=string;
while(1){
s=ctok->name;
if(*s=='L') {
#ifdef HAVE_MISRA
/* removed */
#endif
s++;} /* Noch keine erweiterten Zeichen */
if(ctok->type==T_STRING&&*s!='\"') ierror(0);
if(ctok->type==T_CHAR&&*s!='\'') ierror(0);
f=*s++;
while(*s!=f&&*s!=0){
size_t pos=p-string;
if(slen<=pos+1){
slen+=128;
string=myrealloc(string,slen);
p=string+pos;
}
if(*s=='\\'){
s++;
if(*s=='\\'){*p++=CHARCONV('\\');s++;continue;}
if(*s=='n'){*p++=CHARCONV('\n');s++;continue;}
if(*s=='t'){*p++=CHARCONV('\t');s++;continue;}
if(*s=='r'){*p++=CHARCONV('\r');s++;continue;}
if(*s=='v'){*p++=CHARCONV('\v');s++;continue;}
if(*s=='b'){*p++=CHARCONV('\b');s++;continue;}
if(*s=='f'){*p++=CHARCONV('\f');s++;continue;}
if(*s=='a'){*p++=CHARCONV('\a');s++;continue;}
if(*s=='\?'){*p++=CHARCONV('\?');s++;continue;}
if(*s=='\''){*p++=CHARCONV('\'');s++;continue;}
if(*s=='\"'){*p++=CHARCONV('\"');s++;continue;}
flag=val=0;
while(*s>='0'&&*s<='7'&&flag<3){
val=val*8+*s-'0';
s++;flag++;
}
if(flag){*p++=val;continue;}
if(*s=='x'){
int warned=0;
s++;val=0;
while((*s>='0'&&*s<='9')||(*s>='a'&&*s<='f')||(*s>='A'&&*s<='F')){
val=val*16;
if(*s>='0'&&*s<='9') val+=*s-'0';
if(*s>='a'&&*s<='f') val+=*s-'a'+10;
if(*s>='A'&&*s<='F') val+=*s-'A'+10;
if(!warned&&((unsigned long)val)>zum2ul(tu_max[CHAR])){
error(364);
warned=1;
}
s++;
}
*p++=val;continue;
}
error(71);
#ifdef HAVE_MISRA
/* removed */
#endif
}
*p++=CHARCONV(*s);
s++;
}
if(*s!=f) error(74);
next_token();
killsp();
if(f!='\"'||ctok->type!=T_STRING) break;
}
if(!string){
slen+=128;
string=myrealloc(string,slen);
p=string;
}
*p=0;
new=new_node();
new->ntyp=new_typ();
if(f=='\"'){
new->ntyp->flags=ARRAY;
new->ntyp->size=l2zm((long)(p-string)+1);
new->ntyp->next=new_typ();
new->ntyp->next->flags=STRINGCONST|CHAR;
new->ntyp->next->next=0;
new->flags=STRING;
new->cl=cl_from_string(string,p);
/* new->identifier=add_identifier(string,p-string);*/
new->val.vmax=l2zm(0L);
}else{
char *l;
if(ecpp)new->ntyp->flags=CONST|CHAR;
else new->ntyp->flags=CONST|INT;
new->ntyp->next=0;
new->flags=CEXPR;
/* TODO: Hier eventuell was mitspeichern das char */
zm=l2zm(0L);zum=ul2zum(0UL);
p--;
if(p>string){ error(72);
#ifdef HAVE_MISRA
/* removed */
#endif
}
for(BIGENDIAN?(l=string):(l=p);BIGENDIAN?(l<=p):(l>=string);BIGENDIAN?(l++):(l--)){
/* zm=zm<<CHAR_BIT+*p */
if(default_unsigned){
zum=zumlshift(zum,char_bit);
zum=zmadd(zum,ul2zum(*(unsigned char *)l));
new->val.vint=(int)zum2zui(zum);
}else{
zm=zmlshift(zm,char_bit);
zm=zmadd(zm,l2zm((long)*l));
new->val.vint=zm2zi(zm);
}
}
}
new->left=new->right=0;
return new;
}
np constant_expression(void)
/* Gibt Zeiger auf erzeugt Struktur fuer Konstante zurueck */
{
np new; zldouble db;
zumax value,zbase,digit;unsigned long base=10,t;
char *s,*merk;int warned=0,tm=0;
merk=s=ctok->name;
value=ul2zum(0L);
new=new_node();
new->ntyp=new_typ();
new->ntyp->flags=0;
new->flags=CEXPR;
new->left=new->right=0;
new->sidefx=0;
if(*s=='0'){
s++;
if(*s=='x'||*s=='X'){s++;base=16;} else base=8;
}
zbase=ul2zum(base);
if(*s>='0'&&*s<='9') t=*s-'0';
else if(*s>='a'&&*s<='f') t=*s-'a'+10;
else if(*s>='A'&&*s<='F') t=*s-'A'+10;
else t=20;
while(t<base){
digit=ul2zum(t);
if(!warned){
if(!c99&&!zumleq(value,zumdiv(zumsub(t_max(UNSIGNED|LONG),digit),zbase)))
warned=1;
if(c99&&!zumleq(value,zumdiv(zumsub(t_max(UNSIGNED|LLONG),digit),zbase)))
warned=1;
}
value=zumadd(zummult(value,zbase),digit);
s++;
if(*s>='0'&&*s<='9') t=*s-'0';
else if(*s>='a'&&*s<='f') t=*s-'a'+10;
else if(*s>='A'&&*s<='F') t=*s-'A'+10;
else t=20;
}
while((!(tm&UNSIGNED)&&(*s=='u'||*s=='U'))||((tm&NQ)==0&&(*s=='l'||*s=='L'))){
#ifdef HAVE_MISRA
/* removed */
#endif
if(!(tm&UNSIGNED)&&(*s=='u'||*s=='U')){
if((tm&NQ)==LONG){
if(!c99||zumleq(value,t_max(UNSIGNED|LONG)))
new->ntyp->flags=(UNSIGNED|LONG);
else
new->ntyp->flags=(UNSIGNED|LLONG);
}else if((tm&NQ)==LLONG)
new->ntyp->flags=(UNSIGNED|LLONG);
else if(zumleq(value,t_max(UNSIGNED|INT)))
new->ntyp->flags=UNSIGNED|INT;
else if(!c99||zumleq(value,t_max(UNSIGNED|LONG)))
new->ntyp->flags=UNSIGNED|LONG;
else
new->ntyp->flags=UNSIGNED|LLONG;
tm|=UNSIGNED;
}else{
if(c99&&s[1]==s[0]){
s++;
if(tm&UNSIGNED)
new->ntyp->flags=(UNSIGNED|LLONG);
else if(base==10||zumleq(value,t_max(LLONG)))
new->ntyp->flags=LLONG;
else
new->ntyp->flags=UNSIGNED|LLONG;
tm|=LLONG;
}else{
if(tm&UNSIGNED){
if(!c99||zumleq(value,t_max(UNSIGNED|LONG)))
new->ntyp->flags=(UNSIGNED|LONG);
else
new->ntyp->flags=(UNSIGNED|LLONG);
}else{
if(!c99){
if(base==10||zumleq(value,t_max(LONG)))
new->ntyp->flags=LONG;
else
new->ntyp->flags=UNSIGNED|LONG;
}else{
if(zumleq(value,t_max(LONG)))
new->ntyp->flags=LONG;
else if(base!=10&&zumleq(value,t_max(UNSIGNED|LONG)))
new->ntyp->flags=UNSIGNED|LONG;
else if(base==10||zumleq(value,t_max(LLONG)))
new->ntyp->flags=LLONG;
else
new->ntyp->flags=UNSIGNED|LLONG;
}
}
tm|=LONG;
}
}
s++;
}
if(*s=='.'||*s=='e'||*s=='E'){
/* Fliesskommakonstante, ignoriert vorher berechneten Wert, falls er */
/* nicht dezimal und nicht 0 war (da er dann oktal war) */
if(*merk=='0'&&!zumeqto(value,ul2zum(0UL))){
value=ul2zum(0UL);zbase=ul2zum(10UL);
while(*merk>='0'&&*merk<='9'){
digit=ul2zum((unsigned long)(*merk-'0'));
value=zumadd(zummult(value,zbase),digit);
merk++;
}
if(merk!=s) error(75);
}
db=zum2zld(value);
if(*s=='.'){
/* Teil hinter Kommastellen */
zldouble zdiv,zbased,zsum,digit;
int cnt=0;
s++;
zbased=d2zld(10.0);zdiv=d2zld(1.0);zsum=d2zld(0.0);
while(*s>='0'&&*s<='9'){
if (cnt<35){
cnt++;
digit=d2zld((double)(*s-'0'));
zsum=zldadd(zldmult(zsum,zbased),digit);
zdiv=zldmult(zdiv,zbased);
}
s++;
}
db=zldadd(db,zlddiv(zsum,zdiv));
}
if(*s=='e'||*s=='E'){
/* Exponentialdarstellung */
int exp,vorz,i;zldouble zbased;
zbased=d2zld((double)10);
s++;
if(*s=='-'){
s++;vorz=-1;
}else{
vorz=1;if(*s=='+') s++;
}
exp=0;
while(*s>='0'&&*s<='9') exp=exp*10+*s++-'0';
for(i=0;i<exp;i++){
if(vorz>0) db=zldmult(db,zbased);
else db=zlddiv(db,zbased);
}
}
new->ntyp->flags=DOUBLE;
if(*s=='f'||*s=='F'){
new->ntyp->flags=FLOAT;s++;
}else if(*s=='l'||*s=='L'){
new->ntyp->flags=LDOUBLE;s++;
}
}else{
if(warned) error(211);
if(new->ntyp->flags==0){
if(base==10){
if(zumleq(value,t_max(INT)))
new->ntyp->flags=INT;
else if(!c99||zumleq(value,t_max(LONG)))
new->ntyp->flags=LONG;
else
new->ntyp->flags=LLONG;
}else{
#ifdef HAVE_MISRA
/* removed */
#endif
if(zumleq(value,t_max(INT)))
new->ntyp->flags=INT;
else
if(zumleq(value,t_max(UNSIGNED|INT)))
new->ntyp->flags=UNSIGNED|INT;
else if(zumleq(value,t_max(LONG)))
new->ntyp->flags=LONG;
else if(!c99||zumleq(value,t_max(UNSIGNED|LONG))){
new->ntyp->flags=UNSIGNED|LONG;error(212);
}else if(zumleq(value,t_max(LLONG)))
new->ntyp->flags=LLONG;
else
new->ntyp->flags=UNSIGNED|LLONG;
}
}
}
if(*s) error(232);
if(new->ntyp->flags==FLOAT) new->val.vfloat=zld2zf(db);
else if(new->ntyp->flags==DOUBLE) new->val.vdouble=zld2zd(db);
else if(new->ntyp->flags==LDOUBLE) new->val.vldouble=db;
else if(new->ntyp->flags==INT) new->val.vint=zm2zi(zum2zm(value));
else if(new->ntyp->flags==(UNSIGNED|INT)) new->val.vuint=zum2zui(value);
else if(new->ntyp->flags==LONG) new->val.vlong=zm2zl(zum2zm(value));
else if(new->ntyp->flags==(UNSIGNED|LONG)) new->val.vulong=zum2zul(value);
else if(new->ntyp->flags==LLONG) new->val.vllong=zm2zll(zum2zm(value));
else if(new->ntyp->flags==(UNSIGNED|LLONG)) new->val.vullong=zum2zull(value);
else ierror(0);
next_token();
return new;
}
np identifier_expression(void)
/* Erzeugt Identifier mit Knoten */
{
np new;char buff[MAXI];
killsp();
if(ctok->type==NAME){
if(is_keyword(ctok->name)) error(216,ctok->name);
#ifdef HAVE_MISRA
/* removed */
#endif
new=new_node();
new->flags=IDENTIFIER;
new->left=new->right=0;
new->identifier=add_identifier(ctok->name,strlen(ctok->name));
new->ntyp=0;
new->sidefx=0;
new->val.vmax=l2zm(0L);
new->o.v=0;
next_token();
}else{
error(76);
new=0;
}
return new;
}
void free_alist(argument_list *p)
/* Gibt argument_list inkl. expressions frei */
{
argument_list *merk;
while(p){
merk=p->next;
if(p->arg) free_expression(p->arg);
free(p);
p=merk;
}
}
void free_expression(np p)
/* Gibt expression mit allen Typen etc. frei */
{
if(!p) return;
if(p->flags==ASSIGNOP){
if(!p->right){ierror(0);return;}
if(p->right->left==p->left) p->left=0;
if(p->right->right==p->left) p->left=0;
}
if(p->flags==CALL&&p->alist) free_alist(p->alist);
if(p->ntyp) freetyp(p->ntyp);
if(p->left) free_expression(p->left);
if(p->right) free_expression(p->right);
free(p);
}