Some intrinsic cleanups

This commit is contained in:
Dale Weiler 2013-08-14 03:03:49 +00:00
parent 90e2e5a4ad
commit 216330a7e2
4 changed files with 61 additions and 53 deletions

54
ast.h
View file

@ -52,6 +52,7 @@ typedef struct ast_switch_s ast_switch;
typedef struct ast_label_s ast_label; typedef struct ast_label_s ast_label;
typedef struct ast_goto_s ast_goto; typedef struct ast_goto_s ast_goto;
typedef struct ast_argpipe_s ast_argpipe; typedef struct ast_argpipe_s ast_argpipe;
typedef struct ast_intrinsic_s ast_intrinsic;
enum { enum {
TYPE_ast_node, /* 0 */ TYPE_ast_node, /* 0 */
@ -75,7 +76,8 @@ enum {
TYPE_ast_switch, /* 18 */ TYPE_ast_switch, /* 18 */
TYPE_ast_label, /* 19 */ TYPE_ast_label, /* 19 */
TYPE_ast_goto, /* 20 */ 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) ) #define ast_istype(x, t) ( ((ast_node*)x)->nodetype == (TYPE_##t) )
@ -176,6 +178,7 @@ typedef union {
ast_function *vfunc; ast_function *vfunc;
ast_value *vfield; ast_value *vfield;
} basic_value_t; } basic_value_t;
struct ast_value_s struct ast_value_s
{ {
ast_expression expression; 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 struct ast_member_s
{ {
ast_expression expression; ast_expression expression;
ast_expression *owner; ast_expression *owner;
unsigned int field; unsigned int field;
const char *name; const char *name;
@ -362,7 +365,7 @@ bool ast_member_set_name(ast_member*, const char *name);
*/ */
struct ast_array_index_s struct ast_array_index_s
{ {
ast_expression expression; ast_expression expression;
ast_expression *array; ast_expression *array;
ast_expression *index; 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 struct ast_argpipe_s
{ {
ast_expression expression; ast_expression expression;
ast_expression *index; ast_expression *index;
}; };
ast_argpipe* ast_argpipe_new(lex_ctx_t ctx, 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 struct ast_store_s
{ {
ast_expression expression; ast_expression expression;
int op; int op;
ast_expression *dest; ast_expression *dest;
ast_expression *source; ast_expression *source;
@ -407,7 +410,7 @@ ast_store* ast_store_new(lex_ctx_t ctx, int op,
*/ */
struct ast_ifthen_s struct ast_ifthen_s
{ {
ast_expression expression; ast_expression expression;
ast_expression *cond; ast_expression *cond;
/* It's all just 'expressions', since an ast_block is one too. */ /* It's all just 'expressions', since an ast_block is one too. */
ast_expression *on_true; 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 struct ast_ternary_s
{ {
ast_expression expression; ast_expression expression;
ast_expression *cond; ast_expression *cond;
/* It's all just 'expressions', since an ast_block is one too. */ /* It's all just 'expressions', since an ast_block is one too. */
ast_expression *on_true; ast_expression *on_true;
@ -463,7 +466,7 @@ continue: // a 'continue' will jump here
*/ */
struct ast_loop_s struct ast_loop_s
{ {
ast_expression expression; ast_expression expression;
ast_expression *initexpr; ast_expression *initexpr;
ast_expression *precond; ast_expression *precond;
ast_expression *postcond; ast_expression *postcond;
@ -489,9 +492,9 @@ ast_loop* ast_loop_new(lex_ctx_t ctx,
*/ */
struct ast_breakcont_s struct ast_breakcont_s
{ {
ast_expression expression; ast_expression expression;
bool is_continue; bool is_continue;
unsigned int levels; unsigned int levels;
}; };
ast_breakcont* ast_breakcont_new(lex_ctx_t ctx, bool iscont, 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; } ast_switch_case;
struct ast_switch_s struct ast_switch_s
{ {
ast_expression expression; ast_expression expression;
ast_expression *operand; ast_expression *operand;
ast_switch_case *cases; ast_switch_case *cases;
@ -525,12 +528,13 @@ ast_switch* ast_switch_new(lex_ctx_t ctx, ast_expression *op);
*/ */
struct ast_label_s struct ast_label_s
{ {
ast_expression expression; ast_expression expression;
const char *name; const char *name;
ir_block *irblock; ir_block *irblock;
ast_goto **gotos; ast_goto **gotos;
/* means it has not yet been defined */ /* 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); 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 struct ast_goto_s
{ {
ast_expression expression; ast_expression expression;
const char *name; const char *name;
ast_label *target; ast_label *target;
ir_block *irblock_from; ir_block *irblock_from;
}; };
ast_goto* ast_goto_new(lex_ctx_t ctx, const char *name); 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 struct ast_call_s
{ {
ast_expression expression; ast_expression expression;
ast_expression *func; ast_expression *func;
ast_expression* *params; ast_expression **params;
ast_expression *va_count; ast_expression *va_count;
}; };
ast_call* ast_call_new(lex_ctx_t ctx, 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 struct ast_block_s
{ {
ast_expression expression; ast_expression expression;
ast_value* *locals; ast_value* *locals;
ast_expression* *exprs; ast_expression* *exprs;
@ -601,7 +605,7 @@ bool GMQCC_WARN ast_block_add_expr(ast_block*, ast_expression*);
*/ */
struct ast_function_s struct ast_function_s
{ {
ast_node node; ast_node node;
ast_value *vtype; ast_value *vtype;
const char *name; const char *name;

View file

@ -198,9 +198,9 @@ static con_t console;
*/ */
static void con_enablecolor(void) { static void con_enablecolor(void) {
if (console.handle_err == stderr || console.handle_err == stdout) 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) if (console.handle_out == stderr || console.handle_out == stdout)
console.color_out = true; /*!!(isatty(STDOUT_FILENO));*/ console.color_out = !!(isatty(STDOUT_FILENO));
} }
/* /*

View file

@ -324,7 +324,7 @@ static ast_expression *intrin_isnan(parser_t *parser) {
static ast_value *value = NULL; static ast_value *value = NULL;
if (!value) { 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_value *local = ast_value_new (parser_ctx(parser), "local", TYPE_FLOAT);
ast_block *body = ast_block_new (parser_ctx(parser)); ast_block *body = ast_block_new (parser_ctx(parser));
ast_function *func = NULL; ast_function *func = NULL;
@ -363,21 +363,23 @@ static ast_expression *intrin_isnan(parser_t *parser) {
return (ast_expression*)value; return (ast_expression*)value;
} }
static ast_expression *intrin_debug_typestring(parser_t *parser) {
(void)parser;
return (ast_expression*)0x1;
}
static intrin_t intrinsics[] = { static intrin_t intrinsics[] = {
{&intrin_exp, "__builtin_exp", "exp"}, {&intrin_exp, "__builtin_exp", "exp"},
{&intrin_mod, "__builtin_mod", "mod"}, {&intrin_mod, "__builtin_mod", "mod"},
{&intrin_pow, "__builtin_pow", "pow"}, {&intrin_pow, "__builtin_pow", "pow"},
{&intrin_isnan, "__builtin_isnan", "isnan"} {&intrin_isnan, "__builtin_isnan", "isnan"},
{&intrin_debug_typestring, "__builtin_debug_typestring", ""}
}; };
void intrin_intrinsics_destroy(parser_t *parser) { void intrin_intrinsics_destroy(parser_t *parser) {
/*size_t i;*/ /*size_t i;*/
(void)parser; (void)parser;
util_htdel(intrin_intrinsics()); 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 */ /* register the intrinsics in the hashtable for O(1) lookup */
if (!init) { if (!init) {
for (i = 0; i < sizeof(intrinsics)/sizeof(*intrinsics); i++) 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 */ 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); 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); parseerror(parser, "need function: `%s` compiler depends on it", name);
return NULL; return NULL;
} }

View file

@ -29,8 +29,6 @@
#define PARSER_HT_SIZE 512 #define PARSER_HT_SIZE 512
#define TYPEDEF_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 void parser_enterblock(parser_t *parser);
static bool parser_leaveblock(parser_t *parser); static bool parser_leaveblock(parser_t *parser);
static void parser_addlocal(parser_t *parser, const char *name, ast_expression *e); 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; return false;
} }
fun = sy->out[fid].out; /*
* TODO handle this at the intrinsic level with an ast_intrinsic
if (fun == intrinsic_debug_typestring) { * node and codegen.
*/
if ((fun = sy->out[fid].out) == intrin_debug_typestring(parser)) {
char ty[1024]; char ty[1024];
if (fid+2 != vec_size(sy->out) || if (fid+2 != vec_size(sy->out) ||
vec_last(sy->out).block) vec_last(sy->out).block)
@ -1214,8 +1214,8 @@ static bool parser_close_call(parser_t *parser, shunt *sy)
vec_shrinkby(sy->out, 1); vec_shrinkby(sy->out, 1);
return true; return true;
} }
call = ast_call_new(sy->ops[vec_size(sy->ops)].ctx, fun); call = ast_call_new(sy->ops[vec_size(sy->ops)].ctx, fun);
if (!call) if (!call)
return false; return false;
@ -1531,9 +1531,7 @@ static bool parse_sya_operand(parser_t *parser, shunt *sy, bool with_labels)
/* a_vector.{x,y,z} */ /* a_vector.{x,y,z} */
if (!vec_size(sy->ops) || if (!vec_size(sy->ops) ||
!vec_last(sy->ops).etype || !vec_last(sy->ops).etype ||
operators[vec_last(sy->ops).etype-1].id != opid1('.') || operators[vec_last(sy->ops).etype-1].id != opid1('.'))
(prev >= intrinsic_debug_typestring &&
prev <= intrinsic_debug_typestring))
{ {
/* When adding more intrinsics, fix the above condition */ /* When adding more intrinsics, fix the above condition */
prev = NULL; 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__")) if (!var && !strcmp(parser_tokval(parser), "__FUNC__"))
var = (ast_expression*)fold_constgen_string(parser->fold, parser->function->name, false); var = (ast_expression*)fold_constgen_string(parser->fold, parser->function->name, false);
if (!var) { if (!var) {
/* intrinsics */ /*
if (!strcmp(parser_tokval(parser), "__builtin_debug_typestring")) { * now we try for the real intrinsic hashtable. If the string
var = (ast_expression*)intrinsic_debug_typestring;
}
/* now we try for the real intrinsic hashtable. If the string
* begins with __builtin, we simply skip past it, otherwise we * begins with __builtin, we simply skip past it, otherwise we
* use the identifier as is. * use the identifier as is.
*/ */
else if (!strncmp(parser_tokval(parser), "__builtin_", 10)) { if (!strncmp(parser_tokval(parser), "__builtin_", 10)) {
var = intrin_func(parser, parser_tokval(parser) + 10 /* skip __builtin */); var = intrin_func(parser, parser_tokval(parser));
} }
if (!var) { if (!var) {