short starts_indented;
short indents;
short since_newline;
+ short since_indent;
} *stack;
void **asn_stack;
int stack_size;
else
next->since_newline = 1;
}
+ if (next->indents)
+ next->since_indent = 0;
+ else if (p->tos)
+ next->since_indent = p->stack[p->tos-1].since_indent + 1;
+ else
+ next->since_indent = 1;
+
p->stack[p->tos] = *next;
p->asn_stack[p->tos] = asn;
p->tos++;
continue;
}
if (next.sym == TK_out) {
- if (tos->indents > tos->starts_indented ||
- (tos->indents == 1 &&
- states[tos->state].reduce_size != 1)) {
- tos->indents -= 1;
- if (tos->indents <= tos->starts_indented) {
- // no internal indent any more, reassess 'newline_permitted'
- if (states[tos->state].starts_line)
- tos->newline_permitted = 1;
- else if (p.tos > 1)
- tos->newline_permitted = p.stack[p.tos-2].newline_permitted;
- else
- tos->newline_permitted = 0;
+ if (states[tos->state].reduce_size >= 0 &&
+ states[tos->state].reduce_size <= tos->since_indent)
+ goto force_reduce;
+ if (states[tos->state].min_prefix >= tos->since_indent) {
+ // OK to cancel
+ struct frame *in = tos - tos->since_indent;
+ in->indents -= 1;
+ if (in->indents == 0) {
+ /* Reassess since_indent and newline_permitted */
+ if (in > p.stack) {
+ in->since_indent = in[-1].since_indent + 1;
+ in->newline_permitted = in[-1].newline_permitted;
+ } else {
+ in->since_indent = 0;
+ in->newline_permitted = 0;
+ }
+ if (states[in->state].starts_line)
+ in->newline_permitted = 0;
+ while (in < tos) {
+ in += 1;
+ in->since_indent = in[-1].since_indent + 1;
+ if (states[in->state].starts_line)
+ in->newline_permitted = 1;
+ else
+ in->newline_permitted = in[-1].newline_permitted;
+ }
}
free(tk);
tk = NULL;
if (next.indents == 0)
break;
next.indents -= 1;
+ // FIXME update since_indent here
}
}
if (p.tos == 0 && tk->num == TK_eof)