mirror of
https://github.com/RGBCube/serenity
synced 2025-05-25 12:45:06 +00:00
JSSpecCompiler: Push ParseError out of Algorithm
This commit is contained in:
parent
d339ad01bb
commit
c7369f2f93
2 changed files with 39 additions and 33 deletions
|
@ -103,38 +103,48 @@ ParseErrorOr<AlgorithmStepList> AlgorithmStepList::create(XML::Node::Element con
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
ParseErrorOr<Algorithm> Algorithm::create(XML::Node const* node)
|
Optional<Algorithm> Algorithm::create(SpecificationParsingContext& ctx, XML::Node const* element)
|
||||||
{
|
{
|
||||||
VERIFY(node->as_element().name == tag_emu_alg);
|
VERIFY(element->as_element().name == tag_emu_alg);
|
||||||
|
|
||||||
XML::Node::Element const* steps_list = nullptr;
|
Vector<XML::Node const*> steps_list;
|
||||||
for (auto const& child : node->as_element().children) {
|
for (auto const& child : element->as_element().children) {
|
||||||
TRY(child->content.visit(
|
child->content.visit(
|
||||||
[&](XML::Node::Element const& element) -> ParseErrorOr<void> {
|
[&](XML::Node::Element const& element) {
|
||||||
if (element.name == tag_ol) {
|
if (element.name == tag_ol) {
|
||||||
if (steps_list != nullptr)
|
steps_list.append(child);
|
||||||
return ParseError::create("<emu-alg> should have exactly one <ol> child"sv, child);
|
return;
|
||||||
steps_list = &element;
|
|
||||||
return {};
|
|
||||||
} else {
|
|
||||||
return ParseError::create("<emu-alg> should not have children other than <ol>"sv, child);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[&](XML::Node::Text const&) -> ParseErrorOr<void> {
|
|
||||||
if (!contains_empty_text(child))
|
|
||||||
return ParseError::create("<emu-alg> should not have non-empty child text nodes"sv, child);
|
|
||||||
return {};
|
|
||||||
},
|
|
||||||
move(ignore_comments)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (steps_list == nullptr)
|
ctx.diag().error(ctx.location_from_xml_offset(child->offset),
|
||||||
return ParseError::create("<emu-alg> should have exactly one <ol> child"sv, node);
|
"<{}> should not be a child of <emu-alg>"sv, element.name);
|
||||||
|
},
|
||||||
|
[&](XML::Node::Text const&) {
|
||||||
|
if (!contains_empty_text(child)) {
|
||||||
|
ctx.diag().error(ctx.location_from_xml_offset(child->offset),
|
||||||
|
"non-empty text node should not be a child of <emu-alg>");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[&](auto const&) {});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (steps_list.size() != 1) {
|
||||||
|
ctx.diag().error(ctx.location_from_xml_offset(element->offset),
|
||||||
|
"<emu-alg> should have exactly one <ol> child"sv);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
auto steps_creation_result = AlgorithmStepList::create(steps_list[0]->as_element());
|
||||||
|
if (steps_creation_result.is_error()) {
|
||||||
|
// TODO: Integrate backtracing parser errors better
|
||||||
|
ctx.diag().error(ctx.location_from_xml_offset(steps_creation_result.error()->offset()),
|
||||||
|
"{}", steps_creation_result.error()->to_string());
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
Algorithm algorithm;
|
Algorithm algorithm;
|
||||||
algorithm.m_steps = TRY(AlgorithmStepList::create(*steps_list));
|
algorithm.m_steps = steps_creation_result.release_value();
|
||||||
algorithm.m_tree = algorithm.m_steps.m_expression;
|
algorithm.m_tree = algorithm.m_steps.m_expression;
|
||||||
|
|
||||||
return algorithm;
|
return algorithm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -278,21 +288,17 @@ bool SpecFunction::post_initialize(SpecificationParsingContext& ctx, XML::Node c
|
||||||
|
|
||||||
if (algorithm_nodes.size() != 1) {
|
if (algorithm_nodes.size() != 1) {
|
||||||
ctx.diag().error(ctx.location_from_xml_offset(element->offset),
|
ctx.diag().error(ctx.location_from_xml_offset(element->offset),
|
||||||
"<emu-clause> specifing function should have exactly one <emu-alg>"sv);
|
"<emu-clause> specifing function should have exactly one <emu-alg> child"sv);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto algorithm_creation_result = Algorithm::create(algorithm_nodes[0]);
|
auto maybe_algorithm = Algorithm::create(ctx, algorithm_nodes[0]);
|
||||||
if (algorithm_creation_result.is_error()) {
|
if (maybe_algorithm.has_value()) {
|
||||||
// TODO: Integrate backtracing parser errors better
|
m_algorithm = maybe_algorithm.release_value();
|
||||||
ctx.diag().error(ctx.location_from_xml_offset(algorithm_creation_result.error()->offset()),
|
|
||||||
"{}", algorithm_creation_result.error()->to_string());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_algorithm = algorithm_creation_result.release_value();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpecFunction::do_collect(TranslationUnitRef translation_unit)
|
void SpecFunction::do_collect(TranslationUnitRef translation_unit)
|
||||||
|
|
|
@ -63,7 +63,7 @@ public:
|
||||||
|
|
||||||
class Algorithm {
|
class Algorithm {
|
||||||
public:
|
public:
|
||||||
static ParseErrorOr<Algorithm> create(XML::Node const* node);
|
static Optional<Algorithm> create(SpecificationParsingContext& ctx, XML::Node const* element);
|
||||||
|
|
||||||
AlgorithmStepList m_steps;
|
AlgorithmStepList m_steps;
|
||||||
Tree m_tree = error_tree;
|
Tree m_tree = error_tree;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue