1
0
mirror of synced 2025-01-29 19:17:28 +01:00

Added unbounded char arrays for null-terminated strings

This commit is contained in:
WerWolv 2021-01-07 21:16:34 +01:00
parent 7e4babaca8
commit 08c802f733
4 changed files with 63 additions and 25 deletions

View File

@ -192,7 +192,10 @@ namespace hex::lang {
ASTNodeArrayVariableDecl(const ASTNodeArrayVariableDecl &other) : ASTNode(other) {
this->m_name = other.m_name;
this->m_type = other.m_type->clone();
this->m_size = other.m_size->clone();
if (other.m_size != nullptr)
this->m_size = other.m_size->clone();
else
this->m_size = nullptr;
if (other.m_placementOffset != nullptr)
this->m_placementOffset = other.m_placementOffset->clone();

View File

@ -28,6 +28,9 @@ namespace hex::lang {
result += *c;
}
if (*(data + size - 1) == '\x00')
result.pop_back();
return result;
}

View File

@ -512,27 +512,39 @@ namespace hex::lang {
auto startOffset = this->m_currOffset;
ASTNodeIntegerLiteral *valueNode;
u64 arraySize = 0;
if (auto sizeNumericExpression = dynamic_cast<ASTNodeNumericExpression*>(node->getSize()); sizeNumericExpression != nullptr)
valueNode = evaluateMathematicalExpression(sizeNumericExpression);
else
throwEvaluateError("array size not a numeric expression", node->getLineNumber());
if (node->getSize() != nullptr) {
if (auto sizeNumericExpression = dynamic_cast<ASTNodeNumericExpression*>(node->getSize()); sizeNumericExpression != nullptr)
valueNode = evaluateMathematicalExpression(sizeNumericExpression);
else
throwEvaluateError("array size not a numeric expression", node->getLineNumber());
SCOPE_EXIT( delete valueNode; );
SCOPE_EXIT( delete valueNode; );
auto arraySize = std::visit([node, type = valueNode->getType()] (auto &&value) {
if (Token::isFloatingPoint(type))
throwEvaluateError("array size must be an integer value", node->getLineNumber());
return static_cast<u64>(value);
}, valueNode->getValue());
arraySize = std::visit([node, type = valueNode->getType()] (auto &&value) {
if (Token::isFloatingPoint(type))
throwEvaluateError("array size must be an integer value", node->getLineNumber());
return static_cast<u64>(value);
}, valueNode->getValue());
if (auto typeDecl = dynamic_cast<ASTNodeTypeDecl*>(node->getType()); typeDecl != nullptr) {
if (auto builtinType = dynamic_cast<ASTNodeBuiltinType*>(typeDecl->getType()); builtinType != nullptr) {
if (builtinType->getType() == Token::ValueType::Padding) {
this->m_currOffset += arraySize;
return new PatternDataPadding(startOffset, arraySize);
if (auto typeDecl = dynamic_cast<ASTNodeTypeDecl*>(node->getType()); typeDecl != nullptr) {
if (auto builtinType = dynamic_cast<ASTNodeBuiltinType*>(typeDecl->getType()); builtinType != nullptr) {
if (builtinType->getType() == Token::ValueType::Padding) {
this->m_currOffset += arraySize;
return new PatternDataPadding(startOffset, arraySize);
}
}
}
} else {
u8 currByte = 0x00;
u64 offset = startOffset;
do {
this->m_provider->read(offset, &currByte, sizeof(u8));
offset += sizeof(u8);
arraySize += sizeof(u8);
} while (currByte != 0x00 && offset < this->m_provider->getSize());
}
std::vector<PatternData*> entries;
@ -563,12 +575,16 @@ namespace hex::lang {
this->m_currEndian.reset();
PatternData *pattern;
if (entries.empty())
if (entries.empty()) {
pattern = new PatternDataPadding(startOffset, 0);
}
else if (dynamic_cast<PatternDataCharacter*>(entries[0]))
pattern = new PatternDataString(startOffset, (this->m_currOffset - startOffset), color.value_or(0));
else
else {
if (node->getSize() == nullptr)
throwEvaluateError("no bounds provided for array", node->getLineNumber());
pattern = new PatternDataArray(startOffset, (this->m_currOffset - startOffset), entries, color.value_or(0));
}
pattern->setVariableName(node->getName().data());

View File

@ -353,10 +353,18 @@ namespace hex::lang {
SCOPE_EXIT( delete temporaryType; );
auto name = getValue<std::string>(-2);
auto size = parseMathematicalExpression();
if (!MATCHES(sequence(SEPARATOR_SQUAREBRACKETCLOSE)))
throwParseError("expected closing ']' at end of array declaration", -1);
ASTNode *size = nullptr;
ScopeExit sizeCleanup([&]{ delete size; });
if (!MATCHES(sequence(SEPARATOR_SQUAREBRACKETCLOSE))) {
size = parseMathematicalExpression();
if (!MATCHES(sequence(SEPARATOR_SQUAREBRACKETCLOSE)))
throwParseError("expected closing ']' at end of array declaration", -1);
}
sizeCleanup.release();
return new ASTNodeArrayVariableDecl(name, temporaryType->getType()->clone(), size);
}
@ -558,21 +566,29 @@ namespace hex::lang {
return new ASTNodeVariableDecl(getValue<std::string>(-2), temporaryType->getType()->clone(), parseMathematicalExpression());
}
// (parseType) Identifier[(parseMathematicalExpression)] @ Integer
// (parseType) Identifier[[(parseMathematicalExpression)]] @ Integer
ASTNode* Parser::parseArrayVariablePlacement() {
auto temporaryType = dynamic_cast<ASTNodeTypeDecl *>(parseType(-3));
if (temporaryType == nullptr) throwParseError("invalid type used in variable declaration", -1);
SCOPE_EXIT( delete temporaryType; );
auto name = getValue<std::string>(-2);
auto size = parseMathematicalExpression();
if (!MATCHES(sequence(SEPARATOR_SQUAREBRACKETCLOSE)))
throwParseError("expected closing ']' at end of array declaration", -1);
ASTNode *size = nullptr;
ScopeExit sizeCleanup([&]{ delete size; });
if (!MATCHES(sequence(SEPARATOR_SQUAREBRACKETCLOSE))) {
size = parseMathematicalExpression();
if (!MATCHES(sequence(SEPARATOR_SQUAREBRACKETCLOSE)))
throwParseError("expected closing ']' at end of array declaration", -1);
}
if (!MATCHES(sequence(OPERATOR_AT)))
throwParseError("expected placement instruction", -1);
sizeCleanup.release();
return new ASTNodeArrayVariableDecl(name, temporaryType->getType()->clone(), size, parseMathematicalExpression());
}