| summaryrefslogtreecommitdiff | 
diff options
Diffstat (limited to 'content/fate_v1')
23 files changed, 1145 insertions, 0 deletions
| diff --git a/content/fate_v1/_index.md b/content/fate_v1/_index.md new file mode 100644 index 0000000..8b90a7a --- /dev/null +++ b/content/fate_v1/_index.md @@ -0,0 +1,162 @@ +--- +title: "Fate (Version 1)" +menuTitle: "Fate" +--- + +When using Tonkadur, Fate is the language the author writes in. This language is +meant to provide the writer with as many tools as possible, so that they do not +feel constrained by the limitations of the language, nor find writing complex +narratives tedious. + +## A few warnings first + +Fate uses strong typing. This is intended to make detection of mistakes easier, +but may lead to some frustrations for authors only used to languages using +dynamic typing. + +Fate does not have any special features for multi-seating/multi-player +narratives. This is by design, as adding proper support for this would make the +underlying language more complex, and thus would make it harder to create an +interpreter for it. This is however something considered for an extension +(see +[this GitHub issue about it](https://github.com/nsensfel/tonkadur/issues/5)). + +You'll need to learn parentheses management, if you make anything complex. Fate +uses a LISP inspired syntax, so parentheses are everywhere. The syntax gives you +free reign over indentation, but so many parentheses does require at least some +discipline in order to be readable. + +Fate is meant to be compiled. This does add an extra step to your existing +process. + +Fate is very much a new language. There isn't many (any?) tools for it. + +If for some reason you want to perform memory allocation, there is no automatic +garbage collection, so you will have to free whatever you allocate. + +In what may seem weird for narrative scripting, Fate does not feature string +manipulation operations. Strings can be made into rich text, with complex +attributes, but you will not be able to use things like regular expressions +(or anything other than simple concatenation, really) with just the base +language. This is because of these operations would need to be implemented +directly by the interpreter anyway, and their use isn't actually common in +a narrative description, which would make requiring support for them of +any Tonkadur interpreter problematic. + +## Some nice features + +If you haven't closed the tab yet, here are some reasons why you *might* want +to use Fate. + +It *is* a LISP inspired syntax. If that's what you like, you might even enjoy +this take on it. There's no fiddling with indentation, no wondering what symbol +does what. It's all about parentheses indicating something is performed on a +list of other things. It's not a purely functional language, though. In fact, +it's a mix of both declarative and imperative programming: sequences (or +procedures) are imperative. Computations are functional. There are lambda +functions, but they're strongly typed. Collections and structures can only be +modified through specific instructions, so it's not quite really a LISP-like +language. + +There are pointers. Oh, come on, it's a plus, *right?* This makes it a lot +easier to refer to things. There's no pointer arithmetic, so you don't have to +worry about the scary stuff. Also, this lets you allocate memory, which is +useful when you want a unspecified amount of distinct instances of something. +Want to describe a story where the player can push a button as many time as +they choose, create a clone of a creature every time they do so, yet let them +fight any of these creature as their distinct instance? Well, with memory +allocation and pointers, it's easily done. Didn't you know? When writing a +narrative, the RAM's the limit. So yeah, maybe don't forget to `free` the +thousands of monster the player will no doubt create. + +You can do recursion. Wait! I *am* listing the nice features! Do people really +not like recursion and pointers? Oh, well... Still, you can do recursions with +both procedures and lambda functions. Not a fan of recursion? That's alright, +you also have imperative loops: `for`, `while`, `do_while`, and even +`for_each`. + +## The basics + +#### Procedures (or Sequences) and Instructions +Procedures are lists of instructions and things to display. Instructions can be +applied to values, but they themselves do not return any value.  Any value not +part of an instruction found in a procedure is displayed. Any value being part +of an instruction is **not** displayed. + +One way to think about it is to consider procedures as being actually two types +of things: sequences and procedures. A sequence is then a scene in the story, +and a procedure is just a construct called upon to perform instructions. + +Procedures can take arguments. Values are passed by copy. + +Procedures can be called in two ways: a `call` or a `jump`. A `call` will +perform the procedure before continuing with the current sequence of +instructions. A `jump` will perform the procedure **instead of** the +**current** sequence of instructions. + +Procedures can be called before their definition. The compiler will simply tell +you if the definition ends up being incompatible or missing. + +#### Computations +Computations are operations returning a value. Computations do not modify +anything, they simply return the result of an operation. + +A special type of computation, called *lambda function*, allows the creation of +a computation that will be performed only when called upon. Those can take +parameters. What's the use of something as advanced in a narrative scripting +language? It's convenient when you want to express something like a character's +name who depends on what the player figured out. Sure, you *could* make each +instance of the name feature a series of tests to find which value to use, or +you could just use a lambda function and just put +`(eval name_of_mysterious_character)` to get the right value. + +One last thing about lambda functions, which really are the only potentially +complicated thing about computations: these *are* computations, so you can use +them as such. They also cannot modify anything, as they only contain +computations and not instructions. + +#### Declarations and First Level Instructions +Declarations and First Level Instructions are a special type of instruction +which can only be done from outside a procedure. This distinction means that, +for example, you cannot define a procedure from within a procedure. + +#### Events +Sometimes, you might need to communicate something to the interpreter which +cannot be expressed in Fate. For example, you might want to say: "pause for 30 +seconds", or "play this music". This kind of thing has been considered to not +be generic enough to mandate every interpreter supports it. Instead, events are +used. + +Events are first declared, by being given a name and a list of types +corresponding to the parameters they take. Then, the `(event ...)` instruction +can be used to indicate that a certain event should occur. This will pause the +execution, and make the interpreter react to the event before continuing. + +The effect of an event is purely the interpreter's responsibility. It cannot be +described in Fate. Thus, you will need to refer to the interpreter you use to +see what events are available. + +#### Types +The basic `string`, `int`, `float`, and `bool` types are what one would expect. + +`rich_text` corresponds to text decorations, see the text effect sub-section. + +Two collection types are available: `(list [TYPE])` is a list of `[TYPE]` +elements, and `(set [COMPARABLE])` is a set of `[COMPARABLE]` elements. + +`(ptr [TYPE])` is an address to a value of type `[TYPE]`. + +Structures can be defined. They may contain other structures, but cannot be +recursive: only already defined types can be used. Pointers cannot be used to +resolve this conundrum in this version of Fate, but it may be added in the next +version (see [this GitHub +issue](https://github.com/nsensfel/tonkadur/issues/6)). + +#### Player Choices +Inputs from the players are limited to the `(player_choice ...)` instruction. +It presents the player with `rich text` options to choose from, which execute +an associated list of instructions if chosen. + +More complicated inputs, such as retrieving a `string` or an `int` from the +player require the definition and use of events. + diff --git a/content/fate_v1/aliases/default.md b/content/fate_v1/aliases/default.md new file mode 100644 index 0000000..9a6bd8a --- /dev/null +++ b/content/fate_v1/aliases/default.md @@ -0,0 +1,41 @@ +--- +title: Aliases +--- +Nearly all computations and instructions have aliases, making it easier to +write in the language when not used to it. This page provides most of them.  As +a general rule, all underscores (`_`) are optional, all `declare` can be +replaced by `define` and `def`. + +* `abs`: `absolute`. +* `and`: `/\`. +* `>=`: `greater_equal_than`, `ge`. +* `/`: `divide`, `div`. +* `=`: `==`, `equals`, `eq`. +* `declare_alias_type`: `declare_sub_type`, `typedef`. +* `declare_structure_type`: `declare_structure`, `declare_dict_type`, +  `declare_dict`. +* `declare_event_type`: `declare_event`. +* `declare_sequence`: `declare_seq`, `declare_procedure`, `declare_proc`. +* `ignore_error`: `ignore_warning`. +* `free`: `release`, `destroy`. +* `implies`: `=>`, `->`. +* `is_member`: `contains`, `has`. +* `=<`: `<=`, `lower_equal_than`, `le`. +* `<`: `lower_than`, `lt`. +* `-`: `minus` +* `min`: `minimum`. +* `max`: `maximum`. +* `eval`: `evaluate`. +* `%`: `mod`, `modulo`. +* `new`: `reserve`, `create`. +* `not`: `~`, `!`. +* `add_element`: `add`. +* `one_in`: `exactly_one_in`, `exactly_one`, `one`. +* `remove_at`: `remove_element_at`, `remove_elem_at`. +* `set`: `set_value`, `set_val`, `set_variable`, `set_var`. +* `var`: `variable`. +* `visit`: `call`, `call_sequence`, `call_procedure`, `call_seq`, `call_proc`, +   `visit_sequence`, `visit_procedure`, `visit_seq`, `visit_proc`. +* `jump_to`: `continue_as`, `continue_to`, `continue_with`, `jump`, `go_to`, +  `exec`.  And you can suffix `_proc`, `_procedure`, `_seq`, or `_sequence` to +  any of these. diff --git a/content/fate_v1/computations/_index.md b/content/fate_v1/computations/_index.md new file mode 100644 index 0000000..9312712 --- /dev/null +++ b/content/fate_v1/computations/_index.md @@ -0,0 +1,138 @@ +--- +title: Computations +--- +Computations are values. They may read from the memory, but do not modify it +(with a single exception). + +### TEXT +{{< fatecode >}}(text [C0 = COMPUTATION] ... [CN = COMPUTATION]){{< /fatecode >}} + +Returns a `text` node containing the text representation of `C0` ... `CN`. + +### VARIABLE | REFERENCE +{{< fatecode >}}(var {String}){{< /fatecode >}} + +Returns the value of the variable `{String}`, or a reference to it if +applicable. Structure members can be accessed by using `.` in `{String}`. + +### STRUCTURE FIELD ACCESS +{{< fatecode >}}{Structure Var Name}.{Field Name}{{< /fatecode >}} +{{< fatecode >}}(field [STRUCTURE VAR] {String}){{< /fatecode >}} + +Accesses the `{String}` field of the structure `<STRUCTURE_VAR>`. Using `.` to +access fields is recommended over the use of this operator. + +### STRUCTURE FIELD VALUE +{{< fatecode >}}(get_field [STRUCTURE] {String}){{< /fatecode >}} +Returns the value of the `{String}` field of the structure `[STRUCTURE]`. + +### TEMPORARY VARIABLES +{{< fatecode >}}(let (({V0 = String} [C0 = COMPUTATION]) ... ({VN = String} [CN = COMPUTATION])) [R = COMPUTATION]){{< /fatecode >}} + +Defines a hierarchical level and local variables `V0` ... `VN` with values `C0` ... `CN`, and returns the value of `[R]`. + +### CAST +{{< fatecode >}}(cast [TYPE] <COMPUTATION*>){{< /fatecode >}} + +Transforms `<COMPUTATION*>` into a value of type `[TYPE]`. Note that the variable +shorthand cannot be used for `<COMPUTATION*>`. The following type changes are +allowed: +* `[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]`. + +### RANDOM NUMBER +{{< fatecode >}}(rand [I0 = INT] [IN = INT]){{< /fatecode >}} + +Returns a random number between `I0` and `IN` (inclusive). + +## Basic Operators +### BOOL OPERATORS +{{< fatecode >}}(and [B0 = BOOL] ... [BN = BOOL]){{< /fatecode >}} + +Standard conjunction (minimum of 2 arguments). + +{{< fatecode >}}(or [B0 = BOOL] ... [BN = BOOL]){{< /fatecode >}} + +Standard disjunction (minimum of 2 arguments). + +{{< fatecode >}}(not [BOOL]){{< /fatecode >}} + +Standard negation. + +{{< fatecode >}}(implies [B0 = BOOL] [B1 = BOOL]){{< /fatecode >}} + +Standard implication. + + +{{< fatecode >}}(one_in [B0 = BOOL] ... [BN = BOOL]){{< /fatecode >}} + +true if, and only if, exactly one of the operands is true. + +### MATH OPERATORS +All operands must be of the same type, which is also the type returned by the +operation. + +{{< fatecode >}}(+ [N0 = NUMBER] ... [NN = NUMBER]){{< /fatecode >}} + +Standard addition (minimum of 2 arguments). + +{{< fatecode >}}(- [N0 = NUMBER] ... [NN = NUMBER]){{< /fatecode >}} + +Standard substraction (minimum of 2 arguments). + +{{< fatecode >}}(* [N0 = NUMBER] ... [NN = NUMBER]){{< /fatecode >}} + +Standard multiplication (minimum of 2 arguments). + +{{< fatecode >}}(/ [N0 = NUMBER] [N1 = NUMBER]){{< /fatecode >}} + +Standard division. Note that a division on integers is indeed a integer +division. + +{{< fatecode >}}(^ [N0 = NUMBER] [N1 = NUMBER]){{< /fatecode >}} + +Standard exponentiation. + +{{< fatecode >}}(% [I0 = INT] [I1 = INT]){{< /fatecode >}} + +Standard modulo operation. + +{{< fatecode >}}(min [N0 = NUMBER] ... [NN = NUMBER]){{< /fatecode >}} + +Lowest value among the operands. + +{{< fatecode >}}(max [N0 = NUMBER] ... [NN = NUMBER]){{< /fatecode >}} + +Highest value among the operands. + +{{< fatecode >}}(clamp [N0 = NUMBER] [N1 = NUMBER] [N2 = NUMBER]){{< /fatecode >}} + +Equivalent to `(min N0 (max N1 N2))`. + + +{{< fatecode >}}(abs [NUMBER]){{< /fatecode >}} + +Positive value of `[NUMBER]`. + +### COMPARISON OPERATORS +{{< fatecode >}}(= [C0 = COMPUTATION] ... [CN = COMPUTATION]){{< /fatecode >}} + +True if, and only if, all operands are equal. + +{{< fatecode >}}(< [C0 = COMPARABLE] [C1 = COMPARABLE]){{< /fatecode >}} + +True if, and only if, `C0` is strictly lower than `C1`. + +{{< fatecode >}}(=< [C0 = COMPARABLE] [C1 = COMPARABLE]){{< /fatecode >}} + +True if, and only if, `C0` is lower or equal to/than `C1`. + +{{< fatecode >}}(> [C0 = COMPARABLE] [C1 = COMPARABLE]){{< /fatecode >}} + +True if, and only if, `C0` is strictly higher than `C1`. + +{{< fatecode >}}(>= [C0 = COMPARABLE] [C1 = COMPARABLE]){{< /fatecode >}} + +True if, and only if, `C0` is higher or equal to/than `C1`. diff --git a/content/fate_v1/computations/collections/_index.md b/content/fate_v1/computations/collections/_index.md new file mode 100644 index 0000000..63c62cc --- /dev/null +++ b/content/fate_v1/computations/collections/_index.md @@ -0,0 +1,98 @@ +--- +title: Collections +--- +### ACCESS +{{< fatecode >}}(access [COLLECTION|COLLECTION PTR] [INT]){{< /fatecode >}} + +Returns the value of the `[INT]`th element in `[COLLECTION|COLLECTION PTR]`. + +### ACCESS CONSTANT INDEX +{{< fatecode >}}[(COLLECTION|COLLECTION PTR) VAR].{Integer}{{< /fatecode >}} + +Returns a variable corresponding to the `[INT]`th element in +`[(COLLECTION|COLLECTION PTR) VAR]`. + +### ACCESS POINTER +{{< fatecode >}}(access_pointer [(COLLECTION|COLLECTION PTR) VAR] [INT]){{< /fatecode >}} + +Returns a pointer to the `[INT]`th element in `[(COLLECTION|COLLECTION PTR) +VAR]`. + +### ADD ELEMENT AT +{{< fatecode >}}(add_element_at [INT] [COMPUTATION*] [LIST]){{< /fatecode >}} + +Returns a copy of `[LIST]` with `[COMPUTATION*]` added at index `[INT]`. Note +that `[COMPUTATION*]` does not allow use of the variable shorthand. + +### ADD ELEMENT +{{< fatecode >}}(add_element [COMPUTATION*] [COLLECTION]){{< /fatecode >}} + +Returns a copy of `[COLLECTION]` with `[COMPUTATION*]` added. If `[COLLECTION]` +is a `[LIST]`, then the element is added at the end of the list. +Note that `[COMPUTATION*]` does not allow use of the variable shorthand. + +### ADDING MEMBERS +{{< fatecode >}}(add_all_elements [C0 = COLLECTION] [C1 = COLLECTION]){{< /fatecode >}} + +Returns a copy of `[C1]`, with all the elements of `[C2]` added. If `[C1]` +is a `[LIST]`, the new members are added at the end of the list. + +### COUNT +{{< fatecode >}}(count [COMPUTATION*] [COLLECTION]){{< /fatecode >}} + +Returns the number of occurrences of `[COMPUTATION*]` in `[COLLECTION]`. +Note that `[COMPUTATION*]` does not allow use of the variable shorthand. + +### INDEX OF +{{< fatecode >}}(index_of [COMPUTATION] [COLLECTION]){{< /fatecode >}} + +Returns the index of the first occurrence of `[COMPUTATION]` in `[COLLECTION]`, +starting at 0. + +### IS MEMBER +{{< fatecode >}}(is_member [COMPUTATION] [COLLECTION]){{< /fatecode >}} + +Returns true if, and only if, `[COMPUTATION]` is in `[COLLECTION]`. + +### SIZE +{{< fatecode >}}(size [COLLECTION]){{< /fatecode >}} + +Returns the size (`[INT]`) of `[COLLECTION]`. + +### IS EMPTY +{{< fatecode >}}(is_empty [COLLECTION]){{< /fatecode >}} + +Returns true if, and only if `[COLLECTION]` is empty. + +### FILTER ELEMENTS +{{< fatecode >}}(filter [LAMBDA BOOL (X)] [X COLLECTION]){{< /fatecode >}} +{{< fatecode >}}(filter [LAMBDA BOOL (X Y0 ... YN)] [X COLLECTION] [Y0 COMPUTATION*] ... [YN COMPUTATION*]){{< /fatecode >}} + +Returns a copy of `[X COLLECTION]` in which only the elements for which +`<LAMBDA BOOL (X)>` returns `true` remain. If the lambda function needs extra +parameters, use the second syntax, which adds those parameters at the end of the +`(filter ...)` call. Note that the variable shorthand cannot be used for these +extra parameters. + +### FILTER ELEMENTS (INDEXED) +{{< fatecode >}}(indexed_filter [LAMBDA BOOL (INT X)] [X COLLECTION]){{< /fatecode >}} +{{< fatecode >}}(indexed_filter [LAMBDA BOOL (INT X Y0 ... YN)] [X COLLECTION] [Y0 COMPUTATION*] ... [YN COMPUTATION*]){{< /fatecode >}} + +Returns a copy of `[INT X COLLECTION]` in which only the elements for which +`<LAMBDA BOOL (INT X)>` (with `INT` being the element's index) returns `true` +remain. If the lambda function needs extra parameters, use the second syntax, +which adds those parameters at the end of the `(indexed_filter ...)` call. Note +that the variable shorthand cannot be used for these extra parameters. + +### FOLD OVER COLLECTION +{{< fatecode >}}(foldl [LAMBDA X (X Y)] [X COMPUTATION*] [Y COLLECTION]){{< /fatecode >}} +{{< fatecode >}}(foldl [LAMBDA X (X Y Z0 ... ZN)] [X COMPUTATION*] [Y COLLECTION] [Z0 COMPUTATION*] ... [ZN COMPUTATION*]){{< /fatecode >}} +{{< fatecode >}}(foldr [LAMBDA X (X Y)> [X COMPUTATION*] [Y COLLECTION]){{< /fatecode >}} +{{< fatecode >}}(foldr [LAMBDA X (X Y Z0 ... ZN)] [X COMPUTATION*] [Y COLLECTION] [Z0 COMPUTATION*] ... [ZN COMPUTATION*]){{< /fatecode >}} + +Returns the result of iterating `<LAMBDA X (X Y)>` over `[Y COLLECTION]`, with +`[X COMPUTATION*]` being the initial value. The direction of the iteration is +by ascending index order when using `foldl`, and the opposite order when using +`foldr`. Extra parameters for the lambda function can be passed as extra +parameters of the call. Note that the variable shorthand cannot be used for +those extra parameters, nor for the initial value. diff --git a/content/fate_v1/computations/conditionals/_index.md b/content/fate_v1/computations/conditionals/_index.md new file mode 100644 index 0000000..2953489 --- /dev/null +++ b/content/fate_v1/computations/conditionals/_index.md @@ -0,0 +1,54 @@ +--- +title: Conditionals +--- +This page presents the computation operators that allow a choice depending on +some condition. All possible returned values must be of the same type. + +### IF-ELSE +{{< fatecode >}}(if_else [BOOL] [C0 = COMPUTATION] [C1 = COMPUTATION]){{< /fatecode >}} + +Returns `C0` is `[BOOL]` yields true, `C1` otherwise. + +### COND +{{< fatecode >}}(cond ([B0 = BOOL] [C0 = COMPUTATION]) ... ([BN = BOOL] [CN = COMPUTATION])){{< /fatecode >}} + +Returns `<Ci>`, such that `<Bi>` is the first to hold true. If there is not such +`Bi`, returns `[CN]`. + +### SWITCH +{{< fatecode >}}(switch [T = COMPUTATION] ([V0 = COMPUTATION] [C0 = COMPUTATION]) ... ([VN = BOOL] [CN = COMPUTATION]) [D = COMPUTATION]){{< /fatecode >}}a + +Returns the first `Ci` such that `Vi` is equal to `T`. If there is not such +`Vi`, returns `[D]`. + +## Examples +{{< fatecode >}}(cond +   ((false) (false)) +   ((false) (false)) +   ((true) +      (cond +         ((false) (false)) +         ((true) (not (is_member 3 test_list))) +         ((true) (false)) +      ) +   ) +) +{{< /fatecode >}} + +{{< fatecode >}}(switch 3 +   (0 (false)) +   (1 (false)) +   (3 (true)) +   (2 (false)) +   (false) +) +{{< /fatecode >}} + +{{< fatecode >}}(if_else (true) +   (if_else (false) +      (assert (false) FAILED: instruction ifelse E) +      (set test_var (true)) +   ) +   (assert (false) FAILED: instruction ifelse F) +) +{{< /fatecode >}} diff --git a/content/fate_v1/computations/cons/_index.md b/content/fate_v1/computations/cons/_index.md new file mode 100644 index 0000000..5ece27b --- /dev/null +++ b/content/fate_v1/computations/cons/_index.md @@ -0,0 +1,22 @@ +--- +title: Cons +--- +Fate features a *construct* computation, making it possible to create an +anonymous structure by creating pairs of computations. Unlike collections, these +pairs do not have to be made of computations of the same type. + +### PAIRING +{{< fatecode >}}(cons [C0 = COMPUTATION*] [C1 = COMPUTATION*]){{< /fatecode >}} + +Returns the value corresponding to a pair made of `[C0]` and `[C1]`. Note that +the variable shorthand cannot be used for either parameter. + +### RETRIEVING THE FIRST ITEM +{{< fatecode >}}(car [CONS]){{< /fatecode >}} + +Returns the value corresponding to the first item in the `[CONS]` pair. + +### RETRIEVING THE SECOND ITEM +{{< fatecode >}}(cdr [CONS]){{< /fatecode >}} + +Returns the value corresponding to the second item in the `[CONS]` pair. diff --git a/content/fate_v1/computations/lambda_functions/_index.md b/content/fate_v1/computations/lambda_functions/_index.md new file mode 100644 index 0000000..35485a3 --- /dev/null +++ b/content/fate_v1/computations/lambda_functions/_index.md @@ -0,0 +1,30 @@ +--- +title: Lambda Functions +--- +Lambda functions are values that correspond to a computation not yet performed. +These can take arguments. Defining a lambda function returns the value that +corresponds to the function itself, the `eval` computation must be used to +obtain the value that the function computes. + +### DEFINITION +{{< fatecode >}}(lambda (([T0 = TYPE] {S0 = String}) ... ([TN = TYPE] {SN = String})) [COMPUTATION]){{< /fatecode >}} + +Returns a lambda function taking `S0` ... `SN` of types `T0` ... `TN` as +arguments and evaluating to `[COMPUTATION]`. + +### EVALUATION +{{< fatecode >}}(eval [REFERENCE] [C0 = COMPUTATION] ... [CN = COMPUTATION]){{< /fatecode >}} + +Returns the result of evaluating the lambda function at `[REFERENCE]` given the +parameters `C0` ... `CN`. + +## Examples +{{< fatecode >}}(lambda ( (int i) ) +   (+ (var i) 1) +) +{{< /fatecode >}} + +{{< fatecode >}}(lambda ( (int i) ) +   (* (eval int_to_int (var i)) 2) +) +{{< /fatecode >}} diff --git a/content/fate_v1/computations/references/_index.md b/content/fate_v1/computations/references/_index.md new file mode 100644 index 0000000..ba5716a --- /dev/null +++ b/content/fate_v1/computations/references/_index.md @@ -0,0 +1,18 @@ +--- +title: References +--- +### VALUE ACCESS +{{< fatecode >}}(at [ADDRESS]){{< /fatecode >}} + +Returns the variable at `[ADDRESS]`. + +### ALLOCATION +{{< fatecode >}}(new [TYPE]){{< /fatecode >}} + +Returns the address of a new variable of type `[TYPE]`. Don't forget to call +`free` on it once you're done. + +### ADDRESS +{{< fatecode >}}(ptr [COMPUTATION VARIABLE]){{< /fatecode >}} + +Returns the address of `[COMPUTATION VARIABLE]`. diff --git a/content/fate_v1/computations/rich_text/_index.md b/content/fate_v1/computations/rich_text/_index.md new file mode 100644 index 0000000..7351a5c --- /dev/null +++ b/content/fate_v1/computations/rich_text/_index.md @@ -0,0 +1,11 @@ +--- +title: Rich Text +--- +### RICH TEXT +{{< fatecode >}}(rich_text [TEXT]){{< /fatecode >}} + +### ADD TEXT EFFECT +{{< fatecode >}}(add_text_effect ({String} [P0 = COMPUTATION] ... [PN = COMPUTATION]) [RICH TEXT]){{< /fatecode >}} + +### NEW LINE +{{< fatecode >}}(newline){{< /fatecode >}} diff --git a/content/fate_v1/declarations/_index.md b/content/fate_v1/declarations/_index.md new file mode 100644 index 0000000..013d404 --- /dev/null +++ b/content/fate_v1/declarations/_index.md @@ -0,0 +1,5 @@ +--- +title: "Declarations" +menuTitle: "Declarations" +chapter: true +--- diff --git a/content/fate_v1/declarations/events/_index.md b/content/fate_v1/declarations/events/_index.md new file mode 100644 index 0000000..5493cd7 --- /dev/null +++ b/content/fate_v1/declarations/events/_index.md @@ -0,0 +1,18 @@ +--- +title: Events +--- +Events are how a Fate narrative can communicate to the interpreter that +something which cannot be expressed in Fate needs to be performed. The execution +is paused until the event is resolved by the interpreter. To avoid mistakes, any +event type must be declared before use. + +#### EVENT +{{< fatecode >}}(declare_event_type {string} [C0 = TYPE] ... [CN = TYPE]){{< /fatecode >}} +**Effect:** An event with the name `{string}` and taking parameters of types +`[C0]`, ..., `[CN]` can be used. + +## Examples +* `(declare_event_type user_string_input rich_text (ptr string))` +* `(declare_event_type wait int)` +* `(declare_event_type set_background_to string)` +* `(declare_event_type rumble)` diff --git a/content/fate_v1/declarations/files/_index.md b/content/fate_v1/declarations/files/_index.md new file mode 100644 index 0000000..05c6836 --- /dev/null +++ b/content/fate_v1/declarations/files/_index.md @@ -0,0 +1,48 @@ +--- +title: File Management +--- +Fate narratives have one main file, but this file can use the contents of other +files, and these files in turn can also use the contents of other files. Three +issues arise then: some things must be declared before they are used, nothing +should be declared multiple times, and where are the files? + +The absolute path to each file is computed in order to detect whether it has +already been loaded. The given paths are expected to be relative. They are then +resolved by attempting access from the following, in order: the current file's +directory; the include directories passed as parameter to the executable; the +calling executable's directory. + +Dependency cycles will raise compiling errors. + +The first "instruction" on each file must be `(fate_version 1)`. Values cannot +be placed before either, obviously. + +{{< fatecode >}}(require {string}){{< /fatecode >}} + +**Effect:** If the file at `{string}` has not yet been loaded, load it. + +{{< fatecode >}}(include {string}){{< /fatecode >}} + +**Effect:** Load the `{string}`, even if it has already been loaded. + +#### Examples +* `(require bonus_sequence.fate)` +* `(include types/plant.fate)` +* `(require ../guild/merchants.fate)` +* `(include ../what/../are/../you/../doing/../there.fate)` +* `(require oh/../oh/../oh/../this_is_fine.fate)` + +Example of Fate file: +{{< fatecode >}};;; A story of great importance +(fate_version 1) + +(require include/events.fate) +(require include/text_effects.fate) + +(require scenes/the_holiday_forest.fate) + +`Twas a long time ago... Longer now that it seems... In a place that can't be +referenced here because I'm pretty sure the transcript is copyrighted. + +(jump_to not_the_tree_door_i_would_have_chosen) +{{< /fatecode >}} diff --git a/content/fate_v1/declarations/sequences/_index.md b/content/fate_v1/declarations/sequences/_index.md new file mode 100644 index 0000000..8bdb30e --- /dev/null +++ b/content/fate_v1/declarations/sequences/_index.md @@ -0,0 +1,113 @@ +--- +title: Sequences and Procedures +--- +Sequences and procedures are the same thing. These are named lists of +instructions and values, which can be called upon at any point where +instructions can be used. They can take parameters. + +Procedures do not return values. It is however possible to emulate something +similar, by passing a pointer as a parameter and storing a "return" value into +it. + +These are also intended to be used to describe scenes. + +The execution of a sequence can be terminated by using the `(done)` +instruction.  The execution of the narrative can be terminated by using the +`(end)` instruction. + +Any value not part of an instruction will simply be displayed when it is +reached during the procedure's execution. + +Sequences can be used before their definition, the compiler will raise an error +if the use ends up being incorrect. + +Execution of a sequence can be started in two ways: `(call sequence_name)` will +execute the sequence then continue with the execution of the current +instruction list; `(jump_to sequence_name)` will replace the current +instruction list by the execution of the sequence. If one were to ignore +variables, the `(jump_to sequence_name)` instruction is similar to performing +`(call sequence_name) (done)`. + +{{< fatecode >}}(define_sequence {String} (([C0 = TYPE] {V0 = String}) ... ([CN = TYPE] {VN = String})) <I0 = INSTRUCTIONS|VALUE> ... <IM = INSTRUCTIONS|VALUE>){{< /fatecode >}} +**Effect:** Defines the sequence `{String}`, with variables `V0` ... `VN` of types `C0` ...`CN` as parameters, and instructions `I0` ... `IM` as content. + +**Acceptable Aliases:** `declare_sequence`, `def_seq`, `define_procedure`, `declare_procedure`, `def_proc`. + +#### Examples +{{< fatecode >}}(define_sequence in_your_room () +   (ifelse +      (is_member visited_your_room progress) +      (text_effect narrator +         You room is still a mess. You don't have time to clean things up, +         though. +      ) +      (text_effect narrator +         You room is a mess. You recall having been through every drawer while +         preparing your bag yesterday. While still unclear on how you are +         supposed to pack all the necessary things for what promises to be at +         least a year-long journey inside a small backpack, you cannot avoid +         but wasting more time contemplating the piles of items that didn't +         make the cut. +      ) +   ) +   (add visited_your_room progress) +   (player_choice +      ( +         ( Look for healing items ) +         (jump_to look_for_healing_items) +      ) +      ( +         ( No time! Let's go adventuring! ) +         (jump_to leave_your_room) +      ) +   ) +) +{{< /fatecode >}} + +{{< fatecode >}}(define_sequence index_of_loop +   ( +      ((ptr int) result_holder) +      ((list int) collection) +      (int target) +   ) +   (local int collection_size) +   (local int i) + +   (set collection_size (size collection)) + +   (for (set i 0) (< (var i) (var collection_size)) (set i (+ (var i) 1)) +      (if (= (access collection (var i)) (var target)) +         ( +            (set (at result_holder) (var i)) +            (done) +         ) +      ) +   ) +   (set (at result_holder) -1) +) +{{< /fatecode >}} + + +{{< fatecode >}}(define_sequence index_of_jump +   ( +      ((ptr int) result_holder) +      ((list int) collection) +      (int target) +      (int i) +      (int collection_size) +   ) +   (ifelse (= (var i) (var collection_size)) +      (set (at result_holder) -1) +      (ifelse (= (access collection (var i)) (var target)) +         (set (at result_holder) (var i)) +         (jump index_of_jump +            (var result_holder) +            (var collection) +            (var target) +            (+ (var i) 1) +            (var collection_size) +         ) +      ) +   ) +) +{{< /fatecode >}} diff --git a/content/fate_v1/declarations/text_effects/_index.md b/content/fate_v1/declarations/text_effects/_index.md new file mode 100644 index 0000000..3bf7a08 --- /dev/null +++ b/content/fate_v1/declarations/text_effects/_index.md @@ -0,0 +1,31 @@ +--- +title: Text Effects +--- +Text effects are attributes that can be given to rich text elements. The +effects themselves can take parameters. To avoid errors that would be difficult +to detect, Tonkadur expects text effects to be declared before being used. +Note that multiple text effects can be applied to the same rich text elements, +so there is no need to create text effects that combine other text effects. + +Two text effects cannot have the same name, even if their parameter types +differ. + +Because text effects are handled by the interpreter, it is recommended to +overlay their use by lambda functions. This way, each interpreter can simply +expose its available text effects in a file, and the definition of the lambda +functions can thus be changed according to which interpreter is used without +having to go through the whole document. Furthermore, the name of text effects +exposed by the interpreter might not match the name that would make the most +sense to use within the narrative. + +### TEXT EFFECT +{{< fatecode >}}(declare_text_effect {Identifier} [T0 = TYPE] ... [TN = TYPE]){{< /fatecode >}} +Declares the text effect `{Identifier}`, with parameters of type `[T0]` ... +`[TN]`. + +## Examples +* `(declare_text_effect bold)` +* `(declare_text_effect speaker string)` +* `(declare_text_effect color int int int)` +* `(declare_text_effect font string)` +* `(declare_text_effect speaker_emotion string int)` diff --git a/content/fate_v1/declarations/types/_index.md b/content/fate_v1/declarations/types/_index.md new file mode 100644 index 0000000..9a3677f --- /dev/null +++ b/content/fate_v1/declarations/types/_index.md @@ -0,0 +1,61 @@ +--- +title: Types +--- +Fate is a strongly typed language. + +## Base Types +There are a few base types already defined: + +* `int`: an integer, which is a number *without* fractional component (e.g. `-3`, `0`, `3`). +* `float`: a number *with* a fractional component (e.g. `-3.14`, `0.0`, `3.9931`). +* `bool`: a Boolean (i.e. `(true)` or `(false)`). +* `string`: a list of characters, not including newlines (e.g. `bob`, +  `something else`, `日本のもの`, or `الاشياء العربية`). This cannot include +  computations: only hardcoded strings. + +* `text`: a list of computations, interpreted as text, which may have +  attributes. + +Pointers are also available: +* `(ptr [TYPE])`: a pointer to a memory element of type `[TYPE]` (e.g. `(ptr int)`, `(ptr (ptr string))`). +If you are not familiar with pointers, a pointer is a value corresponding to an address containing a memory element. +Accessing the value of the pointer yields the address, accessing the value pointed to by the value of the pointer yields the memory element. +Pointers to pointers can be made, in which case that memory element is also an address to yet another memory element. +Pointers still have to point to a definite type. Unlike in C, you cannot create a pointer to an unspecified type. + +Two collection types are available: +* `(list [TYPE])` +* `(set [COMPARABLE TYPE])` + +Lambda computations are available: +* `(lambda <r = TYPE> (<a0 = TYPE> ... <an = TYPE>))` is a type corresponding +  to a lambda function returning a value of type `r` and taking parameters of +  types `a0` ... `an`. + +### Common Type Groupings +* `[NUMBER]` corresponds to `int`, `float`. +* `[COLLECTION]` corresponds to `(list [TYPE])` and `(set [COMPARABLE TYPE])`. +* `[PRIMITIVE]` `int`, `float`, `bool`, `string`, `rich_text`. +* `[COMPARABLE]` corresponds to `int`, `float`, `bool`, `string`, `rich_text`, +  and `(ptr [TYPE])`. This indicates types for which operators such as `<` are +  defined. + +## Defining Your Own Types + +### Aliasing +{{< fatecode >}}(declare_alias_type [TYPE] {String}){{< /fatecode >}}. +**Effect:** Declares the type `{String}`. If `[TYPE]` is not a `[PRIMITIVE]`, +   `[TYPE]` and `{String}` are now two equivalent types. If `[TYPE]` is a +   `[PRIMITIVE]`, `{String}` is a subtype of `[TYPE]`. + +### Structures +{{< fatecode >}}(declare_structure_type {String} (<t0 = TYPE> {f0 = String}) ... (<tn = TYPE> {fn = String})){{< /fatecode >}}. + +## Examples + +{{< fatecode >}}(define_structure_type player +   (creature creature) +   ((list (ptr item)) inventory) +   (int money) +) +{{< /fatecode >}} diff --git a/content/fate_v1/declarations/variables/_index.md b/content/fate_v1/declarations/variables/_index.md new file mode 100644 index 0000000..153135c --- /dev/null +++ b/content/fate_v1/declarations/variables/_index.md @@ -0,0 +1,72 @@ +--- +title: Variables +--- +Variables are what hold values. Each variable has a type, which cannot be +changed. + +There are two variable scopes: local and global. A global variable can only be +declared outside of any sequence. A local variable can also be declared within a +sequence. Local variables can only be accessed within their context. In effect, +a local variable declared outside of a sequence cannot be accessed in any +sequence, and local variables cannot be accessed within lambda functions. Local +variables can override global variables within their context. + +The sole exception to accessing a local variable outside its context is done +through the use of pointers. Local variables live as long as the context +that declared them does. Accessed one through a pointer past that point is +likely to result in a runtime error and is, in any case, not to be done. + +Each sequence and lambda function defines its own context and thus does not +share local variable with the others. Instructions which themselves contain +instructions define hierarchies. Local variables defined within a hierarchical +level can be accessed in that level and inner level, but are not shared with +outer levels. For example: + +{{< fatecode >}}(if_else (var my_test) +   ( +      (local int my_var) ;; my_var (a) +      (set my_var 32) +   ) +   ( +      ;; my_var (a) is not defined here. +      (local int my_var) ;; my_var (b) +      (set my_var 42) +      (if (var my_other_test) +         ( +            (local int my_other_var) +            ;; Both my_other_var and my_var (b) are defined here +         ) +      ) +      ;; only my_var (b) is defined here +   ) +) +{{< /fatecode >}} + +Generic instruction lists do not generate a new level of hierarchy: + +{{< fatecode >}}( +   (local int my_var) +) +;; my_var is still defined. +{{< /fatecode >}} + +### LOCAL VARIABLE +{{< fatecode >}}(local [TYPE] {Identifier}){{< /fatecode >}} +Declares the local variable `{Identifier}` of type `[TYPE]`. + +### GLOBAL VARIABLE +{{< fatecode >}}(global [TYPE] {Identifier}){{< /fatecode >}} +Declares the global variable `{Identifier}` of type `[TYPE]`. + +## Example +{{< fatecode >}}(local string name_of_dog) + +(global (ptr int) index_of_result) + +;; Here is an amusing use of variables: +(global int something_unexpected) +(local int something_unexpected) +;; something_unexpected will not be the same variable within processes (which +;; will use the global variable) and outside of them (which will use the local +;; variable). For code readability reasons, I do not recommend doing this. +{{< /fatecode >}} diff --git a/content/fate_v1/extensions/_index.md b/content/fate_v1/extensions/_index.md new file mode 100644 index 0000000..01f7127 --- /dev/null +++ b/content/fate_v1/extensions/_index.md @@ -0,0 +1,4 @@ +--- +title: Extensions +--- +This page not available yet, sorry. diff --git a/content/fate_v1/instructions/_index.md b/content/fate_v1/instructions/_index.md new file mode 100644 index 0000000..51066d1 --- /dev/null +++ b/content/fate_v1/instructions/_index.md @@ -0,0 +1,48 @@ +--- +title: Instructions +--- +Instructions do not return values, but modify the memory in some way or +interact with the interpreter. Computations are valid instructions, and will be +automatically converted into `[TEXT]` to be displayed. + +### ASSERT +{{< fatecode >}}(assert [BOOL] [TEXT]){{< /fatecode >}} + +Raises the exception `[TEXT]` to the interpreter if `[BOOL]` yields +false. + +### DONE +{{< fatecode >}}(done){{< /fatecode >}} + +Completes the execution of the current sequence. + +### END +{{< fatecode >}}(end){{< /fatecode >}} + +Completes the execution of the script. + +### SET VALUE +{{< fatecode >}}(set [REFERENCE] [COMPUTATION]){{< /fatecode >}} + +Gives the value `[COMPUTATION]` to `[REFERENCE]`. + +### VISIT SEQUENCE +{{< fatecode >}}(visit {String} [C0 = COMPUTATION] ... [CN = COMPUTATION]){{< /fatecode >}} + +Visits the sequence named `{String}`, with `C0` ... `CN` as arguments. That +sequence does not need to already have been defined. Visiting a sequence means +that the execution of the current sequence continues once the visited sequence +has completed. + +### JUMP TO SEQUENCE +{{< fatecode >}}(jump_to {String} [C0 = COMPUTATION] ... [CN = COMPUTATION]){{< /fatecode >}} + +Jumps to the sequence named `{String}`, with `C0` ... `CN` as arguments. That +sequence does not need to already have been defined. Jumping to a sequence means +that the execution of the current sequence is replaced by that of the target +sequence. + +### INSTRUCTION LIST +{{< fatecode >}}([C0 = INSTRUCTION] ... [CN = INSTRUCTION]){{< /fatecode >}} + +Instruction corresponding to the execution of `[C0]` ... `[CN]` in order. diff --git a/content/fate_v1/instructions/collections/_index.md b/content/fate_v1/instructions/collections/_index.md new file mode 100644 index 0000000..8d646ee --- /dev/null +++ b/content/fate_v1/instructions/collections/_index.md @@ -0,0 +1,72 @@ +--- +title: Collections +--- +Fate supports two types of collections: `[LIST]`, which are basic, unordered +lists; and `[SET]`, which are ordered lists, but only useable with +`[COMPARABLE]` elements. + +### ADDING A MEMBER +{{< fatecode >}}(add_element! [COMPUTATION*] [COLLECTION VAR]){{< /fatecode >}} + +Adds `[COMPUTATION*]` to `[COLLECTION VAR]`. If `[COLLECTION VAR]` is a +`[LIST]`, the new member is added at the end of the list. Note that +`[COMPUTATION*]` does not support use of the variable shorthand. + +### ADDING A MEMBER AT INDEX +{{< fatecode >}}(add_element_at! [INT] [COMPUTATION*] [LIST VAR]){{< /fatecode >}} + +Adds `[COMPUTATION*]` to `[LIST VAR]` at index `[INT]`. If `[INT]` is less than +0, the element is added at the start of the list, and if `[INT]` is greater or +equal to the size of the list, the element is added at the end of the list. Note +that `[COMPUTATION*]` does not support use of the variable shorthand. + +### ADDING MEMBERS +{{< fatecode >}}(add_all_elements! [COLLECTION] [COLLECTION VAR]){{< /fatecode >}} + +Adds all the elements of `[COLLECTION]` to `[COLLECTION VAR]`. If +`[COLLECTION VAR]` is a `[LIST]`, the new members are added at the end of the +list. + +### EMPTYING COLLECTIONS +{{< fatecode >}}(clear [COLLECTION]){{< /fatecode >}} + +Removes all members of `[COLLECTION]`. + +### REMOVING MEMBER +{{< fatecode >}}(remove [COMPUTATION] [COLLECTION]){{< /fatecode >}} + +Removes the first member of `[COLLECTION]` equal to `[COMPUTATION]`. + +### REMOVING MEMBERS +{{< fatecode >}}(remove_all [COMPUTATION] [COLLECTION]){{< /fatecode >}} + +Removes all instances of  `[COMPUTATION]` from `[COLLECTION]`. + +### REMOVING AT INDEX +{{< fatecode >}}(remove_at [INT] [COLLECTION]){{< /fatecode >}} + +Removes the element of `[COLLECTION]` at `[INT]`. + +### REVERSING LISTS +{{< fatecode >}}(reverse [LIST]){{< /fatecode >}} + +Reverses the order of the members of `[LIST]`. + +### FILTER ELEMENTS +{{< fatecode >}}(filter! <LAMBDA BOOL (X)> [X COLLECTION VAR]){{< /fatecode >}} +{{< fatecode >}}(filter! <LAMBDA BOOL (X Y0 ... YN)> [X COLLECTION VAR] [Y0 COMPUTATION*] ... [YN COMPUTATION*]){{< /fatecode >}} +Modifies `[X COLLECTION VAR]` so that only the elements for which +`<LAMBDA BOOL (X)>` returns `true` remain. If the lambda function needs extra +parameters, use the second syntax, which adds those parameters at the end of the +`(filter! ...)` call. Note that the variable shorthand cannot be used for these +extra parameters. + +### FILTER ELEMENTS (INDEXED) +{{< fatecode >}}(indexed_filter! <LAMBDA BOOL (INT X)> [X COLLECTION VAR]){{< /fatecode >}} +{{< fatecode >}}(indexed_filter! <LAMBDA BOOL (INT X Y0 ... YN)> [X COLLECTION VAR] [Y0 COMPUTATION*] ... [YN COMPUTATION*]){{< /fatecode >}} +Modifies `[X COLLECTION VAR]` so that only the elements for which +`<LAMBDA BOOL (INT X)>` (with the `INT` being the element's index) returns +`true` remain. If the lambda function needs extra parameters, use the second +syntax, which adds those parameters at the end of the `(indexed_filter! ...)` +call.  Note that the variable shorthand cannot be used for these extra +parameters. diff --git a/content/fate_v1/instructions/conditionals/_index.md b/content/fate_v1/instructions/conditionals/_index.md new file mode 100644 index 0000000..e129b1b --- /dev/null +++ b/content/fate_v1/instructions/conditionals/_index.md @@ -0,0 +1,27 @@ +--- +title: Conditionals +--- +Allow the control of whether to execute instructions or not according to a +computation. Every conditional branch defines its hierarchy level, from the +local variables' point of view. + +### IF +{{< fatecode >}}(if [BOOL] [INSTRUCTION]){{< /fatecode >}} + +Executes `[INSTRUCTION]` if, and only if, `[BOOL]` yields true. + +### IF-ELSE +{{< fatecode >}}(if_else [BOOL] <IF_TRUE = INSTRUCTION> <IF_FALSE = INSTRUCTION>){{< /fatecode >}} + +Executes `<IF_TRUE>` if `[BOOL]` yields true, but `<IF_FALSE>` if it does not. + +### COND +{{< fatecode >}}(cond ([C0 = BOOL] [I0 = INSTRUCTION]) ... ([CN = BOOL] [IN = INSTRUCTION])){{< /fatecode >}} + +Executes `[II]`, such that `[CI]` is the first listed boolean to yield true. + +### SWITCH +{{< fatecode >}}(switch [T = COMPUTATION] ([C0 = COMPUTATION] [I0 = INSTRUCTION]) ... ([CN = COMPUTATION] [IN = INSTRUCTION]) [DEFAULT = INSTRUCTION]){{< /fatecode >}} + +Executes `[II]`, such that `[CI]` is the first listed computation to be equal +to `[T]`. Executes `[DEFAULT]` if there is no such `[CI]`. diff --git a/content/fate_v1/instructions/loops/_index.md b/content/fate_v1/instructions/loops/_index.md new file mode 100644 index 0000000..03c0f3b --- /dev/null +++ b/content/fate_v1/instructions/loops/_index.md @@ -0,0 +1,34 @@ +--- +title: Loops +--- +Allow the repetition of a group of instructions according to a computation. +Every loop body defines its hierarchy level, from the local variables' point of +view. + +### WHILE +{{< fatecode >}}(while [BOOL] [I0 = INSTRUCTION] ... [IM = INSTRUCTION]){{< /fatecode >}} + +Executes `[I0]` ... `[IM]` if, and as long as, `[BOOL]` yields true. + +### DO WHILE +{{< fatecode >}}(do_while [BOOL] [I0 = INSTRUCTION] ... [IM = INSTRUCTION]){{< /fatecode >}} + +Executes `[I0]` ... `[IM]`,  and does so again as long as, `[BOOL]` yields +true. + +### FOR +{{< fatecode >}}(for <pre = INSTRUCTION> [BOOL] <post = INSTRUCTION> [I0 = INSTRUCTION] ... [IM = INSTRUCTION]){{< /fatecode >}} + +Executes `<pre>`, then, if and as long as `[BOOL]` yields true, executes +`[I0]` ... `[IM]` followed by `<post>`. + +### FOR EACH +{{< fatecode >}}(foreach [COLLECTION] {String} [I0 = INSTRUCTION] ... [IM = INSTRUCTION]){{< /fatecode >}} + +Executes `[I0]` ... `[IM]` for each member of `[COLLECTION]`, in order. The current +member is stored in a new local variable named `{String}`. + +### BREAK +{{< fatecode >}}(break){{< /fatecode >}} + +Exits the current loop. diff --git a/content/fate_v1/instructions/player_choices/_index.md b/content/fate_v1/instructions/player_choices/_index.md new file mode 100644 index 0000000..a0dba20 --- /dev/null +++ b/content/fate_v1/instructions/player_choices/_index.md @@ -0,0 +1,31 @@ +--- +title: Player Choices +--- +Player choices are the main way to interact with the user, by presenting them +with a list of `[RICH TEXT]` choices, and executing a list of instructions +associated to the choice they have made. + +### CHOICE OPTION +{{< fatecode >}}([TEXT] [I0 = INSTRUCTION] ... [IN = INSTRUCTION]){{< /fatecode >}} + +Adds a choice showing `[RICH TEXT]` to the user, and executing `[I0]` ... `[IN]` +if chosen. + +### CHOICE PROMPT +{{< fatecode >}}(player_choice [C0 = CHOICE] ... [C1 = CHOICE]){{< /fatecode >}} + +Prompts the user to choose between `C0` ... `C1`. `[CHOICE]`. `[CHOICE]` is +either an option as shown above, a [conditional](../conditionals), or a +`for_each` (see [loops](../loops)) with `[CHOICE]` instead of `[INSTRUCTION]`. + +### 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]`. diff --git a/content/fate_v1/instructions/references/_index.md b/content/fate_v1/instructions/references/_index.md new file mode 100644 index 0000000..9beb132 --- /dev/null +++ b/content/fate_v1/instructions/references/_index.md @@ -0,0 +1,7 @@ +--- +title: References +--- +### DE-ALLOCATION +{{< fatecode >}}(free [POINTER]){{< /fatecode >}} + +Removes the memory element at `[POINTER]` from the memory. | 


