]> git.xonotic.org Git - xonotic/gmqcc.git/blobdiff - parser.c
remove ast.h-include from lexer.h to parser.c...
[xonotic/gmqcc.git] / parser.c
index edf4f2a5306273591aa41fe68603679b39b608fe..425668225f2ee37c21be88d8c1ab4bbf40bc17b1 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012
+ * Copyright (C) 2012, 2013
  *     Wolfgang Bumiller
  *     Dale Weiler
  * 
@@ -26,6 +26,7 @@
 
 #include "gmqcc.h"
 #include "lexer.h"
+#include "ast.h"
 
 /* beginning of locals */
 #define PARSER_HT_LOCALS  2
@@ -983,14 +984,14 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy)
                 return false;
             }
             vec_pop(parser->pot);
-            if (exprs[1]->expression.vtype != exprs[2]->expression.vtype) {
+            if (!ast_compare_type(exprs[1], exprs[2])) {
                 ast_type_to_string(exprs[1], ty1, sizeof(ty1));
                 ast_type_to_string(exprs[2], ty2, sizeof(ty2));
                 parseerror(parser, "operands of ternary expression must have the same type, got %s and %s", ty1, ty2);
                 return false;
             }
             if (CanConstFold1(exprs[0]))
-                out = (ConstF(0) ? exprs[1] : exprs[2]);
+                out = (immediate_is_true(ctx, asvalue[0]) ? exprs[1] : exprs[2]);
             else
                 out = (ast_expression*)ast_ternary_new(ctx, exprs[0], exprs[1], exprs[2]);
             break;
@@ -1403,35 +1404,18 @@ static bool parser_close_call(parser_t *parser, shunt *sy)
               vec_size(fun->expression.params) < paramcount))
         {
             const char *fewmany = (vec_size(fun->expression.params) > paramcount) ? "few" : "many";
-            if (opts.standard == COMPILER_GMQCC)
-            {
-                if (fval)
-                    parseerror(parser, "too %s parameters for call to %s: expected %i, got %i\n"
-                               " -> `%s` has been declared here: %s:%i",
-                               fewmany, fval->name, (int)vec_size(fun->expression.params), (int)paramcount,
-                               fval->name, ast_ctx(fun).file, (int)ast_ctx(fun).line);
-                else
-                    parseerror(parser, "too %s parameters for function call: expected %i, got %i\n"
-                               " -> it has been declared here: %s:%i",
-                               fewmany, (int)vec_size(fun->expression.params), (int)paramcount,
-                               ast_ctx(fun).file, (int)ast_ctx(fun).line);
-                return false;
-            }
+            if (fval)
+                return !parsewarning(parser, WARN_INVALID_PARAMETER_COUNT,
+                                     "too %s parameters for call to %s: expected %i, got %i\n"
+                                     " -> `%s` has been declared here: %s:%i",
+                                     fewmany, fval->name, (int)vec_size(fun->expression.params), (int)paramcount,
+                                     fval->name, ast_ctx(fun).file, (int)ast_ctx(fun).line);
             else
-            {
-                if (fval)
-                    return !parsewarning(parser, WARN_TOO_FEW_PARAMETERS,
-                                         "too %s parameters for call to %s: expected %i, got %i\n"
-                                         " -> `%s` has been declared here: %s:%i",
-                                         fewmany, fval->name, (int)vec_size(fun->expression.params), (int)paramcount,
-                                         fval->name, ast_ctx(fun).file, (int)ast_ctx(fun).line);
-                else
-                    return !parsewarning(parser, WARN_TOO_FEW_PARAMETERS,
-                                         "too %s parameters for function call: expected %i, got %i\n"
-                                         " -> it has been declared here: %s:%i",
-                                         fewmany, (int)vec_size(fun->expression.params), (int)paramcount,
-                                         ast_ctx(fun).file, (int)ast_ctx(fun).line);
-            }
+                return !parsewarning(parser, WARN_INVALID_PARAMETER_COUNT,
+                                     "too %s parameters for function call: expected %i, got %i\n"
+                                     " -> it has been declared here: %s:%i",
+                                     fewmany, (int)vec_size(fun->expression.params), (int)paramcount,
+                                     ast_ctx(fun).file, (int)ast_ctx(fun).line);
         }
     }
 
@@ -2429,11 +2413,13 @@ static bool parse_for_go(parser_t *parser, ast_block *block, ast_expression **ou
         typevar = parser_find_typedef(parser, parser_tokval(parser), 0);
 
     if (typevar || parser->tok == TOKEN_TYPENAME) {
+#if 0
         if (opts.standard != COMPILER_GMQCC) {
             if (parsewarning(parser, WARN_EXTENSIONS,
                              "current standard does not allow variable declarations in for-loop initializers"))
                 goto onerr;
         }
+#endif
         if (!parse_variable(parser, block, true, CV_VAR, typevar, false, false, 0, NULL))
             goto onerr;
     }
@@ -2534,7 +2520,9 @@ static bool parse_return(parser_t *parser, ast_block *block, ast_expression **ou
         if (!exp)
             return false;
 
-        if (exp->expression.vtype != expected->expression.next->expression.vtype) {
+        if (exp->expression.vtype != TYPE_NIL &&
+            exp->expression.vtype != expected->expression.next->expression.vtype)
+        {
             parseerror(parser, "return with invalid expression");
         }
 
@@ -2547,10 +2535,7 @@ static bool parse_return(parser_t *parser, ast_block *block, ast_expression **ou
         if (!parser_next(parser))
             parseerror(parser, "parse error");
         if (expected->expression.next->expression.vtype != TYPE_VOID) {
-            if (opts.standard != COMPILER_GMQCC)
-                (void)!parsewarning(parser, WARN_MISSING_RETURN_VALUES, "return without value");
-            else
-                parseerror(parser, "return without value");
+            (void)!parsewarning(parser, WARN_MISSING_RETURN_VALUES, "return without value");
         }
         ret = ast_return_new(ctx, NULL);
     }
@@ -4577,35 +4562,28 @@ static bool parse_variable(parser_t *parser, ast_block *localblock, bool nofield
                 {
                     /* other globals */
                     if (old) {
-                        if (opts.standard == COMPILER_GMQCC) {
-                            parseerror(parser, "global `%s` already declared here: %s:%i",
-                                       var->name, ast_ctx(old).file, ast_ctx(old).line);
+                        if (parsewarning(parser, WARN_DOUBLE_DECLARATION,
+                                         "global `%s` already declared here: %s:%i",
+                                         var->name, ast_ctx(old).file, ast_ctx(old).line))
+                        {
                             retval = false;
                             goto cleanup;
-                        } else {
-                            if (parsewarning(parser, WARN_DOUBLE_DECLARATION,
-                                             "global `%s` already declared here: %s:%i",
-                                             var->name, ast_ctx(old).file, ast_ctx(old).line))
-                            {
-                                retval = false;
-                                goto cleanup;
-                            }
-                            proto = (ast_value*)old;
-                            if (!ast_istype(old, ast_value)) {
-                                parseerror(parser, "internal error: not an ast_value");
-                                retval = false;
-                                proto = NULL;
-                                goto cleanup;
-                            }
-                            if (!parser_check_qualifiers(parser, var, proto)) {
-                                retval = false;
-                                proto = NULL;
-                                goto cleanup;
-                            }
-                            proto->expression.flags |= var->expression.flags;
-                            ast_delete(var);
-                            var = proto;
                         }
+                        proto = (ast_value*)old;
+                        if (!ast_istype(old, ast_value)) {
+                            parseerror(parser, "internal error: not an ast_value");
+                            retval = false;
+                            proto = NULL;
+                            goto cleanup;
+                        }
+                        if (!parser_check_qualifiers(parser, var, proto)) {
+                            retval = false;
+                            proto = NULL;
+                            goto cleanup;
+                        }
+                        proto->expression.flags |= var->expression.flags;
+                        ast_delete(var);
+                        var = proto;
                     }
                     if (opts.standard == COMPILER_QCC &&
                         (old = parser_find_field(parser, var->name)))
@@ -4915,8 +4893,7 @@ skipvar:
                 }
                 else
                 {
-                    if (opts.standard != COMPILER_GMQCC &&
-                        !OPTS_FLAG(INITIALIZED_NONCONSTANTS) &&
+                    if (!OPTS_FLAG(INITIALIZED_NONCONSTANTS) &&
                         qualifier != CV_VAR)
                     {
                         var->cvq = CV_CONST;