// Parse {block} [else {block}] static void parse_block_else_block(bool parse_first) { // Parse first block. // If it's not correctly terminated, return immediately (because // in that case, there's no use in checking for an "else" part). if(skip_or_parse_block(parse_first)) return; // now GotByte = '}'. Check for "else" part. // If end of statement, return immediately. NEXTANDSKIPSPACE(); if(GotByte == CHAR_EOS) return; // read keyword and check whether really "else" if(Input_read_and_lower_keyword()) { if(strcmp(GlobalDynaBuf->buffer, "else")) Throw_error(exception_syntax); else { SKIPSPACE(); if(GotByte != CHAR_SOB) Throw_serious_error(exception_no_left_brace); skip_or_parse_block(!parse_first); // now GotByte = '}' GetByte(); } } Input_ensure_EOS(); }
// Try to read a comma, skipping spaces before and after. Return TRUE if comma // found, otherwise FALSE. bool Input_accept_comma(void) { SKIPSPACE(); if(GotByte != ',') return(FALSE); NEXTANDSKIPSPACE(); return(TRUE); }
// Looping assembly ("!do"). Has to be re-entrant. static enum eos_t PO_do(void) { // Now GotByte = illegal char loopcond_t condition1, condition2; input_t loop_input, *outer_input; char* loop_body; bool go_on; int loop_start;// line number of loop pseudo opcode // Read head condition to buffer SKIPSPACE(); store_condition(&condition1, CHAR_SOB); if(GotByte != CHAR_SOB) Throw_serious_error(exception_no_left_brace); // Remember line number of loop body, // then read block and get copy loop_start = Input_now->line_number; loop_body = Input_skip_or_store_block(TRUE); // changes line number! // now GotByte = '}' NEXTANDSKIPSPACE();// Now GotByte = first non-blank char after block // Read tail condition to buffer store_condition(&condition2, CHAR_EOS); // now GotByte = CHAR_EOS // set up new input loop_input = *Input_now;// copy current input structure into new loop_input.source_is_ram = TRUE; // set new byte source // remember old input outer_input = Input_now; // activate new input (not useable yet, as pointer and // line number are not yet set up) Input_now = &loop_input; do { // Check head condition go_on = check_condition(&condition1); if(go_on) { parse_ram_block(loop_start, loop_body); // Check tail condition go_on = check_condition(&condition2); } } while(go_on); // Free memory free(condition1.body); free(loop_body); free(condition2.body); // restore previous input: Input_now = outer_input; GotByte = CHAR_EOS; // CAUTION! Very ugly kluge. // But by switching input, we lost the outer input's GotByte. We know // it was CHAR_EOS. We could just call GetByte() to get real input, but // then the main loop could choke on unexpected bytes. So we pretend // that we got the outer input's GotByte value magically back. return(AT_EOS_ANYWAY); }