X-Git-Url: https://git.xonotic.org/?p=xonotic%2Fgmqcc.git;a=blobdiff_plain;f=ast.h;h=5f553798980ad9c1ea216dd31ea658b9228a192f;hp=9d419609157039ce944b2fffcc28901422bd160c;hb=0920cb6ec4e1a00af744d1c33a4f0b44de33a3fa;hpb=5e23e8296d1d82df528481e04262a9e3afb38908 diff --git a/ast.h b/ast.h index 9d41960..5f55379 100644 --- a/ast.h +++ b/ast.h @@ -52,27 +52,27 @@ typedef struct ast_label_s ast_label; typedef struct ast_goto_s ast_goto; enum { - TYPE_ast_node, - TYPE_ast_expression, - TYPE_ast_value, - TYPE_ast_function, - TYPE_ast_block, - TYPE_ast_binary, - TYPE_ast_store, - TYPE_ast_binstore, - TYPE_ast_entfield, - TYPE_ast_ifthen, - TYPE_ast_ternary, - TYPE_ast_loop, - TYPE_ast_call, - TYPE_ast_unary, - TYPE_ast_return, - TYPE_ast_member, - TYPE_ast_array_index, - TYPE_ast_breakcont, - TYPE_ast_switch, - TYPE_ast_label, - TYPE_ast_goto + TYPE_ast_node, /* 0 */ + TYPE_ast_expression, /* 1 */ + TYPE_ast_value, /* 2 */ + TYPE_ast_function, /* 3 */ + TYPE_ast_block, /* 4 */ + TYPE_ast_binary, /* 5 */ + TYPE_ast_store, /* 6 */ + TYPE_ast_binstore, /* 7 */ + TYPE_ast_entfield, /* 8 */ + TYPE_ast_ifthen, /* 9 */ + TYPE_ast_ternary, /* 10 */ + TYPE_ast_loop, /* 11 */ + TYPE_ast_call, /* 12 */ + TYPE_ast_unary, /* 13 */ + TYPE_ast_return, /* 14 */ + TYPE_ast_member, /* 15 */ + TYPE_ast_array_index, /* 16 */ + TYPE_ast_breakcont, /* 17 */ + TYPE_ast_switch, /* 18 */ + TYPE_ast_label, /* 19 */ + TYPE_ast_goto /* 20 */ }; #define ast_istype(x, t) ( ((ast_node_common*)x)->nodetype == (TYPE_##t) ) @@ -95,7 +95,7 @@ typedef struct bool side_effects; } ast_node_common; -#define ast_delete(x) ( ( (ast_node*)(x) ) -> node.destroy )((ast_node*)(x)) +#define ast_delete(x) (*( ((ast_node*)(x))->node.destroy ))((ast_node*)(x)) #define ast_unref(x) do \ { \ if (! (((ast_node*)(x))->node.keep) ) { \ @@ -131,7 +131,7 @@ typedef struct /* arrays get a member-count */ size_t count; ast_value* *params; - bool variadic; + uint32_t flags; /* The codegen functions should store their output values * so we can call it multiple times without re-evaluating. * Store lvalue and rvalue seperately though. So that @@ -140,6 +140,12 @@ typedef struct ir_value *outl; ir_value *outr; } ast_expression_common; +#define AST_FLAG_VARIADIC (1<<0) +#define AST_FLAG_NORETURN (1<<1) +#define AST_FLAG_INLINE (1<<2) +#define AST_FLAG_INITIALIZED (1<<3) +#define AST_FLAG_DEPRECATED (1<<4) +#define AST_FLAG_TYPE_MASK (AST_FLAG_VARIADIC | AST_FLAG_NORETURN) /* Value * @@ -153,13 +159,15 @@ struct ast_value_s ast_expression_common expression; const char *name; + const char *desc; /* int vtype; ast_value *next; */ - bool cvq; /* const/var qualifier */ + int cvq; /* const/var qualifier */ + bool isfield; /* this declares a field */ bool hasvalue; union { double vfloat; @@ -168,6 +176,7 @@ struct ast_value_s const char *vstring; int ventity; ast_function *vfunc; + ast_value *vfield; } constval; /* usecount for the parser */ @@ -319,9 +328,11 @@ struct ast_member_s ast_expression *owner; unsigned int field; const char *name; + bool rvalue; }; ast_member* ast_member_new(lex_ctx ctx, ast_expression *owner, unsigned int field, const char *name); void ast_member_delete(ast_member*); +bool ast_member_set_name(ast_member*, const char *name); bool ast_member_codegen(ast_member*, ast_function*, bool lvalue, ir_value**); @@ -445,11 +456,19 @@ struct ast_loop_s ast_expression *postcond; ast_expression *increment; ast_expression *body; + /* For now we allow a seperate flag on whether or not the condition + * is supposed to be true or false. + * That way, the parser can generate a 'while not(!x)' for `while(x)` + * if desired, which is useful for the new -f{true,false}-empty-strings + * flag. + */ + bool pre_not; + bool post_not; }; ast_loop* ast_loop_new(lex_ctx ctx, ast_expression *initexpr, - ast_expression *precond, - ast_expression *postcond, + ast_expression *precond, bool pre_not, + ast_expression *postcond, bool post_not, ast_expression *increment, ast_expression *body); void ast_loop_delete(ast_loop*); @@ -461,9 +480,10 @@ bool ast_loop_codegen(ast_loop*, ast_function*, bool lvalue, ir_value**); struct ast_breakcont_s { ast_expression_common expression; - bool is_continue; + bool is_continue; + unsigned int levels; }; -ast_breakcont* ast_breakcont_new(lex_ctx ctx, bool iscont); +ast_breakcont* ast_breakcont_new(lex_ctx ctx, bool iscont, unsigned int levels); void ast_breakcont_delete(ast_breakcont*); bool ast_breakcont_codegen(ast_breakcont*, ast_function*, bool lvalue, ir_value**); @@ -571,7 +591,7 @@ bool ast_block_set_type(ast_block*, ast_expression *from); bool ast_block_codegen(ast_block*, ast_function*, bool lvalue, ir_value**); void ast_block_collect(ast_block*, ast_expression*); -void ast_block_add_expr(ast_block*, ast_expression*); +bool GMQCC_WARN ast_block_add_expr(ast_block*, ast_expression*); /* Function * @@ -594,8 +614,8 @@ struct ast_function_s ir_function *ir_func; ir_block *curblock; - ir_block *breakblock; - ir_block *continueblock; + ir_block **breakblocks; + ir_block **continueblocks; #if 0 /* In order for early-out logic not to go over @@ -624,6 +644,7 @@ void ast_function_delete(ast_function*); const char* ast_function_label(ast_function*, const char *prefix); bool ast_function_codegen(ast_function *self, ir_builder *builder); +bool ast_generate_accessors(ast_value *asvalue, ir_builder *ir); /* Expression union */