Add support for actual vector expressions.

Currently, they can represent either vectors or quaternions, and the
quaternions can be in either [s, v] form or [w, x, y, z] form.

Many things will not actual work yet as the vector expression needs to be
converted into the appropriate form for assigning the elements to the
components of the "vector" type.
This commit is contained in:
Bill Currie 2013-06-24 15:37:08 +09:00
parent 2572811bf4
commit 7a7a685105
5 changed files with 77 additions and 1 deletions

View File

@ -51,6 +51,7 @@ typedef enum {
ex_uexpr, ///< unary expression (::ex_expr_t)
ex_symbol, ///< non-temporary variable (::symbol_t)
ex_temp, ///< temporary variable (::ex_temp_t)
ex_vector, ///< "vector" expression (::ex_vector_t)
ex_nil, ///< umm, nil, null. nuff said (0 of any type)
ex_value, ///< constant value (::ex_value_t)
@ -96,6 +97,11 @@ typedef struct {
struct type_s *type; ///< The type of the temporary variable.
} ex_temp_t;
typedef struct {
struct type_s *type; ///< Type of vector (vector/quaternion)
struct expr_s *list; ///< Linked list of element expressions.
} ex_vector_t;
/** Pointer constant expression.
Represent a pointer to an absolute address in data space.
@ -199,6 +205,7 @@ typedef struct expr_s {
ex_expr_t expr; ///< binary or unary expression
struct symbol_s *symbol; ///< symbol reference expression
ex_temp_t temp; ///< temporary variable expression
ex_vector_t vector; ///< vector expression list
ex_value_t *value; ///< constant value
} e;
} expr_t;
@ -396,6 +403,7 @@ float expr_float (expr_t *e);
*/
expr_t *new_vector_expr (const float *vector_val);
const float *expr_vector (expr_t *e);
expr_t *new_vector_list (expr_t *e);
/** Create a new entity constant expression node.

View File

@ -361,6 +361,14 @@ print_temp (dstring_t *dstr, expr_t *e, int level, int id, expr_t *next)
e->line);
}
static void
print_vector (dstring_t *dstr, expr_t *e, int level, int id, expr_t *next)
{
int indent = level * 2 + 2;
dasprintf (dstr, "%*se_%p [label=\"vector FIXME\"];\n", indent, "", e);
}
static void
print_nil (dstring_t *dstr, expr_t *e, int level, int id, expr_t *next)
{
@ -455,6 +463,7 @@ _print_expr (dstring_t *dstr, expr_t *e, int level, int id, expr_t *next)
print_uexpr,
print_symbol,
print_temp,
print_vector,
print_nil,
print_value,
};

View File

@ -178,6 +178,8 @@ get_type (expr_t *e)
convert_int (e);
}
return ev_types[e->e.value->type];
case ex_vector:
return e->e.vector.type;
}
return 0;
}
@ -355,6 +357,18 @@ copy_expr (expr_t *e)
n->file = pr.source_file;
n->e.temp.expr = copy_expr (e->e.temp.expr);
return n;
case ex_vector:
n = new_expr ();
n->e.vector.type = e->e.vector.type;
n->e.vector.list = copy_expr (e->e.vector.list);
n = n->e.vector.list;
t = e->e.vector.list;
while (t->next) {
n->next = copy_expr (t->next);
n = n->next;
t = t->next;
}
return n;
}
internal_error (e, "invalid expression");
}
@ -546,6 +560,46 @@ new_vector_expr (const float *vector_val)
return e;
}
expr_t *
new_vector_list (expr_t *e)
{
expr_t *t;
int count;
type_t *type = &type_vector;
expr_t *vec;
e = reverse_expr_list (e); // put the elements in the right order
for (t = e, count = 0; t; t = t->next)
count++;
switch (count) {
case 4:
type = &type_quaternion;
case 3:
// quaternion or vector. all expressions must be compatible with
// a float
for (t = e; t; t = t->next)
if (!type_assignable (&type_float, get_type (t)))
return error (t, "invalid type for vector element");
vec = new_expr ();
vec->type = ex_vector;
vec->e.vector.type = type;
vec->e.vector.list = e;
break;
case 2:
// quaternion. first expression must be compatible with a float,
// the other must be a vector
if (!type_assignable (&type_float, get_type (e))
|| type_assignable (&type_vector, get_type(e->next))) {
return error (t, "invalid types for vector elements");
}
// s, v
break;
default:
return error (e, "invalid number of elements in vector exprssion");
}
return vec;
}
expr_t *
new_entity_expr (int entity_val)
{
@ -1669,6 +1723,7 @@ unary_expr (int op, expr_t *e)
case ex_expr:
case ex_bool:
case ex_temp:
case ex_vector:
{
expr_t *n = new_unary_expr (op, e);
@ -1733,6 +1788,7 @@ unary_expr (int op, expr_t *e)
case ex_expr:
case ex_symbol:
case ex_temp:
case ex_vector:
{
expr_t *n = new_unary_expr (op, e);
@ -1793,6 +1849,7 @@ unary_expr (int op, expr_t *e)
case ex_bool:
case ex_symbol:
case ex_temp:
case ex_vector:
bitnot_expr:
if (options.code.progsversion == PROG_ID_VERSION) {
expr_t *n1 = new_integer_expr (-1);

View File

@ -1245,7 +1245,7 @@ unary_expr
{
$$ = sizeof_expr (0, $3->type);
}
| vector_expr { $$ = $1; }
| vector_expr { $$ = new_vector_list ($1); }
| obj_expr { $$ = $1; }
;

View File

@ -1005,6 +1005,7 @@ statement_subexpr (sblock_t *sblock, expr_t *e, operand_t **op)
expr_uexpr,
expr_symbol,
expr_temp,
0, // ex_vector
0, // ex_nil
expr_value,
};
@ -1287,6 +1288,7 @@ statement_slist (sblock_t *sblock, expr_t *e)
statement_uexpr,
statement_nonexec, // ex_symbol
statement_nonexec, // ex_temp
statement_nonexec, // ex_vector
statement_nonexec, // ex_nil
statement_nonexec, // ex_value
};