summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathanael Sensfelder <SpamShield0@MultiAgentSystems.org>2022-01-15 00:13:48 +0100
committerNathanael Sensfelder <SpamShield0@MultiAgentSystems.org>2022-01-15 00:13:48 +0100
commitd272efa49173c3708ddde54a96486261b73d7908 (patch)
treec6b5fa20c04593552fb378777cdc78471b1892b8
parent0a32a8eeb98d5f3507edf5e303ae655f4b923c74 (diff)
...
-rw-r--r--Makefile3
-rw-r--r--content/fate_v1/_index.md4
-rw-r--r--content/fate_v1/instructions/player_choices/_index.md14
-rw-r--r--content/wyrd_v1/_index.md92
-rw-r--r--content/wyrd_v1/computation/_index.md179
-rw-r--r--content/wyrd_v1/computations/_index.md100
-rw-r--r--content/wyrd_v1/extensions/_index.md5
-rw-r--r--content/wyrd_v1/file/_index.md5
-rw-r--r--content/wyrd_v1/input/_index.md5
-rw-r--r--content/wyrd_v1/instruction/_index.md291
-rw-r--r--content/wyrd_v1/instruction_result/_index.md5
-rw-r--r--content/wyrd_v1/instructions/_index.md76
-rw-r--r--content/wyrd_v1/state/_index.md46
-rw-r--r--content/wyrd_v1/value/_index.md11
-rwxr-xr-xdia/wyrd_interpreter_overview.diabin0 -> 2052 bytes
-rw-r--r--layouts/shortcodes/svg.html3
-rwxr-xr-xstatic/images/wyrd_interpreter_overview.svg474
17 files changed, 1079 insertions, 234 deletions
diff --git a/Makefile b/Makefile
index e5efc23..125a902 100644
--- a/Makefile
+++ b/Makefile
@@ -1,3 +1,4 @@
compile:
hugo
- scp -r public/* dreamhost:~/tonkadur/
+ #scp -r public/* dreamhost:~/tonkadur/
+ rsync -rzP --delete public/ dreamhost:~/tonkadur/
diff --git a/content/fate_v1/_index.md b/content/fate_v1/_index.md
index 2b14b63..43075d1 100644
--- a/content/fate_v1/_index.md
+++ b/content/fate_v1/_index.md
@@ -1,6 +1,6 @@
---
-title: "Fate (Version 1)"
-menuTitle: "Fate"
+title: "Fate Language (Version 1) Documentation"
+menuTitle: "Fate Language"
weight: 3
---
diff --git a/content/fate_v1/instructions/player_choices/_index.md b/content/fate_v1/instructions/player_choices/_index.md
index 4b54789..7b7ac58 100644
--- a/content/fate_v1/instructions/player_choices/_index.md
+++ b/content/fate_v1/instructions/player_choices/_index.md
@@ -30,6 +30,20 @@ A special version of the `for` loop is also possible, as described below:
### USER CHOICE - FOR
TODO
+### COMMAND PROMPT
+{{< fatecode >}}(prompt_command! [(STRING LIST) REFERENCE] [MIN = INT] [MAX = INT] [TEXT]){{< /fatecode >}}
+
+Prompts the user for a list of strings separated by spaces. `[MIN]` and `[MAX]`
+indicate the total number of characters (spaces included) allowed as input.
+The `[TEXT]` message is prompted to the user. The result is stored in
+`[(STRING LIST) REFERENCE]`.
+
+### FLOAT PROMPT
+{{< fatecode >}}(prompt_float! [FLOAT REFERENCE] [MIN = FLOAT] [MAX = FLOAT] [TEXT]){{< /fatecode >}}
+
+Prompts the user for a float between `[MIN]` and `[MAX]` by displaying the
+message `[TEXT]`. The result is stored in `[FLOAT REFERENCE]`.
+
### INTEGER PROMPT
{{< fatecode >}}(prompt_integer! [INT REFERENCE] [MIN = INT] [MAX = INT] [TEXT]){{< /fatecode >}}
diff --git a/content/wyrd_v1/_index.md b/content/wyrd_v1/_index.md
index c6e6e97..ac49ebe 100644
--- a/content/wyrd_v1/_index.md
+++ b/content/wyrd_v1/_index.md
@@ -1,57 +1,49 @@
---
-menuTitle: Wyrd
-title: Wyrd (Version 1)
+menuTitle: Wyrd Interpreter
+title: Coding a Wyrd (Version 1) Interpreter
weight: 4
---
Wyrd is the language in which the narrative is given to the game engine. It is
purposefully kept small and simple to facilitate porting Tonkadur to a new
engine.
-The memory is seen as a table mapping strings to values. These values may also
-be tables. Thus a reference is a list of strings corresponding to a move from
-one table to the next.
-
-The program is a list of instructions. These instructions may use computations
-as parameters. They sometimes use hard-coded strings parameters as well.
-Instructions cannot take instructions as parameters. Instructions are not
-associated to any value.
-
-An integer, called _Program Counter_ is used to indicate the current
-instruction. In most cases, this integer is incremented by one after every
-instruction. There is an instruction to modify the value of the Program Counter,
-which allows conditional jumps and loops to be described.
-
-Computations are values and operations returning values. These are solely used
-as parameters of instructions. They do not alter memory (with one exception)
-and do not interact with the Program Counter in any way. An execution cannot be
-stopped during the evaluation of a computation: it is part of its parent
-instruction and is thus completed exactly when that instruction is performed.
-Computations may _read_ from the memory, as they may need to fetch the value
-associated with an address or traverse tables. All computations have a return
-type.
-
-Wyrd does not have the notion of sequence or that lambda functions. It does not
-even associate player choices with lists of actions. It's all done by carefully
-managing the Program Counter.
-
-Lambda functions are stored as an `INT` corresponding to a line in the program.
-
-## Types
-* `ADDRESS` (or `POINTER`, or `REFERENCE`), a list of `STRING` (note: not a
- `STRING COLLECTION`).
-* `BOOL`. This should be changed to `BOOL` soon, for consistency's sake.
-* `[SOMETHING] COLLECTION`, table mapping `STRING` to `[SOMETHING]`.
-* `FLOAT`.
-* `INT`.
-* `TEXT`, a list of `STRINGS` with attributes attached.
-* `STRING`.
-* `STRUCTURE` (or `DICTIONARY`), table mapping `STRING` to values of any type.
-* `{String}`, a hard-coded string.
-
-#### Aliases sometimes used to refer to types
-* `? ADDRESS`: an `ADDRESS` pointing to a particular type.
-* `BASE TYPE`: `INT`, `FLOAT`, `BOOL`, `STRING`.
-* `COMPARABLE`: `INT`, `FLOAT`, `BOOL`, `STRING`, `TEXT`, `ADDRESS`.
-* `COLLECTION`: any `? COLLECTION`.
-* `COMPUTATION`: any type.
-* `NUMBER`: `INT` or `FLOAT`.
+This part of the website guides you through the implementation of a Wyrd
+interpreter.
+
+Wyrd files are meant to use easily parsable formats. Tonkadur provides Wyrd
+files as JSON, since JSON parsers are commonly available in pretty much any
+general programming language. However, the code generating this output is
+cleanly separated from the rest of the compiler, so changing the compiler to
+output in a different format should be approachable.
+
+As with Fate, Wyrd is split into computations and instructions. As a
+reminder, computations do not modify the memory, whereas instructions may.
+Furthermore, a computation in Fate may actually result in instructions in
+Wyrd (a notable example being the `random` Fate computation, which is actually
+implemented using the `set_random` Wyrd instruction).
+
+Here is an overview of the Wyrd interpreter:
+{{< svg "static/images/wyrd_interpreter_overview.svg" "1000px" >}}
+
+The state a Wyrd story is described by `<State>`, a structure defined on [this
+page](/wyrd_v1/state).
+
+* `execute(<State>)` executes the next `<Instruction>` and returns the updated
+ `<State>`. The semantics of each `<Instruction>` is explained on [this
+ page](/wyrd_v1/instruction). Their effect on the `{User Interface}` is
+ communicated by a `<InstructionResult>` member of `<State>`, but this it can
+ alternatively be returned alongside the updated `<State>` if the
+ implementation language permits it. All possible such effects are described
+ on [this page](/wyrd_v1/instruction_result).
+* Calls to `compute(<State>, <Computation>)` come from two sources: resolving
+ the parameters of an `<Instruction>` and resolving the parameters of
+ `<Computation>` (recursive call). The semantics of each `<Computation>` is
+ defined on [this page](/wyrd_v1/computation) and is computed according to
+ current `<State>` (they do not, however, modify it). The result is given as a
+ `<Value>`, the semantics of which can be found on [this page](/wyrd_v1/value).
+* The user may be called to provide an `<Input>`. This is presented by
+ `handle_input(<Input>, <State>)` on the figure above. The different
+ `<Input>`s and how to handle them are described on [this
+ page](/wyrd_v1/input).
+* The parsing process (`parse(<File>)`) is described on [this
+ page](/wyrd_v1/file).
diff --git a/content/wyrd_v1/computation/_index.md b/content/wyrd_v1/computation/_index.md
new file mode 100644
index 0000000..d0462a0
--- /dev/null
+++ b/content/wyrd_v1/computation/_index.md
@@ -0,0 +1,179 @@
+---
+menuTitle: <Computation>
+title: Computation
+weight: 3
+---
+This page presents all the `<Computation>`s that can be performed in Wyrd.
+`<Computation>`s do not modify the memory, but they always return a `<Value>`.
+
+**Shortcut to each `<Computation>`:**
+* [`(add_text_effect {name: String} {parameters: <Computation> List} {values: <Computation> list})`](#add_text_effect)
+* [`(address <value_or_target: Computation>)`](#address)
+* [`(cast {from: String} {to: String} <content: Computation>)`](#cast)
+* [`(constant {type: String} {value: String})`](#constant)
+* [`(get_allocable_address)`](#get_allocable_address)
+* [`(if_else <condition: Computation> <if_true: Computation> <if_false: Computation>)`](#if_else)
+* [`(last_choice_index)`](#last_choice_index)
+* [`(newline)`](#newline)
+* [`(operation {operator: String} <x: Computation>)`](#unary-operation)
+* [`(operation {operator: String} <x: Computation> <y: Computation>)`](#operation)
+* [`(relative_address <target: Computation> <extra: Computation>)`](#relative_address)
+* [`(size <target: Computation>)`](#target)
+* [`(text {values: <Computation> List})`](#text)
+* [`(value_of <target: Computation>)`](#value_of)
+* [`({extra_computation} {parameters: <Computation> List})`](#extra_computation)
+
+### add_text_effect
+`(add_text_effect {name: String} {parameters: <Computation> List} {values: <Computation> list})`
+
+Add an effect to a list of texts, returning it as a single text.
+
+**Parameters:**
+* `name` is a `{String}` indicating the name of the effect.
+* `parameters` is a `{List}` of `<Computation>` that will yield the `<Value>`s
+ used as parameters for the effect.
+* `values` is a `{<Computation> List}` that will yield the texts to merge and
+ apply the effect to. These will yield `<TextValue>`s.
+
+**Process:**
+* Compute the `{params: <Value> List}` corresponding to `parameters` (keep the
+ order).
+* Compute the `{texts: <Value> List}` corresponding to `values` (keep the
+ order).
+* Return a new `<AugmentedText>` `<TextValue>` with `texts` as `content`,
+ `name` as `effect_name`, and `params` as `effect_parameters`.
+
+### address
+`(address <value_or_target: Computation>)`
+
+Converts to an address.
+
+**Parameters:**
+* `value_or_target` is a `<Computation>` that will either result in in a
+ `<PointerValue>` or a `<StringValue>`.
+
+**Process:**
+* Compute the `<Value>` corresponding to `value_or_target`.
+* If this resulted in a `<PointerValue>`, return the value as is.
+* If this resulted in a `<StringValue>`, interpret the value as
+ `{addr: String}`, return a new `<PointerValue>` built from a singleton list
+ with `addr` as its only element.
+
+### cast
+`(cast {from: String} {to: String} <content: Computation>)`
+
+Convert from one type to another.
+
+**Parameters:**
+* `from` is a `{String}` naming the type `content` will result to.
+* `to` is a `{String}` naming the type to convert `content` to.
+* `content` is a `<Computation>` that will yield the `<Value>` to convert.
+
+**Process:**
+* Compute the `<Value>` associate with `content`.
+* Convert this `<Value>` from `from` to `to`.
+* Return the converted value.
+
+**Note:**
+The following conversions are expected to be available:
+* A type to the same type, returning the same value.
+* `<BoolValue>` to `<StringValue>`, returning `(StringValue "true")` if
+ `<Value>` is `(BoolValue TRUE)` and `(StringValue "false")` otherwise.
+* `<BoolValue>` to `<TextValue>`, same as above, but with text instead of
+ string.
+* `<FloatValue>` to `<StringValue>`.
+* `<FloatValue>` to `<TextValue>`.
+* `<FloatValue>` to `<IntValue>`, using a *floor* function.
+* `<IntValue>` to `<StringValue>`.
+* `<IntValue>` to `<TextValue>`.
+* `<IntValue>` to `<FloatValue>`.
+* `<IntValue>` to `<BoolValue>`, with `0` being `(BoolValue FALSE)` and
+ anything else being `(BoolValue TRUE)`.
+* `<StringValue>` to `<FloatValue>`.
+* `<StringValue>` to `<IntValue>`.
+* `<StringValue>` to `<BoolValue>`, `(BoolValue TRUE)` if the string is
+ `"true"`, `(BoolValue FALSE)` if it is `"false"`. Convert to lowercase prior
+ to checking.
+* `<TextValue>` to `<StringValue>`, by recursively converting all content to
+ `{String}`, discarding effects and newlines, and appending it all.
+* `<TextValue>` to `<IntValue>`, by converting it to `<StringValue>` first.
+* `<TextValue>` to `<FloatValue>`, by converting it to `<StringValue>` first.
+* `<TextValue>` to `<BoolValue>`, by converting it to `<StringValue>` first.
+
+### constant
+`(constant {type: String} {value: String})`
+
+**Parameters:**
+
+**Process:**
+
+### get_allocable_address
+`(get_allocable_address)`
+
+**Process:**
+
+### if_else
+`(if_else <condition: Computation> <if_true: Computation> <if_false: Computation>)`
+
+**Parameters:**
+
+**Process:**
+
+### last_choice_index
+`(last_choice_index)`
+
+**Process:**
+
+### newline
+`(newline)`
+
+**Process:**
+
+### Unary operation
+`(operation {operator: String} <x: Computation>)`
+
+**Parameters:**
+
+**Process:**
+
+### operation
+`(operation {operator: String} <x: Computation> <y: Computation>)`
+
+**Parameters:**
+
+**Process:**
+
+### relative_address
+`(relative_address <target: Computation> <extra: Computation>)`
+
+**Parameters:**
+
+**Process:**
+
+### size
+`(size <target: Computation>)`
+
+**Parameters:**
+
+**Process:**
+
+### text
+`(text {values: <Computation> List})`
+
+**Parameters:**
+
+**Process:**
+
+### value_of
+`(value_of <target: Computation>)`
+
+**Parameters:**
+
+**Process:**
+
+### extra_computation
+`({extra_computation} {parameters: <Computation> List})`
+
+**Parameters:**
+
+**Process:**
diff --git a/content/wyrd_v1/computations/_index.md b/content/wyrd_v1/computations/_index.md
deleted file mode 100644
index bc30f12..0000000
--- a/content/wyrd_v1/computations/_index.md
+++ /dev/null
@@ -1,100 +0,0 @@
----
-title: Computations
-weight: 1
----
-This page presents all the computations that can be performed in Wyrd.
-Computations may access the current memory, but, with one exception, do not
-change it. The one exception is `(new t)`. All computations return values.
-The terms 'value' and 'computation' are interchangeable.
-
-## CONSTANT
-{{< fatecode >}}(const [BASE TYPE] {string}){{< /fatecode >}}
-Returns the `[BASE TYPE]` represented by `{string}`.
-
-## CAST
-{{< fatecode >}}(cast [COMPUTATION] [BASE TYPE]){{< /fatecode >}}
-Converts `[COMPUTATION]` to `[BASE TYPE]`, returns the result.
-
-Note:
-* Converting from `FLOAT` to `INT` returns `floor(v)`.
-* Converting from `BOOL` to `STRING` yields either `True` or `False`.
-
-The following must be supported:
-* `[FLOAT]` to `[FLOAT]`, `[INT]`, and `[STRING]`.
-* `[INT]` to `[FLOAT]`, `[INT]`, and `[STRING]`.
-* `[BOOL]` to `[BOOL]` and `[STRING]`.
-* `[STRING]` to `[BOOL]` (`true` and `false`), `[FLOAT]`, `[INT]`, and`[STRING]`.
-
-## IF-ELSE
-{{< fatecode >}}(if_else [BOOL] [C0 = COMPUTATION] [C1 = COMPUTATION]){{< /fatecode >}}
-Returns `C0` if `[BOOL]` holds _true_, `C1` otherwise. `C0` and `C1` both
-have the same type.
-
-## EQUALS
-{{< fatecode >}}(equals [C0 = COMPUTATION] [C1 = COMPUTATION]){{< /fatecode >}}
-Returns a `BOOL`, _true_ if `C0` and `C1` hold the same value. `C0` and `C1`
-are both of the same type.
-
-## MATHEMATICAL OPERATORS
-{{< fatecode >}}(divide [C0 = NUMBER] [C1 = NUMBER]){{< /fatecode >}}
-
-{{< fatecode >}}(minus [C0 = NUMBER] [C1 = NUMBER]){{< /fatecode >}}
-
-{{< fatecode >}}(plus [C0 = NUMBER] [C1 = NUMBER]){{< /fatecode >}}
-
-{{< fatecode >}}(power [C0 = NUMBER] [C1 = NUMBER]){{< /fatecode >}}
-
-{{< fatecode >}}(times [C0 = NUMBER] [C1 = NUMBER]){{< /fatecode >}}
-The operation returns a value of the same type as `C0` and `C1` (both `C0` and
-`C1` are also of the same type). Thus, `(divide C0 C1)` is an integer division
-(the remainder is discarded) if `C0` and `C1` are of type `INT`, and a standard
-division if they are of type `FLOAT`.
-
-{{< fatecode >}}(rand [C0 = INT] [C1 = INT]){{< /fatecode >}}
-Returns a random value between `C0` and `C1`, inclusive. Raises a runtime error
-if `C0 > C1`.
-
-## MATHEMATICAL COMPARISON
-{{< fatecode >}}(less_than [C0 = COMPARABLE] [C1 = COMPARABLE]){{< /fatecode >}}
-Returns a `[BOOL]` indicating if `C0` is strictly less than `C1`.
-`C0` and `C1` are both of the same type.
-
-## LOGICAL OPERATORS
-{{< fatecode >}}(and [C0 = BOOL] [C1 = BOOL]){{< /fatecode >}}
-
-{{< fatecode >}}(not [C0 = BOOL]){{< /fatecode >}}
-
-## SIZE
-{{< fatecode >}}(size [COLLECTION ADDRESS]){{< /fatecode >}}
-Returns the number of elements held by the collection at
-`[COLLECTION ADDRESS]`.
-
-## REFERENCES
-{{< fatecode >}}(address [COMPUTATION]){{< /fatecode >}}
-Returns an `ADDRESS` to the memory element at address `[COMPUTATION]`. Raises a
-runtime error if `[COMPUTATION]` is not a memory element.
-
-{{< fatecode >}}(relative_address [R0 = (COLLECTION|STRUCTURE) ADDRESS] [STRING]){{< /fatecode >}}
-Returns a `REFERENCE` to member `[STRING]` of `R0`.
-
-{{< fatecode >}}(value_of [ADDRESS]){{< /fatecode >}}
-Returns the value held at the memory location `[ADDRESS]`.
-
-{{< fatecode >}}(new [TYPE]){{< /fatecode >}}
-Returns an `[TYPE] ADDRESS` to a newly allocated memory element of
-type `[TYPE]`.
-
-## TEXT
-{{< fatecode >}}(newline){{< /fatecode >}}
-Returns a `TEXT` value corresponding to a newline.
-
-{{< fatecode >}}(text [S0 = STRING] ... [SN = STRING]){{< /fatecode >}}
-Returns a single value `[TEXT]` representing the elements `S0` ... `S1`.
-
-{{< fatecode >}}(add_text_effect ({string} [V0 = COMPUTATION] ... [VN = COMPUTATION]) [TEXT]){{< /fatecode >}}
-Returns a `[TEXT]` value of `[TEXT]` with the given effect enabled.
-
-## LAST USER CHOICE
-{{< fatecode >}}(get_last_user_choice){{< /fatecode >}}
-Returns the number corresponding to the option last chosen by the user in a
-`(resolve_choices)`, or `-1` if there is no such value.
diff --git a/content/wyrd_v1/extensions/_index.md b/content/wyrd_v1/extensions/_index.md
deleted file mode 100644
index 5ce9946..0000000
--- a/content/wyrd_v1/extensions/_index.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Extensions
-weight: 3
----
-Not available in Version 1.
diff --git a/content/wyrd_v1/file/_index.md b/content/wyrd_v1/file/_index.md
new file mode 100644
index 0000000..e0aa619
--- /dev/null
+++ b/content/wyrd_v1/file/_index.md
@@ -0,0 +1,5 @@
+---
+menuTitle: <File>
+title: File
+weight: 7
+---
diff --git a/content/wyrd_v1/input/_index.md b/content/wyrd_v1/input/_index.md
new file mode 100644
index 0000000..d6bbc87
--- /dev/null
+++ b/content/wyrd_v1/input/_index.md
@@ -0,0 +1,5 @@
+---
+menuTitle: <Input>
+title: Input
+weight: 6
+---
diff --git a/content/wyrd_v1/instruction/_index.md b/content/wyrd_v1/instruction/_index.md
new file mode 100644
index 0000000..d441ee1
--- /dev/null
+++ b/content/wyrd_v1/instruction/_index.md
@@ -0,0 +1,291 @@
+---
+menuTitle: <Instruction>
+title: Instruction
+weight: 2
+---
+This page presents all the `<Instruction>`s that can be performed in Wyrd.
+`<Instruction>`s do not return values.
+
+Unless otherwise specified, all `<Instruction>`s:
+* Increment the `<State>`'s `program_counter` by 1.
+* Set the `<State>`'s `last_instruction_result` to `(MUST_CONTINUE)`.
+
+Implementing `execute(<State>)` to recurse/loop as long as the newly updated
+`<State>`'s `last_instruction_result` is `(MUST_CONTINUE)` is acceptable.
+
+**Shortcut to each `<Instruction>`:**
+* [`(add_event_option! {name: String} {parameters: <Computation> List})`](#add_event_option)
+* [`(add_text_option! <value: Computation>)`](#add_text_option)
+* [`(assert! <condition: Computation> <message: Computation>)`](#assert)
+* [`(display! <value: Computation>)`](#display)
+* [`(end!)`](#end)
+* [`(initialize! {type: String} <target: Computation>)`](#initialize)
+* [`(prompt_command! <min: Computation> <max: Computation> <target: Computation> <message: Computation>)`](#prompt_command)
+* [`(prompt_float! <min: Computation> <max: Computation> <target: Computation> <message: Computation>)`](#prompt_float)
+* [`(prompt_integer! <min: Computation> <max: Computation> <target: Computation> <message: Computation>)`](#prompt_integer)
+* [`(prompt_string! <min: Computation> <max: Computation> <target: Computation> <message: Computation>)`](#prompt_string)
+* [`(remove! <target: Computation>)`](#remove)
+* [`(resolve_choice!)`](#resolve_choice)
+* [`(set_pc! <value: Computation>)`](#set_pc)
+* [`(set_random! <min: Computation> <max: Computation> <target: Computation>)`](#set_random)
+* [`(set_value! <target: Computation> <value: Computation>)`](#set_value)
+* [`({extra_instruction: String}! {parameters: <Computation> List})`](#extra_instruction)
+
+### add_event_option
+`(add_event_option! {name: String} {parameters: <Computation> List})`
+
+Adds an `<Option>` based on an `<Event>` for the user.
+
+**Parameters:**
+* `value` is a `{String}` indicating the name of the `<Event>`.
+* `parameters` is a `{List}` of `<Computation>` that will yield the `<Value>`s
+ required for this option to be chosen when the `<Event>` occurs on the next
+ `(resolve_choice!)`.
+
+**Process:**
+* Compute the `<Value>` corresponding to each member of `parameters`, store them
+ in a `{List}` while keeping the order.
+* Create a new `<EventOption>` with name `name` and the aforementioned
+ `{<Value> List}` as parameters.
+* Append the newly created `<EventOption>` to the end of the `<State>`'s
+ `available_options`.
+
+### add_text_option
+`(add_text_option! <value: Computation>)`
+
+Adds an `<Option>` based on an `<TextValue>` for the user.
+
+**Parameters:**
+* `value` is a `<Computation>` that will yield the `<TextValue>` displayed to
+ the user for this option on the next `(resolve_choice!)`.
+
+**Process:**
+* Compute the `<Value>` yielded by `value`.
+* Create a new `<TextOption>` corresponding to the aforementioned
+ `<Value>`.
+* Append the newly created `<TextOption>` to the end of the `<State>`'s
+ `available_options`.
+
+### assert
+`(assert! <condition: Computation> <message: Computation>)`
+
+Checks if a condition is fulfilled and prints an error message if it is not.
+
+**Parameters:**
+* `condition` is a `<Computation>` corresponding to what needs to be tested.
+* `message` is a `<Computation>` defining the error message displayed to the
+ user if the condition is not verified.
+
+**Process:**
+* Compute the `<Value>` yielded by `condition`.
+* Interpret this `<Value>` as `{Boolean}`.
+* If it is `TRUE`, the `<Instruction>` has completed.
+* Otherwise, compute the `<msg: Value>` corresponding to the `message`.
+* Set the `<State>`'s `last_instruction_result` to
+ `(MUST_DISPLAY_ERROR <msg: Value>)`.
+
+### display
+`(display! <value: Computation>)`
+
+Displays text to the user.
+
+**Parameters:**
+* `value` is a `<Computation>` corresponding to what has to be displayed.
+
+**Process:**
+* Compute the `<msg: Value>` corresponding to `value`.
+* Set the `<State>`'s `last_instruction_result` to
+ `(MUST_DISPLAY <msg: Value>)`.
+
+### end
+`(end!)`
+
+Ends the story.
+
+**Process:**
+* Do **not** increase the `<State>`'s `program_counter`.
+* Set the `<State>`'s `last_instruction_result` to `(MUST_END)`
+
+### initialize
+`(initialize! {type: String} <target: Computation>)`
+
+Adds an element to `memory` with a deterministic default value.
+
+**Parameters:**
+* `type` is a `{String}` corresponding to the type that will be used by
+ `target`.
+* `target` is `<Computation>` that will yield the address to initialize.
+
+**Process:**
+* Compute the `<Value>` resulting from `target`. This is a `<PointerValue>`.
+* Interpret this `<PointerValue>` as a `{{String} List}`.
+* Update the `<State>`'s `memory` so that the element pointed to by the
+ `<PointerValue>` takes the default value for a `<Value>` of type `type`. Note
+ that the `target` might point to an element that does not exist yet.
+
+### prompt_command
+`(prompt_command! <min: Computation> <max: Computation> <target: Computation> <message: Computation>)`
+
+Asks the user to provide a list of strings as input.
+
+**Parameters:**
+* `min` is a `<Computation>` indicating the minimum size the user `{String}`
+ input should be (in characters).
+* `max` is a `<Computation>` indicating the maximum size the user `{String}`
+ input should be (in characters).
+* `target` is a `<Computation>` indicating where to store the result.
+* `message` is a `<Computation>` corresponding to the message displayed to the
+ user for this prompt.
+
+**Process:**
+* Compute the `<Value>` corresponding to each of these parameter.
+* Update the `<State>`'s `memorized_target` to be the `<Value>` resulting from
+ `target`.
+* Set the `<State>`'s `last_instruction_result` to
+ `(MUST_PROMPT_COMMAND <min_val: Value> <max_val: Value> <msg: Value>)`.
+
+### prompt_float
+`(prompt_float! <min: Computation> <max: Computation> <target: Computation> <message: Computation>)`
+
+Asks the user to provide a float as input.
+
+**Parameters:**
+* `min` is a `<Computation>` indicating the minimum float the user is allowed
+ to input
+* `max` is a `<Computation>` indicating the maximum float the user is allowed
+ to input
+* `target` is a `<Computation>` indicating where to store the result.
+* `message` is a `<Computation>` corresponding to the message displayed to the
+ user for this prompt.
+
+**Process:**
+* Compute the `<Value>` corresponding to each of these parameter.
+* Update the `<State>`'s `memorized_target` to be the `<Value>` resulting from
+ `target`.
+* Set the `<State>`'s `last_instruction_result` to
+ `(MUST_PROMPT_FLOAT <min_val: Value> <max_val: Value> <msg: Value>)`.
+
+
+### prompt_integer
+`(prompt_integer! <min: Computation> <max: Computation> <target: Computation> <message: Computation>)`
+
+Asks the user to provide an integer as input.
+
+**Parameters:**
+* `min` is a `<Computation>` indicating the minimum integer the user is allowed
+ to input
+* `max` is a `<Computation>` indicating the maximum integer the user is allowed
+ to input
+* `target` is a `<Computation>` indicating where to store the result.
+* `message` is a `<Computation>` corresponding to the message displayed to the
+ user for this prompt.
+
+**Process:**
+* Compute the `<Value>` corresponding to each of these parameter.
+* Update the `<State>`'s `memorized_target` to be the `<Value>` resulting from
+ `target`.
+* Set the `<State>`'s `last_instruction_result` to
+ `(MUST_PROMPT_INTEGER <min_val: Value> <max_val: Value> <msg: Value>)`.
+
+### prompt_string
+`(prompt_string! <min: Computation> <max: Computation> <target: Computation> <message: Computation>)`
+
+Asks the user to provide a string as input.
+
+**Parameters:**
+* `min` is a `<Computation>` indicating the minimum size the user `{String}`
+ input should be (in characters).
+* `max` is a `<Computation>` indicating the maximum size the user `{String}`
+ input should be (in characters).
+* `target` is a `<Computation>` indicating where to store the result.
+* `message` is a `<Computation>` corresponding to the message displayed to the
+ user for this prompt.
+
+**Process:**
+* Compute the `<Value>` corresponding to each of these parameter.
+* Update the `<State>`'s `memorized_target` to be the `<Value>` resulting from
+ `target`.
+* Set the `<State>`'s `last_instruction_result` to
+ `(MUST_PROMPT_STRING <min_val: Value> <max_val: Value> <msg: Value>)`.
+
+### remove
+`(remove! <target: Computation>)`
+
+Removes an element from memory.
+
+**Parameter:**
+* `target` is a `<Computation>` indicating where the element to remove is.
+
+**Process:**
+* Compute the `<Value>` corresponding to `target`.
+* Interpet this `<Value>` as an address.
+* Remove the element at this address from the `<State>`'s `memory`.
+
+### resolve_choice
+`(resolve_choice!)`
+
+Makes the user choose between all previously added options.
+
+**Process:**
+* Set the `<State>`'s `last_instruction_result` to `(MUST_PROMPT_CHOICE)`.
+
+
+### set_pc
+`(set_pc! <value: Computation>)`
+
+Sets the program counter to a given value.
+
+**Parameter:**
+* `value` is a `<Computation>` indicating what to set the program counter to.
+
+**Process:**
+* Compute the `<Value>` for `value`.
+* Interpret this `<Value>` as an `{Integer}`.
+* Set the `<State>`'s `program_counter` to this value.
+* Do **not** otherwise increase the `<State>`'s `program_counter`.
+
+### set_random
+`(set_random! <min: Computation> <max: Computation> <target: Computation>)`
+
+Replaces the `<Value>` at a given address with a random integer. This is not
+a computation as some languages will require state updates to keep generating
+new random values.
+
+**Parameters:**
+* `min` is a `<Computation>` indicating the minimum integer allowed.
+ to input
+* `max` is a `<Computation>` indicating the maximum integer allowed.
+* `target` is a `<Computation>` indicating where to store the result.
+
+**Process:**
+* Compute the `<Value>` corresponding to each of these parameter.
+* Generate a random `{Integer}` between `min` and `max` (included).
+* Update the `<State>`'s `memory`so that the element at `target` is to be the
+ `<Value>` resulting from `target`.
+
+### set_value
+`(set_value! <target: Computation> <value: Computation>)`
+
+Sets the value of an element in memory.
+
+**Parameters:**
+* `target` is a `<Computation>` indicating what element to set to the value.
+* `value` is a `<Computation>` corresponding to the value to give the element.
+
+**Process:**
+* Compute `target` as `<addr: Value>`.
+* Modify the `<State>`'s `memory` so that the element at `addr` takes the
+ `<Value>` resulting from `value`'s computation.
+
+### extra_instruction
+`({extra_instruction: String}! {parameters: <Computation> List})`
+
+Executes non-standard instruction.
+
+**Parameters:**
+* `extra_instruction` is the name of the extra instruction.
+* `parameters` is a list of parameters for this instruction call.
+
+**Process:**
+* Undetermined. This is where you choose the process according to the value of
+ `extra_instruction` so that you can add non-standard instructions.
diff --git a/content/wyrd_v1/instruction_result/_index.md b/content/wyrd_v1/instruction_result/_index.md
new file mode 100644
index 0000000..b77b496
--- /dev/null
+++ b/content/wyrd_v1/instruction_result/_index.md
@@ -0,0 +1,5 @@
+---
+menuTitle: <InstructionResult>
+title: Instruction Result
+weight: 5
+---
diff --git a/content/wyrd_v1/instructions/_index.md b/content/wyrd_v1/instructions/_index.md
deleted file mode 100644
index 500f884..0000000
--- a/content/wyrd_v1/instructions/_index.md
+++ /dev/null
@@ -1,76 +0,0 @@
----
-title: Instructions
-weight: 2
----
-This page presents all the instructions that can be performed in Wyrd.
-Instructions do not return values. With one exception, all instructions increase
-the Program Counter by 1.
-
-
-## ADD CHOICE
-{{< fatecode >}}(add_choice [TEXT]){{< /fatecode >}}
-Adds a new option for the next `resolve_choices` instruction. The new option
-presents the player with `[TEXT]`.
-
-## INTEGER PROMPT
-{{< fatecode >}}(prompt_integer [INT REFERENCE] [MIN = INT] [MAX = INT] [TEXT]){{< /fatecode >}}
-
-Prompts the user for an integer between `[MIN]` and `[MAX]` by displaying the
-message `[TEXT]`. The result is stored in `[INT REFERENCE]`.
-
-## STRING PROMPT
-{{< fatecode >}}(prompt_string [STRING REFERENCE] [MIN = INT] [MAX = INT] [TEXT]){{< /fatecode >}}
-
-Prompts the user for a string of size between `[MIN]` and `[MAX]` by displaying
-the message `[TEXT]`. The result is stored in `[STRING REFERENCE]`.
-
-
-## ASSERT
-{{< fatecode >}}(assert [BOOL] [TEXT]){{< /fatecode >}}
-If `[BOOL]` isn't _true_, raise a runtime error containing `[TEXT]`.
-
-
-## DISPLAY
-{{< fatecode >}}(display [TEXT]){{< /fatecode >}}
-Displays `[TEXT]` to the player.
-
-
-## END
-{{< fatecode >}}(end){{< /fatecode >}}
-Marks the end of the narration. Interrupts the execution.
-
-
-## EVENT CALL
-{{< fatecode >}}(event_call {string} [C0 = COMPUTATION] ... [CN = COMPUTATION]){{< /fatecode >}}
-Interrupts execution, informs the interpreter that the given event `{String}`
-was triggered with the parameters `C0 ... CN`.
-
-
-## REMOVE
-{{< fatecode >}}(remove [ADDRESS]){{< /fatecode >}}
-The memory at `[ADDRESS]` is freed.
-
-
-## RESOLVE CHOICES
-{{< fatecode >}}(resolve_choices){{< /fatecode >}}
-Present the player with all options that where added using `add_choice` since
-the last `resolve_choices`. The execution is paused and should be resumed by
-the interpreter setting the Program Counter according to the chosen option.
-
-
-## SET PC
-{{< fatecode >}}(set_pc [INT]){{< /fatecode >}}
-Sets the Program Counter to `[INT]`. The program counter is not automatically
-increased by 1 in this case.
-
-
-## SET VALUE
-{{< fatecode >}}(set_value [ADDRESS] [COMPUTATION]){{< /fatecode >}}
-Sets the memory pointed by `[ADDRESS]` to `[COMPUTATION]`.
-`[COMPUTATION]` is passed by value, not reference (i.e. no aliasing can occur
-without it being done explicitly through pointers).
-
-## INITIALIZE MEMORY ELEMENT
-{{< fatecode >}}(initialize [ADDRESS] [TYPE]){{< /fatecode >}}
-Initializes a memory element at `[ADDRESS]` with the default value for the type
-`[TYPE]`.
diff --git a/content/wyrd_v1/state/_index.md b/content/wyrd_v1/state/_index.md
new file mode 100644
index 0000000..f42e2ae
--- /dev/null
+++ b/content/wyrd_v1/state/_index.md
@@ -0,0 +1,46 @@
+---
+menuTitle: <State>
+title: State
+weight: 1
+---
+* `memory: {{String} -> <Value>}`, which is pretty self-explanatory.
+* `user_types: {{String} -> <Value>}`, providing the default value for each
+ user-defined type.
+* `sequences: {{String} -> {Int}}`, an optional member that gives you the value
+ to give `program_counter` in order to jump to a certain sequence (untested).
+* `code: {{Int} -> <Instruction>}`, to retrieve the `<Instruction>`
+ corresponding to a line.
+* `program_counter: {Int}`, the line of the next `<Instruction>` to be executed.
+* `last_choice_index: {Int}`, the index (starting from 0) corresponding to the
+ `<Option>` chosen by the user following a `(resolve_choice!)`.
+* `available_options: {<Option> List}`, the list of `<Option>`s to present to
+ the user upon encountering a `(resolve_choice!)`.
+* `memorized_target: <Value>`, the address in which to store the next user
+ input.
+* `last_instruction_effect: <InstructionEffect>`, the result of the last
+ executed `<Instruction>`. Developers may choose to keep it separate from the
+ `<State>` structure if it makes more sense to do so in their chosen language
+ (e.g. languages allowing functions with multiple returned values).
+
+In order to manage unique address allocation, the proposed solution is to
+include the following members. There is no issue with employing other solutions,
+when more appropriate:
+* `allocated_data: {Int}`, a value that has not been used to generate any
+ allocable `<Address>`es before.
+* `freed_addresses: {{String} Collection}`, a collection of freed allocable
+ `<Address>`es, so that they may be re-used.
+
+Lastly, randomness management might call for an additional member, depending on
+the language:
+* `random_seed: {RandomSeed}`, the next randomness seed to be used.
+
+### Note on `memory`
+One will notice that `memory` is `{{String} -> <Value>}`, yet addresses are
+converted to `{{String} List}` before use. This is because some `<Value>`s
+returned by `memory` can also be converted to `{{String} -> <Value>}` (see
+`<ListValue>` and `<StructureValue>` on [this page](/wyrd_v1/value)). As a
+result, the list is used to traverse/update these.
+
+It is likely that you will want to treat the last element of the address
+differently from the rest, as its parent would be the `{{String} -> Value}`
+construction to consult or modify.
diff --git a/content/wyrd_v1/value/_index.md b/content/wyrd_v1/value/_index.md
new file mode 100644
index 0000000..18e2a6a
--- /dev/null
+++ b/content/wyrd_v1/value/_index.md
@@ -0,0 +1,11 @@
+---
+menuTitle: <Value>
+title: Value
+weight: 4
+---
+
+`{Integer}` and `{Float}` are meant to represent the largest available integer
+and float point value types available in the interpreter's language. This is not
+mandatory, but be especially wary of using too small a type for `{Integer}`, as
+the `<State>` `program_counter` value will need to be able to be as big as there
+are instructions in the program.
diff --git a/dia/wyrd_interpreter_overview.dia b/dia/wyrd_interpreter_overview.dia
new file mode 100755
index 0000000..b5eeff6
--- /dev/null
+++ b/dia/wyrd_interpreter_overview.dia
Binary files differ
diff --git a/layouts/shortcodes/svg.html b/layouts/shortcodes/svg.html
new file mode 100644
index 0000000..8378691
--- /dev/null
+++ b/layouts/shortcodes/svg.html
@@ -0,0 +1,3 @@
+<div class="svg-container" style="width: {{(print (index .Params 1))}}">
+{{ readFile (print (index .Params 0)) | safeHTML }}
+</div>
diff --git a/static/images/wyrd_interpreter_overview.svg b/static/images/wyrd_interpreter_overview.svg
new file mode 100755
index 0000000..9c13551
--- /dev/null
+++ b/static/images/wyrd_interpreter_overview.svg
@@ -0,0 +1,474 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="52.949188cm"
+ height="36.688496cm"
+ viewBox="518 499 1042.0001 716.91304"
+ version="1.1"
+ id="svg4641"
+ sodipodi:docname="wyrd_interpreter_overview.svg"
+ inkscape:version="0.92.1 r15371">
+ <metadata
+ id="metadata4647">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ <cc:license
+ rdf:resource="http://creativecommons.org/publicdomain/zero/1.0/" />
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/publicdomain/zero/1.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs4645" />
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="2560"
+ inkscape:window-height="1377"
+ id="namedview4643"
+ showgrid="false"
+ inkscape:zoom="0.87670045"
+ inkscape:cx="999.65424"
+ inkscape:cy="737.98941"
+ inkscape:window-x="-8"
+ inkscape:window-y="-8"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg4641"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0" />
+ <g
+ id="g4489"
+ transform="translate(-1,-2.5641373)">
+ <rect
+ style="fill:#ffffff"
+ x="520"
+ y="600"
+ width="160"
+ height="300"
+ rx="60"
+ ry="60"
+ id="rect4485" />
+ <rect
+ style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2;stroke-linejoin:round"
+ x="520"
+ y="600"
+ width="160"
+ height="300"
+ rx="60"
+ ry="60"
+ id="rect4487" />
+ </g>
+ <text
+ font-size="16.9333"
+ style="font-style:normal;font-weight:700;font-size:16.93330002px;font-family:sans-serif;text-anchor:middle;fill:#000000"
+ x="599"
+ y="742.72784"
+ id="text4495">
+ <tspan
+ x="599"
+ y="742.72784"
+ id="tspan4491">User</tspan>
+ <tspan
+ x="599"
+ y="763.89386"
+ id="tspan4493">Interface</tspan>
+ </text>
+ <g
+ id="g4501"
+ transform="translate(-1,-2.5641373)">
+ <rect
+ style="fill:#ffffff"
+ x="960"
+ y="600"
+ width="160"
+ height="300"
+ rx="60"
+ ry="60"
+ id="rect4497" />
+ <rect
+ style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2;stroke-linejoin:round"
+ x="960"
+ y="600"
+ width="160"
+ height="300"
+ rx="60"
+ ry="60"
+ id="rect4499" />
+ </g>
+ <text
+ font-size="16.9333"
+ style="font-style:normal;font-weight:700;font-size:16.93330002px;font-family:sans-serif;text-anchor:middle;fill:#000000"
+ x="1039"
+ y="742.72784"
+ id="text4507">
+ <tspan
+ x="1039"
+ y="742.72784"
+ id="tspan4503">Instruction</tspan>
+ <tspan
+ x="1039"
+ y="763.89386"
+ id="tspan4505">Handling</tspan>
+ </text>
+ <g
+ id="g4513"
+ transform="translate(-1,-2.5641373)">
+ <rect
+ style="fill:#ffffff"
+ x="1400"
+ y="600"
+ width="160"
+ height="300"
+ rx="60"
+ ry="60"
+ id="rect4509" />
+ <rect
+ style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2;stroke-linejoin:round"
+ x="1400"
+ y="600"
+ width="160"
+ height="300"
+ rx="60"
+ ry="60"
+ id="rect4511" />
+ </g>
+ <text
+ font-size="16.9333"
+ style="font-style:normal;font-weight:700;font-size:16.93330002px;font-family:sans-serif;text-anchor:middle;fill:#000000"
+ x="1479"
+ y="742.72784"
+ id="text4519">
+ <tspan
+ x="1479"
+ y="742.72784"
+ id="tspan4515">Computation</tspan>
+ <tspan
+ x="1479"
+ y="763.89386"
+ id="tspan4517">Handling</tspan>
+ </text>
+ <g
+ id="g4527"
+ transform="translate(-1,-2.5641373)">
+ <line
+ style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2;stroke-linejoin:round"
+ x1="689.73602"
+ y1="840"
+ x2="960"
+ y2="840"
+ id="line4521" />
+ <polygon
+ style="fill:#000000"
+ points="689.736,840 692.236,845 682.236,840 692.236,835 "
+ id="polygon4523" />
+ <polygon
+ style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
+ points="689.736,840 692.236,845 682.236,840 692.236,835 "
+ id="polygon4525" />
+ </g>
+ <text
+ font-size="12.8"
+ style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sans-serif;text-anchor:start;fill:#000000"
+ x="699"
+ y="641.69983"
+ id="text4531">
+ <tspan
+ x="699"
+ y="641.69983"
+ id="tspan4529">execute(&lt;State&gt;)</tspan>
+ </text>
+ <g
+ id="g4539"
+ transform="translate(-1,-2.5641373)">
+ <line
+ style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
+ x1="680"
+ y1="660"
+ x2="950.26398"
+ y2="660"
+ id="line4533" />
+ <polygon
+ style="fill:#000000"
+ points="950.264,660 947.764,655 957.764,660 947.764,665 "
+ id="polygon4535" />
+ <polygon
+ style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
+ points="950.264,660 947.764,655 957.764,660 947.764,665 "
+ id="polygon4537" />
+ </g>
+ <text
+ font-size="12.8"
+ style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sans-serif;text-anchor:start;fill:#000000"
+ x="699"
+ y="721.69983"
+ id="text4543">
+ <tspan
+ x="699"
+ y="721.69983"
+ id="tspan4541">handle_input(&lt;Input&gt;, &lt;State&gt;)</tspan>
+ </text>
+ <g
+ id="g4551"
+ transform="translate(-1,-2.5641373)">
+ <line
+ style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
+ x1="680"
+ y1="740"
+ x2="950.26398"
+ y2="740"
+ id="line4545" />
+ <polygon
+ style="fill:#000000"
+ points="950.264,740 947.764,735 957.764,740 947.764,745 "
+ id="polygon4547" />
+ <polygon
+ style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
+ points="950.264,740 947.764,735 957.764,740 947.764,745 "
+ id="polygon4549" />
+ </g>
+ <text
+ font-size="12.8"
+ style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sans-serif;text-anchor:end;fill:#000000"
+ x="939"
+ y="821.69983"
+ id="text4555">
+ <tspan
+ x="939"
+ y="821.69983"
+ id="tspan4553">&lt;State&gt;</tspan>
+ </text>
+ <g
+ id="g4563"
+ transform="translate(-1,-2.5641373)">
+ <line
+ style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
+ x1="1129.74"
+ y1="840"
+ x2="1400"
+ y2="840"
+ id="line4557" />
+ <polygon
+ style="fill:#000000"
+ points="1129.74,840 1132.24,845 1122.24,840 1132.24,835 "
+ id="polygon4559" />
+ <polygon
+ style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
+ points="1129.74,840 1132.24,845 1122.24,840 1132.24,835 "
+ id="polygon4561" />
+ </g>
+ <text
+ font-size="12.8"
+ style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sans-serif;text-anchor:end;fill:#000000"
+ x="1379"
+ y="821.69983"
+ id="text4567">
+ <tspan
+ x="1379"
+ y="821.69983"
+ id="tspan4565">&lt;Value&gt;</tspan>
+ </text>
+ <text
+ font-size="12.8"
+ style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sans-serif;text-anchor:start;fill:#000000"
+ x="1139"
+ y="641.69983"
+ id="text4571">
+ <tspan
+ x="1139"
+ y="641.69983"
+ id="tspan4569">compute(&lt;State&gt;, &lt;Computation&gt;)</tspan>
+ </text>
+ <g
+ id="g4579"
+ transform="translate(-1,-2.5641373)">
+ <line
+ style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
+ x1="1120"
+ y1="660"
+ x2="1390.26"
+ y2="660"
+ id="line4573" />
+ <polygon
+ style="fill:#000000"
+ points="1390.26,660 1387.76,655 1397.76,660 1387.76,665 "
+ id="polygon4575" />
+ <polygon
+ style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
+ points="1390.26,660 1387.76,655 1397.76,660 1387.76,665 "
+ id="polygon4577" />
+ </g>
+ <g
+ id="g4587"
+ transform="translate(-1,-2.5641373)">
+ <polyline
+ style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
+ points="620,900 620,980 750.264,980 "
+ id="polyline4581" />
+ <polygon
+ style="fill:#000000"
+ points="750.264,980 747.764,975 757.764,980 747.764,985 "
+ id="polygon4583" />
+ <polygon
+ style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
+ points="750.264,980 747.764,975 757.764,980 747.764,985 "
+ id="polygon4585" />
+ </g>
+ <g
+ id="g4595"
+ transform="translate(-1,-2.5641373)">
+ <polyline
+ style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
+ points="760,1160 760,1160 580,1160 580,909.736 "
+ id="polyline4589" />
+ <polygon
+ style="fill:#000000"
+ points="580,909.736 575,912.236 580,902.236 585,912.236 "
+ id="polygon4591" />
+ <polygon
+ style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
+ points="580,909.736 575,912.236 580,902.236 585,912.236 "
+ id="polygon4593" />
+ </g>
+ <text
+ font-size="12.7998"
+ style="font-style:normal;font-weight:normal;font-size:12.79979992px;font-family:sans-serif;text-anchor:start;fill:#000000"
+ x="639"
+ y="957.43585"
+ id="text4599">
+ <tspan
+ x="639"
+ y="957.43585"
+ id="tspan4597">parse(&lt;File&gt;)</tspan>
+ </text>
+ <text
+ font-size="12.8"
+ style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sans-serif;text-anchor:end;fill:#000000"
+ x="739"
+ y="1141.6959"
+ id="text4603">
+ <tspan
+ x="739"
+ y="1141.6959"
+ id="tspan4601">&lt;State&gt;</tspan>
+ </text>
+ <g
+ id="g4609"
+ transform="translate(-1,-2.5641373)">
+ <rect
+ style="fill:#ffffff"
+ x="760"
+ y="920"
+ width="160"
+ height="300"
+ rx="60"
+ ry="60"
+ id="rect4605" />
+ <rect
+ style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2;stroke-linejoin:round"
+ x="760"
+ y="920"
+ width="160"
+ height="300"
+ rx="60"
+ ry="60"
+ id="rect4607" />
+ </g>
+ <text
+ font-size="16.9333"
+ style="font-style:normal;font-weight:700;font-size:16.93330002px;font-family:sans-serif;text-anchor:middle;fill:#000000"
+ x="839"
+ y="1062.476"
+ id="text4615">
+ <tspan
+ x="839"
+ y="1062.476"
+ id="tspan4611">Wyrd</tspan>
+ <tspan
+ x="839"
+ y="1083.6459"
+ id="tspan4613">Parser</tspan>
+ </text>
+ <g
+ id="g4623"
+ transform="translate(-1,-2.5641373)">
+ <path
+ style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2;stroke-linejoin:round"
+ d="m 1412.68,890.773 a 75.3596,75.3596 0 1 0 129.75,-8.347"
+ id="path4617"
+ inkscape:connector-curvature="0" />
+ <polygon
+ style="fill:#000000"
+ points="1412.12,890.492 1406.58,889.762 1416.32,884.279 1414.86,895.363 "
+ id="polygon4619" />
+ <polygon
+ style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
+ points="1412.12,890.492 1406.58,889.762 1416.32,884.279 1414.86,895.363 "
+ id="polygon4621" />
+ </g>
+ <text
+ font-size="12.8"
+ style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sans-serif;text-anchor:start;fill:#000000"
+ x="1159"
+ y="921.88586"
+ id="text4627">
+ <tspan
+ x="1159"
+ y="921.88586"
+ id="tspan4625">compute(&lt;State&gt;, &lt;Computation&gt;)</tspan>
+ </text>
+ <g
+ id="g4635"
+ transform="translate(-1,-2.5641373)">
+ <path
+ style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
+ d="m 1540,620 a 75,75 0 1 0 -125.29,-8.098"
+ id="path4629"
+ inkscape:connector-curvature="0" />
+ <polygon
+ style="fill:#000000"
+ points="1414.16,612.211 1416.66,607.211 1418.66,618.211 1408.66,613.211 "
+ id="polygon4631" />
+ <polygon
+ style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
+ points="1414.16,612.211 1416.66,607.211 1418.66,618.211 1408.66,613.211 "
+ id="polygon4633" />
+ </g>
+ <text
+ font-size="12.8"
+ style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sans-serif;text-anchor:end;fill:#000000"
+ x="1399"
+ y="541.69983"
+ id="text4639">
+ <tspan
+ x="1399"
+ y="541.69983"
+ id="tspan4637">&lt;Value&gt;</tspan>
+ </text>
+</svg>