From b30cbb4d7bd46338d2223d7fa6cf3ef3bfc5e86c Mon Sep 17 00:00:00 2001 From: MultisampledNight Date: Tue, 9 Jan 2024 10:21:57 +0100 Subject: [PATCH] docs(design): actually write some content --- docs/design/graphics.typ | 5 +- docs/design/iowo-design.typ | 198 ++++++++++++++++++++++++++++++++++-- docs/template.typ | 12 +++ 3 files changed, 204 insertions(+), 11 deletions(-) diff --git a/docs/design/graphics.typ b/docs/design/graphics.typ index cf5f7e0..5e0ef4c 100644 --- a/docs/design/graphics.typ +++ b/docs/design/graphics.typ @@ -67,10 +67,7 @@ nodes( [Source], [Graph IR], - [Optimizer], - [Compiler], - [VM Bytecode], - [VM], + [Runtime], ) }) diff --git a/docs/design/iowo-design.typ b/docs/design/iowo-design.typ index 5c02cee..4d8e8d8 100644 --- a/docs/design/iowo-design.typ +++ b/docs/design/iowo-design.typ @@ -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 + +- 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 + +- 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 + +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 + +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 + += 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 diff --git a/docs/template.typ b/docs/template.typ index a688b07..5bdf52a 100644 --- a/docs/template.typ +++ b/docs/template.typ @@ -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 {