docs: some initial groundwork #2
3 changed files with 204 additions and 11 deletions
|
@ -67,10 +67,7 @@
|
|||
nodes(
|
||||
[Source],
|
||||
[Graph IR],
|
||||
[Optimizer],
|
||||
[Compiler],
|
||||
[VM Bytecode],
|
||||
[VM],
|
||||
[Runtime],
|
||||
)
|
||||
})
|
||||
|
||||
|
|
|
@ -2,7 +2,73 @@
|
|||
#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
|
||||
|
||||
|
@ -10,7 +76,7 @@
|
|||
|
||||
- Color-aware
|
||||
- It can handle colors and colorspaces for images
|
||||
- ocio????
|
||||
- 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
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in a new issue