Skip to content

Commit

Permalink
Proof-of-concept size-based synchronization at top-level.
Browse files Browse the repository at this point in the history
This aims to address a situation like this:

    type Chunks = unit {
        chunks: (Chunk &synchronize)[];
    };

    type Chunk = unit {
        content_size: bytes &until=b"\n" &convert=$$.to_uint();
        content: bytes &size=self.content_size;
    };

If an error happens while parsing `content` (e.g., a gap in the
input), the top-level `chunks` should be able to just move on the
subsequent chunk because it's clear where that start (namely after
`contents_size` bytes).

This proof-of-concept implementation makes this example work, but
isn't very pretty nor tested in detail; and other tests fail
currently. Need to clean up and re-assess.
  • Loading branch information
rsmmr committed Dec 20, 2024
1 parent 6c277fc commit a13eb04
Show file tree
Hide file tree
Showing 6 changed files with 310 additions and 102 deletions.
3 changes: 2 additions & 1 deletion hilti/toolchain/include/ast/ctors/optional.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ class Optional : public Ctor {
static auto create(ASTContext* ctx, QualifiedType* type, const Meta& meta = {}) {
return ctx->make<Optional>(ctx,
{
QualifiedType::create(ctx, type::Optional::create(ctx, type), Constness::Const),
QualifiedType::create(ctx, type::Optional::create(ctx, type),
Constness::Mutable),
nullptr,
},
meta);
Expand Down
4 changes: 3 additions & 1 deletion hilti/toolchain/src/compiler/coercer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -853,7 +853,9 @@ Result<std::pair<bool, Expressions>> hilti::coerceOperands(Builder* builder, ope
switch ( op->kind() ) {
case parameter::Kind::In:
case parameter::Kind::Copy: needs_mutable = false; break;
case parameter::Kind::InOut: needs_mutable = true; break;
case parameter::Kind::InOut:
needs_mutable = false;
break; // TODO: should be true, but doesn't work with optional inputs
case parameter::Kind::Unknown: logger().internalError("unknown operand kind"); break;
}

Expand Down
13 changes: 13 additions & 0 deletions spicy/toolchain/include/compiler/detail/codegen/parser-builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,19 @@ struct ParserState {
* Expression* holding the last parse error if any. This field is set only in sync or trial mode.
*/
Expression* error = nullptr;

/**
* If set, expression referencing an optional iterator to set while parsing a
* production as soon as parsing knows the end of the bytes data the
* production will consume. Once this is set, upper-level error recovery
* might use that information to jump there for continuing parsing.
*
* To work with this, before a production starts parsing, it needs to call
* ParserBuilder::setEndOfProduction(), either with a specific iterator
* where the production will end parsing, or with a null value to indicate
* that it cannot know.
*/
Expression* end_of_production = nullptr;
};

/** Generates the parsing logic for a unit type. */
Expand Down
Loading

0 comments on commit a13eb04

Please sign in to comment.