feat: update railroad diagrams with revised syntax

This commit is contained in:
2026-05-21 07:53:56 +02:00
parent db8fe5d3ff
commit 429d0d98fe

View File

@@ -1,4 +1,15 @@
#import "@preview/fervojo:0.1.1": render #import "@preview/fervojo:0.1.1": default-css, render
#let extra-css = ```css
svg.railroad .terminal rect {
fill: #F7DCD4;
}
```
#let css = default-css() + bytes(extra-css.text)
#let variable = ```
{[`variable` 'identifier'*"."]}
```
#let value = ``` #let value = ```
{[`value` < {[`value` <
@@ -8,90 +19,156 @@
>]} >]}
``` ```
#let constraint = ``` #let lambda-value = ```
{[`constraint` <"_", 'value'> <">", "<", ">=", "<=", "==", "!="> <"_", 'value'>]} {[`lambda-value` <"_", 'value', 'variable'>]}
``` ```
#let type-with-constraints = ``` #let lambda-operator = ```
{[`type-with-constraints` 'identifier' <!, ["+" "(" 'constraint' ")"] * !>]} {[`lambda-operator` <">", "<", ">=", "<=", "==", "!=">]}
```
#let lambda = ```
{[`lambda` 'lambda-value' ['lambda-operator' 'lambda-value']*!]}
```
#let simple-type = ```
{[`simple-type` 'identifier' <!, "?">]}
```
#let template = ```
{[`template` "[" 'simple-type' "]"]}
```
#let type = ```
{[`type` 'identifier' <!, 'template'> <!, "?">]}
```
#let constraint = ```
{[`constraint` <'identifier', 'lambda'>]}
```
#let wrapped-constraint = ```
{[`wrapped-constraint` <'constraint', ["(" 'constraint' ")"]>]}
```
#let constraints = ```
{[`constraints` 'wrapped-constraint'*"&"]}
``` ```
#let type-property = ``` #let type-property = ```
{[`type-property` 'identifier' ":" 'type-with-constraints']} {[`type-property` 'identifier' ":" 'type' <!, ["where" 'constraints']>]}
``` ```
#let type-body = ``` #let type-body = ```
{[`type-body` "{" <!, 'type-property'*!> "}"]} {[`type-body` "{" <!, 'type-property'*!> "}"]}
``` ```
#let operation-type = ```
{[`operation-type` "<" 'type-with-constraints' ">"]}
```
#let type-statement = ``` #let type-statement = ```
{[`type-statement` "type" 'identifier' "<" 'type-with-constraints'*"," ">" <!, 'type-body'>]} {[`type-statement` "type" 'identifier' <!, 'template'> <[["(" 'type' ")"] <!, ["where" 'constraints']>], 'type-body'>]}
``` ```
#let operation-statement = ``` #let op-definition = ```
{[`operation-statement` "op" 'operation-type' "operator" 'operation-type' "=" 'operation-type']} {[`op-definition` "op" <'identifier', ["__" 'identifier' "__"]> "(" 'type' ")" "->" 'type']}
``` ```
#let constraint-statement = ``` #let extend-statement = ```
{[`constraint-statement` "constraint" 'identifier' "=" 'constraint']} {[`extend-statement` "extend" 'type' "{" <!, 'op-definition'*!> "}"]}
```
#let predicate-statement = ```
{[`predicate-statement` "predicate" 'identifier' "(" 'identifier' ":" 'type' ")" "=" 'constraints']}
``` ```
#let statement = ``` #let statement = ```
{[`statement` <'type-statement', 'operation-statement', 'constraint-statement'>]} {[`statement` <'type-statement', 'extend-statement', 'predicate-statement'>]}
``` ```
#let rules = ( #let rules = (
value, variable: variable,
constraint, value: value,
type-with-constraints, lambda-value: lambda-value,
type-property, lambda-operator: lambda-operator,
type-body, lambda: lambda,
operation-type, simple-type: simple-type,
type-statement, template: template,
operation-statement, type: type,
constraint-statement, constraint: constraint,
statement, wrapped-constraint: wrapped-constraint,
constraints: constraints,
type-property: type-property,
type-body: type-body,
type-statement: type-statement,
op-definition: op-definition,
extend-statement: extend-statement,
predicate-statement: predicate-statement,
statement: statement,
)
#let inline = (
"value",
"variable",
"lambda-operator",
"template",
"lambda",
"simple-type",
"wrapped-constraint",
"type-property",
"type-body",
"op-definition",
"type-statement",
"extend-statement",
"predicate-statement",
) )
#set text(font: "Source Sans 3") #set text(font: "Source Sans 3")
= Midas type definition syntax #title[Midas type definition syntax]
#for rule in rules { = Outline
render(rule)
}
/* #box(
#let by-name = ( columns(
value: value, 2,
constraint: constraint, outline(title: none),
type-with-constraints: type-with-constraints, ),
type-property: type-property, height: 8cm,
type-body: type-body, stroke: 1pt,
operation-type: operation-type, inset: 1em,
type-statement: type-statement,
operation-statement: operation-statement,
constraint-statement: constraint-statement,
) )
= Statements and expressions
#for (name, rule) in rules.pairs().rev() {
[== #name]
render(rule, css: css)
}
#let substitute(base-rule) = { #let substitute(base-rule) = {
let new-rule = base-rule let new-rule = base-rule
for (key, rule) in by-name.pairs() { for name in inline {
new-rule = new-rule.replace("'" + key + "'", rule.text.slice(1, -1)) let rule = rules.at(name)
let replacement = rule.text.slice(1, -1).replace(regex("\[`.*?`"), "[")
replacement = "[" + replacement + "#`" + name + "`]"
new-rule = new-rule.replace(
"'" + name + "'",
replacement,
)
} }
if new-rule != base-rule { if new-rule != base-rule {
new-rule = substitute(new-rule) new-rule = substitute(new-rule)
} }
return new-rule.replace(regex("`.*?`"), "") return new-rule
} }
#let combined = raw(substitute(statement.text))
#set page(flipped: true) #set page(flipped: true)
#render(combined)
*/ = Combined rules
#for (name, rule) in rules.pairs() {
if not name in inline {
[== #name]
let combined = substitute(rule.text)
render(raw(combined), css: css)
//raw(block: true, combined)
}
}