register arith val = 0;
if (ch == '.') { /* an embarrassing ambiguity */
+#ifndef NOFLOAT
LoadChar(vch);
PushBack();
if (!is_dig(vch)) /* just a `.' */
/* in the rest of the compiler, all floats
have to start with a digit.
*/
+#else NOFLOAT
+ return ptok->tk_symb = ch;
+#endif NOFLOAT
}
if (ch == '0') {
*np++ = ch;
ptok->tk_fund = LONG;
return ptok->tk_symb = INTEGER;
}
- if (base == 16 || !(ch == '.' || ch == 'e' || ch == 'E')) {
+#ifndef NOFLOAT
+ if (base == 16 || !(ch == '.' || ch == 'e' || ch == 'E'))
+#endif NOFLOAT
+ {
PushBack();
ptok->tk_ival = val;
/* The semantic analyser must know if the
return ptok->tk_symb = INTEGER;
}
/* where's the test for the length of the integral ??? */
+#ifndef NOFLOAT
if (ch == '.'){
if (np < &buf[NUMSIZE])
*np++ = ch;
else
ptok->tk_fval = Salloc(buf, np - buf) + 1;
return ptok->tk_symb = FLOATING;
+#endif NOFLOAT
}
case STEOI: /* end of text on source file */
return ptok->tk_symb = EOI;
int tok_fund; /* INT or LONG */
arith tok_ival;
} tok_integer;
+#ifndef NOFLOAT
char *tok_fval;
+#endif NOFLOAT
} tok_data;
};
#define tk_len tok_data.tok_string.tok_len
#define tk_fund tok_data.tok_integer.tok_fund
#define tk_ival tok_data.tok_integer.tok_ival
+#ifndef NOFLOAT
#define tk_fval tok_data.tok_fval
+#endif NOFLOAT
extern struct token dot, ahead, aside;
extern unsigned int LineNumber; /* "LLlex.c" */
dot.tk_fund = INT;
dot.tk_ival = 1;
break;
+#ifndef NOFLOAT
case FLOATING:
dot.tk_fval = Salloc("0.0", 4);
break;
+#endif NOFLOAT
}
}
#define SZ_WORD (arith)4
#define SZ_INT (arith)4
#define SZ_LONG (arith)4
+#ifndef NOFLOAT
#define SZ_FLOAT (arith)4
#define SZ_DOUBLE (arith)8
+#endif NOFLOAT
#define SZ_POINTER (arith)4
/* target machine alignment requirements */
#define AL_WORD SZ_WORD
#define AL_INT SZ_WORD
#define AL_LONG SZ_WORD
+#ifndef NOFLOAT
#define AL_FLOAT SZ_WORD
#define AL_DOUBLE SZ_WORD
+#endif NOFLOAT
#define AL_POINTER SZ_WORD
#define AL_STRUCT 1
#define AL_UNION 1
extern int
short_align, word_align, int_align, long_align,
- float_align, double_align, pointer_align,
+#ifndef NOFLOAT
+ float_align, double_align,
+#endif NOFLOAT
+ pointer_align,
struct_align, union_align;
extern arith align();
t2 = any2arith(e2p, oper);
/* Now t1 and t2 are either INT or LONG or DOUBLE */
+#ifndef NOFLOAT
if (t1 == DOUBLE && t2 != DOUBLE)
t2 = int2float(e2p, double_type);
else
else
if (t1 == DOUBLE)
return DOUBLE;
+#endif NOFLOAT
/* Now they are INT or LONG */
u1 = (*e1p)->ex_type->tp_unsigned;
expr_warning(*expp, "%s on enum", symbol2str(oper));
int2int(expp, int_type);
break;
+#ifndef NOFLOAT
case FLOAT:
float2float(expp, double_type);
break;
case DOUBLE:
break;
+#endif NOFLOAT
#ifndef NOBITFIELD
case FIELD:
field2arith(expp);
return (*expp)->ex_type->tp_fund;
}
+#ifndef NOFLOAT
int
int2float(expp, tp)
struct expr **expp;
else
*expp = arith2arith(tp, FLOAT2FLOAT, *expp);
}
+#endif NOFLOAT
array2pointer(expp)
struct expr **expp;
case LONG:
case ENUM:
case POINTER:
+#ifndef NOFLOAT
case FLOAT:
case DOUBLE:
+#endif NOFLOAT
break;
default:
expr_error(*expp, "%s operand to %s",
case CHAR:
case SHORT:
case ENUM:
+#ifndef NOFLOAT
case FLOAT:
+#endif NOFLOAT
any2arith(expp, oper);
break;
case ARRAY:
}
#endif NOBITFIELD
+#ifndef NOFLOAT
/* switch_sign_fp() negates the given floating constant expression
The lexical analyser has reserved an extra byte of space in front
of the string containing the representation of the floating
else
--(expr->FL_VALUE);
}
+#endif NOFLOAT
symbol2str(oper));
int2int(expp, tp);
}
+#ifndef NOFLOAT
else
if (oldi && !i) {
if (oldtp->tp_fund == ENUM && oper != CAST)
float2int(expp, tp);
else /* !oldi && !i */
float2float(expp, tp);
+#else NOFLOAT
+ else
+ crash("(ch7cast) floats not implemented\n");
+#endif NOFLOAT
}
else
if (oldtp->tp_fund == POINTER && tp->tp_fund == POINTER) {
case INT:
case LONG:
case ENUM:
+#ifndef NOFLOAT
case FLOAT:
case DOUBLE:
+#endif NOFLOAT
return 1;
#ifndef NOBITFIELD
case FIELD:
/* prepares the integral expression expp2 in order to
apply it to the pointer expression expp1
*/
+#ifndef NOFLOAT
if (any2arith(expp2, oper) == DOUBLE) {
expr_error(*expp2,
"illegal combination of float and pointer");
erroneous2int(expp2);
}
+#endif NOFLOAT
ch7bin( expp2, '*',
intexpr(size_of_type((*expp1)->ex_type->tp_up, "object"),
pa_type->tp_fund)
}
break;
case '~':
+#ifndef NOFLOAT
{
int fund = (*expp)->ex_type->tp_fund;
}
/* FALLTHROUGH */
}
+#endif NOFLOAT
case '-':
any2arith(expp, oper);
if (is_cp_cst(*expp)) {
);
}
else
+#ifndef NOFLOAT
if (is_fp_cst(*expp))
switch_sign_fp(*expp);
else
+#endif NOFLOAT
*expp = new_oper((*expp)->ex_type,
NILEXPR, oper, *expp);
break;
static struct stmt_block *stmt_stack;
char *symbol2str();
+#ifndef NOFLOAT
int fp_used;
+#endif NOFLOAT
label lab_count = 1;
label datlab_count = 1;
else
C_ret(ATW(func_tp->tp_size));
}
+#ifndef NOFLOAT
if (fp_used && mes_flt_given == 0) {
/* floating point used */
C_ms_flt();
mes_flt_given++;
}
+#endif NOFLOAT
C_ms_par(fbytes); /* # bytes for formals */
if (sp_occurred[SP_SETJMP]) { /* indicate use of "setjmp" */
C_ms_gto();
#define T_SIGNED 1
#define T_UNSIGNED 2
+#ifndef NOFLOAT
#define T_FLOATING 3
+#endif NOFLOAT
/* conversion() generates the EM code for a conversion between
the types char, short, int, long, float, double and pointer.
C_ciu();
break;
+#ifndef NOFLOAT
case T_FLOATING:
C_loc(from_size < word_size ? word_size : from_size);
C_loc(to_size < word_size ? word_size : to_size);
C_cif();
break;
+#endif NOFLOAT
}
break;
C_cuu();
break;
+#ifndef NOFLOAT
case T_FLOATING:
C_cuf();
break;
+#endif NOFLOAT
}
break;
+#ifndef NOFLOAT
case T_FLOATING:
C_loc(from_size < word_size ? word_size : from_size);
C_loc(to_size < word_size ? word_size : to_size);
break;
}
break;
+#endif NOFLOAT
default:
crash("(conversion) illegal type conversion");
}
case ENUM:
return tp->tp_unsigned ? T_UNSIGNED : T_SIGNED;
+#ifndef NOFLOAT
case FLOAT:
case DOUBLE:
return T_FLOATING;
+#endif NOFLOAT
case POINTER: /* pointer : signed / unsigned ??? */
return T_SIGNED;
case SHORT:
if (tp == int_type)
tp = short_type;
- else error("short with illegal type");
+ else
+ error("short with illegal type");
break;
case LONG:
if (tp == int_type)
tp = long_type;
else
+#ifndef NOFLOAT
if (tp == float_type)
tp = double_type;
- else error("long with illegal type");
+ else
+#endif NOFLOAT
+ error("long with illegal type");
break;
}
if (ds->ds_unsigned) {
expr->ex_depth,
expr->ex_class == Value ? "Value" :
expr->ex_class == String ? "String" :
+#ifndef NOFLOAT
expr->ex_class == Float ? "Float" :
+#endif NOFLOAT
expr->ex_class == Oper ? "Oper" :
expr->ex_class == Type ? "Type" : "UNKNOWN CLASS"
);
);
break;
}
+#ifndef NOFLOAT
case Float:
print("%s\n", expr->FL_VALUE);
break;
+#endif NOFLOAT
case Oper:
o = &expr->ex_object.ex_oper;
print("\n");
C_lae_dlb(expr->VL_LBL, expr->VL_VALUE);
}
break;
+#ifndef NOFLOAT
case Float: /* a floating constant */
if (gencode) {
label datlab = data_label();
C_loi(expr->ex_type->tp_size);
}
break;
+#endif NOFLOAT
case Oper: /* compound expression */
{
register int oper = expr->OP_OPER;
case POINTER:
C_ads(rightop->ex_type->tp_size);
break;
+#ifndef NOFLOAT
case DOUBLE:
C_adf(tp->tp_size);
break;
+#endif NOFLOAT
default:
crash("bad type +");
}
EVAL(rightop, RVAL, code, NO_LABEL, NO_LABEL);
if (gencode) {
switch (tp->tp_fund) {
- case DOUBLE:
- C_ngf(tp->tp_size);
- break;
case INT:
case LONG:
case POINTER:
C_ngi(tp->tp_size);
break;
+#ifndef NOFLOAT
+ case DOUBLE:
+ C_ngf(tp->tp_size);
+ break;
+#endif NOFLOAT
default:
CRASH();
}
C_ads(rightop->ex_type->tp_size);
}
break;
+#ifndef NOFLOAT
case DOUBLE:
C_sbf(tp->tp_size);
break;
+#endif NOFLOAT
default:
crash("bad type -");
}
else
C_mli(tp->tp_size);
break;
+#ifndef NOFLOAT
case DOUBLE:
C_mlf(double_size);
break;
+#endif NOFLOAT
default:
crash("bad type *");
}
else
C_dvi(tp->tp_size);
break;
+#ifndef NOFLOAT
case DOUBLE:
C_dvf(double_size);
break;
+#endif NOFLOAT
default:
crash("bad type /");
}
case '%':
EVAL(leftop, RVAL, code, NO_LABEL, NO_LABEL);
EVAL(rightop, RVAL, code, NO_LABEL, NO_LABEL);
- if (gencode)
- if ( tp->tp_fund == INT
- || tp->tp_fund == LONG
- ) {
- if (tp->tp_unsigned)
- C_rmu(tp->tp_size);
- else
- C_rmi(tp->tp_size);
- }
+ ASSERT(tp->tp_fund==INT || tp->tp_fund==LONG);
+ if (gencode) {
+ if (tp->tp_unsigned)
+ C_rmu(tp->tp_size);
else
- crash("bad type %%");
+ C_rmi(tp->tp_size);
+ }
break;
case LEFT:
EVAL(leftop, RVAL, code, NO_LABEL, NO_LABEL);
else
C_cmi(size);
break;
- case FLOAT:
+#ifndef NOFLOAT
+ case FLOAT: /* thought they were converted??? */
case DOUBLE:
C_cmf(size);
break;
+#endif NOFLOAT
case POINTER:
C_cmp();
break;
EVAL(leftop, RVAL, TRUE, l_true, l_false);
C_df_ilb(l_true);
- EVAL(rightop->OP_LEFT, RVAL, code,
- NO_LABEL, NO_LABEL);
+ EVAL(rightop->OP_LEFT, RVAL, code, NO_LABEL, NO_LABEL);
C_bra(l_end);
C_df_ilb(l_false);
- EVAL(rightop->OP_RIGHT, RVAL, code,
- NO_LABEL, NO_LABEL);
+ EVAL(rightop->OP_RIGHT, RVAL, code, NO_LABEL, NO_LABEL);
C_df_ilb(l_end);
break;
}
true_label);
break;
case INT2INT:
+#ifndef NOFLOAT
case INT2FLOAT:
case FLOAT2INT:
case FLOAT2FLOAT:
+#endif NOFLOAT
EVAL(rightop, RVAL, code, NO_LABEL, NO_LABEL);
if (gencode)
conversion(rightop->ex_type, leftop->ex_type);
break;
}
break;
+#ifndef NOFLOAT
case FLOAT:
case DOUBLE:
switch (oper) {
break;
}
break;
+#endif NOFLOAT
case POINTER:
if (oper == MINAB || oper == MINMIN || oper == POSTDECR)
C_ngi(size);
case INTEGER:
int2expr(*expp);
break;
+#ifndef NOFLOAT
case FLOATING:
float2expr(*expp);
break;
+#endif NOFLOAT
default:
crash("bad conversion to expression");
break;
fill_int_expr(expr, dot.tk_ival, dot.tk_fund);
}
+#ifndef NOFLOAT
float2expr(expr)
struct expr *expr;
{
expr->FL_VALUE = dot.tk_fval;
expr->FL_DATLAB = 0;
}
+#endif NOFLOAT
struct expr*
intexpr(ivalue, fund)
expr_warning(expr,
"expression comma in constant expression");
}
-
- if (err) {
+ if (err)
erroneous2int(expp);
- }
}
init_expression(eppp, expr)
return is_ld_cst(expr) && expr->VL_CLASS == Const;
}
+#ifndef NOFLOAT
int
is_fp_cst(expr)
register struct expr *expr;
*/
return expr->ex_class == Float;
}
+#endif NOFLOAT
free_expression(expr)
struct expr *expr;
label sg_datlab; /* global data-label */
};
+#ifndef NOFLOAT
struct floating {
char *fl_value; /* pointer to string repr. the fp const. */
label fl_datlab; /* global data_label */
};
+#endif NOFLOAT
struct oper {
struct type *op_type; /* resulting type of the operation */
/* The following constants indicate the class of the expression: */
#define Value 0 /* it is a value known at load time */
#define String 1 /* it is a string constant */
+#ifndef NOFLOAT
#define Float 2 /* it is a floating point constant */
+#endif NOFLOAT
#define Oper 3 /* it is a run-time expression */
#define Type 4 /* only its type is relevant */
union {
struct value ex_value;
struct string ex_string;
+#ifndef NOFLOAT
struct floating ex_float;
+#endif NOFLOAT
struct oper ex_oper;
} ex_object;
};
#define SG_VALUE ex_object.ex_string.sg_value
#define SG_LEN ex_object.ex_string.sg_len
#define SG_DATLAB ex_object.ex_string.sg_datlab
+#ifndef NOFLOAT
#define FL_VALUE ex_object.ex_float.fl_value
#define FL_DATLAB ex_object.ex_float.fl_datlab
+#endif NOFLOAT
#define OP_TYPE ex_object.ex_oper.op_type
#define OP_LEFT ex_object.ex_oper.op_left
#define OP_OPER ex_object.ex_oper.op_oper
type = construct_type(POINTER, type->tp_up, (arith)0);
formal_array = 1;
break;
+#ifndef NOFLOAT
case FLOAT: /* RM 10.1 */
type = double_type;
break;
+#endif NOFLOAT
case CHAR:
case SHORT:
/* The RM is not clear about this: we must
case POINTER:
C_con_ucon("0", tp->tp_size);
break;
+#ifndef NOFLOAT
case FLOAT:
case DOUBLE:
C_con_fcon("0", tp->tp_size);
break;
+#endif NOFLOAT
case UNION:
error("initialisation of unions not allowed");
break;
C_con_dlb(ex->VL_LBL, ex->VL_VALUE);
}
break;
+#ifndef NOFLOAT
case FLOAT:
case DOUBLE:
ch7cast(&ex, '=', tp);
else
illegal_init_cst(ex);
break;
+#endif NOFLOAT
#ifndef NOBITFIELD
case FIELD:
dword_size = (2 * SZ_WORD),
int_size = SZ_INT,
long_size = SZ_LONG,
+#ifndef NOFLOAT
float_size = SZ_FLOAT,
double_size = SZ_DOUBLE,
+#endif NOFLOAT
pointer_size = SZ_POINTER;
int
word_align = AL_WORD,
int_align = AL_INT,
long_align = AL_LONG,
+#ifndef NOFLOAT
float_align = AL_FLOAT,
double_align = AL_DOUBLE,
+#endif NOFLOAT
pointer_align = AL_POINTER,
struct_align = AL_STRUCT,
union_align = AL_UNION;
long_type = standard_type(LONG, 0, long_align, long_size);
ulong_type = standard_type(LONG, UNSIGNED, long_align, long_size);
+#ifndef NOFLOAT
float_type = standard_type(FLOAT, 0, float_align, float_size);
double_type = standard_type(DOUBLE, 0, double_align, double_size);
+#endif NOFLOAT
void_type = standard_type(VOID, 0, 0, (arith)0);
label_type = standard_type(LABEL, 0, 0, (arith)0);
error_type = standard_type(ERRONEOUS, 0, 1, (arith)1);
/* Define the standard type identifiers. */
add_def(str2idf("char"), TYPEDEF, char_type, L_UNIVERSAL);
add_def(str2idf("int"), TYPEDEF, int_type, L_UNIVERSAL);
+#ifndef NOFLOAT
add_def(str2idf("float"), TYPEDEF, float_type, L_UNIVERSAL);
add_def(str2idf("double"), TYPEDEF, double_type, L_UNIVERSAL);
+#endif NOFLOAT
add_def(str2idf("void"), TYPEDEF, void_type, L_UNIVERSAL);
stack_level();
}
case INTEGER:
print("%ld ", dot.tk_ival);
break;
+#ifndef NOFLOAT
case FLOATING:
print("%s ", dot.tk_fval);
break;
+#endif NOFLOAT
case EOI:
case EOF:
return;
long_align = align;
break;
case 'f': /* float */
+#ifndef NOFLOAT
if (size != (arith)0)
float_size = size;
if (align != 0)
float_align = align;
+#endif NOFLOAT
break;
case 'd': /* double */
+#ifndef NOFLOAT
if (size != (arith)0)
double_size = size;
if (align != 0)
double_align = align;
+#endif NOFLOAT
break;
case 'p': /* pointer */
if (size != (arith)0)
extern arith
short_size, word_size, dword_size, int_size, long_size,
- float_size, double_size, pointer_size;
+#ifndef NOFLOAT
+ float_size, double_size,
+#endif NOFLOAT
+ pointer_size;
extern arith max_int, max_unsigned; /* cstoper.c */
case POINTER:
reg = reg_pointer;
break;
+#ifndef NOFLOAT
case FLOAT:
case DOUBLE:
reg = reg_float;
break;
+#endif NOFLOAT
default:
reg = reg_any;
break;
warning("long in switch (cast to int)");
int2int(expp, int_type);
break;
+#ifndef NOFLOAT
case DOUBLE:
error("float/double in switch");
erroneous2int(expp);
break;
+#endif NOFLOAT
}
stack_stmt(l_break, NO_LABEL);
*word_type, *uword_type,
*int_type, *uint_type,
*long_type, *ulong_type,
+#ifndef NOFLOAT
*float_type, *double_type,
+#endif NOFLOAT
*void_type, *label_type,
*string_type, *funint_type, *error_type;
*word_type, *uword_type,
*int_type, *uint_type,
*long_type, *ulong_type,
+#ifndef NOFLOAT
*float_type, *double_type,
+#endif NOFLOAT
*void_type, *label_type,
*string_type, *funint_type, *error_type;