[qfcc] Support 32-bit and 64-bit handle types

32-bit is nice because it's small, but 64-bit is handy for special
handle encodings.
This commit is contained in:
Bill Currie 2023-10-02 23:33:37 +09:00
parent 360dfc0038
commit ba35ce71b3
9 changed files with 98 additions and 14 deletions

View file

@ -50,6 +50,8 @@ typedef enum {
ty_alias,
ty_handle,
ty_algebra,
ty_meta_count
} ty_meta_e;
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);
case ty_algebra:
return 1; //FIXME wip
case ty_meta_count:
break;
}
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);
value_string (data, type, value);
break;
case ty_meta_count:
break;
}
}

View file

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

View file

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

View file

@ -829,6 +829,40 @@ static expr_type_t **binary_expr_types[ev_type_count] = {
[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
static int scalar_vec_ops[] = { '*', '/', '%', MOD, 0 };
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);
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);
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);
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)
expr_type++;
if (!expr_type->op)

View file

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

View file

@ -156,7 +156,8 @@ int yylex (void);
%token RETURN AT_RETURN ELLIPSIS
%token NIL GOTO SWITCH CASE DEFAULT ENUM ALGEBRA
%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> OBJECT_NAME
%token CLASS DEFS ENCODE END IMPLEMENTATION INTERFACE PRIVATE
@ -164,6 +165,7 @@ int yylex (void);
%type <spec> storage_class save_storage
%type <spec> typespec typespec_reserved typespec_nonreserved
%type <spec> handle
%type <spec> declspecs declspecs_nosc declspecs_nots
%type <spec> declspecs_ts
%type <spec> declspecs_nosc_ts declspecs_nosc_nots
@ -1122,9 +1124,10 @@ struct_specifier
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);
$$ = make_spec (sym->type, 0, 0, 0);
if (!sym->table) {
@ -1137,6 +1140,11 @@ struct_specifier
}
;
handle
: HANDLE { $$ = make_spec (&type_int, 0, 0, 0); }
| HANDLE '(' TYPE_SPEC ')' { $$ = $3; }
;
struct_list
: '{'
{

View file

@ -128,11 +128,15 @@ start_struct (int *su, symbol_t *tag, symtab_t *parent)
symbol_t *
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) {
sym->type->type = ev_func;
sym->type->type = type->type;
sym->type->width = 1;
sym->type->alignment = 1;
sym->type->alignment = type->alignment;
}
return sym;
}

View file

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