docs(design): actually write some content

This commit is contained in:
multisn8 2024-01-09 10:21:57 +01:00
parent 43e6dfd240
commit 1faa6f6d29
Signed by: multisamplednight
GPG key ID: C81EF9B053977241
3 changed files with 204 additions and 11 deletions

View file

@ -67,10 +67,7 @@
nodes(
[Source],
[Graph IR],
[Optimizer],
[Compiler],
[VM Bytecode],
[VM],
[Runtime],
)
})

View file

@ -2,15 +2,81 @@
#import "graphics.typ"
#show: conf.with(title: [iOwO design], subtitle: [don't worry, we're just dreaming])
#show ">": graphics.arrow()
// highlight important terms in bold
#let expand(it) = {
("("
+ upper(it.first())
+ "|"
+ it.first()
+ ")"
+ it.clusters().slice(1).join()
+ "s?")
}
#let singlify(it) = {
it = lower(it)
if it.ends-with("s") {
it = it.slice(0, -1)
}
it
}
#let terminate-recursion(it) = {
let clusters = it.text.clusters()
clusters.insert(1, "\u{FEFF}")
clusters.join()
}
// TODO: could make this just look over headings in section "Execution stages" tbh
#let terms = (
"source",
"graph IR",
"runtime",
"optimizer",
"scheduler",
"VM",
"command",
"pipeline",
"input", "argument", "consumer",
"output", "streamer",
"modifier",
)
#let terms-trigger = regex(terms.map(expand).join("|"))
#show raw: it => {
// avoid making terms in codeblocks bold
show terms-trigger: terminate-recursion
it
}
#show terms-trigger: strong
// color codeblocks
// haskell hl seems to work ok for this
#show raw.where(lang: "iowo", block: true): it => {
raw(it.text, lang: "haskell", block: true)
}
// actual content lol
#outline(
indent: auto,
fill: line(
length: 100%,
stroke: (
cap: "round",
join: "round",
thickness: 0.5pt,
paint: luma(75%),
),
),
)
= Type data model
== Requirements
- Color-aware
- It can handle colors and colorspaces for images
- ocio????
- It can handle colors and colorspaces for images
- OpenColorIO?
- number/number type support
- custom types (structs/enums)
- algebraic enums
@ -20,12 +86,130 @@
#graphics.stages-overview
== Source > Graph IR
== Source
== Graph IR > VM Bytecode
Functional and pipeline-based.
However, in contrast to classic shell commands,
commands can have multiple outputs and multiple inputs.
=== Commands
The foundation of actually "doing" something.
- Can have any, even infinite, amount of inputs and outputs.
- Their amounts may or may not be equal.
- Inputs and outputs must have their types explicitly declared.
- An command with
- at least one output is called a streamer.
- at least one input is called a consumer.
- _both_ at least one input and at least one output is _both_ a streamer and a consumer, and culminatively called a modifier.
- May also contain spaces in its name.
==== Inputs <input>
- Based on position.
- Inputs can be provided both through the pipeline and ad-hoc.
- Ad-hoc inputs are called arguments.
- So all of these are equivalent:
```iowo
1 | add 2
add 1 2
[ 1 2 ] | add
```
==== Outputs
- Also based on position.
=== Pipelines <pipeline>
- Exchange data between streamers and consumers.
==== Simple forwarding
In the simplest case, where inputs map to outputs bijectively#footnote[one to one], pipelines are just pipes and forward unchanged:
```iowo
open owo.png | invert | save owo.png
```
==== Splitting <splitting>
To handle each output of a streamer individually, they can be _split_:
```iowo
mask
|> invert -- would invert the unmasked part
|> show -- would show the masked part
```
==== Combination <combination>
To throw multiple streamers into the inputs of a consumer, they can be _combined_:
```iowo
open base.png >|
open stencil.png >|
mask
```
However, since lists are automatically spliced into inputs, this is equivalent to the above:
```iowo
[
open base.png,
open stencil.png,
]
| mask
```
=== Comments
Done with any of `--` or `//`.
=== Data types
==== Lists
- Signified by `[]` braces.
- If thrown into a pipeline, it automatically works like a streamer.
- Can be delimited by commas.
- Must be delimited by commas if a contained streamer takes an input.
- May have a trailing comma.
- Outputs of streamers are spliced into the contained list.
- In effect, they are automatically flattened.
== Graph IR
=== Optimizer
=== Compiler
Merges and simplifies commands in the graph IR.
== VM Bytecode > VM
== Runtime
=== Scheduler
Looks at the graph IR and decides when the VM should execute what.
=== VM <vm>
= Open questions
- @input
- At which position are arguments injected into command inputs?
- How could that be controlled if set to e.g. the end by default?
- Not all inputs are order-independent, e.g. `div`
- Should inputs and outputs really be positional?
- Could make more complex commands hard to read
- But keyworded could also make code very noisy
- Maybe a middle ground, such that at most 1 input is allowed to be positional?
- @pipeline
- We need some way to reshuffle and reorder outputs and inputs in a pipeline
- @splitting
- How would one split different outputs into a list?
- Should outputs that are not thrown into a consumer be automatically displayed in some kind of debug view?
- Or should that be done instead using a debug `show` command or the like?
- Should consumers be called sinks instead?
- Shorter
- More ambiguous if only looking at the first char though

View file

@ -15,6 +15,7 @@
) = {
set page(
numbering: "1 / 1",
margin: 3.25cm,
header: locate(loc => {
datetime.today().display()
@ -29,6 +30,17 @@
set heading(numbering: "A.1")
show heading: it => text(..fonts.heading, it)
show raw.where(block: true): box.with(
fill: luma(95%),
inset: 1.25em,
radius: 0.75em,
width: 45em,
)
show raw.where(block: false): box.with(
fill: luma(95%),
outset: 0.25em,
radius: 0.25em,
)
// document title
if title != none {