mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-25 05:01:24 +00:00
[qfcc] Use non-invasive lists for most expressions
This covers attribute params, vector, state, and comma expressions. Just function args to go, I think.
This commit is contained in:
parent
cc67e69923
commit
81b544c362
10 changed files with 194 additions and 87 deletions
|
@ -38,6 +38,6 @@ typedef struct attribute_s {
|
||||||
} attribute_t;
|
} attribute_t;
|
||||||
|
|
||||||
struct expr_s;
|
struct expr_s;
|
||||||
attribute_t *new_attribute(const char *name, struct expr_s *value);
|
attribute_t *new_attribute(const char *name, struct expr_s *params);
|
||||||
|
|
||||||
#endif//attribute_h
|
#endif//attribute_h
|
||||||
|
|
|
@ -382,6 +382,10 @@ ex_listitem_t *new_listitem (expr_t *e);
|
||||||
int list_count (ex_list_t *list) __attribute__((pure));
|
int list_count (ex_list_t *list) __attribute__((pure));
|
||||||
void list_scatter (ex_list_t *list, expr_t **exprs);
|
void list_scatter (ex_list_t *list, expr_t **exprs);
|
||||||
void list_gather (ex_list_t *dst, expr_t **exprs, int count);
|
void list_gather (ex_list_t *dst, expr_t **exprs, int count);
|
||||||
|
expr_t *new_list_expr (expr_t *first);
|
||||||
|
expr_t *list_append_expr (expr_t *list, expr_t *expr);
|
||||||
|
expr_t *list_prepend_expr (expr_t *list, expr_t *expr);
|
||||||
|
expr_t *list_prepend_list (expr_t *list, ex_list_t *prepend);
|
||||||
|
|
||||||
/** Create a new expression node.
|
/** Create a new expression node.
|
||||||
|
|
||||||
|
@ -474,14 +478,12 @@ expr_t *new_block_expr (void);
|
||||||
|
|
||||||
/** Create a new statement block expression node from an expression list
|
/** Create a new statement block expression node from an expression list
|
||||||
|
|
||||||
The returned block holds the expression list in reverse order. This makes
|
\param list The expression list to convert to an expression block.
|
||||||
it easy to build the list in a parser.
|
\param set_result If true, the block's result will be set to the last
|
||||||
|
expression in the list.
|
||||||
\param expr_list The expression list to convert to an expression block.
|
|
||||||
Note that the evaluation order will be reversed.
|
|
||||||
\return The new block expression (::ex_block_t) node.
|
\return The new block expression (::ex_block_t) node.
|
||||||
*/
|
*/
|
||||||
expr_t *build_block_expr (expr_t *expr_list);
|
expr_t *build_block_expr (expr_t *list, bool set_result);
|
||||||
|
|
||||||
designator_t *new_designator (expr_t *field, expr_t *index);
|
designator_t *new_designator (expr_t *field, expr_t *index);
|
||||||
element_t *new_element (expr_t *expr, designator_t *designator);
|
element_t *new_element (expr_t *expr, designator_t *designator);
|
||||||
|
|
|
@ -343,10 +343,18 @@ algebra_type (type_t *type, expr_t *params)
|
||||||
error (0, "algebra type must be float or double");
|
error (0, "algebra type must be float or double");
|
||||||
return type_default;
|
return type_default;
|
||||||
}
|
}
|
||||||
params = reverse_expr_list (params);
|
int param_count = params ? list_count (¶ms->list) : 0;
|
||||||
auto plus = params;
|
if (param_count > 3) {
|
||||||
auto minus = plus ? plus->next : 0;
|
error (params, "too many arguments in signature");
|
||||||
auto zero = minus ? minus->next : 0;
|
return type_default;
|
||||||
|
}
|
||||||
|
expr_t *param_exprs[3] = {};
|
||||||
|
if (params) {
|
||||||
|
list_scatter (¶ms->list, param_exprs);
|
||||||
|
}
|
||||||
|
auto plus = param_exprs[0];
|
||||||
|
auto minus = param_exprs[1];
|
||||||
|
auto zero = param_exprs[2];
|
||||||
|
|
||||||
expr_t *err = 0;
|
expr_t *err = 0;
|
||||||
if ((plus && !is_integral_val (err = plus))
|
if ((plus && !is_integral_val (err = plus))
|
||||||
|
@ -410,11 +418,11 @@ algebra_subtype (type_t *type, attribute_t *attr)
|
||||||
}
|
}
|
||||||
auto algebra = algebra_get (type);
|
auto algebra = algebra_get (type);
|
||||||
if (strcmp (attr->name, "group_mask") == 0) {
|
if (strcmp (attr->name, "group_mask") == 0) {
|
||||||
if (!attr->params || attr->params->next) {
|
if (!attr->params || attr->params->list.head->next) {
|
||||||
error (0, "incorrect number of parameters to 'group_mask'");
|
error (0, "incorrect number of parameters to 'group_mask'");
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
auto param = attr->params;
|
auto param = attr->params->list.head->expr;
|
||||||
if (!is_integral_val (param)) {
|
if (!is_integral_val (param)) {
|
||||||
error (0, "'group_mask' parameter must be an integer constant");
|
error (0, "'group_mask' parameter must be an integer constant");
|
||||||
return type;
|
return type;
|
||||||
|
|
|
@ -40,18 +40,23 @@
|
||||||
|
|
||||||
ALLOC_STATE (attribute_t, attributes);
|
ALLOC_STATE (attribute_t, attributes);
|
||||||
|
|
||||||
attribute_t *new_attribute(const char *name, expr_t *value)
|
attribute_t *new_attribute(const char *name, expr_t *params)
|
||||||
{
|
{
|
||||||
for (auto v = value; v; v = v->next) {
|
if (params && params->type != ex_list) {
|
||||||
if (v->type != ex_value) {
|
internal_error (params, "attribute params not a list");
|
||||||
error (value, "not a literal constant");
|
}
|
||||||
|
if (params) {
|
||||||
|
for (auto p = params->list.head; p; p = p->next) {
|
||||||
|
if (p->expr->type != ex_value) {
|
||||||
|
error (p->expr, "not a literal constant");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
attribute_t *attr;
|
attribute_t *attr;
|
||||||
ALLOC (16384, attribute_t, attributes, attr);
|
ALLOC (16384, attribute_t, attributes, attr);
|
||||||
attr->name = save_string (name);
|
attr->name = save_string (name);
|
||||||
attr->params = value ? reverse_expr_list (value) : 0;
|
attr->params = params;
|
||||||
return attr;
|
return attr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -227,18 +227,22 @@ print_block (dstring_t *dstr, expr_t *e, int level, int id, expr_t *next)
|
||||||
list_scatter (&e->block.list, exprs);
|
list_scatter (&e->block.list, exprs);
|
||||||
exprs[num_exprs] = 0;
|
exprs[num_exprs] = 0;
|
||||||
|
|
||||||
|
int colspan = num_exprs ? num_exprs : 1;
|
||||||
|
|
||||||
dasprintf (dstr, "%*se_%p [shape=none,label=<\n", indent, "", e);
|
dasprintf (dstr, "%*se_%p [shape=none,label=<\n", indent, "", e);
|
||||||
dasprintf (dstr, "%*s<table border=\"0\" cellborder=\"1\" "
|
dasprintf (dstr, "%*s<table border=\"0\" cellborder=\"1\" "
|
||||||
"cellspacing=\"0\">\n", indent + 2, "");
|
"cellspacing=\"0\">\n", indent + 2, "");
|
||||||
dasprintf (dstr, "%*s<tr><td colspan=\"%d\"><block>(%d)%s</td>"
|
dasprintf (dstr, "%*s<tr><td colspan=\"%d\"><block>(%d)%s</td>"
|
||||||
"</tr>\n", indent + 4, "", num_exprs, e->line,
|
"</tr>\n", indent + 4, "", colspan, e->line,
|
||||||
e->block.is_call ? "c" : "");
|
e->block.is_call ? "c" : "");
|
||||||
if (e->block.result)
|
if (e->block.result)
|
||||||
dasprintf (dstr, "%*s<tr><td colspan=\"%d\" port=\"result\">=</td>"
|
dasprintf (dstr, "%*s<tr><td colspan=\"%d\" port=\"result\">=</td>"
|
||||||
"</tr>\n", indent + 4, "", num_exprs);
|
"</tr>\n", indent + 4, "", colspan);
|
||||||
|
if (num_exprs) {
|
||||||
dasprintf (dstr, "%*s<tr>\n", indent + 4, "");
|
dasprintf (dstr, "%*s<tr>\n", indent + 4, "");
|
||||||
for (int i = 0; i < num_exprs; i++) {
|
for (int i = 0; i < num_exprs; i++) {
|
||||||
dasprintf (dstr, "%*s<td>%d</td>\n", indent + 8, "", exprs[i]->line);
|
dasprintf (dstr, "%*s<td>%d</td>\n", indent + 8, "",
|
||||||
|
exprs[i]->line);
|
||||||
}
|
}
|
||||||
dasprintf (dstr, "%*s</tr>\n", indent + 4, "");
|
dasprintf (dstr, "%*s</tr>\n", indent + 4, "");
|
||||||
dasprintf (dstr, "%*s<tr>\n", indent + 4, "");
|
dasprintf (dstr, "%*s<tr>\n", indent + 4, "");
|
||||||
|
@ -247,6 +251,7 @@ print_block (dstring_t *dstr, expr_t *e, int level, int id, expr_t *next)
|
||||||
i, expr_names[exprs[i]->type]);
|
i, expr_names[exprs[i]->type]);
|
||||||
}
|
}
|
||||||
dasprintf (dstr, "%*s</tr>\n", indent + 4, "");
|
dasprintf (dstr, "%*s</tr>\n", indent + 4, "");
|
||||||
|
}
|
||||||
dasprintf (dstr, "%*s</table>\n", indent + 2, "");
|
dasprintf (dstr, "%*s</table>\n", indent + 2, "");
|
||||||
dasprintf (dstr, "%*s>];\n", indent, "");
|
dasprintf (dstr, "%*s>];\n", indent, "");
|
||||||
|
|
||||||
|
@ -262,6 +267,47 @@ print_block (dstring_t *dstr, expr_t *e, int level, int id, expr_t *next)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_list (dstring_t *dstr, expr_t *e, int level, int id, expr_t *next)
|
||||||
|
{
|
||||||
|
int indent = level * 2 + 2;
|
||||||
|
int num_exprs = list_count (&e->list);
|
||||||
|
expr_t *exprs[num_exprs + 1];
|
||||||
|
|
||||||
|
list_scatter (&e->list, exprs);
|
||||||
|
exprs[num_exprs] = 0;
|
||||||
|
|
||||||
|
int colspan = num_exprs ? num_exprs : 1;
|
||||||
|
|
||||||
|
dasprintf (dstr, "%*se_%p [shape=none,label=<\n", indent, "", e);
|
||||||
|
dasprintf (dstr, "%*s<table border=\"0\" cellborder=\"1\" "
|
||||||
|
"cellspacing=\"0\">\n", indent + 2, "");
|
||||||
|
dasprintf (dstr, "%*s<tr><td colspan=\"%d\"><list>(%d)</td>"
|
||||||
|
"</tr>\n", indent + 4, "", colspan, e->line);
|
||||||
|
if (num_exprs) {
|
||||||
|
dasprintf (dstr, "%*s<tr>\n", indent + 4, "");
|
||||||
|
for (int i = 0; i < num_exprs; i++) {
|
||||||
|
dasprintf (dstr, "%*s<td>%d</td>\n", indent + 8, "",
|
||||||
|
exprs[i]->line);
|
||||||
|
}
|
||||||
|
dasprintf (dstr, "%*s</tr>\n", indent + 4, "");
|
||||||
|
dasprintf (dstr, "%*s<tr>\n", indent + 4, "");
|
||||||
|
for (int i = 0; i < num_exprs; i++) {
|
||||||
|
dasprintf (dstr, "%*s<td port=\"b%d\">%s</td>\n", indent + 8, "",
|
||||||
|
i, expr_names[exprs[i]->type]);
|
||||||
|
}
|
||||||
|
dasprintf (dstr, "%*s</tr>\n", indent + 4, "");
|
||||||
|
}
|
||||||
|
dasprintf (dstr, "%*s</table>\n", indent + 2, "");
|
||||||
|
dasprintf (dstr, "%*s>];\n", indent, "");
|
||||||
|
|
||||||
|
for (int i = 0; i < num_exprs; i++) {
|
||||||
|
_print_expr (dstr, exprs[i], level + 1, id, exprs[i + 1]);
|
||||||
|
dasprintf (dstr, "%*se_%p:b%d -> e_%p;\n", indent, "", e,
|
||||||
|
i, exprs[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
print_subexpr (dstring_t *dstr, expr_t *e, int level, int id, expr_t *next)
|
print_subexpr (dstring_t *dstr, expr_t *e, int level, int id, expr_t *next)
|
||||||
{
|
{
|
||||||
|
@ -676,6 +722,7 @@ _print_expr (dstring_t *dstr, expr_t *e, int level, int id, expr_t *next)
|
||||||
[ex_swizzle] = print_swizzle,
|
[ex_swizzle] = print_swizzle,
|
||||||
[ex_extend] = print_extend,
|
[ex_extend] = print_extend,
|
||||||
[ex_multivec] = print_multivec,
|
[ex_multivec] = print_multivec,
|
||||||
|
[ex_list] = print_list,
|
||||||
};
|
};
|
||||||
int indent = level * 2 + 2;
|
int indent = level * 2 + 2;
|
||||||
|
|
||||||
|
|
|
@ -273,6 +273,53 @@ new_listitem (expr_t *e)
|
||||||
return li;
|
return li;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expr_t *
|
||||||
|
list_append_expr (expr_t *list, expr_t *expr)
|
||||||
|
{
|
||||||
|
auto li = new_listitem (expr);
|
||||||
|
*list->list.tail = li;
|
||||||
|
list->list.tail = &li->next;
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
expr_t *
|
||||||
|
list_prepend_expr (expr_t *list, expr_t *expr)
|
||||||
|
{
|
||||||
|
auto li = new_listitem (expr);
|
||||||
|
li->next = list->list.head;
|
||||||
|
list->list.head = li;
|
||||||
|
|
||||||
|
if (list->list.tail == &list->list.head) {
|
||||||
|
list->list.tail = &li->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
expr_t *
|
||||||
|
list_prepend_list (expr_t *list, ex_list_t *prepend)
|
||||||
|
{
|
||||||
|
if (!list->list.head) {
|
||||||
|
list->list.tail = prepend->tail;
|
||||||
|
}
|
||||||
|
*prepend->tail = list->list.head;
|
||||||
|
list->list.head = prepend->head;
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
expr_t *
|
||||||
|
new_list_expr (expr_t *first)
|
||||||
|
{
|
||||||
|
auto list = new_expr ();
|
||||||
|
list->type = ex_list;
|
||||||
|
list->list.head = 0;
|
||||||
|
list->list.tail = &list->list.head;
|
||||||
|
if (first) {
|
||||||
|
list_append_expr (list, first);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
list_count (ex_list_t *list)
|
list_count (ex_list_t *list)
|
||||||
{
|
{
|
||||||
|
@ -638,15 +685,18 @@ new_binary_expr (int op, expr_t *e1, expr_t *e2)
|
||||||
}
|
}
|
||||||
|
|
||||||
expr_t *
|
expr_t *
|
||||||
build_block_expr (expr_t *expr_list)
|
build_block_expr (expr_t *list, bool set_result)
|
||||||
{
|
{
|
||||||
|
if (list->type != ex_list) {
|
||||||
|
return list;
|
||||||
|
}
|
||||||
expr_t *b = new_block_expr ();
|
expr_t *b = new_block_expr ();
|
||||||
|
|
||||||
while (expr_list) {
|
b->block.head = list->list.head;
|
||||||
expr_t *e = expr_list;
|
b->block.tail = list->list.tail;
|
||||||
expr_list = e->next;
|
if (set_result && b->block.tail != &b->block.head) {
|
||||||
e->next = 0;
|
auto last = (ex_listitem_t *) b->block.tail;
|
||||||
append_expr (b, e);
|
b->block.result = last->expr;
|
||||||
}
|
}
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
@ -3028,14 +3078,19 @@ build_for_statement (expr_t *init, expr_t *test, expr_t *next,
|
||||||
expr_t *
|
expr_t *
|
||||||
build_state_expr (expr_t *e)
|
build_state_expr (expr_t *e)
|
||||||
{
|
{
|
||||||
expr_t *frame = 0;
|
int count = e ? list_count (&e->list) : 0;
|
||||||
expr_t *think = 0;
|
if (count < 2) {
|
||||||
expr_t *step = 0;
|
return error (e, "not enough state arguments");
|
||||||
|
}
|
||||||
|
if (count > 3) {
|
||||||
|
return error (e, "too many state arguments");
|
||||||
|
}
|
||||||
|
expr_t *state_args[3] = {};
|
||||||
|
list_scatter (&e->list, state_args);
|
||||||
|
expr_t *frame = state_args[0];
|
||||||
|
expr_t *think = state_args[1];
|
||||||
|
expr_t *step = state_args[2];
|
||||||
|
|
||||||
e = reverse_expr_list (e);
|
|
||||||
frame = e;
|
|
||||||
think = frame->next;
|
|
||||||
step = think->next;
|
|
||||||
if (think->type == ex_symbol)
|
if (think->type == ex_symbol)
|
||||||
think = think_expr (think->symbol);
|
think = think_expr (think->symbol);
|
||||||
if (is_int_val (frame))
|
if (is_int_val (frame))
|
||||||
|
@ -3045,8 +3100,6 @@ build_state_expr (expr_t *e)
|
||||||
if (extract_type (think) != ev_func)
|
if (extract_type (think) != ev_func)
|
||||||
return error (think, "invalid type for think");
|
return error (think, "invalid type for think");
|
||||||
if (step) {
|
if (step) {
|
||||||
if (step->next)
|
|
||||||
return error (step->next, "too many state arguments");
|
|
||||||
if (is_int_val (step))
|
if (is_int_val (step))
|
||||||
step = cast_expr (&type_float, step);
|
step = cast_expr (&type_float, step);
|
||||||
if (!type_assignable (&type_float, get_type (step)))
|
if (!type_assignable (&type_float, get_type (step)))
|
||||||
|
|
|
@ -714,12 +714,14 @@ convert_scalar (expr_t *scalar, int op, expr_t *vec)
|
||||||
type_t *vec_type = get_type (vec);
|
type_t *vec_type = get_type (vec);
|
||||||
|
|
||||||
if (is_constant (scalar)) {
|
if (is_constant (scalar)) {
|
||||||
for (int i = 1; i < type_width (get_type (vec)); i++) {
|
int width = type_width (get_type (vec));
|
||||||
expr_t *s = copy_expr (scalar);
|
expr_t *elements[width];
|
||||||
s->next = scalar;
|
for (int i = 0; i < width; i++) {
|
||||||
scalar = s;
|
elements[i] = scalar;
|
||||||
}
|
}
|
||||||
return new_vector_list (scalar);
|
auto scalar_list = new_list_expr (0);
|
||||||
|
list_gather (&scalar_list->list, elements, width);
|
||||||
|
return new_vector_list (scalar_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new_extend_expr (scalar, vec_type, 2, false);//2 = copy
|
return new_extend_expr (scalar, vec_type, 2, false);//2 = copy
|
||||||
|
|
|
@ -40,15 +40,15 @@ expr_t *
|
||||||
new_vector_list (expr_t *expr_list)
|
new_vector_list (expr_t *expr_list)
|
||||||
{
|
{
|
||||||
type_t *ele_type = type_default;
|
type_t *ele_type = type_default;
|
||||||
|
int count = list_count (&expr_list->list);
|
||||||
// lists are built in reverse order
|
expr_t *elements[count + 1];
|
||||||
expr_list = reverse_expr_list (expr_list);
|
list_scatter (&expr_list->list, elements);
|
||||||
|
elements[count] = 0;
|
||||||
|
|
||||||
int width = 0;
|
int width = 0;
|
||||||
int count = 0;
|
for (int i = 0; i < count; i++) {
|
||||||
for (expr_t *e = expr_list; e; e = e->next) {
|
auto e = elements[i];
|
||||||
count++;
|
auto t = get_type (e);
|
||||||
type_t *t = get_type (e);
|
|
||||||
if (!t) {
|
if (!t) {
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
@ -73,16 +73,13 @@ new_vector_list (expr_t *expr_list)
|
||||||
|
|
||||||
int all_constant = 1;
|
int all_constant = 1;
|
||||||
int all_implicit = 1;
|
int all_implicit = 1;
|
||||||
expr_t *elements[count + 1];
|
for (int i = 0; i < count; i++) {
|
||||||
elements[count] = 0;
|
auto e = elements[i];
|
||||||
count = 0;
|
|
||||||
for (expr_t *e = expr_list; e; e = e->next) {
|
|
||||||
int cast_width = type_width (get_type (e));
|
int cast_width = type_width (get_type (e));
|
||||||
type_t *cast_type = vector_type (ele_type, cast_width);
|
type_t *cast_type = vector_type (ele_type, cast_width);
|
||||||
all_implicit = all_implicit && e->implicit;
|
all_implicit = all_implicit && e->implicit;
|
||||||
elements[count] = cast_expr (cast_type, fold_constants (e));
|
elements[i] = cast_expr (cast_type, fold_constants (e));
|
||||||
all_constant = all_constant && is_constant (elements[count]);
|
all_constant = all_constant && is_constant (elements[i]);
|
||||||
count++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (count) {
|
switch (count) {
|
||||||
|
|
|
@ -198,7 +198,8 @@ int yylex (void);
|
||||||
%type <expr> compound_init element_list
|
%type <expr> compound_init element_list
|
||||||
%type <designator> designator designator_spec
|
%type <designator> designator designator_spec
|
||||||
%type <element> element
|
%type <element> element
|
||||||
%type <expr> ose optional_state_expr texpr vector_expr
|
%type <expr> method_optional_state_expr optional_state_expr
|
||||||
|
%type <expr> texpr vector_expr
|
||||||
%type <expr> statement statements compound_statement
|
%type <expr> statement statements compound_statement
|
||||||
%type <expr> else bool_label break_label continue_label
|
%type <expr> else bool_label break_label continue_label
|
||||||
%type <expr> unary_expr ident_expr cast_expr expr_list
|
%type <expr> unary_expr ident_expr cast_expr expr_list
|
||||||
|
@ -972,7 +973,7 @@ save_storage
|
||||||
;
|
;
|
||||||
|
|
||||||
function_body
|
function_body
|
||||||
: ose
|
: method_optional_state_expr
|
||||||
{
|
{
|
||||||
specifier_t spec = default_type ($<spec>0, $<spec>0.sym);
|
specifier_t spec = default_type ($<spec>0, $<spec>0.sym);
|
||||||
symbol_t *sym = funtion_sym_type (spec, spec.sym);
|
symbol_t *sym = funtion_sym_type (spec, spec.sym);
|
||||||
|
@ -1415,7 +1416,7 @@ compound_init
|
||||||
| '{' '}' { $$ = 0; }
|
| '{' '}' { $$ = 0; }
|
||||||
;
|
;
|
||||||
|
|
||||||
ose
|
method_optional_state_expr
|
||||||
: /* emtpy */ { $$ = 0; }
|
: /* emtpy */ { $$ = 0; }
|
||||||
| SHR vector_expr { $$ = build_state_expr ($2); }
|
| SHR vector_expr { $$ = build_state_expr ($2); }
|
||||||
;
|
;
|
||||||
|
@ -1565,7 +1566,7 @@ statement
|
||||||
'(' opt_init_semi opt_expr ';' opt_expr ')' statement pop_scope
|
'(' opt_init_semi opt_expr ';' opt_expr ')' statement pop_scope
|
||||||
{
|
{
|
||||||
if ($6) {
|
if ($6) {
|
||||||
$6 = build_block_expr ($6);
|
$6 = build_block_expr ($6, false);
|
||||||
}
|
}
|
||||||
$$ = build_for_statement ($6, $7, $9, $11,
|
$$ = build_for_statement ($6, $7, $9, $11,
|
||||||
break_label, continue_label);
|
break_label, continue_label);
|
||||||
|
@ -1727,11 +1728,7 @@ ident_expr
|
||||||
vector_expr
|
vector_expr
|
||||||
: '[' expr ',' expr_list ']'
|
: '[' expr ',' expr_list ']'
|
||||||
{
|
{
|
||||||
expr_t *t = $4;
|
$$ = list_prepend_expr ($4, $2);
|
||||||
while (t->next)
|
|
||||||
t = t->next;
|
|
||||||
t->next = $2;
|
|
||||||
$$ = $4;
|
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -1783,22 +1780,17 @@ texpr
|
||||||
comma_expr
|
comma_expr
|
||||||
: expr_list
|
: expr_list
|
||||||
{
|
{
|
||||||
if ($1->next) {
|
if ($1->list.head->next) {
|
||||||
expr_t *res = $1;
|
$$ = build_block_expr ($1, true);
|
||||||
$1 = build_block_expr ($1);
|
} else {
|
||||||
$1->block.result = res;
|
$$ = $1->list.head->expr;
|
||||||
}
|
}
|
||||||
$$ = $1;
|
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
expr_list
|
expr_list
|
||||||
: expr
|
: expr { $$ = new_list_expr ($1); }
|
||||||
| expr_list ',' expr
|
| expr_list ',' expr { $$ = list_append_expr ($1, $3); }
|
||||||
{
|
|
||||||
$3->next = $1;
|
|
||||||
$$ = $3;
|
|
||||||
}
|
|
||||||
;
|
;
|
||||||
|
|
||||||
opt_arg_list
|
opt_arg_list
|
||||||
|
@ -2216,7 +2208,7 @@ notype_ivar_declarator
|
||||||
;
|
;
|
||||||
|
|
||||||
methoddef
|
methoddef
|
||||||
: ci methoddecl ose
|
: ci methoddecl method_optional_state_expr
|
||||||
{
|
{
|
||||||
method_t *method = $2;
|
method_t *method = $2;
|
||||||
|
|
||||||
|
|
|
@ -2307,7 +2307,8 @@ statement_single (sblock_t *sblock, expr_t *e)
|
||||||
};
|
};
|
||||||
|
|
||||||
if (e->type >= ex_count || !sfuncs[e->type]) {
|
if (e->type >= ex_count || !sfuncs[e->type]) {
|
||||||
internal_error (e, "bad expression type");
|
internal_error (e, "bad expression type: %s",
|
||||||
|
e->type < ex_count ? expr_names[e->type] : "?");
|
||||||
}
|
}
|
||||||
sblock = sfuncs[e->type] (sblock, e);
|
sblock = sfuncs[e->type] (sblock, e);
|
||||||
return sblock;
|
return sblock;
|
||||||
|
|
Loading…
Reference in a new issue