Use records instead of dictionaries

This commit is contained in:
Tony Garnock-Jones 2023-11-01 11:57:23 +01:00
parent ae7555f6f3
commit 9ae16b4561
1 changed files with 34 additions and 42 deletions

View File

@ -3,7 +3,7 @@ title: "P-expressions"
---
Tony Garnock-Jones <tonyg@leastfixedpoint.com>
October 2023. Version 0.1.2.
October 2023. Version 0.2.0.
This document defines a grammar called *Preserves Expressions*
(*P-expressions*, *pexprs*) that includes [ordinary Preserves text
@ -105,35 +105,27 @@ We write ⌜*p*⌝ for the encoding into Preserves of P-expression *p*.
| ⌜·⌝ : **P-expression** | ⟶ | **Preserves** |
Aside from `Group`, `Block`, `Comma`, `Semicolon`, `Colons`, `Trailer`,
and empty `Record`, P-expressions are encoded directly as Preserves
data.
and `Record`, P-expressions are encoded directly as Preserves data.
{:.pseudocode.equations}
| ⌜`[`*p* ...`]`⌝ | = | `[`⌜*p*⌝ ...`]` |
| ⌜`<`*p* ...`>`⌝ | = | `<`⌜*p*⌝ ...`>` |
| ⌜`#{`*p* ...`}`⌝ | = | `#{`⌜*p*⌝ ...`}` |
| ⌜`#!`*p*⌝ | = | `#!`⌜*p*⌝ |
| ⌜`@`*p* *q*⌝ | = | `@`⌜*p*⌝ ⌜*q*⌝ |
| ⌜*p*⌝ | = | *p* when *p***Atom** |
Everything else is encoded as Preserves
dictionaries.[^encoding-rationale]
[^encoding-rationale]: In principle, it would be nice to use *records*
for this purpose, but if we did so we would have to also encode
usages of records!
Everything else is encoded as Preserves records.
{:.pseudocode.equations}
| ⌜`<>`⌝ | = | `{r:[]}` |
| ⌜`(`*p* ...`)`⌝ | = | `{g:[`⌜*p*⌝ ...`]}` |
| ⌜`{`*p* ...`}`⌝ | = | `{b:[`⌜*p*⌝ ...`]}` |
| ⌜`,`⌝ | = | `{s:|,|}` |
| ⌜`;`⌝ | = | `{s:|;|}` |
| ⌜`:` ...⌝ | = | `{s:|:` ...`|}` |
| ⌜*t*⌝ | = | ⌜*a*⌝ ... `{}`, where *a* ... are the annotations in *t* and *t***Trailer** |
| ⌜`<`*p* ...`>`⌝ | = | `<r` ⌜*p*⌝ ...`>` |
| ⌜`(`*p* ...`)`⌝ | = | `<g` ⌜*p*⌝ ...`>` |
| ⌜`{`*p* ...`}`⌝ | = | `<b` ⌜*p*⌝ ...`>` |
| ⌜`,`⌝ | = | `<s |,|>` |
| ⌜`;`⌝ | = | `<s |;|>` |
| ⌜`:` ...⌝ | = | `<s |:` ...`|>` |
| ⌜*t*⌝ | = | ⌜*a*⌝ ... `<a>`, where *a* ... are the annotations in *t* and *t***Trailer** |
The empty dictionary `{}` acts as an anchor for the annotations in a
`Trailer`.
The record `<a>` acts as an anchor for the annotations in a `Trailer`.
We overload the ⌜·⌝ notation for encoding whole `Document`s into
sequences of Preserves values.
@ -179,25 +171,25 @@ text-syntax encodings.
```preserves
<date 1821 (lookup-month "February") 3>
= <date 1821 {g:[lookup-month "February"]} 3>
= <r date 1821 <g lookup-month "February"> 3>
```
```preserves
<>⌝
= {r:[]}
= <r>
```
```preserves
⌜(begin (println! (+ 1 2)) (+ 3 4))⌝
= {g:[begin {g:[println! {g:[+ 1 2]}]} {g:[+ 3 4]}]}
= <g begin <g println! <g + 1 2>> <g + 3 4>>
```
```preserves
⌜()⌝
= {g:[]}
= <g>
⌜[() () ()]⌝
= [{g:[]}, {g:[]}, {g:[]}]
= [<g>, <g>, <g>]
```
```preserves
@ -209,20 +201,20 @@ text-syntax encodings.
}
tearDown();
}⌝
= {b:[
setUp {g:[]} {s:|;|}
= <b
setUp <g> <s |;|>
# Now enter the loop
loop {s:|:|} {b:[
greet {g:["World"]} {s:|;|}
]}
tearDown {g:[]} {s:|;|}
]}
loop <s |:|> <b
greet <g "World"> <s |;|>
>
tearDown <g> <s |;|>
>
```
```preserves
⌜[1 + 2.0, print "Hello", predicate: #t, foo, #!remote, bar]⌝
= [1 + 2.0 {s:|,|} print "Hello" {s:|,|} predicate {s:|:|} #t {s:|,|}
foo {s:|,|} #!remote {s:|,|} bar]
= [1 + 2.0 <s |,|> print "Hello" <s |,|> predicate <s |:|> #t <s |,|>
foo <s |,|> #!remote <s |,|> bar]
```
```preserves
@ -230,10 +222,10 @@ text-syntax encodings.
optional name: string,
address: Address,
}⌝
= {b:[
optional name {s:|:|} string {s:|,|}
address {s:|:|} Address {s:|,|}
]}
= <b
optional name <s |:|> string <s |,|>
address <s |:|> Address <s |,|>
>
```
### Whole `Document`s
@ -244,12 +236,12 @@ text-syntax encodings.
# example of a comment at the end of a dictionary
}
# example of a comment at the end of the input file⌝
= [ {b:[
key {s:|:|} value
@"example of a comment at the end of a dictionary" {}
]}
= [ <b
key <s |:|> value
@"example of a comment at the end of a dictionary" <a>
>
@"example of a comment at the end of the input file"
{}
<a>
]
```