diff --git a/tools/qfcc/include/expr.h b/tools/qfcc/include/expr.h index 6b9bf3123..9d340f489 100644 --- a/tools/qfcc/include/expr.h +++ b/tools/qfcc/include/expr.h @@ -1,4 +1,5 @@ typedef enum { + ex_label, ex_expr, // binary expression ex_uexpr, // unary expression ex_def, @@ -9,10 +10,17 @@ typedef enum { ex_quaternion, } expr_type; +typedef struct { + statref_t *refs; + dstatement_t *statement; + char *name; +} label_t; + typedef struct expr_s { struct expr_s *next; expr_type type; union { + label_t *label; struct { int op; type_t *type; diff --git a/tools/qfcc/include/qfcc.h b/tools/qfcc/include/qfcc.h index 37683d6c5..cd2abd5cd 100644 --- a/tools/qfcc/include/qfcc.h +++ b/tools/qfcc/include/qfcc.h @@ -412,6 +412,7 @@ typedef enum { } token_type_t; extern char pr_token[2048]; +extern int pr_token_len; extern token_type_t pr_token_type; extern type_t *pr_immediate_type; extern eval_t pr_immediate; @@ -419,6 +420,7 @@ extern eval_t pr_immediate; void PR_PrintStatement (dstatement_t *s); void PR_Lex (void); +void PR_LexString (void); // reads the next token into pr_token and classifies its type type_t *PR_ParseType (void); diff --git a/tools/qfcc/source/expr.c b/tools/qfcc/source/expr.c index 9f350f4b1..35fbde648 100644 --- a/tools/qfcc/source/expr.c +++ b/tools/qfcc/source/expr.c @@ -8,11 +8,13 @@ #include "qc-parse.h" void yyerror (const char*); +extern function_t *current_func; static etype_t qc_types[] = { - ev_void, - ev_void, - ev_void, + ev_void, // ex_label + ev_void, // ex_expr + ev_void, // ex_uexpr + ev_void, // ex_def ev_void, // FIXME ex_int ev_float, // ex_float ev_string, // ex_string @@ -35,6 +37,7 @@ static etype_t get_type (expr_t *e) { switch (e->type) { + case ex_label: case ex_quaternion: //FIXME return ev_void; case ex_expr: @@ -65,13 +68,14 @@ expr_t * label_expr (void) { static int label = 0; + int lnum = ++label; + const char *fname = current_func->def->name; expr_t *l = new_expr (); - l->type = ex_uexpr; - l->e.expr.op = 'l'; - l->e.expr.e1 = new_expr (); - l->e.expr.e1->type = ex_int; - l->e.expr.e1->e.int_val = label++; + l->type = ex_label; + l->e.label = calloc (1, sizeof (label_t)); + l->e.label->name = malloc (1 + strlen (fname) + 1 + ceil (log10 (lnum)) + 1); + sprintf (l->e.label->name, "$%s_%d", fname, lnum); return l; } @@ -84,6 +88,9 @@ print_expr (expr_t *e) return; } switch (e->type) { + case ex_label: + printf ("%s", e->e.label->name); + break; case ex_expr: print_expr (e->e.expr.e1); if (e->e.expr.op == 'c') { @@ -434,6 +441,8 @@ unary_expr (int op, expr_t *e) switch (op) { case '-': switch (e->type) { + case ex_label: + abort (); case ex_uexpr: if (e->e.expr.op == '-') return e->e.expr.e1; @@ -472,6 +481,8 @@ unary_expr (int op, expr_t *e) break; case '!': switch (e->type) { + case ex_label: + abort (); case ex_uexpr: case ex_expr: case ex_def: diff --git a/tools/qfcc/source/pr_lex.c b/tools/qfcc/source/pr_lex.c index 18492c352..156b79c4e 100644 --- a/tools/qfcc/source/pr_lex.c +++ b/tools/qfcc/source/pr_lex.c @@ -41,6 +41,7 @@ char *pr_line_start; // start of current source line int pr_bracelevel; char pr_token[2048]; +int pr_token_len; token_type_t pr_token_type; type_t *pr_immediate_type; eval_t pr_immediate; @@ -157,12 +158,11 @@ void PR_LexString (void) { int c; - int len; int i; int mask; int boldnext; - len = 0; + pr_token_len = 0; mask = 0x00; boldnext = 0; @@ -253,7 +253,7 @@ PR_LexString (void) break; } } else if (c == '\"') { - pr_token[len] = 0; + pr_token[pr_token_len] = 0; pr_token_type = tt_immediate; pr_immediate_type = &type_string; strcpy (pr_immediate_string, pr_token); @@ -263,8 +263,8 @@ PR_LexString (void) c = c ^ 0x80; boldnext = 0; c = c ^ mask; - pr_token[len] = c; - len++; + pr_token[pr_token_len] = c; + pr_token_len++; } while (1); } diff --git a/tools/qfcc/source/qc-lex.l b/tools/qfcc/source/qc-lex.l index 0dd930977..2a4299524 100644 --- a/tools/qfcc/source/qc-lex.l +++ b/tools/qfcc/source/qc-lex.l @@ -17,6 +17,8 @@ int do_grab (char *token); void add_frame_macro (char *token); +char *make_string (char *token); + extern YYSTYPE yylval; %} @@ -62,10 +64,7 @@ m ([\-+]?) {ID} return type_or_name(yytext); \"(\\.|[^"])*\" { - int len = strlen (yytext) - 2; - yylval.string_val = malloc (len + 1); - strncpy (yylval.string_val, yytext + 1, len); - yylval.string_val[len] = 0; + yylval.string_val = make_string (yytext); return STRING_VAL; } @@ -256,3 +255,15 @@ clear_frame_macros (void) if (frame_tab) Hash_FlushTable (frame_tab); } + +char * +make_string (char *token) +{ + char *str; + + pr_file_p = token + 1; + PR_LexString (); + str = malloc (pr_token_len + 1); + memcpy (str, pr_token, pr_token_len + 1); + return str; +} diff --git a/tools/qfcc/source/qc-parse.y b/tools/qfcc/source/qc-parse.y index a20bc2c0a..8783d7ee5 100644 --- a/tools/qfcc/source/qc-parse.y +++ b/tools/qfcc/source/qc-parse.y @@ -76,6 +76,7 @@ typedef struct { type_t *current_type; def_t *current_def; def_t param_scope; +function_t *current_func; %} @@ -252,7 +253,7 @@ opt_initializer begin_function : /*empty*/ { - $$ = new_function (); + $$ = current_func = new_function (); $$->def = current_def; $$->code = numstatements; pr_scope = current_def; diff --git a/tools/qfcc/source/qfcc.c b/tools/qfcc/source/qfcc.c index 1765a4935..6d803129f 100644 --- a/tools/qfcc/source/qfcc.c +++ b/tools/qfcc/source/qfcc.c @@ -915,6 +915,7 @@ Options: \n\ printf ("compiling %s\n", filename); yyin = fopen (filename, "rt"); + s_file = ReuseString (filename); lineno = 1; clear_frame_macros (); if (yyparse ()) {