X-Git-Url: https://git.xonotic.org/?p=xonotic%2Fgmqcc.git;a=blobdiff_plain;f=ast.h;h=97a3dc0f4ef88a5c3ac07e5db29cafcfa90be254;hp=25243c069c0f4ba3d6d65464fae87782581b4385;hb=686394654fff6ecfc4f6b9a76bec599585d56795;hpb=8777624fe2f0695a2ddd3ec705672db3f98e4eb7 diff --git a/ast.h b/ast.h index 25243c0..97a3dc0 100644 --- a/ast.h +++ b/ast.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 + * Copyright (C) 2012, 2013 * Wolfgang Bumiller * * Permission is hereby granted, free of charge, to any person obtaining a copy of @@ -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,14 @@ 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 { @@ -321,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**); @@ -447,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*); @@ -463,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**); @@ -596,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