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); } }
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; }