Skip to content

Let formats #367

@brendanzab

Description

@brendanzab

In the OpenType we sometimes have to employ records as a way to store intermediate values during parsing. For example:

htmx <- required_table "hmtx" {
    hhea <- deref _ hhea.link,
    maxp <- deref _ maxp.link,
    table <- htmx_table
        hhea.number_of_long_horizontal_metrics
        maxp.num_glyphs,
},

This is not ideal as this results in a copy of hhea and maxp appearing in the resulting data structures after parsing. For example:

4752 = [
    {
        hhea = {
            major_version = 1,
            ⋮
            number_of_long_horizontal_metrics = 1,
        },
        maxp = { version = 20480, num_glyphs = 100 },
        table = {
            h_metrics = [ { advance_width = 1500, left_side_bearing = 300 } ],
        },
    },
]

It would be nice however to be able to write something like:

htmx <- required_table "hmtx" (
    let hhea <- deref _ hhea.link;
    let maxp <- deref _ maxp.link;
    htmx_table
        hhea.number_of_long_horizontal_metrics
        maxp.num_glyphs,
),

This would employ a new format of the form: let x <- f₁; f₂, which allows a format to be parsed, with the result added to the environment, and then a subsequent format will be parsed in that environment. This would result in a data structure that looks something like:

4752 = [
    {
        h_metrics = [ { advance_width = 1500, left_side_bearing = 300 } ],
    },
]

This also has the tantalizing possibility of being further improved to look something like:

htmx <- required_table "hmtx" (
    htmx_table
        (deref _ hhea.link).number_of_long_horizontal_metrics
        (deref _ maxp.link).num_glyphs,
),

Rough Specification

The typing and parsing rules for this format could look something like:

  f₁ : Format     x : Repr f₁ ⊢ f₂ : Format
──────────────────────────────────────────────
           let x <- f₁; f₂ : Format


  s .. s' : f₁ ⟹ e₁   x : Repr f = e₁ ⊢ s' .. s'' : f₁ ⟹ e₂
────────────────────────────────────────────────────────────────
          s .. s'' : (let x <- f₁; f₂) ⟹ e₂

Alas, difficulty arises when attempting to define a host representation for this format.

Repr (let x <- f₁; f₂ x) = Repr (f₂ x)
                                    ^ where is `x : Repr f₁` bound?

I'm not sure yet how to resolve this.

I also have suspicions that this could also make a implementing a dual binary semantics more challenging, but we’ll likely also struggle with this for link and deref types.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions