mirror of
https://github.com/DarkPlacesEngine/gmqcc.git
synced 2025-01-31 03:50:36 +00:00
Preparing to parse arrays: adding TYPE_ARRAY and union/struct TYPE_ constants to be consistent with fteqcc, filled type-arrays with their data, attempting to parse an array variable and added some error messages to the IR in case of unhandled types
This commit is contained in:
parent
c87b056fdc
commit
1869440fd9
4 changed files with 119 additions and 20 deletions
2
ast.h
2
ast.h
|
@ -116,6 +116,8 @@ typedef struct
|
|||
ast_expression_codegen *codegen;
|
||||
int vtype;
|
||||
ast_expression *next;
|
||||
/* arrays get a member-count */
|
||||
size_t count;
|
||||
MEM_VECTOR_MAKE(ast_value*, params);
|
||||
bool variadic;
|
||||
/* The codegen functions should store their output values
|
||||
|
|
3
gmqcc.h
3
gmqcc.h
|
@ -290,6 +290,9 @@ enum {
|
|||
TYPE_POINTER ,
|
||||
TYPE_INTEGER ,
|
||||
TYPE_VARIANT ,
|
||||
TYPE_STRUCT ,
|
||||
TYPE_UNION ,
|
||||
TYPE_ARRAY ,
|
||||
|
||||
TYPE_COUNT
|
||||
};
|
||||
|
|
60
ir.c
60
ir.c
|
@ -38,10 +38,11 @@ const char *type_name[TYPE_COUNT] = {
|
|||
"field",
|
||||
"function",
|
||||
"pointer",
|
||||
#if 0
|
||||
"integer",
|
||||
#endif
|
||||
"variant"
|
||||
"variant",
|
||||
"struct",
|
||||
"union",
|
||||
"array"
|
||||
};
|
||||
|
||||
size_t type_sizeof[TYPE_COUNT] = {
|
||||
|
@ -53,10 +54,11 @@ size_t type_sizeof[TYPE_COUNT] = {
|
|||
1, /* TYPE_FIELD */
|
||||
1, /* TYPE_FUNCTION */
|
||||
1, /* TYPE_POINTER */
|
||||
#if 0
|
||||
1, /* TYPE_INTEGER */
|
||||
#endif
|
||||
3, /* TYPE_VARIANT */
|
||||
0, /* TYPE_STRUCT */
|
||||
0, /* TYPE_UNION */
|
||||
0, /* TYPE_ARRAY */
|
||||
};
|
||||
|
||||
uint16_t type_store_instr[TYPE_COUNT] = {
|
||||
|
@ -70,9 +72,15 @@ uint16_t type_store_instr[TYPE_COUNT] = {
|
|||
INSTR_STORE_ENT, /* should use I */
|
||||
#if 0
|
||||
INSTR_STORE_I, /* integer type */
|
||||
#else
|
||||
INSTR_STORE_F,
|
||||
#endif
|
||||
|
||||
INSTR_STORE_V, /* variant, should never be accessed */
|
||||
|
||||
AINSTR_END, /* struct */
|
||||
AINSTR_END, /* union */
|
||||
AINSTR_END, /* array */
|
||||
};
|
||||
|
||||
uint16_t field_store_instr[TYPE_COUNT] = {
|
||||
|
@ -86,9 +94,15 @@ uint16_t field_store_instr[TYPE_COUNT] = {
|
|||
INSTR_STORE_FLD,
|
||||
#if 0
|
||||
INSTR_STORE_FLD, /* integer type */
|
||||
#else
|
||||
INSTR_STORE_FLD,
|
||||
#endif
|
||||
|
||||
INSTR_STORE_V, /* variant, should never be accessed */
|
||||
|
||||
AINSTR_END, /* struct */
|
||||
AINSTR_END, /* union */
|
||||
AINSTR_END, /* array */
|
||||
};
|
||||
|
||||
uint16_t type_storep_instr[TYPE_COUNT] = {
|
||||
|
@ -102,9 +116,15 @@ uint16_t type_storep_instr[TYPE_COUNT] = {
|
|||
INSTR_STOREP_ENT, /* should use I */
|
||||
#if 0
|
||||
INSTR_STOREP_ENT, /* integer type */
|
||||
#else
|
||||
INSTR_STOREP_F,
|
||||
#endif
|
||||
|
||||
INSTR_STOREP_V, /* variant, should never be accessed */
|
||||
|
||||
AINSTR_END, /* struct */
|
||||
AINSTR_END, /* union */
|
||||
AINSTR_END, /* array */
|
||||
};
|
||||
|
||||
uint16_t type_eq_instr[TYPE_COUNT] = {
|
||||
|
@ -118,9 +138,15 @@ uint16_t type_eq_instr[TYPE_COUNT] = {
|
|||
INSTR_EQ_E, /* should use I */
|
||||
#if 0
|
||||
INSTR_EQ_I,
|
||||
#else
|
||||
INSTR_EQ_F,
|
||||
#endif
|
||||
|
||||
INSTR_EQ_V, /* variant, should never be accessed */
|
||||
|
||||
AINSTR_END, /* struct */
|
||||
AINSTR_END, /* union */
|
||||
AINSTR_END, /* array */
|
||||
};
|
||||
|
||||
uint16_t type_ne_instr[TYPE_COUNT] = {
|
||||
|
@ -134,9 +160,15 @@ uint16_t type_ne_instr[TYPE_COUNT] = {
|
|||
INSTR_NE_E, /* should use I */
|
||||
#if 0
|
||||
INSTR_NE_I,
|
||||
#else
|
||||
INSTR_NE_F,
|
||||
#endif
|
||||
|
||||
INSTR_NE_V, /* variant, should never be accessed */
|
||||
|
||||
AINSTR_END, /* struct */
|
||||
AINSTR_END, /* union */
|
||||
AINSTR_END, /* array */
|
||||
};
|
||||
|
||||
MEM_VEC_FUNCTIONS(ir_value_vector, ir_value*, v)
|
||||
|
@ -1561,6 +1593,7 @@ ir_value* ir_block_create_load_from_ent(ir_block *self, const char *label, ir_va
|
|||
case TYPE_INTEGER: op = INSTR_LOAD_I; break;
|
||||
#endif
|
||||
default:
|
||||
irerror(self->context, "invalid type for ir_block_create_load_from_ent: %s", type_name[outype]);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -1577,6 +1610,7 @@ ir_value* ir_block_create_add(ir_block *self,
|
|||
if (l == r) {
|
||||
switch (l) {
|
||||
default:
|
||||
irerror(self->context, "invalid type for ir_block_create_add: %s", type_name[l]);
|
||||
return NULL;
|
||||
case TYPE_FLOAT:
|
||||
op = INSTR_ADD_F;
|
||||
|
@ -1598,7 +1632,10 @@ ir_value* ir_block_create_add(ir_block *self,
|
|||
op = INSTR_ADD_IF;
|
||||
else
|
||||
#endif
|
||||
{
|
||||
irerror(self->context, "invalid type for ir_block_create_add: %s", type_name[l]);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return ir_block_create_binop(self, label, op, left, right);
|
||||
}
|
||||
|
@ -1614,6 +1651,7 @@ ir_value* ir_block_create_sub(ir_block *self,
|
|||
|
||||
switch (l) {
|
||||
default:
|
||||
irerror(self->context, "invalid type for ir_block_create_sub: %s", type_name[l]);
|
||||
return NULL;
|
||||
case TYPE_FLOAT:
|
||||
op = INSTR_SUB_F;
|
||||
|
@ -1635,7 +1673,10 @@ ir_value* ir_block_create_sub(ir_block *self,
|
|||
op = INSTR_SUB_IF;
|
||||
else
|
||||
#endif
|
||||
{
|
||||
irerror(self->context, "invalid type for ir_block_create_sub: %s", type_name[l]);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return ir_block_create_binop(self, label, op, left, right);
|
||||
}
|
||||
|
@ -1651,6 +1692,7 @@ ir_value* ir_block_create_mul(ir_block *self,
|
|||
|
||||
switch (l) {
|
||||
default:
|
||||
irerror(self->context, "invalid type for ir_block_create_mul: %s", type_name[l]);
|
||||
return NULL;
|
||||
case TYPE_FLOAT:
|
||||
op = INSTR_MUL_F;
|
||||
|
@ -1679,8 +1721,10 @@ ir_value* ir_block_create_mul(ir_block *self,
|
|||
else if ( (l == TYPE_INTEGER && r == TYPE_FLOAT) )
|
||||
op = INSTR_MUL_IF;
|
||||
#endif
|
||||
else
|
||||
else {
|
||||
irerror(self->context, "invalid type for ir_block_create_mul: %s", type_name[l]);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return ir_block_create_binop(self, label, op, left, right);
|
||||
}
|
||||
|
@ -1696,6 +1740,7 @@ ir_value* ir_block_create_div(ir_block *self,
|
|||
|
||||
switch (l) {
|
||||
default:
|
||||
irerror(self->context, "invalid type for ir_block_create_div: %s", type_name[l]);
|
||||
return NULL;
|
||||
case TYPE_FLOAT:
|
||||
op = INSTR_DIV_F;
|
||||
|
@ -1716,7 +1761,10 @@ ir_value* ir_block_create_div(ir_block *self,
|
|||
op = INSTR_DIV_IF;
|
||||
else
|
||||
#endif
|
||||
{
|
||||
irerror(self->context, "invalid type for ir_block_create_div: %s", type_name[l]);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return ir_block_create_binop(self, label, op, left, right);
|
||||
}
|
||||
|
|
74
parser.c
74
parser.c
|
@ -2314,29 +2314,25 @@ static ast_value *parse_typename(parser_t *parser, ast_value **storebase)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* an opening paren now starts the parameter-list of a function */
|
||||
/* an opening paren now starts the parameter-list of a function
|
||||
* this is where original-QC has parameter lists.
|
||||
* We allow a single parameter list here.
|
||||
* Much like fteqcc we don't allow `float()() x`
|
||||
*/
|
||||
if (parser->tok == '(') {
|
||||
var = parse_parameter_list(parser, var);
|
||||
if (!var)
|
||||
return NULL;
|
||||
}
|
||||
/* This is the point where we can turn it into a field */
|
||||
if (isfield) {
|
||||
/* turn it into a field if desired */
|
||||
tmp = ast_value_new(ctx, "<type:f>", TYPE_FIELD);
|
||||
tmp->expression.next = (ast_expression*)var;
|
||||
var = tmp;
|
||||
}
|
||||
|
||||
while (parser->tok == '(') {
|
||||
var = parse_parameter_list(parser, var);
|
||||
if (!var)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* store the base if requested */
|
||||
if (storebase) {
|
||||
*storebase = ast_value_copy(var);
|
||||
if (isfield) {
|
||||
tmp = ast_value_new(ctx, "<type:f>", TYPE_FIELD);
|
||||
tmp->expression.next = (ast_expression*)*storebase;
|
||||
*storebase = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
/* there may be a name now */
|
||||
|
@ -2344,11 +2340,60 @@ static ast_value *parse_typename(parser_t *parser, ast_value **storebase)
|
|||
name = util_strdup(parser_tokval(parser));
|
||||
/* parse on */
|
||||
if (!parser_next(parser)) {
|
||||
ast_delete(var);
|
||||
parseerror(parser, "error after variable or field declaration");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* now this may be an array */
|
||||
if (parser->tok == '[') {
|
||||
ast_expression *cexp = parse_expression_leave(parser, true);
|
||||
ast_value *cval;
|
||||
if (!cexp || !ast_istype(cexp, ast_value)) {
|
||||
if (cexp) ast_delete(cexp);
|
||||
ast_delete(var);
|
||||
parseerror(parser, "expected array-size as constant positive integer");
|
||||
return NULL;
|
||||
}
|
||||
cval = (ast_value*)cexp;
|
||||
|
||||
tmp = ast_value_new(ctx, "<type[]>", TYPE_ARRAY);
|
||||
tmp->expression.next = (ast_expression*)var;
|
||||
var = tmp;
|
||||
|
||||
if (cval->expression.vtype == TYPE_INTEGER)
|
||||
tmp->expression.count = cval->constval.vint;
|
||||
else if (cval->expression.vtype == TYPE_FLOAT)
|
||||
tmp->expression.count = cval->constval.vfloat;
|
||||
else {
|
||||
ast_delete(cexp);
|
||||
ast_delete(var);
|
||||
parseerror(parser, "array-size must be a positive integer constant");
|
||||
return NULL;
|
||||
}
|
||||
ast_delete(cexp);
|
||||
|
||||
if (parser->tok != ']') {
|
||||
ast_delete(var);
|
||||
parseerror(parser, "expected ']' after array-size");
|
||||
return NULL;
|
||||
}
|
||||
if (!parser_next(parser)) {
|
||||
ast_delete(var);
|
||||
parseerror(parser, "error after parsing array size");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* This is the point where we can turn it into a field */
|
||||
if (isfield) {
|
||||
/* turn it into a field if desired */
|
||||
tmp = ast_value_new(ctx, "<type:f>", TYPE_FIELD);
|
||||
tmp->expression.next = (ast_expression*)var;
|
||||
var = tmp;
|
||||
}
|
||||
|
||||
/* now there may be function parens again */
|
||||
if (parser->tok == '(' && opts_standard == COMPILER_QCC)
|
||||
parseerror(parser, "C-style function syntax is not allowed in -std=qcc");
|
||||
|
@ -2357,6 +2402,7 @@ static ast_value *parse_typename(parser_t *parser, ast_value **storebase)
|
|||
if (!var) {
|
||||
if (name)
|
||||
mem_d((void*)name);
|
||||
ast_delete(var);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue