/* 15.6.2.2531 [ELSE] “bracket-else” TOOLS EXT Compilation: Perform the execution semantics given below. Execution: ( “hspacesiname ...” -- ) Skipping leading spaces, parse and discard space-delimited words from the parse area, including nested occurrences of [IF] ... [THEN] and [IF] ... [ELSE] ... [THEN], until the word [THEN] has been parsed and discarded. If the parse area be- comes exhausted, it is refilled as with REFILL. [ELSE] is an immediate word. See: 3.4.1 Parsing, A.15.6.2.2531 [ELSE]. 15.6.2.2532 [IF] “bracket-if” TOOLS EXT */ static void do_bracket_else(void) { /* : [else] 1 ( initialize [if]/[else]/[then] nesting level) begin bl word count dup 0= ( refill input buffer) if drop drop refill 0= if ( refill failed) drop ( drop nesting level) ." error: input exhausted" cr exit then [ over ] ( continue loop) again then 0 if 2dup ." found word: " type cr then 2dup s" [if]" compare 0= if ( increase nesting level) rot 1+ rot rot then 2dup s" [else]" compare 0= if ( special-case for the nesting level) rot dup 1 = if 1- then rot rot then s" [then]" compare 0= if ( decrease nesting level) 1- then dup 0= until drop ; immediate : [if] 0= if postpone [else] then ; immediate : [then] ; immediate */ /* initialize [if]/[else]/[then] nesting level */ sf_push(1); do { do_bl(); do_word(); do_count(); if (!sf_top()) { /* input exhausted, refill input buffer */ do_drop(); do_drop(); do_refill(); if (!sf_pop()) { /* 'refill' failed */ /* drop nesting level */ do_drop(); print_str(__func__); print_str("(): input exhausted; aborting\n"); do_abort(); } continue; } do_two_to_r(); do_two_r_fetch(); //sf_push((cell) "\04[if]"); do_count(); sf_push((cell) compare_word_xt); do_execute(); if (sf_pop() == 4) { if (!xmemcmp((void *) sf_pop(), "[if]", 4)) /* increase nesting level */ do_one_plus(); } else do_drop(); do_two_r_fetch(); //sf_push((cell) "\06[else]"); do_count(); sf_push((cell) compare_word_xt); do_execute(); if (sf_pop() == 6) { if (!xmemcmp((void *) sf_pop(), "[else]", 6)) /* see if an [if] block should be terminated */ if (sf_top() == 1) do_one_minus(); } else do_drop(); do_two_r_from(); //sf_push((cell) "\06[then]"); do_count(); sf_push((cell) compare_word_xt); do_execute(); if (sf_pop() == 6) { if (!xmemcmp((void *) sf_pop(), "[then]", 6)) /* decrease nesting level */ do_one_minus(); } else do_drop(); } while (sf_top()); /* drop nesting level */ do_drop(); }
// bequal reports whether the buffers have the same content. bool bequal(Buf *s, Buf *t) { return s->len == t->len && xmemcmp(s->p, t->p, s->len) == 0; }