mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-17 01:11:45 +00:00
Implement double constants
This commit is contained in:
parent
2cd62fe01b
commit
533fb8acc9
11 changed files with 132 additions and 10 deletions
|
@ -692,7 +692,12 @@ value_string (progs_t *pr, etype_t type, pr_type_t *val)
|
|||
case ev_uinteger:
|
||||
dsprintf (line, "$%08x", val->uinteger_var);
|
||||
break;
|
||||
default:
|
||||
case ev_double:
|
||||
dsprintf (line, "%g", *(double *)val);
|
||||
break;
|
||||
case ev_short:
|
||||
case ev_invalid:
|
||||
case ev_type_count:
|
||||
//dsprintf (line, "bad type %i", type);
|
||||
dsprintf (line, "<%x %x %x %x>",
|
||||
val[0].integer_var, val[1].integer_var,
|
||||
|
|
|
@ -174,7 +174,7 @@ typedef struct ex_value_s {
|
|||
etype_t lltype;
|
||||
union {
|
||||
const char *string_val; ///< string constant
|
||||
float double_val; ///< double constant
|
||||
double double_val; ///< double constant
|
||||
float float_val; ///< float constant
|
||||
float vector_val[3]; ///< vector constant
|
||||
int entity_val; ///< entity constant
|
||||
|
|
|
@ -97,6 +97,9 @@ dump_def (progs_t *pr, ddef_t *def, int indent)
|
|||
case ev_float:
|
||||
comment = va (" %g", G_FLOAT (pr, offset));
|
||||
break;
|
||||
case ev_double:
|
||||
comment = va (" %.17g", G_DOUBLE (pr, offset));
|
||||
break;
|
||||
case ev_vector:
|
||||
comment = va (" '%g %g %g'",
|
||||
G_VECTOR (pr, offset)[0],
|
||||
|
|
|
@ -2273,6 +2273,14 @@ address_expr (expr_t *e1, expr_t *e2, type_t *t)
|
|||
e = e1->e.expr.e2;
|
||||
break;
|
||||
}
|
||||
if (e1->e.expr.op == 'A') {
|
||||
if (!t)
|
||||
t = e1->e.expr.type;
|
||||
if (e2) {
|
||||
e2 = binary_expr ('+', e1->e.expr.e2, e2);
|
||||
}
|
||||
return address_expr (e1->e.expr.e1, e2, t);
|
||||
}
|
||||
return error (e1, "invalid type for unary &");
|
||||
case ex_uexpr:
|
||||
if (e1->e.expr.op == '.') {
|
||||
|
|
|
@ -93,6 +93,8 @@ B [01]
|
|||
X [0-9a-fA-F]
|
||||
ID [a-zA-Z_][a-zA-Z_0-9]*
|
||||
FLOAT ({D}+|{D}*\.{D}+|{D}+\.{D}*)([eE]{m}?{D}+)?
|
||||
FLOATf {FLOAT}[fF]
|
||||
FLOATd {FLOAT}[dD]
|
||||
INT ({D}+|0[xX]{X}+|0[bB]{B})
|
||||
RANGE \.\.
|
||||
ELLIPSIS \.\.\.
|
||||
|
@ -136,10 +138,35 @@ STRING \"(\\.|[^"\\])*\"
|
|||
}
|
||||
|
||||
{FLOAT} {
|
||||
// advanced code defaults to double, but traditional
|
||||
// and extended code defaults to float
|
||||
if (options.traditional < 1) {
|
||||
double d = strtod (yytext, 0);
|
||||
qc_yylval.expr = new_double_expr (d);
|
||||
} else {
|
||||
float f = strtof (yytext, 0);
|
||||
qc_yylval.expr = new_float_expr (f);
|
||||
}
|
||||
return VALUE;
|
||||
}
|
||||
{FLOATf} {
|
||||
float f = strtof (yytext, 0);
|
||||
qc_yylval.expr = new_float_expr (f);
|
||||
return VALUE;
|
||||
}
|
||||
{FLOATd} {
|
||||
// advanced code defaults to double, but traditional
|
||||
// and extended code defaults to float
|
||||
if (options.traditional < 1) {
|
||||
double d = strtod (yytext, 0);
|
||||
qc_yylval.expr = new_double_expr (d);
|
||||
} else {
|
||||
float f = strtof (yytext, 0);
|
||||
qc_yylval.expr = new_float_expr (f);
|
||||
warning (0, "truncating double constant to float");
|
||||
}
|
||||
return VALUE;
|
||||
}
|
||||
|
||||
{ID} {
|
||||
int tok = keyword_or_id(yytext);
|
||||
|
|
|
@ -69,6 +69,7 @@ typedef struct {
|
|||
ex_pointer_t pointer;
|
||||
float quaternion_val[4];
|
||||
int integer_val;
|
||||
double double_val;
|
||||
} i;
|
||||
} immediate_t;
|
||||
|
||||
|
@ -275,6 +276,7 @@ static hashtab_t *func_imm_defs;
|
|||
static hashtab_t *pointer_imm_defs;
|
||||
static hashtab_t *quaternion_imm_defs;
|
||||
static hashtab_t *integer_imm_defs;
|
||||
static hashtab_t *double_imm_defs;
|
||||
|
||||
static void
|
||||
imm_free (void *_imm, void *unused)
|
||||
|
@ -306,6 +308,8 @@ imm_get_hash (const void *_imm, void *_tab)
|
|||
} else if (tab == &quaternion_imm_defs) {
|
||||
return Hash_Buffer (&imm->i.quaternion_val,
|
||||
sizeof (&imm->i.quaternion_val));
|
||||
} else if (tab == &double_imm_defs) {
|
||||
return Hash_Buffer (&imm->i.double_val, sizeof (&imm->i.double_val));
|
||||
} else if (tab == &integer_imm_defs) {
|
||||
return imm->i.integer_val;
|
||||
} else {
|
||||
|
@ -340,6 +344,8 @@ imm_compare (const void *_imm1, const void *_imm2, void *_tab)
|
|||
sizeof (imm1->i.pointer));
|
||||
} else if (tab == &quaternion_imm_defs) {
|
||||
return QuatCompare (imm1->i.quaternion_val, imm2->i.quaternion_val);
|
||||
} else if (tab == &double_imm_defs) {
|
||||
return imm1->i.double_val == imm2->i.double_val;
|
||||
} else if (tab == &integer_imm_defs) {
|
||||
return imm1->i.integer_val == imm2->i.integer_val;
|
||||
} else {
|
||||
|
@ -362,6 +368,24 @@ value_as_float (ex_value_t *value)
|
|||
return value->v.integer_val;
|
||||
if (value->lltype == ev_short)
|
||||
return value->v.short_val;
|
||||
if (value->lltype == ev_double)
|
||||
return value->v.double_val;
|
||||
if (value->lltype == ev_float)
|
||||
return value->v.float_val;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static double
|
||||
value_as_double (ex_value_t *value)
|
||||
{
|
||||
if (value->lltype == ev_uinteger)
|
||||
return value->v.uinteger_val;
|
||||
if (value->lltype == ev_integer)
|
||||
return value->v.integer_val;
|
||||
if (value->lltype == ev_short)
|
||||
return value->v.short_val;
|
||||
if (value->lltype == ev_double)
|
||||
return value->v.double_val;
|
||||
if (value->lltype == ev_float)
|
||||
return value->v.float_val;
|
||||
return 0;
|
||||
|
@ -376,6 +400,8 @@ value_as_int (ex_value_t *value)
|
|||
return value->v.integer_val;
|
||||
if (value->lltype == ev_short)
|
||||
return value->v.short_val;
|
||||
if (value->lltype == ev_double)
|
||||
return value->v.double_val;
|
||||
if (value->lltype == ev_float)
|
||||
return value->v.float_val;
|
||||
return 0;
|
||||
|
@ -390,6 +416,8 @@ value_as_uint (ex_value_t *value)
|
|||
return value->v.integer_val;
|
||||
if (value->lltype == ev_short)
|
||||
return value->v.short_val;
|
||||
if (value->lltype == ev_double)
|
||||
return value->v.double_val;
|
||||
if (value->lltype == ev_float)
|
||||
return value->v.float_val;
|
||||
return 0;
|
||||
|
@ -405,6 +433,9 @@ convert_value (ex_value_t *value, type_t *type)
|
|||
if (is_float (type)) {
|
||||
float val = value_as_float (value);
|
||||
return new_float_val (val);
|
||||
} else if (is_double (type)) {
|
||||
double val = value_as_double (value);
|
||||
return new_double_val (val);
|
||||
} else if (type->type == ev_short) {
|
||||
int val = value_as_int (value);
|
||||
return new_short_val (val);
|
||||
|
@ -504,6 +535,10 @@ emit_value (ex_value_t *value, def_t *def)
|
|||
tab = quaternion_imm_defs;
|
||||
type = &type_quaternion;
|
||||
break;
|
||||
case ev_double:
|
||||
tab = double_imm_defs;
|
||||
type = &type_double;
|
||||
break;
|
||||
default:
|
||||
internal_error (0, 0);
|
||||
}
|
||||
|
@ -601,6 +636,7 @@ clear_immediates (void)
|
|||
Hash_FlushTable (pointer_imm_defs);
|
||||
Hash_FlushTable (quaternion_imm_defs);
|
||||
Hash_FlushTable (integer_imm_defs);
|
||||
Hash_FlushTable (double_imm_defs);
|
||||
} else {
|
||||
value_table = Hash_NewTable (16381, 0, 0, 0);
|
||||
Hash_SetHashCompare (value_table, value_get_hash, value_compare);
|
||||
|
@ -634,6 +670,10 @@ clear_immediates (void)
|
|||
integer_imm_defs =
|
||||
Hash_NewTable (16381, 0, imm_free, &integer_imm_defs);
|
||||
Hash_SetHashCompare (integer_imm_defs, imm_get_hash, imm_compare);
|
||||
|
||||
double_imm_defs =
|
||||
Hash_NewTable (16381, 0, imm_free, &double_imm_defs);
|
||||
Hash_SetHashCompare (double_imm_defs, imm_get_hash, imm_compare);
|
||||
}
|
||||
|
||||
def = make_symbol (".zero", &type_zero, 0, sc_extern)->s.def;
|
||||
|
|
|
@ -33,6 +33,7 @@ test_progs_dat=\
|
|||
chewed-return.dat \
|
||||
comma-expr.dat \
|
||||
deadbool.dat \
|
||||
double.dat \
|
||||
enum.dat \
|
||||
fordecl.dat \
|
||||
func-expr.dat \
|
||||
|
@ -111,6 +112,15 @@ deadbool.run: Makefile build-run
|
|||
include ./$(DEPDIR)/deadbool.Qo # am--include-marker
|
||||
r_depfiles_remade += ./$(DEPDIR)/deadbool.Qo
|
||||
|
||||
double_dat_SOURCES=double.r
|
||||
double_obj=$(double_dat_SOURCES:.r=.qfo)
|
||||
double.dat$(EXEEXT): $(double_obj) $(QFCC_DEP)
|
||||
$(QFCC) $(QCFLAGS) -o $@ $(double_obj)
|
||||
double.run: Makefile build-run
|
||||
$(srcdir)/build-run $@
|
||||
include ./$(DEPDIR)/double.Qo # am--include-marker
|
||||
r_depfiles_remade += ./$(DEPDIR)/double.Qo
|
||||
|
||||
enum_dat_SOURCES=enum.r
|
||||
enum_obj=$(enum_dat_SOURCES:.r=.qfo)
|
||||
enum.dat$(EXEEXT): $(enum_obj) $(QFCC_DEP)
|
||||
|
|
|
@ -9,7 +9,7 @@ void foo (void)
|
|||
return;
|
||||
if (!time) {
|
||||
ent = spawn ();
|
||||
ent.f = time + 0.1;
|
||||
ent.f = time + 0.1f;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
25
tools/qfcc/test/double.r
Normal file
25
tools/qfcc/test/double.r
Normal file
|
@ -0,0 +1,25 @@
|
|||
void printf (string fmt, ...) = #0;
|
||||
# define M_PI 3.14159265358979323846
|
||||
|
||||
union {
|
||||
double d;
|
||||
int i[2];
|
||||
} type_pun;
|
||||
|
||||
int
|
||||
test_format ()
|
||||
{
|
||||
int fail = 0;
|
||||
type_pun.d = M_PI;
|
||||
printf ("%g %08x%08x\n", type_pun.d, type_pun.i[1], type_pun.i[0]);
|
||||
//printf ("%08x%08x\n", type_pun.i[1], type_pun.i[0]);
|
||||
return fail;
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
int fail = 0;
|
||||
fail |= test_format ();
|
||||
return fail;
|
||||
}
|
|
@ -13,7 +13,7 @@ state0 (void)
|
|||
[$frame1, state1]
|
||||
{
|
||||
if (self.frame != $frame1 || self.think != state1
|
||||
|| self.nextthink != 0.1) {
|
||||
|| self.nextthink != 0.1f) {
|
||||
printf ("state0: %g %x %g\n", self.frame, self.think, self.nextthink);
|
||||
exit (1);
|
||||
}
|
||||
|
@ -21,10 +21,10 @@ state0 (void)
|
|||
|
||||
void
|
||||
state1 (void)
|
||||
[$frame2, state2, 0.2]
|
||||
[$frame2, state2, 0.2f]
|
||||
{
|
||||
if (self.frame != $frame2 || self.think != state2
|
||||
|| self.nextthink != 0.2) {
|
||||
|| self.nextthink != 0.2f) {
|
||||
printf ("state0: %g %x %g\n", self.frame, self.think, self.nextthink);
|
||||
exit (1);
|
||||
}
|
||||
|
@ -32,10 +32,10 @@ state1 (void)
|
|||
|
||||
void
|
||||
state2 (void)
|
||||
[$frame0, state0, 0.5]
|
||||
[$frame0, state0, 0.5f]
|
||||
{
|
||||
if (self.frame != $frame0 || self.think != state0
|
||||
|| self.nextthink != 0.5) {
|
||||
|| self.nextthink != 0.5f) {
|
||||
printf ("state0: %g %x %g\n", self.frame, self.think, self.nextthink);
|
||||
exit (1);
|
||||
}
|
||||
|
|
|
@ -135,9 +135,13 @@ init_qf (void)
|
|||
|
||||
Memory_Init (malloc (1024 * 1024), 1024 * 1024);
|
||||
|
||||
Cvar_Get ("pr_debug", "2", 0, 0, 0);
|
||||
cvar_t *debug = Cvar_Get ("pr_debug", "2", 0, 0, 0);
|
||||
Cvar_Get ("pr_boundscheck", "2", 0, 0, 0);
|
||||
|
||||
if (options.trace > 1) {
|
||||
Cvar_SetValue (debug, 4);
|
||||
}
|
||||
|
||||
pr.edicts = &edicts;
|
||||
pr.num_edicts = &num_edicts;
|
||||
pr.reserved_edicts = &reserved_edicts;
|
||||
|
@ -207,7 +211,7 @@ parse_options (int argc, char **argv)
|
|||
options.flote = 1;
|
||||
break;
|
||||
case 't':
|
||||
options.trace = 1;
|
||||
options.trace++;
|
||||
break;
|
||||
case 'h':
|
||||
usage (0);
|
||||
|
|
Loading…
Reference in a new issue