]> git.xonotic.org Git - xonotic/gmqcc.git/commitdiff
ast_binary_codegen, ast_function_label (no I don't like sprintf...)
authorWolfgang (Blub) Bumiller <blub@speed.at>
Wed, 2 May 2012 21:11:39 +0000 (23:11 +0200)
committerWolfgang (Blub) Bumiller <blub@speed.at>
Wed, 2 May 2012 21:11:39 +0000 (23:11 +0200)
ast.c
ast.h

diff --git a/ast.c b/ast.c
index 7fa27f5b3c4188a6897749987de79456b5fc14d2..22fbe7a558b79af11beadaebe605ebca4acac15c 100644 (file)
--- a/ast.c
+++ b/ast.c
@@ -266,6 +266,8 @@ ast_function* ast_function_new(lex_ctx ctx, const char *name, ast_value *vtype)
     self->name = name ? util_strdup(name) : NULL;
     MEM_VECTOR_INIT(self, blocks);
 
+    self->labelcount = 0;
+
     self->ir_func = NULL;
     self->curblock = NULL;
 
@@ -297,6 +299,13 @@ void ast_function_delete(ast_function *self)
     mem_d(self);
 }
 
+const char* ast_function_label(ast_function *self)
+{
+    size_t id = (self->labelcount++);
+    sprintf(self->labelbuf, "label%8u", (unsigned int)id);
+    return self->labelbuf;
+}
+
 /*********************************************************************/
 /* AST codegen part
  * by convention you must never pass NULL to the 'ir_value **out'
@@ -517,7 +526,30 @@ bool ast_store_codegen(ast_store *self, ast_function *func, bool lvalue, ir_valu
 
 bool ast_binary_codegen(ast_binary *self, ast_function *func, bool lvalue, ir_value **out)
 {
-    return false;
+    ast_expression_codegen *cgen;
+    ir_value *left, *right;
+
+    /* In the context of a binary operation, we can disregard
+     * the lvalue flag.
+     */
+     (void)lvalue;
+
+    cgen = self->left->expression.codegen;
+    /* lvalue! */
+    if (!(*cgen)((ast_expression*)(self->left), func, false, &left))
+        return false;
+
+    cgen = self->right->expression.codegen;
+    /* rvalue! */
+    if (!(*cgen)((ast_expression*)(self->right), func, false, &right))
+        return false;
+
+    *out = ir_block_create_binop(func->curblock, ast_function_label(func),
+                                 self->op, left, right);
+    if (!*out)
+        return false;
+
+    return true;
 }
 
 bool ast_entfield_codegen(ast_entfield *self, ast_function *func, bool lvalue, ir_value **out)
diff --git a/ast.h b/ast.h
index 9609a08d678600d2a44fe4b741203c40e5da0b4f..b2d906e6a0c9bdf3a515d311ea51ba8bc1eeab9f 100644 (file)
--- a/ast.h
+++ b/ast.h
@@ -276,11 +276,24 @@ struct ast_function_s
     ir_function *ir_func;
     ir_block    *curblock;
 
+    size_t       labelcount;
+    /* in order for thread safety - for the optional
+     * channel abesed multithreading... keeping a buffer
+     * here to use in ast_function_label.
+     */
+    char         labelbuf[64];
+
     MEM_VECTOR_MAKE(ast_block*, blocks);
 };
 ast_function* ast_function_new(lex_ctx ctx, const char *name, ast_value *vtype);
 /* This will NOT delete the underlying ast_value */
 void ast_function_delete(ast_function*);
+/* TODO: for better readability in dumps, this should take some kind of
+ * value prefix...
+ * For "optimized" builds this can just keep returning "foo"...
+ * or whatever...
+ */
+const char* ast_function_label(ast_function*);
 
 MEM_VECTOR_PROTO(ast_function, ast_block*, blocks);