mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-04-07 01:42:04 +00:00
[qfcc] Add declaration expressions
Now declarations can be deferred too, thus things like generic/template and inline functions should be possible. However, the most important thing is this is a step towards a cleaner middle layer for compilation, separating front-end language from back-end code-gen.
This commit is contained in:
parent
8b9333e108
commit
d46620fcf4
12 changed files with 266 additions and 85 deletions
|
@ -114,6 +114,7 @@ typedef struct ex_list_s {
|
|||
|
||||
typedef struct {
|
||||
ex_list_t list;
|
||||
symtab_t *scope;
|
||||
const expr_t *result; ///< the result of this block if non-void
|
||||
int is_call; ///< this block exprssion forms a function call
|
||||
void *return_addr; ///< who allocated this
|
||||
|
@ -342,6 +343,11 @@ typedef struct {
|
|||
const type_t *type;
|
||||
} ex_array_t;
|
||||
|
||||
typedef struct {
|
||||
specifier_t spec;
|
||||
ex_list_t list;
|
||||
} ex_decl_t;
|
||||
|
||||
#define POINTER_VAL(p) (((p).def ? (p).def->offset : 0) + (p).val)
|
||||
|
||||
typedef struct expr_s {
|
||||
|
@ -389,6 +395,7 @@ typedef struct expr_s {
|
|||
ex_cond_t cond; ///< ?: conditional expression
|
||||
ex_field_t field; ///< field reference expression
|
||||
ex_array_t array; ///< array index expression
|
||||
ex_decl_t decl; ///< variable declaration expression
|
||||
};
|
||||
} expr_t;
|
||||
|
||||
|
@ -460,6 +467,8 @@ expr_t *expr_prepend_list (expr_t *list, ex_list_t *prepend);
|
|||
*/
|
||||
expr_t *new_expr (void);
|
||||
|
||||
expr_t *new_error_expr (void);
|
||||
|
||||
/** Create a new label name.
|
||||
|
||||
The label name is guaranteed to be unique to the compilation. It is made
|
||||
|
@ -902,6 +911,9 @@ expr_t *new_cond_expr (const expr_t *test, const expr_t *true_expr,
|
|||
const expr_t *false_expr);
|
||||
expr_t *new_field_expr (const expr_t *object, const expr_t *member);
|
||||
expr_t *new_array_expr (const expr_t *base, const expr_t *index);
|
||||
expr_t *new_decl_expr (specifier_t spec);
|
||||
expr_t *append_decl (expr_t *decl, symbol_t *sym, const expr_t *init);
|
||||
expr_t *append_decl_list (expr_t *decl, const expr_t *list);
|
||||
|
||||
/** Create an expression of the correct type that references the specified
|
||||
parameter slot.
|
||||
|
|
|
@ -56,7 +56,7 @@ EX_EXPR(compound) ///< compound initializer
|
|||
EX_EXPR(memset) ///< memset needs three params...
|
||||
EX_EXPR(alias) ///< view expression as different type (::ex_alias_t)
|
||||
EX_EXPR(address) ///< address of an lvalue expression (::ex_address_t)
|
||||
EX_EXPR(assign) ///< assignment of src expr to dst expr (::ex_assing_t)
|
||||
EX_EXPR(assign) ///< assignment of src expr to dst expr (::ex_assign_t)
|
||||
EX_EXPR(branch) ///< branch expression (::ex_branch_t)
|
||||
EX_EXPR(inout) ///< inout arg expression (::ex_inout_t)
|
||||
EX_EXPR(return) ///< return expression (::ex_return_t)
|
||||
|
@ -72,7 +72,8 @@ EX_EXPR(type) ///< type expression for generics
|
|||
EX_EXPR(incop) ///< pre or post increment/decrement (::ex_incop_t)
|
||||
EX_EXPR(cond) ///< ?: conditional expression (::ex_cond_t)
|
||||
EX_EXPR(field) ///< field reference expression (::ex_field_t)
|
||||
EX_EXPR(array) ///< array index ex_field_t (::ex_array_t)
|
||||
EX_EXPR(array) ///< array index expression (::ex_array_t)
|
||||
EX_EXPR(decl) ///< delcaration expression (::ex_array_t)
|
||||
|
||||
#undef EX_EXPR
|
||||
|
||||
|
|
|
@ -98,8 +98,7 @@ glsl_block_t *glsl_get_block (const char *name, glsl_interface_t interface);
|
|||
symtab_t *glsl_optimize_attributes (attribute_t *attributes);
|
||||
void glsl_apply_attributes (symtab_t *attributes, specifier_t spec);
|
||||
|
||||
void glsl_parse_declaration (specifier_t spec,
|
||||
symbol_t *sym, const type_t *array,
|
||||
void glsl_parse_declaration (specifier_t spec, symbol_t *sym,
|
||||
const expr_t *init, symtab_t *symtab);
|
||||
void glsl_declare_field (specifier_t spec, symtab_t *symtab);
|
||||
void glsl_layout (const ex_list_t *qualifiers, specifier_t spec);
|
||||
|
|
|
@ -68,6 +68,7 @@ typedef struct rua_loc_s {
|
|||
} while (0)
|
||||
|
||||
typedef struct expr_s expr_t;
|
||||
typedef struct symbol_s symbol_t;
|
||||
typedef struct symtab_s symtab_t;
|
||||
typedef struct function_s function_t;
|
||||
|
||||
|
@ -202,6 +203,8 @@ typedef struct language_s {
|
|||
void (*extension) (const char *name, const char *value, void *scanner);
|
||||
void (*version) (int version, const char *profile);
|
||||
bool (*on_include) (const char *name);
|
||||
void (*parse_declaration) (specifier_t spec, symbol_t *sym,
|
||||
const expr_t *init, symtab_t *symtab);
|
||||
void *sublanguage;
|
||||
} language_t;
|
||||
|
||||
|
|
|
@ -141,6 +141,7 @@ get_type (const expr_t *e)
|
|||
case ex_error:
|
||||
return 0;
|
||||
case ex_return:
|
||||
case ex_decl:
|
||||
internal_error (e, "unexpected expression type");
|
||||
case ex_label:
|
||||
case ex_compound:
|
||||
|
@ -461,7 +462,7 @@ new_label_name (void)
|
|||
return lname;
|
||||
}
|
||||
|
||||
static expr_t *
|
||||
expr_t *
|
||||
new_error_expr (void)
|
||||
{
|
||||
expr_t *e = new_expr ();
|
||||
|
@ -1593,8 +1594,12 @@ new_type_expr (const type_t *type)
|
|||
expr_t *
|
||||
append_expr (expr_t *block, const expr_t *e)
|
||||
{
|
||||
if (block->type != ex_block)
|
||||
if (block->type != ex_block) {
|
||||
internal_error (block, "not a block expression");
|
||||
}
|
||||
if (e == block) {
|
||||
internal_error (block, "adding block to itself");
|
||||
}
|
||||
|
||||
if (!e || e->type == ex_error)
|
||||
return block;
|
||||
|
@ -1924,6 +1929,7 @@ has_function_call (const expr_t *e)
|
|||
case ex_with:
|
||||
case ex_args:
|
||||
case ex_type:
|
||||
case ex_decl:
|
||||
return 0;
|
||||
case ex_multivec:
|
||||
for (auto c = e->multivec.components.head; c; c = c->next) {
|
||||
|
@ -2523,6 +2529,38 @@ new_array_expr (const expr_t *base, const expr_t *index)
|
|||
return array;
|
||||
}
|
||||
|
||||
expr_t *
|
||||
new_decl_expr (specifier_t spec)
|
||||
{
|
||||
auto decl = new_expr ();
|
||||
decl->type = ex_decl;
|
||||
decl->decl = (ex_decl_t) {
|
||||
.spec = spec,
|
||||
};
|
||||
return decl;
|
||||
}
|
||||
|
||||
expr_t *
|
||||
append_decl (expr_t *decl, symbol_t *sym, const expr_t *init)
|
||||
{
|
||||
auto expr = new_symbol_expr (sym);
|
||||
if (init) {
|
||||
expr = new_assign_expr (expr, init);
|
||||
}
|
||||
list_append (&decl->decl.list, expr);
|
||||
return decl;
|
||||
}
|
||||
|
||||
expr_t *
|
||||
append_decl_list (expr_t *decl, const expr_t *list)
|
||||
{
|
||||
if (list->type != ex_list) {
|
||||
internal_error (list, "not a list expression");
|
||||
}
|
||||
list_append_list (&decl->decl.list, &list->list);
|
||||
return decl;
|
||||
}
|
||||
|
||||
const expr_t *
|
||||
incop_expr (int op, const expr_t *e, int postop)
|
||||
{
|
||||
|
|
|
@ -132,6 +132,7 @@ is_lvalue (const expr_t *expr)
|
|||
case ex_list:
|
||||
case ex_type:
|
||||
case ex_incop:
|
||||
case ex_decl:
|
||||
break;
|
||||
case ex_cond:
|
||||
return (is_lvalue (expr->cond.true_expr)
|
||||
|
|
|
@ -74,6 +74,9 @@ math_constructor (const type_t *type, const expr_t *params, const expr_t *e)
|
|||
if (p < num_param) {
|
||||
auto pexpr = param_exprs[p++];
|
||||
auto ptype = get_type (pexpr);
|
||||
if (!ptype) {
|
||||
continue;
|
||||
}
|
||||
if (!is_math (ptype)) {
|
||||
components[c++] = error (pexpr, "invalid type for conversion");
|
||||
continue;
|
||||
|
|
|
@ -79,6 +79,7 @@ edag_add_expr (const expr_t *expr)
|
|||
case ex_args:
|
||||
case ex_type:
|
||||
case ex_incop:
|
||||
case ex_decl:
|
||||
// these are never put in the dag
|
||||
return expr;
|
||||
case ex_list:
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include "tools/qfcc/include/diagnostic.h"
|
||||
#include "tools/qfcc/include/expr.h"
|
||||
#include "tools/qfcc/include/rua-lang.h"
|
||||
#include "tools/qfcc/include/shared.h"
|
||||
#include "tools/qfcc/include/symtab.h"
|
||||
#include "tools/qfcc/include/type.h"
|
||||
#include "tools/qfcc/include/value.h"
|
||||
|
@ -55,6 +56,7 @@ proc_expr (const expr_t *expr)
|
|||
return e2;
|
||||
}
|
||||
|
||||
scoped_src_loc (expr);
|
||||
return binary_expr (expr->expr.op, e1, e2);
|
||||
}
|
||||
|
||||
|
@ -66,34 +68,83 @@ proc_uexpr (const expr_t *expr)
|
|||
return e1;
|
||||
}
|
||||
|
||||
scoped_src_loc (expr);
|
||||
return unary_expr (expr->expr.op, e1);
|
||||
}
|
||||
|
||||
static const expr_t *
|
||||
proc_block (const expr_t *expr)
|
||||
{
|
||||
if (expr->block.scope) {
|
||||
expr->block.scope->parent = current_symtab;
|
||||
current_symtab = expr->block.scope;
|
||||
}
|
||||
int count = list_count (&expr->block.list);
|
||||
int num_out = 0;
|
||||
const expr_t *result = nullptr;
|
||||
const expr_t *in[count + 1];
|
||||
const expr_t *out[count + 1];
|
||||
list_scatter (&expr->block.list, in);
|
||||
for (int i = 0; i < count; i++) {
|
||||
auto e = expr_process (in[i]);
|
||||
if (e && !is_error (e)) {
|
||||
out[num_out++] = e;
|
||||
if (expr->block.result == in[i]) {
|
||||
result = e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
scoped_src_loc (expr);
|
||||
auto block = new_block_expr (nullptr);
|
||||
list_gather (&block->block.list, out, num_out);
|
||||
block->block.scope = expr->block.scope;
|
||||
block->block.result = result;
|
||||
block->block.is_call = expr->block.is_call;
|
||||
if (expr->block.scope) {
|
||||
current_symtab = current_symtab->parent;
|
||||
}
|
||||
return block;
|
||||
}
|
||||
|
||||
static const expr_t *
|
||||
proc_symbol (const expr_t *expr)
|
||||
{
|
||||
auto sym = symtab_lookup (current_symtab, expr->symbol->name);
|
||||
if (sym) {
|
||||
scoped_src_loc (expr);
|
||||
expr = new_symbol_expr (sym);
|
||||
}
|
||||
return expr;
|
||||
}
|
||||
|
||||
static void
|
||||
static bool
|
||||
proc_do_list (ex_list_t *out, const ex_list_t *in)
|
||||
{
|
||||
int count = list_count (in);
|
||||
const expr_t *exprs[count + 1];
|
||||
list_scatter (in, exprs);
|
||||
bool ok = true;
|
||||
for (int i = 0; i < count; i++) {
|
||||
exprs[i] = expr_process (exprs[i]);
|
||||
if (is_error (exprs[i])) {
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
list_gather (out, exprs, count);
|
||||
return ok;
|
||||
}
|
||||
|
||||
static const expr_t *
|
||||
proc_vector (const expr_t *expr)
|
||||
{
|
||||
scoped_src_loc (expr);
|
||||
auto vec = new_expr ();
|
||||
vec->type = ex_vector;
|
||||
vec->vector.type = expr->vector.type;
|
||||
proc_do_list (&vec->vector.list, &expr->vector.list);
|
||||
if (!proc_do_list (&vec->vector.list, &expr->vector.list)) {
|
||||
return new_error_expr ();
|
||||
}
|
||||
return vec;
|
||||
}
|
||||
|
||||
|
@ -106,6 +157,7 @@ proc_value (const expr_t *expr)
|
|||
static const expr_t *
|
||||
proc_compound (const expr_t *expr)
|
||||
{
|
||||
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),
|
||||
|
@ -125,12 +177,14 @@ proc_assign (const expr_t *expr)
|
|||
if (is_error (src)) {
|
||||
return src;
|
||||
}
|
||||
scoped_src_loc (expr);
|
||||
return assign_expr (dst, src);
|
||||
}
|
||||
|
||||
static const expr_t *
|
||||
proc_branch (const expr_t *expr)
|
||||
{
|
||||
scoped_src_loc (expr);
|
||||
if (expr->branch.type == pr_branch_call) {
|
||||
auto args = new_list_expr (nullptr);
|
||||
proc_do_list (&args->list, &expr->branch.args->list);
|
||||
|
@ -155,18 +209,58 @@ proc_branch (const expr_t *expr)
|
|||
}
|
||||
}
|
||||
|
||||
static const expr_t *
|
||||
proc_decl (const expr_t *expr)
|
||||
{
|
||||
if (expr->decl.spec.storage == sc_local) {
|
||||
scoped_src_loc (expr);
|
||||
local_expr = new_block_expr (nullptr);
|
||||
}
|
||||
int count = list_count (&expr->decl.list);
|
||||
const expr_t *decls[count + 1];
|
||||
list_scatter (&expr->decl.list, decls);
|
||||
for (int i = 0; i < count; i++) {
|
||||
auto decl = decls[i];
|
||||
const expr_t *init = nullptr;
|
||||
symbol_t *sym;
|
||||
if (decl->type == ex_assign) {
|
||||
init = decl->assign.src;
|
||||
if (decl->assign.dst->type != ex_symbol) {
|
||||
internal_error (decl->assign.dst, "not a symbol");
|
||||
}
|
||||
sym = decl->assign.dst->symbol;
|
||||
} else if (decl->type == ex_symbol) {
|
||||
sym = decl->symbol;
|
||||
} else {
|
||||
internal_error (decl->assign.dst, "not a symbol");
|
||||
}
|
||||
auto spec = expr->decl.spec;
|
||||
if (sym && sym->type) {
|
||||
spec.type = append_type (sym->type, spec.type);
|
||||
spec.type = find_type (spec.type);
|
||||
sym->type = nullptr;
|
||||
}
|
||||
current_language.parse_declaration (spec, sym, init, current_symtab);
|
||||
}
|
||||
auto block = local_expr;
|
||||
local_expr = nullptr;
|
||||
return block;
|
||||
}
|
||||
|
||||
const expr_t *
|
||||
expr_process (const expr_t *expr)
|
||||
{
|
||||
static process_f funcs[ex_count] = {
|
||||
[ex_expr] = proc_expr,
|
||||
[ex_uexpr] = proc_uexpr,
|
||||
[ex_block] = proc_block,
|
||||
[ex_symbol] = proc_symbol,
|
||||
[ex_vector] = proc_vector,
|
||||
[ex_value] = proc_value,
|
||||
[ex_compound] = proc_compound,
|
||||
[ex_assign] = proc_assign,
|
||||
[ex_branch] = proc_branch,
|
||||
[ex_decl] = proc_decl,
|
||||
};
|
||||
|
||||
if (expr->type >= ex_count) {
|
||||
|
|
|
@ -42,18 +42,17 @@
|
|||
#include "tools/qfcc/include/type.h"
|
||||
|
||||
void
|
||||
glsl_parse_declaration (specifier_t spec, symbol_t *sym, const type_t *array,
|
||||
glsl_parse_declaration (specifier_t spec, symbol_t *sym,
|
||||
const expr_t *init, symtab_t *symtab)
|
||||
{
|
||||
if (sym->type) {
|
||||
internal_error (0, "unexected typed symbol");
|
||||
}
|
||||
if (array) {
|
||||
spec.type = append_type (array, spec.type);
|
||||
spec.type = find_type (spec.type);
|
||||
}
|
||||
if (init) {
|
||||
init = expr_process (init);
|
||||
if (is_error (init)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
auto attributes = glsl_optimize_attributes (spec.attributes);
|
||||
if (sym && sym->sy_type == sy_expr) {
|
||||
|
|
|
@ -168,7 +168,7 @@ int yylex (YYSTYPE *yylval, YYLTYPE *yylloc);
|
|||
|
||||
%type <symbol> variable_identifier
|
||||
%type <block> block_declaration
|
||||
%type <expr> constant_expression
|
||||
%type <expr> declaration constant_expression
|
||||
%type <expr> expression primary_exprsssion assignment_expression
|
||||
%type <expr> for_init_statement conditionopt expressionopt else
|
||||
%type <expr> conditional_expression unary_expression postfix_expression
|
||||
|
@ -186,6 +186,7 @@ int yylex (YYSTYPE *yylval, YYLTYPE *yylloc);
|
|||
%type <expr> condition
|
||||
%type <expr> compound_statement_no_new_scope compound_statement
|
||||
%type <expr> statement statement_no_new_scope statement_list
|
||||
%type <expr> new_block new_scope
|
||||
%type <expr> simple_statement expression_statement
|
||||
%type <expr> declaration_statement selection_statement
|
||||
%type <expr> switch_statement switch_statement_list case_label
|
||||
|
@ -193,9 +194,9 @@ int yylex (YYSTYPE *yylval, YYLTYPE *yylloc);
|
|||
%type <expr> iteration_statement jump_statement
|
||||
%type <expr> break_label continue_label
|
||||
%type <mut_expr> initializer_list
|
||||
%type <mut_expr> single_declaration init_declarator_list
|
||||
%type <op> unary_operator assignment_operator
|
||||
|
||||
%type <spec> single_declaration init_declarator_list
|
||||
%type <spec> function_prototype function_declarator
|
||||
%type <spec> function_header function_header_with_parameters
|
||||
%type <spec> fully_specified_type type_specifier struct_specifier
|
||||
|
@ -269,7 +270,7 @@ translation_unit
|
|||
|
||||
external_declaration
|
||||
: function_definition
|
||||
| declaration
|
||||
| declaration { if ($1) expr_process ($1); }
|
||||
| ';'
|
||||
;
|
||||
|
||||
|
@ -290,7 +291,8 @@ function_definition
|
|||
{
|
||||
auto spec = $1;
|
||||
auto sym = spec.sym;
|
||||
build_code_function (sym, nullptr, (expr_t *) $3);
|
||||
expr_t *statments = (expr_t *) expr_process ($3);
|
||||
build_code_function (sym, nullptr, statments);
|
||||
current_symtab = $<symtab>2;
|
||||
current_storage = sc_global;//FIXME
|
||||
current_func = nullptr;
|
||||
|
@ -569,50 +571,62 @@ constant_expression
|
|||
;
|
||||
|
||||
declaration
|
||||
: function_prototype ';'
|
||||
| init_declarator_list ';'
|
||||
: function_prototype ';' { $$ = nullptr; }
|
||||
| init_declarator_list ';' { $$ = $1; }
|
||||
| PRECISION precision_qualifier type_specifier ';'
|
||||
{
|
||||
notice (0, "PRECISION precision_qualifier");
|
||||
$$ = nullptr;
|
||||
}
|
||||
| type_qualifier block_declaration ';'
|
||||
{
|
||||
auto block = $block_declaration;
|
||||
glsl_declare_block_instance (block, nullptr);
|
||||
if (current_symtab != pr.symtab) {
|
||||
error (0, "blocks must be declared globally");
|
||||
} else {
|
||||
auto block = $block_declaration;
|
||||
glsl_declare_block_instance (block, nullptr);
|
||||
}
|
||||
$$ = nullptr;
|
||||
}
|
||||
| type_qualifier block_declaration IDENTIFIER ';'
|
||||
{
|
||||
auto block = $block_declaration;
|
||||
auto instance_name = $IDENTIFIER;
|
||||
glsl_declare_block_instance (block, instance_name);
|
||||
if (current_symtab != pr.symtab) {
|
||||
error (0, "blocks must be declared globally");
|
||||
} else {
|
||||
auto block = $block_declaration;
|
||||
auto instance_name = $IDENTIFIER;
|
||||
glsl_declare_block_instance (block, instance_name);
|
||||
}
|
||||
$$ = nullptr;
|
||||
}
|
||||
| type_qualifier block_declaration IDENTIFIER array_specifier ';'
|
||||
{
|
||||
auto block = $block_declaration;
|
||||
auto instance_name = $IDENTIFIER;
|
||||
instance_name->type = $array_specifier;
|
||||
glsl_declare_block_instance (block, instance_name);
|
||||
if (current_symtab != pr.symtab) {
|
||||
error (0, "blocks must be declared globally");
|
||||
} else {
|
||||
auto block = $block_declaration;
|
||||
auto instance_name = $IDENTIFIER;
|
||||
instance_name->type = $array_specifier;
|
||||
glsl_declare_block_instance (block, instance_name);
|
||||
}
|
||||
$$ = nullptr;
|
||||
}
|
||||
| type_qualifier ';'
|
||||
{
|
||||
glsl_parse_declaration ($type_qualifier, nullptr,
|
||||
nullptr, nullptr, current_symtab);
|
||||
nullptr, current_symtab);
|
||||
$$ = nullptr;
|
||||
}
|
||||
| type_qualifier IDENTIFIER ';'
|
||||
{
|
||||
glsl_parse_declaration ($type_qualifier, $IDENTIFIER,
|
||||
nullptr, nullptr, current_symtab);
|
||||
auto decl = new_decl_expr ($type_qualifier);
|
||||
$$ = append_decl (decl, $IDENTIFIER, nullptr);
|
||||
}
|
||||
| type_qualifier IDENTIFIER identifier_list ';'
|
||||
{
|
||||
auto id_list = $identifier_list;
|
||||
auto expr = new_symbol_expr ($IDENTIFIER);
|
||||
expr_prepend_expr (id_list, expr);
|
||||
auto sym = new_symbol (nullptr);
|
||||
sym->sy_type = sy_expr;
|
||||
sym->expr = id_list;
|
||||
glsl_parse_declaration ($type_qualifier, sym,
|
||||
nullptr, nullptr, current_symtab);
|
||||
auto decl = new_decl_expr ($type_qualifier);
|
||||
append_decl (decl, $IDENTIFIER, nullptr);
|
||||
$$ = append_decl_list (decl, $identifier_list);
|
||||
}
|
||||
;
|
||||
|
||||
|
@ -723,60 +737,58 @@ init_declarator_list
|
|||
: single_declaration
|
||||
| init_declarator_list ',' IDENTIFIER
|
||||
{
|
||||
$$ = $1;
|
||||
auto symtab = current_symtab;
|
||||
auto space = symtab->space;
|
||||
auto storage = current_storage;
|
||||
initialize_def ($3, nullptr, space, storage, symtab);
|
||||
auto decl = $1;
|
||||
$$ = append_decl (decl, $IDENTIFIER, nullptr);
|
||||
}
|
||||
| init_declarator_list ',' IDENTIFIER array_specifier
|
||||
{
|
||||
auto decl = $1;
|
||||
$IDENTIFIER->type = $array_specifier;
|
||||
$$ = append_decl (decl, $IDENTIFIER, nullptr);
|
||||
}
|
||||
| init_declarator_list ',' IDENTIFIER array_specifier '=' initializer
|
||||
{
|
||||
auto decl = $1;
|
||||
$IDENTIFIER->type = $array_specifier;
|
||||
$$ = append_decl (decl, $IDENTIFIER, $initializer);
|
||||
}
|
||||
| init_declarator_list ',' IDENTIFIER '=' initializer
|
||||
{
|
||||
$$ = $1;
|
||||
auto symtab = current_symtab;
|
||||
auto space = symtab->space;
|
||||
auto storage = current_storage;
|
||||
if (storage == sc_local && !local_expr) {
|
||||
local_expr = new_block_expr (nullptr);
|
||||
}
|
||||
initialize_def ($3, $5, space, storage, symtab);
|
||||
auto decl = $1;
|
||||
$$ = append_decl (decl, $IDENTIFIER, $initializer);
|
||||
}
|
||||
;
|
||||
|
||||
single_declaration
|
||||
: fully_specified_type
|
||||
{
|
||||
glsl_parse_declaration ($$ = $fully_specified_type,
|
||||
nullptr, nullptr,
|
||||
nullptr, current_symtab);
|
||||
$$ = new_decl_expr ($fully_specified_type);
|
||||
}
|
||||
| fully_specified_type IDENTIFIER
|
||||
{
|
||||
glsl_parse_declaration ($$ = $fully_specified_type,
|
||||
$IDENTIFIER, nullptr,
|
||||
nullptr, current_symtab);
|
||||
auto decl = new_decl_expr ($fully_specified_type);
|
||||
$$ = append_decl (decl, $IDENTIFIER, nullptr);
|
||||
}
|
||||
| fully_specified_type IDENTIFIER array_specifier
|
||||
{
|
||||
glsl_parse_declaration ($$ = $fully_specified_type,
|
||||
$IDENTIFIER, $array_specifier,
|
||||
nullptr, current_symtab);
|
||||
auto spec = $fully_specified_type;
|
||||
spec.type = append_type ($array_specifier, spec.type);
|
||||
spec.type = find_type (spec.type);
|
||||
auto decl = new_decl_expr (spec);
|
||||
$$ = append_decl (decl, $IDENTIFIER, nullptr);
|
||||
}
|
||||
| fully_specified_type IDENTIFIER array_specifier '=' initializer
|
||||
{
|
||||
glsl_parse_declaration ($$ = $fully_specified_type,
|
||||
$IDENTIFIER, $array_specifier,
|
||||
$initializer, current_symtab);
|
||||
auto spec = $fully_specified_type;
|
||||
spec.type = append_type ($array_specifier, spec.type);
|
||||
spec.type = find_type (spec.type);
|
||||
auto decl = new_decl_expr (spec);
|
||||
$$ = append_decl (decl, $IDENTIFIER, $initializer);
|
||||
}
|
||||
| fully_specified_type IDENTIFIER '=' initializer
|
||||
{
|
||||
if (current_storage == sc_local && !local_expr) {
|
||||
local_expr = new_block_expr (nullptr);
|
||||
}
|
||||
glsl_parse_declaration ($$ = $fully_specified_type,
|
||||
$IDENTIFIER, nullptr,
|
||||
$initializer, current_symtab);
|
||||
auto decl = new_decl_expr ($fully_specified_type);
|
||||
$$ = append_decl (decl, $IDENTIFIER, $initializer);
|
||||
}
|
||||
;
|
||||
|
||||
|
@ -1028,10 +1040,6 @@ initializer_list
|
|||
|
||||
declaration_statement
|
||||
: declaration
|
||||
{
|
||||
$$ = local_expr;
|
||||
local_expr = nullptr;
|
||||
}
|
||||
;
|
||||
|
||||
statement
|
||||
|
@ -1041,7 +1049,7 @@ statement
|
|||
|
||||
simple_statement
|
||||
: declaration_statement
|
||||
| expression_statement { $$ = expr_process ($1); }//FIXME shouldn't be here
|
||||
| expression_statement
|
||||
| selection_statement
|
||||
| switch_statement
|
||||
| case_label
|
||||
|
@ -1051,7 +1059,11 @@ simple_statement
|
|||
|
||||
compound_statement
|
||||
: '{' '}' { $$ = nullptr; }
|
||||
| '{' statement_list '}' { $$ = $2; }
|
||||
| '{' new_scope statement_list '}'
|
||||
{
|
||||
$$ = $3;
|
||||
current_symtab = $2->block.scope->parent;
|
||||
}
|
||||
;
|
||||
|
||||
statement_no_new_scope
|
||||
|
@ -1061,13 +1073,31 @@ statement_no_new_scope
|
|||
|
||||
compound_statement_no_new_scope
|
||||
: '{' '}' { $$ = nullptr; }
|
||||
| '{' statement_list '}' { $$ = $2; }
|
||||
| '{' new_block statement_list '}' { $$ = $3; }
|
||||
;
|
||||
|
||||
new_scope
|
||||
: /* empty */
|
||||
{
|
||||
auto block = new_block_expr (nullptr);
|
||||
block->block.scope = new_symtab (nullptr, stab_local);
|
||||
current_symtab = block->block.scope;
|
||||
$$ = block;
|
||||
}
|
||||
;
|
||||
|
||||
new_block
|
||||
: /* empty */
|
||||
{
|
||||
auto block = new_block_expr (nullptr);
|
||||
$$ = block;
|
||||
}
|
||||
;
|
||||
|
||||
statement_list
|
||||
: statement
|
||||
{
|
||||
auto list = new_block_expr (nullptr);
|
||||
auto list = $<mut_expr>0;
|
||||
append_expr (list, $1);
|
||||
$$ = list;
|
||||
}
|
||||
|
@ -1160,7 +1190,7 @@ switch_block
|
|||
|
||||
switch_statement_list
|
||||
: /* empty */ { $$ = nullptr; }
|
||||
| statement_list
|
||||
| new_block statement_list { $$ = $2; }
|
||||
;
|
||||
|
||||
case_label
|
||||
|
@ -1713,6 +1743,7 @@ language_t lang_glsl_comp = {
|
|||
.extension = glsl_extension,
|
||||
.version = glsl_version,
|
||||
.on_include = glsl_on_include,
|
||||
.parse_declaration = glsl_parse_declaration,
|
||||
.sublanguage = &glsl_comp_sublanguage,
|
||||
};
|
||||
|
||||
|
@ -1722,6 +1753,7 @@ language_t lang_glsl_vert = {
|
|||
.extension = glsl_extension,
|
||||
.version = glsl_version,
|
||||
.on_include = glsl_on_include,
|
||||
.parse_declaration = glsl_parse_declaration,
|
||||
.sublanguage = &glsl_vert_sublanguage,
|
||||
};
|
||||
|
||||
|
@ -1731,6 +1763,7 @@ language_t lang_glsl_tesc = {
|
|||
.extension = glsl_extension,
|
||||
.version = glsl_version,
|
||||
.on_include = glsl_on_include,
|
||||
.parse_declaration = glsl_parse_declaration,
|
||||
.sublanguage = &glsl_tesc_sublanguage,
|
||||
};
|
||||
|
||||
|
@ -1740,6 +1773,7 @@ language_t lang_glsl_tese = {
|
|||
.extension = glsl_extension,
|
||||
.version = glsl_version,
|
||||
.on_include = glsl_on_include,
|
||||
.parse_declaration = glsl_parse_declaration,
|
||||
.sublanguage = &glsl_tese_sublanguage,
|
||||
};
|
||||
|
||||
|
@ -1749,6 +1783,7 @@ language_t lang_glsl_geom = {
|
|||
.extension = glsl_extension,
|
||||
.version = glsl_version,
|
||||
.on_include = glsl_on_include,
|
||||
.parse_declaration = glsl_parse_declaration,
|
||||
.sublanguage = &glsl_geom_sublanguage,
|
||||
};
|
||||
|
||||
|
@ -1758,5 +1793,6 @@ language_t lang_glsl_frag = {
|
|||
.extension = glsl_extension,
|
||||
.version = glsl_version,
|
||||
.on_include = glsl_on_include,
|
||||
.parse_declaration = glsl_parse_declaration,
|
||||
.sublanguage = &glsl_frag_sublanguage,
|
||||
};
|
||||
|
|
|
@ -796,12 +796,6 @@ spirv_write (struct pr_info_s *pr, const char *filename)
|
|||
spirv_MemoryModel (expr_uint (pr->module->addressing_model),
|
||||
expr_uint (pr->module->memory_model), ctx.space);
|
||||
|
||||
for (auto sym = pr->symtab->symbols; sym; sym = sym->next) {
|
||||
if (sym->sy_type == sy_expr && is_constexpr (sym->expr)) {
|
||||
puts (sym->name);
|
||||
spirv_emit_expr (sym->expr, &ctx);
|
||||
}
|
||||
}
|
||||
|
||||
auto srcid = spirv_String (pr->src_name, &ctx);
|
||||
spirv_Source (0, 1, srcid, nullptr, &ctx);
|
||||
|
|
Loading…
Reference in a new issue