]> de.git.xonotic.org Git - xonotic/gmqcc.git/commitdiff
TYPE_NIL, builder->nil, ast_value_codegen for TYPE_NIL
authorWolfgang Bumiller <blub@speed.at>
Fri, 28 Dec 2012 17:05:28 +0000 (18:05 +0100)
committerWolfgang Bumiller <blub@speed.at>
Fri, 28 Dec 2012 17:05:28 +0000 (18:05 +0100)
ast.c
gmqcc.h
ir.c
ir.h

diff --git a/ast.c b/ast.c
index 3bb5bf8b8367be6f8ed6ca981f017c13da20f71d..89d738cd5d40cc060e9236f41f168275b7ae167a 100644 (file)
--- a/ast.c
+++ b/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...
diff --git a/gmqcc.h b/gmqcc.h
index 2ed331fe30b28682064b1b6762f1838854f39c0c..27d32f77acd2341ff23d3613a298b03f46a232b0 100644 (file)
--- a/gmqcc.h
+++ b/gmqcc.h
@@ -392,6 +392,8 @@ enum {
     TYPE_UNION    ,
     TYPE_ARRAY    ,
 
+    TYPE_NIL      , /* it's its own type / untyped */
+
     TYPE_COUNT
 };
 
diff --git a/ir.c b/ir.c
index 37f68f940660818d4632c2b5f9d12e4ea8ab5709..87ad615a4b77ba8d4238706a26a42b27aba79743 100644 (file)
--- a/ir.c
+++ b/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);
diff --git a/ir.h b/ir.h
index 9f8e1fa4e9f0aec9657c88865aede0d3f42344e8..4a1778e9d11d0b9e011745546802560e1feb10a2 100644 (file)
--- a/ir.h
+++ b/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);