[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 **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 language_s language_t;
typedef struct defspace_s defspace_t;
typedef struct rua_ctx_s rua_ctx_t;
void glsl_init_comp (void);
void glsl_init_vert (void);
void glsl_init_tesc (void);
void glsl_init_tese (void);
void glsl_init_geom (void);
void glsl_init_frag (void);
void glsl_init_comp (rua_ctx_t *ctx);
void glsl_init_vert (rua_ctx_t *ctx);
void glsl_init_tesc (rua_ctx_t *ctx);
void glsl_init_tese (rua_ctx_t *ctx);
void glsl_init_geom (rua_ctx_t *ctx);
void glsl_init_frag (rua_ctx_t *ctx);
int glsl_parse_string (const char *str);
int glsl_parse_string (const char *str, rua_ctx_t *ctx);
extern language_t lang_glsl_comp;
extern language_t lang_glsl_vert;
@ -109,7 +110,7 @@ typedef struct glsl_sublang_s {
const char *name;
const char **interface_default_names;
} glsl_sublang_t;
#define glsl_sublang (*(glsl_sublang_t *) current_language.sublanguage)
extern glsl_sublang_t glsl_sublang;
extern glsl_sublang_t glsl_comp_sublanguage;
extern glsl_sublang_t glsl_vert_sublanguage;
extern glsl_sublang_t glsl_tesc_sublanguage;
@ -127,11 +128,11 @@ void glsl_apply_attributes (symtab_t *attributes, specifier_t spec);
void glsl_parse_declaration (specifier_t spec, symbol_t *sym,
const expr_t *init, symtab_t *symtab,
expr_t *block);
void glsl_declare_field (specifier_t spec, symtab_t *symtab);
expr_t *block, rua_ctx_t *ctx);
void glsl_declare_field (specifier_t spec, symtab_t *symtab, rua_ctx_t *ctx);
void glsl_layout (const ex_list_t *qualifiers, specifier_t spec);
bool glsl_on_include (const char *name);
bool glsl_on_include (const char *name, rua_ctx_t *ctx);
void glsl_include (int behavior, void *scanner);
void glsl_multiview (int behavior, void *scanner);

View file

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

View file

@ -34,6 +34,7 @@ typedef struct type_s type_t;
typedef struct function_s function_t;
typedef struct expr_s expr_t;
typedef struct specifier_s specifier_t;
typedef struct rua_ctx_s rua_ctx_t;
typedef struct {
bool (*value_too_large) (const type_t *val_type);
@ -45,9 +46,9 @@ typedef struct {
const expr_t *(*initialized_temp) (const type_t *type, const expr_t *src);
const expr_t *(*assign_vector) (const expr_t *dst, const expr_t *src);
const expr_t *(*proc_switch) (const expr_t *expr);
const expr_t *(*proc_caselabel) (const expr_t *expr);
const expr_t *(*proc_address) (const expr_t *expr);
const expr_t *(*proc_switch) (const expr_t *expr, rua_ctx_t *ctx);
const expr_t *(*proc_caselabel) (const expr_t *expr, rua_ctx_t *ctx);
const expr_t *(*proc_address) (const expr_t *expr, rua_ctx_t *ctx);
unsigned label_id;
} target_t;
@ -60,9 +61,9 @@ extern target_t spirv_target;
bool target_set_backend (const char *tgt);
const expr_t *ruamoko_proc_switch (const expr_t *expr);
const expr_t *ruamoko_proc_caselabel (const expr_t *expr);
const expr_t *ruamoko_proc_switch (const expr_t *expr, rua_ctx_t *ctx);
const expr_t *ruamoko_proc_caselabel (const expr_t *expr, rua_ctx_t *ctx);
const expr_t *ruamoko_field_array (const expr_t *e);
const expr_t *ruamoko_proc_address (const expr_t *expr);
const expr_t *ruamoko_proc_address (const expr_t *expr, rua_ctx_t *ctx);
#endif//__target_h

View file

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

View file

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

View file

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

View file

@ -43,7 +43,7 @@
void
glsl_parse_declaration (specifier_t spec, symbol_t *sym, const expr_t *init,
symtab_t *symtab, expr_t *block)
symtab_t *symtab, expr_t *block, rua_ctx_t *ctx)
{
if (sym && sym->type) {
internal_error (0, "unexected typed symbol");
@ -105,7 +105,7 @@ glsl_parse_declaration (specifier_t spec, symbol_t *sym, const expr_t *init,
}
void
glsl_declare_field (specifier_t spec, symtab_t *symtab)
glsl_declare_field (specifier_t spec, symtab_t *symtab, rua_ctx_t *ctx)
{
auto attributes = glsl_optimize_attributes (spec.attributes);
spec.sym = declare_field (spec, symtab);

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -43,11 +43,8 @@
void
rua_parse_declaration (specifier_t spec, symbol_t *sym, const expr_t *init,
symtab_t *symtab, expr_t *block)
symtab_t *symtab, expr_t *block, rua_ctx_t *ctx)
{
if (sym && sym->type) {
internal_error (0, "unexected typed symbol");
}
if (sym && sym->sy_type == sy_expr) {
auto id_list = sym->expr;
if (id_list->type != ex_list) {

View file

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