Forlog is a script language to define and process grammars.
The name Forlog comes from the old norse word forlǫg, which stands for fate or destiny.
The following shall be a short tutorial/guide to this script language.
You could also just load one of those examples and figure it out yourself:
ATTENTION: This manual was not written for the latest state of the language. Everything should work as stated in this manual, but not every working feature is listed here.
The basic structure of the grammar are production rules. A production rule is a simple replace mechanism. It replaces the rule call in the text with one of the rules possible outcomes. The outcome is selected randomly.
To define a production rule you simply write the name of the rule in one line. Production rule names must start with an upper case letter. Every following outcome definition is added to the current rule. A production rule can be defined like this:
RULE_NAME
An outcome is defined as the rest of a line starting with '>'.
>this is an outcome
>this is another outcome
An outcome can contain production rules itself. (But keep in mind, that this algorithm has not (yet) a detection for endless loops.)
A production rule can be called like this:
[RULE_NAME]
The [START] rule is the first rule to be called. Before any other rule is defined all outcomes are added to the [START] rule.
An outcome can be weighted with an integer like this:
#2>outcome1
>outcome2
In this case outcome1 is twice as likely to occure than outcome2. What basically happens is that outcome1 is added twice to the rule. So while
#1000>outcome1
#500>outcome2
would have the same chance for both outcomes, it is computational more expensive, since this rule now consists of 1500 outcomes instead of 3.
It is possible to produce an call a comined production rule from defined production rules. The so created production rule containes all outcomes of all combined rules and containes the weighting (since it's not more than the same outcome several times). The combined rules are separated by a '|'.
[RULE_1|RULE_2|...]
With this unknown language it's possible to store and call variables. A variable is called like a production rule, but variable names must start with a lower case letter.
[var_name]
To set a variable you use one of the following commands:
<set|var_name|value>
<set?|var_name|value>
The 'set' command in the first line sets the variable and overrides the old value, if it had one. The 'set?' command checks if a variable name has already assigned a value and if so doesn't override it.
The text given in the value field is processed like any other text, meaning that commands or production rules are processed depth first and before the value is actually written to the variable. The following outcome would resolve to 'a':
><set?|x|[RACE]>[x]
RACE
>Human
>Twi'lek
>Togruta
>Zabrak
The processor would read the set command, process the [RACE] production rule to one of its outcomes, write that to the variable x and then calls the variable with '[x]'.
The 'if' command compares two (depth first processed) statements and returns one statement based on that comparison.
<if|val_1|val_2|do|else>
The statements are processed in the occuring order. This means (val_1, val_2, do) or (val_1, val_2, else). This could be important if variables are set in one of the statements.
The following outcome would resolve to 'He was at home.' if the variable [gender] is 'male', otherwise it would resolve to 'She was at home.':
><if|[gender]|male|He|She> was at home.
My (still) unnamed language is a kind of WIP thing, so I'll collect known issues here to fix them later. If you find any problems or have suggestions please contact me on reddit under /u/ArdorDeosis!
Currently only ASCII characters can be used to name a production rule or variable.
Currently it's not possible to write nested commands like
><if|[x]|[y]|<set|z|true>|else>
I'm working on a solution. Meanwhile you can use this workaround:
><if|[x]|[y]|[R]|else>
R
><set|z|true>