diff --git a/tools/qfcc/include/expr.h b/tools/qfcc/include/expr.h index 711daf7cb..6f3336cc9 100644 --- a/tools/qfcc/include/expr.h +++ b/tools/qfcc/include/expr.h @@ -135,6 +135,7 @@ expr_t *new_bind_expr (expr_t *e1, expr_t *e2); expr_t *new_name_expr (const char *name); expr_t *new_def_expr (def_t *def); expr_t *new_self_expr (void); +expr_t *new_this_expr (void); void inc_users (expr_t *e); void convert_name (expr_t *e); diff --git a/tools/qfcc/include/type.h b/tools/qfcc/include/type.h index 6ae3f749c..e1d9b6255 100644 --- a/tools/qfcc/include/type.h +++ b/tools/qfcc/include/type.h @@ -65,6 +65,7 @@ struct dstring_s; type_t *find_type (type_t *new); void new_typedef (const char *name, type_t *type); type_t *get_typedef (const char *name); +type_t *field_type (type_t *aux); type_t *pointer_type (type_t *aux); type_t *array_type (type_t *aux, int size); void print_type (type_t *type); diff --git a/tools/qfcc/source/expr.c b/tools/qfcc/source/expr.c index 66f4e6287..6f50f3d25 100644 --- a/tools/qfcc/source/expr.c +++ b/tools/qfcc/source/expr.c @@ -481,6 +481,16 @@ new_self_expr (void) return new_def_expr (def); } +expr_t * +new_this_expr (void) +{ + type_t *type = field_type (&type_id); + def_t *def = PR_GetDef (type, ".this", 0, &numpr_globals); + + PR_DefInitialized (def); + return new_def_expr (def); +} + expr_t * append_expr (expr_t *block, expr_t *e) { diff --git a/tools/qfcc/source/qc-lex.l b/tools/qfcc/source/qc-lex.l index b59dbac59..d4bca12df 100644 --- a/tools/qfcc/source/qc-lex.l +++ b/tools/qfcc/source/qc-lex.l @@ -279,6 +279,7 @@ static keyword_t keywords[] = { {"@public", PUBLIC, 0, 0, PROG_VERSION}, {"@selector", SELECTOR, 0, 0, PROG_VERSION}, {"@self", SELF, 0, 0, PROG_VERSION}, + {"@this", THIS, 0, 0, PROG_VERSION}, {"@argc", ARGC, 0, 0, PROG_VERSION}, {"@argv", ARGV, 0, 0, PROG_VERSION}, }; diff --git a/tools/qfcc/source/qc-parse.y b/tools/qfcc/source/qc-parse.y index 3cd085be6..8745bb799 100644 --- a/tools/qfcc/source/qc-parse.y +++ b/tools/qfcc/source/qc-parse.y @@ -64,8 +64,6 @@ parse_error (void) int yylex (void); -type_t *build_type (int is_field, type_t *type); - hashtab_t *save_local_inits (def_t *scope); hashtab_t *merge_local_inits (hashtab_t *dl_1, hashtab_t *dl_2); void restore_local_inits (hashtab_t *def_list); @@ -112,7 +110,7 @@ void free_local_inits (hashtab_t *def_list); %token LOCAL RETURN WHILE DO IF ELSE FOR BREAK CONTINUE ELLIPSIS NIL %token IFBE IFB IFAE IFA -%token SWITCH CASE DEFAULT STRUCT ENUM TYPEDEF SUPER SELF +%token SWITCH CASE DEFAULT STRUCT ENUM TYPEDEF SUPER SELF THIS %token ARGC ARGV %token ELE_START %token TYPE @@ -244,16 +242,16 @@ enum ; type - : '.' type { $$ = build_type (1, $2); } + : '.' type { $$ = field_type ($2); } | non_field_type { $$ = $1; } | non_field_type function_decl { current_params = $2; - $$ = build_type (0, parse_params ($1, $2)); + $$ = parse_params ($1, $2); } | non_field_type array_decl { - $$ = build_type (0, array_type ($1, $2)); + $$ = array_type ($1, $2); } ; @@ -783,6 +781,7 @@ expr | ARGC { $$ = new_name_expr (".argc"); } | ARGV { $$ = new_name_expr (".argv"); } | SELF { $$ = new_self_expr (); } + | THIS { $$ = new_this_expr (); } | const { $$ = $1; } | '(' expr ')' { $$ = $2; $$->paren = 1; } ; @@ -1292,20 +1291,6 @@ obj_string %% -type_t * -build_type (int is_field, type_t *type) -{ - if (is_field) { - type_t new; - memset (&new, 0, sizeof (new)); - new.type = ev_field; - new.aux_type = type; - return find_type (&new); - } else { - return type; - } -} - typedef struct { def_t *def; int state; diff --git a/tools/qfcc/source/type.c b/tools/qfcc/source/type.c index a9262b380..4d34c07ae 100644 --- a/tools/qfcc/source/type.c +++ b/tools/qfcc/source/type.c @@ -175,6 +175,17 @@ get_typedef (const char *name) return td->type; } +type_t * +field_type (type_t *aux) +{ + type_t new; + + memset (&new, 0, sizeof (new)); + new.type = ev_field; + new.aux_type = aux; + return find_type (&new); +} + type_t * pointer_type (type_t *aux) {