mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-26 22:31:05 +00:00
Support assigning non-constant vector expressions.
This commit is contained in:
parent
e03dfa29b4
commit
78e0a8dc52
17 changed files with 536 additions and 253 deletions
|
@ -171,7 +171,8 @@ typedef struct {
|
|||
typedef struct ex_value_s {
|
||||
struct ex_value_s *next;
|
||||
struct daglabel_s *daglabel;///< dag label for this value
|
||||
etype_t type;
|
||||
struct type_s *type;
|
||||
etype_t lltype;
|
||||
union {
|
||||
const char *string_val; ///< string constant
|
||||
float float_val; ///< float constant
|
||||
|
|
|
@ -155,10 +155,13 @@ int is_enum (const type_t *type) __attribute__((pure));
|
|||
int is_integral (const type_t *type) __attribute__((pure));
|
||||
int is_float (const type_t *type) __attribute__((pure));
|
||||
int is_scalar (const type_t *type) __attribute__((pure));
|
||||
int is_vector (const type_t *type) __attribute__((pure));
|
||||
int is_quaternion (const type_t *type) __attribute__((pure));
|
||||
int is_math (const type_t *type) __attribute__((pure));
|
||||
int is_pointer (const type_t *type) __attribute__((pure));
|
||||
int is_struct (const type_t *type) __attribute__((pure));
|
||||
int is_array (const type_t *type) __attribute__((pure));
|
||||
int is_func (const type_t *type) __attribute__((pure));
|
||||
int type_assignable (const type_t *dst, const type_t *src);
|
||||
int type_size (const type_t *type) __attribute__((pure));
|
||||
|
||||
|
|
|
@ -41,7 +41,8 @@ bin_SCRIPTS= qfpreqcc
|
|||
common_src=\
|
||||
class.c codespace.c constfold.c cpp.c dags.c debug.c def.c defspace.c \
|
||||
diagnostic.c dot.c dot_dag.c dot_expr.c dot_flow.c dot_sblock.c emit.c \
|
||||
expr.c expr_binary.c flow.c function.c grab.c idstuff.c linker.c method.c \
|
||||
expr.c expr_assign.c expr_binary.c flow.c function.c grab.c idstuff.c \
|
||||
linker.c method.c \
|
||||
obj_file.c \
|
||||
obj_type.c opcodes.c options.c pragma.c qfcc.c reloc.c shared.c \
|
||||
statements.c strpool.c struct.c switch.c symtab.c type.c value.c
|
||||
|
|
|
@ -140,7 +140,7 @@ convert_to_float (expr_t *e)
|
|||
|
||||
switch (e->type) {
|
||||
case ex_value:
|
||||
switch (e->e.value->type) {
|
||||
switch (e->e.value->lltype) {
|
||||
case ev_integer:
|
||||
convert_int (e);
|
||||
return e;
|
||||
|
|
|
@ -356,7 +356,7 @@ dagnode_set_edges (dag_t *dag, dagnode_t *n)
|
|||
if (node != child && node != n)
|
||||
set_add (node->edges, n->number);
|
||||
if (op->op_type == op_value
|
||||
&& op->o.value->type == ev_pointer
|
||||
&& op->o.value->lltype == ev_pointer
|
||||
&& op->o.value->v.pointer.def)
|
||||
def_visit_all (op->o.value->v.pointer.def, 1,
|
||||
dagnode_set_edges_visit, n);
|
||||
|
|
|
@ -350,7 +350,7 @@ init_elements (struct def_s *def, expr_t *eles)
|
|||
reloc_def_op (c->e.labelref.label, &loc);
|
||||
continue;
|
||||
} else if (c->type == ex_value) {
|
||||
if (c->e.value->type == ev_integer
|
||||
if (c->e.value->lltype == ev_integer
|
||||
&& elements[i].type->type == ev_float)
|
||||
convert_int (c);
|
||||
if (get_type (c) != elements[i].type) {
|
||||
|
@ -372,7 +372,7 @@ init_elements (struct def_s *def, expr_t *eles)
|
|||
} else {
|
||||
if (c->type != ex_value)
|
||||
internal_error (c, "bogus expression type in init_elements()");
|
||||
if (c->e.value->type == ev_string) {
|
||||
if (c->e.value->lltype == ev_string) {
|
||||
EMIT_STRING (def->space, g->string_var,
|
||||
c->e.value->v.string_val);
|
||||
} else {
|
||||
|
@ -407,7 +407,7 @@ init_vector_components (symbol_t *vector_sym, int is_field)
|
|||
expr = sym->s.expr;
|
||||
if (is_field) {
|
||||
if (expr->type != ex_value
|
||||
|| expr->e.value->type != ev_field) {
|
||||
|| expr->e.value->lltype != ev_field) {
|
||||
error (0, "%s redefined", name);
|
||||
sym = 0;
|
||||
} else {
|
||||
|
@ -574,8 +574,8 @@ initialize_def (symbol_t *sym, type_t *type, expr_t *init, defspace_t *space,
|
|||
error (0, "non-constant initializier");
|
||||
return;
|
||||
}
|
||||
if (init->e.value->type == ev_pointer
|
||||
|| init->e.value->type == ev_field) {
|
||||
if (init->e.value->lltype == ev_pointer
|
||||
|| init->e.value->lltype == ev_field) {
|
||||
// FIXME offset pointers
|
||||
D_INT (sym->s.def) = init->e.value->v.pointer.val;
|
||||
if (init->e.value->v.pointer.def)
|
||||
|
@ -584,7 +584,7 @@ initialize_def (symbol_t *sym, type_t *type, expr_t *init, defspace_t *space,
|
|||
ex_value_t *v = init->e.value;
|
||||
if (is_scalar (sym->type))
|
||||
v = convert_value (v, sym->type);
|
||||
if (v->type == ev_string) {
|
||||
if (v->lltype == ev_string) {
|
||||
EMIT_STRING (sym->s.def->space, D_STRING (sym->s.def),
|
||||
v->v.string_val);
|
||||
} else {
|
||||
|
|
|
@ -386,7 +386,7 @@ print_value (dstring_t *dstr, expr_t *e, int level, int id, expr_t *next)
|
|||
type_t *type;
|
||||
const char *label = "?!?";
|
||||
|
||||
switch (e->e.value->type) {
|
||||
switch (e->e.value->lltype) {
|
||||
case ev_string:
|
||||
label = va ("\\\"%s\\\"", quote_string (e->e.value->v.string_val));
|
||||
break;
|
||||
|
|
|
@ -159,6 +159,13 @@ convert_vector (expr_t *e)
|
|||
val[2] = expr_float(z);
|
||||
return new_vector_expr (val);
|
||||
}
|
||||
// at least one of x, y, z is not constant, so rebuild the
|
||||
// list incase any of them are new expressions
|
||||
z->next = 0;
|
||||
y->next = z;
|
||||
x->next = y;
|
||||
e->e.vector.list = x;
|
||||
return e;
|
||||
}
|
||||
if (e->e.vector.type == &type_quaternion) {
|
||||
// guaranteed to have two or four elements
|
||||
|
@ -180,6 +187,14 @@ convert_vector (expr_t *e)
|
|||
val[3] = expr_float(w);
|
||||
return new_quaternion_expr (val);
|
||||
}
|
||||
// at least one of x, y, z, w is not constant, so rebuild the
|
||||
// list incase any of them are new expressions
|
||||
w->next = 0;
|
||||
z->next = w;
|
||||
y->next = z;
|
||||
x->next = y;
|
||||
e->e.vector.list = x;
|
||||
return e;
|
||||
} else {
|
||||
// v, s
|
||||
expr_t *v = e->e.vector.list;
|
||||
|
@ -192,7 +207,7 @@ convert_vector (expr_t *e)
|
|||
val[3] = expr_float (s);
|
||||
return new_quaternion_expr (val);
|
||||
}
|
||||
// Either v or is is not constant, so can't convert to a quaternion
|
||||
// Either v or s is not constant, so can't convert to a quaternion
|
||||
// constant.
|
||||
// Rebuild the list in case v or s is a new expression
|
||||
s->next = 0;
|
||||
|
@ -233,17 +248,7 @@ get_type (expr_t *e)
|
|||
case ex_temp:
|
||||
return e->e.temp.type;
|
||||
case ex_value:
|
||||
if (e->e.value->type == ev_func)
|
||||
return e->e.value->v.func_val.type;
|
||||
if (e->e.value->type == ev_pointer)
|
||||
return pointer_type (e->e.value->v.pointer.type);
|
||||
if (e->e.value->type == ev_field)
|
||||
return field_type (e->e.value->v.pointer.type);
|
||||
if (e->e.value->type == ev_integer
|
||||
&& options.code.progsversion == PROG_ID_VERSION) {
|
||||
convert_int (e);
|
||||
}
|
||||
return ev_types[e->e.value->type];
|
||||
return e->e.value->type;
|
||||
case ex_vector:
|
||||
return e->e.vector.type;
|
||||
}
|
||||
|
@ -801,7 +806,7 @@ is_string_val (expr_t *e)
|
|||
{
|
||||
if (e->type == ex_nil)
|
||||
return 1;
|
||||
if (e->type == ex_value && e->e.value->type == ev_string)
|
||||
if (e->type == ex_value && e->e.value->lltype == ev_string)
|
||||
return 1;
|
||||
if (e->type == ex_symbol && e->e.symbol->sy_type == sy_const
|
||||
&& e->e.symbol->type->type == ev_string)
|
||||
|
@ -814,7 +819,7 @@ expr_string (expr_t *e)
|
|||
{
|
||||
if (e->type == ex_nil)
|
||||
return 0;
|
||||
if (e->type == ex_value && e->e.value->type == ev_string)
|
||||
if (e->type == ex_value && e->e.value->lltype == ev_string)
|
||||
return e->e.value->v.string_val;
|
||||
internal_error (e, "not a string constant");
|
||||
}
|
||||
|
@ -824,7 +829,7 @@ is_float_val (expr_t *e)
|
|||
{
|
||||
if (e->type == ex_nil)
|
||||
return 1;
|
||||
if (e->type == ex_value && e->e.value->type == ev_float)
|
||||
if (e->type == ex_value && e->e.value->lltype == ev_float)
|
||||
return 1;
|
||||
if (e->type == ex_symbol && e->e.symbol->sy_type == sy_const
|
||||
&& e->e.symbol->type->type == ev_float)
|
||||
|
@ -837,7 +842,7 @@ expr_float (expr_t *e)
|
|||
{
|
||||
if (e->type == ex_nil)
|
||||
return 0;
|
||||
if (e->type == ex_value && e->e.value->type == ev_float)
|
||||
if (e->type == ex_value && e->e.value->lltype == ev_float)
|
||||
return e->e.value->v.float_val;
|
||||
if (e->type == ex_symbol && e->e.symbol->sy_type == sy_const
|
||||
&& e->e.symbol->type->type == ev_float)
|
||||
|
@ -854,7 +859,7 @@ is_vector_val (expr_t *e)
|
|||
{
|
||||
if (e->type == ex_nil)
|
||||
return 1;
|
||||
if (e->type == ex_value && e->e.value->type == ev_vector)
|
||||
if (e->type == ex_value && e->e.value->lltype == ev_vector)
|
||||
return 1;
|
||||
if (e->type == ex_symbol && e->e.symbol->sy_type == sy_const
|
||||
&& e->e.symbol->type->type == ev_vector)
|
||||
|
@ -867,7 +872,7 @@ expr_vector (expr_t *e)
|
|||
{
|
||||
if (e->type == ex_nil)
|
||||
return vec3_origin;
|
||||
if (e->type == ex_value && e->e.value->type == ev_vector)
|
||||
if (e->type == ex_value && e->e.value->lltype == ev_vector)
|
||||
return e->e.value->v.vector_val;
|
||||
if (e->type == ex_symbol && e->e.symbol->sy_type == sy_const
|
||||
&& e->e.symbol->type->type == ev_vector)
|
||||
|
@ -884,7 +889,7 @@ is_quaternion_val (expr_t *e)
|
|||
{
|
||||
if (e->type == ex_nil)
|
||||
return 1;
|
||||
if (e->type == ex_value && e->e.value->type == ev_quat)
|
||||
if (e->type == ex_value && e->e.value->lltype == ev_quat)
|
||||
return 1;
|
||||
if (e->type == ex_symbol && e->e.symbol->sy_type == sy_const
|
||||
&& e->e.symbol->type->type == ev_quat)
|
||||
|
@ -897,7 +902,7 @@ expr_quaternion (expr_t *e)
|
|||
{
|
||||
if (e->type == ex_nil)
|
||||
return quat_origin;
|
||||
if (e->type == ex_value && e->e.value->type == ev_quat)
|
||||
if (e->type == ex_value && e->e.value->lltype == ev_quat)
|
||||
return e->e.value->v.quaternion_val;
|
||||
if (e->type == ex_symbol && e->e.symbol->sy_type == sy_const
|
||||
&& e->e.symbol->type->type == ev_quat)
|
||||
|
@ -914,7 +919,7 @@ is_integer_val (expr_t *e)
|
|||
{
|
||||
if (e->type == ex_nil)
|
||||
return 1;
|
||||
if (e->type == ex_value && e->e.value->type == ev_integer)
|
||||
if (e->type == ex_value && e->e.value->lltype == ev_integer)
|
||||
return 1;
|
||||
if (e->type == ex_symbol && e->e.symbol->sy_type == sy_const
|
||||
&& (e->e.symbol->type->type == ev_integer
|
||||
|
@ -928,7 +933,7 @@ expr_integer (expr_t *e)
|
|||
{
|
||||
if (e->type == ex_nil)
|
||||
return 0;
|
||||
if (e->type == ex_value && e->e.value->type == ev_integer)
|
||||
if (e->type == ex_value && e->e.value->lltype == ev_integer)
|
||||
return e->e.value->v.integer_val;
|
||||
if (e->type == ex_symbol && e->e.symbol->sy_type == sy_const
|
||||
&& (e->e.symbol->type->type == ev_integer
|
||||
|
@ -946,7 +951,7 @@ expr_uinteger (expr_t *e)
|
|||
{
|
||||
if (e->type == ex_nil)
|
||||
return 0;
|
||||
if (e->type == ex_value && e->e.value->type == ev_uinteger)
|
||||
if (e->type == ex_value && e->e.value->lltype == ev_uinteger)
|
||||
return e->e.value->v.uinteger_val;
|
||||
if (e->type == ex_symbol && e->e.symbol->sy_type == sy_const
|
||||
&& e->e.symbol->type->type == ev_uinteger)
|
||||
|
@ -963,7 +968,7 @@ is_short_val (expr_t *e)
|
|||
{
|
||||
if (e->type == ex_nil)
|
||||
return 1;
|
||||
if (e->type == ex_value && e->e.value->type == ev_short)
|
||||
if (e->type == ex_value && e->e.value->lltype == ev_short)
|
||||
return 1;
|
||||
if (e->type == ex_symbol && e->e.symbol->sy_type == sy_const
|
||||
&& e->e.symbol->type->type == ev_short)
|
||||
|
@ -976,7 +981,7 @@ expr_short (expr_t *e)
|
|||
{
|
||||
if (e->type == ex_nil)
|
||||
return 0;
|
||||
if (e->type == ex_value && e->e.value->type == ev_short)
|
||||
if (e->type == ex_value && e->e.value->lltype == ev_short)
|
||||
return e->e.value->v.short_val;
|
||||
if (e->type == ex_symbol && e->e.symbol->sy_type == sy_const
|
||||
&& e->e.symbol->type->type == ev_short)
|
||||
|
@ -1172,7 +1177,8 @@ field_expr (expr_t *e1, expr_t *e2)
|
|||
}
|
||||
def = sym->s.def;
|
||||
e2 = new_field_expr (0, field->type, def);
|
||||
} else if (e2->type != ex_value || e2->e.value->type != ev_field) {
|
||||
} else if (e2->type != ex_value
|
||||
|| e2->e.value->lltype != ev_field) {
|
||||
internal_error (e2, "unexpected field exression");
|
||||
}
|
||||
e2->e.value = new_field_val (e2->e.value->v.pointer.val + field->s.offset, field->type, e2->e.value->v.pointer.def);
|
||||
|
@ -2215,7 +2221,7 @@ address_expr (expr_t *e1, expr_t *e2, type_t *t)
|
|||
if (e2) {
|
||||
if (e2->type == ex_error)
|
||||
return e2;
|
||||
if (e->type == ex_value && e->e.value->type == ev_pointer
|
||||
if (e->type == ex_value && e->e.value->lltype == ev_pointer
|
||||
&& is_short_val (e2)) {
|
||||
e->e.value = new_pointer_val (e->e.value->v.pointer.val + expr_short (e2), t, e->e.value->v.pointer.def);
|
||||
} else {
|
||||
|
@ -2479,24 +2485,6 @@ think_expr (symbol_t *think_sym)
|
|||
return new_symbol_expr (think_sym);
|
||||
}
|
||||
|
||||
static __attribute__((pure)) int
|
||||
is_indirect (expr_t *e)
|
||||
{
|
||||
if (e->type == ex_block && e->e.block.result)
|
||||
return is_indirect (e->e.block.result);
|
||||
if (e->type == ex_expr && e->e.expr.op == '.')
|
||||
return 1;
|
||||
if (!(e->type == ex_uexpr && e->e.expr.op == '.'))
|
||||
return 0;
|
||||
e = e->e.expr.e1;
|
||||
if (e->type != ex_value || e->e.value->type != ev_pointer
|
||||
|| !(POINTER_VAL (e->e.value->v.pointer) >= 0
|
||||
&& POINTER_VAL (e->e.value->v.pointer) < 65536)) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline __attribute__((pure)) int
|
||||
is_lvalue (expr_t *e)
|
||||
{
|
||||
|
@ -2527,150 +2515,6 @@ is_lvalue (expr_t *e)
|
|||
return 0;
|
||||
}
|
||||
|
||||
expr_t *
|
||||
assign_expr (expr_t *e1, expr_t *e2)
|
||||
{
|
||||
int op = '=';
|
||||
type_t *t1, *t2, *type;
|
||||
expr_t *e;
|
||||
|
||||
convert_name (e1);
|
||||
convert_name (e2);
|
||||
e2 = convert_vector (e2);
|
||||
|
||||
if (e1->type == ex_error)
|
||||
return e1;
|
||||
if (e2->type == ex_error)
|
||||
return e2;
|
||||
|
||||
e1 = fold_constants (e1);
|
||||
e2 = fold_constants (e2);
|
||||
|
||||
if (options.traditional) {
|
||||
if (e2->type == ex_expr && !e2->paren
|
||||
&& (e2->e.expr.op == AND || e2->e.expr.op == OR)) {
|
||||
notice (e2, "precedence of `%s' and `%s' inverted for "
|
||||
"traditional code", get_op_string (op),
|
||||
get_op_string (e2->e.expr.op));
|
||||
e1 = assign_expr (e1, e2->e.expr.e1);
|
||||
e1->paren = 1;
|
||||
return binary_expr (e2->e.expr.op, e1, e2->e.expr.e2);
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_lvalue (e1)) {
|
||||
if (options.traditional)
|
||||
warning (e1, "invalid lvalue in assignment");
|
||||
else
|
||||
return error (e1, "invalid lvalue in assignment");
|
||||
}
|
||||
t1 = get_type (e1);
|
||||
t2 = get_type (e2);
|
||||
if (!t1 || !t2)
|
||||
internal_error (e1, 0);
|
||||
//XXX func = func ???
|
||||
if (t1->type == ev_pointer && is_array (t2)) {
|
||||
e2 = address_expr (e2, 0, t2->t.fldptr.type);
|
||||
t2 = get_type (e2);
|
||||
}
|
||||
if (e2->type == ex_bool)
|
||||
e2 = convert_from_bool (e2, t1);
|
||||
|
||||
if (t1->type != ev_void && e2->type == ex_nil) {
|
||||
t2 = t1;
|
||||
convert_nil (e2, t2);
|
||||
}
|
||||
|
||||
e2->rvalue = 1;
|
||||
|
||||
if (!type_assignable (t1, t2)) {
|
||||
if (options.traditional) {
|
||||
if (t1->type == ev_func && t2->type == ev_func) {
|
||||
warning (e1, "assignment between disparate function types");
|
||||
} else if (t1->type == ev_float && t2->type == ev_vector) {
|
||||
warning (e1, "assignment of vector to float");
|
||||
e2 = field_expr (e2, new_name_expr ("x"));
|
||||
} else if (t1->type == ev_vector && t2->type == ev_float) {
|
||||
warning (e1, "assignment of float to vector");
|
||||
e1 = field_expr (e1, new_name_expr ("x"));
|
||||
} else {
|
||||
return type_mismatch (e1, e2, op);
|
||||
}
|
||||
} else {
|
||||
return type_mismatch (e1, e2, op);
|
||||
}
|
||||
}
|
||||
type = t1;
|
||||
if (is_indirect (e1) && is_indirect (e2)) {
|
||||
if (is_struct (get_type (e2))) {
|
||||
e1 = address_expr (e1, 0, 0);
|
||||
e2 = address_expr (e2, 0, 0);
|
||||
e = new_move_expr (e1, e2, t2, 1);
|
||||
} else {
|
||||
expr_t *temp = new_temp_def_expr (t1);
|
||||
|
||||
e = new_block_expr ();
|
||||
append_expr (e, assign_expr (temp, e2));
|
||||
append_expr (e, assign_expr (e1, temp));
|
||||
e->e.block.result = temp;
|
||||
}
|
||||
return e;
|
||||
} else if (is_indirect (e1)) {
|
||||
if (is_struct (get_type (e1))) {
|
||||
e1 = address_expr (e1, 0, 0);
|
||||
e2 = address_expr (e2, 0, 0);
|
||||
return new_move_expr (e1, e2, t1, 1);
|
||||
}
|
||||
if (e1->type == ex_expr) {
|
||||
if (get_type (e1->e.expr.e1) == &type_entity) {
|
||||
type = e1->e.expr.type;
|
||||
e1->e.expr.type = pointer_type (type);
|
||||
e1->e.expr.op = '&';
|
||||
}
|
||||
op = PAS;
|
||||
} else {
|
||||
e = e1->e.expr.e1;
|
||||
if ((e->type != ex_value || e->e.value->type != ev_pointer)
|
||||
|| !(POINTER_VAL (e->e.value->v.pointer) > 0
|
||||
&& POINTER_VAL (e->e.value->v.pointer) < 65536)) {
|
||||
e1 = e;
|
||||
op = PAS;
|
||||
}
|
||||
}
|
||||
} else if (is_indirect (e2)) {
|
||||
if (is_struct (get_type (e1))) {
|
||||
e1 = address_expr (e1, 0, 0);
|
||||
e2 = address_expr (e2, 0, 0);
|
||||
e2->rvalue = 1;
|
||||
return new_move_expr (e1, e2, t2, 1);
|
||||
}
|
||||
if (e2->type == ex_uexpr) {
|
||||
e = e2->e.expr.e1;
|
||||
if ((e->type != ex_value || e->e.value->type != ev_pointer)
|
||||
|| !(POINTER_VAL (e->e.value->v.pointer) > 0
|
||||
&& POINTER_VAL (e->e.value->v.pointer) < 65536)) {
|
||||
if (e->type == ex_expr && e->e.expr.op == '&'
|
||||
&& e->e.expr.type->type == ev_pointer
|
||||
&& !is_constant (e)) {
|
||||
e2 = e;
|
||||
e2->e.expr.op = '.';
|
||||
e2->e.expr.type = t2;
|
||||
e2->rvalue = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (is_struct (get_type (e1))) {
|
||||
return new_move_expr (e1, e2, get_type (e1), 0);
|
||||
}
|
||||
if (!type)
|
||||
internal_error (e1, 0);
|
||||
|
||||
e = new_binary_expr (op, e1, e2);
|
||||
e->e.expr.type = type;
|
||||
return e;
|
||||
}
|
||||
|
||||
expr_t *
|
||||
cast_expr (type_t *type, expr_t *e)
|
||||
{
|
||||
|
|
396
tools/qfcc/source/expr_assign.c
Normal file
396
tools/qfcc/source/expr_assign.c
Normal file
|
@ -0,0 +1,396 @@
|
|||
/*
|
||||
expr_assign.c
|
||||
|
||||
assignment expression construction and manipulations
|
||||
|
||||
Copyright (C) 2001 Bill Currie <bill@taniwha.org>
|
||||
|
||||
Author: Bill Currie <bill@taniwha.org>
|
||||
Date: 2001/06/15
|
||||
|
||||
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:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRINGS_H
|
||||
# include <strings.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "QF/alloc.h"
|
||||
#include "QF/dstring.h"
|
||||
#include "QF/mathlib.h"
|
||||
#include "QF/sys.h"
|
||||
#include "QF/va.h"
|
||||
|
||||
#include "qfcc.h"
|
||||
#include "class.h"
|
||||
#include "def.h"
|
||||
#include "defspace.h"
|
||||
#include "diagnostic.h"
|
||||
#include "emit.h"
|
||||
#include "expr.h"
|
||||
#include "function.h"
|
||||
#include "idstuff.h"
|
||||
#include "method.h"
|
||||
#include "options.h"
|
||||
#include "reloc.h"
|
||||
#include "shared.h"
|
||||
#include "strpool.h"
|
||||
#include "struct.h"
|
||||
#include "symtab.h"
|
||||
#include "type.h"
|
||||
#include "value.h"
|
||||
#include "qc-parse.h"
|
||||
|
||||
static expr_t *
|
||||
check_assign_logic_precedence (expr_t *dst, expr_t *src)
|
||||
{
|
||||
if (src->type == ex_expr && !src->paren && is_logic (src->e.expr.op)) {
|
||||
// traditional QuakeC gives = higher precedence than && and ||
|
||||
expr_t *assignment;
|
||||
notice (src, "precedence of `=' and `%s' inverted for "
|
||||
"traditional code", get_op_string (src->e.expr.op));
|
||||
// change {a = (b logic c)} to {(a = b) logic c}
|
||||
assignment = assign_expr (dst, src->e.expr.e1);
|
||||
assignment->paren = 1; // protect assignment from binary_expr
|
||||
return binary_expr (src->e.expr.op, assignment, src->e.expr.e2);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static expr_t *
|
||||
check_valid_lvalue (expr_t *expr)
|
||||
{
|
||||
switch (expr->type) {
|
||||
case ex_symbol:
|
||||
switch (expr->e.symbol->sy_type) {
|
||||
case sy_var:
|
||||
return 0;
|
||||
case sy_const:
|
||||
break;
|
||||
case sy_type:
|
||||
break;
|
||||
case sy_expr:
|
||||
break;
|
||||
case sy_func:
|
||||
break;
|
||||
case sy_class:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ex_temp:
|
||||
return 0;
|
||||
case ex_expr:
|
||||
if (expr->e.expr.op == '.') {
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case ex_uexpr:
|
||||
if (expr->e.expr.op == '.') {
|
||||
return 0;
|
||||
}
|
||||
if (expr->e.expr.op == 'A') {
|
||||
return check_valid_lvalue (expr->e.expr.e1);
|
||||
}
|
||||
break;
|
||||
case ex_state:
|
||||
case ex_bool:
|
||||
case ex_label:
|
||||
case ex_labelref:
|
||||
case ex_block:
|
||||
case ex_vector:
|
||||
case ex_nil:
|
||||
case ex_value:
|
||||
case ex_error:
|
||||
break;
|
||||
}
|
||||
if (options.traditional) {
|
||||
warning (expr, "invalid lvalue in assignment");
|
||||
return 0;
|
||||
}
|
||||
return error (expr, "invalid lvalue in assignment");
|
||||
}
|
||||
|
||||
static expr_t *
|
||||
check_types_compatible (expr_t *dst, expr_t *src)
|
||||
{
|
||||
type_t *dst_type = get_type (dst);
|
||||
type_t *src_type = get_type (src);
|
||||
|
||||
if (type_assignable (dst_type, src_type)) {
|
||||
return 0;
|
||||
}
|
||||
// traditional qcc is a little sloppy
|
||||
if (!options.traditional) {
|
||||
return type_mismatch (dst, src, '=');
|
||||
}
|
||||
if (is_func (dst_type) && is_func (src_type)) {
|
||||
warning (dst, "assignment between disparate function types");
|
||||
return 0;
|
||||
}
|
||||
if (is_float (dst_type) && is_vector (src_type)) {
|
||||
warning (dst, "assignment of vector to float");
|
||||
src = field_expr (src, new_name_expr ("x"));
|
||||
return assign_expr (dst, src);
|
||||
}
|
||||
if (is_vector (dst_type) && is_float (src_type)) {
|
||||
warning (dst, "assignment of float to vector");
|
||||
dst = field_expr (dst, new_name_expr ("x"));
|
||||
return assign_expr (dst, src);
|
||||
}
|
||||
return type_mismatch (dst, src, '=');
|
||||
}
|
||||
|
||||
static expr_t *
|
||||
assign_vector_expr (expr_t *dst, expr_t *src)
|
||||
{
|
||||
expr_t *dx, *sx;
|
||||
expr_t *dy, *sy;
|
||||
expr_t *dz, *sz;
|
||||
expr_t *dw, *sw;
|
||||
expr_t *ds, *ss;
|
||||
expr_t *dv, *sv;
|
||||
expr_t *block;
|
||||
|
||||
if (src->type == ex_vector) {
|
||||
src = convert_vector (src);
|
||||
if (src->type != ex_vector) {
|
||||
// src was constant and thus converted
|
||||
return assign_expr (dst, src);
|
||||
}
|
||||
}
|
||||
if (src->type == ex_vector && dst->type != ex_vector) {
|
||||
if (src->e.vector.type == &type_vector) {
|
||||
// guaranteed to have three elements
|
||||
sx = src->e.vector.list;
|
||||
sy = sx->next;
|
||||
sz = sy->next;
|
||||
dx = field_expr (dst, new_name_expr ("x"));
|
||||
dy = field_expr (dst, new_name_expr ("y"));
|
||||
dz = field_expr (dst, new_name_expr ("z"));
|
||||
block = new_block_expr ();
|
||||
append_expr (block, assign_expr (dx, sx));
|
||||
append_expr (block, assign_expr (dy, sy));
|
||||
append_expr (block, assign_expr (dz, sz));
|
||||
block->e.block.result = dst;
|
||||
return block;
|
||||
}
|
||||
if (src->e.vector.type == &type_quaternion) {
|
||||
// guaranteed to have two or four elements
|
||||
if (src->e.vector.list->next->next) {
|
||||
// four vals: x, y, z, w
|
||||
sx = src->e.vector.list;
|
||||
sy = sx->next;
|
||||
sz = sy->next;
|
||||
sw = sz->next;
|
||||
dx = field_expr (dst, new_name_expr ("x"));
|
||||
dy = field_expr (dst, new_name_expr ("y"));
|
||||
dz = field_expr (dst, new_name_expr ("z"));
|
||||
dw = field_expr (dst, new_name_expr ("w"));
|
||||
block = new_block_expr ();
|
||||
append_expr (block, assign_expr (dx, sx));
|
||||
append_expr (block, assign_expr (dy, sy));
|
||||
append_expr (block, assign_expr (dz, sz));
|
||||
append_expr (block, assign_expr (dw, sw));
|
||||
block->e.block.result = dst;
|
||||
return block;
|
||||
} else {
|
||||
// v, s
|
||||
sv = src->e.vector.list;
|
||||
ss = sv->next;
|
||||
dv = field_expr (dst, new_name_expr ("v"));
|
||||
ds = field_expr (dst, new_name_expr ("s"));
|
||||
block = new_block_expr ();
|
||||
append_expr (block, assign_expr (dv, sv));
|
||||
append_expr (block, assign_expr (ds, ss));
|
||||
block->e.block.result = dst;
|
||||
return block;
|
||||
}
|
||||
}
|
||||
internal_error (src, "bogus vector expression");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __attribute__((pure)) int
|
||||
is_const_ptr (expr_t *e)
|
||||
{
|
||||
if ((e->type != ex_value || e->e.value->lltype != ev_pointer)
|
||||
|| !(POINTER_VAL (e->e.value->v.pointer) > 0
|
||||
&& POINTER_VAL (e->e.value->v.pointer) < 65536)) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __attribute__((pure)) int
|
||||
is_indirect (expr_t *e)
|
||||
{
|
||||
if (e->type == ex_block && e->e.block.result)
|
||||
return is_indirect (e->e.block.result);
|
||||
if (e->type == ex_expr && e->e.expr.op == '.')
|
||||
return 1;
|
||||
if (!(e->type == ex_uexpr && e->e.expr.op == '.'))
|
||||
return 0;
|
||||
return is_const_ptr (e->e.expr.e1);
|
||||
}
|
||||
|
||||
expr_t *
|
||||
aassign_expr (expr_t *dst, expr_t *src);
|
||||
expr_t *
|
||||
assign_expr (expr_t *dst, expr_t *src)
|
||||
{
|
||||
int op = '=';
|
||||
expr_t *expr;
|
||||
type_t *dst_type, *src_type;
|
||||
|
||||
convert_name (dst);
|
||||
convert_name (src);
|
||||
|
||||
if (dst->type == ex_error) {
|
||||
return dst;
|
||||
}
|
||||
if (src->type == ex_error) {
|
||||
return src;
|
||||
}
|
||||
|
||||
if (options.traditional
|
||||
&& (expr = check_assign_logic_precedence (dst, src))) {
|
||||
return expr;
|
||||
}
|
||||
|
||||
dst = fold_constants (dst);
|
||||
src = fold_constants (src);
|
||||
|
||||
if ((expr = check_valid_lvalue (dst))) {
|
||||
return expr;
|
||||
}
|
||||
|
||||
dst_type = get_type (dst);
|
||||
src_type = get_type (src);
|
||||
if (!dst_type) {
|
||||
internal_error (dst, "dst_type broke in assign_expr");
|
||||
}
|
||||
if (!src_type) {
|
||||
internal_error (src, "src_type broke in assign_expr");
|
||||
}
|
||||
|
||||
if (is_pointer (dst_type) && is_array (src_type)) {
|
||||
// assigning an array to a pointer is the same as taking the address of
|
||||
// the array but using the type of the array elements
|
||||
src = address_expr (src, 0, src_type->t.fldptr.type);
|
||||
src_type = get_type (src);
|
||||
}
|
||||
if (src->type == ex_bool) {
|
||||
src = convert_from_bool (src, dst_type);
|
||||
if (src->type == ex_error) {
|
||||
return src;
|
||||
}
|
||||
src_type = get_type (src);
|
||||
}
|
||||
if (!is_void (dst_type) && src->type == ex_nil) {
|
||||
// nil is a type-agnostic 0
|
||||
// FIXME: assignment to compound types? error or memset?
|
||||
src_type = dst_type;
|
||||
convert_nil (src, src_type);
|
||||
}
|
||||
|
||||
if ((expr = check_types_compatible (dst, src))) {
|
||||
// expr might be a valid expression, but if so, check_types_compatible
|
||||
// will take care of everything
|
||||
return expr;
|
||||
}
|
||||
|
||||
if ((expr = assign_vector_expr (dst, src))) {
|
||||
return expr;
|
||||
}
|
||||
|
||||
if (is_indirect (dst) && is_indirect (src)) {
|
||||
debug (dst, "here");
|
||||
if (is_struct (src_type)) {
|
||||
dst = address_expr (dst, 0, 0);
|
||||
src = address_expr (src, 0, 0);
|
||||
expr = new_move_expr (dst, src, src_type, 1);
|
||||
} else {
|
||||
expr_t *temp = new_temp_def_expr (dst_type);
|
||||
|
||||
expr = new_block_expr ();
|
||||
append_expr (expr, assign_expr (temp, src));
|
||||
append_expr (expr, assign_expr (dst, temp));
|
||||
expr->e.block.result = temp;
|
||||
}
|
||||
return expr;
|
||||
} else if (is_indirect (dst)) {
|
||||
debug (dst, "here");
|
||||
if (is_struct (dst_type)) {
|
||||
dst = address_expr (dst, 0, 0);
|
||||
src = address_expr (src, 0, 0);
|
||||
return new_move_expr (dst, src, dst_type, 1);
|
||||
}
|
||||
if (dst->type == ex_expr) {
|
||||
if (get_type (dst->e.expr.e1) == &type_entity) {
|
||||
dst_type = dst->e.expr.type;
|
||||
dst->e.expr.type = pointer_type (dst_type);
|
||||
dst->e.expr.op = '&';
|
||||
}
|
||||
op = PAS;
|
||||
} else {
|
||||
if (is_const_ptr (dst->e.expr.e1)) {
|
||||
dst = dst->e.expr.e1;
|
||||
op = PAS;
|
||||
}
|
||||
}
|
||||
} else if (is_indirect (src)) {
|
||||
debug (dst, "here");
|
||||
if (is_struct (dst_type)) {
|
||||
dst = address_expr (dst, 0, 0);
|
||||
src = address_expr (src, 0, 0);
|
||||
src->rvalue = 1;
|
||||
return new_move_expr (dst, src, src_type, 1);
|
||||
}
|
||||
if (src->type == ex_uexpr) {
|
||||
expr = src->e.expr.e1;
|
||||
if (is_const_ptr (expr)) {
|
||||
if (expr->type == ex_expr && expr->e.expr.op == '&'
|
||||
&& expr->e.expr.type->type == ev_pointer
|
||||
&& !is_constant (expr)) {
|
||||
src = expr;
|
||||
src->e.expr.op = '.';
|
||||
src->e.expr.type = src_type;
|
||||
src->rvalue = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (is_struct (dst_type)) {
|
||||
return new_move_expr (dst, src, dst_type, 0);
|
||||
}
|
||||
|
||||
expr = new_binary_expr (op, dst, src);
|
||||
expr->e.expr.type = dst_type;
|
||||
return expr;
|
||||
}
|
|
@ -830,7 +830,7 @@ flow_analyze_statement (statement_t *s, set_t *use, set_t *def, set_t *kill,
|
|||
} else if (!strcmp (s->opcode, "<MOVEP>")) {
|
||||
flow_add_op_var (use, s->opc);
|
||||
if (s->opc->op_type == op_value
|
||||
&& s->opc->o.value->type == ev_pointer
|
||||
&& s->opc->o.value->lltype == ev_pointer
|
||||
&& s->opc->o.value->v.pointer.def) {
|
||||
operand_t *op;
|
||||
ex_pointer_t *ptr = &s->opc->o.value->v.pointer;
|
||||
|
|
|
@ -428,8 +428,10 @@ qfo_write (qfo_t *qfo, const char *filename)
|
|||
QFile *file;
|
||||
|
||||
file = Qopen (filename, options.gzip ? "wbz9" : "wb");
|
||||
if (!file)
|
||||
if (!file) {
|
||||
perror (va ("failed to open %s for writing", filename));
|
||||
return -1;
|
||||
}
|
||||
|
||||
size = sizeof (qfo_header_t);
|
||||
size += sizeof (qfo_space_t) * qfo->num_spaces;
|
||||
|
|
|
@ -396,9 +396,12 @@ compile_to_obj (const char *file, const char *obj, lang_t lang)
|
|||
qfo_t *qfo;
|
||||
|
||||
class_finish_module ();
|
||||
qfo = qfo_from_progs (&pr);
|
||||
err = qfo_write (qfo, obj);
|
||||
qfo_delete (qfo);
|
||||
err = pr.error_count;
|
||||
if (!err) {
|
||||
qfo = qfo_from_progs (&pr);
|
||||
err = qfo_write (qfo, obj);
|
||||
qfo_delete (qfo);
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
|
|
@ -83,7 +83,7 @@ operand_string (operand_t *op)
|
|||
case op_def:
|
||||
return op->o.def->name;
|
||||
case op_value:
|
||||
switch (op->o.value->type) {
|
||||
switch (op->o.value->lltype) {
|
||||
case ev_string:
|
||||
return va ("\"%s\"",
|
||||
quote_string (op->o.value->v.string_val));
|
||||
|
@ -154,7 +154,7 @@ print_operand (operand_t *op)
|
|||
break;
|
||||
case op_value:
|
||||
printf ("(%s) ", pr_type_name[op->type]);
|
||||
switch (op->o.value->type) {
|
||||
switch (op->o.value->lltype) {
|
||||
case ev_string:
|
||||
printf ("\"%s\"", op->o.value->v.string_val);
|
||||
break;
|
||||
|
@ -316,7 +316,7 @@ value_operand (ex_value_t *value)
|
|||
{
|
||||
operand_t *op;
|
||||
op = new_operand (op_value);
|
||||
op->type = value->type;
|
||||
op->type = value->lltype;
|
||||
op->o.value = value;
|
||||
return op;
|
||||
}
|
||||
|
@ -337,8 +337,11 @@ alias_operand (etype_t type, operand_t *op)
|
|||
{
|
||||
operand_t *aop;
|
||||
|
||||
if (pr_type_size[type] != pr_type_size[op->type])
|
||||
internal_error (0, "aliasing operand with type of diffent size");
|
||||
if (pr_type_size[type] != pr_type_size[op->type]) {
|
||||
internal_error (0, "\naliasing operand with type of diffent size"
|
||||
" (%d, %d)", pr_type_size[type],
|
||||
pr_type_size[op->type]);
|
||||
}
|
||||
aop = new_operand (op_alias);
|
||||
aop->o.alias = op;
|
||||
aop->type = type;
|
||||
|
@ -659,7 +662,7 @@ expr_call (sblock_t *sblock, expr_t *call, operand_t **op)
|
|||
pref = "R";
|
||||
sblock = statement_subexpr (sblock, param, &arguments[ind]);
|
||||
if (options.code.vector_calls && a->type == ex_value
|
||||
&& a->e.value->type == ev_vector)
|
||||
&& a->e.value->lltype == ev_vector)
|
||||
sblock = vector_call (sblock, a, param, ind, &arguments[ind]);
|
||||
else
|
||||
sblock = statement_subexpr (sblock, a, &arguments[ind]);
|
||||
|
@ -673,7 +676,7 @@ expr_call (sblock_t *sblock, expr_t *call, operand_t **op)
|
|||
sblock = statement_slist (sblock, mov);
|
||||
} else {
|
||||
if (options.code.vector_calls && a->type == ex_value
|
||||
&& a->e.value->type == ev_vector) {
|
||||
&& a->e.value->lltype == ev_vector) {
|
||||
sblock = vector_call (sblock, a, param, ind, 0);
|
||||
} else {
|
||||
operand_t *p = 0;
|
||||
|
@ -774,7 +777,7 @@ expr_deref (sblock_t *sblock, expr_t *deref, operand_t **op)
|
|||
s->opc = *op;
|
||||
sblock_add_statement (sblock, s);
|
||||
}
|
||||
} else if (e->type == ex_value && e->e.value->type == ev_pointer) {
|
||||
} else if (e->type == ex_value && e->e.value->lltype == ev_pointer) {
|
||||
ex_pointer_t *ptr = &e->e.value->v.pointer;
|
||||
*op = def_operand (alias_def (ptr->def, ptr->type, ptr->val),
|
||||
ptr->type);
|
||||
|
@ -1017,7 +1020,7 @@ statement_subexpr (sblock_t *sblock, expr_t *e, operand_t **op)
|
|||
if (e->type > ex_value)
|
||||
internal_error (e, "bad expression type");
|
||||
if (!sfuncs[e->type])
|
||||
internal_error (e, "unexpected expression type; %s",
|
||||
internal_error (e, "unexpected expression type: %s",
|
||||
expr_names[e->type]);
|
||||
|
||||
sblock = sfuncs[e->type] (sblock, e, op);
|
||||
|
|
|
@ -82,7 +82,7 @@ get_hash (const void *_cl, void *unused)
|
|||
if (!cl->value)
|
||||
return 0;
|
||||
val = get_value (cl->value);
|
||||
return Hash_Buffer (&val->v, sizeof (val->v)) + val->type;
|
||||
return Hash_Buffer (&val->v, sizeof (val->v)) + val->lltype;
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
|
@ -681,6 +681,18 @@ is_scalar (const type_t *type)
|
|||
return is_float (type) || is_integral (type);
|
||||
}
|
||||
|
||||
int
|
||||
is_vector (const type_t *type)
|
||||
{
|
||||
return type->type == ev_vector;
|
||||
}
|
||||
|
||||
int
|
||||
is_quaternion (const type_t *type)
|
||||
{
|
||||
return type->type == ev_quat;
|
||||
}
|
||||
|
||||
int
|
||||
is_math (const type_t *type)
|
||||
{
|
||||
|
@ -714,6 +726,14 @@ is_array (const type_t *type)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
is_func (const type_t *type)
|
||||
{
|
||||
if (type->type == ev_func)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
type_assignable (const type_t *dst, const type_t *src)
|
||||
{
|
||||
|
|
|
@ -79,7 +79,7 @@ static uintptr_t
|
|||
value_get_hash (const void *_val, void *unused)
|
||||
{
|
||||
const ex_value_t *val = (const ex_value_t *) _val;
|
||||
return Hash_Buffer (&val->v, sizeof (val->v)) + val->type;
|
||||
return Hash_Buffer (&val->v, sizeof (val->v)) + val->lltype;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -87,7 +87,7 @@ value_compare (const void *_val1, const void *_val2, void *unused)
|
|||
{
|
||||
const ex_value_t *val1 = (const ex_value_t *) _val1;
|
||||
const ex_value_t *val2 = (const ex_value_t *) _val2;
|
||||
if (val1->type != val2->type)
|
||||
if (val1->lltype != val2->lltype)
|
||||
return 0;
|
||||
return memcmp (&val1->v, &val2->v, sizeof (val1->v)) == 0;
|
||||
}
|
||||
|
@ -100,6 +100,13 @@ new_value (void)
|
|||
return value;
|
||||
}
|
||||
|
||||
static void
|
||||
set_val_type (ex_value_t *val, type_t *type)
|
||||
{
|
||||
val->type = type;
|
||||
val->lltype = low_level_type (type);
|
||||
}
|
||||
|
||||
static ex_value_t *
|
||||
find_value (const ex_value_t *val)
|
||||
{
|
||||
|
@ -119,7 +126,7 @@ new_string_val (const char *string_val)
|
|||
{
|
||||
ex_value_t val;
|
||||
memset (&val, 0, sizeof (val));
|
||||
val.type = ev_string;
|
||||
set_val_type (&val, &type_string);
|
||||
if (string_val)
|
||||
val.v.string_val = save_string (string_val);
|
||||
return find_value (&val);
|
||||
|
@ -130,7 +137,7 @@ new_float_val (float float_val)
|
|||
{
|
||||
ex_value_t val;
|
||||
memset (&val, 0, sizeof (val));
|
||||
val.type = ev_float;
|
||||
set_val_type (&val, &type_float);
|
||||
val.v.float_val = float_val;
|
||||
return find_value (&val);
|
||||
}
|
||||
|
@ -140,7 +147,7 @@ new_vector_val (const float *vector_val)
|
|||
{
|
||||
ex_value_t val;
|
||||
memset (&val, 0, sizeof (val));
|
||||
val.type = ev_vector;
|
||||
set_val_type (&val, &type_vector);
|
||||
VectorCopy (vector_val, val.v.vector_val);
|
||||
return find_value (&val);
|
||||
}
|
||||
|
@ -150,7 +157,7 @@ new_entity_val (int entity_val)
|
|||
{
|
||||
ex_value_t val;
|
||||
memset (&val, 0, sizeof (val));
|
||||
val.type = ev_entity;
|
||||
set_val_type (&val, &type_entity);
|
||||
val.v.entity_val = entity_val;
|
||||
return find_value (&val);
|
||||
}
|
||||
|
@ -160,7 +167,7 @@ new_field_val (int field_val, type_t *type, def_t *def)
|
|||
{
|
||||
ex_value_t val;
|
||||
memset (&val, 0, sizeof (val));
|
||||
val.type = ev_field;
|
||||
set_val_type (&val, field_type (type));
|
||||
val.v.pointer.val = field_val;
|
||||
val.v.pointer.type = type;
|
||||
val.v.pointer.def = def;
|
||||
|
@ -172,7 +179,7 @@ new_func_val (int func_val, type_t *type)
|
|||
{
|
||||
ex_value_t val;
|
||||
memset (&val, 0, sizeof (val));
|
||||
val.type = ev_func;
|
||||
set_val_type (&val, type);
|
||||
val.v.func_val.val = func_val;
|
||||
val.v.func_val.type = type;
|
||||
return find_value (&val);
|
||||
|
@ -183,7 +190,7 @@ new_pointer_val (int pointer_val, type_t *type, def_t *def)
|
|||
{
|
||||
ex_value_t val;
|
||||
memset (&val, 0, sizeof (val));
|
||||
val.type = ev_pointer;
|
||||
set_val_type (&val, pointer_type (type));
|
||||
val.v.pointer.val = pointer_val;
|
||||
val.v.pointer.type = type;
|
||||
val.v.pointer.def = def;
|
||||
|
@ -195,7 +202,7 @@ new_quaternion_val (const float *quaternion_val)
|
|||
{
|
||||
ex_value_t val;
|
||||
memset (&val, 0, sizeof (val));
|
||||
val.type = ev_quat;
|
||||
set_val_type (&val, &type_quaternion);
|
||||
QuatCopy (quaternion_val, val.v.quaternion_val);
|
||||
return find_value (&val);
|
||||
}
|
||||
|
@ -205,7 +212,7 @@ new_integer_val (int integer_val)
|
|||
{
|
||||
ex_value_t val;
|
||||
memset (&val, 0, sizeof (val));
|
||||
val.type = ev_integer;
|
||||
set_val_type (&val, &type_integer);
|
||||
val.v.integer_val = integer_val;
|
||||
return find_value (&val);
|
||||
}
|
||||
|
@ -215,7 +222,7 @@ new_uinteger_val (int uinteger_val)
|
|||
{
|
||||
ex_value_t val;
|
||||
memset (&val, 0, sizeof (val));
|
||||
val.type = ev_uinteger;
|
||||
set_val_type (&val, &type_uinteger);
|
||||
val.v.uinteger_val = uinteger_val;
|
||||
return find_value (&val);
|
||||
}
|
||||
|
@ -225,7 +232,7 @@ new_short_val (short short_val)
|
|||
{
|
||||
ex_value_t val;
|
||||
memset (&val, 0, sizeof (val));
|
||||
val.type = ev_short;
|
||||
set_val_type (&val, &type_short);
|
||||
val.v.short_val = short_val;
|
||||
return find_value (&val);
|
||||
}
|
||||
|
@ -235,10 +242,13 @@ new_nil_val (type_t *type)
|
|||
{
|
||||
ex_value_t val;
|
||||
memset (&val, 0, sizeof (val));
|
||||
val.type = low_level_type (type);
|
||||
if (val.type == ev_pointer|| val.type == ev_field )
|
||||
set_val_type (&val, type);
|
||||
if (val.lltype == ev_void) {
|
||||
val.lltype = type_nil->type;
|
||||
}
|
||||
if (val.lltype == ev_pointer || val.lltype == ev_field )
|
||||
val.v.pointer.type = type->t.fldptr.type;
|
||||
if (val.type == ev_func)
|
||||
if (val.lltype == ev_func)
|
||||
val.v.func_val.type = type;
|
||||
return find_value (&val);
|
||||
}
|
||||
|
@ -333,13 +343,13 @@ ReuseString (const char *str)
|
|||
static float
|
||||
value_as_float (ex_value_t *value)
|
||||
{
|
||||
if (value->type == ev_uinteger)
|
||||
if (value->lltype == ev_uinteger)
|
||||
return value->v.uinteger_val;
|
||||
if (value->type == ev_integer)
|
||||
if (value->lltype == ev_integer)
|
||||
return value->v.integer_val;
|
||||
if (value->type == ev_short)
|
||||
if (value->lltype == ev_short)
|
||||
return value->v.short_val;
|
||||
if (value->type == ev_float)
|
||||
if (value->lltype == ev_float)
|
||||
return value->v.float_val;
|
||||
return 0;
|
||||
}
|
||||
|
@ -347,13 +357,13 @@ value_as_float (ex_value_t *value)
|
|||
static int
|
||||
value_as_int (ex_value_t *value)
|
||||
{
|
||||
if (value->type == ev_uinteger)
|
||||
if (value->lltype == ev_uinteger)
|
||||
return value->v.uinteger_val;
|
||||
if (value->type == ev_integer)
|
||||
if (value->lltype == ev_integer)
|
||||
return value->v.integer_val;
|
||||
if (value->type == ev_short)
|
||||
if (value->lltype == ev_short)
|
||||
return value->v.short_val;
|
||||
if (value->type == ev_float)
|
||||
if (value->lltype == ev_float)
|
||||
return value->v.float_val;
|
||||
return 0;
|
||||
}
|
||||
|
@ -361,13 +371,13 @@ value_as_int (ex_value_t *value)
|
|||
static unsigned
|
||||
value_as_uint (ex_value_t *value)
|
||||
{
|
||||
if (value->type == ev_uinteger)
|
||||
if (value->lltype == ev_uinteger)
|
||||
return value->v.uinteger_val;
|
||||
if (value->type == ev_integer)
|
||||
if (value->lltype == ev_integer)
|
||||
return value->v.integer_val;
|
||||
if (value->type == ev_short)
|
||||
if (value->lltype == ev_short)
|
||||
return value->v.short_val;
|
||||
if (value->type == ev_float)
|
||||
if (value->lltype == ev_float)
|
||||
return value->v.float_val;
|
||||
return 0;
|
||||
}
|
||||
|
@ -375,7 +385,7 @@ value_as_uint (ex_value_t *value)
|
|||
ex_value_t *
|
||||
convert_value (ex_value_t *value, type_t *type)
|
||||
{
|
||||
if (!is_scalar (type) || !is_scalar (ev_types[value->type])) {
|
||||
if (!is_scalar (type) || !is_scalar (ev_types[value->lltype])) {
|
||||
error (0, "unable to convert non-scalar value");
|
||||
return value;
|
||||
}
|
||||
|
@ -400,12 +410,12 @@ alias_value (ex_value_t *value, type_t *type)
|
|||
{
|
||||
ex_value_t new;
|
||||
|
||||
if (type_size (type) != type_size (ev_types[value->type])) {
|
||||
if (type_size (type) != type_size (ev_types[value->lltype])) {
|
||||
error (0, "unable to alias different sized values");
|
||||
return value;
|
||||
}
|
||||
new = *value;
|
||||
new.type = type->type;
|
||||
set_val_type (&new, type);
|
||||
return find_value (&new);
|
||||
}
|
||||
|
||||
|
@ -436,9 +446,9 @@ emit_value (ex_value_t *value, def_t *def)
|
|||
clear_immediates ();
|
||||
}
|
||||
cn = 0;
|
||||
if (val.type == ev_void)
|
||||
val.type = type_nil->type;
|
||||
switch (val.type) {
|
||||
// if (val.type == ev_void)
|
||||
// val.type = type_nil->type;
|
||||
switch (val.lltype) {
|
||||
case ev_entity:
|
||||
tab = entity_imm_defs;
|
||||
type = &type_entity;
|
||||
|
@ -463,7 +473,7 @@ emit_value (ex_value_t *value, def_t *def)
|
|||
break;
|
||||
}
|
||||
val.v.float_val = val.v.integer_val;
|
||||
val.type = ev_float;
|
||||
val.lltype = ev_float;
|
||||
case ev_float:
|
||||
tab = float_imm_defs;
|
||||
type = &type_float;
|
||||
|
@ -528,7 +538,7 @@ emit_value (ex_value_t *value, def_t *def)
|
|||
cn->initialized = cn->constant = 1;
|
||||
cn->nosave = 1;
|
||||
// copy the immediate to the global area
|
||||
switch (val.type) {
|
||||
switch (val.lltype) {
|
||||
case ev_string:
|
||||
reloc_def_string (cn);
|
||||
break;
|
||||
|
|
|
@ -43,7 +43,7 @@ test_format ()
|
|||
printf ("q = [[5, 6, 7], 8] -> %v, %g\n", q.v, q.s);
|
||||
fail = 1;
|
||||
}
|
||||
/* q = [s, v];
|
||||
q = [s, v];
|
||||
if (q.x != v.x || q.y != v.y || q.z != v.z || q.w != s) {
|
||||
printf ("q = [s, v] -> %q (%v)\n", q, v);
|
||||
fail = 1;
|
||||
|
@ -60,7 +60,7 @@ test_format ()
|
|||
if (q.v != v || q.s != s) {
|
||||
printf ("q = [v, s] -> %v, %g (%v %s)\n", q.v, q.s, v, s);
|
||||
fail = 1;
|
||||
}*/
|
||||
}
|
||||
return fail;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue