[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)).
This commit is contained in:
Bill Currie 2024-12-07 23:52:50 +09:00
parent e87e01e4f2
commit 213ac2a328
16 changed files with 464 additions and 434 deletions

View file

@ -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 *gather_factors (const type_t *type, int op,
const expr_t **factors, int count); 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);
///@} ///@}

View file

@ -39,15 +39,16 @@ typedef struct symbol_s symbol_t;
typedef struct symtab_s symtab_t; typedef struct symtab_s symtab_t;
typedef struct language_s language_t; typedef struct language_s language_t;
typedef struct defspace_s defspace_t; typedef struct defspace_s defspace_t;
typedef struct rua_ctx_s rua_ctx_t;
void glsl_init_comp (void); void glsl_init_comp (rua_ctx_t *ctx);
void glsl_init_vert (void); void glsl_init_vert (rua_ctx_t *ctx);
void glsl_init_tesc (void); void glsl_init_tesc (rua_ctx_t *ctx);
void glsl_init_tese (void); void glsl_init_tese (rua_ctx_t *ctx);
void glsl_init_geom (void); void glsl_init_geom (rua_ctx_t *ctx);
void glsl_init_frag (void); 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_comp;
extern language_t lang_glsl_vert; extern language_t lang_glsl_vert;
@ -109,7 +110,7 @@ typedef struct glsl_sublang_s {
const char *name; const char *name;
const char **interface_default_names; const char **interface_default_names;
} glsl_sublang_t; } 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_comp_sublanguage;
extern glsl_sublang_t glsl_vert_sublanguage; extern glsl_sublang_t glsl_vert_sublanguage;
extern glsl_sublang_t glsl_tesc_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, void glsl_parse_declaration (specifier_t spec, symbol_t *sym,
const expr_t *init, symtab_t *symtab, const expr_t *init, symtab_t *symtab,
expr_t *block); expr_t *block, rua_ctx_t *ctx);
void glsl_declare_field (specifier_t spec, symtab_t *symtab); 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); 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_include (int behavior, void *scanner);
void glsl_multiview (int behavior, void *scanner); void glsl_multiview (int behavior, void *scanner);

View file

@ -67,6 +67,7 @@ typedef struct rua_loc_s {
(Current).file = YYRHSLOC (Rhs, 0).file; \ (Current).file = YYRHSLOC (Rhs, 0).file; \
} while (0) } while (0)
typedef struct rua_ctx_s rua_ctx_t;
typedef struct expr_s expr_t; typedef struct expr_s expr_t;
typedef struct symbol_s symbol_t; typedef struct symbol_s symbol_t;
typedef struct symtab_s symtab_t; typedef struct symtab_s symtab_t;
@ -119,7 +120,7 @@ typedef union rua_val_s {
#include "tools/qfcc/source/glsl-parse.h" #include "tools/qfcc/source/glsl-parse.h"
typedef struct rua_macro_s rua_macro_t; 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 { typedef struct rua_macro_s {
rua_macro_t *next; rua_macro_t *next;
@ -145,38 +146,38 @@ typedef struct rua_preval_s {
}; };
} rua_preval_t; } 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, rua_macro_t *rua_macro_param (rua_macro_t *macro, const rua_tok_t *token,
void *scanner); rua_ctx_t *ctx);
rua_macro_t *rua_end_params (rua_macro_t *macro, void *scanner); 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, rua_macro_t *rua_macro_append (rua_macro_t *macro, const rua_tok_t *token,
void *scanner); rua_ctx_t *ctx);
void rua_macro_finish (rua_macro_t *macro, void *scanner); void rua_macro_finish (rua_macro_t *macro, rua_ctx_t *ctx);
rua_macro_t *rua_macro_arg (const rua_tok_t *token, void *scanner); rua_macro_t *rua_macro_arg (const rua_tok_t *token, rua_ctx_t *ctx);
void rua_start_pragma (void *scanner); void rua_start_pragma (rua_ctx_t *ctx);
void rua_start_text (void *scanner); void rua_start_text (rua_ctx_t *ctx);
void rua_start_expr (void *scanner); void rua_start_expr (rua_ctx_t *ctx);
void rua_start_include (void *scanner); void rua_start_include (rua_ctx_t *ctx);
void rua_expand_on (void *scanner); void rua_expand_on (rua_ctx_t *ctx);
void rua_expand_off (void *scanner); void rua_expand_off (rua_ctx_t *ctx);
void rua_end_directive (void *scanner); void rua_end_directive (rua_ctx_t *ctx);
void rua_start_if (bool expand, void *scanner); void rua_start_if (bool expand, rua_ctx_t *ctx);
void rua_start_else (bool expand, void *scanner); void rua_start_else (bool expand, rua_ctx_t *ctx);
void rua_if (bool pass, void *scanner); void rua_if (bool pass, rua_ctx_t *ctx);
void rua_else (bool pass, const char *tok, void *scanner); void rua_else (bool pass, const char *tok, rua_ctx_t *ctx);
void rua_endif (void *scanner); void rua_endif (rua_ctx_t *ctx);
bool rua_defined (const char *sym, void *scanner); bool rua_defined (const char *sym, rua_ctx_t *ctx);
void rua_undefine (const char *sym, void *scanner); void rua_undefine (const char *sym, rua_ctx_t *ctx);
void rua_include_file (const char *name, void *scanner); void rua_include_file (const char *name, rua_ctx_t *ctx);
void rua_embed_file (const char *name, void *scanner); void rua_embed_file (const char *name, rua_ctx_t *ctx);
int rua_parse_define (const char *def); int rua_parse_define (const char *def);
void rua_line_info (const expr_t *line_expr, const char *text, 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_file (rua_macro_t *macro, rua_ctx_t *ctx);
void rua_macro_line (rua_macro_t *macro, void *scanner); void rua_macro_line (rua_macro_t *macro, rua_ctx_t *ctx);
void rua_macro_va_opt (rua_macro_t *macro, void *scanner); void rua_macro_va_opt (rua_macro_t *macro, rua_ctx_t *ctx);
void rua_macro_va_args (rua_macro_t *macro, void *scanner); void rua_macro_va_args (rua_macro_t *macro, rua_ctx_t *ctx);
void rua_print_location (FILE *out, const rua_loc_t *loc); 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 { typedef struct rua_parser_s {
int (*parse) (rua_yypstate *state, int token, 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; rua_yypstate *state;
directive_t *(*directive) (const char *token); 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; } rua_parser_t;
int rua_parse (FILE *in, 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); 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_directive_get_key (const void *dir, void *unused) __attribute__((pure));
const char *rua_keyword_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 { typedef struct language_s {
bool initialized; bool initialized;
bool always_override; bool always_overload;
void (*init) (void); void (*init) (rua_ctx_t *ctx);
int (*parse) (FILE *in); int (*parse) (FILE *in, rua_ctx_t *ctx);
int (*finish) (const char *file); int (*finish) (const char *file, rua_ctx_t *ctx);
void (*extension) (const char *name, const char *value, void *scanner); void (*extension) (const char *name, const char *value,
void (*version) (int version, const char *profile); rua_ctx_t *ctx);
bool (*on_include) (const char *name); 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, void (*parse_declaration) (specifier_t spec, symbol_t *sym,
const expr_t *init, symtab_t *symtab, const expr_t *init, symtab_t *symtab,
expr_t *block); expr_t *block, rua_ctx_t *ctx);
void *sublanguage; void *sublanguage;
} language_t; } 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_ruamoko;
extern language_t lang_pascal; 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, void rua_parse_declaration (specifier_t spec, symbol_t *sym,
const expr_t *init, symtab_t *symtab, const expr_t *init, symtab_t *symtab,
expr_t *block); expr_t *block, rua_ctx_t *ctx);
#endif//__rua_lang_h #endif//__rua_lang_h

View file

@ -34,6 +34,7 @@ typedef struct type_s type_t;
typedef struct function_s function_t; typedef struct function_s function_t;
typedef struct expr_s expr_t; typedef struct expr_s expr_t;
typedef struct specifier_s specifier_t; typedef struct specifier_s specifier_t;
typedef struct rua_ctx_s rua_ctx_t;
typedef struct { typedef struct {
bool (*value_too_large) (const type_t *val_type); 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 *(*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 *(*assign_vector) (const expr_t *dst, const expr_t *src);
const expr_t *(*proc_switch) (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); const expr_t *(*proc_caselabel) (const expr_t *expr, rua_ctx_t *ctx);
const expr_t *(*proc_address) (const expr_t *expr); const expr_t *(*proc_address) (const expr_t *expr, rua_ctx_t *ctx);
unsigned label_id; unsigned label_id;
} target_t; } target_t;
@ -60,9 +61,9 @@ extern target_t spirv_target;
bool target_set_backend (const char *tgt); bool target_set_backend (const char *tgt);
const expr_t *ruamoko_proc_switch (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); 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_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 #endif//__target_h

View file

@ -48,19 +48,19 @@
#include "tools/qfcc/include/type.h" #include "tools/qfcc/include/type.h"
#include "tools/qfcc/include/value.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 * static const expr_t *
proc_expr (const expr_t *expr) proc_expr (const expr_t *expr, rua_ctx_t *ctx)
{ {
scoped_src_loc (expr); scoped_src_loc (expr);
if (expr->expr.op == 'C') { if (expr->expr.op == 'C') {
auto type = resolve_type (expr->expr.e1); 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); return cast_expr (type, expr);
} }
auto e1 = expr_process (expr->expr.e1); auto e1 = expr_process (expr->expr.e1, ctx);
auto e2 = expr_process (expr->expr.e2); auto e2 = expr_process (expr->expr.e2, ctx);
if (is_error (e1)) { if (is_error (e1)) {
return e1; return e1;
} }
@ -81,13 +81,13 @@ proc_expr (const expr_t *expr)
} }
static const expr_t * static const expr_t *
proc_uexpr (const expr_t *expr) proc_uexpr (const expr_t *expr, rua_ctx_t *ctx)
{ {
scoped_src_loc (expr); scoped_src_loc (expr);
if (expr->expr.op == '&') { 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)) { if (is_error (e1)) {
return e1; return e1;
} }
@ -105,10 +105,10 @@ proc_uexpr (const expr_t *expr)
} }
static const expr_t * static const expr_t *
proc_field (const expr_t *expr) proc_field (const expr_t *expr, rua_ctx_t *ctx)
{ {
scoped_src_loc (expr); scoped_src_loc (expr);
auto object = expr_process (expr->field.object); auto object = expr_process (expr->field.object, ctx);
auto member = expr->field.member; auto member = expr->field.member;
if (is_error (object)) { if (is_error (object)) {
return object; return object;
@ -160,7 +160,7 @@ proc_field (const expr_t *expr)
member = new_deffield_expr (0, field->type, field->def); member = new_deffield_expr (0, field->type, field->def);
return typed_binary_expr (field->type, '.', object, member); return typed_binary_expr (field->type, '.', object, member);
} else { } else {
member = expr_process (member); member = expr_process (member, ctx);
if (is_error (member)) { if (is_error (member)) {
return member; return member;
} }
@ -205,10 +205,10 @@ proc_field (const expr_t *expr)
} }
static const expr_t * 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 base = expr_process (expr->array.base, ctx);
auto index = expr_process (expr->array.index); auto index = expr_process (expr->array.index, ctx);
if (is_error (base)) { if (is_error (base)) {
return base; return base;
} }
@ -234,13 +234,13 @@ proc_array (const expr_t *expr)
} }
static const expr_t * static const expr_t *
proc_label (const expr_t *expr) proc_label (const expr_t *expr, rua_ctx_t *ctx)
{ {
return expr; return expr;
} }
static const expr_t * 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; auto old_scope = current_symtab;
current_symtab = expr->block.scope; current_symtab = expr->block.scope;
@ -252,7 +252,7 @@ proc_block (const expr_t *expr)
list_scatter (&expr->block.list, in); list_scatter (&expr->block.list, in);
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
edag_flush (); edag_flush ();
auto e = expr_process (in[i]); auto e = expr_process (in[i], ctx);
if (e && !is_error (e)) { if (e && !is_error (e)) {
out[num_out++] = e; out[num_out++] = e;
if (expr->block.result == in[i]) { if (expr->block.result == in[i]) {
@ -317,7 +317,7 @@ static struct {
}; };
static const expr_t * static const expr_t *
proc_symbol (const expr_t *expr) proc_symbol (const expr_t *expr, rua_ctx_t *ctx)
{ {
auto sym = expr->symbol; auto sym = expr->symbol;
for (auto bi = builtin_names; bi->name; bi++) { for (auto bi = builtin_names; bi->name; bi++) {
@ -341,7 +341,7 @@ proc_symbol (const expr_t *expr)
} }
static bool 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); int count = list_count (in);
const expr_t *exprs[count + 1] = {}; 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; bool ok = true;
int new_count = 0; int new_count = 0;
for (int i = 0; i < count; i++) { 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 // keep null expressions out of the list (non-local declarations
// or local declarations without initializers return null) // or local declarations without initializers return null)
new_count += !!exprs[new_count]; 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 * static const expr_t *
proc_vector (const expr_t *expr) proc_vector (const expr_t *expr, rua_ctx_t *ctx)
{ {
scoped_src_loc (expr); scoped_src_loc (expr);
auto list = new_expr (); auto list = new_expr ();
list->type = ex_list; 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_error_expr ();
} }
return new_vector_list (list); return new_vector_list (list);
} }
static const expr_t * static const expr_t *
proc_selector (const expr_t *expr) proc_selector (const expr_t *expr, rua_ctx_t *ctx)
{ {
return expr; return expr;
} }
static const expr_t * 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; auto message = expr->message.message;
scoped_src_loc (receiver); scoped_src_loc (receiver);
for (auto k = message; k; k = k->next) { for (auto k = message; k; k = k->next) {
if (k->expr) { 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); return message_expr (receiver, message);
} }
static const expr_t * static const expr_t *
proc_nil (const expr_t *expr) proc_nil (const expr_t *expr, rua_ctx_t *ctx)
{ {
return expr; return expr;
} }
static const expr_t * static const expr_t *
proc_value (const expr_t *expr) proc_value (const expr_t *expr, rua_ctx_t *ctx)
{ {
return expr; return expr;
} }
static const expr_t * static const expr_t *
proc_compound (const expr_t *expr) proc_compound (const expr_t *expr, rua_ctx_t *ctx)
{ {
scoped_src_loc (expr); scoped_src_loc (expr);
auto comp = new_compound_init (); auto comp = new_compound_init ();
for (auto ele = expr->compound.head; ele; ele = ele->next) { 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)); ele->designator));
} }
return comp; return comp;
} }
static const expr_t * 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 dst = expr_process (expr->assign.dst, ctx);
auto src = expr_process (expr->assign.src); auto src = expr_process (expr->assign.src, ctx);
if (is_error (src)) { if (is_error (src)) {
return src; return src;
} }
@ -437,24 +437,24 @@ proc_assign (const expr_t *expr)
} }
static const expr_t * static const expr_t *
proc_branch (const expr_t *expr) proc_branch (const expr_t *expr, rua_ctx_t *ctx)
{ {
scoped_src_loc (expr); scoped_src_loc (expr);
if (expr->branch.type == pr_branch_call) { 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; auto args = (expr_t *) expr->branch.args;
if (expr->branch.args) { if (expr->branch.args) {
args = new_list_expr (nullptr); 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); return function_expr (target, args);
} else { } else {
auto branch = new_expr (); auto branch = new_expr ();
branch->type = ex_branch; branch->type = ex_branch;
branch->branch = expr->branch; branch->branch = expr->branch;
branch->branch.target = expr_process (expr->branch.target); branch->branch.target = expr_process (expr->branch.target, ctx);
branch->branch.index = expr_process (expr->branch.index); branch->branch.index = expr_process (expr->branch.index, ctx);
branch->branch.test = expr_process (expr->branch.test); branch->branch.test = expr_process (expr->branch.test, ctx);
if (is_error (branch->branch.target)) { if (is_error (branch->branch.target)) {
return branch->branch.target; return branch->branch.target;
} }
@ -469,12 +469,12 @@ proc_branch (const expr_t *expr)
} }
static const expr_t * static const expr_t *
proc_return (const expr_t *expr) proc_return (const expr_t *expr, rua_ctx_t *ctx)
{ {
scoped_src_loc (expr); scoped_src_loc (expr);
auto ret_val = expr->retrn.ret_val; auto ret_val = expr->retrn.ret_val;
if (ret_val) { if (ret_val) {
ret_val = expr_process (ret_val); ret_val = expr_process (ret_val, ctx);
} }
if (expr->retrn.at_return) { if (expr->retrn.at_return) {
return at_return_expr (current_func, ret_val); return at_return_expr (current_func, ret_val);
@ -484,18 +484,18 @@ proc_return (const expr_t *expr)
} }
static const expr_t * static const expr_t *
proc_list (const expr_t *expr) proc_list (const expr_t *expr, rua_ctx_t *ctx)
{ {
scoped_src_loc (expr); scoped_src_loc (expr);
auto list = new_list_expr (nullptr); 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 new_error_expr ();
} }
return list; return list;
} }
static const expr_t * static const expr_t *
proc_type (const expr_t *expr) proc_type (const expr_t *expr, rua_ctx_t *ctx)
{ {
scoped_src_loc (expr); scoped_src_loc (expr);
auto type = resolve_type (expr); auto type = resolve_type (expr);
@ -503,10 +503,10 @@ proc_type (const expr_t *expr)
} }
static const expr_t * static const expr_t *
proc_incop (const expr_t *expr) proc_incop (const expr_t *expr, rua_ctx_t *ctx)
{ {
scoped_src_loc (expr); scoped_src_loc (expr);
auto e = expr_process (expr->incop.expr); auto e = expr_process (expr->incop.expr, ctx);
if (is_error (e)) { if (is_error (e)) {
return e; return e;
} }
@ -518,12 +518,12 @@ proc_incop (const expr_t *expr)
} }
static const expr_t * static const expr_t *
proc_cond (const expr_t *expr) proc_cond (const expr_t *expr, rua_ctx_t *ctx)
{ {
scoped_src_loc (expr); scoped_src_loc (expr);
auto test = expr_process (expr->cond.test); auto test = expr_process (expr->cond.test, ctx);
auto true_expr = expr_process (expr->cond.true_expr); auto true_expr = expr_process (expr->cond.true_expr, ctx);
auto false_expr = expr_process (expr->cond.false_expr); auto false_expr = expr_process (expr->cond.false_expr, ctx);
if (is_error (test)) { if (is_error (test)) {
return test; return test;
} }
@ -537,11 +537,12 @@ proc_cond (const expr_t *expr)
} }
static const expr_t * static const expr_t *
proc_decl (const expr_t *expr) proc_decl (const expr_t *expr, rua_ctx_t *ctx)
{ {
scoped_src_loc (expr); scoped_src_loc (expr);
expr_t *block = nullptr; 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); scoped_src_loc (expr);
block = new_block_expr (nullptr); block = new_block_expr (nullptr);
} }
@ -558,7 +559,7 @@ proc_decl (const expr_t *expr)
if (decl->assign.dst->type != ex_symbol) { if (decl->assign.dst->type != ex_symbol) {
internal_error (decl->assign.dst, "not a symbol"); internal_error (decl->assign.dst, "not a symbol");
} }
init = expr_process (init); init = expr_process (init, ctx);
if (is_error (init)) { if (is_error (init)) {
return init; return init;
} }
@ -569,26 +570,26 @@ proc_decl (const expr_t *expr)
} else { } else {
internal_error (decl, "not a symbol"); internal_error (decl, "not a symbol");
} }
auto spec = expr->decl.spec; auto spec = decl_spec;
if (sym && sym->type) { if (sym && !spec.type_expr) {
spec.type = append_type (sym->type, spec.type); spec.type = append_type (sym->type, spec.type);
spec.type = find_type (spec.type); spec.type = find_type (spec.type);
sym->type = nullptr; sym->type = nullptr;
} }
auto symtab = expr->decl.symtab; 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 (); edag_flush ();
return block; return block;
} }
static const expr_t * 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 test = expr_process (expr->loop.test, ctx);
auto body = expr_process (expr->loop.body); auto body = expr_process (expr->loop.body, ctx);
auto continue_label = expr->loop.continue_label; 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; auto break_label = expr->loop.break_label;
bool do_while = expr->loop.do_while; bool do_while = expr->loop.do_while;
bool not = expr->loop.not; bool not = expr->loop.not;
@ -598,11 +599,11 @@ proc_loop (const expr_t *expr)
} }
static const expr_t * 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 test = expr_process (expr->select.test, ctx);
auto true_body = expr_process (expr->select.true_body); auto true_body = expr_process (expr->select.true_body, ctx);
auto false_body = expr_process (expr->select.false_body); auto false_body = expr_process (expr->select.false_body, ctx);
scoped_src_loc (expr); scoped_src_loc (expr);
auto select = new_select_expr (expr->select.not, test, true_body, nullptr, auto select = new_select_expr (expr->select.not, test, true_body, nullptr,
false_body); false_body);
@ -611,14 +612,14 @@ proc_select (const expr_t *expr)
} }
static const expr_t * 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); int count = list_count (&expr->intrinsic.operands);
const expr_t *operands[count + 1]; const expr_t *operands[count + 1];
list_scatter (&expr->intrinsic.operands, operands); 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++) { for (int i = 0; i < count; i++) {
operands[i] = expr_process (operands[i]); operands[i] = expr_process (operands[i], ctx);
} }
scoped_src_loc (expr); scoped_src_loc (expr);
auto e = new_expr (); auto e = new_expr ();
@ -632,19 +633,19 @@ proc_intrinsic (const expr_t *expr)
} }
static const expr_t * 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 * 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 * const expr_t *
expr_process (const expr_t *expr) expr_process (const expr_t *expr, rua_ctx_t *ctx)
{ {
if (!expr) { if (!expr) {
return expr; return expr;
@ -686,5 +687,5 @@ expr_process (const expr_t *expr)
expr_names[expr->type]); expr_names[expr->type]);
} }
return funcs[expr->type] (expr); return funcs[expr->type] (expr, ctx);
} }

View file

@ -774,7 +774,7 @@ get_function (const char *name, specifier_t spec)
call_params[i].type = type->func.param_types[i]; 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); metafunc_t *func = Hash_Find (function_map, name);
if (func && func->meta_type == mf_generic) { if (func && func->meta_type == mf_generic) {
auto genfuncs = (genfunc_t **) Hash_FindList (generic_functions, name); auto genfuncs = (genfunc_t **) Hash_FindList (generic_functions, name);

View file

@ -36,6 +36,7 @@
#include "tools/qfcc/include/struct.h" #include "tools/qfcc/include/struct.h"
#include "tools/qfcc/include/type.h" #include "tools/qfcc/include/type.h"
glsl_sublang_t glsl_sublang;
glsl_imageset_t glsl_imageset = DARRAY_STATIC_INIT (16); glsl_imageset_t glsl_imageset = DARRAY_STATIC_INIT (16);
static struct_def_t glsl_image_struct[] = { static struct_def_t glsl_image_struct[] = {
@ -918,7 +919,7 @@ glsl_multiview (int behavior, void *scanner)
static int glsl_include_state = 0; static int glsl_include_state = 0;
bool bool
glsl_on_include (const char *name) glsl_on_include (const char *name, rua_ctx_t *ctx)
{ {
if (!glsl_include_state) { if (!glsl_include_state) {
error (0, "'#include' : required extension not requested"); error (0, "'#include' : required extension not requested");
@ -937,13 +938,13 @@ glsl_include (int behavior, void *scanner)
} }
static void 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 static void
glsl_init_common (void) glsl_init_common (rua_ctx_t *ctx)
{ {
static module_t module; //FIXME probably not what I want static module_t module; //FIXME probably not what I want
pr.module = &module; pr.module = &module;
@ -958,63 +959,66 @@ glsl_init_common (void)
spirv_set_addressing_model (pr.module, SpvAddressingModelLogical); spirv_set_addressing_model (pr.module, SpvAddressingModelLogical);
spirv_set_memory_model (pr.module, SpvMemoryModelGLSL450); 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 (); glsl_block_clear ();
qc_parse_string (glsl_general_functions); rua_ctx_t rua_ctx = { .language = &lang_ruamoko };
glsl_parse_vars (glsl_system_constants); qc_parse_string (glsl_general_functions, &rua_ctx);
glsl_parse_vars (glsl_system_constants, ctx);
} }
void void
glsl_init_comp (void) glsl_init_comp (rua_ctx_t *ctx)
{ {
glsl_init_common (); glsl_init_common (ctx);
glsl_parse_vars (glsl_compute_vars); glsl_parse_vars (glsl_compute_vars, ctx);
spirv_add_capability (pr.module, SpvCapabilityShader); spirv_add_capability (pr.module, SpvCapabilityShader);
} }
void void
glsl_init_vert (void) glsl_init_vert (rua_ctx_t *ctx)
{ {
glsl_init_common (); glsl_init_common (ctx);
glsl_parse_vars (glsl_Vulkan_vertex_vars); glsl_parse_vars (glsl_Vulkan_vertex_vars, ctx);
spirv_add_capability (pr.module, SpvCapabilityShader); spirv_add_capability (pr.module, SpvCapabilityShader);
} }
void void
glsl_init_tesc (void) glsl_init_tesc (rua_ctx_t *ctx)
{ {
glsl_init_common (); glsl_init_common (ctx);
glsl_parse_vars (glsl_tesselation_control_vars); glsl_parse_vars (glsl_tesselation_control_vars, ctx);
spirv_add_capability (pr.module, SpvCapabilityTessellation); spirv_add_capability (pr.module, SpvCapabilityTessellation);
} }
void void
glsl_init_tese (void) glsl_init_tese (rua_ctx_t *ctx)
{ {
glsl_init_common (); glsl_init_common (ctx);
glsl_parse_vars (glsl_tesselation_evaluation_vars); glsl_parse_vars (glsl_tesselation_evaluation_vars, ctx);
spirv_add_capability (pr.module, SpvCapabilityTessellation); spirv_add_capability (pr.module, SpvCapabilityTessellation);
} }
void void
glsl_init_geom (void) glsl_init_geom (rua_ctx_t *ctx)
{ {
glsl_init_common (); glsl_init_common (ctx);
glsl_parse_vars (glsl_geometry_vars); glsl_parse_vars (glsl_geometry_vars, ctx);
qc_parse_string (glsl_geometry_functions); rua_ctx_t rua_ctx = { .language = &lang_ruamoko };
qc_parse_string (glsl_geometry_functions, &rua_ctx);
spirv_add_capability (pr.module, SpvCapabilityGeometry); spirv_add_capability (pr.module, SpvCapabilityGeometry);
} }
void void
glsl_init_frag (void) glsl_init_frag (rua_ctx_t *ctx)
{ {
glsl_init_common (); glsl_init_common (ctx);
glsl_parse_vars (glsl_fragment_vars); glsl_parse_vars (glsl_fragment_vars, ctx);
spirv_add_capability (pr.module, SpvCapabilityShader); spirv_add_capability (pr.module, SpvCapabilityShader);
} }

View file

@ -43,7 +43,7 @@
void void
glsl_parse_declaration (specifier_t spec, symbol_t *sym, const expr_t *init, 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) { if (sym && sym->type) {
internal_error (0, "unexected typed symbol"); internal_error (0, "unexected typed symbol");
@ -105,7 +105,7 @@ glsl_parse_declaration (specifier_t spec, symbol_t *sym, const expr_t *init,
} }
void 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); auto attributes = glsl_optimize_attributes (spec.attributes);
spec.sym = declare_field (spec, symtab); spec.sym = declare_field (spec, symtab);

View file

@ -32,7 +32,7 @@
%define api.push-pull push %define api.push-pull push
%define api.token.prefix {GLSL_} %define api.token.prefix {GLSL_}
%locations %locations
%parse-param {void *scanner} %parse-param {struct rua_ctx_s *ctx}
%define api.value.type {rua_val_t} %define api.value.type {rua_val_t}
%define api.location.type {rua_loc_t} %define api.location.type {rua_loc_t}
@ -82,11 +82,11 @@
#include "tools/qfcc/source/glsl-parse.h" #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); char *qc_yyget_text (void *scanner);
static void static void
yyerror (YYLTYPE *yylloc, void *scanner, const char *s) yyerror (YYLTYPE *yylloc, rua_ctx_t *ctx, const char *s)
{ {
#ifdef GLSL_YYERROR_VERBOSE #ifdef GLSL_YYERROR_VERBOSE
error (0, "%s %s\n", glsl_yytext, s); error (0, "%s %s\n", glsl_yytext, s);
@ -97,7 +97,7 @@ yyerror (YYLTYPE *yylloc, void *scanner, const char *s)
} }
static void __attribute__((used)) static void __attribute__((used))
parse_error (void *scanner) parse_error (rua_ctx_t *ctx)
{ {
error (0, "parse error before %s", glsl_yytext); error (0, "parse error before %s", glsl_yytext);
} }
@ -321,7 +321,7 @@ translation_unit
external_declaration external_declaration
: function_definition : function_definition
| declaration { if ($1) expr_process ($1); } | declaration { if ($1) expr_process ($1, ctx); }
| ';' | ';'
; ;
@ -331,6 +331,7 @@ function_definition
$<symtab>$ = current_symtab; $<symtab>$ = current_symtab;
auto spec = $1; auto spec = $1;
spec.sym->params = spec.params; spec.sym->params = spec.params;
spec.is_overload = true;
auto sym = function_symbol (spec); auto sym = function_symbol (spec);
current_func = begin_function (sym, nullptr, current_symtab, current_func = begin_function (sym, nullptr, current_symtab,
false, spec.storage); false, spec.storage);
@ -343,7 +344,7 @@ function_definition
{ {
auto spec = $1; auto spec = $1;
auto sym = spec.sym; 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); build_code_function (sym, nullptr, statments);
current_symtab = $<symtab>2; current_symtab = $<symtab>2;
current_storage = sc_global;//FIXME current_storage = sc_global;//FIXME
@ -662,7 +663,7 @@ declaration
| type_qualifier ';' | type_qualifier ';'
{ {
glsl_parse_declaration ($type_qualifier, nullptr, glsl_parse_declaration ($type_qualifier, nullptr,
nullptr, current_symtab, nullptr); nullptr, current_symtab, nullptr, ctx);
$$ = nullptr; $$ = nullptr;
} }
| type_qualifier new_identifier ';' | type_qualifier new_identifier ';'
@ -1070,7 +1071,7 @@ struct_declarator
{ {
auto spec = $<spec>0; auto spec = $<spec>0;
spec.sym = $1; spec.sym = $1;
glsl_declare_field (spec, current_symtab); glsl_declare_field (spec, current_symtab, ctx);
} }
| new_identifier array_specifier | new_identifier array_specifier
{ {
@ -1078,7 +1079,7 @@ struct_declarator
spec.type = append_type ($2, spec.type); spec.type = append_type ($2, spec.type);
spec.type = find_type (spec.type); spec.type = find_type (spec.type);
spec.sym = $1; 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 * 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[] = { static image_sub_t image_type[] = {
{ .substr = "sampler", .val = 0, .type = &type_float }, { .substr = "sampler", .val = 0, .type = &type_float },
@ -1750,12 +1751,13 @@ invalid:
} }
static int 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) { if (keyword->value == GLSL_STRUCT) {
lval->op = token[0]; lval->op = token[0];
} else if (keyword->value == GLSL_TYPE_SPEC && !keyword->spec.type) { } 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; keyword->spec.type = sym->type;
lval->spec = keyword->spec; lval->spec = keyword->spec;
} else if (keyword->use_name) { } else if (keyword->use_name) {
@ -1767,7 +1769,7 @@ glsl_process_keyword (rua_val_t *lval, keyword_t *keyword, const char *token)
} }
static int 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; 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); keyword = Hash_Find (glsl_keyword_tab, token);
if (keyword && keyword->value) if (keyword && keyword->value)
return glsl_process_keyword (lval, keyword, token); return glsl_process_keyword (lval, keyword, token, ctx);
if (token[0] == '@') { if (token[0] == '@') {
return '@'; return '@';
} }
@ -1803,7 +1805,7 @@ glsl_keyword_or_id (rua_val_t *lval, const char *token)
} }
static int static int
glsl_yyparse (FILE *in) glsl_yyparse (FILE *in, rua_ctx_t *ctx)
{ {
rua_parser_t parser = { rua_parser_t parser = {
.parse = glsl_yypush_parse, .parse = glsl_yypush_parse,
@ -1811,13 +1813,13 @@ glsl_yyparse (FILE *in)
.directive = glsl_directive, .directive = glsl_directive,
.keyword_or_id = glsl_keyword_or_id, .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); glsl_yypstate_delete (parser.state);
return ret; return ret;
} }
int int
glsl_parse_string (const char *str) glsl_parse_string (const char *str, rua_ctx_t *ctx)
{ {
rua_parser_t parser = { rua_parser_t parser = {
.parse = glsl_yypush_parse, .parse = glsl_yypush_parse,
@ -1825,7 +1827,8 @@ glsl_parse_string (const char *str)
.directive = glsl_directive, .directive = glsl_directive,
.keyword_or_id = glsl_keyword_or_id, .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); glsl_yypstate_delete (parser.state);
return ret; return ret;
} }
@ -1866,9 +1869,9 @@ behavior_cmp (const void *_a, const void *_b)
} }
static void 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 " error (0, "extensions directives must occur before any "
"non-preprocessor tokens"); "non-preprocessor tokens");
return; return;
@ -1887,7 +1890,7 @@ glsl_extension (const char *name, const char *value, void *scanner)
return; return;
} }
for (size_t i = 0; i < num_extensions; i++) { for (size_t i = 0; i < num_extensions; i++) {
glsl_extensions[i].set_behavior (behavior, scanner); glsl_extensions[i].set_behavior (behavior, ctx);
} }
} else { } else {
glsl_ext_t key = { .name = name }; 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, ext = bsearch (&key, glsl_extensions, num_extensions,
sizeof (glsl_ext_t), extension_cmp); sizeof (glsl_ext_t), extension_cmp);
if (ext) { if (ext) {
ext->set_behavior (behavior, scanner); ext->set_behavior (behavior, ctx);
} else { } else {
if (behavior == 2) { if (behavior == 2) {
error (0, "unknown extension '%s'", name); error (0, "unknown extension '%s'", name);
@ -1907,7 +1910,7 @@ glsl_extension (const char *name, const char *value, void *scanner)
} }
static void 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) { if (!profile || strcmp (profile, "core") == 0) {
// ok // ok
@ -1924,7 +1927,7 @@ glsl_version (int version, const char *profile)
} }
language_t lang_glsl_comp = { language_t lang_glsl_comp = {
.always_override = true, .always_overload = true,
.init = glsl_init_comp, .init = glsl_init_comp,
.parse = glsl_yyparse, .parse = glsl_yyparse,
.extension = glsl_extension, .extension = glsl_extension,
@ -1935,7 +1938,7 @@ language_t lang_glsl_comp = {
}; };
language_t lang_glsl_vert = { language_t lang_glsl_vert = {
.always_override = true, .always_overload = true,
.init = glsl_init_vert, .init = glsl_init_vert,
.parse = glsl_yyparse, .parse = glsl_yyparse,
.extension = glsl_extension, .extension = glsl_extension,
@ -1946,7 +1949,7 @@ language_t lang_glsl_vert = {
}; };
language_t lang_glsl_tesc = { language_t lang_glsl_tesc = {
.always_override = true, .always_overload = true,
.init = glsl_init_tesc, .init = glsl_init_tesc,
.parse = glsl_yyparse, .parse = glsl_yyparse,
.extension = glsl_extension, .extension = glsl_extension,
@ -1957,7 +1960,7 @@ language_t lang_glsl_tesc = {
}; };
language_t lang_glsl_tese = { language_t lang_glsl_tese = {
.always_override = true, .always_overload = true,
.init = glsl_init_tese, .init = glsl_init_tese,
.parse = glsl_yyparse, .parse = glsl_yyparse,
.extension = glsl_extension, .extension = glsl_extension,
@ -1968,7 +1971,7 @@ language_t lang_glsl_tese = {
}; };
language_t lang_glsl_geom = { language_t lang_glsl_geom = {
.always_override = true, .always_overload = true,
.init = glsl_init_geom, .init = glsl_init_geom,
.parse = glsl_yyparse, .parse = glsl_yyparse,
.extension = glsl_extension, .extension = glsl_extension,
@ -1979,7 +1982,7 @@ language_t lang_glsl_geom = {
}; };
language_t lang_glsl_frag = { language_t lang_glsl_frag = {
.always_override = true, .always_overload = true,
.init = glsl_init_frag, .init = glsl_init_frag,
.parse = glsl_yyparse, .parse = glsl_yyparse,
.extension = glsl_extension, .extension = glsl_extension,

View file

@ -32,7 +32,7 @@
%define api.push-pull push %define api.push-pull push
%define api.token.prefix {PRE_} %define api.token.prefix {PRE_}
%locations %locations
%parse-param {void *scanner} %parse-param {struct rua_ctx_s *ctx}
%{ %{
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
@ -56,11 +56,11 @@
#include "tools/qfcc/source/pre-parse.h" #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); char *qc_yyget_text (void *scanner);
static void 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); const char *text = quote_string (pre_yytext);
#ifdef YYERROR_VERBOSE #ifdef YYERROR_VERBOSE
@ -71,13 +71,13 @@ yyerror (YYLTYPE *yylloc, void *scanner, const char *s)
} }
#if 0 #if 0
static void static void
parse_error (void *scanner) parse_error (rua_ctx_t *ctx)
{ {
const char *text = pre_yytext; const char *text = pre_yytext;
error (0, "parse error before %s", text); 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 #endif
#define YYLLOC_DEFAULT(Current, Rhs, N) RUA_LOC_DEFAULT(Current, Rhs, N) #define YYLLOC_DEFAULT(Current, Rhs, N) RUA_LOC_DEFAULT(Current, Rhs, N)
@ -188,7 +188,7 @@ start
: directive_list : directive_list
| ARGS | ARGS
<macro>{ <macro>{
$$ = rua_macro_arg (&$<t>1, scanner); $$ = rua_macro_arg (&$<t>1, ctx);
} }
args ')' { YYACCEPT; } args ')' { YYACCEPT; }
; ;
@ -198,19 +198,19 @@ directive_list
| directive_list directive | directive_list directive
; ;
eod : EOD { rua_end_directive (scanner); } ; eod : EOD { rua_end_directive (ctx); } ;
directive directive
: INCLUDE incexp string extra_warn { rua_include_file ($3, scanner); } : INCLUDE incexp string extra_warn { rua_include_file ($3, ctx); }
| EMBED incexp string extra_ignore { rua_embed_file ($3, scanner); } | EMBED incexp string extra_ignore { rua_embed_file ($3, ctx); }
| DEFINE ID <macro> { $$ = rua_start_macro ($2, false, scanner); } | DEFINE ID <macro> { $$ = rua_start_macro ($2, false, ctx); }
body { rua_macro_finish ($body, scanner); } body { rua_macro_finish ($body, ctx); }
eod eod
| DEFINE IDp <macro> { $$ = rua_start_macro ($2, true, scanner); } | DEFINE IDp <macro> { $$ = rua_start_macro ($2, true, ctx); }
opt_params ')' <macro>{ $$ = rua_end_params ($3, scanner); } opt_params ')' <macro>{ $$ = rua_end_params ($3, ctx); }
body { rua_macro_finish ($body, scanner); } body { rua_macro_finish ($body, ctx); }
eod eod
| UNDEF ID { rua_undefine ($2, scanner); } | UNDEF ID { rua_undefine ($2, ctx); }
extra_warn extra_warn
| ERROR text { error (0, "%s", $text->str); dstring_delete ($text); } | ERROR text { error (0, "%s", $text->str); dstring_delete ($text); }
eod eod
@ -218,39 +218,39 @@ directive
eod eod
| NOTICE text { notice (0, "%s", $text->str); dstring_delete ($text); } | NOTICE text { notice (0, "%s", $text->str); dstring_delete ($text); }
eod eod
| PRAGMA expand { rua_start_pragma (scanner); } | PRAGMA expand { rua_start_pragma (ctx); }
pragma_params { pragma_process (); } pragma_params { pragma_process (); }
eod eod
| LINE expand expr extra_warn | 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 | LINE expand expr string line_expr extra_warn
{ rua_line_info ($3, $4, $5, scanner); } { rua_line_info ($3, $4, $5, ctx); }
| IF { rua_start_if (true, scanner); } | IF { rua_start_if (true, ctx); }
expr { rua_if (expr_long ($3), scanner); } expr { rua_if (expr_long ($3), ctx); }
eod eod
| IFDEF { rua_start_if (false, scanner); } | IFDEF { rua_start_if (false, ctx); }
ID { rua_if (rua_defined ($3, scanner), scanner); } ID { rua_if (rua_defined ($3, ctx), ctx); }
extra_warn extra_warn
| IFNDEF { rua_start_if (false, scanner); } | IFNDEF { rua_start_if (false, ctx); }
ID { rua_if (!rua_defined ($3, scanner), scanner); } ID { rua_if (!rua_defined ($3, ctx), ctx); }
extra_warn extra_warn
| ELSE { rua_else (true, "else", scanner); } | ELSE { rua_else (true, "else", ctx); }
extra_warn extra_warn
| ELIF { rua_start_else (true, scanner); } | ELIF { rua_start_else (true, ctx); }
expr { rua_else (expr_long ($3), "elif", scanner); } expr { rua_else (expr_long ($3), "elif", ctx); }
eod eod
| ELIFDEF { rua_start_else (false, scanner); } | ELIFDEF { rua_start_else (false, ctx); }
ID { rua_else (rua_defined ($3, scanner), "elifdef", scanner); } ID { rua_else (rua_defined ($3, ctx), "elifdef", ctx); }
extra_warn extra_warn
| ELIFNDEF { rua_start_else (false, scanner); } | ELIFNDEF { rua_start_else (false, ctx); }
ID { rua_else (!rua_defined ($3, scanner), "elifndef", scanner); } ID { rua_else (!rua_defined ($3, ctx), "elifndef", ctx); }
extra_warn extra_warn
| ENDIF { rua_endif (scanner); } | ENDIF { rua_endif (ctx); }
extra_warn extra_warn
| EXTENSION ID ':' ID | EXTENSION ID ':' ID
{ {
if (current_language.extension) { if (ctx->language->extension) {
current_language.extension ($2, $4, scanner); ctx->language->extension ($2, $4, ctx);
} else { } else {
internal_error (0, "invalid directive"); internal_error (0, "invalid directive");
} }
@ -258,9 +258,9 @@ directive
extra_warn extra_warn
| VERSION VALUE opt_profile | VERSION VALUE opt_profile
{ {
if (current_language.version) { if (ctx->language->version) {
auto version = get_long ($2, $<t.text>2, 460); auto version = get_long ($2, $<t.text>2, 460);
current_language.version (expr_long (version), $3); ctx->language->version (expr_long (version), $3, ctx);
} else { } else {
internal_error (0, "invalid directive"); internal_error (0, "invalid directive");
} }
@ -281,7 +281,7 @@ extra_ignore
: {} eod : {} eod
; ;
text: { rua_start_text (scanner); $<dstr>$ = dstring_new (); } text_text text: { rua_start_text (ctx); $<dstr>$ = dstring_new (); } text_text
{ $text = $text_text; } { $text = $text_text; }
; ;
text_text text_text
@ -290,7 +290,7 @@ text_text
; ;
body: /* empty */ { $$ = $<macro>0; } body: /* empty */ { $$ = $<macro>0; }
| body body_token { $$ = rua_macro_append ($1, &$2, scanner); } | body body_token { $$ = rua_macro_append ($1, &$2, ctx); }
; ;
body_token body_token
@ -301,11 +301,11 @@ body_token
; ;
incexp incexp
: { rua_start_include (scanner); } : { rua_start_include (ctx); }
; ;
expand expand
: { rua_start_expr (scanner); } : { rua_start_expr (ctx); }
; ;
pragma_params pragma_params
@ -324,14 +324,14 @@ opt_params
; ;
params params
: TOKEN { $$ = rua_macro_param ($<macro>0, &$1, scanner); } : TOKEN { $$ = rua_macro_param ($<macro>0, &$1, ctx); }
| params ',' TOKEN { $$ = rua_macro_param ($1, &$3, scanner); } | params ',' TOKEN { $$ = rua_macro_param ($1, &$3, ctx); }
; ;
args: arg_list args: arg_list
| args ',' | args ','
<macro>{ <macro>{
$$ = rua_macro_arg (&$<t>2, scanner); $$ = rua_macro_arg (&$<t>2, ctx);
} }
arg_list arg_list
; ;
@ -341,18 +341,18 @@ arg_list
| arg_list arg { $$ = $2; } | arg_list arg { $$ = $2; }
; ;
arg : '(' <macro> { $$ = rua_macro_append ($<macro>0, &$<t>1, scanner); } arg : '(' <macro> { $$ = rua_macro_append ($<macro>0, &$<t>1, ctx); }
arg_clist <macro> { $$ = $<macro>2; } arg_clist <macro> { $$ = $<macro>2; }
')' { $$ = rua_macro_append ($<macro>4, &$<t>5, scanner); } ')' { $$ = rua_macro_append ($<macro>4, &$<t>5, ctx); }
| TOKEN { $$ = rua_macro_append ($<macro>0, &$1, scanner); } | TOKEN { $$ = rua_macro_append ($<macro>0, &$1, ctx); }
| VALUE { $$ = rua_macro_append ($<macro>0, &$<t>1, scanner); } | VALUE { $$ = rua_macro_append ($<macro>0, &$<t>1, ctx); }
| ID { $$ = rua_macro_append ($<macro>0, &$<t>1, scanner); } | ID { $$ = rua_macro_append ($<macro>0, &$<t>1, ctx); }
; ;
arg_clist arg_clist
: /* emtpy */ { $$ = $<macro>0; } : /* emtpy */ { $$ = $<macro>0; }
| arg_clist arg { $$ = $2; } | arg_clist arg { $$ = $2; }
| arg_clist ',' { $$ = rua_macro_append ($1, &$<t>2, scanner); } | arg_clist ',' { $$ = rua_macro_append ($1, &$<t>2, ctx); }
; ;
id : ID { $$ = new_long_expr (0, false); } id : ID { $$ = new_long_expr (0, false); }
@ -366,7 +366,7 @@ defined
//the token's text is quite ephemeral when short (the usual case) //the token's text is quite ephemeral when short (the usual case)
defined_id defined_id
: ID { $$ = new_long_expr (rua_defined ($1, scanner), false); } : ID { $$ = new_long_expr (rua_defined ($1, ctx), false); }
; ;
unary_expr unary_expr
@ -374,8 +374,8 @@ unary_expr
| VALUE { $$ = get_long ($1, $<t.text>1, 1); } | VALUE { $$ = get_long ($1, $<t.text>1, 1); }
| QSTRING { $$ = get_long (0, $<t.text>1, 1); } | QSTRING { $$ = get_long (0, $<t.text>1, 1); }
| '(' expr ')' { $$ = $2; } | '(' expr ')' { $$ = $2; }
| DEFINED { rua_expand_off (scanner); } | DEFINED { rua_expand_off (ctx); }
defined { rua_expand_on (scanner); $$ = $3; } defined { rua_expand_on (ctx); $$ = $3; }
| '+' unary_expr { $$ = $2; } | '+' unary_expr { $$ = $2; }
| '-' unary_expr { $$ = UEXPR (-, $2); } | '-' unary_expr { $$ = UEXPR (-, $2); }
| '~' unary_expr { $$ = UEXPR (~, $2); } | '~' unary_expr { $$ = UEXPR (~, $2); }

View file

@ -995,7 +995,7 @@ convert_long (const expr_t *value)
static int static int
qc_token (rua_extra_t *extra, rua_val_t *lval, const rua_tok_t *tok, 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; 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: case rua_error:
break; break;
case rua_id: case rua_id:
token = extra->parser->keyword_or_id (lval, tok->text); token = extra->parser->keyword_or_id (lval, tok->text, ctx);
break; break;
case rua_grab: case rua_grab:
{ {
@ -1141,7 +1141,8 @@ dump_macro (rua_macro_t *macro)
} }
static int 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; 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) { if (-token == rua_ignore) {
return YYPUSH_MORE; return YYPUSH_MORE;
} }
return pre_yypush_parse (state, token, &lval, loc, scanner); return pre_yypush_parse (state, token, &lval, loc, ctx);
} else { } else {
if (!extra->suppressed) { if (!extra->suppressed) {
if (options.preprocess_only) { 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; return token ? YYPUSH_MORE : 0;
} }
if (!current_language.initialized && current_language.init) { if (!ctx->language->initialized && ctx->language->init) {
current_language.init (); ctx->language->init (ctx);
} }
QC_YYSTYPE lval = {}; QC_YYSTYPE lval = {};
token = qc_token (extra, &lval, tok, scanner); token = qc_token (extra, &lval, tok, scanner, ctx);
if (token >= 0) { if (token >= 0) {
auto p = extra->parser; 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 * static const rua_tok_t *
get_arg_token (bool last, const rua_tok_t *arg, const rua_macro_t *macro, 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; symbol_t *sym;
if (arg->token == -rua_va_opt) { if (arg->token == -rua_va_opt) {
sym = symtab_lookup (macro->params, arg->text); sym = symtab_lookup (macro->params, arg->text);
auto m = sym->macro; auto m = sym->macro;
m->update (m, scanner); m->update (m, ctx);
if (last) { if (last) {
if (m->tokens) { if (m->tokens) {
return (rua_tok_t *) m->tail; return (rua_tok_t *) m->tail;
@ -1383,7 +1384,7 @@ check_macro (rua_macro_t *macro)
} }
static int 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); auto extra = qc_yyget_extra (scanner);
rescan: rescan:
@ -1432,7 +1433,7 @@ rescan:
if (n->token == -rua_va_opt) { if (n->token == -rua_va_opt) {
sym = symtab_lookup (macro->params, n->text); sym = symtab_lookup (macro->params, n->text);
auto m = sym->macro; auto m = sym->macro;
m->update (m, scanner); m->update (m, ctx);
arg = m; arg = m;
} else { } else {
sym = symtab_lookup (macro->params, n->text); sym = symtab_lookup (macro->params, n->text);
@ -1448,8 +1449,8 @@ rescan:
bool sf = false; bool sf = false;
bool sl; bool sl;
do { do {
auto p = get_arg_token (true, &e, macro, scanner); auto p = get_arg_token (true, &e, macro, scanner, ctx);
auto n = get_arg_token (false, e.next->next, macro, scanner); auto n = get_arg_token (false, e.next->next, macro, scanner, ctx);
rua_tok_t cat; rua_tok_t cat;
if (!(sl = join_tokens (&cat, p, n, extra))) { if (!(sl = join_tokens (&cat, p, n, extra))) {
cat.location = e.next->location; cat.location = e.next->location;
@ -1476,7 +1477,7 @@ rescan:
} }
sym = symtab_lookup (macro->params, e.text); sym = symtab_lookup (macro->params, e.text);
auto m = sym->macro; auto m = sym->macro;
m->update (m, scanner); m->update (m, ctx);
queue_macro (extra, m); queue_macro (extra, m);
goto rescan; goto rescan;
} else if (token == -rua_id && macro->params } else if (token == -rua_id && macro->params
@ -1492,7 +1493,7 @@ rescan:
// force object-type macros in macro arguments to be expanded // force object-type macros in macro arguments to be expanded
auto m = sym->macro; auto m = sym->macro;
if (m->update) { if (m->update) {
m->update (m, scanner); m->update (m, ctx);
} }
queue_macro (extra, m); queue_macro (extra, m);
goto rescan; goto rescan;
@ -1513,7 +1514,7 @@ rescan:
collect_args (m, macro, scanner); collect_args (m, macro, scanner);
if (macro->cursor != c) { if (macro->cursor != c) {
if (m->update) { if (m->update) {
m->update (m, scanner); m->update (m, ctx);
} }
queue_macro (extra, m); queue_macro (extra, m);
goto rescan; goto rescan;
@ -1528,7 +1529,7 @@ rescan:
if (extra->recording) { if (extra->recording) {
token = preproc_token (extra, &lval, &e, scanner); token = preproc_token (extra, &lval, &e, scanner);
int s = pre_yypush_parse (extra->args_state, token, &lval, int s = pre_yypush_parse (extra->args_state, token, &lval,
&e.location, scanner); &e.location, ctx);
if (s == YYPUSH_MORE) { if (s == YYPUSH_MORE) {
goto rescan; goto rescan;
} }
@ -1563,7 +1564,7 @@ rescan:
&& !sym->macro->next) { && !sym->macro->next) {
auto macro = sym->macro; auto macro = sym->macro;
if (macro->update) { if (macro->update) {
macro->update (macro, scanner); macro->update (macro, ctx);
} }
if (macro->params) { if (macro->params) {
// function-type macro, need to check for ( so set up a temporary // 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 static int
rua_do_scan (yyscan_t scanner) rua_do_scan (yyscan_t scanner, rua_ctx_t *ctx)
{ {
auto extra = qc_yyget_extra (scanner); auto extra = qc_yyget_extra (scanner);
int status; int status;
rua_tok_t tok = {}; rua_tok_t tok = {};
do { do {
int token = next_token (&tok, scanner); int token = next_token (&tok, scanner, ctx);
if (!token && extra->cond_stack.size) { if (!token && extra->cond_stack.size) {
int ind = extra->cond_stack.size - 1; int ind = extra->cond_stack.size - 1;
auto cond = extra->cond_stack.a[ind]; auto cond = extra->cond_stack.a[ind];
@ -1643,42 +1644,44 @@ rua_do_scan (yyscan_t scanner)
extra->cond_stack = incl.cond_stack; extra->cond_stack = incl.cond_stack;
continue; continue;
} }
status = qc_process (extra, token, &tok, scanner); status = qc_process (extra, token, &tok, scanner, ctx);
} while (status == YYPUSH_MORE); } while (status == YYPUSH_MORE);
return status; return status;
} }
int 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; rua_extra_t extra;
yyscan_t scanner = rua_init_scanner (&extra, parser); ctx->extra = &extra;
yyset_in (in, scanner); ctx->scanner = rua_init_scanner (&extra, parser);
int status = rua_do_scan (scanner); yyset_in (in, ctx->scanner);
rua_destroy_scanner (scanner, &extra); int status = rua_do_scan (ctx->scanner, ctx);
rua_destroy_scanner (ctx->scanner, &extra);
return status; return status;
} }
int 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; auto loc = pr.loc;
rua_extra_t extra; rua_extra_t extra;
yyscan_t scanner = rua_init_scanner (&extra, parser); ctx->extra = &extra;
yy_scan_string (str, scanner); ctx->scanner = rua_init_scanner (&extra, parser);
int status = rua_do_scan (scanner); yy_scan_string (str, ctx->scanner);
rua_destroy_scanner (scanner, &extra); int status = rua_do_scan (ctx->scanner, ctx);
rua_destroy_scanner (ctx->scanner, &extra);
pr.loc = loc; pr.loc = loc;
return status; return status;
} }
rua_macro_t * 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) { if (extra->suppressed) {
return 0; return 0;
} }
@ -1694,16 +1697,16 @@ rua_start_macro (const char *name, bool params, void *scanner)
} }
} }
yy_pop_state (scanner); yy_pop_state (ctx->scanner);
yy_push_state (MACRO, scanner); yy_push_state (MACRO, ctx->scanner);
return alloc_macro (name, params); return alloc_macro (name, params);
} }
rua_macro_t * 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) { if (extra->suppressed) {
return 0; return 0;
} }
@ -1713,9 +1716,9 @@ rua_end_params (rua_macro_t *macro, void *scanner)
} }
rua_macro_t * 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) { if (extra->suppressed || !macro) {
return 0; 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_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) { if (extra->suppressed) {
return 0; 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 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) { if (extra->suppressed) {
return; return;
} }
@ -1890,14 +1893,14 @@ hashhash_error:
} }
rua_macro_t * 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; auto macro = extra->pending_macro;
rua_macro_t *arg; rua_macro_t *arg;
if (macro->num_params < 0 && macro->num_args == -macro->num_params) { if (macro->num_params < 0 && macro->num_args == -macro->num_params) {
arg = macro->args[macro->num_args - 1]; arg = macro->args[macro->num_args - 1];
rua_macro_append (arg, token, scanner); rua_macro_append (arg, token, ctx->scanner);
} else { } else {
if (macro->num_args < macro->num_params if (macro->num_args < macro->num_params
|| 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 void
rua_start_pragma (void *scanner) rua_start_pragma (rua_ctx_t *ctx)
{ {
if (options.preprocess_output) { if (options.preprocess_output) {
printf ("#pragma"); printf ("#pragma");
} }
yy_pop_state (scanner); yy_pop_state (ctx->scanner);
yy_push_state (PRAGMA, scanner); yy_push_state (PRAGMA, ctx->scanner);
} }
void void
rua_start_text (void *scanner) rua_start_text (rua_ctx_t *ctx)
{ {
yy_pop_state (scanner); yy_pop_state (ctx->scanner);
yy_push_state (TEXT, scanner); yy_push_state (TEXT, ctx->scanner);
} }
void 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; extra->expand = true;
yy_pop_state (scanner); yy_pop_state (ctx->scanner);
yy_push_state (PREPROC, scanner); yy_push_state (PREPROC, ctx->scanner);
} }
void 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; extra->expand = !extra->suppressed;
yy_pop_state (scanner); yy_pop_state (ctx->scanner);
yy_push_state (PREEXPR, scanner); yy_push_state (PREEXPR, ctx->scanner);
} }
void 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; extra->expand = !extra->suppressed;
} }
void 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; extra->expand = false;
} }
void 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->preprocessor = false;
extra->recording = false; extra->recording = false;
extra->expand = false; extra->expand = false;
yy_pop_state (scanner); yy_pop_state (ctx->scanner);
} }
static void static void
@ -2016,9 +2019,9 @@ dump_token (rua_tok_t *tok, rua_loc_t *loc, int state)
} }
void 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 = { rua_cond_t cond = {
.saw_true = false, .saw_true = false,
.saw_else = false, .saw_else = false,
@ -2033,49 +2036,49 @@ rua_start_if (bool expand, void *scanner)
DARRAY_APPEND (&extra->cond_stack, cond); DARRAY_APPEND (&extra->cond_stack, cond);
extra->expand = expand; extra->expand = expand;
yy_pop_state (scanner); yy_pop_state (ctx->scanner);
yy_push_state (PREEXPR, scanner); yy_push_state (PREEXPR, ctx->scanner);
} }
void 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; extra->expand = expand;
yy_pop_state (scanner); yy_pop_state (ctx->scanner);
yy_push_state (PREEXPR, scanner); yy_push_state (PREEXPR, ctx->scanner);
} }
void 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) { if (!extra->cond_stack.size) {
internal_error (0, "#if without start_if"); internal_error (0, "#if without start_if");
return; return;
} }
auto cond = &extra->cond_stack.a[extra->cond_stack.size - 1]; auto cond = &extra->cond_stack.a[extra->cond_stack.size - 1];
cond->saw_true = cond->enabled = pass; 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) { if (cond->own_state && !cond->enabled) {
extra->suppressed = true; extra->suppressed = true;
} }
//printf ("#if on %s:%d %d\n", GETSTR(pr.loc.file), //printf ("#if on %s:%d %d\n", GETSTR(pr.loc.file),
// cond->line, extra->suppressed); // cond->line, extra->suppressed);
// put PREEXPR on the stack for EOD to pop // put PREEXPR on the stack for EOD to pop
//yy_push_state (PREEXPR, scanner); //yy_push_state (PREEXPR, ctx->scanner);
} }
void 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) { if (!extra->cond_stack.size) {
error (0, "#else without #if"); error (0, "#else without #if");
return; 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]; auto cond = &extra->cond_stack.a[extra->cond_stack.size - 1];
if (cond->saw_else) { if (cond->saw_else) {
error (0, "#%s after #else", tok); 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) { if (cond->own_state && !cond->enabled) {
extra->suppressed = false; extra->suppressed = false;
//yy_pop_state (scanner); //yy_pop_state (ctx->scanner);
} }
pass &= !cond->saw_true; pass &= !cond->saw_true;
cond->enabled = pass; cond->enabled = pass;
@ -2096,41 +2099,41 @@ rua_else (bool pass, const char *tok, void *scanner)
extra->suppressed = true; extra->suppressed = true;
} }
// put PREEXPR on the stack for EOD to pop // put PREEXPR on the stack for EOD to pop
//yy_push_state (PREEXPR, scanner); //yy_push_state (PREEXPR, ctx->scanner);
} }
void 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) { if (!extra->cond_stack.size) {
error (0, "#endif without #if"); error (0, "#endif without #if");
return; return;
} }
//yy_pop_state (scanner); // remove DIRECTIVE state //yy_pop_state (ctx->scanner); // remove DIRECTIVE state
auto cond = DARRAY_REMOVE (&extra->cond_stack); auto cond = DARRAY_REMOVE (&extra->cond_stack);
//printf ("#endif on %s:%d for %d %d\n", GETSTR(pr.loc.file), //printf ("#endif on %s:%d for %d %d\n", GETSTR(pr.loc.file),
// pr.loc.line, cond.line, extra->suppressed); // pr.loc.line, cond.line, extra->suppressed);
if (cond.own_state && !cond.enabled) { if (cond.own_state && !cond.enabled) {
extra->suppressed = false; extra->suppressed = false;
//yy_pop_state (scanner); //yy_pop_state (ctx->scanner);
} }
// put PREEXPR on the stack for EOD to pop // put PREEXPR on the stack for EOD to pop
//yy_push_state (PREEXPR, scanner); //yy_push_state (PREEXPR, ctx->scanner);
} }
bool 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; auto macro_tab = extra->macro_tab;
return symtab_lookup (macro_tab, name); return symtab_lookup (macro_tab, name);
} }
void 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) { if (extra->suppressed) {
return; return;
} }
@ -2142,18 +2145,18 @@ rua_undefine (const char *name, void *scanner)
} }
void 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) { if (extra->suppressed) {
return; return;
} }
if (current_language.on_include) { if (ctx->language->on_include) {
if (!current_language.on_include (name)) { if (!ctx->language->on_include (name, ctx)) {
return; return;
} }
} }
struct yyguts_t * yyg = (struct yyguts_t*)scanner;//FIXME struct yyguts_t * yyg = (struct yyguts_t*)ctx->scanner;//FIXME
int quote = *name; int quote = *name;
name = make_string (name, 0); name = make_string (name, 0);
bool is_system; bool is_system;
@ -2171,8 +2174,8 @@ rua_include_file (const char *name, void *scanner)
.location = extra->location, .location = extra->location,
})); }));
extra->cond_stack = (rua_cond_stack_t) DARRAY_STATIC_INIT (8); extra->cond_stack = (rua_cond_stack_t) DARRAY_STATIC_INIT (8);
auto buffer = yy_create_buffer (yyin, YY_BUF_SIZE, scanner); auto buffer = yy_create_buffer (yyin, YY_BUF_SIZE, ctx->scanner);
yy_switch_to_buffer (buffer, scanner); yy_switch_to_buffer (buffer, ctx->scanner);
extra->location = (rua_loc_t) { extra->location = (rua_loc_t) {
.line = 1, .line = 1,
.column = 1, .column = 1,
@ -2183,9 +2186,9 @@ rua_include_file (const char *name, void *scanner)
} }
void 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) { if (extra->suppressed) {
return; return;
} }
@ -2197,31 +2200,33 @@ int
rua_parse_define (const char *def) rua_parse_define (const char *def)
{ {
int status; int status;
yyscan_t scanner;
rua_tok_t tok = { .location = { 1, 1, 1, 1 }, .token = -1, }; rua_tok_t tok = { .location = { 1, 1, 1, 1 }, .token = -1, };
rua_extra_t extra = { rua_extra_t extra = {
.preprocessor = true, .preprocessor = true,
.pre_state = pre_yypstate_new (), .pre_state = pre_yypstate_new (),
.macro_tab = cpp_macros, .macro_tab = cpp_macros,
}; };
rua_ctx_t ctx = {
.extra = &extra,
};
yylex_init_extra (&extra, &scanner); yylex_init_extra (&extra, &ctx.scanner);
yy_scan_string (def, scanner); yy_scan_string (def, ctx.scanner);
yy_push_state (PREPROC, scanner); yy_push_state (PREPROC, ctx.scanner);
do { do {
if (tok.token == -1) { if (tok.token == -1) {
tok.token = PRE_DEFINE; tok.token = PRE_DEFINE;
} else { } else {
tok.token = yylex (&tok, &tok.location, scanner); tok.token = yylex (&tok, &tok.location, ctx.scanner);
if (tok.text == extra.str_text) { if (tok.text == extra.str_text) {
tok.text = save_string (tok.text); tok.text = save_string (tok.text);
} }
status = 0; status = 0;
} }
while (tok.token) { 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) { if (status != YYPUSH_MORE || !extra.macro) {
break; break;
} }
@ -2233,7 +2238,7 @@ rua_parse_define (const char *def)
} }
} while (status == YYPUSH_MORE); } while (status == YYPUSH_MORE);
yylex_destroy (scanner); yylex_destroy (ctx.scanner);
pre_yypstate_delete (extra.pre_state); pre_yypstate_delete (extra.pre_state);
dstring_delete (extra.dstr); dstring_delete (extra.dstr);
return status; return status;
@ -2241,9 +2246,9 @@ rua_parse_define (const char *def)
void void
rua_line_info (const expr_t *line_expr, const char *file, 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 line = expr_long (line_expr);
int flags = flags_expr ? expr_long (flags_expr) : 0; 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 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; int file = extra->location.file;
if (macro->tokens && macro->tokens->location.file == file) { if (macro->tokens && macro->tokens->location.file == file) {
return; return;
@ -2286,9 +2291,9 @@ rua_macro_file (rua_macro_t *macro, void *scanner)
} }
void 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; int line = extra->location.line;
if (macro->tokens && macro->tokens->location.line == line) { if (macro->tokens && macro->tokens->location.line == line) {
@ -2312,7 +2317,7 @@ rua_macro_line (rua_macro_t *macro, void *scanner)
} }
static void 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); auto extra = qc_yyget_extra (scanner);
rua_extra_t arg_extra = *extra; 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) { while (true) {
rua_tok_t e; rua_tok_t e;
if (next_token (&e, scanner)) { if (next_token (&e, scanner, ctx)) {
if (macro->tokens if (macro->tokens
|| (e.token != -rua_space && e.token != -rua_ignore)) { || (e.token != -rua_space && e.token != -rua_ignore)) {
append_token (macro, &e); append_token (macro, &e);
@ -2382,19 +2387,19 @@ macro_empty (rua_macro_t *macro, yyscan_t scanner)
} }
void 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->tokens = 0;
macro->tail = &macro->tokens; macro->tail = &macro->tokens;
auto extra = qc_yyget_extra (scanner); auto extra = ctx->extra;
auto cur = extra->macro; auto cur = extra->macro;
if (!cur || !cur->params || cur->num_params >= 0) { if (!cur || !cur->params || cur->num_params >= 0) {
warning (0, "__VA_OPT__ can appear only in the expansion of a " warning (0, "__VA_OPT__ can appear only in the expansion of a "
"variadic macro"); "variadic macro");
return; return;
} }
if (macro_empty (cur->args[~cur->num_params], scanner)) { if (macro_empty (cur->args[~cur->num_params], ctx->scanner)) {
return; return;
} }
auto arg = macro->args[0]; 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->num_args = cur->num_args;
arg->args = cur->args; arg->args = cur->args;
expand_arg (macro, arg, scanner); expand_arg (macro, arg, ctx->scanner, ctx);
} }
void 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->tokens = 0;
macro->tail = &macro->tokens; macro->tail = &macro->tokens;
auto extra = qc_yyget_extra (scanner); auto extra = ctx->extra;
auto cur = extra->macro; auto cur = extra->macro;
if (!cur || !cur->params || cur->num_params >= 0) { if (!cur || !cur->params || cur->num_params >= 0) {
warning (0, "__VA_ARGS__ can appear only in the expansion of a " warning (0, "__VA_ARGS__ can appear only in the expansion of a "

View file

@ -32,7 +32,7 @@
%define api.push-pull push %define api.push-pull push
%define api.token.prefix {QC_} %define api.token.prefix {QC_}
%locations %locations
%parse-param {void *scanner} %parse-param {struct rua_ctx_s *ctx}
%define api.value.type {rua_val_t} %define api.value.type {rua_val_t}
%define api.location.type {rua_loc_t} %define api.location.type {rua_loc_t}
@ -83,11 +83,11 @@
#include "tools/qfcc/source/qc-parse.h" #include "tools/qfcc/source/qc-parse.h"
#define qc_yytext qc_yyget_text (scanner) #define qc_yytext qc_yyget_text (ctx->scanner)
char *qc_yyget_text (void *scanner); char *qc_yyget_text (rua_ctx_t *ctx);
static void static void
yyerror (YYLTYPE *yylloc, void *scanner, const char *s) yyerror (YYLTYPE *yylloc, rua_ctx_t *ctx, const char *s)
{ {
#ifdef QC_YYERROR_VERBOSE #ifdef QC_YYERROR_VERBOSE
error (0, "%s %s\n", qc_yytext, s); error (0, "%s %s\n", qc_yytext, s);
@ -97,12 +97,12 @@ yyerror (YYLTYPE *yylloc, void *scanner, const char *s)
} }
static void static void
parse_error (void *scanner) parse_error (rua_ctx_t *ctx)
{ {
error (0, "parse error before %s", qc_yytext); 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 YYLLOC_DEFAULT(Current, Rhs, N) RUA_LOC_DEFAULT(Current, Rhs, N)
#define YYLOCATION_PRINT rua_print_location #define YYLOCATION_PRINT rua_print_location
@ -310,7 +310,7 @@ overload_spec (void)
} }
static specifier_t static specifier_t
generic_spec (void) generic_spec (rua_ctx_t *ctx)
{ {
specifier_t spec = { specifier_t spec = {
.storage = current_storage, .storage = current_storage,
@ -609,7 +609,7 @@ is_null_spec (specifier_t spec)
} }
static int 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 = new_symbol (spec.sym->name);
spec.sym->type = spec.type; spec.sym->type = spec.type;
@ -626,7 +626,7 @@ use_type_name (specifier_t spec)
} }
static void __attribute__((used)) static void __attribute__((used))
check_specifiers (specifier_t spec) check_specifiers (specifier_t spec, rua_ctx_t *ctx)
{ {
if (!is_null_spec (spec)) { if (!is_null_spec (spec)) {
if (!spec.type && !spec.sym) { 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. // 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, // this is allowed in C, so long as it's in a different scope,
// or the types are the same // 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", error (0, "%s redeclared as different kind of symbol",
spec.sym->name); spec.sym->name);
} }
@ -654,7 +654,7 @@ check_specifiers (specifier_t spec)
} }
static const expr_t * 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; auto sym = spec.sym;
spec.sym = nullptr; spec.sym = nullptr;
@ -717,15 +717,15 @@ fndef
datadef datadef
: defspecs notype_initdecls ';' : defspecs notype_initdecls ';'
{ {
expr_process ($2); expr_process ($2, ctx);
} }
| declspecs_nots notype_initdecls ';' | declspecs_nots notype_initdecls ';'
{ {
expr_process ($2); expr_process ($2, ctx);
} }
| declspecs_ts initdecls ';' | declspecs_ts initdecls ';'
{ {
expr_process ($2); expr_process ($2, ctx);
} }
| declspecs_ts qc_func_params | declspecs_ts qc_func_params
{ {
@ -829,8 +829,9 @@ qc_nocode_func
: identifier '=' '#' expr : identifier '=' '#' expr
{ {
specifier_t spec = qc_set_symbol ($<spec>0, $1); specifier_t spec = qc_set_symbol ($<spec>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); symbol_t *sym = function_symbol (spec);
build_builtin_function (sym, bi_val, 0, spec.storage); build_builtin_function (sym, bi_val, 0, spec.storage);
} }
@ -862,6 +863,7 @@ qc_code_func
.function = current_func, .function = current_func,
}; };
specifier_t spec = qc_set_symbol ($<spec>0, $1); specifier_t spec = qc_set_symbol ($<spec>0, $1);
spec.is_overload |= ctx->language->always_overload;
symbol_t *sym = function_symbol (spec); symbol_t *sym = function_symbol (spec);
current_func = begin_function (sym, 0, current_symtab, 0, current_func = begin_function (sym, 0, current_symtab, 0,
spec.storage); spec.storage);
@ -871,7 +873,7 @@ qc_code_func
} }
compound_statement_ns compound_statement_ns
{ {
auto statements = (expr_t *) expr_process ($6); auto statements = (expr_t *) expr_process ($6, ctx);
build_code_function ($1, $3, statements); build_code_function ($1, $3, statements);
current_symtab = $<funcstate>5.symtab; current_symtab = $<funcstate>5.symtab;
current_func = $<funcstate>5.function; current_func = $<funcstate>5.function;
@ -958,8 +960,8 @@ initdecls
; ;
initdecl initdecl
: declarator '=' var_initializer { $$ = decl_expr ($1, $3); } : declarator '=' var_initializer { $$ = decl_expr ($1, $3, ctx); }
| declarator { $$ = decl_expr ($1, nullptr); } | declarator { $$ = decl_expr ($1, nullptr, ctx); }
; ;
notype_initdecls notype_initdecls
@ -971,8 +973,8 @@ notype_initdecls
; ;
notype_initdecl notype_initdecl
: notype_declarator '=' var_initializer { $$ = decl_expr ($1, $3); } : notype_declarator '=' var_initializer { $$ = decl_expr ($1, $3, ctx); }
| notype_declarator { $$ = decl_expr ($1, nullptr); } | notype_declarator { $$ = decl_expr ($1, nullptr, ctx); }
; ;
/* various lists of type specifiers, storage class etc */ /* various lists of type specifiers, storage class etc */
@ -1173,6 +1175,7 @@ function_body
: method_optional_state_expr : method_optional_state_expr
{ {
specifier_t spec = default_type ($<spec>0, $<spec>0.sym); specifier_t spec = default_type ($<spec>0, $<spec>0.sym);
spec.is_overload |= ctx->language->always_overload;
$<symbol>$ = function_symbol (spec); $<symbol>$ = function_symbol (spec);
} }
save_storage save_storage
@ -1188,7 +1191,7 @@ function_body
} }
compound_statement_ns compound_statement_ns
{ {
auto statements = (expr_t *) expr_process ($5); auto statements = (expr_t *) expr_process ($5, ctx);
build_code_function ($<symbol>2, $1, statements); build_code_function ($<symbol>2, $1, statements);
current_symtab = $<funcstate>4.symtab; current_symtab = $<funcstate>4.symtab;
current_func = $<funcstate>4.function; current_func = $<funcstate>4.function;
@ -1197,8 +1200,9 @@ function_body
| '=' '#' expr ';' | '=' '#' expr ';'
{ {
specifier_t spec = $<spec>0; specifier_t spec = $<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); symbol_t *sym = function_symbol (spec);
build_builtin_function (sym, bi_val, 0, spec.storage); build_builtin_function (sym, bi_val, 0, spec.storage);
} }
@ -1219,7 +1223,7 @@ storage_class
| SYSTEM { $$ = storage_spec (sc_system); } | SYSTEM { $$ = storage_spec (sc_system); }
| TYPEDEF { $$ = typedef_spec (); } | TYPEDEF { $$ = typedef_spec (); }
| OVERLOAD { $$ = overload_spec (); } | OVERLOAD { $$ = overload_spec (); }
| GENERIC '(' { $<spec>$ = generic_spec (); } | GENERIC '(' { $<spec>$ = generic_spec (ctx); }
generic_param_list ')' generic_param_list ')'
{ {
$$ = $<spec>3; $$ = $<spec>3;
@ -1408,7 +1412,7 @@ enumerator
} }
| identifier '=' expr | identifier '=' expr
{ {
$expr = expr_process ($expr); $expr = expr_process ($expr, ctx);
add_enum ($<symbol>0, $identifier, $expr); add_enum ($<symbol>0, $identifier, $expr);
} }
; ;
@ -2630,7 +2634,7 @@ methoddef
} }
compound_statement_ns compound_statement_ns
{ {
auto statements = (expr_t *) expr_process ($7); auto statements = (expr_t *) expr_process ($7, ctx);
build_code_function ($<symbol>4, $3, statements); build_code_function ($<symbol>4, $3, statements);
current_symtab = $<funcstate>6.symtab; current_symtab = $<funcstate>6.symtab;
current_func = $<funcstate>6.function; current_func = $<funcstate>6.function;
@ -2640,7 +2644,7 @@ methoddef
{ {
symbol_t *sym; symbol_t *sym;
method_t *method = $2; 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->instance = $1;
method = class_find_method (current_class, method); method = class_find_method (current_class, method);
@ -3022,7 +3026,8 @@ static keyword_t keywords[] = {
}; };
static int 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) { if (keyword->value == QC_STRUCT) {
lval->op = token[0]; lval->op = token[0];
@ -3065,7 +3070,7 @@ qc_process_keyword (QC_YYSTYPE *lval, keyword_t *keyword, const char *token)
} }
static int 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 *keyword_tab;
static hashtab_t *qf_keyword_tab; static hashtab_t *qf_keyword_tab;
@ -3119,7 +3124,7 @@ qc_keyword_or_id (QC_YYSTYPE *lval, const char *token)
if (!keyword) if (!keyword)
keyword = Hash_Find (keyword_tab, token); keyword = Hash_Find (keyword_tab, token);
if (keyword && keyword->value) if (keyword && keyword->value)
return qc_process_keyword (lval, keyword, token); return qc_process_keyword (lval, keyword, token, ctx);
if (token[0] == '@') { if (token[0] == '@') {
return '@'; return '@';
} }
@ -3154,7 +3159,7 @@ qc_keyword_or_id (QC_YYSTYPE *lval, const char *token)
} }
static int static int
qc_yyparse (FILE *in) qc_yyparse (FILE *in, rua_ctx_t *ctx)
{ {
rua_parser_t parser = { rua_parser_t parser = {
.parse = qc_yypush_parse, .parse = qc_yypush_parse,
@ -3162,13 +3167,13 @@ qc_yyparse (FILE *in)
.directive = qc_directive, .directive = qc_directive,
.keyword_or_id = qc_keyword_or_id, .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); qc_yypstate_delete (parser.state);
return ret; return ret;
} }
int int
qc_parse_string (const char *str) qc_parse_string (const char *str, rua_ctx_t *ctx)
{ {
rua_parser_t parser = { rua_parser_t parser = {
.parse = qc_yypush_parse, .parse = qc_yypush_parse,
@ -3176,12 +3181,13 @@ qc_parse_string (const char *str)
.directive = qc_directive, .directive = qc_directive,
.keyword_or_id = qc_keyword_or_id, .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); glsl_yypstate_delete (parser.state);
return ret; return ret;
} }
static int qc_finish (const char *file) static int qc_finish (const char *file, rua_ctx_t *ctx)
{ {
if (options.frames_files) { if (options.frames_files) {
write_frame_macros (va (0, "%s.frame", file_basename (file, 0))); write_frame_macros (va (0, "%s.frame", file_basename (file, 0)));
@ -3191,9 +3197,9 @@ static int qc_finish (const char *file)
} }
static void static void
rua_init (void) rua_init (rua_ctx_t *ctx)
{ {
current_language.initialized = true; ctx->language->initialized = true;
if (options.code.spirv) { if (options.code.spirv) {
static module_t module; //FIXME probably not what I want static module_t module; //FIXME probably not what I want
pr.module = &module; pr.module = &module;

View file

@ -372,21 +372,20 @@ setup_sym_file (const char *output_file)
} }
static int 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; int err;
FILE *yyin; FILE *yyin;
auto lang = ctx->language;
yyin = preprocess_file (file, 0); yyin = preprocess_file (file, 0);
if (options.preprocess_only || !yyin) { if (options.preprocess_only || !yyin) {
if (yyin) { if (yyin) {
return lang->parse (yyin); return lang->parse (yyin, ctx);
} }
return !options.preprocess_only; return !options.preprocess_only;
} }
current_language = *lang;
InitData (); InitData ();
chain_initial_types (); chain_initial_types ();
begin_compilation (); begin_compilation ();
@ -394,7 +393,7 @@ compile_to_obj (const char *file, const char *obj, language_t *lang)
pr.comp_dir = save_cwd (); pr.comp_dir = save_cwd ();
add_source_file (file); add_source_file (file);
lang->initialized = false; lang->initialized = false;
err = lang->parse (yyin) || pr.error_count; err = lang->parse (yyin, ctx) || pr.error_count;
fclose (yyin); fclose (yyin);
if (cpp_name && !options.save_temps) { if (cpp_name && !options.save_temps) {
if (unlink (tempname->str)) { if (unlink (tempname->str)) {
@ -406,7 +405,7 @@ compile_to_obj (const char *file, const char *obj, language_t *lang)
qfo_t *qfo; qfo_t *qfo;
if (lang->finish) { if (lang->finish) {
err = lang->finish (file); err = lang->finish (file, ctx);
} }
if (!err) { if (!err) {
emit_ctor (); emit_ctor ();
@ -570,10 +569,14 @@ separate_compile (void)
// need *file for checking -lfoo // need *file for checking -lfoo
auto lang = file_language (*file, extension->str); auto lang = file_language (*file, extension->str);
if (lang) { if (lang) {
rua_ctx_t ctx = {
.language = lang,
};
if (options.verbosity >= 1) if (options.verbosity >= 1)
printf ("%s %s\n", *file, output_file->str); printf ("%s %s\n", *file, output_file->str);
temp_files[i++] = save_string (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) { if (!err) {
cpp_write_dependencies (*file, output_file->str); cpp_write_dependencies (*file, output_file->str);
@ -676,13 +679,11 @@ parse_cpp_line (script_t *script, dstring_t *filename)
} }
static int static int
compile_file (const char *filename) compile_file (const char *filename, rua_ctx_t *ctx)
{ {
int err; int err;
FILE *yyin; FILE *yyin;
int (*yyparse) (FILE *in) = lang_ruamoko.parse;
current_language = lang_ruamoko;
yyin = preprocess_file (filename, 0); yyin = preprocess_file (filename, 0);
if (options.preprocess_only || !yyin) if (options.preprocess_only || !yyin)
return !options.preprocess_only; return !options.preprocess_only;
@ -695,7 +696,7 @@ compile_file (const char *filename)
}; };
add_source_file (filename); add_source_file (filename);
clear_frame_macros (); clear_frame_macros ();
err = yyparse (yyin) || pr.error_count; err = ctx->language->parse (yyin, ctx) || pr.error_count;
fclose (yyin); fclose (yyin);
if (cpp_name && (!options.save_temps)) { if (cpp_name && (!options.save_temps)) {
if (unlink (tempname->str)) { if (unlink (tempname->str)) {
@ -780,6 +781,9 @@ progs_src_compile (void)
} }
setup_sym_file (options.output_file); setup_sym_file (options.output_file);
rua_ctx_t ctx = {
.language = &lang_ruamoko,
};
InitData (); InitData ();
chain_initial_types (); chain_initial_types ();
@ -811,7 +815,7 @@ progs_src_compile (void)
fprintf (single, "$frame_write \"%s.frame\"\n", fprintf (single, "$frame_write \"%s.frame\"\n",
file_basename (qc_filename->str, 0)); file_basename (qc_filename->str, 0));
} else { } else {
if (compile_file (qc_filename->str)) if (compile_file (qc_filename->str, &ctx))
return 1; return 1;
if (options.frames_files) { if (options.frames_files) {
write_frame_macros (va (0, "%s.frame", write_frame_macros (va (0, "%s.frame",
@ -827,7 +831,7 @@ progs_src_compile (void)
if (single) { if (single) {
int err; int err;
fclose (single); fclose (single);
err = compile_file (single_name->str); err = compile_file (single_name->str, &ctx);
if (!options.save_temps) { if (!options.save_temps) {
if (unlink (single_name->str)) { if (unlink (single_name->str)) {
perror ("unlink"); perror ("unlink");

View file

@ -80,7 +80,7 @@ int yyget_debug (yyscan_t yyscanner) __attribute__((pure));
FILE *yyget_in (yyscan_t yyscanner) __attribute__((pure)); FILE *yyget_in (yyscan_t yyscanner) __attribute__((pure));
FILE *yyget_out (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 int convert_relop (const char *relop) __attribute__((pure));
static void update_loc (rua_loc_t *loc, size_t textlen); static void update_loc (rua_loc_t *loc, size_t textlen);
static void next_line (rua_loc_t *loc, yyscan_t scanner); static void next_line (rua_loc_t *loc, yyscan_t scanner);
@ -108,6 +108,7 @@ FRAMEID {ID}(\.{ID})*
%x GRAB_FRAME GRAB_OTHER COMMENT %x GRAB_FRAME GRAB_OTHER COMMENT
%% %%
auto ctx = (rua_ctx_t *) qp_yyget_extra (yyscanner);
grab_frame = GRAB_FRAME; grab_frame = GRAB_FRAME;
grab_other = GRAB_OTHER; grab_other = GRAB_OTHER;
@ -142,7 +143,7 @@ FRAMEID {ID}(\.{ID})*
return VALUE; return VALUE;
} }
{ID} return keyword_or_id (yylval, yytext); {ID} return keyword_or_id (yylval, yytext, ctx);
\"(\\.|[^"\\])*\" { \"(\\.|[^"\\])*\" {
const char *s = make_string (yytext, 0); const char *s = make_string (yytext, 0);
@ -247,7 +248,7 @@ keyword_get_key (const void *kw, void *unused)
} }
static int 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; static hashtab_t *keyword_tab;
keyword_t *keyword; keyword_t *keyword;
@ -308,19 +309,19 @@ convert_relop (const char *relop)
} }
static int static int
qp_yyparse (FILE *in) qp_yyparse (FILE *in, rua_ctx_t *ctx)
{ {
int status; int status;
yyscan_t scanner; yyscan_t scanner;
qp_yypstate *ps = qp_yypstate_new (); qp_yypstate *ps = qp_yypstate_new ();
yylex_init_extra (0, &scanner); yylex_init_extra (ctx, &scanner);
yyset_in (in, scanner); yyset_in (in, scanner);
YYLTYPE lloc = { 1, 1, 1, 1 }; YYLTYPE lloc = { 1, 1, 1, 1 };
do { do {
YYSTYPE lval; YYSTYPE lval;
int token = yylex (&lval, &lloc, scanner); 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); } while (status == YYPUSH_MORE);
yylex_destroy (scanner); yylex_destroy (scanner);

View file

@ -43,11 +43,8 @@
void void
rua_parse_declaration (specifier_t spec, symbol_t *sym, const expr_t *init, 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) { if (sym && sym->sy_type == sy_expr) {
auto id_list = sym->expr; auto id_list = sym->expr;
if (id_list->type != ex_list) { if (id_list->type != ex_list) {

View file

@ -236,15 +236,15 @@ ruamoko_assign_vector (const expr_t *dst, const expr_t *src)
static switch_block_t *switch_block; static switch_block_t *switch_block;
const expr_t * 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); scoped_src_loc (expr);
auto test = expr_process (expr->switchblock.test); auto test = expr_process (expr->switchblock.test, ctx);
auto sb = switch_block; auto sb = switch_block;
switch_block = new_switch_block (); switch_block = new_switch_block ();
switch_block->test = test; 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 break_label = expr->switchblock.break_label;
auto swtch = switch_expr (switch_block, break_label, body); auto swtch = switch_expr (switch_block, break_label, body);
@ -253,13 +253,13 @@ ruamoko_proc_switch (const expr_t *expr)
} }
const expr_t * 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); scoped_src_loc (expr);
if (expr->caselabel.end_value) { if (expr->caselabel.end_value) {
internal_error (expr, "case ranges not implemented"); 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)) { if (is_error (value)) {
return value; return value;
} }
@ -342,10 +342,10 @@ ruamoko_field_array (const expr_t *e)
} }
const expr_t * 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); scoped_src_loc (expr);
auto e = expr_process (expr->expr.e1); auto e = expr_process (expr->expr.e1, ctx);
if (is_error (e)) { if (is_error (e)) {
return e; return e;
} }