Ejemplo n.º 1
0
bool 
PreProcessor::elif_directive()
{
	assert(tokenit.is(_PP_ELIF));
	tokenit.next();

	if (ifBlockEnables.empty()) {
		ERROR("'if' directive is not found");
		return false;
	}

	bool if_is_enable = ifBlockEnables.back();
	if (if_is_enable) {
		TokenIterator tag = tokenit;
		skipUntilElseOrEnd();
		tag.erase(tokenit-tag);
	} else {
		AST *ast = expression();
		if (!ast) {
			return false;
		}
		if (eval(ast)) {
			ifBlockEnables.pop_back();
			ifBlockEnables.push_back(true);
		} else {
			TokenIterator tag = tokenit;
			skipUntilElseOrEnd();
			tag.erase(tokenit-tag);
		}
	}
	return true;
}
Ejemplo n.º 2
0
void
PreProcessor::applyMacro(const String &ident, const ref<MacroDef> &macro)
{
	assert(tokenit.is(_IDENT));
	
	DBG("apply macro: %s", ident.c_str());
	if (macro->params.empty()) {
		tokenit.erase(1);//erase identifier
		tokenit.insert(macro->tokens);
	} else {
		TokenIterator tag = tokenit;
		tokenit.next();
		//get caller params
		if (tokenit.is(_LPAREN)) {
			tokenit.next();
			List<List<Token> > caller_params;
			if (!parseFunctionParams(caller_params)) {
				ERROR("failed to parse function macro");
				return;
			}
			if (macro->params.size() != caller_params.size()) {
				ERROR("macro %s requres %d parameters", 
					  ident.c_str(), macro->params.size());
				return;
			}
			tag.erase(tokenit-tag);//erase function call tokens

			//replace macro params
			List<Token> replace_tokens = replaceMacroParams(macro->tokens, caller_params);
			tokenit.insert(replace_tokens);
			//tokenit.next();
		}
	}
}
Ejemplo n.º 3
0
bool 
PreProcessor::else_directive()
{
	assert(tokenit.is(_PP_ELSE));
	tokenit.next();
	if (!tokenit.is(_PP_END)) {
		//TODO: warning
	} 
	tokenit.skipUntil({_PP_END}, true);
	tokenit.next();

	if (ifBlockEnables.empty()) {
		ERROR("'if' directive is not found (before 'else')");
		return false;
	}
	bool if_is_enable = ifBlockEnables.back();
	if (if_is_enable) {
		TokenIterator tag = tokenit;
		skipUntilElseOrEnd();
		tag.erase(tokenit-tag);
	} else {
		ifBlockEnables.pop_back();
		ifBlockEnables.push_back(true);
	}

	return true;
}
Ejemplo n.º 4
0
List<Token> 
PreProcessor::replaceMacroParams(const List<Token> &mtokens, const List<List<Token>> &caller_params)
{
	//FIXME: nested macro
	//i.e. FUNC(x, FUNC(x,y))

	List<Token> replace = mtokens;
	TokenIterator it;
	it.setTokens(&replace);
	while (!it.eof()) {
		if (it.is(_PP_MACRO_PARAM)) {
			int index = it.val()->toInt();
			const List<Token> &param = caller_params.at(index);
			it.erase(1);
			it.insert(param);
		}
		it.next();
	}
	return replace;
}
Ejemplo n.º 5
0
bool 
PreProcessor::if_directive()
{
	assert(tokenit.is(_PP_IF));
	tokenit.next();

	AST *ast = expression();
	if (!ast) {
		return false;
	}

	if (eval(ast)) {
		ifBlockEnables.push_back(true);
	} else {
		ifBlockEnables.push_back(false);
		TokenIterator tag = tokenit;
		skipUntilElseOrEnd();
		tag.erase(tokenit-tag);
	}
	return true;
}