From 213ac2a328aedfce8d22b8e47a0c2063bea7846f Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 7 Dec 2024 23:52:50 +0900 Subject: [PATCH] [qfcc] Use a context object to hold current language Because the glsl front-end uses Ruamoko to compile its builtins, it needs to switch languages, and the cleanest way to do so is to use a context object that gets passed around. This removes not only the current_language global, but also (as a bonus) any real references to flex's scanner object (there's still a pointer in rua_ctx_t, but it's no longer a parameter (which caused some pain in the change)). --- tools/qfcc/include/expr.h | 3 +- tools/qfcc/include/glsl-lang.h | 23 +-- tools/qfcc/include/rua-lang.h | 92 +++++----- tools/qfcc/include/target.h | 13 +- tools/qfcc/source/expr_process.c | 147 ++++++++-------- tools/qfcc/source/function.c | 2 +- tools/qfcc/source/glsl-builtins.c | 56 +++--- tools/qfcc/source/glsl-declaration.c | 4 +- tools/qfcc/source/glsl-parse.y | 61 ++++--- tools/qfcc/source/pre-parse.y | 104 +++++------ tools/qfcc/source/qc-lex.l | 253 ++++++++++++++------------- tools/qfcc/source/qc-parse.y | 78 +++++---- tools/qfcc/source/qfcc.c | 30 ++-- tools/qfcc/source/qp-lex.l | 13 +- tools/qfcc/source/rua-declaration.c | 5 +- tools/qfcc/source/target_rua.c | 14 +- 16 files changed, 464 insertions(+), 434 deletions(-) diff --git a/tools/qfcc/include/expr.h b/tools/qfcc/include/expr.h index bc515c5bc..ef2800ab1 100644 --- a/tools/qfcc/include/expr.h +++ b/tools/qfcc/include/expr.h @@ -1138,7 +1138,8 @@ void scatter_factors (const expr_t *prod, const expr_t **factors); const expr_t *gather_factors (const type_t *type, int op, const expr_t **factors, int count); -const expr_t *expr_process (const expr_t *expr); +typedef struct rua_ctx_s rua_ctx_t; +const expr_t *expr_process (const expr_t *expr, rua_ctx_t *ctx); ///@} diff --git a/tools/qfcc/include/glsl-lang.h b/tools/qfcc/include/glsl-lang.h index 93d594583..a86ca6d1a 100644 --- a/tools/qfcc/include/glsl-lang.h +++ b/tools/qfcc/include/glsl-lang.h @@ -39,15 +39,16 @@ typedef struct symbol_s symbol_t; typedef struct symtab_s symtab_t; typedef struct language_s language_t; typedef struct defspace_s defspace_t; +typedef struct rua_ctx_s rua_ctx_t; -void glsl_init_comp (void); -void glsl_init_vert (void); -void glsl_init_tesc (void); -void glsl_init_tese (void); -void glsl_init_geom (void); -void glsl_init_frag (void); +void glsl_init_comp (rua_ctx_t *ctx); +void glsl_init_vert (rua_ctx_t *ctx); +void glsl_init_tesc (rua_ctx_t *ctx); +void glsl_init_tese (rua_ctx_t *ctx); +void glsl_init_geom (rua_ctx_t *ctx); +void glsl_init_frag (rua_ctx_t *ctx); -int glsl_parse_string (const char *str); +int glsl_parse_string (const char *str, rua_ctx_t *ctx); extern language_t lang_glsl_comp; extern language_t lang_glsl_vert; @@ -109,7 +110,7 @@ typedef struct glsl_sublang_s { const char *name; const char **interface_default_names; } glsl_sublang_t; -#define glsl_sublang (*(glsl_sublang_t *) current_language.sublanguage) +extern glsl_sublang_t glsl_sublang; extern glsl_sublang_t glsl_comp_sublanguage; extern glsl_sublang_t glsl_vert_sublanguage; extern glsl_sublang_t glsl_tesc_sublanguage; @@ -127,11 +128,11 @@ void glsl_apply_attributes (symtab_t *attributes, specifier_t spec); void glsl_parse_declaration (specifier_t spec, symbol_t *sym, const expr_t *init, symtab_t *symtab, - expr_t *block); -void glsl_declare_field (specifier_t spec, symtab_t *symtab); + expr_t *block, rua_ctx_t *ctx); +void glsl_declare_field (specifier_t spec, symtab_t *symtab, rua_ctx_t *ctx); void glsl_layout (const ex_list_t *qualifiers, specifier_t spec); -bool glsl_on_include (const char *name); +bool glsl_on_include (const char *name, rua_ctx_t *ctx); void glsl_include (int behavior, void *scanner); void glsl_multiview (int behavior, void *scanner); diff --git a/tools/qfcc/include/rua-lang.h b/tools/qfcc/include/rua-lang.h index 1b5b8ca0a..de3fbb92b 100644 --- a/tools/qfcc/include/rua-lang.h +++ b/tools/qfcc/include/rua-lang.h @@ -67,6 +67,7 @@ typedef struct rua_loc_s { (Current).file = YYRHSLOC (Rhs, 0).file; \ } while (0) +typedef struct rua_ctx_s rua_ctx_t; typedef struct expr_s expr_t; typedef struct symbol_s symbol_t; typedef struct symtab_s symtab_t; @@ -119,7 +120,7 @@ typedef union rua_val_s { #include "tools/qfcc/source/glsl-parse.h" typedef struct rua_macro_s rua_macro_t; -typedef void (*rua_macro_f) (rua_macro_t *macro, void *scanner); +typedef void (*rua_macro_f) (rua_macro_t *macro, rua_ctx_t *ctx); typedef struct rua_macro_s { rua_macro_t *next; @@ -145,38 +146,38 @@ typedef struct rua_preval_s { }; } rua_preval_t; -rua_macro_t *rua_start_macro (const char *name, bool params, void *scanner); +rua_macro_t *rua_start_macro (const char *name, bool params, rua_ctx_t *ctx); rua_macro_t *rua_macro_param (rua_macro_t *macro, const rua_tok_t *token, - void *scanner); -rua_macro_t *rua_end_params (rua_macro_t *macro, void *scanner); + rua_ctx_t *ctx); +rua_macro_t *rua_end_params (rua_macro_t *macro, rua_ctx_t *ctx); rua_macro_t *rua_macro_append (rua_macro_t *macro, const rua_tok_t *token, - void *scanner); -void rua_macro_finish (rua_macro_t *macro, void *scanner); -rua_macro_t *rua_macro_arg (const rua_tok_t *token, void *scanner); -void rua_start_pragma (void *scanner); -void rua_start_text (void *scanner); -void rua_start_expr (void *scanner); -void rua_start_include (void *scanner); -void rua_expand_on (void *scanner); -void rua_expand_off (void *scanner); -void rua_end_directive (void *scanner); -void rua_start_if (bool expand, void *scanner); -void rua_start_else (bool expand, void *scanner); -void rua_if (bool pass, void *scanner); -void rua_else (bool pass, const char *tok, void *scanner); -void rua_endif (void *scanner); -bool rua_defined (const char *sym, void *scanner); -void rua_undefine (const char *sym, void *scanner); -void rua_include_file (const char *name, void *scanner); -void rua_embed_file (const char *name, void *scanner); + rua_ctx_t *ctx); +void rua_macro_finish (rua_macro_t *macro, rua_ctx_t *ctx); +rua_macro_t *rua_macro_arg (const rua_tok_t *token, rua_ctx_t *ctx); +void rua_start_pragma (rua_ctx_t *ctx); +void rua_start_text (rua_ctx_t *ctx); +void rua_start_expr (rua_ctx_t *ctx); +void rua_start_include (rua_ctx_t *ctx); +void rua_expand_on (rua_ctx_t *ctx); +void rua_expand_off (rua_ctx_t *ctx); +void rua_end_directive (rua_ctx_t *ctx); +void rua_start_if (bool expand, rua_ctx_t *ctx); +void rua_start_else (bool expand, rua_ctx_t *ctx); +void rua_if (bool pass, rua_ctx_t *ctx); +void rua_else (bool pass, const char *tok, rua_ctx_t *ctx); +void rua_endif (rua_ctx_t *ctx); +bool rua_defined (const char *sym, rua_ctx_t *ctx); +void rua_undefine (const char *sym, rua_ctx_t *ctx); +void rua_include_file (const char *name, rua_ctx_t *ctx); +void rua_embed_file (const char *name, rua_ctx_t *ctx); int rua_parse_define (const char *def); void rua_line_info (const expr_t *line_expr, const char *text, - const expr_t *flags_epxr, void *scanner); + const expr_t *flags_epxr, rua_ctx_t *ctx); -void rua_macro_file (rua_macro_t *macro, void *scanner); -void rua_macro_line (rua_macro_t *macro, void *scanner); -void rua_macro_va_opt (rua_macro_t *macro, void *scanner); -void rua_macro_va_args (rua_macro_t *macro, void *scanner); +void rua_macro_file (rua_macro_t *macro, rua_ctx_t *ctx); +void rua_macro_line (rua_macro_t *macro, rua_ctx_t *ctx); +void rua_macro_va_opt (rua_macro_t *macro, rua_ctx_t *ctx); +void rua_macro_va_args (rua_macro_t *macro, rua_ctx_t *ctx); void rua_print_location (FILE *out, const rua_loc_t *loc); @@ -184,41 +185,46 @@ void rua_print_location (FILE *out, const rua_loc_t *loc); typedef struct rua_parser_s { int (*parse) (rua_yypstate *state, int token, - const rua_val_t *val, rua_loc_t *loc, void *scanner); + const rua_val_t *val, rua_loc_t *loc, rua_ctx_t *ctx); rua_yypstate *state; directive_t *(*directive) (const char *token); - int (*keyword_or_id) (rua_val_t *lval, const char *token); + int (*keyword_or_id) (rua_val_t *lval, const char *token, rua_ctx_t *ctx); } rua_parser_t; -int rua_parse (FILE *in, rua_parser_t *parser); -int rua_parse_string (const char *str, rua_parser_t *parser); +int rua_parse (FILE *in, rua_parser_t *parser, rua_ctx_t *ctx); +int rua_parse_string (const char *str, rua_parser_t *parser, rua_ctx_t *ctx); const char *rua_directive_get_key (const void *dir, void *unused) __attribute__((pure)); const char *rua_keyword_get_key (const void *dir, void *unused) __attribute__((pure)); typedef struct language_s { bool initialized; - bool always_override; - void (*init) (void); - int (*parse) (FILE *in); - int (*finish) (const char *file); - void (*extension) (const char *name, const char *value, void *scanner); - void (*version) (int version, const char *profile); - bool (*on_include) (const char *name); + bool always_overload; + void (*init) (rua_ctx_t *ctx); + int (*parse) (FILE *in, rua_ctx_t *ctx); + int (*finish) (const char *file, rua_ctx_t *ctx); + void (*extension) (const char *name, const char *value, + rua_ctx_t *ctx); + void (*version) (int version, const char *profile, rua_ctx_t *ctx); + bool (*on_include) (const char *name, rua_ctx_t *ctx); void (*parse_declaration) (specifier_t spec, symbol_t *sym, const expr_t *init, symtab_t *symtab, - expr_t *block); + expr_t *block, rua_ctx_t *ctx); void *sublanguage; } language_t; -extern language_t current_language; +typedef struct rua_ctx_s { + struct rua_extra_s *extra; + void *scanner; + language_t *language; +} rua_ctx_t; extern language_t lang_ruamoko; extern language_t lang_pascal; -int qc_parse_string (const char *str); +int qc_parse_string (const char *str, rua_ctx_t *ctx); void rua_parse_declaration (specifier_t spec, symbol_t *sym, const expr_t *init, symtab_t *symtab, - expr_t *block); + expr_t *block, rua_ctx_t *ctx); #endif//__rua_lang_h diff --git a/tools/qfcc/include/target.h b/tools/qfcc/include/target.h index 46e18f39e..a0a9a34c3 100644 --- a/tools/qfcc/include/target.h +++ b/tools/qfcc/include/target.h @@ -34,6 +34,7 @@ typedef struct type_s type_t; typedef struct function_s function_t; typedef struct expr_s expr_t; typedef struct specifier_s specifier_t; +typedef struct rua_ctx_s rua_ctx_t; typedef struct { bool (*value_too_large) (const type_t *val_type); @@ -45,9 +46,9 @@ typedef struct { const expr_t *(*initialized_temp) (const type_t *type, const expr_t *src); const expr_t *(*assign_vector) (const expr_t *dst, const expr_t *src); - const expr_t *(*proc_switch) (const expr_t *expr); - const expr_t *(*proc_caselabel) (const expr_t *expr); - const expr_t *(*proc_address) (const expr_t *expr); + const expr_t *(*proc_switch) (const expr_t *expr, rua_ctx_t *ctx); + const expr_t *(*proc_caselabel) (const expr_t *expr, rua_ctx_t *ctx); + const expr_t *(*proc_address) (const expr_t *expr, rua_ctx_t *ctx); unsigned label_id; } target_t; @@ -60,9 +61,9 @@ extern target_t spirv_target; bool target_set_backend (const char *tgt); -const expr_t *ruamoko_proc_switch (const expr_t *expr); -const expr_t *ruamoko_proc_caselabel (const expr_t *expr); +const expr_t *ruamoko_proc_switch (const expr_t *expr, rua_ctx_t *ctx); +const expr_t *ruamoko_proc_caselabel (const expr_t *expr, rua_ctx_t *ctx); const expr_t *ruamoko_field_array (const expr_t *e); -const expr_t *ruamoko_proc_address (const expr_t *expr); +const expr_t *ruamoko_proc_address (const expr_t *expr, rua_ctx_t *ctx); #endif//__target_h diff --git a/tools/qfcc/source/expr_process.c b/tools/qfcc/source/expr_process.c index e064d51f3..a53ba58f6 100644 --- a/tools/qfcc/source/expr_process.c +++ b/tools/qfcc/source/expr_process.c @@ -48,19 +48,19 @@ #include "tools/qfcc/include/type.h" #include "tools/qfcc/include/value.h" -typedef const expr_t *(*process_f) (const expr_t *expr); +typedef const expr_t *(*process_f) (const expr_t *expr, rua_ctx_t *ctx); static const expr_t * -proc_expr (const expr_t *expr) +proc_expr (const expr_t *expr, rua_ctx_t *ctx) { scoped_src_loc (expr); if (expr->expr.op == 'C') { auto type = resolve_type (expr->expr.e1); - expr = expr_process (expr->expr.e2); + expr = expr_process (expr->expr.e2, ctx); return cast_expr (type, expr); } - auto e1 = expr_process (expr->expr.e1); - auto e2 = expr_process (expr->expr.e2); + auto e1 = expr_process (expr->expr.e1, ctx); + auto e2 = expr_process (expr->expr.e2, ctx); if (is_error (e1)) { return e1; } @@ -81,13 +81,13 @@ proc_expr (const expr_t *expr) } static const expr_t * -proc_uexpr (const expr_t *expr) +proc_uexpr (const expr_t *expr, rua_ctx_t *ctx) { scoped_src_loc (expr); if (expr->expr.op == '&') { - return current_target.proc_address (expr); + return current_target.proc_address (expr, ctx); } - auto e1 = expr_process (expr->expr.e1); + auto e1 = expr_process (expr->expr.e1, ctx); if (is_error (e1)) { return e1; } @@ -105,10 +105,10 @@ proc_uexpr (const expr_t *expr) } static const expr_t * -proc_field (const expr_t *expr) +proc_field (const expr_t *expr, rua_ctx_t *ctx) { scoped_src_loc (expr); - auto object = expr_process (expr->field.object); + auto object = expr_process (expr->field.object, ctx); auto member = expr->field.member; if (is_error (object)) { return object; @@ -160,7 +160,7 @@ proc_field (const expr_t *expr) member = new_deffield_expr (0, field->type, field->def); return typed_binary_expr (field->type, '.', object, member); } else { - member = expr_process (member); + member = expr_process (member, ctx); if (is_error (member)) { return member; } @@ -205,10 +205,10 @@ proc_field (const expr_t *expr) } static const expr_t * -proc_array (const expr_t *expr) +proc_array (const expr_t *expr, rua_ctx_t *ctx) { - auto base = expr_process (expr->array.base); - auto index = expr_process (expr->array.index); + auto base = expr_process (expr->array.base, ctx); + auto index = expr_process (expr->array.index, ctx); if (is_error (base)) { return base; } @@ -234,13 +234,13 @@ proc_array (const expr_t *expr) } static const expr_t * -proc_label (const expr_t *expr) +proc_label (const expr_t *expr, rua_ctx_t *ctx) { return expr; } static const expr_t * -proc_block (const expr_t *expr) +proc_block (const expr_t *expr, rua_ctx_t *ctx) { auto old_scope = current_symtab; current_symtab = expr->block.scope; @@ -252,7 +252,7 @@ proc_block (const expr_t *expr) list_scatter (&expr->block.list, in); for (int i = 0; i < count; i++) { edag_flush (); - auto e = expr_process (in[i]); + auto e = expr_process (in[i], ctx); if (e && !is_error (e)) { out[num_out++] = e; if (expr->block.result == in[i]) { @@ -317,7 +317,7 @@ static struct { }; static const expr_t * -proc_symbol (const expr_t *expr) +proc_symbol (const expr_t *expr, rua_ctx_t *ctx) { auto sym = expr->symbol; for (auto bi = builtin_names; bi->name; bi++) { @@ -341,7 +341,7 @@ proc_symbol (const expr_t *expr) } static bool -proc_do_list (ex_list_t *out, const ex_list_t *in) +proc_do_list (ex_list_t *out, const ex_list_t *in, rua_ctx_t *ctx) { int count = list_count (in); const expr_t *exprs[count + 1] = {}; @@ -349,7 +349,7 @@ proc_do_list (ex_list_t *out, const ex_list_t *in) bool ok = true; int new_count = 0; for (int i = 0; i < count; i++) { - exprs[new_count] = expr_process (exprs[i]); + exprs[new_count] = expr_process (exprs[i], ctx); // keep null expressions out of the list (non-local declarations // or local declarations without initializers return null) new_count += !!exprs[new_count]; @@ -362,66 +362,66 @@ proc_do_list (ex_list_t *out, const ex_list_t *in) } static const expr_t * -proc_vector (const expr_t *expr) +proc_vector (const expr_t *expr, rua_ctx_t *ctx) { scoped_src_loc (expr); auto list = new_expr (); list->type = ex_list; - if (!proc_do_list (&list->list, &expr->vector.list)) { + if (!proc_do_list (&list->list, &expr->vector.list, ctx)) { return new_error_expr (); } return new_vector_list (list); } static const expr_t * -proc_selector (const expr_t *expr) +proc_selector (const expr_t *expr, rua_ctx_t *ctx) { return expr; } static const expr_t * -proc_message (const expr_t *expr) +proc_message (const expr_t *expr, rua_ctx_t *ctx) { - auto receiver = expr_process (expr->message.receiver); + auto receiver = expr_process (expr->message.receiver, ctx); auto message = expr->message.message; scoped_src_loc (receiver); for (auto k = message; k; k = k->next) { if (k->expr) { - k->expr = (expr_t *) expr_process (k->expr); + k->expr = (expr_t *) expr_process (k->expr, ctx); } } return message_expr (receiver, message); } static const expr_t * -proc_nil (const expr_t *expr) +proc_nil (const expr_t *expr, rua_ctx_t *ctx) { return expr; } static const expr_t * -proc_value (const expr_t *expr) +proc_value (const expr_t *expr, rua_ctx_t *ctx) { return expr; } static const expr_t * -proc_compound (const expr_t *expr) +proc_compound (const expr_t *expr, rua_ctx_t *ctx) { scoped_src_loc (expr); auto comp = new_compound_init (); for (auto ele = expr->compound.head; ele; ele = ele->next) { - append_element (comp, new_element (expr_process (ele->expr), + append_element (comp, new_element (expr_process (ele->expr, ctx), ele->designator)); } return comp; } static const expr_t * -proc_assign (const expr_t *expr) +proc_assign (const expr_t *expr, rua_ctx_t *ctx) { - auto dst = expr_process (expr->assign.dst); - auto src = expr_process (expr->assign.src); + auto dst = expr_process (expr->assign.dst, ctx); + auto src = expr_process (expr->assign.src, ctx); if (is_error (src)) { return src; } @@ -437,24 +437,24 @@ proc_assign (const expr_t *expr) } static const expr_t * -proc_branch (const expr_t *expr) +proc_branch (const expr_t *expr, rua_ctx_t *ctx) { scoped_src_loc (expr); if (expr->branch.type == pr_branch_call) { - auto target = expr_process (expr->branch.target); + auto target = expr_process (expr->branch.target, ctx); auto args = (expr_t *) expr->branch.args; if (expr->branch.args) { args = new_list_expr (nullptr); - proc_do_list (&args->list, &expr->branch.args->list); + proc_do_list (&args->list, &expr->branch.args->list, ctx); } return function_expr (target, args); } else { auto branch = new_expr (); branch->type = ex_branch; branch->branch = expr->branch; - branch->branch.target = expr_process (expr->branch.target); - branch->branch.index = expr_process (expr->branch.index); - branch->branch.test = expr_process (expr->branch.test); + branch->branch.target = expr_process (expr->branch.target, ctx); + branch->branch.index = expr_process (expr->branch.index, ctx); + branch->branch.test = expr_process (expr->branch.test, ctx); if (is_error (branch->branch.target)) { return branch->branch.target; } @@ -469,12 +469,12 @@ proc_branch (const expr_t *expr) } static const expr_t * -proc_return (const expr_t *expr) +proc_return (const expr_t *expr, rua_ctx_t *ctx) { scoped_src_loc (expr); auto ret_val = expr->retrn.ret_val; if (ret_val) { - ret_val = expr_process (ret_val); + ret_val = expr_process (ret_val, ctx); } if (expr->retrn.at_return) { return at_return_expr (current_func, ret_val); @@ -484,18 +484,18 @@ proc_return (const expr_t *expr) } static const expr_t * -proc_list (const expr_t *expr) +proc_list (const expr_t *expr, rua_ctx_t *ctx) { scoped_src_loc (expr); auto list = new_list_expr (nullptr); - if (!proc_do_list (&list->list, &expr->list)) { + if (!proc_do_list (&list->list, &expr->list, ctx)) { return new_error_expr (); } return list; } static const expr_t * -proc_type (const expr_t *expr) +proc_type (const expr_t *expr, rua_ctx_t *ctx) { scoped_src_loc (expr); auto type = resolve_type (expr); @@ -503,10 +503,10 @@ proc_type (const expr_t *expr) } static const expr_t * -proc_incop (const expr_t *expr) +proc_incop (const expr_t *expr, rua_ctx_t *ctx) { scoped_src_loc (expr); - auto e = expr_process (expr->incop.expr); + auto e = expr_process (expr->incop.expr, ctx); if (is_error (e)) { return e; } @@ -518,12 +518,12 @@ proc_incop (const expr_t *expr) } static const expr_t * -proc_cond (const expr_t *expr) +proc_cond (const expr_t *expr, rua_ctx_t *ctx) { scoped_src_loc (expr); - auto test = expr_process (expr->cond.test); - auto true_expr = expr_process (expr->cond.true_expr); - auto false_expr = expr_process (expr->cond.false_expr); + auto test = expr_process (expr->cond.test, ctx); + auto true_expr = expr_process (expr->cond.true_expr, ctx); + auto false_expr = expr_process (expr->cond.false_expr, ctx); if (is_error (test)) { return test; } @@ -537,11 +537,12 @@ proc_cond (const expr_t *expr) } static const expr_t * -proc_decl (const expr_t *expr) +proc_decl (const expr_t *expr, rua_ctx_t *ctx) { scoped_src_loc (expr); expr_t *block = nullptr; - if (expr->decl.spec.storage == sc_local) { + auto decl_spec = expr->decl.spec; + if (decl_spec.storage == sc_local) { scoped_src_loc (expr); block = new_block_expr (nullptr); } @@ -558,7 +559,7 @@ proc_decl (const expr_t *expr) if (decl->assign.dst->type != ex_symbol) { internal_error (decl->assign.dst, "not a symbol"); } - init = expr_process (init); + init = expr_process (init, ctx); if (is_error (init)) { return init; } @@ -569,26 +570,26 @@ proc_decl (const expr_t *expr) } else { internal_error (decl, "not a symbol"); } - auto spec = expr->decl.spec; - if (sym && sym->type) { + auto spec = decl_spec; + if (sym && !spec.type_expr) { spec.type = append_type (sym->type, spec.type); spec.type = find_type (spec.type); sym->type = nullptr; } auto symtab = expr->decl.symtab; - current_language.parse_declaration (spec, sym, init, symtab, block); + ctx->language->parse_declaration (spec, sym, init, symtab, block, ctx); } edag_flush (); return block; } static const expr_t * -proc_loop (const expr_t *expr) +proc_loop (const expr_t *expr, rua_ctx_t *ctx) { - auto test = expr_process (expr->loop.test); - auto body = expr_process (expr->loop.body); + auto test = expr_process (expr->loop.test, ctx); + auto body = expr_process (expr->loop.body, ctx); auto continue_label = expr->loop.continue_label; - auto continue_body = expr_process (expr->loop.continue_body); + auto continue_body = expr_process (expr->loop.continue_body, ctx); auto break_label = expr->loop.break_label; bool do_while = expr->loop.do_while; bool not = expr->loop.not; @@ -598,11 +599,11 @@ proc_loop (const expr_t *expr) } static const expr_t * -proc_select (const expr_t *expr) +proc_select (const expr_t *expr, rua_ctx_t *ctx) { - auto test = expr_process (expr->select.test); - auto true_body = expr_process (expr->select.true_body); - auto false_body = expr_process (expr->select.false_body); + auto test = expr_process (expr->select.test, ctx); + auto true_body = expr_process (expr->select.true_body, ctx); + auto false_body = expr_process (expr->select.false_body, ctx); scoped_src_loc (expr); auto select = new_select_expr (expr->select.not, test, true_body, nullptr, false_body); @@ -611,14 +612,14 @@ proc_select (const expr_t *expr) } static const expr_t * -proc_intrinsic (const expr_t *expr) +proc_intrinsic (const expr_t *expr, rua_ctx_t *ctx) { int count = list_count (&expr->intrinsic.operands); const expr_t *operands[count + 1]; list_scatter (&expr->intrinsic.operands, operands); - auto opcode = expr_process (expr->intrinsic.opcode); + auto opcode = expr_process (expr->intrinsic.opcode, ctx); for (int i = 0; i < count; i++) { - operands[i] = expr_process (operands[i]); + operands[i] = expr_process (operands[i], ctx); } scoped_src_loc (expr); auto e = new_expr (); @@ -632,19 +633,19 @@ proc_intrinsic (const expr_t *expr) } static const expr_t * -proc_switch (const expr_t *expr) +proc_switch (const expr_t *expr, rua_ctx_t *ctx) { - return current_target.proc_switch (expr); + return current_target.proc_switch (expr, ctx); } static const expr_t * -proc_caselabel (const expr_t *expr) +proc_caselabel (const expr_t *expr, rua_ctx_t *ctx) { - return current_target.proc_caselabel (expr); + return current_target.proc_caselabel (expr, ctx); } const expr_t * -expr_process (const expr_t *expr) +expr_process (const expr_t *expr, rua_ctx_t *ctx) { if (!expr) { return expr; @@ -686,5 +687,5 @@ expr_process (const expr_t *expr) expr_names[expr->type]); } - return funcs[expr->type] (expr); + return funcs[expr->type] (expr, ctx); } diff --git a/tools/qfcc/source/function.c b/tools/qfcc/source/function.c index e9cfb3e1c..8dd2ed4a5 100644 --- a/tools/qfcc/source/function.c +++ b/tools/qfcc/source/function.c @@ -774,7 +774,7 @@ get_function (const char *name, specifier_t spec) call_params[i].type = type->func.param_types[i]; } - bool overload = spec.is_overload | current_language.always_override; + bool overload = spec.is_overload; metafunc_t *func = Hash_Find (function_map, name); if (func && func->meta_type == mf_generic) { auto genfuncs = (genfunc_t **) Hash_FindList (generic_functions, name); diff --git a/tools/qfcc/source/glsl-builtins.c b/tools/qfcc/source/glsl-builtins.c index ed5b9611c..7e1dc21e7 100644 --- a/tools/qfcc/source/glsl-builtins.c +++ b/tools/qfcc/source/glsl-builtins.c @@ -36,6 +36,7 @@ #include "tools/qfcc/include/struct.h" #include "tools/qfcc/include/type.h" +glsl_sublang_t glsl_sublang; glsl_imageset_t glsl_imageset = DARRAY_STATIC_INIT (16); static struct_def_t glsl_image_struct[] = { @@ -918,7 +919,7 @@ glsl_multiview (int behavior, void *scanner) static int glsl_include_state = 0; bool -glsl_on_include (const char *name) +glsl_on_include (const char *name, rua_ctx_t *ctx) { if (!glsl_include_state) { error (0, "'#include' : required extension not requested"); @@ -937,13 +938,13 @@ glsl_include (int behavior, void *scanner) } static void -glsl_parse_vars (const char *var_src) +glsl_parse_vars (const char *var_src, rua_ctx_t *ctx) { - glsl_parse_string (var_src); + glsl_parse_string (var_src, ctx); } static void -glsl_init_common (void) +glsl_init_common (rua_ctx_t *ctx) { static module_t module; //FIXME probably not what I want pr.module = &module; @@ -958,63 +959,66 @@ glsl_init_common (void) spirv_set_addressing_model (pr.module, SpvAddressingModelLogical); spirv_set_memory_model (pr.module, SpvMemoryModelGLSL450); - current_language.initialized = true; + glsl_sublang = *(glsl_sublang_t *) ctx->language->sublanguage; + ctx->language->initialized = true; glsl_block_clear (); - qc_parse_string (glsl_general_functions); - glsl_parse_vars (glsl_system_constants); + rua_ctx_t rua_ctx = { .language = &lang_ruamoko }; + qc_parse_string (glsl_general_functions, &rua_ctx); + glsl_parse_vars (glsl_system_constants, ctx); } void -glsl_init_comp (void) +glsl_init_comp (rua_ctx_t *ctx) { - glsl_init_common (); - glsl_parse_vars (glsl_compute_vars); + glsl_init_common (ctx); + glsl_parse_vars (glsl_compute_vars, ctx); spirv_add_capability (pr.module, SpvCapabilityShader); } void -glsl_init_vert (void) +glsl_init_vert (rua_ctx_t *ctx) { - glsl_init_common (); - glsl_parse_vars (glsl_Vulkan_vertex_vars); + glsl_init_common (ctx); + glsl_parse_vars (glsl_Vulkan_vertex_vars, ctx); spirv_add_capability (pr.module, SpvCapabilityShader); } void -glsl_init_tesc (void) +glsl_init_tesc (rua_ctx_t *ctx) { - glsl_init_common (); - glsl_parse_vars (glsl_tesselation_control_vars); + glsl_init_common (ctx); + glsl_parse_vars (glsl_tesselation_control_vars, ctx); spirv_add_capability (pr.module, SpvCapabilityTessellation); } void -glsl_init_tese (void) +glsl_init_tese (rua_ctx_t *ctx) { - glsl_init_common (); - glsl_parse_vars (glsl_tesselation_evaluation_vars); + glsl_init_common (ctx); + glsl_parse_vars (glsl_tesselation_evaluation_vars, ctx); spirv_add_capability (pr.module, SpvCapabilityTessellation); } void -glsl_init_geom (void) +glsl_init_geom (rua_ctx_t *ctx) { - glsl_init_common (); - glsl_parse_vars (glsl_geometry_vars); - qc_parse_string (glsl_geometry_functions); + glsl_init_common (ctx); + glsl_parse_vars (glsl_geometry_vars, ctx); + rua_ctx_t rua_ctx = { .language = &lang_ruamoko }; + qc_parse_string (glsl_geometry_functions, &rua_ctx); spirv_add_capability (pr.module, SpvCapabilityGeometry); } void -glsl_init_frag (void) +glsl_init_frag (rua_ctx_t *ctx) { - glsl_init_common (); - glsl_parse_vars (glsl_fragment_vars); + glsl_init_common (ctx); + glsl_parse_vars (glsl_fragment_vars, ctx); spirv_add_capability (pr.module, SpvCapabilityShader); } diff --git a/tools/qfcc/source/glsl-declaration.c b/tools/qfcc/source/glsl-declaration.c index ae2bf822d..7cea704ca 100644 --- a/tools/qfcc/source/glsl-declaration.c +++ b/tools/qfcc/source/glsl-declaration.c @@ -43,7 +43,7 @@ void glsl_parse_declaration (specifier_t spec, symbol_t *sym, const expr_t *init, - symtab_t *symtab, expr_t *block) + symtab_t *symtab, expr_t *block, rua_ctx_t *ctx) { if (sym && sym->type) { internal_error (0, "unexected typed symbol"); @@ -105,7 +105,7 @@ glsl_parse_declaration (specifier_t spec, symbol_t *sym, const expr_t *init, } void -glsl_declare_field (specifier_t spec, symtab_t *symtab) +glsl_declare_field (specifier_t spec, symtab_t *symtab, rua_ctx_t *ctx) { auto attributes = glsl_optimize_attributes (spec.attributes); spec.sym = declare_field (spec, symtab); diff --git a/tools/qfcc/source/glsl-parse.y b/tools/qfcc/source/glsl-parse.y index c4145ef26..cd56172fc 100644 --- a/tools/qfcc/source/glsl-parse.y +++ b/tools/qfcc/source/glsl-parse.y @@ -32,7 +32,7 @@ %define api.push-pull push %define api.token.prefix {GLSL_} %locations -%parse-param {void *scanner} +%parse-param {struct rua_ctx_s *ctx} %define api.value.type {rua_val_t} %define api.location.type {rua_loc_t} @@ -82,11 +82,11 @@ #include "tools/qfcc/source/glsl-parse.h" -#define glsl_yytext qc_yyget_text (scanner) +#define glsl_yytext qc_yyget_text (ctx->scanner) char *qc_yyget_text (void *scanner); static void -yyerror (YYLTYPE *yylloc, void *scanner, const char *s) +yyerror (YYLTYPE *yylloc, rua_ctx_t *ctx, const char *s) { #ifdef GLSL_YYERROR_VERBOSE error (0, "%s %s\n", glsl_yytext, s); @@ -97,7 +97,7 @@ yyerror (YYLTYPE *yylloc, void *scanner, const char *s) } static void __attribute__((used)) -parse_error (void *scanner) +parse_error (rua_ctx_t *ctx) { error (0, "parse error before %s", glsl_yytext); } @@ -321,7 +321,7 @@ translation_unit external_declaration : function_definition - | declaration { if ($1) expr_process ($1); } + | declaration { if ($1) expr_process ($1, ctx); } | ';' ; @@ -331,6 +331,7 @@ function_definition $$ = current_symtab; auto spec = $1; spec.sym->params = spec.params; + spec.is_overload = true; auto sym = function_symbol (spec); current_func = begin_function (sym, nullptr, current_symtab, false, spec.storage); @@ -343,7 +344,7 @@ function_definition { auto spec = $1; auto sym = spec.sym; - expr_t *statments = (expr_t *) expr_process ($3); + expr_t *statments = (expr_t *) expr_process ($3, ctx); build_code_function (sym, nullptr, statments); current_symtab = $2; current_storage = sc_global;//FIXME @@ -662,7 +663,7 @@ declaration | type_qualifier ';' { glsl_parse_declaration ($type_qualifier, nullptr, - nullptr, current_symtab, nullptr); + nullptr, current_symtab, nullptr, ctx); $$ = nullptr; } | type_qualifier new_identifier ';' @@ -1070,7 +1071,7 @@ struct_declarator { auto spec = $0; spec.sym = $1; - glsl_declare_field (spec, current_symtab); + glsl_declare_field (spec, current_symtab, ctx); } | new_identifier array_specifier { @@ -1078,7 +1079,7 @@ struct_declarator spec.type = append_type ($2, spec.type); spec.type = find_type (spec.type); spec.sym = $1; - glsl_declare_field (spec, current_symtab); + glsl_declare_field (spec, current_symtab, ctx); } ; @@ -1639,7 +1640,7 @@ find_image_sub (image_sub_t *sub, const char *str) } static symbol_t * -glsl_parse_image (const char *token) +glsl_parse_image (const char *token, rua_ctx_t *ctx) { static image_sub_t image_type[] = { { .substr = "sampler", .val = 0, .type = &type_float }, @@ -1750,12 +1751,13 @@ invalid: } static int -glsl_process_keyword (rua_val_t *lval, keyword_t *keyword, const char *token) +glsl_process_keyword (rua_val_t *lval, keyword_t *keyword, const char *token, + rua_ctx_t *ctx) { if (keyword->value == GLSL_STRUCT) { lval->op = token[0]; } else if (keyword->value == GLSL_TYPE_SPEC && !keyword->spec.type) { - auto sym = glsl_parse_image (token); + auto sym = glsl_parse_image (token, ctx); keyword->spec.type = sym->type; lval->spec = keyword->spec; } else if (keyword->use_name) { @@ -1767,7 +1769,7 @@ glsl_process_keyword (rua_val_t *lval, keyword_t *keyword, const char *token) } static int -glsl_keyword_or_id (rua_val_t *lval, const char *token) +glsl_keyword_or_id (rua_val_t *lval, const char *token, rua_ctx_t *ctx) { static hashtab_t *glsl_keyword_tab; @@ -1784,7 +1786,7 @@ glsl_keyword_or_id (rua_val_t *lval, const char *token) } keyword = Hash_Find (glsl_keyword_tab, token); if (keyword && keyword->value) - return glsl_process_keyword (lval, keyword, token); + return glsl_process_keyword (lval, keyword, token, ctx); if (token[0] == '@') { return '@'; } @@ -1803,7 +1805,7 @@ glsl_keyword_or_id (rua_val_t *lval, const char *token) } static int -glsl_yyparse (FILE *in) +glsl_yyparse (FILE *in, rua_ctx_t *ctx) { rua_parser_t parser = { .parse = glsl_yypush_parse, @@ -1811,13 +1813,13 @@ glsl_yyparse (FILE *in) .directive = glsl_directive, .keyword_or_id = glsl_keyword_or_id, }; - int ret = rua_parse (in, &parser); + int ret = rua_parse (in, &parser, ctx); glsl_yypstate_delete (parser.state); return ret; } int -glsl_parse_string (const char *str) +glsl_parse_string (const char *str, rua_ctx_t *ctx) { rua_parser_t parser = { .parse = glsl_yypush_parse, @@ -1825,7 +1827,8 @@ glsl_parse_string (const char *str) .directive = glsl_directive, .keyword_or_id = glsl_keyword_or_id, }; - int ret = rua_parse_string (str, &parser); + auto glsl_ctx = *ctx; + int ret = rua_parse_string (str, &parser, &glsl_ctx); glsl_yypstate_delete (parser.state); return ret; } @@ -1866,9 +1869,9 @@ behavior_cmp (const void *_a, const void *_b) } static void -glsl_extension (const char *name, const char *value, void *scanner) +glsl_extension (const char *name, const char *value, rua_ctx_t *ctx) { - if (current_language.initialized) { + if (ctx->language->initialized) { error (0, "extensions directives must occur before any " "non-preprocessor tokens"); return; @@ -1887,7 +1890,7 @@ glsl_extension (const char *name, const char *value, void *scanner) return; } for (size_t i = 0; i < num_extensions; i++) { - glsl_extensions[i].set_behavior (behavior, scanner); + glsl_extensions[i].set_behavior (behavior, ctx); } } else { glsl_ext_t key = { .name = name }; @@ -1895,7 +1898,7 @@ glsl_extension (const char *name, const char *value, void *scanner) ext = bsearch (&key, glsl_extensions, num_extensions, sizeof (glsl_ext_t), extension_cmp); if (ext) { - ext->set_behavior (behavior, scanner); + ext->set_behavior (behavior, ctx); } else { if (behavior == 2) { error (0, "unknown extension '%s'", name); @@ -1907,7 +1910,7 @@ glsl_extension (const char *name, const char *value, void *scanner) } static void -glsl_version (int version, const char *profile) +glsl_version (int version, const char *profile, rua_ctx_t *ctx) { if (!profile || strcmp (profile, "core") == 0) { // ok @@ -1924,7 +1927,7 @@ glsl_version (int version, const char *profile) } language_t lang_glsl_comp = { - .always_override = true, + .always_overload = true, .init = glsl_init_comp, .parse = glsl_yyparse, .extension = glsl_extension, @@ -1935,7 +1938,7 @@ language_t lang_glsl_comp = { }; language_t lang_glsl_vert = { - .always_override = true, + .always_overload = true, .init = glsl_init_vert, .parse = glsl_yyparse, .extension = glsl_extension, @@ -1946,7 +1949,7 @@ language_t lang_glsl_vert = { }; language_t lang_glsl_tesc = { - .always_override = true, + .always_overload = true, .init = glsl_init_tesc, .parse = glsl_yyparse, .extension = glsl_extension, @@ -1957,7 +1960,7 @@ language_t lang_glsl_tesc = { }; language_t lang_glsl_tese = { - .always_override = true, + .always_overload = true, .init = glsl_init_tese, .parse = glsl_yyparse, .extension = glsl_extension, @@ -1968,7 +1971,7 @@ language_t lang_glsl_tese = { }; language_t lang_glsl_geom = { - .always_override = true, + .always_overload = true, .init = glsl_init_geom, .parse = glsl_yyparse, .extension = glsl_extension, @@ -1979,7 +1982,7 @@ language_t lang_glsl_geom = { }; language_t lang_glsl_frag = { - .always_override = true, + .always_overload = true, .init = glsl_init_frag, .parse = glsl_yyparse, .extension = glsl_extension, diff --git a/tools/qfcc/source/pre-parse.y b/tools/qfcc/source/pre-parse.y index 4ea399ac1..ea4519431 100644 --- a/tools/qfcc/source/pre-parse.y +++ b/tools/qfcc/source/pre-parse.y @@ -32,7 +32,7 @@ %define api.push-pull push %define api.token.prefix {PRE_} %locations -%parse-param {void *scanner} +%parse-param {struct rua_ctx_s *ctx} %{ #ifdef HAVE_CONFIG_H @@ -56,11 +56,11 @@ #include "tools/qfcc/source/pre-parse.h" -#define pre_yytext qc_yyget_text (scanner) +#define pre_yytext qc_yyget_text (ctx->scanner) char *qc_yyget_text (void *scanner); static void -yyerror (YYLTYPE *yylloc, void *scanner, const char *s) +yyerror (YYLTYPE *yylloc, rua_ctx_t *ctx, const char *s) { const char *text = quote_string (pre_yytext); #ifdef YYERROR_VERBOSE @@ -71,13 +71,13 @@ yyerror (YYLTYPE *yylloc, void *scanner, const char *s) } #if 0 static void -parse_error (void *scanner) +parse_error (rua_ctx_t *ctx) { const char *text = pre_yytext; error (0, "parse error before %s", text); } -#define PARSE_ERROR do { parse_error (scanner); YYERROR; } while (0) +#define PARSE_ERROR do { parse_error (ctx); YYERROR; } while (0) #endif #define YYLLOC_DEFAULT(Current, Rhs, N) RUA_LOC_DEFAULT(Current, Rhs, N) @@ -188,7 +188,7 @@ start : directive_list | ARGS { - $$ = rua_macro_arg (&$1, scanner); + $$ = rua_macro_arg (&$1, ctx); } args ')' { YYACCEPT; } ; @@ -198,19 +198,19 @@ directive_list | directive_list directive ; -eod : EOD { rua_end_directive (scanner); } ; +eod : EOD { rua_end_directive (ctx); } ; directive - : INCLUDE incexp string extra_warn { rua_include_file ($3, scanner); } - | EMBED incexp string extra_ignore { rua_embed_file ($3, scanner); } - | DEFINE ID { $$ = rua_start_macro ($2, false, scanner); } - body { rua_macro_finish ($body, scanner); } + : INCLUDE incexp string extra_warn { rua_include_file ($3, ctx); } + | EMBED incexp string extra_ignore { rua_embed_file ($3, ctx); } + | DEFINE ID { $$ = rua_start_macro ($2, false, ctx); } + body { rua_macro_finish ($body, ctx); } eod - | DEFINE IDp { $$ = rua_start_macro ($2, true, scanner); } - opt_params ')' { $$ = rua_end_params ($3, scanner); } - body { rua_macro_finish ($body, scanner); } + | DEFINE IDp { $$ = rua_start_macro ($2, true, ctx); } + opt_params ')' { $$ = rua_end_params ($3, ctx); } + body { rua_macro_finish ($body, ctx); } eod - | UNDEF ID { rua_undefine ($2, scanner); } + | UNDEF ID { rua_undefine ($2, ctx); } extra_warn | ERROR text { error (0, "%s", $text->str); dstring_delete ($text); } eod @@ -218,39 +218,39 @@ directive eod | NOTICE text { notice (0, "%s", $text->str); dstring_delete ($text); } eod - | PRAGMA expand { rua_start_pragma (scanner); } + | PRAGMA expand { rua_start_pragma (ctx); } pragma_params { pragma_process (); } eod | LINE expand expr extra_warn - { rua_line_info ($3, 0, 0, scanner); } + { rua_line_info ($3, 0, 0, ctx); } | LINE expand expr string line_expr extra_warn - { rua_line_info ($3, $4, $5, scanner); } - | IF { rua_start_if (true, scanner); } - expr { rua_if (expr_long ($3), scanner); } + { rua_line_info ($3, $4, $5, ctx); } + | IF { rua_start_if (true, ctx); } + expr { rua_if (expr_long ($3), ctx); } eod - | IFDEF { rua_start_if (false, scanner); } - ID { rua_if (rua_defined ($3, scanner), scanner); } + | IFDEF { rua_start_if (false, ctx); } + ID { rua_if (rua_defined ($3, ctx), ctx); } extra_warn - | IFNDEF { rua_start_if (false, scanner); } - ID { rua_if (!rua_defined ($3, scanner), scanner); } + | IFNDEF { rua_start_if (false, ctx); } + ID { rua_if (!rua_defined ($3, ctx), ctx); } extra_warn - | ELSE { rua_else (true, "else", scanner); } + | ELSE { rua_else (true, "else", ctx); } extra_warn - | ELIF { rua_start_else (true, scanner); } - expr { rua_else (expr_long ($3), "elif", scanner); } + | ELIF { rua_start_else (true, ctx); } + expr { rua_else (expr_long ($3), "elif", ctx); } eod - | ELIFDEF { rua_start_else (false, scanner); } - ID { rua_else (rua_defined ($3, scanner), "elifdef", scanner); } + | ELIFDEF { rua_start_else (false, ctx); } + ID { rua_else (rua_defined ($3, ctx), "elifdef", ctx); } extra_warn - | ELIFNDEF { rua_start_else (false, scanner); } - ID { rua_else (!rua_defined ($3, scanner), "elifndef", scanner); } + | ELIFNDEF { rua_start_else (false, ctx); } + ID { rua_else (!rua_defined ($3, ctx), "elifndef", ctx); } extra_warn - | ENDIF { rua_endif (scanner); } + | ENDIF { rua_endif (ctx); } extra_warn | EXTENSION ID ':' ID { - if (current_language.extension) { - current_language.extension ($2, $4, scanner); + if (ctx->language->extension) { + ctx->language->extension ($2, $4, ctx); } else { internal_error (0, "invalid directive"); } @@ -258,9 +258,9 @@ directive extra_warn | VERSION VALUE opt_profile { - if (current_language.version) { + if (ctx->language->version) { auto version = get_long ($2, $2, 460); - current_language.version (expr_long (version), $3); + ctx->language->version (expr_long (version), $3, ctx); } else { internal_error (0, "invalid directive"); } @@ -281,7 +281,7 @@ extra_ignore : {} eod ; -text: { rua_start_text (scanner); $$ = dstring_new (); } text_text +text: { rua_start_text (ctx); $$ = dstring_new (); } text_text { $text = $text_text; } ; text_text @@ -290,7 +290,7 @@ text_text ; body: /* empty */ { $$ = $0; } - | body body_token { $$ = rua_macro_append ($1, &$2, scanner); } + | body body_token { $$ = rua_macro_append ($1, &$2, ctx); } ; body_token @@ -301,11 +301,11 @@ body_token ; incexp - : { rua_start_include (scanner); } + : { rua_start_include (ctx); } ; expand - : { rua_start_expr (scanner); } + : { rua_start_expr (ctx); } ; pragma_params @@ -324,14 +324,14 @@ opt_params ; params - : TOKEN { $$ = rua_macro_param ($0, &$1, scanner); } - | params ',' TOKEN { $$ = rua_macro_param ($1, &$3, scanner); } + : TOKEN { $$ = rua_macro_param ($0, &$1, ctx); } + | params ',' TOKEN { $$ = rua_macro_param ($1, &$3, ctx); } ; args: arg_list | args ',' { - $$ = rua_macro_arg (&$2, scanner); + $$ = rua_macro_arg (&$2, ctx); } arg_list ; @@ -341,18 +341,18 @@ arg_list | arg_list arg { $$ = $2; } ; -arg : '(' { $$ = rua_macro_append ($0, &$1, scanner); } +arg : '(' { $$ = rua_macro_append ($0, &$1, ctx); } arg_clist { $$ = $2; } - ')' { $$ = rua_macro_append ($4, &$5, scanner); } - | TOKEN { $$ = rua_macro_append ($0, &$1, scanner); } - | VALUE { $$ = rua_macro_append ($0, &$1, scanner); } - | ID { $$ = rua_macro_append ($0, &$1, scanner); } + ')' { $$ = rua_macro_append ($4, &$5, ctx); } + | TOKEN { $$ = rua_macro_append ($0, &$1, ctx); } + | VALUE { $$ = rua_macro_append ($0, &$1, ctx); } + | ID { $$ = rua_macro_append ($0, &$1, ctx); } ; arg_clist : /* emtpy */ { $$ = $0; } | arg_clist arg { $$ = $2; } - | arg_clist ',' { $$ = rua_macro_append ($1, &$2, scanner); } + | arg_clist ',' { $$ = rua_macro_append ($1, &$2, ctx); } ; id : ID { $$ = new_long_expr (0, false); } @@ -366,7 +366,7 @@ defined //the token's text is quite ephemeral when short (the usual case) defined_id - : ID { $$ = new_long_expr (rua_defined ($1, scanner), false); } + : ID { $$ = new_long_expr (rua_defined ($1, ctx), false); } ; unary_expr @@ -374,8 +374,8 @@ unary_expr | VALUE { $$ = get_long ($1, $1, 1); } | QSTRING { $$ = get_long (0, $1, 1); } | '(' expr ')' { $$ = $2; } - | DEFINED { rua_expand_off (scanner); } - defined { rua_expand_on (scanner); $$ = $3; } + | DEFINED { rua_expand_off (ctx); } + defined { rua_expand_on (ctx); $$ = $3; } | '+' unary_expr { $$ = $2; } | '-' unary_expr { $$ = UEXPR (-, $2); } | '~' unary_expr { $$ = UEXPR (~, $2); } diff --git a/tools/qfcc/source/qc-lex.l b/tools/qfcc/source/qc-lex.l index fe2941e95..7bdbc546c 100644 --- a/tools/qfcc/source/qc-lex.l +++ b/tools/qfcc/source/qc-lex.l @@ -995,7 +995,7 @@ convert_long (const expr_t *value) static int qc_token (rua_extra_t *extra, rua_val_t *lval, const rua_tok_t *tok, - yyscan_t scanner) + yyscan_t scanner, rua_ctx_t *ctx) { int token = tok->token; @@ -1010,7 +1010,7 @@ qc_token (rua_extra_t *extra, rua_val_t *lval, const rua_tok_t *tok, case rua_error: break; case rua_id: - token = extra->parser->keyword_or_id (lval, tok->text); + token = extra->parser->keyword_or_id (lval, tok->text, ctx); break; case rua_grab: { @@ -1141,7 +1141,8 @@ dump_macro (rua_macro_t *macro) } static int -qc_process (rua_extra_t *extra, int token, rua_tok_t *tok, yyscan_t scanner) +qc_process (rua_extra_t *extra, int token, rua_tok_t *tok, yyscan_t scanner, + rua_ctx_t *ctx) { auto loc = &tok->location; @@ -1159,7 +1160,7 @@ qc_process (rua_extra_t *extra, int token, rua_tok_t *tok, yyscan_t scanner) if (-token == rua_ignore) { return YYPUSH_MORE; } - return pre_yypush_parse (state, token, &lval, loc, scanner); + return pre_yypush_parse (state, token, &lval, loc, ctx); } else { if (!extra->suppressed) { if (options.preprocess_only) { @@ -1171,14 +1172,14 @@ qc_process (rua_extra_t *extra, int token, rua_tok_t *tok, yyscan_t scanner) } return token ? YYPUSH_MORE : 0; } - if (!current_language.initialized && current_language.init) { - current_language.init (); + if (!ctx->language->initialized && ctx->language->init) { + ctx->language->init (ctx); } QC_YYSTYPE lval = {}; - token = qc_token (extra, &lval, tok, scanner); + token = qc_token (extra, &lval, tok, scanner, ctx); if (token >= 0) { auto p = extra->parser; - return p->parse (p->state, token, &lval, loc, scanner); + return p->parse (p->state, token, &lval, loc, ctx); } } } @@ -1195,14 +1196,14 @@ next_macro_token (rua_macro_t *macro) static const rua_tok_t * get_arg_token (bool last, const rua_tok_t *arg, const rua_macro_t *macro, - yyscan_t scanner) + yyscan_t scanner, rua_ctx_t *ctx) { symbol_t *sym; if (arg->token == -rua_va_opt) { sym = symtab_lookup (macro->params, arg->text); auto m = sym->macro; - m->update (m, scanner); + m->update (m, ctx); if (last) { if (m->tokens) { return (rua_tok_t *) m->tail; @@ -1383,7 +1384,7 @@ check_macro (rua_macro_t *macro) } static int -next_token (rua_tok_t *tok, yyscan_t scanner) +next_token (rua_tok_t *tok, yyscan_t scanner, rua_ctx_t *ctx) { auto extra = qc_yyget_extra (scanner); rescan: @@ -1432,7 +1433,7 @@ rescan: if (n->token == -rua_va_opt) { sym = symtab_lookup (macro->params, n->text); auto m = sym->macro; - m->update (m, scanner); + m->update (m, ctx); arg = m; } else { sym = symtab_lookup (macro->params, n->text); @@ -1448,8 +1449,8 @@ rescan: bool sf = false; bool sl; do { - auto p = get_arg_token (true, &e, macro, scanner); - auto n = get_arg_token (false, e.next->next, macro, scanner); + auto p = get_arg_token (true, &e, macro, scanner, ctx); + auto n = get_arg_token (false, e.next->next, macro, scanner, ctx); rua_tok_t cat; if (!(sl = join_tokens (&cat, p, n, extra))) { cat.location = e.next->location; @@ -1476,7 +1477,7 @@ rescan: } sym = symtab_lookup (macro->params, e.text); auto m = sym->macro; - m->update (m, scanner); + m->update (m, ctx); queue_macro (extra, m); goto rescan; } else if (token == -rua_id && macro->params @@ -1492,7 +1493,7 @@ rescan: // force object-type macros in macro arguments to be expanded auto m = sym->macro; if (m->update) { - m->update (m, scanner); + m->update (m, ctx); } queue_macro (extra, m); goto rescan; @@ -1513,7 +1514,7 @@ rescan: collect_args (m, macro, scanner); if (macro->cursor != c) { if (m->update) { - m->update (m, scanner); + m->update (m, ctx); } queue_macro (extra, m); goto rescan; @@ -1528,7 +1529,7 @@ rescan: if (extra->recording) { token = preproc_token (extra, &lval, &e, scanner); int s = pre_yypush_parse (extra->args_state, token, &lval, - &e.location, scanner); + &e.location, ctx); if (s == YYPUSH_MORE) { goto rescan; } @@ -1563,7 +1564,7 @@ rescan: && !sym->macro->next) { auto macro = sym->macro; if (macro->update) { - macro->update (macro, scanner); + macro->update (macro, ctx); } if (macro->params) { // function-type macro, need to check for ( so set up a temporary @@ -1618,13 +1619,13 @@ rua_destroy_scanner (yyscan_t scanner, rua_extra_t *extra) } static int -rua_do_scan (yyscan_t scanner) +rua_do_scan (yyscan_t scanner, rua_ctx_t *ctx) { auto extra = qc_yyget_extra (scanner); int status; rua_tok_t tok = {}; do { - int token = next_token (&tok, scanner); + int token = next_token (&tok, scanner, ctx); if (!token && extra->cond_stack.size) { int ind = extra->cond_stack.size - 1; auto cond = extra->cond_stack.a[ind]; @@ -1643,42 +1644,44 @@ rua_do_scan (yyscan_t scanner) extra->cond_stack = incl.cond_stack; continue; } - status = qc_process (extra, token, &tok, scanner); + status = qc_process (extra, token, &tok, scanner, ctx); } while (status == YYPUSH_MORE); return status; } int -rua_parse (FILE *in, rua_parser_t *parser) +rua_parse (FILE *in, rua_parser_t *parser, rua_ctx_t *ctx) { rua_extra_t extra; - yyscan_t scanner = rua_init_scanner (&extra, parser); - yyset_in (in, scanner); - int status = rua_do_scan (scanner); - rua_destroy_scanner (scanner, &extra); + ctx->extra = &extra; + ctx->scanner = rua_init_scanner (&extra, parser); + yyset_in (in, ctx->scanner); + int status = rua_do_scan (ctx->scanner, ctx); + rua_destroy_scanner (ctx->scanner, &extra); return status; } int -rua_parse_string (const char *str, rua_parser_t *parser) +rua_parse_string (const char *str, rua_parser_t *parser, rua_ctx_t *ctx) { auto loc = pr.loc; rua_extra_t extra; - yyscan_t scanner = rua_init_scanner (&extra, parser); - yy_scan_string (str, scanner); - int status = rua_do_scan (scanner); - rua_destroy_scanner (scanner, &extra); + ctx->extra = &extra; + ctx->scanner = rua_init_scanner (&extra, parser); + yy_scan_string (str, ctx->scanner); + int status = rua_do_scan (ctx->scanner, ctx); + rua_destroy_scanner (ctx->scanner, &extra); pr.loc = loc; return status; } rua_macro_t * -rua_start_macro (const char *name, bool params, void *scanner) +rua_start_macro (const char *name, bool params, rua_ctx_t *ctx) { - auto extra = qc_yyget_extra (scanner); + auto extra = ctx->extra; if (extra->suppressed) { return 0; } @@ -1694,16 +1697,16 @@ rua_start_macro (const char *name, bool params, void *scanner) } } - yy_pop_state (scanner); - yy_push_state (MACRO, scanner); + yy_pop_state (ctx->scanner); + yy_push_state (MACRO, ctx->scanner); return alloc_macro (name, params); } rua_macro_t * -rua_end_params (rua_macro_t *macro, void *scanner) +rua_end_params (rua_macro_t *macro, rua_ctx_t *ctx) { - auto extra = qc_yyget_extra (scanner); + auto extra = ctx->extra; if (extra->suppressed) { return 0; } @@ -1713,9 +1716,9 @@ rua_end_params (rua_macro_t *macro, void *scanner) } rua_macro_t * -rua_macro_append (rua_macro_t *macro, const rua_tok_t *token, void *scanner) +rua_macro_append (rua_macro_t *macro, const rua_tok_t *token, rua_ctx_t *ctx) { - auto extra = qc_yyget_extra (scanner); + auto extra = ctx->extra; if (extra->suppressed || !macro) { return 0; } @@ -1724,9 +1727,9 @@ rua_macro_append (rua_macro_t *macro, const rua_tok_t *token, void *scanner) } rua_macro_t * -rua_macro_param (rua_macro_t *macro, const rua_tok_t *token, void *scanner) +rua_macro_param (rua_macro_t *macro, const rua_tok_t *token, rua_ctx_t *ctx) { - auto extra = qc_yyget_extra (scanner); + auto extra = ctx->extra; if (extra->suppressed) { return 0; } @@ -1795,9 +1798,9 @@ build_va_opt (rua_macro_t *macro, rua_tok_t *t, rua_tok_t *u, int va_opt_ind) } void -rua_macro_finish (rua_macro_t *macro, void *scanner) +rua_macro_finish (rua_macro_t *macro, rua_ctx_t *ctx) { - auto extra = qc_yyget_extra (scanner); + auto extra = ctx->extra; if (extra->suppressed) { return; } @@ -1890,14 +1893,14 @@ hashhash_error: } rua_macro_t * -rua_macro_arg (const rua_tok_t *token, void *scanner) +rua_macro_arg (const rua_tok_t *token, rua_ctx_t *ctx) { - auto extra = qc_yyget_extra (scanner); + auto extra = ctx->extra; auto macro = extra->pending_macro; rua_macro_t *arg; if (macro->num_params < 0 && macro->num_args == -macro->num_params) { arg = macro->args[macro->num_args - 1]; - rua_macro_append (arg, token, scanner); + rua_macro_append (arg, token, ctx->scanner); } else { if (macro->num_args < macro->num_params || macro->num_args < -macro->num_params) { @@ -1912,64 +1915,64 @@ rua_macro_arg (const rua_tok_t *token, void *scanner) } void -rua_start_pragma (void *scanner) +rua_start_pragma (rua_ctx_t *ctx) { if (options.preprocess_output) { printf ("#pragma"); } - yy_pop_state (scanner); - yy_push_state (PRAGMA, scanner); + yy_pop_state (ctx->scanner); + yy_push_state (PRAGMA, ctx->scanner); } void -rua_start_text (void *scanner) +rua_start_text (rua_ctx_t *ctx) { - yy_pop_state (scanner); - yy_push_state (TEXT, scanner); + yy_pop_state (ctx->scanner); + yy_push_state (TEXT, ctx->scanner); } void -rua_start_include (void *scanner) +rua_start_include (rua_ctx_t *ctx) { - auto extra = qc_yyget_extra (scanner); + auto extra = ctx->extra; extra->expand = true; - yy_pop_state (scanner); - yy_push_state (PREPROC, scanner); + yy_pop_state (ctx->scanner); + yy_push_state (PREPROC, ctx->scanner); } void -rua_start_expr (void *scanner) +rua_start_expr (rua_ctx_t *ctx) { - auto extra = qc_yyget_extra (scanner); + auto extra = ctx->extra; extra->expand = !extra->suppressed; - yy_pop_state (scanner); - yy_push_state (PREEXPR, scanner); + yy_pop_state (ctx->scanner); + yy_push_state (PREEXPR, ctx->scanner); } void -rua_expand_on (void *scanner) +rua_expand_on (rua_ctx_t *ctx) { - auto extra = qc_yyget_extra (scanner); + auto extra = ctx->extra; extra->expand = !extra->suppressed; } void -rua_expand_off (void *scanner) +rua_expand_off (rua_ctx_t *ctx) { - auto extra = qc_yyget_extra (scanner); + auto extra = ctx->extra; extra->expand = false; } void -rua_end_directive (void *scanner) +rua_end_directive (rua_ctx_t *ctx) { - auto extra = qc_yyget_extra (scanner); + auto extra = ctx->extra; extra->preprocessor = false; extra->recording = false; extra->expand = false; - yy_pop_state (scanner); + yy_pop_state (ctx->scanner); } static void @@ -2016,9 +2019,9 @@ dump_token (rua_tok_t *tok, rua_loc_t *loc, int state) } void -rua_start_if (bool expand, void *scanner) +rua_start_if (bool expand, rua_ctx_t *ctx) { - auto extra = qc_yyget_extra (scanner); + auto extra = ctx->extra; rua_cond_t cond = { .saw_true = false, .saw_else = false, @@ -2033,49 +2036,49 @@ rua_start_if (bool expand, void *scanner) DARRAY_APPEND (&extra->cond_stack, cond); extra->expand = expand; - yy_pop_state (scanner); - yy_push_state (PREEXPR, scanner); + yy_pop_state (ctx->scanner); + yy_push_state (PREEXPR, ctx->scanner); } void -rua_start_else (bool expand, void *scanner) +rua_start_else (bool expand, rua_ctx_t *ctx) { - auto extra = qc_yyget_extra (scanner); + auto extra = ctx->extra; extra->expand = expand; - yy_pop_state (scanner); - yy_push_state (PREEXPR, scanner); + yy_pop_state (ctx->scanner); + yy_push_state (PREEXPR, ctx->scanner); } void -rua_if (bool pass, void *scanner) +rua_if (bool pass, rua_ctx_t *ctx) { - auto extra = qc_yyget_extra (scanner); + auto extra = ctx->extra; if (!extra->cond_stack.size) { internal_error (0, "#if without start_if"); return; } auto cond = &extra->cond_stack.a[extra->cond_stack.size - 1]; cond->saw_true = cond->enabled = pass; - //yy_pop_state (scanner); // remove DIRECTIVE/PREEXPR state + //yy_pop_state (ctx->scanner); // remove DIRECTIVE/PREEXPR state if (cond->own_state && !cond->enabled) { extra->suppressed = true; } //printf ("#if on %s:%d %d\n", GETSTR(pr.loc.file), // cond->line, extra->suppressed); // put PREEXPR on the stack for EOD to pop - //yy_push_state (PREEXPR, scanner); + //yy_push_state (PREEXPR, ctx->scanner); } void -rua_else (bool pass, const char *tok, void *scanner) +rua_else (bool pass, const char *tok, rua_ctx_t *ctx) { - auto extra = qc_yyget_extra (scanner); + auto extra = ctx->extra; if (!extra->cond_stack.size) { error (0, "#else without #if"); return; } - //yy_pop_state (scanner); // remove DIRECTIVE state + //yy_pop_state (ctx->scanner); // remove DIRECTIVE state auto cond = &extra->cond_stack.a[extra->cond_stack.size - 1]; if (cond->saw_else) { error (0, "#%s after #else", tok); @@ -2083,7 +2086,7 @@ rua_else (bool pass, const char *tok, void *scanner) } if (cond->own_state && !cond->enabled) { extra->suppressed = false; - //yy_pop_state (scanner); + //yy_pop_state (ctx->scanner); } pass &= !cond->saw_true; cond->enabled = pass; @@ -2096,41 +2099,41 @@ rua_else (bool pass, const char *tok, void *scanner) extra->suppressed = true; } // put PREEXPR on the stack for EOD to pop - //yy_push_state (PREEXPR, scanner); + //yy_push_state (PREEXPR, ctx->scanner); } void -rua_endif (void *scanner) +rua_endif (rua_ctx_t *ctx) { - auto extra = qc_yyget_extra (scanner); + auto extra = ctx->extra; if (!extra->cond_stack.size) { error (0, "#endif without #if"); return; } - //yy_pop_state (scanner); // remove DIRECTIVE state + //yy_pop_state (ctx->scanner); // remove DIRECTIVE state auto cond = DARRAY_REMOVE (&extra->cond_stack); //printf ("#endif on %s:%d for %d %d\n", GETSTR(pr.loc.file), // pr.loc.line, cond.line, extra->suppressed); if (cond.own_state && !cond.enabled) { extra->suppressed = false; - //yy_pop_state (scanner); + //yy_pop_state (ctx->scanner); } // put PREEXPR on the stack for EOD to pop - //yy_push_state (PREEXPR, scanner); + //yy_push_state (PREEXPR, ctx->scanner); } bool -rua_defined (const char *name, void *scanner) +rua_defined (const char *name, rua_ctx_t *ctx) { - auto extra = qc_yyget_extra (scanner); + auto extra = ctx->extra; auto macro_tab = extra->macro_tab; return symtab_lookup (macro_tab, name); } void -rua_undefine (const char *name, void *scanner) +rua_undefine (const char *name, rua_ctx_t *ctx) { - auto extra = qc_yyget_extra (scanner); + auto extra = ctx->extra; if (extra->suppressed) { return; } @@ -2142,18 +2145,18 @@ rua_undefine (const char *name, void *scanner) } void -rua_include_file (const char *name, void *scanner) +rua_include_file (const char *name, rua_ctx_t *ctx) { - auto extra = qc_yyget_extra (scanner); + auto extra = ctx->extra; if (extra->suppressed) { return; } - if (current_language.on_include) { - if (!current_language.on_include (name)) { + if (ctx->language->on_include) { + if (!ctx->language->on_include (name, ctx)) { return; } } - struct yyguts_t * yyg = (struct yyguts_t*)scanner;//FIXME + struct yyguts_t * yyg = (struct yyguts_t*)ctx->scanner;//FIXME int quote = *name; name = make_string (name, 0); bool is_system; @@ -2171,8 +2174,8 @@ rua_include_file (const char *name, void *scanner) .location = extra->location, })); extra->cond_stack = (rua_cond_stack_t) DARRAY_STATIC_INIT (8); - auto buffer = yy_create_buffer (yyin, YY_BUF_SIZE, scanner); - yy_switch_to_buffer (buffer, scanner); + auto buffer = yy_create_buffer (yyin, YY_BUF_SIZE, ctx->scanner); + yy_switch_to_buffer (buffer, ctx->scanner); extra->location = (rua_loc_t) { .line = 1, .column = 1, @@ -2183,9 +2186,9 @@ rua_include_file (const char *name, void *scanner) } void -rua_embed_file (const char *name, void *scanner) +rua_embed_file (const char *name, rua_ctx_t *ctx) { - auto extra = qc_yyget_extra (scanner); + auto extra = ctx->extra; if (extra->suppressed) { return; } @@ -2197,31 +2200,33 @@ int rua_parse_define (const char *def) { int status; - yyscan_t scanner; rua_tok_t tok = { .location = { 1, 1, 1, 1 }, .token = -1, }; rua_extra_t extra = { .preprocessor = true, .pre_state = pre_yypstate_new (), .macro_tab = cpp_macros, }; + rua_ctx_t ctx = { + .extra = &extra, + }; - yylex_init_extra (&extra, &scanner); - yy_scan_string (def, scanner); + yylex_init_extra (&extra, &ctx.scanner); + yy_scan_string (def, ctx.scanner); - yy_push_state (PREPROC, scanner); + yy_push_state (PREPROC, ctx.scanner); do { if (tok.token == -1) { tok.token = PRE_DEFINE; } else { - tok.token = yylex (&tok, &tok.location, scanner); + tok.token = yylex (&tok, &tok.location, ctx.scanner); if (tok.text == extra.str_text) { tok.text = save_string (tok.text); } status = 0; } while (tok.token) { - status = qc_process (&extra, tok.token, &tok, scanner); + status = qc_process (&extra, tok.token, &tok, ctx.scanner, &ctx); if (status != YYPUSH_MORE || !extra.macro) { break; } @@ -2233,7 +2238,7 @@ rua_parse_define (const char *def) } } while (status == YYPUSH_MORE); - yylex_destroy (scanner); + yylex_destroy (ctx.scanner); pre_yypstate_delete (extra.pre_state); dstring_delete (extra.dstr); return status; @@ -2241,9 +2246,9 @@ rua_parse_define (const char *def) void rua_line_info (const expr_t *line_expr, const char *file, - const expr_t *flags_expr, void *scanner) + const expr_t *flags_expr, rua_ctx_t *ctx) { - auto extra = qc_yyget_extra (scanner); + auto extra = ctx->extra; int line = expr_long (line_expr); int flags = flags_expr ? expr_long (flags_expr) : 0; @@ -2260,9 +2265,9 @@ rua_line_info (const expr_t *line_expr, const char *file, } void -rua_macro_file (rua_macro_t *macro, void *scanner) +rua_macro_file (rua_macro_t *macro, rua_ctx_t *ctx) { - auto extra = qc_yyget_extra (scanner); + auto extra = ctx->extra; int file = extra->location.file; if (macro->tokens && macro->tokens->location.file == file) { return; @@ -2286,9 +2291,9 @@ rua_macro_file (rua_macro_t *macro, void *scanner) } void -rua_macro_line (rua_macro_t *macro, void *scanner) +rua_macro_line (rua_macro_t *macro, rua_ctx_t *ctx) { - auto extra = qc_yyget_extra (scanner); + auto extra = ctx->extra; int line = extra->location.line; if (macro->tokens && macro->tokens->location.line == line) { @@ -2312,7 +2317,7 @@ rua_macro_line (rua_macro_t *macro, void *scanner) } static void -expand_arg (rua_macro_t *macro, rua_macro_t *arg, yyscan_t scanner) +expand_arg (rua_macro_t *macro, rua_macro_t *arg, yyscan_t scanner, rua_ctx_t *ctx) { auto extra = qc_yyget_extra (scanner); rua_extra_t arg_extra = *extra; @@ -2323,7 +2328,7 @@ expand_arg (rua_macro_t *macro, rua_macro_t *arg, yyscan_t scanner) while (true) { rua_tok_t e; - if (next_token (&e, scanner)) { + if (next_token (&e, scanner, ctx)) { if (macro->tokens || (e.token != -rua_space && e.token != -rua_ignore)) { append_token (macro, &e); @@ -2382,19 +2387,19 @@ macro_empty (rua_macro_t *macro, yyscan_t scanner) } void -rua_macro_va_opt (rua_macro_t *macro, void *scanner) +rua_macro_va_opt (rua_macro_t *macro, rua_ctx_t *ctx) { macro->tokens = 0; macro->tail = ¯o->tokens; - auto extra = qc_yyget_extra (scanner); + auto extra = ctx->extra; auto cur = extra->macro; if (!cur || !cur->params || cur->num_params >= 0) { warning (0, "__VA_OPT__ can appear only in the expansion of a " "variadic macro"); return; } - if (macro_empty (cur->args[~cur->num_params], scanner)) { + if (macro_empty (cur->args[~cur->num_params], ctx->scanner)) { return; } auto arg = macro->args[0]; @@ -2403,16 +2408,16 @@ rua_macro_va_opt (rua_macro_t *macro, void *scanner) arg->num_args = cur->num_args; arg->args = cur->args; - expand_arg (macro, arg, scanner); + expand_arg (macro, arg, ctx->scanner, ctx); } void -rua_macro_va_args (rua_macro_t *macro, void *scanner) +rua_macro_va_args (rua_macro_t *macro, rua_ctx_t *ctx) { macro->tokens = 0; macro->tail = ¯o->tokens; - auto extra = qc_yyget_extra (scanner); + auto extra = ctx->extra; auto cur = extra->macro; if (!cur || !cur->params || cur->num_params >= 0) { warning (0, "__VA_ARGS__ can appear only in the expansion of a " diff --git a/tools/qfcc/source/qc-parse.y b/tools/qfcc/source/qc-parse.y index 84cb5e12e..5434f3c4c 100644 --- a/tools/qfcc/source/qc-parse.y +++ b/tools/qfcc/source/qc-parse.y @@ -32,7 +32,7 @@ %define api.push-pull push %define api.token.prefix {QC_} %locations -%parse-param {void *scanner} +%parse-param {struct rua_ctx_s *ctx} %define api.value.type {rua_val_t} %define api.location.type {rua_loc_t} @@ -83,11 +83,11 @@ #include "tools/qfcc/source/qc-parse.h" -#define qc_yytext qc_yyget_text (scanner) -char *qc_yyget_text (void *scanner); +#define qc_yytext qc_yyget_text (ctx->scanner) +char *qc_yyget_text (rua_ctx_t *ctx); static void -yyerror (YYLTYPE *yylloc, void *scanner, const char *s) +yyerror (YYLTYPE *yylloc, rua_ctx_t *ctx, const char *s) { #ifdef QC_YYERROR_VERBOSE error (0, "%s %s\n", qc_yytext, s); @@ -97,12 +97,12 @@ yyerror (YYLTYPE *yylloc, void *scanner, const char *s) } static void -parse_error (void *scanner) +parse_error (rua_ctx_t *ctx) { error (0, "parse error before %s", qc_yytext); } -#define PARSE_ERROR do { parse_error (scanner); YYERROR; } while (0) +#define PARSE_ERROR do { parse_error (ctx); YYERROR; } while (0) #define YYLLOC_DEFAULT(Current, Rhs, N) RUA_LOC_DEFAULT(Current, Rhs, N) #define YYLOCATION_PRINT rua_print_location @@ -310,7 +310,7 @@ overload_spec (void) } static specifier_t -generic_spec (void) +generic_spec (rua_ctx_t *ctx) { specifier_t spec = { .storage = current_storage, @@ -609,7 +609,7 @@ is_null_spec (specifier_t spec) } static int -use_type_name (specifier_t spec) +use_type_name (specifier_t spec, rua_ctx_t *ctx) { spec.sym = new_symbol (spec.sym->name); spec.sym->type = spec.type; @@ -626,7 +626,7 @@ use_type_name (specifier_t spec) } static void __attribute__((used)) -check_specifiers (specifier_t spec) +check_specifiers (specifier_t spec, rua_ctx_t *ctx) { if (!is_null_spec (spec)) { if (!spec.type && !spec.sym) { @@ -645,7 +645,7 @@ check_specifiers (specifier_t spec) // a type name (id, typedef, etc) was used as a variable name. // this is allowed in C, so long as it's in a different scope, // or the types are the same - if (!use_type_name (spec)) { + if (!use_type_name (spec, ctx)) { error (0, "%s redeclared as different kind of symbol", spec.sym->name); } @@ -654,7 +654,7 @@ check_specifiers (specifier_t spec) } static const expr_t * -decl_expr (specifier_t spec, const expr_t *init) +decl_expr (specifier_t spec, const expr_t *init, rua_ctx_t *ctx) { auto sym = spec.sym; spec.sym = nullptr; @@ -717,15 +717,15 @@ fndef datadef : defspecs notype_initdecls ';' { - expr_process ($2); + expr_process ($2, ctx); } | declspecs_nots notype_initdecls ';' { - expr_process ($2); + expr_process ($2, ctx); } | declspecs_ts initdecls ';' { - expr_process ($2); + expr_process ($2, ctx); } | declspecs_ts qc_func_params { @@ -829,8 +829,9 @@ qc_nocode_func : identifier '=' '#' expr { specifier_t spec = qc_set_symbol ($0, $1); - const expr_t *bi_val = expr_process ($4); + const expr_t *bi_val = expr_process ($4, ctx); + spec.is_overload |= ctx->language->always_overload; symbol_t *sym = function_symbol (spec); build_builtin_function (sym, bi_val, 0, spec.storage); } @@ -862,6 +863,7 @@ qc_code_func .function = current_func, }; specifier_t spec = qc_set_symbol ($0, $1); + spec.is_overload |= ctx->language->always_overload; symbol_t *sym = function_symbol (spec); current_func = begin_function (sym, 0, current_symtab, 0, spec.storage); @@ -871,7 +873,7 @@ qc_code_func } compound_statement_ns { - auto statements = (expr_t *) expr_process ($6); + auto statements = (expr_t *) expr_process ($6, ctx); build_code_function ($1, $3, statements); current_symtab = $5.symtab; current_func = $5.function; @@ -958,8 +960,8 @@ initdecls ; initdecl - : declarator '=' var_initializer { $$ = decl_expr ($1, $3); } - | declarator { $$ = decl_expr ($1, nullptr); } + : declarator '=' var_initializer { $$ = decl_expr ($1, $3, ctx); } + | declarator { $$ = decl_expr ($1, nullptr, ctx); } ; notype_initdecls @@ -971,8 +973,8 @@ notype_initdecls ; notype_initdecl - : notype_declarator '=' var_initializer { $$ = decl_expr ($1, $3); } - | notype_declarator { $$ = decl_expr ($1, nullptr); } + : notype_declarator '=' var_initializer { $$ = decl_expr ($1, $3, ctx); } + | notype_declarator { $$ = decl_expr ($1, nullptr, ctx); } ; /* various lists of type specifiers, storage class etc */ @@ -1173,6 +1175,7 @@ function_body : method_optional_state_expr { specifier_t spec = default_type ($0, $0.sym); + spec.is_overload |= ctx->language->always_overload; $$ = function_symbol (spec); } save_storage @@ -1188,7 +1191,7 @@ function_body } compound_statement_ns { - auto statements = (expr_t *) expr_process ($5); + auto statements = (expr_t *) expr_process ($5, ctx); build_code_function ($2, $1, statements); current_symtab = $4.symtab; current_func = $4.function; @@ -1197,8 +1200,9 @@ function_body | '=' '#' expr ';' { specifier_t spec = $0; - const expr_t *bi_val = expr_process ($3); + const expr_t *bi_val = expr_process ($3, ctx); + spec.is_overload |= ctx->language->always_overload; symbol_t *sym = function_symbol (spec); build_builtin_function (sym, bi_val, 0, spec.storage); } @@ -1219,7 +1223,7 @@ storage_class | SYSTEM { $$ = storage_spec (sc_system); } | TYPEDEF { $$ = typedef_spec (); } | OVERLOAD { $$ = overload_spec (); } - | GENERIC '(' { $$ = generic_spec (); } + | GENERIC '(' { $$ = generic_spec (ctx); } generic_param_list ')' { $$ = $3; @@ -1408,7 +1412,7 @@ enumerator } | identifier '=' expr { - $expr = expr_process ($expr); + $expr = expr_process ($expr, ctx); add_enum ($0, $identifier, $expr); } ; @@ -2630,7 +2634,7 @@ methoddef } compound_statement_ns { - auto statements = (expr_t *) expr_process ($7); + auto statements = (expr_t *) expr_process ($7, ctx); build_code_function ($4, $3, statements); current_symtab = $6.symtab; current_func = $6.function; @@ -2640,7 +2644,7 @@ methoddef { symbol_t *sym; method_t *method = $2; - const expr_t *bi_val = expr_process ($5); + const expr_t *bi_val = expr_process ($5, ctx); method->instance = $1; method = class_find_method (current_class, method); @@ -3022,7 +3026,8 @@ static keyword_t keywords[] = { }; static int -qc_process_keyword (QC_YYSTYPE *lval, keyword_t *keyword, const char *token) +qc_process_keyword (QC_YYSTYPE *lval, keyword_t *keyword, const char *token, + rua_ctx_t *ctx) { if (keyword->value == QC_STRUCT) { lval->op = token[0]; @@ -3065,7 +3070,7 @@ qc_process_keyword (QC_YYSTYPE *lval, keyword_t *keyword, const char *token) } static int -qc_keyword_or_id (QC_YYSTYPE *lval, const char *token) +qc_keyword_or_id (QC_YYSTYPE *lval, const char *token, rua_ctx_t *ctx) { static hashtab_t *keyword_tab; static hashtab_t *qf_keyword_tab; @@ -3119,7 +3124,7 @@ qc_keyword_or_id (QC_YYSTYPE *lval, const char *token) if (!keyword) keyword = Hash_Find (keyword_tab, token); if (keyword && keyword->value) - return qc_process_keyword (lval, keyword, token); + return qc_process_keyword (lval, keyword, token, ctx); if (token[0] == '@') { return '@'; } @@ -3154,7 +3159,7 @@ qc_keyword_or_id (QC_YYSTYPE *lval, const char *token) } static int -qc_yyparse (FILE *in) +qc_yyparse (FILE *in, rua_ctx_t *ctx) { rua_parser_t parser = { .parse = qc_yypush_parse, @@ -3162,13 +3167,13 @@ qc_yyparse (FILE *in) .directive = qc_directive, .keyword_or_id = qc_keyword_or_id, }; - int ret = rua_parse (in, &parser); + int ret = rua_parse (in, &parser, ctx); qc_yypstate_delete (parser.state); return ret; } int -qc_parse_string (const char *str) +qc_parse_string (const char *str, rua_ctx_t *ctx) { rua_parser_t parser = { .parse = qc_yypush_parse, @@ -3176,12 +3181,13 @@ qc_parse_string (const char *str) .directive = qc_directive, .keyword_or_id = qc_keyword_or_id, }; - int ret = rua_parse_string (str, &parser); + auto qc_ctx = *ctx; + int ret = rua_parse_string (str, &parser, &qc_ctx); glsl_yypstate_delete (parser.state); return ret; } -static int qc_finish (const char *file) +static int qc_finish (const char *file, rua_ctx_t *ctx) { if (options.frames_files) { write_frame_macros (va (0, "%s.frame", file_basename (file, 0))); @@ -3191,9 +3197,9 @@ static int qc_finish (const char *file) } static void -rua_init (void) +rua_init (rua_ctx_t *ctx) { - current_language.initialized = true; + ctx->language->initialized = true; if (options.code.spirv) { static module_t module; //FIXME probably not what I want pr.module = &module; diff --git a/tools/qfcc/source/qfcc.c b/tools/qfcc/source/qfcc.c index 0376e38a6..ee7e96f2a 100644 --- a/tools/qfcc/source/qfcc.c +++ b/tools/qfcc/source/qfcc.c @@ -372,21 +372,20 @@ setup_sym_file (const char *output_file) } static int -compile_to_obj (const char *file, const char *obj, language_t *lang) +compile_to_obj (const char *file, const char *obj, rua_ctx_t *ctx) { int err; FILE *yyin; + auto lang = ctx->language; yyin = preprocess_file (file, 0); if (options.preprocess_only || !yyin) { if (yyin) { - return lang->parse (yyin); + return lang->parse (yyin, ctx); } return !options.preprocess_only; } - current_language = *lang; - InitData (); chain_initial_types (); begin_compilation (); @@ -394,7 +393,7 @@ compile_to_obj (const char *file, const char *obj, language_t *lang) pr.comp_dir = save_cwd (); add_source_file (file); lang->initialized = false; - err = lang->parse (yyin) || pr.error_count; + err = lang->parse (yyin, ctx) || pr.error_count; fclose (yyin); if (cpp_name && !options.save_temps) { if (unlink (tempname->str)) { @@ -406,7 +405,7 @@ compile_to_obj (const char *file, const char *obj, language_t *lang) qfo_t *qfo; if (lang->finish) { - err = lang->finish (file); + err = lang->finish (file, ctx); } if (!err) { emit_ctor (); @@ -570,10 +569,14 @@ separate_compile (void) // need *file for checking -lfoo auto lang = file_language (*file, extension->str); if (lang) { + rua_ctx_t ctx = { + .language = lang, + }; + if (options.verbosity >= 1) printf ("%s %s\n", *file, output_file->str); temp_files[i++] = save_string (output_file->str); - err = compile_to_obj (*file, output_file->str, lang) || err; + err = compile_to_obj (*file, output_file->str, &ctx) || err; if (!err) { cpp_write_dependencies (*file, output_file->str); @@ -676,13 +679,11 @@ parse_cpp_line (script_t *script, dstring_t *filename) } static int -compile_file (const char *filename) +compile_file (const char *filename, rua_ctx_t *ctx) { int err; FILE *yyin; - int (*yyparse) (FILE *in) = lang_ruamoko.parse; - current_language = lang_ruamoko; yyin = preprocess_file (filename, 0); if (options.preprocess_only || !yyin) return !options.preprocess_only; @@ -695,7 +696,7 @@ compile_file (const char *filename) }; add_source_file (filename); clear_frame_macros (); - err = yyparse (yyin) || pr.error_count; + err = ctx->language->parse (yyin, ctx) || pr.error_count; fclose (yyin); if (cpp_name && (!options.save_temps)) { if (unlink (tempname->str)) { @@ -780,6 +781,9 @@ progs_src_compile (void) } setup_sym_file (options.output_file); + rua_ctx_t ctx = { + .language = &lang_ruamoko, + }; InitData (); chain_initial_types (); @@ -811,7 +815,7 @@ progs_src_compile (void) fprintf (single, "$frame_write \"%s.frame\"\n", file_basename (qc_filename->str, 0)); } else { - if (compile_file (qc_filename->str)) + if (compile_file (qc_filename->str, &ctx)) return 1; if (options.frames_files) { write_frame_macros (va (0, "%s.frame", @@ -827,7 +831,7 @@ progs_src_compile (void) if (single) { int err; fclose (single); - err = compile_file (single_name->str); + err = compile_file (single_name->str, &ctx); if (!options.save_temps) { if (unlink (single_name->str)) { perror ("unlink"); diff --git a/tools/qfcc/source/qp-lex.l b/tools/qfcc/source/qp-lex.l index cb988ac7e..3a14d5ddd 100644 --- a/tools/qfcc/source/qp-lex.l +++ b/tools/qfcc/source/qp-lex.l @@ -80,7 +80,7 @@ int yyget_debug (yyscan_t yyscanner) __attribute__((pure)); FILE *yyget_in (yyscan_t yyscanner) __attribute__((pure)); FILE *yyget_out (yyscan_t yyscanner) __attribute__((pure)); -static int keyword_or_id (YYSTYPE *lval, const char *token); +static int keyword_or_id (YYSTYPE *lval, const char *token, rua_ctx_t *ctx); static int convert_relop (const char *relop) __attribute__((pure)); static void update_loc (rua_loc_t *loc, size_t textlen); static void next_line (rua_loc_t *loc, yyscan_t scanner); @@ -108,6 +108,7 @@ FRAMEID {ID}(\.{ID})* %x GRAB_FRAME GRAB_OTHER COMMENT %% + auto ctx = (rua_ctx_t *) qp_yyget_extra (yyscanner); grab_frame = GRAB_FRAME; grab_other = GRAB_OTHER; @@ -142,7 +143,7 @@ FRAMEID {ID}(\.{ID})* return VALUE; } -{ID} return keyword_or_id (yylval, yytext); +{ID} return keyword_or_id (yylval, yytext, ctx); \"(\\.|[^"\\])*\" { const char *s = make_string (yytext, 0); @@ -247,7 +248,7 @@ keyword_get_key (const void *kw, void *unused) } static int -keyword_or_id (YYSTYPE *lval, const char *token) +keyword_or_id (YYSTYPE *lval, const char *token, rua_ctx_t *ctx) { static hashtab_t *keyword_tab; keyword_t *keyword; @@ -308,19 +309,19 @@ convert_relop (const char *relop) } static int -qp_yyparse (FILE *in) +qp_yyparse (FILE *in, rua_ctx_t *ctx) { int status; yyscan_t scanner; qp_yypstate *ps = qp_yypstate_new (); - yylex_init_extra (0, &scanner); + yylex_init_extra (ctx, &scanner); yyset_in (in, scanner); YYLTYPE lloc = { 1, 1, 1, 1 }; do { YYSTYPE lval; int token = yylex (&lval, &lloc, scanner); - status = qp_yypush_parse (ps, token, &lval, &lloc, scanner); + status = qp_yypush_parse (ps, token, &lval, &lloc, ctx); } while (status == YYPUSH_MORE); yylex_destroy (scanner); diff --git a/tools/qfcc/source/rua-declaration.c b/tools/qfcc/source/rua-declaration.c index 82a9473b1..65ddd8e20 100644 --- a/tools/qfcc/source/rua-declaration.c +++ b/tools/qfcc/source/rua-declaration.c @@ -43,11 +43,8 @@ void rua_parse_declaration (specifier_t spec, symbol_t *sym, const expr_t *init, - symtab_t *symtab, expr_t *block) + symtab_t *symtab, expr_t *block, rua_ctx_t *ctx) { - if (sym && sym->type) { - internal_error (0, "unexected typed symbol"); - } if (sym && sym->sy_type == sy_expr) { auto id_list = sym->expr; if (id_list->type != ex_list) { diff --git a/tools/qfcc/source/target_rua.c b/tools/qfcc/source/target_rua.c index bc26bbb2f..17d51e03e 100644 --- a/tools/qfcc/source/target_rua.c +++ b/tools/qfcc/source/target_rua.c @@ -236,15 +236,15 @@ ruamoko_assign_vector (const expr_t *dst, const expr_t *src) static switch_block_t *switch_block; const expr_t * -ruamoko_proc_switch (const expr_t *expr) +ruamoko_proc_switch (const expr_t *expr, rua_ctx_t *ctx) { scoped_src_loc (expr); - auto test = expr_process (expr->switchblock.test); + auto test = expr_process (expr->switchblock.test, ctx); auto sb = switch_block; switch_block = new_switch_block (); switch_block->test = test; - auto body = expr_process (expr->switchblock.body); + auto body = expr_process (expr->switchblock.body, ctx); auto break_label = expr->switchblock.break_label; auto swtch = switch_expr (switch_block, break_label, body); @@ -253,13 +253,13 @@ ruamoko_proc_switch (const expr_t *expr) } const expr_t * -ruamoko_proc_caselabel (const expr_t *expr) +ruamoko_proc_caselabel (const expr_t *expr, rua_ctx_t *ctx) { scoped_src_loc (expr); if (expr->caselabel.end_value) { internal_error (expr, "case ranges not implemented"); } - auto value = expr_process (expr->caselabel.value); + auto value = expr_process (expr->caselabel.value, ctx); if (is_error (value)) { return value; } @@ -342,10 +342,10 @@ ruamoko_field_array (const expr_t *e) } const expr_t * -ruamoko_proc_address (const expr_t *expr) +ruamoko_proc_address (const expr_t *expr, rua_ctx_t *ctx) { scoped_src_loc (expr); - auto e = expr_process (expr->expr.e1); + auto e = expr_process (expr->expr.e1, ctx); if (is_error (e)) { return e; }