From: Dale Weiler Date: Wed, 14 Aug 2013 03:03:49 +0000 (+0000) Subject: Some intrinsic cleanups X-Git-Tag: v0.3.0~33 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=216330a7e27ad50d67b12ca76ba00f1c557913d7;p=xonotic%2Fgmqcc.git Some intrinsic cleanups --- diff --git a/ast.h b/ast.h index ca323a2..d3dfdb2 100644 --- a/ast.h +++ b/ast.h @@ -52,6 +52,7 @@ typedef struct ast_switch_s ast_switch; typedef struct ast_label_s ast_label; typedef struct ast_goto_s ast_goto; typedef struct ast_argpipe_s ast_argpipe; +typedef struct ast_intrinsic_s ast_intrinsic; enum { TYPE_ast_node, /* 0 */ @@ -75,7 +76,8 @@ enum { TYPE_ast_switch, /* 18 */ TYPE_ast_label, /* 19 */ TYPE_ast_goto, /* 20 */ - TYPE_ast_argpipe /* 21 */ + TYPE_ast_argpipe, /* 21 */ + TYPE_ast_intrinsic /* 22 */ }; #define ast_istype(x, t) ( ((ast_node*)x)->nodetype == (TYPE_##t) ) @@ -176,6 +178,7 @@ typedef union { ast_function *vfunc; ast_value *vfield; } basic_value_t; + struct ast_value_s { ast_expression expression; @@ -339,7 +342,7 @@ ast_entfield* ast_entfield_new_force(lex_ctx_t ctx, ast_expression *entity, ast_ */ struct ast_member_s { - ast_expression expression; + ast_expression expression; ast_expression *owner; unsigned int field; const char *name; @@ -362,7 +365,7 @@ bool ast_member_set_name(ast_member*, const char *name); */ struct ast_array_index_s { - ast_expression expression; + ast_expression expression; ast_expression *array; ast_expression *index; }; @@ -374,7 +377,7 @@ ast_array_index* ast_array_index_new(lex_ctx_t ctx, ast_expression *array, ast_e */ struct ast_argpipe_s { - ast_expression expression; + ast_expression expression; ast_expression *index; }; ast_argpipe* ast_argpipe_new(lex_ctx_t ctx, ast_expression *index); @@ -386,7 +389,7 @@ ast_argpipe* ast_argpipe_new(lex_ctx_t ctx, ast_expression *index); */ struct ast_store_s { - ast_expression expression; + ast_expression expression; int op; ast_expression *dest; ast_expression *source; @@ -407,7 +410,7 @@ ast_store* ast_store_new(lex_ctx_t ctx, int op, */ struct ast_ifthen_s { - ast_expression expression; + ast_expression expression; ast_expression *cond; /* It's all just 'expressions', since an ast_block is one too. */ ast_expression *on_true; @@ -430,7 +433,7 @@ ast_ifthen* ast_ifthen_new(lex_ctx_t ctx, ast_expression *cond, ast_expression * */ struct ast_ternary_s { - ast_expression expression; + ast_expression expression; ast_expression *cond; /* It's all just 'expressions', since an ast_block is one too. */ ast_expression *on_true; @@ -463,7 +466,7 @@ continue: // a 'continue' will jump here */ struct ast_loop_s { - ast_expression expression; + ast_expression expression; ast_expression *initexpr; ast_expression *precond; ast_expression *postcond; @@ -489,9 +492,9 @@ ast_loop* ast_loop_new(lex_ctx_t ctx, */ struct ast_breakcont_s { - ast_expression expression; - bool is_continue; - unsigned int levels; + ast_expression expression; + bool is_continue; + unsigned int levels; }; ast_breakcont* ast_breakcont_new(lex_ctx_t ctx, bool iscont, unsigned int levels); @@ -511,7 +514,7 @@ typedef struct { } ast_switch_case; struct ast_switch_s { - ast_expression expression; + ast_expression expression; ast_expression *operand; ast_switch_case *cases; @@ -525,12 +528,13 @@ ast_switch* ast_switch_new(lex_ctx_t ctx, ast_expression *op); */ struct ast_label_s { - ast_expression expression; - const char *name; - ir_block *irblock; - ast_goto **gotos; + ast_expression expression; + const char *name; + ir_block *irblock; + ast_goto **gotos; + /* means it has not yet been defined */ - bool undefined; + bool undefined; }; ast_label* ast_label_new(lex_ctx_t ctx, const char *name, bool undefined); @@ -541,10 +545,10 @@ ast_label* ast_label_new(lex_ctx_t ctx, const char *name, bool undefined); */ struct ast_goto_s { - ast_expression expression; - const char *name; - ast_label *target; - ir_block *irblock_from; + ast_expression expression; + const char *name; + ast_label *target; + ir_block *irblock_from; }; ast_goto* ast_goto_new(lex_ctx_t ctx, const char *name); @@ -562,9 +566,9 @@ void ast_goto_set_label(ast_goto*, ast_label*); */ struct ast_call_s { - ast_expression expression; + ast_expression expression; ast_expression *func; - ast_expression* *params; + ast_expression **params; ast_expression *va_count; }; ast_call* ast_call_new(lex_ctx_t ctx, @@ -576,7 +580,7 @@ bool ast_call_check_types(ast_call*, ast_expression *this_func_va_type); */ struct ast_block_s { - ast_expression expression; + ast_expression expression; ast_value* *locals; ast_expression* *exprs; @@ -601,7 +605,7 @@ bool GMQCC_WARN ast_block_add_expr(ast_block*, ast_expression*); */ struct ast_function_s { - ast_node node; + ast_node node; ast_value *vtype; const char *name; diff --git a/conout.c b/conout.c index 7fb50b9..aedff4d 100644 --- a/conout.c +++ b/conout.c @@ -198,9 +198,9 @@ static con_t console; */ static void con_enablecolor(void) { if (console.handle_err == stderr || console.handle_err == stdout) - console.color_err = true; /*!!(isatty(STDERR_FILENO));*/ + console.color_err = !!(isatty(STDERR_FILENO)); if (console.handle_out == stderr || console.handle_out == stdout) - console.color_out = true; /*!!(isatty(STDOUT_FILENO));*/ + console.color_out = !!(isatty(STDOUT_FILENO)); } /* diff --git a/intrin.h b/intrin.h index 1503d60..0c0e861 100644 --- a/intrin.h +++ b/intrin.h @@ -324,7 +324,7 @@ static ast_expression *intrin_isnan(parser_t *parser) { static ast_value *value = NULL; if (!value) { - ast_value *arg1 = ast_value_new (parser_ctx(parser), "x", TYPE_FLOAT); + ast_value *arg1 = ast_value_new (parser_ctx(parser), "x", TYPE_FLOAT); ast_value *local = ast_value_new (parser_ctx(parser), "local", TYPE_FLOAT); ast_block *body = ast_block_new (parser_ctx(parser)); ast_function *func = NULL; @@ -363,21 +363,23 @@ static ast_expression *intrin_isnan(parser_t *parser) { return (ast_expression*)value; } +static ast_expression *intrin_debug_typestring(parser_t *parser) { + (void)parser; + return (ast_expression*)0x1; +} + static intrin_t intrinsics[] = { - {&intrin_exp, "__builtin_exp", "exp"}, - {&intrin_mod, "__builtin_mod", "mod"}, - {&intrin_pow, "__builtin_pow", "pow"}, - {&intrin_isnan, "__builtin_isnan", "isnan"} + {&intrin_exp, "__builtin_exp", "exp"}, + {&intrin_mod, "__builtin_mod", "mod"}, + {&intrin_pow, "__builtin_pow", "pow"}, + {&intrin_isnan, "__builtin_isnan", "isnan"}, + {&intrin_debug_typestring, "__builtin_debug_typestring", ""} }; void intrin_intrinsics_destroy(parser_t *parser) { /*size_t i;*/ (void)parser; util_htdel(intrin_intrinsics()); -#if 0 - for (i = 0; i < sizeof(intrinsics)/sizeof(intrin_t); i++) - ast_value_delete( (ast_value*) intrinsics[i].intrin(parser)); -#endif } @@ -389,7 +391,7 @@ static ast_expression *intrin_func(parser_t *parser, const char *name) { /* register the intrinsics in the hashtable for O(1) lookup */ if (!init) { for (i = 0; i < sizeof(intrinsics)/sizeof(*intrinsics); i++) - util_htset(intrin_intrinsics(), intrinsics[i].alias, &intrinsics[i]); + util_htset(intrin_intrinsics(), intrinsics[i].name, &intrinsics[i]); init = true; /* only once */ } @@ -411,6 +413,13 @@ static ast_expression *intrin_func(parser_t *parser, const char *name) { return ((intrin_t*)find)->intrin(parser); } + /* + * check aliases now to see if there is an implementation of it. + */ + for (i = 0; i < sizeof(intrinsics) / sizeof(*intrinsics); i++) + if (!strcmp(intrinsics[i].alias, name)) + return intrinsics[i].intrin(parser); + parseerror(parser, "need function: `%s` compiler depends on it", name); return NULL; } diff --git a/parser.c b/parser.c index faa5604..bbca3cf 100644 --- 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); @@ -1197,9 +1195,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)) { char ty[1024]; if (fid+2 != vec_size(sy->out) || vec_last(sy->out).block) @@ -1214,8 +1214,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; @@ -1531,9 +1531,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; @@ -1557,16 +1555,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, parser_tokval(parser)); } if (!var) {