Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Let formats #367

Open
brendanzab opened this issue Jun 7, 2022 · 2 comments
Open

Let formats #367

brendanzab opened this issue Jun 7, 2022 · 2 comments

Comments

@brendanzab
Copy link
Member

brendanzab commented Jun 7, 2022

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.

@Kmeakin
Copy link
Contributor

Kmeakin commented Nov 10, 2022

Fixed by #371?

@brendanzab
Copy link
Member Author

brendanzab commented Nov 10, 2022

No, this is a bit different… here we bind the result of some parsed data but then don’t add a corresponding field in the representation type. I’m not sure if that really makes sense or is a good idea or not! The computed fields in #371 allow you to add a constant in the middle of a record format and do show up in the representation type. I realise this is confusing though (and the confusion might show there’s an issue with the design).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants