Beispiel #1
0
/* register */
static int _register(State * state)
	/* "%" WORD */
{
	AsmArchOperand * p;
	char const * string;

#ifdef DEBUG
	fprintf(stderr, "DEBUG: %s(%%%s) %d\n", __func__, token_get_string(
				state->token), state->address);
#endif
	p = &state->call.operands[state->call.operands_cnt];
	string = token_get_string(state->token); /* XXX may be null or empty? */
	if(state->address == 2)
	{
		p->definition = AO_DREGISTER2(0, 0, 0, 0);
		p->value.dregister2.name = p->value.dregister.name;
		p->value.dregister2.name2 = strdup(string);
	}
	else if(state->address == 1)
	{
		p->definition = AO_DREGISTER(0, 0, 0, 0);
		p->value.dregister.name = strdup(string);
	}
	else if(state->address == 0)
	{
		p->definition = AO_REGISTER(0, 0, 0);
		p->value._register.name = strdup(string);
	}
	return _parser_scan(state);
}
Beispiel #2
0
/* section_name */
static int _section_name(State * state)
	/* WORD */
{
	int ret = 0;
	char const * string = NULL;
	size_t len;
	char * section = NULL;

#ifdef DEBUG
	fprintf(stderr, "DEBUG: %s()\n", __func__);
#endif
	if(state->token == NULL
			|| (string = token_get_string(state->token)) == NULL
			|| (len = strlen(token_get_string(state->token))) == 0)
		return error_set_code(1, "%s",
				"Sections with empty names are not allowed");
	if((section = malloc(len + 2)) == NULL)
		return ret | error_set_code(1, "%s", strerror(errno));
	snprintf(section, len + 2, ".%s", string);
	ret |= _parser_scan(state);
#ifdef DEBUG
	fprintf(stderr, "%s\"%s\"\n", "DEBUG: section ", section);
#endif
	if(asmcode_section(state->code, section) != 0)
		ret |= _parser_error(state, "%s", error_get());
	free(section);
	return ret;
}
Beispiel #3
0
static int _parser_scan(State * state)
{
	int ret;
	TokenCode code;
	char const * string;

	if(state->token != NULL)
		token_delete(state->token);
	if((ret = _scan_skip_meta(state)) != 0
			|| state->token == NULL)
		return ret;
	code = token_get_code(state->token);
	string = token_get_string(state->token);
	if(code == AS_CODE_WORD)
	{
		if(string != NULL && string[0] == '$')
			token_set_code(state->token, AS_CODE_IMMEDIATE);
	}
	else if(code == AS_CODE_OPERATOR_MODULO)
	{
		/* FIXME ugly workaround */
		if((ret = _scan_skip_meta(state)) != 0)
			return ret;
		if(_parser_is_code(state, AS_CODE_WORD))
			token_set_code(state->token, AS_CODE_REGISTER);
	}
	return 0;
}
Beispiel #4
0
/* immediate */
static int _immediate(State * state)
	/* [ sign ] "$" NUMBER */
{
	int ret = 0;
	AsmArchOperand * p;
	char const * string;
	uint64_t value = 0;

#ifdef DEBUG
	fprintf(stderr, "DEBUG: %s()\n", __func__);
#endif
	/* [ sign ] */
	if(_parser_in_set(state, TS_SIGN))
		ret |= _sign(state);
	else
		state->negative = 0;
	/* "$" NUMBER */
	p = &state->call.operands[state->call.operands_cnt];
	if((string = token_get_string(state->token)) != NULL
			|| strlen(string) == 0)
		value = strtoul(string + 1, NULL, 0);
	else
		ret = _parser_error(state, "%s", "Empty values are not"
				" allowed");
	if(state->address > 0)
		p->value.dregister.offset = value;
	else
	{
		p->value.immediate.value = strtoul(string + 1, NULL, 0);
		p->definition = AO_IMMEDIATE(0, 0, 0);
		p->value.immediate.negative = state->negative;
	}
	return ret | _parser_scan(state);
}
Beispiel #5
0
static void _do_print_token(FILE * fp, Token * token)
{
	CppCode code;

	code = token_get_code(token);
#ifdef DEBUG
	fprintf(stderr, "DEBUG: \"%s\" (%d)\n", token_get_string(token), code);
#else
	if(code != CPP_CODE_META_ERROR && code != CPP_CODE_META_WARNING)
	{
		fputs(token_get_string(token), fp);
		return;
	}
	fprintf(stderr, "%s%s%s%s%u%s%s\n", code == CPP_CODE_META_ERROR
			? "Error" : "Warning", " in ",
			token_get_filename(token), ":", token_get_line(token),
			": ", token_get_string(token));
#endif
}
Beispiel #6
0
static int _scan_skip_meta(State * state)
{
	int ret = 0;
	TokenCode code;

	while(cpp_scan(state->cpp, &state->token) == 0)
	{
		if(state->token == NULL)
			return ret;
		if((code = token_get_code(state->token)) < AS_CODE_META_FIRST
				|| code > AS_CODE_META_LAST)
			return ret;
		if(code == AS_CODE_META_ERROR)
			ret |= _parser_error(state, "%s", token_get_string(
						state->token));
		else if(code == AS_CODE_META_WARNING)
			_parser_warning(state, "%s", token_get_string(
						state->token));
		token_delete(state->token);
	}
	return 1;
}
Beispiel #7
0
/* function_name */
static int _function_name(State * state)
	/* WORD */
{
	int ret;
	char const * string;
	char * function = NULL;

	if((string = token_get_string(state->token)) == NULL)
		return _parser_error(state, "%s", "Empty function names are"
				" not allowed");
	if((function = strdup(string)) == NULL)
		return error_set_code(1, "%s", strerror(errno));
	ret = _parser_check(state, AS_CODE_WORD);
#ifdef DEBUG
	fprintf(stderr, "DEBUG: %s \"%s\"\n", "function", function);
#endif
	if(asmcode_function(state->code, function) != 0)
		ret |= _parser_error(state, "%s", error_get());
	free(function);
	return ret;
}
Beispiel #8
0
/* instruction_name */
static int _instruction_name(State * state)
	/* WORD */
{
	char const * string;

#ifdef DEBUG
	fprintf(stderr, "DEBUG: %s()\n", __func__);
#endif
	if((string = token_get_string(state->token)) == NULL)
	{
		_parser_scan(state);
		return _parser_error(state, "%s", "Empty instructions are not"
				" allowed");
	}
	if((state->call.name = strdup(string)) == NULL)
		return error_set_code(1, "%s", strerror(errno));
	/* optimized free(state->operator); out */
#ifdef DEBUG
	fprintf(stderr, "DEBUG: %s() %s \"%s\"\n", __func__, "instruction ",
			string);
#endif
	return _parser_scan(state);
}
static void token_run(struct finsh_token* self)
{
	char ch;

	token_trim_space(self); /* first trim space and tab. */
	token_get_string(self, &(self->string[0]));

	if ( is_eof(self) ) { /*if it is eof, break;*/
		self->current_token = finsh_token_type_eof;
		return ;
	}

	if (self->string[0] != '\0') { /*It is a key word or a identifier.*/
		if ( !token_match_name(self, (char*)self->string) ) {
			self->current_token = finsh_token_type_identifier;
		}
		return;
	} else { /*It is a operator character.*/
		ch = token_next_char(self);

		switch ( ch ) {
		case '(':
			self->current_token = finsh_token_type_left_paren;
			break;

		case ')':
			self->current_token = finsh_token_type_right_paren;
			break;

		case ',':
			self->current_token = finsh_token_type_comma;
			break;

		case ';':
			self->current_token = finsh_token_type_semicolon;
			break;

		case '&':
			self->current_token = finsh_token_type_and;
			break;

		case '*':
			self->current_token = finsh_token_type_mul;
			break;

		case '+':
			ch = token_next_char(self);

			if ( ch == '+' ) {
				self->current_token = finsh_token_type_inc;
			} else {
				token_prev_char(self);
				self->current_token = finsh_token_type_add;
			}
			break;

		case '-':
			ch = token_next_char(self);

			if ( ch == '-' ) {
				self->current_token = finsh_token_type_dec;
			} else {
				token_prev_char(self);
				self->current_token = finsh_token_type_sub;
			}
			break;

		case '/':
			ch = token_next_char(self);
			if (ch == '/') {
				/* line comments, set to end of file */
				self->current_token = finsh_token_type_eof;
			} else {
				token_prev_char(self);
				self->current_token = finsh_token_type_div;
			}
			break;

		case '<':
			ch = token_next_char(self);

			if ( ch == '<' ) {
				self->current_token = finsh_token_type_shl;
			} else {
				token_prev_char(self);
				self->current_token = finsh_token_type_bad;
			}
			break;

		case '>':
			ch = token_next_char(self);

			if ( ch == '>' ) {
				self->current_token = finsh_token_type_shr;
			} else {
				token_prev_char(self);
				self->current_token = finsh_token_type_bad;
			}
			break;

		case '|':
			self->current_token = finsh_token_type_or;
			break;

		case '%':
			self->current_token = finsh_token_type_mod;
			break;

		case '~':
			self->current_token = finsh_token_type_bitwise;
			break;

		case '^':
			self->current_token = finsh_token_type_xor;
			break;

		case '=':
			self->current_token = finsh_token_type_assign;
			break;

		case '\'':
			self->value.char_value = token_proc_char(self);
			self->current_token = finsh_token_type_value_char;
			break;

		case '"':
			token_proc_string(self);
			self->current_token = finsh_token_type_value_string;
			break;

		default:
			if ( is_digit(ch) ) {
				token_prev_char(self);
				token_proc_number(self);
				break;
			}

			finsh_error_set(FINSH_ERROR_UNKNOWN_TOKEN);
			self->current_token = finsh_token_type_bad;

			break;
		}
	}
}