📄 floatexp.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
*/
/*
* this evaluates an expression that may have floating point values in it
* e.g. the initializer for a module-scoped float or double
*/
#include <stdio.h>
#include <string.h>
#include "lists.h"
#include "expr.h"
#include "c.h"
#include "ccerr.h"
extern LLONG_TYPE ival;
extern long double rval;
extern enum e_sym lastst;
extern char lastid[];
extern TABLE defsyms;
extern int prm_cmangle;
extern SYM *typequal;
long double floatexpr(void);
/* Primary for constant floats
* id
* iconst
* rconst
* defined(MACRO)
* (cast) floatexpr
*/
static long double feprimary(void)
{
long double temp = 0;
SYM *sp;
if (lastst == id)
{
char *lid = lastid;
if (prm_cmangle)
lid++;
sp = gsearch(lastid);
if (sp == NULL)
{
gensymerror(ERR_UNDEFINED, lastid);
getsym();
return 0;
} if (sp->storage_class != sc_const && sp->tp->type != bt_enum)
{
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 == lconst)
{
temp = ival;
getsym();
return temp;
}
else if (lastst == iuconst)
{
temp = (unsigned)ival;
getsym();
return temp;
}
else if (lastst == luconst)
{
temp = (unsigned)ival;
getsym();
return temp;
}
else if (lastst = rconst || lastst == lrconst || lastst == fconst)
{
temp = rval;
getsym();
return temp;
}
else if (lastst == openpa)
{
getsym();
if (castbegin(lastst))
{
typequal = 0;
decl(0, 0);
decl1(sc_type, 0);
needpunc(closepa, 0);
return floatexpr();
}
else
{
temp = floatexpr();
needpunc(closepa, 0);
return (temp);
}
}
getsym();
generror(ERR_NEEDCONST, 0, 0);
return 0;
}
/* Unary for floating const
* -unary
* !unary
* primary
*/
static long double feunary(void)
{
long double temp;
switch (lastst)
{
case minus:
getsym();
temp = - feunary();
break;
case en_not:
getsym();
temp = !feunary();
break;
case plus:
getsym();
temp = feunary();
break;
default:
temp = feprimary();
break;
}
return (temp);
}
/* Multiply ops */
static long double femultops(void)
{
long double val1 = feunary(), val2;
while (lastst == star || lastst == divide)
{
int oper = lastst;
getsym();
val2 = feunary();
switch (oper)
{
case star:
val1 = val1 * val2;
break;
case divide:
val1 = val1 / val2;
break;
}
}
return (val1);
}
/* Add ops */
static long double feaddops(void)
{
long double val1 = femultops(), val2;
while (lastst == plus || lastst == minus)
{
int oper = lastst;
getsym();
val2 = femultops();
if (oper == plus)
val1 = val1 + val2;
else
val1 = val1 - val2;
}
return (val1);
}
/* Floating point constant expression */
long double floatexpr(void)
{
return (feaddops());
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -