# Syntax

## Comments

`#` is a comment, but only if followed by a space. My editor makes it easy to comment / uncomment lines of iogii if I just tell it to use ruby syntax for `.iog` files.

## Literals

Integers are any continuous sequence of digits. Leading 0's are a separate number.

    0050 -> 0 0 50

Chars are a `'` followed by a single character. `\` can escape `\`, `n` (newline), `0` (null character), `x00` for any two digit hexadecimal.

    '\x0a -> '\n'

Strings are enclosed in `""`, the last `"` can be omitted if it is the last thing in your program. `\` can also be used to escape `"`.

Identifiers (`[A-Za-z][A-Za-z0-9]*`) will be broken into individual characters if there is no op or variable by that name.

## `>` matching

This section assumes you have already read the intro on [looping and functions](index.html#looping).

End brackets (`>`) match with loop ops (`i iterate`, `e expand`, `f foldr`, and `m meld`) like parenthesis. Think of `iefm` as left brackets that all match with `>` as the right bracket.

If end brackets are missing, they are implicitly inserted at the first valid location. `i e f m` can use values from left, they are normal syntactic elements.

The value before `>` is passed to the matching `i e f m` op. The result of the op is returned after the `>`.

It is somewhat rare to have a `>` that could match with two different loop ops, or a loop op that could match with two different `>`. But in such cases it would be good to know how iogii decides what the match is: iogii maximizes function lengths for anything matching with `>` (while first prioritizing the maximum number of matches possible).

When developing code with nested loops, I recommend explicitly using `>` until you are ready to optimize, then [try to] make them implicit. If matching is confusing you, I recommend purposefully making a function error which causes iogii to error and print how things are matched. The easiest way to do this is first unwrap any input placement then end your program with `;` (which doesn't have a function after it so errors).

    0 foldr 1,2,3 + > succ > ;
    ---
    ERROR: 1:26 (;) unterminated function (stack is never rid of extra values again, functions can only return one value)
    0 foldr 1,2,3 + > succ > ;
        \           ?     /  ?
         \               /
          \             /
           \           /
            \         /
             \       /
              \     /
               \   /
                \ /

This error shows that the second `>` matched the `foldr` (to maximize function length). And that the first `>` is unmatched (which would cause an error anyway since the implicit value is unused). And finally that the `;` is unsatisfied as well.

Note that folds would always be invalid if there were only unary ops applied to the arg, so they will not implicitly close until there has been a binary op (or trinary). It is still possible to write completely jibberish folds, but detecting them would require looking at type level information, while bracket matching is done purely before this.

    0 foldr succ 1,2,3 + -> 9

The fold does not terminate after `succ`, but an `iterate` would.

    0 iterate succ 1,2,3 + -> [1,3,5]

### `>,`

This feature is obscure (I have never actually needed it in hundreds of programs written). But for the language to be able to express any arbitrary nesting of loops it is theoretically necessary.

You can proceed `>` with any number of `,`s. This causes that end bracket to match with a loop op (`i e f m`) that is to the right of where it would have matched (number of loop ops moved = number of `,`s). This is necessary if you wish to use an outer loop's var inside and inner loop's function.

For example, suppose we wanted to create a sequence where each next number is the sum of the numbers 1 to the previous number (without using the `sum` op).

With the `sum` op that would just be:

    2 iterate countTo sum > -> [2,3,6,21,231,...

Sum can be written as a fold from 0 (meld):

    meld [thing to sum] + >

So that would be:

    2 iterate meld [iterate loop var] countTo + end_meld end_iterate

So how do we do this? `iterate` represents where the loop var goes, so just put it where it goes!

    meld 2 iterate countTo + [end meld] [end iterate]

But the `[end iterate]` is last and it matches with the inner loop. That is what `>,` is for...

    meld 2 iterate countTo + > >, -> [2,3,6,21,231,...

The `>,` was used on the last end bracket because it moves matches to the right and without it it matches `meld` but we want it to match `iterate`.

Note that the other `>` isn't needed and we could have written this shortly as:

    m2i}+>, -> [2,3,6,21,231,...

This example is a bit contrived because we could have just used the `sum` op, but also because addition is commutative, so we actually could have swapped the order of the args which would have allowed us to write this without `>,`. But not all operations are commutative so this will sometimes be necessary.

`>,` could be useful for setting the implicit value inside a loop.

In even rarer cases where you would need multiple `>,`'s, the last `>,` is moved first and set in stone and once moved the next `>,` is handled, etc.

## Difference between function loop op and meta op functions

Loop ops and meta ops (`mdup` / `mpeek`) both take in a function after the op.

But meta ops can never match with `>`, they always implicitly close (because this would almost never be useful compared to using `=`, but could cause extra `>`s to be needed).

Loop ops and meta ops implicitly close in reverse order they are created. This makes them behave more intuitively although such an assumption is not actually required in iogii.

Meta ops ignore loop ops for matching closing purposes, but meta ops are not ignored by loop ops. This difference is because loop op endings must be calculated after parsing is complete since they could be explicitly ended. Whereas meta ops affect the stack size and their effects must be known while parsing is happing. (Another way of thinking about it is just that meta ops are parsed before loop ops are implicitly or explicitly matched - loop ops are just regular ops to them).

    5 mdup iterate + -> [5,10,15...

(because `mdup` closes imediately after the `iterate`), but:

    1 5 iterate mdup +
    ---
    ERROR: 1:5 (iterate) unterminated function (stack is never rid of extra values again, functions can only return one value)
    1 5 iterate mdup + duped_value
           ?      \ /

(because `iterate` doesn't terminate immediately after `mdup`, `mdup` pulls in another value to `+` on then the duped value is place with no more ops after it for `iterate` to bring it back down to one).

## Input Placement

As mentioned in [IO](io.html#placement) input placement can always be done implicitly by rotating your program so that the input would come first (then omit it). If you are using input multiple times, you have choices about which one you can make implicit.

## Implicit Values

If an op uses more args than there are items on the stack, it creates `implicit` args as needed (that is an actual op name you can use to simulate the effect as needed too).

If you have not set the implicit value using unmatched `>` then the implicit value is the value yielded by the innermost loop function you are in when it is consumed. (Which for the main program it is the input).

In this next example the implicit value is used in the main program so it is equivalent to input again:

    4
    ---
    *
    ---
    16

In this next example, iterate consumes the input as its starting value, then the function multiplies the loop variable by itself (since the implicit value is used which is that same loop variable).

    4
    ---
    iterate * >
    ---
    4
    16
    256...

If the input is empty and used as auto input, then it is removed and only implicit values are placed.

    4 iterate * >
    ---
    4
    16
    256...

If you are using input and implicit values, implicits are created as needed after your program is unrotated. So for example if this was your program:

    implicit implict [extra values] input [main program]

You could have written it as:

    [main program] [extra values]

But note that `[extra values]` cannot consume those implicits because there is no way to distinguish that from consuming the result of the main program.

### Summary of implicit value behavior

Implicit behavior is the first applicable item in this list:

1. Value set by an unmatched `>`
2. Loop value if consumed by an op inside a loop
3. Input (if auto parsing and non empty input).
4. Result of the first `}` occurring in your program after unwrapping input.
5. Nil

The input that can be placed by wrapping your program is special in that it is the input (if input is present), otherwise it is a regular implicit value too (essentially case 3. becomes first priority).

## `$`

`$` is the value of the innermost loop function it is in. (Outside of all loops it is input if present, implicit value otherwise).

    4 iterate $ * >
    ---
    4
    16
    256...

Use in main program:

    4
    ---
    $$*
    ---
    16

Here the implicit value is set to 4 and no input is present:

    4> del $$*
    ---
    16

### Unmatched End Brackets

If an end bracket cannot be matched, then it will act like a unary op that sets the implicit value with its arg (see [above](#implicitvalues) to learn more about the implicit value).

    5> ++ -> 15

You can set the implicit value multiple times. Each unmatched `>` sets any implicit values used between it and the next unmatched `>`. This wraps around to the beginning, so a single unmatched `>` sets the implicit value everywhere in the program.

    3>*>+ -> 18

## Other ways to use values multiple times

Postfix is perfect at representing expression trees, but what about when you need to use a value more than once (which would technically be a directed acyclic graph (DAG) not a tree)?

If that value is the loop value, you can just use `$`.

Or if it just so happens to be used at the left hand side of the tree you could set the implicit value and use it implicitly.

If it is used twice and only simple manipulation is done before combining the two uses, you can use one of `dup`, `mdup`, `peek`, or `mpeek`. These correspond to the 4 cases the S combinator (`Sxyz = xz(yz)`), for each of `x` or `y` being the identity function.

They can't be used to handle all cases because they don't take in arbitrarily complex functions as args (doing so would require `>` which would then not be shorter than iogii's other method, see below).

 `mdup ;` and `mpeek !` ops take a function just like looping ops, but this function does not match with `>`'s so it can only handle simple cases because it always ends implicitly. `>` would not be useful anyway since this would be the same number of characters as using set next var (see below). And this increases the chances of a loop function needing and extra `>` because the loop function's `>` got matched with one of these ops instead.

### `set`

`set` is assignment, the token following the `set` has the value before the `set` assigned to it. This overrides any other meaning of that token for the entire program (both before and after the `set`).

    1 2+ set foo foo -> 3 3

`let` is a `set` followed by a `del`.

These have long names because they are intended only for debugging since there is a shorter way to set vars...

## Set Next Var

`=` saves the top of the stack to the next available var. The next available var is a capital letter A-Z chosen in a special way so that you never overwrite an op that you want to use. How can it do that?! Find the largest gap between used letters and choose the next one. Technically it is the largest difference between starting runs of used letters (so that adding the use of the next var does not change the selection process).

So if you don't use any capital letter ops then the first use of `=` will save to `A`, and the next to `B`.

    5= A + -> 10

These values can be used before they are set since iogii is really just a bunch of timeless static definitions.

    A 5= + -> 10

If you use capital letter ops `A`, `C` and `W` now the largest gap is between `C` and `W` so the first use of `=` will save to `D`.

If you use so many `=` that you fill the largest gap completely it will not work, so there is a limit to how many times you can use this.

Note that you **MUST** use the saved value (otherwise it will think that an op you used is actually a variable being used).

Sometimes it can be tedious to find the largest gap yourself, you could use iogii to automatically find it by using a bunch of `=`s - more than there are consecutive capital letters (which will cause an error saying which var is unused).

    CWA === -> ERROR: 1:6 (=) Sets register 'D' but it is never used

Set Next Vars are powerful but I recommend using `set` as you develop your program and only switching to them at the end, since it would be tedious if you frequently change which capital letter ops you use in your code.

