diff --git a/spicy/lib/spicy_rt.hlt b/spicy/lib/spicy_rt.hlt index 8e6fad50b2..e284f94109 100644 --- a/spicy/lib/spicy_rt.hlt +++ b/spicy/lib/spicy_rt.hlt @@ -94,6 +94,6 @@ declare public void backtrack() &cxxname="spicy::rt::detail::backtrack" &have_pr declare public void initializeParsedUnit(inout ParsedUnit punit, any unit, TypeInfo ti) &cxxname="spicy::rt::ParsedUnit::initialize" &have_prototype; declare public bytes extractBytes(inout value_ref data, view cur, uint<64> n, bool eod_ok, string location, inout strong_ref filters) &cxxname="spicy::rt::detail::extractBytes" &have_prototype; -declare public void expectBytesLiteral(inout value_ref data, view cur, bytes literal, string location, inout strong_ref filters) &cxxname="spicy::rt::detail::expectBytesLiteral" &have_prototype; +declare public bytes expectBytesLiteral(inout value_ref data, view cur, bytes literal, string location, inout strong_ref filters) &cxxname="spicy::rt::detail::expectBytesLiteral" &have_prototype; } diff --git a/spicy/runtime/include/parser.h b/spicy/runtime/include/parser.h index 08da2bdd22..0c04d0cc07 100644 --- a/spicy/runtime/include/parser.h +++ b/spicy/runtime/include/parser.h @@ -553,11 +553,13 @@ hilti::rt::Bytes extractBytes(hilti::rt::ValueReference& data * @param literal raw bytes representation of the literal to extract * @param location location associated with the situation * @param filters filter state associated with current unit instance (which may be null) + * @returns `literal` (for convenience) * @throws ParseError if the literal isn't found at the beginning of *cur* */ -void expectBytesLiteral(hilti::rt::ValueReference& data, const hilti::rt::stream::View& cur, - const hilti::rt::Bytes& literal, std::string_view location, - const hilti::rt::StrongReference& filters); +hilti::rt::Bytes expectBytesLiteral(hilti::rt::ValueReference& data, + const hilti::rt::stream::View& cur, hilti::rt::Bytes literal, + std::string_view location, + const hilti::rt::StrongReference& filters); } // namespace detail } // namespace spicy::rt diff --git a/spicy/runtime/src/parser.cc b/spicy/runtime/src/parser.cc index 4ed3b8d802..b62e33c661 100644 --- a/spicy/runtime/src/parser.cc +++ b/spicy/runtime/src/parser.cc @@ -200,9 +200,9 @@ hilti::rt::Bytes detail::extractBytes(hilti::rt::ValueReference& data, const hilti::rt::stream::View& cur, - const hilti::rt::Bytes& literal, std::string_view location, - const hilti::rt::StrongReference& filters) { +hilti::rt::Bytes detail::expectBytesLiteral( + hilti::rt::ValueReference& data, const hilti::rt::stream::View& cur, hilti::rt::Bytes literal, + std::string_view location, const hilti::rt::StrongReference& filters) { detail::waitForInput(data, cur, literal.size(), hilti::rt::fmt("expected %" PRIu64 R"( bytes for bytes literal "%s")", literal.size(), literal), @@ -212,4 +212,6 @@ void detail::expectBytesLiteral(hilti::rt::ValueReference& da throw ParseError(hilti::rt::fmt(R"(expected bytes literal "%s" but input starts with "%s")", literal, content), location); } + + return literal; } diff --git a/spicy/runtime/src/tests/parser.cc b/spicy/runtime/src/tests/parser.cc index 2598c8cf1d..87723a6b67 100644 --- a/spicy/runtime/src/tests/parser.cc +++ b/spicy/runtime/src/tests/parser.cc @@ -454,7 +454,7 @@ TEST_CASE("expectBytesLiteral") { data->freeze(); auto view = data->view(); - CHECK_NOTHROW(detail::expectBytesLiteral(data, data->view(), "123"_b, "", {})); + CHECK_EQ(detail::expectBytesLiteral(data, data->view(), "123"_b, "", {}), "123"_b); CHECK_THROWS_WITH_AS(detail::expectBytesLiteral(data, data->view(), "abc"_b, "", {}), "expected bytes literal \"abc\" but input starts with \"123\" ()", const spicy::rt::ParseError&); diff --git a/spicy/toolchain/src/compiler/codegen/parsers/literals.cc b/spicy/toolchain/src/compiler/codegen/parsers/literals.cc index 06676ffe80..f251467c53 100644 --- a/spicy/toolchain/src/compiler/codegen/parsers/literals.cc +++ b/spicy/toolchain/src/compiler/codegen/parsers/literals.cc @@ -89,32 +89,39 @@ struct Visitor : public visitor::PreOrder { pb()->parseError("unexpected token to consume", n->meta()); popBuilder(); - pushBuilder( - builder()->addIf(builder()->unequal(builder()->expression(n), - builder()->memberCall(state().cur, "sub", - {builder()->begin(state().cur), - state().lahead_end})))); + auto literal = builder()->addTmp("literal", builder()->expression(n)); + + pushBuilder(builder()->addIf( + builder()->unequal(literal, builder()->memberCall(state().cur, "sub", + {builder()->begin(state().cur), + state().lahead_end})))); pb()->parseError("unexpected data when consuming token", n->meta()); popBuilder(); + builder()->addAssign(lp->destination(n->type()->type()), literal); + pb()->consumeLookAhead(); popBuilder(); pushBuilder(no_lah); } - builder()->addCall("spicy_rt::expectBytesLiteral", - {state().data, state().cur, builder()->expression(n), - builder()->expression(n->meta()), pb()->currentFilters(state())}); + auto expect_bytes_literal = + builder()->call("spicy_rt::expectBytesLiteral", + {state().data, state().cur, builder()->expression(n), + builder()->expression(n->meta()), pb()->currentFilters(state())}); + + + if ( state().literal_mode != LiteralMode::Skip ) + builder()->addAssign(lp->destination(n->type()->type()), expect_bytes_literal); + else + builder()->addExpression(expect_bytes_literal); pb()->advanceInput(len); if ( check_for_look_ahead ) popBuilder(); - if ( state().literal_mode != LiteralMode::Skip ) - builder()->addAssign(lp->destination(n->type()->type()), builder()->expression(n)); - result = builder()->expression(n); return; } diff --git a/tests/Baseline/spicy.types.function.cxxname-normalization/output b/tests/Baseline/spicy.types.function.cxxname-normalization/output index c16489a77d..24c3518816 100644 --- a/tests/Baseline/spicy.types.function.cxxname-normalization/output +++ b/tests/Baseline/spicy.types.function.cxxname-normalization/output @@ -59,7 +59,7 @@ [debug/resolver] [spicy_rt.hlt:92:33-92:71] Attribute "&cxxname="spicy::rt::detail::backtrack"" -> Attribute "&cxxname="::spicy::rt::detail::backtrack"" [debug/resolver] [spicy_rt.hlt:94:89-94:132] Attribute "&cxxname="spicy::rt::ParsedUnit::initialize"" -> Attribute "&cxxname="::spicy::rt::ParsedUnit::initialize"" [debug/resolver] [spicy_rt.hlt:96:160-96:201] Attribute "&cxxname="spicy::rt::detail::extractBytes"" -> Attribute "&cxxname="::spicy::rt::detail::extractBytes"" -[debug/resolver] [spicy_rt.hlt:97:155-97:202] Attribute "&cxxname="spicy::rt::detail::expectBytesLiteral"" -> Attribute "&cxxname="::spicy::rt::detail::expectBytesLiteral"" +[debug/resolver] [spicy_rt.hlt:97:156-97:203] Attribute "&cxxname="spicy::rt::detail::expectBytesLiteral"" -> Attribute "&cxxname="::spicy::rt::detail::expectBytesLiteral"" [debug/resolver] [spicy.spicy:14:3-14:37] Attribute "&cxxname="hilti::rt::AddressFamily"" -> Attribute "&cxxname="::hilti::rt::AddressFamily"" [debug/resolver] [spicy.spicy:23:3-23:41] Attribute "&cxxname="hilti::rt::integer::BitOrder"" -> Attribute "&cxxname="::hilti::rt::integer::BitOrder"" [debug/resolver] [spicy.spicy:31:3-31:33] Attribute "&cxxname="hilti::rt::ByteOrder"" -> Attribute "&cxxname="::hilti::rt::ByteOrder"" diff --git a/tests/Baseline/spicy.types.unit.hooks-across-imports/.stderr b/tests/Baseline/spicy.types.unit.hooks-across-imports/.stderr index 18f4f68c73..b6449fe52b 100644 --- a/tests/Baseline/spicy.types.unit.hooks-across-imports/.stderr +++ b/tests/Baseline/spicy.types.unit.hooks-across-imports/.stderr @@ -1,55 +1,55 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. -[debug/ast-stats] garbage collected 1098 nodes in 12 rounds, 8159 left retained -[debug/ast-stats] garbage collected 479 nodes in 11 rounds, 9404 left retained -[debug/ast-stats] garbage collected 170 nodes in 6 rounds, 9807 left retained -[debug/ast-stats] garbage collected 78 nodes in 3 rounds, 9807 left retained -[debug/ast-stats] garbage collected 78 nodes in 3 rounds, 9807 left retained +[debug/ast-stats] garbage collected 1098 nodes in 12 rounds, 8163 left retained +[debug/ast-stats] garbage collected 479 nodes in 11 rounds, 9412 left retained +[debug/ast-stats] garbage collected 170 nodes in 6 rounds, 9815 left retained +[debug/ast-stats] garbage collected 78 nodes in 3 rounds, 9815 left retained +[debug/ast-stats] garbage collected 78 nodes in 3 rounds, 9815 left retained [debug/ast-stats] # [Spicy] AST statistics: [debug/ast-stats] - # AST rounds 5 [debug/ast-stats] - max tree depth: 16 [debug/ast-stats] - # context declarations: 67 [debug/ast-stats] - # context types: 47 [debug/ast-stats] - # context modules: 5 -[debug/ast-stats] - # nodes reachable in AST: 3201 -[debug/ast-stats] - # nodes live: 9807 -[debug/ast-stats] - # nodes retained: 9807 +[debug/ast-stats] - # nodes reachable in AST: 3205 +[debug/ast-stats] - # nodes live: 9815 +[debug/ast-stats] - # nodes retained: 9815 [debug/ast-stats] - # nodes live > 1%: [debug/ast-stats] - Attribute: 171 [debug/ast-stats] - AttributeSet: 341 -[debug/ast-stats] - QualifiedType: 3318 +[debug/ast-stats] - QualifiedType: 3322 [debug/ast-stats] - ctor::String: 120 [debug/ast-stats] - declaration::Parameter: 138 [debug/ast-stats] - expression::Ctor: 209 [debug/ast-stats] - type::Bool: 157 -[debug/ast-stats] - type::Bytes: 151 +[debug/ast-stats] - type::Bytes: 153 [debug/ast-stats] - type::Function: 134 [debug/ast-stats] - type::Member: 175 [debug/ast-stats] - type::OperandList: 670 [debug/ast-stats] - type::String: 215 [debug/ast-stats] - type::Unknown: 157 -[debug/ast-stats] - type::UnsignedInteger: 533 -[debug/ast-stats] - type::Void: 116 -[debug/ast-stats] - type::bytes::Iterator: 179 +[debug/ast-stats] - type::UnsignedInteger: 535 +[debug/ast-stats] - type::Void: 114 +[debug/ast-stats] - type::bytes::Iterator: 181 [debug/ast-stats] - type::operand_list::Operand: 1257 [debug/ast-stats] - type::stream::Iterator: 141 -[debug/ast-stats] garbage collected 8966 nodes in 14 rounds, 21095 left retained -[debug/ast-stats] garbage collected 2310 nodes in 16 rounds, 24911 left retained -[debug/ast-stats] garbage collected 2346 nodes in 8 rounds, 26329 left retained -[debug/ast-stats] garbage collected 4594 nodes in 11 rounds, 27547 left retained -[debug/ast-stats] garbage collected 412 nodes in 3 rounds, 27547 left retained +[debug/ast-stats] garbage collected 8966 nodes in 14 rounds, 21103 left retained +[debug/ast-stats] garbage collected 2310 nodes in 16 rounds, 24919 left retained +[debug/ast-stats] garbage collected 2346 nodes in 8 rounds, 26337 left retained +[debug/ast-stats] garbage collected 4594 nodes in 11 rounds, 27555 left retained +[debug/ast-stats] garbage collected 412 nodes in 3 rounds, 27555 left retained [debug/ast-stats] # [HILTI] AST statistics: [debug/ast-stats] - # AST rounds 5 [debug/ast-stats] - max tree depth: 27 [debug/ast-stats] - # context declarations: 254 [debug/ast-stats] - # context types: 55 [debug/ast-stats] - # context modules: 8 -[debug/ast-stats] - # nodes reachable in AST: 18587 -[debug/ast-stats] - # nodes live: 27547 -[debug/ast-stats] - # nodes retained: 27547 +[debug/ast-stats] - # nodes reachable in AST: 18591 +[debug/ast-stats] - # nodes live: 27555 +[debug/ast-stats] - # nodes retained: 27555 [debug/ast-stats] - # nodes live > 1%: [debug/ast-stats] - Attribute: 301 [debug/ast-stats] - AttributeSet: 765 -[debug/ast-stats] - QualifiedType: 9116 +[debug/ast-stats] - QualifiedType: 9120 [debug/ast-stats] - declaration::Parameter: 399 [debug/ast-stats] - expression::Ctor: 770 [debug/ast-stats] - expression::Member: 314 @@ -61,10 +61,10 @@ [debug/ast-stats] - type::Optional: 465 [debug/ast-stats] - type::String: 441 [debug/ast-stats] - type::Tuple: 324 -[debug/ast-stats] - type::UnsignedInteger: 1695 +[debug/ast-stats] - type::UnsignedInteger: 1697 [debug/ast-stats] - type::operand_list::Operand: 1557 [debug/ast-stats] - type::stream::Iterator: 1016 [debug/ast-stats] - type::stream::View: 550 [debug/ast-stats] - type::tuple::Element: 673 -[debug/ast-stats] garbage collected 32191 nodes in 18 rounds, 0 left retained +[debug/ast-stats] garbage collected 32199 nodes in 18 rounds, 0 left retained [debug/ast-stats] garbage collected 0 nodes in 1 round, 0 left retained diff --git a/tests/Baseline/spicy.types.unit.sub-unit/.stderr b/tests/Baseline/spicy.types.unit.sub-unit/.stderr index 064693d479..774a1eb5b0 100644 --- a/tests/Baseline/spicy.types.unit.sub-unit/.stderr +++ b/tests/Baseline/spicy.types.unit.sub-unit/.stderr @@ -1,54 +1,54 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. -[debug/ast-stats] garbage collected 1086 nodes in 12 rounds, 7903 left retained -[debug/ast-stats] garbage collected 282 nodes in 11 rounds, 9057 left retained -[debug/ast-stats] garbage collected 70 nodes in 2 rounds, 9413 left retained -[debug/ast-stats] garbage collected 70 nodes in 2 rounds, 9413 left retained +[debug/ast-stats] garbage collected 1086 nodes in 12 rounds, 7907 left retained +[debug/ast-stats] garbage collected 282 nodes in 11 rounds, 9065 left retained +[debug/ast-stats] garbage collected 70 nodes in 2 rounds, 9421 left retained +[debug/ast-stats] garbage collected 70 nodes in 2 rounds, 9421 left retained [debug/ast-stats] # [Spicy] AST statistics: [debug/ast-stats] - # AST rounds 4 [debug/ast-stats] - max tree depth: 16 [debug/ast-stats] - # context declarations: 60 [debug/ast-stats] - # context types: 43 [debug/ast-stats] - # context modules: 4 -[debug/ast-stats] - # nodes reachable in AST: 2805 -[debug/ast-stats] - # nodes live: 9413 -[debug/ast-stats] - # nodes retained: 9413 +[debug/ast-stats] - # nodes reachable in AST: 2809 +[debug/ast-stats] - # nodes live: 9421 +[debug/ast-stats] - # nodes retained: 9421 [debug/ast-stats] - # nodes live > 1%: [debug/ast-stats] - Attribute: 166 [debug/ast-stats] - AttributeSet: 317 -[debug/ast-stats] - QualifiedType: 3188 +[debug/ast-stats] - QualifiedType: 3192 [debug/ast-stats] - ctor::String: 112 [debug/ast-stats] - declaration::Parameter: 138 [debug/ast-stats] - expression::Ctor: 196 [debug/ast-stats] - type::Bool: 157 -[debug/ast-stats] - type::Bytes: 120 +[debug/ast-stats] - type::Bytes: 122 [debug/ast-stats] - type::Function: 127 [debug/ast-stats] - type::Member: 167 [debug/ast-stats] - type::OperandList: 670 [debug/ast-stats] - type::String: 207 [debug/ast-stats] - type::Unknown: 157 -[debug/ast-stats] - type::UnsignedInteger: 508 -[debug/ast-stats] - type::Void: 109 -[debug/ast-stats] - type::bytes::Iterator: 148 +[debug/ast-stats] - type::UnsignedInteger: 510 +[debug/ast-stats] - type::Void: 107 +[debug/ast-stats] - type::bytes::Iterator: 150 [debug/ast-stats] - type::operand_list::Operand: 1257 [debug/ast-stats] - type::stream::Iterator: 141 -[debug/ast-stats] garbage collected 5080 nodes in 12 rounds, 17788 left retained -[debug/ast-stats] garbage collected 2884 nodes in 16 rounds, 20614 left retained -[debug/ast-stats] garbage collected 1582 nodes in 8 rounds, 21511 left retained -[debug/ast-stats] garbage collected 3397 nodes in 11 rounds, 22304 left retained -[debug/ast-stats] garbage collected 286 nodes in 3 rounds, 22304 left retained +[debug/ast-stats] garbage collected 5080 nodes in 12 rounds, 17796 left retained +[debug/ast-stats] garbage collected 2884 nodes in 16 rounds, 20622 left retained +[debug/ast-stats] garbage collected 1582 nodes in 8 rounds, 21519 left retained +[debug/ast-stats] garbage collected 3397 nodes in 11 rounds, 22312 left retained +[debug/ast-stats] garbage collected 286 nodes in 3 rounds, 22312 left retained [debug/ast-stats] # [HILTI] AST statistics: [debug/ast-stats] - # AST rounds 5 [debug/ast-stats] - max tree depth: 27 [debug/ast-stats] - # context declarations: 189 [debug/ast-stats] - # context types: 49 [debug/ast-stats] - # context modules: 6 -[debug/ast-stats] - # nodes reachable in AST: 14254 -[debug/ast-stats] - # nodes live: 22304 -[debug/ast-stats] - # nodes retained: 22304 +[debug/ast-stats] - # nodes reachable in AST: 14258 +[debug/ast-stats] - # nodes live: 22312 +[debug/ast-stats] - # nodes retained: 22312 [debug/ast-stats] - # nodes live > 1%: [debug/ast-stats] - Attribute: 251 [debug/ast-stats] - AttributeSet: 593 -[debug/ast-stats] - QualifiedType: 7347 +[debug/ast-stats] - QualifiedType: 7351 [debug/ast-stats] - ctor::String: 290 [debug/ast-stats] - declaration::Parameter: 307 [debug/ast-stats] - expression::Ctor: 695 @@ -60,11 +60,11 @@ [debug/ast-stats] - type::Optional: 339 [debug/ast-stats] - type::String: 536 [debug/ast-stats] - type::Tuple: 269 -[debug/ast-stats] - type::UnsignedInteger: 1290 -[debug/ast-stats] - type::Void: 253 +[debug/ast-stats] - type::UnsignedInteger: 1292 +[debug/ast-stats] - type::Void: 251 [debug/ast-stats] - type::operand_list::Operand: 1451 [debug/ast-stats] - type::stream::Iterator: 763 [debug/ast-stats] - type::stream::View: 417 [debug/ast-stats] - type::tuple::Element: 600 -[debug/ast-stats] garbage collected 23630 nodes in 18 rounds, 0 left retained +[debug/ast-stats] garbage collected 23638 nodes in 18 rounds, 0 left retained [debug/ast-stats] garbage collected 0 nodes in 1 round, 0 left retained diff --git a/tests/spicy/types/bytes/parse-length.spicy b/tests/spicy/types/bytes/parse-length.spicy index 3e67259933..dec9668aa4 100644 --- a/tests/spicy/types/bytes/parse-length.spicy +++ b/tests/spicy/types/bytes/parse-length.spicy @@ -5,7 +5,7 @@ # @TEST-EXEC: spicyc -p %INPUT | grep -q 'b2 = spicy_rt::extractBytes' # # Ensure literal-specific optimization kicks in. -# @TEST-EXEC: spicyc -p %INPUT | grep -q '^ *spicy_rt::expectBytesLiteral' +# @TEST-EXEC: spicyc -p %INPUT | grep -q ' = spicy_rt::expectBytesLiteral' # # Ensure we don't get any look-ahead checks when parsing the literals, we don't need them here. # @TEST-EXEC: spicyc -p %INPUT | grep -vq 'if.*lah'