extern void parse_code_block(int break_label, int continue_label, int switch_rule) { int switch_clause_made = FALSE, default_clause_made = FALSE, switch_label = 0, unary_minus_flag; begin_syntax_line(TRUE); get_next_token(); if (token_type == SEP_TT && token_value == OPEN_BRACE_SEP) { do { begin_syntax_line(TRUE); get_next_token(); if (token_type == SEP_TT && token_value == CLOSE_BRACE_SEP) { if (switch_clause_made && (!default_clause_made)) assemble_label_no(switch_label); return; } if (token_type == EOF_TT) { ebf_error("'}'", token_text); return; } if (switch_rule != 0) { /* Within a 'switch' block */ if ((token_type==STATEMENT_TT)&&(token_value==SDEFAULT_CODE)) { if (default_clause_made) error("Multiple 'default' clauses defined in same 'switch'"); default_clause_made = TRUE; if (switch_clause_made) { if (!execution_never_reaches_here) { sequence_point_follows = FALSE; assemble_jump(break_label); } assemble_label_no(switch_label); } switch_clause_made = TRUE; get_next_token(); if ((token_type == SEP_TT) && (token_value == COLON_SEP)) continue; ebf_error("':' after 'default'", token_text); panic_mode_error_recovery(); continue; } /* Decide: is this an ordinary statement, or the start of a new case? */ if (token_type == DQ_TT) goto NotASwitchCase; unary_minus_flag = ((token_type == SEP_TT)&&(token_value == MINUS_SEP)); if (unary_minus_flag) get_next_token(); /* Now read the token _after_ any possible constant: if that's a 'to', ',' or ':' then we have a case */ misc_keywords.enabled = TRUE; get_next_token(); misc_keywords.enabled = FALSE; if (switch_sign() > 0) { assembly_operand AO; if (default_clause_made) error("'default' must be the last 'switch' case"); if (switch_clause_made) { if (!execution_never_reaches_here) { sequence_point_follows = FALSE; assemble_jump(break_label); } assemble_label_no(switch_label); } switch_label = next_label++; switch_clause_made = TRUE; put_token_back(); put_token_back(); if (unary_minus_flag) put_token_back(); AO = temp_var1; parse_switch_spec(AO, switch_label, FALSE); continue; } else { put_token_back(); put_token_back(); if (unary_minus_flag) put_token_back(); get_next_token(); } } if ((switch_rule != 0) && (!switch_clause_made)) ebf_error("switch value", token_text); NotASwitchCase: sequence_point_follows = TRUE; parse_statement(break_label, continue_label); } while(TRUE); } if (switch_rule != 0) ebf_error("braced code block after 'switch'", token_text); parse_statement(break_label, continue_label); return; }
void assemble(const char *fn) { u16 pc, n; fin = fopen(fn, "r"); filename = fn; linenumber = 0; if (!fin) die("cannot read file"); for (;;) { next(); again: switch (token) { case tEOF: goto done; case tSTRING: expect(tCOLON); set_label(tstring, PC); continue; case tCOLON: expect(tSTRING); set_label(tstring, PC); continue; case tWORD: case tDAT: case tDATA: case tDW: assemble_imm_or_label(); goto again; case tJMP: // alias for SET PC, ... assemble_jump(); continue; case tMOV: // alias for SET token = tSET; case tSET: case tADD: case tSUB: case tMUL: case tDIV: case tMOD: case tSHL: case tSHR: case tAND: case tBOR: case tXOR: case tIFE: case tIFN: case tIFG: case tIFB: case tPUSH: case tPOP: case tNOP: assemble_binop(); continue; case tJSR: pc = PC++; n = assemble_operand(); image[pc] = (n << 10) | (0x01 << 5); continue; case tINT: pc = PC++; n = assemble_operand(); image[pc] = (n << 10) | (0x08 << 5); continue; case tIAG: pc = PC++; n = assemble_operand(); image[pc] = (n << 10) | (0x09 << 5); continue; case tIAS: pc = PC++; n = assemble_operand(); image[pc] = (n << 10) | (0x0a << 5); continue; case tRFI: pc = PC++; n = assemble_operand(); image[pc] = (n << 10) | (0x0b << 5); continue; case tIAQ: pc = PC++; n = assemble_operand(); image[pc] = (n << 10) | (0x0c << 5); continue; case tHWN: pc = PC++; n = assemble_operand(); image[pc] = (n << 10) | (0x10 << 5); continue; case tHWQ: pc = PC++; n = assemble_operand(); image[pc] = (n << 10) | (0x11 << 5); continue; case tHWI: pc = PC++; n = assemble_operand(); image[pc] = (n << 10) | (0x12 << 5); continue; default: die("unexpected: %s", tnames[token]); } } done: fclose(fin); }