]> git.xonotic.org Git - xonotic/gmqcc.git/blobdiff - parser.c
Made intrinsics seperate from the parser.
[xonotic/gmqcc.git] / parser.c
index fc2ef35de879a5cb58d49793984650ff6332f3c5..9b7c75db79a99bebd7699809c6c90ca44e973d6d 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -29,8 +29,6 @@
 #define PARSER_HT_SIZE    512
 #define TYPEDEF_HT_SIZE   512
 
-static ast_expression * const intrinsic_debug_typestring = (ast_expression*)0x1;
-
 static void parser_enterblock(parser_t *parser);
 static bool parser_leaveblock(parser_t *parser);
 static void parser_addlocal(parser_t *parser, const char *name, ast_expression *e);
@@ -111,7 +109,7 @@ static ast_expression* parser_find_label(parser_t *parser, const char *name)
     return NULL;
 }
 
-static ast_expression* parser_find_global(parser_t *parser, const char *name)
+ast_expression* parser_find_global(parser_t *parser, const char *name)
 {
     ast_expression *var = (ast_expression*)util_htget(parser->aliases, parser_tokval(parser));
     if (var)
@@ -173,9 +171,6 @@ static ast_value* parser_find_typedef(parser_t *parser, const char *name, size_t
     return NULL;
 }
 
-/* include intrinsics */
-#include "intrin.h"
-
 typedef struct
 {
     size_t etype; /* 0 = expression, others are operators */
@@ -353,11 +348,6 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy)
 #define NotSameType(T) \
              (exprs[0]->vtype != exprs[1]->vtype || \
               exprs[0]->vtype != T)
-
-    /* preform any constant folding on operator usage first */
-    /*if ((out = fold_op(parser->fold, op, exprs)))*/
-    /*goto complete;*/
-
     switch (op->id)
     {
         default:
@@ -587,6 +577,7 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy)
                 }
             }
             break;
+
         case opid1('/'):
             if (exprs[1]->vtype != TYPE_FLOAT) {
                 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
@@ -595,21 +586,9 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy)
                 return false;
             }
             if (!(out = fold_op(parser->fold, op, exprs))) {
-                if (exprs[0]->vtype == TYPE_FLOAT) 
+                if (exprs[0]->vtype == TYPE_FLOAT)
                     out = (ast_expression*)ast_binary_new(ctx, INSTR_DIV_F, exprs[0], exprs[1]);
-                else if (exprs[0]->vtype == TYPE_VECTOR) {
-                    out = (ast_expression*)ast_binary_new (
-                                ctx,
-                                INSTR_MUL_VF,
-                                exprs[0],
-                                (ast_expression*)ast_binary_new(
-                                    ctx,
-                                    INSTR_DIV_F,
-                                    (ast_expression*)parser->fold->imm_float[1],
-                                    exprs[1]
-                                )
-                    );
-                } else {
+                else {
                     ast_type_to_string(exprs[0], ty1, sizeof(ty1));
                     ast_type_to_string(exprs[1], ty2, sizeof(ty2));
                     compile_error(ctx, "invalid types used in expression: cannot divide types %s and %s", ty1, ty2);
@@ -626,7 +605,7 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy)
                 return false;
             } else if (!(out = fold_op(parser->fold, op, exprs))) {
                 /* generate a call to __builtin_mod */
-                ast_expression *mod  = intrin_func(parser, "mod");
+                ast_expression *mod  = intrin_func(parser->intrin, "mod");
                 ast_call       *call = NULL;
                 if (!mod) return false; /* can return null for missing floor */
 
@@ -828,7 +807,7 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy)
             }
             
             if (!(out = fold_op(parser->fold, op, exprs))) {
-                ast_call *gencall = ast_call_new(parser_ctx(parser), intrin_func(parser, "pow"));
+                ast_call *gencall = ast_call_new(parser_ctx(parser), intrin_func(parser->intrin, "pow"));
                 vec_push(gencall->params, exprs[0]);
                 vec_push(gencall->params, exprs[1]);
                 out = (ast_expression*)gencall;
@@ -1172,7 +1151,6 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy)
             break;
     }
 #undef NotSameType
-/*complete:*/
     if (!out) {
         compile_error(ctx, "failed to apply operator %s", op->op);
         return false;
@@ -1214,9 +1192,11 @@ static bool parser_close_call(parser_t *parser, shunt *sy)
         return false;
     }
 
-    fun = sy->out[fid].out;
-
-    if (fun == intrinsic_debug_typestring) {
+    /* 
+     * TODO handle this at the intrinsic level with an ast_intrinsic
+     * node and codegen.
+     */
+    if ((fun = sy->out[fid].out) == intrin_debug_typestring(parser->intrin)) {
         char ty[1024];
         if (fid+2 != vec_size(sy->out) ||
             vec_last(sy->out).block)
@@ -1231,8 +1211,8 @@ static bool parser_close_call(parser_t *parser, shunt *sy)
         vec_shrinkby(sy->out, 1);
         return true;
     }
-
     call = ast_call_new(sy->ops[vec_size(sy->ops)].ctx, fun);
+
     if (!call)
         return false;
 
@@ -1548,9 +1528,7 @@ static bool parse_sya_operand(parser_t *parser, shunt *sy, bool with_labels)
         /* a_vector.{x,y,z} */
         if (!vec_size(sy->ops) ||
             !vec_last(sy->ops).etype ||
-            operators[vec_last(sy->ops).etype-1].id != opid1('.') ||
-            (prev >= intrinsic_debug_typestring &&
-             prev <= intrinsic_debug_typestring))
+            operators[vec_last(sy->ops).etype-1].id != opid1('.'))
         {
             /* When adding more intrinsics, fix the above condition */
             prev = NULL;
@@ -1574,16 +1552,13 @@ static bool parse_sya_operand(parser_t *parser, shunt *sy, bool with_labels)
         if (!var && !strcmp(parser_tokval(parser), "__FUNC__"))
             var = (ast_expression*)fold_constgen_string(parser->fold, parser->function->name, false);
         if (!var) {
-            /* intrinsics */
-            if (!strcmp(parser_tokval(parser), "__builtin_debug_typestring")) {
-                var = (ast_expression*)intrinsic_debug_typestring;
-            }
-            /* now we try for the real intrinsic hashtable. If the string
+            /* 
+             * now we try for the real intrinsic hashtable. If the string
              * begins with __builtin, we simply skip past it, otherwise we
              * use the identifier as is.
              */
-            else if (!strncmp(parser_tokval(parser), "__builtin_", 10)) {
-                var = intrin_func(parser, parser_tokval(parser) + 10 /* skip __builtin */);
+            if (!strncmp(parser_tokval(parser), "__builtin_", 10)) {
+                var = intrin_func(parser->intrin, parser_tokval(parser));
             }
 
             if (!var) {
@@ -5890,7 +5865,8 @@ parser_t *parser_create()
         parser->reserved_version = NULL;
     }
 
-    parser->fold = fold_init(parser);
+    parser->fold   = fold_init  (parser);
+    parser->intrin = intrin_init(parser);
     return parser;
 }
 
@@ -6008,9 +5984,9 @@ static void parser_remove_ast(parser_t *parser)
     if (parser->reserved_version)
         ast_value_delete(parser->reserved_version);
 
-    util_htdel(parser->aliases);
-    intrin_intrinsics_destroy(parser);
+    util_htdel(parser->aliases); 
     fold_cleanup(parser->fold);
+    intrin_cleanup(parser->intrin);
 }
 
 void parser_cleanup(parser_t *parser)