]> git.rm.cloudns.org Git - xonotic/gmqcc.git/commitdiff
Allow string concatenation in the parser as well, for now only for immediate strings...
authorWolfgang Bumiller <wry.git@bumiller.com>
Wed, 24 Apr 2013 14:07:31 +0000 (16:07 +0200)
committerWolfgang Bumiller <wry.git@bumiller.com>
Wed, 24 Apr 2013 15:27:04 +0000 (17:27 +0200)
ast.c
ast.h
parser.c
tests/predef_func.qc
tests/predef_func.tmpl
tests/predef_func_concat.tmpl [new file with mode: 0644]

diff --git a/ast.c b/ast.c
index aa7050914fb5475219664cb51dd82cc5b6f58dae..3e5d304d1e53c6ba9666f56ddfd6aafdc4bc94c8 100755 (executable)
--- a/ast.c
+++ b/ast.c
@@ -316,6 +316,7 @@ ast_value* ast_value_new(lex_ctx ctx, const char *name, int t)
     self->isfield  = false;
     self->cvq      = CV_NONE;
     self->hasvalue = false;
+    self->isimm    = false;
     self->uses    = 0;
     memset(&self->constval, 0, sizeof(self->constval));
 
diff --git a/ast.h b/ast.h
index 14d38d886458efb76207fe878b2a2d46aacee1f0..bae07db39ec85c13481a10ecec947ece7f0c7ce8 100755 (executable)
--- a/ast.h
+++ b/ast.h
@@ -177,6 +177,7 @@ struct ast_value_s
 
     int  cvq;     /* const/var qualifier */
     bool isfield; /* this declares a field */
+    bool isimm;   /* an immediate, not just const */
     bool hasvalue;
     union {
         double        vfloat;
index d480e1ffd6598ee983a7474027a03cb90060aa50..a19db282629e128dd0b9de61a150ba3385619e0b 100755 (executable)
--- a/parser.c
+++ b/parser.c
@@ -217,6 +217,7 @@ static ast_value* parser_const_float(parser_t *parser, double d)
     out = ast_value_new(ctx, "#IMMEDIATE", TYPE_FLOAT);
     out->cvq      = CV_CONST;
     out->hasvalue = true;
+    out->isimm    = true;
     out->constval.vfloat = d;
     vec_push(parser->imm_float, out);
     return out;
@@ -279,6 +280,7 @@ static ast_value* parser_const_string(parser_t *parser, const char *str, bool do
         out = ast_value_new(parser_ctx(parser), "#IMMEDIATE", TYPE_STRING);
     out->cvq      = CV_CONST;
     out->hasvalue = true;
+    out->isimm    = true;
     out->constval.vstring = parser_strdup(str);
     vec_push(parser->imm_string, out);
     util_htseth(parser->ht_imm_string, str, hash, out);
@@ -296,6 +298,7 @@ static ast_value* parser_const_vector(parser_t *parser, vector v)
     out = ast_value_new(parser_ctx(parser), "#IMMEDIATE", TYPE_VECTOR);
     out->cvq      = CV_CONST;
     out->hasvalue = true;
+    out->isimm    = true;
     out->constval.vvec = v;
     vec_push(parser->imm_vector, out);
     return out;
@@ -2182,8 +2185,27 @@ static ast_expression* parse_expression_leave(parser_t *parser, bool stopatcomma
             wantop = true;
         }
         else {
-            parseerror(parser, "expected operator or end of statement");
-            goto onerr;
+            /* in this case we might want to allow constant string concatenation */
+            bool concatenated = false;
+            if (parser->tok == TOKEN_STRINGCONST && vec_size(sy.out)) {
+                ast_expression *lexpr = vec_last(sy.out).out;
+                if (ast_istype(lexpr, ast_value)) {
+                    ast_value *last = (ast_value*)lexpr;
+                    if (last->isimm == true && last->cvq == CV_CONST &&
+                        last->hasvalue && last->expression.vtype == TYPE_STRING)
+                    {
+                        char *newstr = NULL;
+                        util_asprintf(&newstr, "%s%s", last->constval.vstring, parser_tokval(parser));
+                        vec_last(sy.out).out = (ast_expression*)parser_const_string(parser, newstr, false);
+                        mem_d(newstr);
+                        concatenated = true;
+                    }
+                }
+            }
+            if (!concatenated) {
+                parseerror(parser, "expected operator or end of statement");
+                goto onerr;
+            }
         }
 
         if (!parser_next(parser)) {
index ec17cd07d65469e6bd1f89d075ed56d9b092ef3a..e8c260bd3f28efc0769e935ecd071e1ef66bb41e 100644 (file)
@@ -1,3 +1,9 @@
 void main() {
+#ifdef SIMPLE
     print(__FUNC__, "\n");
+#elifdef CONCATENATED
+    print(__FUNC__ "\n");
+#else
+#   error this is wrong
+#endif
 }
index 694413810c88d02d502aeea65191b1dd7655680f..ef9f8d40c52d8d329f5b288a719345473fc1132a 100644 (file)
@@ -1,5 +1,5 @@
 I: predef_func.qc
 D: simple __FUNC__ case
 T: -execute
-C: -std=fte -fftepp-predefs
+C: -std=fteqcc -DSIMPLE
 M: main
diff --git a/tests/predef_func_concat.tmpl b/tests/predef_func_concat.tmpl
new file mode 100644 (file)
index 0000000..bb1bb43
--- /dev/null
@@ -0,0 +1,5 @@
+I: predef_func.qc
+D: concatenated __FUNC__ case
+T: -execute
+C: -std=fteqcc -DCONCATENATED
+M: main