From 3967f5cf9540ddc43b068b325f990979f54656d0 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Wed, 22 May 2002 05:03:36 +0000 Subject: [PATCH] type.h: *type_method to type_Method emit.c: support casting between pointers expr.c: support casting between pointers method.c: correct the type for _cmd type_method to type_Method.aux_type qc-lex.l: Method type is a poniter to a method qc-parse.y: support , args to messages (not fully implemented yet) type.c: *type_method to type_Method and make type_Method a pointer to a method --- tools/qfcc/include/type.h | 2 +- tools/qfcc/source/emit.c | 8 ++++++-- tools/qfcc/source/expr.c | 26 ++++++++++++++++++-------- tools/qfcc/source/method.c | 4 ++-- tools/qfcc/source/qc-lex.l | 1 + tools/qfcc/source/qc-parse.y | 4 ++-- tools/qfcc/source/type.c | 14 +++++++------- 7 files changed, 37 insertions(+), 22 deletions(-) diff --git a/tools/qfcc/include/type.h b/tools/qfcc/include/type.h index 7fa53be18..efb1082c3 100644 --- a/tools/qfcc/include/type.h +++ b/tools/qfcc/include/type.h @@ -52,7 +52,7 @@ extern type_t type_Protocol; extern type_t type_SEL; extern type_t type_IMP; extern type_t type_obj_exec_class; -extern type_t *type_method; +extern type_t type_Method; extern type_t *type_category; extern type_t *type_ivar; extern type_t *type_module; diff --git a/tools/qfcc/source/emit.c b/tools/qfcc/source/emit.c index f37f8d005..61f3b8ee5 100644 --- a/tools/qfcc/source/emit.c +++ b/tools/qfcc/source/emit.c @@ -353,12 +353,16 @@ emit_sub_expr (expr_t *e, def_t *dest) d->type = e->e.expr.type; return d; case 'C': + def_a = emit_sub_expr (e->e.expr.e1, 0); + if (def_a->type->type == ev_pointer + && e->e.expr.type->type == ev_pointer) { + return def_a; + } + def_b = &def_void; if (!dest) { dest = PR_GetTempDef (e->e.expr.type, pr_scope); dest->users = 2; } - def_a = emit_sub_expr (e->e.expr.e1, 0); - def_b = &def_void; operator = "="; break; default: diff --git a/tools/qfcc/source/expr.c b/tools/qfcc/source/expr.c index a650b2950..66f4e6287 100644 --- a/tools/qfcc/source/expr.c +++ b/tools/qfcc/source/expr.c @@ -1935,21 +1935,31 @@ assign_expr (expr_t *e1, expr_t *e2) } expr_t * -cast_expr (type_t *t, expr_t *e) +cast_expr (type_t *type, expr_t *e) { expr_t *c; + type_t *e_type; + + convert_name (e); if (e->type == ex_error) return e; - if ((t != &type_integer && t != &type_uinteger - && get_type (e) != &type_float) - && (t != &type_float && get_type (e) != &type_integer)) { - return error (e, "can not cast from %s to %s", - pr_type_name[extract_type (e)], pr_type_name[t->type]); + e_type = get_type (e); + + if (type->type == ev_pointer && e_type->type == ev_pointer) { + c = new_unary_expr ('C', e); + c->e.expr.type = type; + } else if (((type == &type_integer || type == &type_uinteger) + && e_type == &type_float) + || (type == &type_float + && (e_type == &type_integer || e_type == &type_uinteger))) { + c = new_unary_expr ('C', e); + c->e.expr.type = type; + } else { + c = error (e, "can not cast from %s to %s", + pr_type_name[extract_type (e)], pr_type_name[type->type]); } - c = new_unary_expr ('C', e); - c->e.expr.type = t; return c; } diff --git a/tools/qfcc/source/method.c b/tools/qfcc/source/method.c index ca19f2d84..592c08a31 100644 --- a/tools/qfcc/source/method.c +++ b/tools/qfcc/source/method.c @@ -51,7 +51,7 @@ method_t * new_method (type_t *ret_type, param_t *selector, param_t *opt_parms) { method_t *meth = malloc (sizeof (method_t)); - param_t *cmd = new_param (0, &type_pointer, "_cmd"); + param_t *cmd = new_param (0, &type_SEL, "_cmd"); param_t *self = new_param (0, &type_id, "self"); dstring_t *name = dstring_newstr (); dstring_t *types = dstring_newstr (); @@ -286,7 +286,7 @@ emit_methods (methodlist_t *_methods, const char *name, int instance) new_struct_field (method_list, &type_pointer, "method_next", vis_public); new_struct_field (method_list, &type_integer, "method_count", vis_public); for (i = 0; i < count; i++) - new_struct_field (method_list, type_method, 0, vis_public); + new_struct_field (method_list, type_Method.aux_type, 0, vis_public); methods_def = PR_GetDef (method_list, va ("_OBJ_%s_METHODS_%s", type, name), 0, &numpr_globals); methods_def->initialized = methods_def->constant = 1; diff --git a/tools/qfcc/source/qc-lex.l b/tools/qfcc/source/qc-lex.l index 0a7528067..b85e48f6e 100644 --- a/tools/qfcc/source/qc-lex.l +++ b/tools/qfcc/source/qc-lex.l @@ -246,6 +246,7 @@ static keyword_t keywords[] = { {"id", TYPE, &type_id, 0, PROG_VERSION}, {"Class", TYPE, &type_Class, 0, PROG_VERSION}, {"Protocol", TYPE, &type_Protocol, 0, PROG_VERSION}, + {"Method", TYPE, &type_Method, 0, PROG_VERSION}, {"SEL", TYPE, &type_SEL, 0, PROG_VERSION}, {"IMP", TYPE, &type_IMP, 0, PROG_VERSION}, {"local", LOCAL, 0, 1, PROG_ID_VERSION}, diff --git a/tools/qfcc/source/qc-parse.y b/tools/qfcc/source/qc-parse.y index 5800a9adf..f9fc31c8a 100644 --- a/tools/qfcc/source/qc-parse.y +++ b/tools/qfcc/source/qc-parse.y @@ -1245,8 +1245,8 @@ keywordarglist ; keywordarg - : selector ':' expr { $$ = new_keywordarg ($1, $3); } - | ':' expr { $$ = new_keywordarg ("", $2); } + : selector ':' arg_list { $$ = new_keywordarg ($1, $3); } + | ':' arg_list { $$ = new_keywordarg ("", $2); } ; selectorarg diff --git a/tools/qfcc/source/type.c b/tools/qfcc/source/type.c index f0683b942..f5f898403 100644 --- a/tools/qfcc/source/type.c +++ b/tools/qfcc/source/type.c @@ -71,7 +71,7 @@ type_t type_Protocol = { ev_pointer }; type_t type_SEL = { ev_pointer }; type_t type_IMP = { ev_func, NULL, &type_id, -3, { &type_id, &type_SEL }}; type_t type_obj_exec_class = { ev_func, NULL, &type_void, 1, { 0 }}; -type_t *type_method; +type_t type_Method = { ev_pointer }; type_t *type_category; type_t *type_ivar; type_t *type_module; @@ -419,16 +419,16 @@ init_types (void) chain_type (&type_struct); chain_type (&type_IMP); - type = type_SEL.aux_type = new_struct ("SEL"); + type = type_SEL.aux_type = new_struct (0); new_struct_field (type, &type_string, "sel_id", vis_public); new_struct_field (type, &type_string, "sel_types", vis_public); chain_type (&type_SEL); - type_method = new_struct (0); - new_struct_field (type_method, type_SEL.aux_type, "method_name", vis_public); - new_struct_field (type_method, &type_string, "method_types", vis_public); - new_struct_field (type_method, &type_IMP, "method_imp", vis_public); - chain_type (type_method); + type = type_Method.aux_type = new_struct (0); + new_struct_field (type, type_SEL.aux_type, "method_name", vis_public); + new_struct_field (type, &type_string, "method_types", vis_public); + new_struct_field (type, &type_IMP, "method_imp", vis_public); + chain_type (&type_Method); type = type_Class.aux_type = new_struct (0); type->type = ev_class;