diff --git a/tools/qfcc/TODO b/tools/qfcc/TODO index 331a74d60..a0bf5ec93 100644 --- a/tools/qfcc/TODO +++ b/tools/qfcc/TODO @@ -9,11 +9,11 @@ X native integer type X ?: operator X = operator ( var += expr, etc. ) X allow temp defs at higher levels +X move the chained funcion support out of emit_function_expr into + funciton_expr I gut out old parser o switch/case, for any type o break/continue keywords for switch() and for(;;) -o quaternion type +o quaternion type. Tricky: requires 4 word args/return o pre- and post- increment operators (++ and --) o CSE optimisations -o move the chained funcion support out of emit_function_expr into - funciton_expr diff --git a/tools/qfcc/source/emit.c b/tools/qfcc/source/emit.c index f0c17a896..5fed68ef2 100644 --- a/tools/qfcc/source/emit.c +++ b/tools/qfcc/source/emit.c @@ -89,40 +89,31 @@ emit_function_call (expr_t *e, def_t *dest) expr_t *earg; opcode_t *op; int count = 0, ind; - def_t *args[MAX_PARMS]; for (earg = e->e.expr.e2; earg; earg = earg->next) count++; ind = count; for (earg = e->e.expr.e2; earg; earg = earg->next) { ind--; - args[ind] = PR_GetTempDef (types[get_type (earg)], pr_scope); - arg = emit_sub_expr (earg, args[ind]); - if (earg->type != ex_expr && earg->type != ex_uexpr) { - op = PR_Opcode_Find ("=", 5, arg, args[ind], &def_void); - emit_statement (e->line, op, arg, args[ind], 0); - } - } - ind = count; - while (ind-- > 0) { - arg = args[ind]; parm = def_parms[ind]; - parm.type = arg->type; - op = PR_Opcode_Find ("=", 5, arg, &parm, &def_void); - emit_statement (e->line, op, arg, &parm, 0); + parm.type = types[get_type (earg)]; + arg = emit_sub_expr (earg, &parm); + if (earg->type != ex_expr && earg->type != ex_uexpr) { + op = PR_Opcode_Find ("=", 5, arg, &parm, &def_void); + emit_statement (e->line, op, arg, &parm, 0); + } } op = PR_Opcode_Find (va ("", count), -1, &def_function, &def_void, &def_void); emit_statement (e->line, op, func, 0, 0); def_ret.type = func->type->aux_type; - if (def_ret.type->type != ev_void) { - if (!dest) - dest = PR_GetTempDef (def_ret.type, pr_scope); - op = PR_Opcode_Find ("=", 5, &def_ret, dest, &def_void); + if (dest) { + op = PR_Opcode_Find ("=", 5, dest, &def_ret, &def_void); emit_statement (e->line, op, &def_ret, dest, 0); return dest; - } else + } else { return &def_ret; + } } def_t * @@ -330,6 +321,9 @@ emit_expr (expr_t *e) statref_t *ref; elabel_t *label; //opcode_t *op; + static int level = 0; + + level++; switch (e->type) { case ex_label: @@ -391,7 +385,7 @@ emit_expr (expr_t *e) emit_branch (e->line, op_goto, 0, e->e.expr.e1); break; default: - warning (e, "Ignoring useless expression"); + warning (e, "useless expression"); emit_expr (e->e.expr.e1); break; } @@ -410,5 +404,6 @@ emit_expr (expr_t *e) warning (e, "Ignoring useless expression"); break; } - PR_FreeTempDefs (); + if (--level == 0) + PR_FreeTempDefs (); } diff --git a/tools/qfcc/source/expr.c b/tools/qfcc/source/expr.c index 439524e85..92b58ce4f 100644 --- a/tools/qfcc/source/expr.c +++ b/tools/qfcc/source/expr.c @@ -989,11 +989,14 @@ unary_expr (int op, expr_t *e) expr_t * function_expr (expr_t *e1, expr_t *e2) { - etype_t t1; - expr_t *e; - int parm_count = 0; - type_t *ftype; - int i; + etype_t t1; + expr_t *e; + int parm_count = 0; + type_t *ftype; + int i; + expr_t *args = 0, **a = &args; + type_t *arg_types[MAX_PARMS]; + expr_t *call; t1 = get_type (e1); @@ -1025,8 +1028,8 @@ function_expr (expr_t *e1, expr_t *e2) for (e = e2; e; e = e->next) parm_count++; - if (parm_count > 8) { - return error (e1, "more than 8 parameters"); + if (parm_count > MAX_PARMS) { + return error (e1, "more than %d parameters", MAX_PARMS); } if (ftype->num_parms != -1) { expr_t *err = 0; @@ -1052,6 +1055,7 @@ function_expr (expr_t *e1, expr_t *e2) if (t != ftype->parm_types[i - 1]) err = error (e, "type mismatch for parameter %d of %s", i, e1->e.def->name); + arg_types[parm_count - i] = t; } if (err) return err; @@ -1060,9 +1064,25 @@ function_expr (expr_t *e1, expr_t *e2) // if (e->type == ex_integer) // warning (e, "passing integer consant into ... function"); } - e = new_binary_expr ('c', e1, e2); + + call = new_block_expr (); + for (e = e2, i = 0; e; e = e->next, i++) { + *a = new_temp_def_expr (arg_types[i]); + append_expr (call, binary_expr ('=', *a, e)); + a = &(*a)->next; + } + e = new_binary_expr ('c', e1, args); e->e.expr.type = ftype->aux_type; - return e; + append_expr (call, e); + if (ftype->aux_type != &type_void) { + expr_t *ret = new_expr (); + ret->type = ex_def; + ret->e.def = &def_ret; + e = new_temp_def_expr (ftype->aux_type); + append_expr (call, new_binary_expr ('=', e, ret)); + call->e.block.result = e; + } + return call; } expr_t *