mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-17 01:11:45 +00:00
fix (expr_type1 && expr_type2). this involed type completing expressions :/
This commit is contained in:
parent
ed0d1d8ba8
commit
098305d649
3 changed files with 175 additions and 40 deletions
|
@ -4,11 +4,16 @@ typedef enum {
|
|||
ex_expr, // binary expression
|
||||
ex_uexpr, // unary expression
|
||||
ex_def,
|
||||
ex_int,
|
||||
ex_float,
|
||||
|
||||
ex_string,
|
||||
ex_float,
|
||||
ex_vector,
|
||||
ex_entity,
|
||||
ex_field,
|
||||
ex_func,
|
||||
ex_pointer,
|
||||
ex_quaternion,
|
||||
ex_int,
|
||||
} expr_type;
|
||||
|
||||
typedef struct {
|
||||
|
@ -38,11 +43,16 @@ typedef struct expr_s {
|
|||
struct expr_s *e2;
|
||||
} expr;
|
||||
def_t *def;
|
||||
int int_val;
|
||||
float float_val;
|
||||
|
||||
char *string_val;
|
||||
float float_val;
|
||||
float vector_val[3];
|
||||
int entity_val;
|
||||
int field_val;
|
||||
int func_val;
|
||||
int pointer_val;
|
||||
float quaternion_val[4];
|
||||
int int_val;
|
||||
} e;
|
||||
} expr_t;
|
||||
|
||||
|
|
|
@ -12,16 +12,21 @@ extern function_t *current_func;
|
|||
int lineno_base;
|
||||
|
||||
static etype_t qc_types[] = {
|
||||
ev_void, // ex_label
|
||||
ev_void, // ex_block
|
||||
ev_void, // ex_expr
|
||||
ev_void, // ex_uexpr
|
||||
ev_void, // ex_def
|
||||
ev_void, // FIXME ex_int
|
||||
ev_float, // ex_float
|
||||
ev_string, // ex_string
|
||||
ev_vector, // ex_vector
|
||||
ev_void, // FIXME ex_quaternion
|
||||
ev_void, // ex_label
|
||||
ev_void, // ex_block
|
||||
ev_void, // ex_expr
|
||||
ev_void, // ex_uexpr
|
||||
ev_void, // ex_def
|
||||
|
||||
ev_string, // ex_string
|
||||
ev_float, // ex_float
|
||||
ev_vector, // ex_vector
|
||||
ev_entity, // ex_entity
|
||||
ev_field, // ex_field
|
||||
ev_func, // ex_func
|
||||
ev_pointer, // ex_pointer
|
||||
ev_quaternion, // ex_quaternion
|
||||
ev_int, // ex_int
|
||||
};
|
||||
|
||||
static type_t *types[] = {
|
||||
|
@ -33,6 +38,8 @@ static type_t *types[] = {
|
|||
&type_field,
|
||||
&type_function,
|
||||
&type_pointer,
|
||||
&type_quaternion,
|
||||
//XXX&type_int,
|
||||
};
|
||||
|
||||
static expr_type expr_types[] = {
|
||||
|
@ -40,10 +47,12 @@ static expr_type expr_types[] = {
|
|||
ex_string, // ev_string
|
||||
ex_float, // ev_float
|
||||
ex_vector, // ev_vector
|
||||
ex_label, // ev_entity (ick)
|
||||
ex_label, // ev_field (ick)
|
||||
ex_label, // ev_func (ick)
|
||||
ex_label, // ev_pointer (ick)
|
||||
ex_entity, // ev_entity
|
||||
ex_field, // ev_field
|
||||
ex_func, // ev_func
|
||||
ex_pointer, // ev_pointer
|
||||
ex_quaternion, // ev_quaternion
|
||||
ex_int, // ev_int
|
||||
};
|
||||
|
||||
static const char *type_names[] = {
|
||||
|
@ -56,6 +65,7 @@ static const char *type_names[] = {
|
|||
"function",
|
||||
"pointer",
|
||||
"quaternion",
|
||||
"int",
|
||||
};
|
||||
|
||||
static etype_t
|
||||
|
@ -64,22 +74,25 @@ get_type (expr_t *e)
|
|||
switch (e->type) {
|
||||
case ex_label:
|
||||
case ex_block:
|
||||
case ex_quaternion: //FIXME
|
||||
return ev_void;
|
||||
case ex_expr:
|
||||
case ex_uexpr:
|
||||
return e->e.expr.type->type;
|
||||
case ex_def:
|
||||
return e->e.def->type->type;
|
||||
case ex_string:
|
||||
case ex_float:
|
||||
case ex_vector:
|
||||
case ex_entity:
|
||||
case ex_field:
|
||||
case ex_func:
|
||||
case ex_pointer:
|
||||
case ex_quaternion:
|
||||
return qc_types[e->type];
|
||||
case ex_int: //FIXME?
|
||||
e->type = ex_float;
|
||||
e->e.float_val = e->e.int_val;
|
||||
return ev_float;
|
||||
case ex_float:
|
||||
case ex_string:
|
||||
case ex_vector:
|
||||
//FIXME case ex_quaternion:
|
||||
return qc_types[e->type];
|
||||
}
|
||||
return ev_void;
|
||||
}
|
||||
|
@ -313,15 +326,12 @@ print_expr (expr_t *e)
|
|||
case ex_def:
|
||||
printf ("%s", e->e.def->name);
|
||||
break;
|
||||
case ex_int:
|
||||
printf ("%d", e->e.int_val);
|
||||
case ex_string:
|
||||
printf ("\"%s\"", e->e.string_val);
|
||||
break;
|
||||
case ex_float:
|
||||
printf ("%g", e->e.float_val);
|
||||
break;
|
||||
case ex_string:
|
||||
printf ("\"%s\"", e->e.string_val);
|
||||
break;
|
||||
case ex_vector:
|
||||
printf ("'%g", e->e.vector_val[0]);
|
||||
printf ( " %g", e->e.vector_val[1]);
|
||||
|
@ -333,6 +343,13 @@ print_expr (expr_t *e)
|
|||
printf (" %g", e->e.quaternion_val[2]);
|
||||
printf (" %g'", e->e.quaternion_val[3]);
|
||||
break;
|
||||
case ex_entity:
|
||||
case ex_field:
|
||||
case ex_func:
|
||||
case ex_pointer:
|
||||
case ex_int:
|
||||
printf ("%d", e->e.int_val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -537,6 +554,54 @@ field_expr (expr_t *e1, expr_t *e2)
|
|||
return e;
|
||||
}
|
||||
|
||||
static expr_t *
|
||||
test_expr (expr_t *e, int test)
|
||||
{
|
||||
expr_t *new = 0;
|
||||
|
||||
if (!test)
|
||||
return unary_expr ('!', e);
|
||||
|
||||
switch (get_type (e)) {
|
||||
case ev_int://FIXME
|
||||
case ev_type_count:
|
||||
case ev_void:
|
||||
error (e, "internal error");
|
||||
abort ();
|
||||
case ev_string:
|
||||
new = new_expr ();
|
||||
new->type = ex_string;
|
||||
break;
|
||||
case ev_float:
|
||||
return e;
|
||||
case ev_vector:
|
||||
new = new_expr ();
|
||||
new->type = ex_vector;
|
||||
break;
|
||||
case ev_entity:
|
||||
new = new_expr ();
|
||||
new->type = ex_entity;
|
||||
break;
|
||||
case ev_field:
|
||||
new = new_expr ();
|
||||
new->type = ex_field;
|
||||
break;
|
||||
case ev_func:
|
||||
new = new_expr ();
|
||||
new->type = ex_func;
|
||||
break;
|
||||
case ev_pointer:
|
||||
new = new_expr ();
|
||||
new->type = ex_pointer;
|
||||
break;
|
||||
case ev_quaternion:
|
||||
new = new_expr ();
|
||||
new->type = ex_quaternion;
|
||||
break;
|
||||
}
|
||||
return binary_expr (NE, e, new);
|
||||
}
|
||||
|
||||
expr_t *
|
||||
binary_expr (int op, expr_t *e1, expr_t *e2)
|
||||
{
|
||||
|
@ -545,7 +610,12 @@ binary_expr (int op, expr_t *e1, expr_t *e2)
|
|||
if (op == '.')
|
||||
return field_expr (e1, e2);
|
||||
|
||||
if (e1->type >= ex_int && e2->type >= ex_int)
|
||||
if (op == OR || op == AND) {
|
||||
e1 = test_expr (e1, true);
|
||||
e2 = test_expr (e2, true);
|
||||
}
|
||||
|
||||
if (e1->type >= ex_string && e2->type >= ex_string)
|
||||
return binary_const (op, e1, e2);
|
||||
|
||||
if ((op == '&' || op == '|')
|
||||
|
@ -631,6 +701,10 @@ unary_expr (int op, expr_t *e)
|
|||
e->e.float_val *= -1;
|
||||
return e;
|
||||
case ex_string:
|
||||
case ex_entity:
|
||||
case ex_field:
|
||||
case ex_func:
|
||||
case ex_pointer:
|
||||
return error (e, "invalid type for unary -");
|
||||
case ex_vector:
|
||||
e->e.vector_val[0] *= -1;
|
||||
|
@ -682,6 +756,12 @@ unary_expr (int op, expr_t *e)
|
|||
&& !e->e.quaternion_val[3];
|
||||
e->type = ex_int;
|
||||
return e;
|
||||
case ex_entity:
|
||||
case ex_field:
|
||||
case ex_func:
|
||||
case ex_pointer:
|
||||
error (e, "internal error");
|
||||
abort ();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -882,9 +962,9 @@ emit_sub_expr (expr_t *e, def_t *dest)
|
|||
int priority;
|
||||
|
||||
switch (e->type) {
|
||||
default:
|
||||
case ex_label:
|
||||
case ex_block:
|
||||
error (e, "internal error");
|
||||
abort ();
|
||||
case ex_expr:
|
||||
if (e->e.expr.op == 'c')
|
||||
|
@ -983,13 +1063,18 @@ emit_sub_expr (expr_t *e, def_t *dest)
|
|||
return emit_statement (e->line, op, def_a, def_b, dest);
|
||||
case ex_def:
|
||||
return e->e.def;
|
||||
case ex_int:
|
||||
case ex_float:
|
||||
case ex_string:
|
||||
case ex_float:
|
||||
case ex_vector:
|
||||
case ex_entity:
|
||||
case ex_field:
|
||||
case ex_func:
|
||||
case ex_pointer:
|
||||
case ex_quaternion:
|
||||
case ex_int:
|
||||
return PR_ReuseConstant (e, 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1068,11 +1153,15 @@ emit_expr (expr_t *e)
|
|||
}
|
||||
break;
|
||||
case ex_def:
|
||||
case ex_int:
|
||||
case ex_float:
|
||||
case ex_string:
|
||||
case ex_float:
|
||||
case ex_vector:
|
||||
case ex_entity:
|
||||
case ex_field:
|
||||
case ex_func:
|
||||
case ex_pointer:
|
||||
case ex_quaternion:
|
||||
case ex_int:
|
||||
warning (e, "Ignoring useless expression");
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -27,6 +27,10 @@
|
|||
static hashtab_t *string_imm_defs;
|
||||
static hashtab_t *float_imm_defs;
|
||||
static hashtab_t *vector_imm_defs;
|
||||
static hashtab_t *entity_imm_defs;
|
||||
static hashtab_t *field_imm_defs;
|
||||
static hashtab_t *func_imm_defs;
|
||||
static hashtab_t *pointer_imm_defs;
|
||||
static hashtab_t *quaternion_imm_defs;
|
||||
|
||||
static const char *
|
||||
|
@ -66,6 +70,16 @@ quaternion_imm_get_key (void *_def, void *unused)
|
|||
return rep;
|
||||
}
|
||||
|
||||
static const char *
|
||||
int_imm_get_key (void *_def, void *_str)
|
||||
{
|
||||
def_t *def = (def_t*)_def;
|
||||
static char rep[60];
|
||||
char *str = (char*)_str;
|
||||
sprintf (rep, "\001%s:%08X", str, G_INT(def->ofs));
|
||||
return rep;
|
||||
}
|
||||
|
||||
/*
|
||||
PR_ParseImmediate
|
||||
|
||||
|
@ -148,7 +162,7 @@ def_t *
|
|||
PR_ReuseConstant (expr_t *expr, def_t *def)
|
||||
{
|
||||
def_t *cn = 0;
|
||||
char rep[60];
|
||||
char rep[60], *r = rep;
|
||||
hashtab_t *tab = 0;
|
||||
type_t *type;
|
||||
expr_t e = *expr;
|
||||
|
@ -157,19 +171,42 @@ PR_ReuseConstant (expr_t *expr, def_t *def)
|
|||
string_imm_defs = Hash_NewTable (16381, string_imm_get_key, 0, 0);
|
||||
float_imm_defs = Hash_NewTable (16381, float_imm_get_key, 0, 0);
|
||||
vector_imm_defs = Hash_NewTable (16381, vector_imm_get_key, 0, 0);
|
||||
entity_imm_defs = Hash_NewTable (16381, int_imm_get_key, 0, "entity");
|
||||
field_imm_defs = Hash_NewTable (16381, int_imm_get_key, 0, "field");
|
||||
func_imm_defs = Hash_NewTable (16381, int_imm_get_key, 0, "func");
|
||||
pointer_imm_defs = Hash_NewTable (16381, int_imm_get_key, 0, "pointer");
|
||||
quaternion_imm_defs = Hash_NewTable (16381, quaternion_imm_get_key, 0, 0);
|
||||
}
|
||||
switch (e.type) {
|
||||
case ex_entity:
|
||||
sprintf (rep, "\001entity:%08X\001", e.e.int_val);
|
||||
tab = float_imm_defs;
|
||||
type = &type_entity;
|
||||
break;
|
||||
case ex_field:
|
||||
sprintf (rep, "\001field:%08X\001", e.e.int_val);
|
||||
tab = float_imm_defs;
|
||||
type = &type_field;
|
||||
break;
|
||||
case ex_func:
|
||||
sprintf (rep, "\001func:%08X\001", e.e.int_val);
|
||||
tab = float_imm_defs;
|
||||
type = &type_function;
|
||||
break;
|
||||
case ex_pointer:
|
||||
sprintf (rep, "\001pointer:%08X\001", e.e.int_val);
|
||||
tab = pointer_imm_defs;
|
||||
type = &type_pointer;
|
||||
break;
|
||||
case ex_int:
|
||||
e.e.float_val = e.e.int_val; //FIXME
|
||||
case ex_float:
|
||||
sprintf (rep, "\001float:%08X\001", e.e.int_val);
|
||||
cn = (def_t*) Hash_Find (float_imm_defs, rep);
|
||||
tab = float_imm_defs;
|
||||
type = &type_float;
|
||||
break;
|
||||
case ex_string:
|
||||
cn = (def_t*) Hash_Find (string_imm_defs, e.e.string_val);
|
||||
r = e.e.string_val;
|
||||
tab = string_imm_defs;
|
||||
type = &type_string;
|
||||
break;
|
||||
|
@ -178,7 +215,6 @@ PR_ReuseConstant (expr_t *expr, def_t *def)
|
|||
*(int*)&e.e.vector_val[0],
|
||||
*(int*)&e.e.vector_val[1],
|
||||
*(int*)&e.e.vector_val[2]);
|
||||
cn = (def_t*) Hash_Find (vector_imm_defs, rep);
|
||||
tab = vector_imm_defs;
|
||||
type = &type_vector;
|
||||
break;
|
||||
|
@ -188,13 +224,13 @@ PR_ReuseConstant (expr_t *expr, def_t *def)
|
|||
*(int*)&e.e.quaternion_val[1],
|
||||
*(int*)&e.e.quaternion_val[2],
|
||||
*(int*)&e.e.quaternion_val[3]);
|
||||
cn = (def_t*) Hash_Find (quaternion_imm_defs, rep);
|
||||
tab = vector_imm_defs;
|
||||
type = &type_quaternion;
|
||||
break;
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
cn = (def_t*) Hash_Find (tab, rep);
|
||||
if (cn) {
|
||||
if (def) {
|
||||
PR_FreeLocation (def);
|
||||
|
|
Loading…
Reference in a new issue