From 1b875c8b06234f820cb79d6fb0ab332aa74eacff Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Wed, 8 May 2002 23:12:49 +0000 Subject: [PATCH] work on getting obj expressions going --- tools/qfcc/include/expr.h | 6 ++ tools/qfcc/include/method.h | 11 ++++ tools/qfcc/source/expr.c | 37 ++++++++++++ tools/qfcc/source/method.c | 25 ++++++++ tools/qfcc/source/qc-parse.y | 114 +++++++++++++++++++++++++---------- 5 files changed, 161 insertions(+), 32 deletions(-) diff --git a/tools/qfcc/include/expr.h b/tools/qfcc/include/expr.h index d786e5b38..25d53e559 100644 --- a/tools/qfcc/include/expr.h +++ b/tools/qfcc/include/expr.h @@ -166,4 +166,10 @@ const char *get_op_string (int op); extern int lineno_base; +struct keywordarg_s; +expr_t *selector_expr (struct keywordarg_s *selector); +expr_t *protocol_expr (const char *protocol); +expr_t *encode_expr (type_t *type); +expr_t *message_expr (expr_t *receiver, struct keywordarg_s *message); + #endif//__expr_h diff --git a/tools/qfcc/include/method.h b/tools/qfcc/include/method.h index 1f3b27835..cbf043546 100644 --- a/tools/qfcc/include/method.h +++ b/tools/qfcc/include/method.h @@ -48,10 +48,21 @@ typedef struct { method_t **tail; } methodlist_t; +typedef struct keywordarg_s { + struct keywordarg_s *next; + const char *selector; + expr_t *expr; +} keywordarg_t; + struct class_s; +struct expr_s; method_t *new_method (type_t *ret_type, param_t *selector, param_t *opt_parms); void add_method (methodlist_t *methodlist, method_t *method); def_t *method_def (struct class_s *klass, method_t *method); +keywordarg_t *new_keywordarg (const char *selector, struct expr_s *expr); + +struct expr_s *send_message (void); + #endif//__method_h diff --git a/tools/qfcc/source/expr.c b/tools/qfcc/source/expr.c index b391b03e4..9d3c59683 100644 --- a/tools/qfcc/source/expr.c +++ b/tools/qfcc/source/expr.c @@ -38,6 +38,7 @@ static const char rcsid[] = #include "qfcc.h" #include "function.h" +#include "method.h" #include "struct.h" #include "type.h" #include "qc-parse.h" @@ -1922,3 +1923,39 @@ init_elements (def_t *def, expr_t *eles) } } } + +expr_t * +selector_expr (keywordarg_t *selector) +{ + return error (0, "not implemented"); +} + +expr_t * +protocol_expr (const char *protocol) +{ + return error (0, "not implemented"); +} + +expr_t * +encode_expr (type_t *type) +{ + return error (0, "not implemented"); +} + +expr_t * +message_expr (expr_t *receiver, keywordarg_t *message) +{ + expr_t *args = 0, **a = &args; + expr_t *selector = selector_expr (message); + keywordarg_t *m; + + for (m = message; m; m = m->next) { + *a = m->expr; + while ((*a)->next) + a = &(*a)->next; + } + *a = selector; + a = &(*a)->next; + *a = receiver; + return function_expr (send_message (), args); +} diff --git a/tools/qfcc/source/method.c b/tools/qfcc/source/method.c index 86b69d254..1597d8594 100644 --- a/tools/qfcc/source/method.c +++ b/tools/qfcc/source/method.c @@ -38,6 +38,9 @@ static const char rcsid[] = #include "method.h" #include "type.h" +static def_t *send_message_def; +static expr_t *send_message_expr; + method_t * new_method (type_t *ret_type, param_t *selector, param_t *opt_parms) { @@ -89,3 +92,25 @@ method_def (class_t *klass, method_t *method) // FIXME need a file scope return PR_GetDef (method->type, str->str, 0, &numpr_globals); } + +keywordarg_t * +new_keywordarg (const char *selector, struct expr_s *expr) +{ + keywordarg_t *k = malloc (sizeof (keywordarg_t)); + + k->next = 0; + k->selector = selector; + k->expr = expr; + return k; +} + +expr_t * +send_message (void) +{ + if (!send_message_def) { + send_message_expr = new_expr (); + send_message_expr->type = ex_def; + send_message_expr->e.def = send_message_def; + } + return send_message_expr; +} diff --git a/tools/qfcc/source/qc-parse.y b/tools/qfcc/source/qc-parse.y index 196352064..a1b35c86c 100644 --- a/tools/qfcc/source/qc-parse.y +++ b/tools/qfcc/source/qc-parse.y @@ -91,6 +91,7 @@ typedef struct { struct class_s *klass; struct protocol_s *protocol; struct category_s *category; + struct keywordarg_s *keywordarg; } %right '=' ASX PAS /* pointer assign */ @@ -125,7 +126,7 @@ typedef struct { %type def_name %type def_item def_list %type const opt_expr expr arg_list element_list element_list1 element -%type string_val opt_state_expr obj_expr +%type string_val opt_state_expr %type statement statements statement_block %type break_label continue_label enum_list enum %type begin_function @@ -133,10 +134,12 @@ typedef struct { %type switch_block %type param_scope -%type selector +%type selector reserved_word %type optparmlist unaryselector keyworddecl keywordselector %type methodproto methoddecl -%type identifier_list +%type obj_expr identifier_list obj_messageexpr obj_string receiver +%type messageargs keywordarg keywordarglist selectorarg +%type keywordnamelist keywordname %expect 2 // statement : if | if else, defs : defs def ';' | defs obj_def @@ -1091,6 +1094,13 @@ optparmlist { $$ = 0; } | ',' ELLIPSIS { $$ = new_param (0, 0, 0); } + | ',' param_list + { $$ = $2; } + | ',' param_list ',' ELLIPSIS + { + $$ = new_param (0, 0, 0); + $$->next = $2; + } ; unaryselector @@ -1104,6 +1114,27 @@ keywordselector selector : NAME + | TYPE { $$ = strdup (yytext); } + | reserved_word + ; + +reserved_word + : LOCAL { $$ = strdup (yytext); } + | RETURN { $$ = strdup (yytext); } + | WHILE { $$ = strdup (yytext); } + | DO { $$ = strdup (yytext); } + | IF { $$ = strdup (yytext); } + | ELSE { $$ = strdup (yytext); } + | FOR { $$ = strdup (yytext); } + | BREAK { $$ = strdup (yytext); } + | CONTINUE { $$ = strdup (yytext); } + | SWITCH { $$ = strdup (yytext); } + | CASE { $$ = strdup (yytext); } + | DEFAULT { $$ = strdup (yytext); } + | NIL { $$ = strdup (yytext); } + | STRUCT { $$ = strdup (yytext); } + | ENUM { $$ = strdup (yytext); } + | TYPEDEF { $$ = strdup (yytext); } ; keyworddecl @@ -1117,55 +1148,74 @@ keyworddecl { $$ = new_param ("", &type_id, $2); } ; -messageargs /* XXX */ - : selector {} +obj_expr + : obj_messageexpr + | SELECTOR '(' selectorarg ')' { $$ = selector_expr ($3); } + | PROTOCOL '(' NAME ')' { $$ = protocol_expr ($3); } + | ENCODE '(' type ')' { $$ = encode_expr ($3); } + | obj_string /* FIXME string object? */ + ; + +obj_messageexpr + : '[' receiver messageargs ']' { $$ = message_expr ($2, $3); } + ; + +receiver + : expr + ; + +messageargs + : selector { $$ = new_keywordarg ($1, 0); } | keywordarglist ; -keywordarglist /* XXX */ +keywordarglist : keywordarg | keywordarglist keywordarg + { + $2->next = $1; + $$ = $2; + } ; -keywordarg /* XXX */ - : selector ':' expr {} - | ':' expr +keywordarg + : selector ':' expr { $$ = new_keywordarg ($1, $3); } + | ':' expr { $$ = new_keywordarg ("", $2); } ; -receiver /* XXX */ - : expr {} - ; - -obj_expr /* XXX */ - : obj_messageexpr {} - | SELECTOR '(' selectorarg ')' {} - | PROTOCOL '(' NAME ')' {} - | ENCODE '(' type ')' {} - | obj_string {} - ; - -obj_messageexpr /* XXX */ - : '[' receiver messageargs ']' - ; - -selectorarg /* XXX */ - : selector {} +selectorarg + : selector { $$ = new_keywordarg ($1, 0); } | keywordnamelist ; -keywordnamelist /* XXX */ +keywordnamelist : keywordname | keywordnamelist keywordname + { + $2->next = $1; + $$ = $2; + } ; -keywordname /* XXX */ - : selector ':' {} - | ':' +keywordname + : selector ':' { $$ = new_keywordarg ($1, 0); } + | ':' { $$ = new_keywordarg ("", 0); } ; -obj_string /* XXX */ +obj_string : '@' STRING_VAL + { + $$ = new_expr (); + $$->type = ex_string; + $$->e.string_val = $2; + } | obj_string '@' STRING_VAL + { + expr_t *e = new_expr (); + e->type = ex_string; + e->e.string_val = $3; + $$ = binary_expr ('+', $1, e); + } ; %%