Ejemplo n.º 1
0
void CDirectiveData::encodeCustom(EncodingTable& table)
{
	customData.clear();
	for (size_t i = 0; i < entries.size(); i++)
	{
		ExpressionValue value = entries[i].evaluate();
		if (!value.isValid())
		{
			Logger::queueError(Logger::Error,L"Invalid expression");
			continue;
		}
		
		if (value.isInt())
		{
			customData.appendByte((u8)value.intValue);
		} else if (value.isString())
		{
			ByteArray encoded = table.encodeString(value.strValue,false);
			if (encoded.size() == 0 && value.strValue.size() > 0)
			{
				Logger::queueError(Logger::Error,L"Failed to encode \"%s\"",value.strValue);
			}
			customData.append(encoded);
		} else {
			Logger::queueError(Logger::Error,L"Invalid expression type");
		}
	}

	if (writeTermination)
	{
		ByteArray encoded = table.encodeTermination();
		customData.append(encoded);
	}
}
Ejemplo n.º 2
0
CAssemblerCommand* parseDirectiveConditional(Parser& parser, int flags)
{
    ConditionType type;
    std::wstring name;
    Expression exp;

    const Token& start = parser.peekToken();
    ConditionalResult condResult = ConditionalResult::Unknown;
    switch (flags)
    {
    case DIRECTIVE_COND_IF:
        type = ConditionType::IF;
        exp = parser.parseExpression();
        if (exp.isLoaded() == false)
        {
            parser.printError(start,L"Invalid condition");
            return new DummyCommand();
        }

        if (exp.isConstExpression())
        {
            ExpressionValue result = exp.evaluate();
            if (result.isInt())
                condResult = result.intValue != 0 ? ConditionalResult::True : ConditionalResult::False;
        }
        break;
    case DIRECTIVE_COND_IFDEF:
        type = ConditionType::IFDEF;
        if (parser.parseIdentifier(name) == false)
            return nullptr;
        break;
    case DIRECTIVE_COND_IFNDEF:
        type = ConditionType::IFNDEF;
        if (parser.parseIdentifier(name) == false)
            return nullptr;
        break;
    }

    parser.pushConditionalResult(condResult);
    CAssemblerCommand* ifBlock = parser.parseCommandSequence(L'.', {L".else", L".elseif", L".elseifdef", L".elseifndef", L".endif"});
    parser.popConditionalResult();

    // update the file info so that else commands get the right line number
    parser.updateFileInfo();

    CAssemblerCommand* elseBlock = nullptr;
    const Token &next = parser.nextToken();
    const std::wstring stringValue = next.getStringValue();

    if (stringValue == L".else")
    {
        ConditionalResult elseResult = condResult;
        switch (condResult)
        {
        case ConditionalResult::True:
            elseResult = ConditionalResult::False;
            break;
        case ConditionalResult::False:
            elseResult = ConditionalResult::True;
            break;
        }

        parser.pushConditionalResult(elseResult);
        elseBlock = parser.parseCommandSequence(L'.', {L".endif"});
        parser.popConditionalResult();

        parser.eatToken();	// eat .endif
    } else if (stringValue == L".elseif")
    {
        elseBlock = parseDirectiveConditional(parser,DIRECTIVE_COND_IF);
    } else if (stringValue == L".elseifdef")
    {
        elseBlock = parseDirectiveConditional(parser,DIRECTIVE_COND_IFDEF);
    } else if (stringValue == L".elseifndef")
    {
        elseBlock = parseDirectiveConditional(parser,DIRECTIVE_COND_IFNDEF);
    } else if (stringValue != L".endif")
    {
        return nullptr;
    }

    // for true or false blocks, there's no need to create a conditional command
    if (condResult == ConditionalResult::True)
    {
        delete elseBlock;
        return ifBlock;
    }

    if (condResult == ConditionalResult::False)
    {
        delete ifBlock;
        if (elseBlock != nullptr)
            return elseBlock;
        else
            return new DummyCommand();
    }

    CDirectiveConditional* cond;
    if (exp.isLoaded())
        cond = new CDirectiveConditional(type,exp);
    else if (name.size() != 0)
        cond = new CDirectiveConditional(type,name);
    else
        cond = new CDirectiveConditional(type);

    cond->setContent(ifBlock,elseBlock);
    return cond;
}