]> ocean-lang.org Git - ocean/commitdiff
parsergen: add since_indent to stack frame.
authorNeilBrown <neilb@suse.de>
Thu, 2 Oct 2014 10:58:38 +0000 (20:58 +1000)
committerNeilBrown <neilb@suse.de>
Thu, 2 Oct 2014 10:58:38 +0000 (20:58 +1000)
This counts frames since last indent.
It is used to determine when an OUT can be canceled and when we must
force a reduction.

Signed-off-by: NeilBrown <neil@brown.name>
csrc/parsergen.mdc

index 45fb09e5228f26ce3240a8daa46f1d6d092ffa7d..082cf117cb1abf8e2e3d50fcc89c6a806502ee71 100644 (file)
@@ -2465,6 +2465,7 @@ before the beginning.
                        short starts_indented;
                        short indents;
                        short since_newline;
+                       short since_indent;
                } *stack;
                void **asn_stack;
                int stack_size;
@@ -2539,6 +2540,13 @@ So we walk down:
                        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++;
@@ -2664,18 +2672,32 @@ since the last state which could have been at the start of a line.
                                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;
@@ -2782,6 +2804,7 @@ since the last state which could have been at the start of a line.
                                        if (next.indents == 0)
                                                break;
                                        next.indents -= 1;
+                                       // FIXME update since_indent here
                                }
                        }
                        if (p.tos == 0 && tk->num == TK_eof)