Merge branch 'master' into wip-trails

This commit is contained in:
Bill Currie 2023-10-03 14:11:22 +09:00
commit 1c6986f0ab
24 changed files with 195 additions and 91 deletions

View file

@ -109,6 +109,7 @@ static struct DARRAY_TYPE(t *) n##_blocks = DARRAY_STATIC_INIT(8)
#define ALLOC_STATE(t,n) \ #define ALLOC_STATE(t,n) \
static t *n##_freelist; static t *n##_freelist;
#define ALLOC_FREE_BLOCKS(n)
#define FREE(n, p) do { free (p); } while (0) #define FREE(n, p) do { free (p); } while (0)
#endif #endif

View file

@ -50,6 +50,8 @@ typedef enum {
ty_alias, ty_alias,
ty_handle, ty_handle,
ty_algebra, ty_algebra,
ty_meta_count
} ty_meta_e; } ty_meta_e;
typedef struct qfot_alias_s { typedef struct qfot_alias_s {

View file

@ -262,6 +262,8 @@ pr_debug_type_size (const progs_t *pr, const qfot_type_t *type)
return pr_debug_type_size (pr, aux_type); return pr_debug_type_size (pr, aux_type);
case ty_algebra: case ty_algebra:
return 1; //FIXME wip return 1; //FIXME wip
case ty_meta_count:
break;
} }
return 0; return 0;
} }
@ -1094,6 +1096,8 @@ value_string (pr_debug_data_t *data, qfot_type_t *type, pr_type_t *value)
type = &G_STRUCT (data->pr, qfot_type_t, type->alias.aux_type); type = &G_STRUCT (data->pr, qfot_type_t, type->alias.aux_type);
value_string (data, type, value); value_string (data, type, value);
break; break;
case ty_meta_count:
break;
} }
} }

View file

@ -14,11 +14,11 @@ typedef struct light_s {
} light_t; } light_t;
//FIXME need a handle type //FIXME need a handle type
typedef struct { long handle; } scene_t; typedef @handle(long) scene_h scene_t;
typedef struct { long handle; } entity_t; typedef @handle(long) entity_h entity_t;
typedef struct { long handle; } transform_t; typedef @handle(long) transform_h transform_t;
typedef struct { long handle; } lightingdata_t; typedef @handle(long) lightingdata_h lightingdata_t;
typedef struct { int handle; } model_t; typedef @handle(int) model_h model_t;
scene_t Scene_NewScene (void); scene_t Scene_NewScene (void);
void Scene_DeleteScene (scene_t scene); void Scene_DeleteScene (scene_t scene);

View file

@ -31,6 +31,8 @@
#ifndef __diagnostic_h #ifndef __diagnostic_h
#define __diagnostic_h #define __diagnostic_h
typedef struct expr_s expr_t;
/** \defgroup qfcc_diagnostic Diagnostic Messages /** \defgroup qfcc_diagnostic Diagnostic Messages
\ingroup qfcc \ingroup qfcc
*/ */
@ -42,37 +44,37 @@ extern diagnostic_hook error_hook;
extern diagnostic_hook warning_hook; extern diagnostic_hook warning_hook;
extern diagnostic_hook notice_hook; extern diagnostic_hook notice_hook;
struct expr_s *_error (const struct expr_s *e, const char *file, const expr_t *_error (const expr_t *e, const char *file,
int line, const char *func, const char *fmt, ...) int line, const char *func, const char *fmt, ...)
__attribute__ ((format (PRINTF, 5, 6))); __attribute__ ((format (PRINTF, 5, 6)));
#define error(e, fmt...) _error(e, __FILE__, __LINE__, __FUNCTION__, fmt) #define error(e, fmt...) _error(e, __FILE__, __LINE__, __FUNCTION__, fmt)
void _internal_error (const struct expr_s *e, const char *file, int line, void _internal_error (const expr_t *e, const char *file, int line,
const char *func, const char *fmt, ...) const char *func, const char *fmt, ...)
__attribute__ ((format (PRINTF, 5, 6), noreturn)); __attribute__ ((format (PRINTF, 5, 6), noreturn));
#define internal_error(e, fmt...) _internal_error(e, __FILE__, __LINE__, __FUNCTION__, fmt) #define internal_error(e, fmt...) _internal_error(e, __FILE__, __LINE__, __FUNCTION__, fmt)
struct expr_s *_warning (const struct expr_s *e, const char *file, const expr_t *_warning (const expr_t *e, const char *file,
int line, const char *func, const char *fmt, ...) int line, const char *func, const char *fmt, ...)
__attribute__ ((format (PRINTF, 5, 6))); __attribute__ ((format (PRINTF, 5, 6)));
#define warning(e, fmt...) _warning(e, __FILE__, __LINE__, __FUNCTION__, fmt) #define warning(e, fmt...) _warning(e, __FILE__, __LINE__, __FUNCTION__, fmt)
struct expr_s *_notice (const struct expr_s *e, const char *file, const expr_t *_notice (const expr_t *e, const char *file,
int line, const char *func, const char *fmt, ...) int line, const char *func, const char *fmt, ...)
__attribute__ ((format (PRINTF, 5, 6))); __attribute__ ((format (PRINTF, 5, 6)));
#define notice(e, fmt...) _notice(e, __FILE__, __LINE__, __FUNCTION__, fmt) #define notice(e, fmt...) _notice(e, __FILE__, __LINE__, __FUNCTION__, fmt)
void _debug (const struct expr_s *e, const char *file, int line, void _debug (const expr_t *e, const char *file, int line,
const char *func, const char *fmt, ...) const char *func, const char *fmt, ...)
__attribute__ ((format (PRINTF, 5, 6))); __attribute__ ((format (PRINTF, 5, 6)));
#define debug(e, fmt...) _debug(e, __FILE__, __LINE__, __FUNCTION__, fmt) #define debug(e, fmt...) _debug(e, __FILE__, __LINE__, __FUNCTION__, fmt)
void _bug (const struct expr_s *e, const char *file, int line, void _bug (const expr_t *e, const char *file, int line,
const char * func, const char *fmt, ...) const char * func, const char *fmt, ...)
__attribute__ ((format (PRINTF, 5, 6))); __attribute__ ((format (PRINTF, 5, 6)));
#define bug(e, fmt...) _bug(e, __FILE__, __LINE__, __FUNCTION__, fmt) #define bug(e, fmt...) _bug(e, __FILE__, __LINE__, __FUNCTION__, fmt)
void print_srcline (int rep, const struct expr_s *e); void print_srcline (int rep, const expr_t *e);
///@} ///@}

View file

@ -129,7 +129,7 @@ typedef struct {
typedef struct { typedef struct {
type_t *type; ///< Type of vector (vector/quaternion) type_t *type; ///< Type of vector (vector/quaternion)
const expr_t *list; ///< Linked list of element expressions. ex_list_t list; ///< Linked list of element expressions.
} ex_vector_t; } ex_vector_t;
typedef struct { typedef struct {
@ -360,11 +360,11 @@ extern const char *expr_names[];
\param op The opcode of the expression. \param op The opcode of the expression.
\return \a e1 with its type set to ex_error. \return \a e1 with its type set to ex_error.
*/ */
expr_t *type_mismatch (const expr_t *e1, const expr_t *e2, int op); const expr_t *type_mismatch (const expr_t *e1, const expr_t *e2, int op);
expr_t *param_mismatch (const expr_t *e, int param, const char *fn, const expr_t *param_mismatch (const expr_t *e, int param, const char *fn,
type_t *t1, type_t *t2); struct type_s *t1, struct type_s *t2);
expr_t *test_error (const expr_t *e, type_t *t); const expr_t *test_error (const expr_t *e, struct type_s *t);
extern expr_t *local_expr; extern expr_t *local_expr;
@ -540,7 +540,7 @@ expr_t *new_unary_expr (int op, const expr_t *e1);
*/ */
expr_t *new_horizontal_expr (int op, const expr_t *vec, type_t *type); expr_t *new_horizontal_expr (int op, const expr_t *vec, type_t *type);
expr_t *new_swizzle_expr (const expr_t *src, const char *swizzle); const expr_t *new_swizzle_expr (const expr_t *src, const char *swizzle);
expr_t *new_extend_expr (const expr_t *src, type_t *type, int ext, bool rev); expr_t *new_extend_expr (const expr_t *src, type_t *type, int ext, bool rev);

View file

@ -208,14 +208,14 @@ _bug (const expr_t *e, const char *file, int line, const char *func,
va_end (args); va_end (args);
} }
expr_t * const expr_t *
_notice (const expr_t *e, const char *file, int line, const char *func, _notice (const expr_t *e, const char *file, int line, const char *func,
const char *fmt, ...) const char *fmt, ...)
{ {
va_list args; va_list args;
if (options.notices.silent) if (options.notices.silent)
return (expr_t *) e; return e;
va_start (args, fmt); va_start (args, fmt);
if (options.notices.promote) { if (options.notices.promote) {
@ -237,10 +237,10 @@ _notice (const expr_t *e, const char *file, int line, const char *func,
dstring_delete (message); dstring_delete (message);
} }
va_end (args); va_end (args);
return (expr_t *) e; return e;
} }
expr_t * const expr_t *
_warning (const expr_t *e, const char *file, int line, const char *func, _warning (const expr_t *e, const char *file, int line, const char *func,
const char *fmt, ...) const char *fmt, ...)
{ {
@ -249,7 +249,7 @@ _warning (const expr_t *e, const char *file, int line, const char *func,
va_start (args, fmt); va_start (args, fmt);
__warning (e, file, line, func, fmt, args); __warning (e, file, line, func, fmt, args);
va_end (args); va_end (args);
return (expr_t *) e; return e;
} }
void void
@ -263,7 +263,7 @@ _internal_error (const expr_t *e, const char *file, int line,
va_end (args); va_end (args);
} }
expr_t * const expr_t *
_error (const expr_t *e, const char *file, int line, const char *func, _error (const expr_t *e, const char *file, int line, const char *func,
const char *fmt, ...) const char *fmt, ...)
{ {
@ -292,5 +292,5 @@ _error (const expr_t *e, const char *file, int line, const char *func,
expr_t *err = new_expr (); expr_t *err = new_expr ();
err->type = ex_error; err->type = ex_error;
return (expr_t *) e; return err;
} }

View file

@ -178,8 +178,6 @@ print_bool (dstring_t *dstr, const expr_t *e, int level, int id, const expr_t *n
i); i);
dasprintf (dstr, "%*s</table>\n", indent + 2, ""); dasprintf (dstr, "%*s</table>\n", indent + 2, "");
dasprintf (dstr, "%*s>];\n", indent, ""); dasprintf (dstr, "%*s>];\n", indent, "");
if (e->next)
next = e->next;
_print_expr (dstr, e->boolean.e, level, id, next); _print_expr (dstr, e->boolean.e, level, id, next);
for (i = 0; i < tl_count; i++) for (i = 0; i < tl_count; i++)
dasprintf (dstr, "%*se_%p:t%d -> e_%p;\n", indent, "", e, i, dasprintf (dstr, "%*se_%p:t%d -> e_%p;\n", indent, "", e, i,
@ -195,8 +193,6 @@ print_label (dstring_t *dstr, const expr_t *e, int level, int id, const expr_t *
{ {
int indent = level * 2 + 2; int indent = level * 2 + 2;
if (e->next)
next = e->next;
if (next) if (next)
dasprintf (dstr, "%*se_%p -> e_%p [constraint=true,style=dashed];\n", dasprintf (dstr, "%*se_%p -> e_%p [constraint=true,style=dashed];\n",
indent, "", e, next); indent, "", e, next);
@ -209,8 +205,6 @@ print_labelref (dstring_t *dstr, const expr_t *e, int level, int id, const expr_
{ {
int indent = level * 2 + 2; int indent = level * 2 + 2;
if (e->next)
next = e->next;
if (next) if (next)
dasprintf (dstr, "%*se_%p -> e_%p [constraint=true,style=dashed];\n", dasprintf (dstr, "%*se_%p -> e_%p [constraint=true,style=dashed];\n",
indent, "", e, next); indent, "", e, next);
@ -227,7 +221,7 @@ print_block (dstring_t *dstr, const expr_t *e, int level, int id,
const expr_t *exprs[num_exprs + 1]; const expr_t *exprs[num_exprs + 1];
list_scatter (&e->block.list, exprs); list_scatter (&e->block.list, exprs);
exprs[num_exprs] = 0; exprs[num_exprs] = next;
int colspan = num_exprs ? num_exprs : 1; int colspan = num_exprs ? num_exprs : 1;
@ -397,9 +391,6 @@ print_conditional (dstring_t *dstr, const expr_t *e, int level, int id, const ex
e->branch.test); e->branch.test);
dasprintf (dstr, "%*se_%p -> \"e_%p\" [label=\"g\"];\n", indent, "", e, dasprintf (dstr, "%*se_%p -> \"e_%p\" [label=\"g\"];\n", indent, "", e,
e->branch.target); e->branch.target);
if (e->next) {
next = e->next;
}
if (next) { if (next) {
dasprintf (dstr, "%*se_%p -> e_%p [constraint=true," dasprintf (dstr, "%*se_%p -> e_%p [constraint=true,"
"style=dashed];\n", indent, "", e, next); "style=dashed];\n", indent, "", e, next);
@ -520,7 +511,8 @@ print_vector (dstring_t *dstr, const expr_t *e, int level, int id, const expr_t
{ {
int indent = level * 2 + 2; int indent = level * 2 + 2;
for (const expr_t *ele = e->vector.list; ele; ele = ele->next) { for (auto li = e->vector.list.head; li; li = li->next) {
auto ele = li->expr;
_print_expr (dstr, ele, level, id, next); _print_expr (dstr, ele, level, id, next);
dasprintf (dstr, "%*se_%p -> \"e_%p\";\n", indent, "", e, ele); dasprintf (dstr, "%*se_%p -> \"e_%p\";\n", indent, "", e, ele);
} }

View file

@ -546,6 +546,8 @@ dump_qfo_types (qfo_t *qfo, int base_address)
printf (" %s[%d] %5x %d\n", printf (" %s[%d] %5x %d\n",
get_ev_type_name (type->type), type->algebra.width, get_ev_type_name (type->type), type->algebra.width,
type->algebra.algebra, type->algebra.element); type->algebra.algebra, type->algebra.element);
case ty_meta_count:
break;
} }
} }
} }

View file

@ -214,15 +214,19 @@ extract_type (const expr_t *e)
return ev_type_count; return ev_type_count;
} }
expr_t * const expr_t *
type_mismatch (const expr_t *e1, const expr_t *e2, int op) type_mismatch (const expr_t *e1, const expr_t *e2, int op)
{ {
if (options.verbosity >= 2) {
print_expr (e1);
print_expr (e2);
}
return error (e1, "type mismatch: %s %s %s", return error (e1, "type mismatch: %s %s %s",
get_type_string (get_type (e1)), get_op_string (op), get_type_string (get_type (e1)), get_op_string (op),
get_type_string (get_type (e2))); get_type_string (get_type (e2)));
} }
expr_t * const expr_t *
param_mismatch (const expr_t *e, int param, const char *fn, type_t *t1, type_t *t2) param_mismatch (const expr_t *e, int param, const char *fn, type_t *t1, type_t *t2)
{ {
return error (e, "type mismatch for parameter %d of %s: " return error (e, "type mismatch for parameter %d of %s: "
@ -230,7 +234,7 @@ param_mismatch (const expr_t *e, int param, const char *fn, type_t *t1, type_t *
get_type_string (t2)); get_type_string (t2));
} }
expr_t * const expr_t *
test_error (const expr_t *e, type_t *t) test_error (const expr_t *e, type_t *t)
{ {
dstring_t *s = dstring_newstr (); dstring_t *s = dstring_newstr ();
@ -587,7 +591,7 @@ new_horizontal_expr (int op, const expr_t *vec, type_t *type)
return e; return e;
} }
expr_t * const expr_t *
new_swizzle_expr (const expr_t *src, const char *swizzle) new_swizzle_expr (const expr_t *src, const char *swizzle)
{ {
src = convert_name (src); src = convert_name (src);
@ -1380,9 +1384,6 @@ append_expr (expr_t *block, const expr_t *e)
if (!e || e->type == ex_error) if (!e || e->type == ex_error)
return block; return block;
if (e->next)
internal_error (e, "append_expr: expr loop detected");
auto li = new_listitem (e); auto li = new_listitem (e);
*block->block.tail = li; *block->block.tail = li;
block->block.tail = &li->next; block->block.tail = &li->next;
@ -1399,9 +1400,6 @@ prepend_expr (expr_t *block, const expr_t *e)
if (!e || e->type == ex_error) if (!e || e->type == ex_error)
return block; return block;
if (e->next)
internal_error (e, "append_expr: expr loop detected");
auto li = new_listitem (e); auto li = new_listitem (e);
li->next = block->block.head; li->next = block->block.head;
block->block.head = li; block->block.head = li;
@ -1489,6 +1487,9 @@ field_expr (const expr_t *e1, const expr_t *e2)
const expr_t *offset = new_short_expr (field->s.offset); const expr_t *offset = new_short_expr (field->s.offset);
e1 = offset_pointer_expr (e1, offset); e1 = offset_pointer_expr (e1, offset);
if (e1->type == ex_error) {
return e1;
}
e1 = cast_expr (pointer_type (field->type), e1); e1 = cast_expr (pointer_type (field->type), e1);
return unary_expr ('.', e1); return unary_expr ('.', e1);
} else if (is_class (t1->t.fldptr.type)) { } else if (is_class (t1->t.fldptr.type)) {
@ -1503,6 +1504,9 @@ field_expr (const expr_t *e1, const expr_t *e2)
const expr_t *offset = new_short_expr (ivar->s.offset); const expr_t *offset = new_short_expr (ivar->s.offset);
e1 = offset_pointer_expr (e1, offset); e1 = offset_pointer_expr (e1, offset);
e1 = cast_expr (pointer_type (ivar->type), e1); e1 = cast_expr (pointer_type (ivar->type), e1);
if (e1->type == ex_error) {
return e1;
}
return unary_expr ('.', e1); return unary_expr ('.', e1);
} }
} else if (is_algebra (t1)) { } else if (is_algebra (t1)) {
@ -1581,7 +1585,6 @@ convert_from_bool (const expr_t *e, type_t *type)
} }
auto cond = new_expr (); auto cond = new_expr ();
*cond = *e; *cond = *e;
cond->next = 0;
return conditional_expr (cond, one, zero); return conditional_expr (cond, one, zero);
} }
@ -2072,7 +2075,7 @@ build_function_call (const expr_t *fexpr, const type_t *ftype, const expr_t *par
{ {
int param_count = 0; int param_count = 0;
expr_t *call; expr_t *call;
expr_t *err = 0; const expr_t *err = 0;
int arg_count = params ? list_count (&params->list) :0; int arg_count = params ? list_count (&params->list) :0;
const expr_t *arguments[arg_count]; const expr_t *arguments[arg_count];
@ -2484,7 +2487,20 @@ conditional_expr (const expr_t *cond, const expr_t *e1, const expr_t *e2)
backpatch (c->boolean.true_list, tlabel); backpatch (c->boolean.true_list, tlabel);
backpatch (c->boolean.false_list, flabel); backpatch (c->boolean.false_list, flabel);
block->block.result = (type1 == type2) ? new_temp_def_expr (type1) : 0; if (!type_same (type1, type2)) {
if (!type_assignable (type1, type2)
&& !type_assignable (type2, type1)) {
type1 = 0;
}
if (!type_assignable (type1, type2)) {
type1 = type2;
}
if (type_promotes (type2, type1)) {
type1 = type2;
}
}
block->block.result = type1 ? new_temp_def_expr (type1) : 0;
append_expr (block, c); append_expr (block, c);
append_expr ((expr_t *) c->boolean.e, flabel);//FIXME cast append_expr ((expr_t *) c->boolean.e, flabel);//FIXME cast
if (block->block.result) if (block->block.result)
@ -2647,6 +2663,9 @@ offset_pointer_expr (const expr_t *pointer, const expr_t *offset)
} else { } else {
ptr = cast_expr (&type_int, pointer); ptr = cast_expr (&type_int, pointer);
} }
if (ptr->type == ex_error) {
return ptr;
}
ptr = binary_expr ('+', ptr, offset); ptr = binary_expr ('+', ptr, offset);
return cast_expr (ptr_type, ptr); return cast_expr (ptr_type, ptr);
} }

View file

@ -230,12 +230,15 @@ copy_qv_elements (expr_t *block, const expr_t *dst, const expr_t *src)
const expr_t *dw, *sw; const expr_t *dw, *sw;
const expr_t *ds, *ss; const expr_t *ds, *ss;
const expr_t *dv, *sv; const expr_t *dv, *sv;
int count = list_count (&src->vector.list);
const expr_t *components[count];
list_scatter (&src->vector.list, components);
if (is_vector (src->vector.type)) { if (is_vector (src->vector.type)) {
// guaranteed to have three elements // guaranteed to have three elements
sx = src->vector.list; sx = components[0];
sy = sx->next; sy = components[1];
sz = sy->next; sz = components[2];
dx = field_expr (dst, new_name_expr ("x")); dx = field_expr (dst, new_name_expr ("x"));
dy = field_expr (dst, new_name_expr ("y")); dy = field_expr (dst, new_name_expr ("y"));
dz = field_expr (dst, new_name_expr ("z")); dz = field_expr (dst, new_name_expr ("z"));
@ -244,12 +247,12 @@ copy_qv_elements (expr_t *block, const expr_t *dst, const expr_t *src)
append_expr (block, assign_expr (dz, sz)); append_expr (block, assign_expr (dz, sz));
} else { } else {
// guaranteed to have two or four elements // guaranteed to have two or four elements
if (src->vector.list->next->next) { if (count == 4) {
// four vals: x, y, z, w // four vals: x, y, z, w
sx = src->vector.list; sx = components[0];
sy = sx->next; sy = components[1];
sz = sy->next; sz = components[2];
sw = sz->next; sw = components[3];
dx = field_expr (dst, new_name_expr ("x")); dx = field_expr (dst, new_name_expr ("x"));
dy = field_expr (dst, new_name_expr ("y")); dy = field_expr (dst, new_name_expr ("y"));
dz = field_expr (dst, new_name_expr ("z")); dz = field_expr (dst, new_name_expr ("z"));
@ -260,8 +263,8 @@ copy_qv_elements (expr_t *block, const expr_t *dst, const expr_t *src)
append_expr (block, assign_expr (dw, sw)); append_expr (block, assign_expr (dw, sw));
} else { } else {
// v, s // v, s
sv = src->vector.list; sv = components[0];
ss = sv->next; ss = components[1];
dv = field_expr (dst, new_name_expr ("v")); dv = field_expr (dst, new_name_expr ("v"));
ds = field_expr (dst, new_name_expr ("s")); ds = field_expr (dst, new_name_expr ("s"));
append_expr (block, assign_expr (dv, sv)); append_expr (block, assign_expr (dv, sv));
@ -274,7 +277,8 @@ static int
copy_elements (expr_t *block, const expr_t *dst, const expr_t *src, int base) copy_elements (expr_t *block, const expr_t *dst, const expr_t *src, int base)
{ {
int index = 0; int index = 0;
for (const expr_t *e = src->vector.list; e; e = e->next) { for (auto li = src->vector.list.head; li; li = li->next) {
auto e = li->expr;
if (e->type == ex_vector) { if (e->type == ex_vector) {
index += copy_elements (block, dst, e, index + base); index += copy_elements (block, dst, e, index + base);
} else { } else {

View file

@ -829,6 +829,40 @@ static expr_type_t **binary_expr_types[ev_type_count] = {
[ev_ulong] = ulong_x, [ev_ulong] = ulong_x,
}; };
static expr_type_t int_handle[] = {
{EQ, &type_int},
{NE, &type_int},
{0, 0}
};
static expr_type_t long_handle[] = {
{EQ, &type_int},
{NE, &type_int},
{0, 0}
};
static expr_type_t *int_handle_x[ev_type_count] = {
[ev_int] = int_handle,
};
static expr_type_t *long_handle_x[ev_type_count] = {
[ev_long] = long_handle,
};
static expr_type_t **binary_expr_handle[ev_type_count] = {
[ev_int] = int_handle_x,
[ev_long] = long_handle_x,
};
static expr_type_t ***binary_expr_meta[ty_meta_count] = {
[ty_basic] = binary_expr_types,
[ty_enum] = binary_expr_types,
[ty_alias] = binary_expr_types,
[ty_handle] = binary_expr_handle,
};
// supported operators for scalar-vector expressions // supported operators for scalar-vector expressions
static int scalar_vec_ops[] = { '*', '/', '%', MOD, 0 }; static int scalar_vec_ops[] = { '*', '/', '%', MOD, 0 };
static const expr_t * static const expr_t *
@ -1284,9 +1318,19 @@ binary_expr (int op, const expr_t *e1, const expr_t *e2)
et1 = low_level_type (t1); et1 = low_level_type (t1);
et2 = low_level_type (t2); et2 = low_level_type (t2);
if (et1 >= ev_type_count || !binary_expr_types[et1]) if (t1->meta >= ty_meta_count || !binary_expr_meta[t1->meta]) {
return invalid_binary_expr(op, e1, e2); return invalid_binary_expr(op, e1, e2);
if (et2 >= ev_type_count || !binary_expr_types[et1][et2]) }
if (t2->meta >= ty_meta_count || !binary_expr_meta[t2->meta]) {
return invalid_binary_expr(op, e1, e2);
}
if (binary_expr_meta[t1->meta] != binary_expr_meta[t2->meta]) {
return invalid_binary_expr(op, e1, e2);
}
auto expr_meta = binary_expr_meta[t1->meta];
if (et1 >= ev_type_count || !expr_meta[et1])
return invalid_binary_expr(op, e1, e2);
if (et2 >= ev_type_count || !expr_meta[et1][et2])
return invalid_binary_expr(op, e1, e2); return invalid_binary_expr(op, e1, e2);
if ((t1->width > 1 || t2->width > 1)) { if ((t1->width > 1 || t2->width > 1)) {
@ -1372,7 +1416,7 @@ binary_expr (int op, const expr_t *e1, const expr_t *e2)
} }
} }
expr_type = binary_expr_types[et1][et2]; expr_type = expr_meta[et1][et2];
while (expr_type->op && expr_type->op != op) while (expr_type->op && expr_type->op != op)
expr_type++; expr_type++;
if (!expr_type->op) if (!expr_type->op)
@ -1398,6 +1442,9 @@ binary_expr (int op, const expr_t *e1, const expr_t *e2)
if (expr_type->anticommute) { if (expr_type->anticommute) {
ne->expr.anticommute = expr_type->anticommute (); ne->expr.anticommute = expr_type->anticommute ();
} }
if (expr_type->associative) {
ne->expr.associative = expr_type->associative ();
}
if (is_compare (op) || is_logic (op)) { if (is_compare (op) || is_logic (op)) {
if (options.code.progsversion == PROG_ID_VERSION) { if (options.code.progsversion == PROG_ID_VERSION) {
ne->expr.type = &type_float; ne->expr.type = &type_float;

View file

@ -170,6 +170,9 @@ super_expr (class_type_t *class_type)
e = new_symbol_expr (class_pointer_symbol (class)); e = new_symbol_expr (class_pointer_symbol (class));
e = assign_expr (field_expr (super, new_name_expr ("class")), e = assign_expr (field_expr (super, new_name_expr ("class")),
field_expr (e, new_name_expr ("super_class"))); field_expr (e, new_name_expr ("super_class")));
if (e->type == ex_error) {
return e;
}
append_expr (super_block, e); append_expr (super_block, e);
e = address_expr (super, 0); e = address_expr (super, 0);

View file

@ -550,8 +550,10 @@ optimize_core (const expr_t *expr)
optimize_extends (adds); optimize_extends (adds);
optimize_extends (subs); optimize_extends (subs);
if (expr->expr.commutative) {
optimize_adds (adds); optimize_adds (adds);
optimize_adds (subs); optimize_adds (subs);
}
optimize_cross_products (adds, subs); optimize_cross_products (adds, subs);
optimize_scale_products (adds, subs); optimize_scale_products (adds, subs);

View file

@ -132,14 +132,9 @@ new_vector_list (const expr_t *expr_list)
return vec; return vec;
} }
for (int i = 0; i < count; i++) {
//FIXME this should use ex_list
((expr_t *) elements[i])->next = (expr_t *) elements[i + 1];
}
expr_t *vec = new_expr (); expr_t *vec = new_expr ();
vec->type = ex_vector; vec->type = ex_vector;
vec->vector.type = vector_type (ele_type, width); vec->vector.type = vector_type (ele_type, width);
vec->vector.list = elements[0]; list_gather (&vec->vector.list, elements, count);
return vec; return vec;
} }

View file

@ -704,7 +704,7 @@ const expr_t *
method_check_params (method_t *method, const expr_t *args) method_check_params (method_t *method, const expr_t *args)
{ {
int i, param_count; int i, param_count;
expr_t *err = 0; const expr_t *err = 0;
type_t *mtype = method->type; type_t *mtype = method->type;
if (mtype->t.func.num_params == -1) if (mtype->t.func.num_params == -1)
@ -725,7 +725,7 @@ method_check_params (method_t *method, const expr_t *args)
list_scatter_rev (&args->list, arg_list); list_scatter_rev (&args->list, arg_list);
for (i = 2; i < count; i++) { for (i = 2; i < count; i++) {
const expr_t *e = arg_list[i]; const expr_t *e = arg_list[i];
type_t *arg_type = mtype->t.func.param_types[i]; type_t *arg_type = i < param_count ? mtype->t.func.param_types[i] : 0;
type_t *t; type_t *t;
if (e->type == ex_compound) { if (e->type == ex_compound) {

View file

@ -717,6 +717,8 @@ get_def_type (qfo_t *qfo, pr_ptr_t type)
case ty_array: case ty_array:
case ty_class: case ty_class:
return ev_invalid; return ev_invalid;
case ty_meta_count:
break;
} }
return ev_invalid; return ev_invalid;
} }
@ -757,6 +759,8 @@ get_type_size (qfo_t *qfo, pr_ptr_t type)
case ty_class: case ty_class:
case ty_algebra: case ty_algebra:
return 0; // FIXME return 0; // FIXME
case ty_meta_count:
break;
} }
return 0; return 0;
} }
@ -807,6 +811,8 @@ get_type_alignment_log (qfo_t *qfo, pr_ptr_t type)
case ty_class: case ty_class:
case ty_algebra: case ty_algebra:
return 0; // FIXME return 0; // FIXME
case ty_meta_count:
break;
} }
return 0; return 0;
} }

View file

@ -334,7 +334,6 @@ qfo_encode_type (type_t *type, defspace_t *space)
if (type->type_def && type->type_def->external) { if (type->type_def && type->type_def->external) {
relocs = type->type_def->relocs; relocs = type->type_def->relocs;
free_def (type->type_def);
type->type_def = 0; type->type_def = 0;
} }
if (type->type_def) if (type->type_def)

View file

@ -156,7 +156,8 @@ int yylex (void);
%token RETURN AT_RETURN ELLIPSIS %token RETURN AT_RETURN ELLIPSIS
%token NIL GOTO SWITCH CASE DEFAULT ENUM ALGEBRA %token NIL GOTO SWITCH CASE DEFAULT ENUM ALGEBRA
%token ARGS TYPEDEF EXTERN STATIC SYSTEM OVERLOAD NOT ATTRIBUTE %token ARGS TYPEDEF EXTERN STATIC SYSTEM OVERLOAD NOT ATTRIBUTE
%token <op> STRUCT HANDLE %token <op> STRUCT
%token HANDLE
%token <spec> TYPE_SPEC TYPE_NAME TYPE_QUAL %token <spec> TYPE_SPEC TYPE_NAME TYPE_QUAL
%token <spec> OBJECT_NAME %token <spec> OBJECT_NAME
%token CLASS DEFS ENCODE END IMPLEMENTATION INTERFACE PRIVATE %token CLASS DEFS ENCODE END IMPLEMENTATION INTERFACE PRIVATE
@ -164,6 +165,7 @@ int yylex (void);
%type <spec> storage_class save_storage %type <spec> storage_class save_storage
%type <spec> typespec typespec_reserved typespec_nonreserved %type <spec> typespec typespec_reserved typespec_nonreserved
%type <spec> handle
%type <spec> declspecs declspecs_nosc declspecs_nots %type <spec> declspecs declspecs_nosc declspecs_nots
%type <spec> declspecs_ts %type <spec> declspecs_ts
%type <spec> declspecs_nosc_ts declspecs_nosc_nots %type <spec> declspecs_nosc_ts declspecs_nosc_nots
@ -1122,9 +1124,10 @@ struct_specifier
symtab_addsymbol (tab, sym); symtab_addsymbol (tab, sym);
} }
} }
| HANDLE tag | handle tag
{ {
symbol_t *sym = find_handle ($2, 0); specifier_t spec = default_type ($1, 0);
symbol_t *sym = find_handle ($2, spec.type);
sym->type = find_type (sym->type); sym->type = find_type (sym->type);
$$ = make_spec (sym->type, 0, 0, 0); $$ = make_spec (sym->type, 0, 0, 0);
if (!sym->table) { if (!sym->table) {
@ -1137,6 +1140,11 @@ struct_specifier
} }
; ;
handle
: HANDLE { $$ = make_spec (&type_int, 0, 0, 0); }
| HANDLE '(' TYPE_SPEC ')' { $$ = $3; }
;
struct_list struct_list
: '{' : '{'
{ {

View file

@ -1926,7 +1926,8 @@ static int
statement_copy_elements (sblock_t **sblock, const expr_t *dst, const expr_t *src, int base) statement_copy_elements (sblock_t **sblock, const expr_t *dst, const expr_t *src, int base)
{ {
int index = 0; int index = 0;
for (const expr_t *e = src->vector.list; e; e = e->next) { for (auto li = src->vector.list.head; li; li = li->next) {
auto e = li->expr;
if (e->type == ex_vector) { if (e->type == ex_vector) {
index += statement_copy_elements (sblock, dst, e, index + base); index += statement_copy_elements (sblock, dst, e, index + base);
} else { } else {
@ -2073,15 +2074,12 @@ build_bool_block (expr_t *block, expr_t *e)
build_bool_block (block, (expr_t *) e->boolean.e); build_bool_block (block, (expr_t *) e->boolean.e);
return; return;
case ex_label: case ex_label:
e->next = 0;
append_expr (block, e); append_expr (block, e);
return; return;
case ex_assign: case ex_assign:
e->next = 0;
append_expr (block, e); append_expr (block, e);
return; return;
case ex_branch: case ex_branch:
e->next = 0;
append_expr (block, e); append_expr (block, e);
return; return;
case ex_expr: case ex_expr:
@ -2089,7 +2087,6 @@ build_bool_block (expr_t *block, expr_t *e)
build_bool_block (block, (expr_t *) e->expr.e1); build_bool_block (block, (expr_t *) e->expr.e1);
build_bool_block (block, (expr_t *) e->expr.e2); build_bool_block (block, (expr_t *) e->expr.e2);
} else { } else {
e->next = 0;
append_expr (block, e); append_expr (block, e);
} }
return; return;

View file

@ -128,11 +128,15 @@ start_struct (int *su, symbol_t *tag, symtab_t *parent)
symbol_t * symbol_t *
find_handle (symbol_t *tag, type_t *type) find_handle (symbol_t *tag, type_t *type)
{ {
symbol_t *sym = find_tag (ty_handle, tag, type); if (type != &type_int && type != &type_long) {
error (0, "@handle type must be int or long");
type = &type_int;
}
symbol_t *sym = find_tag (ty_handle, tag, 0);
if (sym->type->type == ev_invalid) { if (sym->type->type == ev_invalid) {
sym->type->type = ev_func; sym->type->type = type->type;
sym->type->width = 1; sym->type->width = 1;
sym->type->alignment = 1; sym->type->alignment = type->alignment;
} }
return sym; return sym;
} }

View file

@ -55,8 +55,8 @@ void codespace_addcode (codespace_t *codespace, struct dstatement_s *code, int s
__attribute__((const)) int function_parms (function_t *f, byte *parm_size) {return 0;} __attribute__((const)) int function_parms (function_t *f, byte *parm_size) {return 0;}
void def_to_ddef (def_t *def, ddef_t *ddef, int aux) {} void def_to_ddef (def_t *def, ddef_t *ddef, int aux) {}
__attribute__((noreturn)) void _internal_error (const expr_t *e, const char *file, int line, const char *func, const char *fmt, ...) {abort();} __attribute__((noreturn)) void _internal_error (const expr_t *e, const char *file, int line, const char *func, const char *fmt, ...) {abort();}
__attribute__((const)) expr_t *_warning (const expr_t *e, const char *file, int line, const char *func, const char *fmt, ...) {return 0;} __attribute__((const)) const expr_t *_warning (const expr_t *e, const char *file, int line, const char *func, const char *fmt, ...) {return 0;}
__attribute__((const)) expr_t *_error (const expr_t *e, const char *file, int line, const char *func, const char *fmt, ...) {return 0;} __attribute__((const)) const expr_t *_error (const expr_t *e, const char *file, int line, const char *func, const char *fmt, ...) {return 0;}
__attribute__((const)) symbol_t *make_structure (const char *name, int su, struct_def_t *defs, type_t *type) {return 0;} __attribute__((const)) symbol_t *make_structure (const char *name, int su, struct_def_t *defs, type_t *type) {return 0;}
__attribute__((const)) symbol_t *symtab_addsymbol (symtab_t *symtab, symbol_t *symbol) {return 0;} __attribute__((const)) symbol_t *symtab_addsymbol (symtab_t *symtab, symbol_t *symbol) {return 0;}
__attribute__((const)) symbol_t *new_symbol_type (const char *name, type_t *type) {return 0;} __attribute__((const)) symbol_t *new_symbol_type (const char *name, type_t *type) {return 0;}

View file

@ -314,6 +314,7 @@ copy_chain (type_t *type, type_t *append)
case ty_alias: //XXX is this correct? case ty_alias: //XXX is this correct?
case ty_handle: case ty_handle:
case ty_algebra: case ty_algebra:
case ty_meta_count:
internal_error (0, "copy object type %d", type->meta); internal_error (0, "copy object type %d", type->meta);
} }
} }
@ -373,6 +374,7 @@ append_type (type_t *type, type_t *new)
case ty_alias: //XXX is this correct? case ty_alias: //XXX is this correct?
case ty_handle: case ty_handle:
case ty_algebra: case ty_algebra:
case ty_meta_count:
internal_error (0, "append to object type"); internal_error (0, "append to object type");
} }
} }
@ -445,6 +447,8 @@ types_same (type_t *a, type_t *b)
return a->name == b->name; return a->name == b->name;
case ty_algebra: case ty_algebra:
return a->t.algebra == b->t.algebra; return a->t.algebra == b->t.algebra;
case ty_meta_count:
break;
} }
internal_error (0, "we be broke"); internal_error (0, "we be broke");
} }
@ -578,6 +582,8 @@ find_type (type_t *type)
break; break;
case ty_algebra: case ty_algebra:
break; break;
case ty_meta_count:
break;
} }
} }
@ -845,6 +851,8 @@ print_type_str (dstring_t *str, const type_t *type)
return; return;
} }
switch (type->meta) { switch (type->meta) {
case ty_meta_count:
break;
case ty_algebra: case ty_algebra:
algebra_print_type_str (str, type); algebra_print_type_str (str, type);
return; return;
@ -1040,6 +1048,8 @@ encode_type (dstring_t *encoding, const type_t *type)
if (!type) if (!type)
return; return;
switch (type->meta) { switch (type->meta) {
case ty_meta_count:
break;
case ty_algebra: case ty_algebra:
algebra_encode_type (encoding, type); algebra_encode_type (encoding, type);
return; return;
@ -1424,6 +1434,8 @@ type_size (const type_t *type)
return type_size (type->t.alias.aux_type); return type_size (type->t.alias.aux_type);
case ty_algebra: case ty_algebra:
return algebra_type_size (type); return algebra_type_size (type);
case ty_meta_count:
break;
} }
internal_error (0, "invalid type meta: %d", type->meta); internal_error (0, "invalid type meta: %d", type->meta);
} }
@ -1456,6 +1468,8 @@ type_width (const type_t *type)
return type_width (type->t.alias.aux_type); return type_width (type->t.alias.aux_type);
case ty_algebra: case ty_algebra:
return algebra_type_width (type); return algebra_type_width (type);
case ty_meta_count:
break;
} }
internal_error (0, "invalid type meta: %d", type->meta); internal_error (0, "invalid type meta: %d", type->meta);
} }

View file

@ -519,6 +519,9 @@ imm_compare (const void *_imm1, const void *_imm2, void *_tab)
sizeof (imm1->i.pointer)); sizeof (imm1->i.pointer));
} else if (tab == &value_imm_defs) { } else if (tab == &value_imm_defs) {
size_t size = type_size (imm1->def->type) * sizeof (pr_type_t); size_t size = type_size (imm1->def->type) * sizeof (pr_type_t);
if (imm1->def->type->alignment != imm2->def->type->alignment) {
return 0;
}
return !memcmp (&imm1->i, &imm2->i, size); return !memcmp (&imm1->i, &imm2->i, size);
} else { } else {
internal_error (0, "invalid immediate hash table"); internal_error (0, "invalid immediate hash table");