X-Git-Url: https://git.xonotic.org/?p=xonotic%2Fgmqcc.git;a=blobdiff_plain;f=ast.h;h=bae07db39ec85c13481a10ecec947ece7f0c7ce8;hp=41ef31821b8d81fe3878d342c3b02a9ce323be1b;hb=69b55ccc03b56af1f6c05eb45866ab198307487f;hpb=1ca3e724176898c5610d943d98915acef43214bb diff --git a/ast.h b/ast.h index 41ef318..bae07db 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,11 @@ typedef struct /* arrays get a member-count */ size_t count; ast_value* *params; - bool variadic; + uint32_t flags; + /* void foo(string...) gets varparam set as a restriction + * for variadic parameters + */ + ast_expression *varparam; /* 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 +144,15 @@ 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_INCLUDE_DEF (1<<5) +#define AST_FLAG_IS_VARARG (1<<6) +#define AST_FLAG_ALIAS (1<<7) +#define AST_FLAG_TYPE_MASK (AST_FLAG_VARIADIC | AST_FLAG_NORETURN) /* Value * @@ -153,14 +166,18 @@ struct ast_value_s ast_expression_common expression; const char *name; + const char *desc; + + const char *argcounter; /* int vtype; ast_value *next; */ - bool cvq; /* const/var qualifier */ + int cvq; /* const/var qualifier */ bool isfield; /* this declares a field */ + bool isimm; /* an immediate, not just const */ bool hasvalue; union { double vfloat; @@ -200,9 +217,16 @@ void ast_value_params_add(ast_value*, ast_value*); bool ast_compare_type(ast_expression *a, ast_expression *b); ast_expression* ast_type_copy(lex_ctx ctx, const ast_expression *ex); #define ast_type_adopt(a, b) ast_type_adopt_impl((ast_expression*)(a), (ast_expression*)(b)) -bool ast_type_adopt_impl(ast_expression *self, const ast_expression *other); +void ast_type_adopt_impl(ast_expression *self, const ast_expression *other); void ast_type_to_string(ast_expression *e, char *buf, size_t bufsize); +typedef enum ast_binary_ref_s { + AST_REF_LEFT = 1 << 1, + AST_REF_RIGHT = 1 << 2, + AST_REF_ALL = (AST_REF_LEFT | AST_REF_RIGHT) +} ast_binary_ref; + + /* Binary * * A value-returning binary expression. @@ -214,6 +238,8 @@ struct ast_binary_s int op; ast_expression *left; ast_expression *right; + ast_binary_ref refs; + }; ast_binary* ast_binary_new(lex_ctx ctx, int op, @@ -321,9 +347,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 +475,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 +499,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**); @@ -507,9 +544,11 @@ struct ast_label_s const char *name; ir_block *irblock; ast_goto **gotos; + /* means it has not yet been defined */ + bool undefined; }; -ast_label* ast_label_new(lex_ctx ctx, const char *name); +ast_label* ast_label_new(lex_ctx ctx, const char *name, bool undefined); void ast_label_delete(ast_label*); void ast_label_register_goto(ast_label*, ast_goto*); @@ -548,6 +587,7 @@ struct ast_call_s ast_expression_common expression; ast_expression *func; ast_expression* *params; + ast_expression *va_count; }; ast_call* ast_call_new(lex_ctx ctx, ast_expression *funcexpr); @@ -568,12 +608,12 @@ struct ast_block_s }; ast_block* ast_block_new(lex_ctx ctx); void ast_block_delete(ast_block*); -bool ast_block_set_type(ast_block*, ast_expression *from); +void 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 * @@ -596,8 +636,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 @@ -616,6 +656,10 @@ struct ast_function_s char labelbuf[64]; ast_block* *blocks; + + ast_value *varargs; + ast_value *argc; + ast_value *fixedparams; }; ast_function* ast_function_new(lex_ctx ctx, const char *name, ast_value *vtype); /* This will NOT delete the underlying ast_value */