mirror of
https://github.com/DarkPlacesEngine/gmqcc.git
synced 2025-03-22 18:51:24 +00:00
TYPE_NIL, builder->nil, ast_value_codegen for TYPE_NIL
This commit is contained in:
parent
3f88b5fa14
commit
40b2a26e89
4 changed files with 34 additions and 2 deletions
15
ast.c
15
ast.c
|
@ -1101,6 +1101,10 @@ bool ast_value_codegen(ast_value *self, ast_function *func, bool lvalue, ir_valu
|
|||
{
|
||||
(void)func;
|
||||
(void)lvalue;
|
||||
if (self->expression.vtype == TYPE_NIL) {
|
||||
*out = func->ir_func->owner->nil;
|
||||
return true;
|
||||
}
|
||||
/* NOTE: This is the codegen for a variable used in an expression.
|
||||
* It is not the codegen to generate the value. For this purpose,
|
||||
* ast_local_codegen and ast_global_codegen are to be used before this
|
||||
|
@ -1122,6 +1126,11 @@ bool ast_global_codegen(ast_value *self, ir_builder *ir, bool isfield)
|
|||
{
|
||||
ir_value *v = NULL;
|
||||
|
||||
if (self->expression.vtype == TYPE_NIL) {
|
||||
compile_error(ast_ctx(self), "internal error: trying to generate a variable of TYPE_NIL");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (self->hasvalue && self->expression.vtype == TYPE_FUNCTION)
|
||||
{
|
||||
ir_function *func = ir_builder_create_function(ir, self->name, self->expression.next->expression.vtype);
|
||||
|
@ -1316,6 +1325,12 @@ error: /* clean up */
|
|||
bool ast_local_codegen(ast_value *self, ir_function *func, bool param)
|
||||
{
|
||||
ir_value *v = NULL;
|
||||
|
||||
if (self->expression.vtype == TYPE_NIL) {
|
||||
compile_error(ast_ctx(self), "internal error: trying to generate a variable of TYPE_NIL");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (self->hasvalue && self->expression.vtype == TYPE_FUNCTION)
|
||||
{
|
||||
/* Do we allow local functions? I think not...
|
||||
|
|
2
gmqcc.h
2
gmqcc.h
|
@ -392,6 +392,8 @@ enum {
|
|||
TYPE_UNION ,
|
||||
TYPE_ARRAY ,
|
||||
|
||||
TYPE_NIL , /* it's its own type / untyped */
|
||||
|
||||
TYPE_COUNT
|
||||
};
|
||||
|
||||
|
|
15
ir.c
15
ir.c
|
@ -42,7 +42,9 @@ const char *type_name[TYPE_COUNT] = {
|
|||
"variant",
|
||||
"struct",
|
||||
"union",
|
||||
"array"
|
||||
"array",
|
||||
|
||||
"nil"
|
||||
};
|
||||
|
||||
size_t type_sizeof_[TYPE_COUNT] = {
|
||||
|
@ -59,6 +61,7 @@ size_t type_sizeof_[TYPE_COUNT] = {
|
|||
0, /* TYPE_STRUCT */
|
||||
0, /* TYPE_UNION */
|
||||
0, /* TYPE_ARRAY */
|
||||
0, /* TYPE_NIL */
|
||||
};
|
||||
|
||||
uint16_t type_store_instr[TYPE_COUNT] = {
|
||||
|
@ -81,6 +84,7 @@ uint16_t type_store_instr[TYPE_COUNT] = {
|
|||
AINSTR_END, /* struct */
|
||||
AINSTR_END, /* union */
|
||||
AINSTR_END, /* array */
|
||||
AINSTR_END, /* nil */
|
||||
};
|
||||
|
||||
uint16_t field_store_instr[TYPE_COUNT] = {
|
||||
|
@ -103,6 +107,7 @@ uint16_t field_store_instr[TYPE_COUNT] = {
|
|||
AINSTR_END, /* struct */
|
||||
AINSTR_END, /* union */
|
||||
AINSTR_END, /* array */
|
||||
AINSTR_END, /* nil */
|
||||
};
|
||||
|
||||
uint16_t type_storep_instr[TYPE_COUNT] = {
|
||||
|
@ -125,6 +130,7 @@ uint16_t type_storep_instr[TYPE_COUNT] = {
|
|||
AINSTR_END, /* struct */
|
||||
AINSTR_END, /* union */
|
||||
AINSTR_END, /* array */
|
||||
AINSTR_END, /* nil */
|
||||
};
|
||||
|
||||
uint16_t type_eq_instr[TYPE_COUNT] = {
|
||||
|
@ -147,6 +153,7 @@ uint16_t type_eq_instr[TYPE_COUNT] = {
|
|||
AINSTR_END, /* struct */
|
||||
AINSTR_END, /* union */
|
||||
AINSTR_END, /* array */
|
||||
AINSTR_END, /* nil */
|
||||
};
|
||||
|
||||
uint16_t type_ne_instr[TYPE_COUNT] = {
|
||||
|
@ -169,6 +176,7 @@ uint16_t type_ne_instr[TYPE_COUNT] = {
|
|||
AINSTR_END, /* struct */
|
||||
AINSTR_END, /* union */
|
||||
AINSTR_END, /* array */
|
||||
AINSTR_END, /* nil */
|
||||
};
|
||||
|
||||
uint16_t type_not_instr[TYPE_COUNT] = {
|
||||
|
@ -191,6 +199,7 @@ uint16_t type_not_instr[TYPE_COUNT] = {
|
|||
AINSTR_END, /* struct */
|
||||
AINSTR_END, /* union */
|
||||
AINSTR_END, /* array */
|
||||
AINSTR_END, /* nil */
|
||||
};
|
||||
|
||||
/* protos */
|
||||
|
@ -300,6 +309,9 @@ ir_builder* ir_builder_new(const char *modulename)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
self->nil = ir_value_var("nil", store_value, TYPE_NIL);
|
||||
self->nil->cvq = CV_CONST;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
@ -325,6 +337,7 @@ void ir_builder_delete(ir_builder* self)
|
|||
for (i = 0; i != vec_size(self->fields); ++i) {
|
||||
ir_value_delete(self->fields[i]);
|
||||
}
|
||||
ir_value_delete(self->nil);
|
||||
vec_free(self->fields);
|
||||
vec_free(self->filenames);
|
||||
vec_free(self->filestrings);
|
||||
|
|
4
ir.h
4
ir.h
|
@ -322,7 +322,9 @@ typedef struct ir_builder_s
|
|||
const char **filenames;
|
||||
qcint *filestrings;
|
||||
/* we cache the #IMMEDIATE string here */
|
||||
qcint str_immediate;
|
||||
qcint str_immediate;
|
||||
/* there should just be this one nil */
|
||||
ir_value *nil;
|
||||
} ir_builder;
|
||||
|
||||
ir_builder* ir_builder_new(const char *modulename);
|
||||
|
|
Loading…
Reference in a new issue