Example #1
0
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;
}
Example #2
0
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);
}