Added unbounded char arrays for null-terminated strings
This commit is contained in:
parent
7e4babaca8
commit
08c802f733
@ -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();
|
||||
|
@ -28,6 +28,9 @@ namespace hex::lang {
|
||||
result += *c;
|
||||
}
|
||||
|
||||
if (*(data + size - 1) == '\x00')
|
||||
result.pop_back();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -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());
|
||||
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user