Esempio n. 1
0
// (Re)set label
static enum eos_t PO_set(void)	// Now GotByte = illegal char
{
	struct result_t	result;
	int		force_bit;
	struct label_t	*label;
	zone_t		zone;

	if (Input_read_zone_and_keyword(&zone) == 0)	// skips spaces before
		// Now GotByte = illegal char
		return SKIP_REMAINDER;

	force_bit = Input_get_force_bit();	// skips spaces after
	label = Label_find(zone, force_bit);
	if (GotByte != '=') {
		Throw_error(exception_syntax);
		return SKIP_REMAINDER;
	}

	// label = parsed value
	GetByte();	// proceed with next char
	ALU_any_result(&result);
	// clear label's force bits and set new ones
	label->result.flags &= ~(MVALUE_FORCEBITS | MVALUE_ISBYTE);
	if (force_bit) {
		label->result.flags |= force_bit;
		result.flags &= ~(MVALUE_FORCEBITS | MVALUE_ISBYTE);
	}
	Label_set_value(label, &result, TRUE);
	return ENSURE_EOS;
}
Esempio n. 2
0
// Looping assembly ("!for"). Has to be re-entrant.
static enum eos_t PO_for(void) {// Now GotByte = illegal char
	input_t		loop_input,
			*outer_input;
	result_t	loop_counter;
	intval_t	maximum;
	char*		loop_body;// pointer to loop's body block
	label_t*	label;
	zone_t		zone;
	int		force_bit,
			loop_start;// line number of "!for" pseudo opcode

	if(Input_read_zone_and_keyword(&zone) == 0)	// skips spaces before
		return(SKIP_REMAINDER);
	// Now GotByte = illegal char
	force_bit = Input_get_force_bit();	// skips spaces after
	label = Label_find(zone, force_bit);
	if(Input_accept_comma() == FALSE) {
		Throw_error(exception_syntax);
		return(SKIP_REMAINDER);
	}
	maximum = ALU_defined_int();
	if(maximum < 0)
		Throw_serious_error("Loop count is negative.");
	if(GotByte != CHAR_SOB)
		Throw_serious_error(exception_no_left_brace);
	// remember line number of loop pseudo opcode
	loop_start = Input_now->line_number;
	// read loop body into DynaBuf and get copy
	loop_body = Input_skip_or_store_block(TRUE);	// changes line number!
	// switching input makes us lose GotByte. But we know it's '}' anyway!
	// 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 yet useable; pointer and line number are still missing)
	Input_now = &loop_input;
	// init counter
	loop_counter.flags = MVALUE_DEFINED | MVALUE_EXISTS;
	loop_counter.val.intval = 0;
	// if count == 0, skip loop
	if(maximum) {
		do {
			loop_counter.val.intval++;// increment counter
			Label_set_value(label, &loop_counter, TRUE);
			parse_ram_block(loop_start, loop_body);
		} while(loop_counter.val.intval < maximum);
	} else
		Label_set_value(label, &loop_counter, TRUE);
	// Free memory
	free(loop_body);
	// restore previous input:
	Input_now = outer_input;
	// GotByte of OuterInput would be '}' (if it would still exist)
	GetByte();	// fetch next byte
	return(ENSURE_EOS);
}
Esempio n. 3
0
// set global label to value, no questions asked (for "-D" switch)
// Name must be held in GlobalDynaBuf.
void Label_define(intval_t value)
{
	struct result_t	result;
	struct label_t	*label;

	result.flags = MVALUE_GIVEN;
	result.val.intval = value;
	label = Label_find(ZONE_GLOBAL, 0);
	Label_set_value(label, &result, TRUE);
}
Esempio n. 4
0
// Parse implicit label definition (can be either global or local).
// GlobalDynaBuf holds the label name.
void Label_implicit_definition(zone_t zone, int stat_flags, int force_bit, int change)
{
	struct result_t	result;
	struct label_t	*label;

	label = Label_find(zone, force_bit);
	// implicit label definition (label)
	if ((stat_flags & SF_FOUND_BLANK) && warn_on_indented_labels)
		Throw_first_pass_warning("Implicit label definition not in leftmost column.");
	result.flags = CPU_pc.flags & MVALUE_DEFINED;
	result.val.intval = CPU_pc.intval;
	Label_set_value(label, &result, change);
}
Esempio n. 5
0
File: label.c Progetto: eiger/earing
Token *Label_expression(Function *func, Token *tk)
{
    Label *label = Label_find(func, tk);

    if(!label) {
        // forward label expression, create but not realized
        label = Label_create_and_add(func, tk, 0);
    } else {
        if(label->realized) {
            // backward label expression
            tk->value = (unsigned long)label->ref;
        } else {
            // forward label expression that's being used again
            // do nothing with it, Call_operation will handle the gore
        }
    }

    return tk;
}
Esempio n. 6
0
// parse label definition (can be either global or local).
// GlobalDynaBuf holds the label name.
void Label_parse_definition(zone_t zone, int stat_flags)
{
	struct result_t	result;
	struct label_t	*label;
	int		force_bit	= Input_get_force_bit();	// skips spaces after
	// FIXME - force bit is allowed for implicit label defs?!

	if (GotByte == '=') {
		// explicit label definition (label = <something>)
		label = Label_find(zone, force_bit);
		// label = parsed value
		GetByte();	// skip '='
		ALU_any_result(&result);
		Label_set_value(label, &result, FALSE);
		Input_ensure_EOS();
	} else {
		Label_implicit_definition(zone, stat_flags, force_bit, FALSE);
	}
}
Esempio n. 7
0
// fix name of anonymous forward label (held in DynaBuf, NOT TERMINATED!) so it
// references the *next* anonymous forward label definition. The tricky bit is,
// each name length would need its own counter. But hey, ACME's real quick in
// finding labels, so I'll just abuse the label system to store those counters.
struct label_t *Label_fix_forward_name(void)
{
	struct label_t	*counter_label;
	unsigned long	number;

	// terminate name, find "counter" label and read value
	DynaBuf_append(GlobalDynaBuf, '\0');
	counter_label = Label_find(Section_now->zone, 0);
	// make sure it gets reset to zero in each new pass
	if (counter_label->pass != pass_count) {
		counter_label->pass = pass_count;
		counter_label->result.val.intval = 0;
	}
	number = (unsigned long) counter_label->result.val.intval;
	// now append to the name to make it unique
	GlobalDynaBuf->size--;	// forget terminator, we want to append
	do {
		DYNABUF_APPEND(GlobalDynaBuf, 'a' + (number & 15));
		number >>= 4;
	} while (number);
	DynaBuf_append(GlobalDynaBuf, '\0');
	return counter_label;
}