#### [Spec](../) - [Data types](../types) - **Operators** - [Encoding](../encoding) **Please note:** This spec is a draft; any detail may change without warning. A list of what has been implemented can be found [here](https://github.com/ETHproductions/crayon/blob/master/info.txt). ### Operators Click on a category or operator to expand it. Key: - `N` - Number - `C` - Char (acts like `S` unless otherwise specified) - `S` - String - `A` - Array - `R` - Regex - `O` - Any type <a href="#" onclick='var show=this.innerText[0]==="E";for(var l=document.getElementsByClassName("expandable"),i=0;i<l.length;i++)l[i].parentElement.children[1].className=show?"":"hidden";this.innerText=show?"Collapse all":"Expand all"'>Expand all</a> <ul> <li> <a class="expandable">Canvas manipulation</a> <ul class="hidden"> <li>`→` - points the cursor E.</li> <li>`↘` - points the cursor SE.</li> <li>`↓` - points the cursor S.</li> <li>`↙` - points the cursor SW.</li> <li>`←` - points the cursor W.</li> <li>`↖` - points the cursor NW.</li> <li>`↑` - points the cursor N.</li> <li>`↗` - points the cursor NE.</li> <li>`⤸` - turns the cursor clockwise by 45 degrees.</li> <li>`⤵` - turns the cursor clockwise by 90 degrees.</li> <li>`↷` - turns the cursor clockwise by 135 degrees.</li> <li>`⟲` - turns the cursor by 180 degrees.</li> <li>`↶` - turns the cursor counter-clockwise by 135 degrees.</li> <li>`⤷` - turns the cursor counter-clockwise by 90 degrees.</li> <li>`⤹` - turns the cursor counter-clockwise by 45 degrees.</li> <li>`e` - moves the cursor E by 1 unit.</li> <li>`s` - moves the cursor S by 1 unit.</li> <li>`w` - moves the cursor W by 1 unit.</li> <li>`n` - moves the cursor N by 1 unit.</li> <li>`f` - moves the cursor forward by 1 unit.</li> <li>`F` - pops `N` and moves the cursor forward by `N`.</li> <li>`q` - draws the top item at the cursor and moves the cursor to the end of the drawn string.</li> <li>`Q` - like `q`, but removes the item from the stack.</li> </ul> </li> <li> <a class="expandable">Input</a> <ul class="hidden"> <li>`T` - inputs the next space-separated token.</li> <li>`L` - inputs the next line.</li> <li>`Z` - inputs a multi-line string, stopping at double newline or EOF.</li> <li>`E` - inputs all remaining input.</li> </ul> </li> <li> <a class="expandable">Control flow</a> <ul class="hidden"> <li>`z` - if TOS is truthy...</li> <li>`!` - if TOS is falsy...</li> <li>`=` - if top 2 items are equal...</li> <li>`<` - if top item is less than next item...</li> <li>`>` - if top item is greater than next item...</li> <li>`?` - delay execution of the previous conditional until here.</li> <li>`{` - else...</li> <li>`O` - for each item `I` and index `i` in TOS... <br>`I` is pushed before each iteration. <br>For numbers, loops through `[0..n)`. <br>If already in a loop, the outer loop uses `J` and `j`.</li> <li>`W` - while TOS is truthy...</li> <li>`}` - end-if/end-loop. Implicit at end of program.</li> </ul> </li> <li> <a class="expandable">Stack manipulation</a> <ul class="hidden"> <li>`[` - push an array and use it as the stack.</li> <li>`]` - exit array and push to stack. If not in array, wraps the entire stack in an array.</li> <li>`~` - use top array as the stack.</li> <li>`\` - swap top two items.</li> <li>`@` - pull up the third item.</li> <li>`:` - duplicate top item.</li> <li>`;` - remove top item.</li> <li>`.;` - push last removed item.</li> <li>`,` - duplicate from below?</li> <li>`l` - pull up `n`th item.</li> <li>`#`? - push the length of the stack.</li> </ul> </li> <li> <a class="expandable">Unary operations</a> <ul class="hidden"> <li> <a class="expandable">`N`</a> <ul class="hidden"> <li>`N` - no-op.</li> <li>`C` - convert to charcode.</li> <li>`S` - attempt to convert to number.</li> <li>`A` - sum.</li> </ul> </li> <li> <a class="expandable">`S`</a> <ul class="hidden"> <li>`N/C` - convert to string.</li> <li>`S` - no-op.</li> <li>`A` - join with (newline? empty string?).</li> </ul> </li> <li> <a class="expandable">`A`</a> <ul class="hidden"> <li>`N` - range; (`[0...N-1]`? `[1...N]`?)</li> <li>`C` - ???</li> <li>`S` - convert to an array of chars.</li> <li>`A` - no-op.</li> </ul> </li> <li> <a class="expandable">`(`</a> <ul class="hidden"> <li>`N/C` - decrement. `a-1`</li> <li>`S/A` - shift; remove first char/item and place on stack.</li> </ul> </li> <li> <a class="expandable">`)`</a> <ul class="hidden"> <li>`N/C` - increment. `a+1`</li> <li>`S/A` - pop; remove last char/item and place on stack.</li> </ul> </li> <li> <a class="expandable">`_`</a> <ul class="hidden"> <li>`N` - negate. `-a`</li> <li>`S/A` - reverse.</li> </ul> </li> <li> <a class="expandable">`~`</a> <ul class="hidden"> <li>`N` - bitwise NOT. `-a`</li> <li>`S` - eval.</li> <li>`A` - enter.</li> </ul> </li> <li> <a class="expandable">`.~`</a> <ul class="hidden"> <li>`N` - ???</li> <li>`S/A` - uniquify.</li> </ul> </li> <li> <a class="expandable">`F`</a> <ul class="hidden"> <li>`N` - move the cursor forward by `N`.</li> <li>`S` - ???</li> <li>`A` - flatten.</li> </ul> </li> <li> <a class="expandable">`l`</a> <ul class="hidden"> <li>`N` - bring up the `n`th item.</li> <li>`S/A` - pushes length. `"abc"l` → `"abc" 3` </li> </ul> </li> <li> <a class="expandable">`X`</a> <ul class="hidden"> <li>`N` - move to `x`.</li> <li>`S/A` - spread onto the stack.</li> </ul> </li> <li> <a class="expandable">`x`</a> <ul class="hidden"> <li>`N` - move by `x`.</li> <li>`S` - ???</li> <li>`A` - join with the empty string.</li> </ul> </li> <li> <a class="expandable">`Y`</a> <ul class="hidden"> <li>`N` - move to `y`.</li> <li>`S` - convert to array of charcodes.</li> <li>`A` - convert from array of charcodes.</li> </ul> </li> <li> <a class="expandable">`y`</a> <ul class="hidden"> <li>`N` - move by `y`.</li> <li>`S` - ???</li> <li>`A` - ???</li> </ul> </li> </ul> </li> <li> <a class="expandable">Binary operations</a> <ul class="hidden"> <li> <a class="expandable">`+`</a> <ul class="hidden"> <li>`NN` - adds two numbers. `a+b`</li> <li>`NC` - adds `a` to the charcode of `b`. ``3`a+ -> `d``</li> <li>`NS` - prepends the number to the string. `a+b`</li> <li>`SN` - appends the number to the string. `a+b`</li> <li>`SS` - concatenates the strings. `a+b`</li> <li>`AA` - concatenates the arrays. `a.concat(b)`</li> <li>`AO` - appends the item to the array. `a.push(b)`</li> <li>`OA` - prepends the item to the array. `b.unshift(a)`</li> </ul> </li> <li> <a class="expandable">`-`</a> <ul class="hidden"> <li>`NN` - subtracts two numbers. `a-b`</li> <li>`NC` - subtracts `a` from the charcode of `b`. ``3`d-`` → `` `a``</li> <li>`NS` - slice; if `n` is negative, keep only the last `n` chars of `s`; else, remove the first `n` chars of `s`.</li> <li>`SN` - slice; if `n` is negative, keep only the first `n` chars of `s`; else, remove the last `n` chars of `s`.</li> <li>`NA` - same as `NS`.</li> <li>`AN` - same as `SN`.</li> <li>`SS` - removes instances of `b` from `a`.</li> <li>`SR` - removes matches of `r` from `s`.</li> <li>`AA` - setwise subtraction; remove all items in `b` from `a`.</li> <li>`AO` - remove all instances of the item from the array.</li> </ul> </li> <li> <a class="expandable">`*`</a> <ul class="hidden"> <li>`NN` - multiplies two numbers. `a*b`</li> <li>`NS` - repeats `s` `n` times. `s.repeat(n)`</li> <li>`NA` - repeats `a` `n` times.</li> <li>`SS` - setwise addition? (concat, sort?, uniquify)</li> <li>`SR` - find all matches of `r` in `s`.</li> <li>`AA` - setwise addition? (concat, sort?, uniquify)</li> <li>`SA` - joins `a` with `s`. `a.join(s)`</li> </ul> </li> <li> <a class="expandable">`/`</a> <ul class="hidden"> <li>`NN` - divides two numbers. `a/b`</li> <li>`NS` - splits `s` into groups of `n` chars. `s.match(RegExp(".{1,"+n+"}","g")`</li> <li>`NA` - splits `a` into groups of `n` items.</li> <li>`SS` - splits `a` at occurances of `b`. `a.split(b)`</li> <li>`SR` - splits `s` at matches of `r`. `s.split(r)`</li> <li>`AA` - pairs arrays. `[0 1 2][3 4 5]/` → `[[0,3],[1,4],[2,5]]`</li> </ul> </li> <li> <a class="expandable">`%`</a> <ul class="hidden"> <li>`NN` - modulo two numbers. Always returns a positive number. `(a%b+b)%b`</li> <li>`NS` - unriffles `s` into `n` strings. `"abcde"2%` → `["ace""bd"]`</li> <li>`NA` - unriffles `s` into `n` arrays. `[1 2 3 4 5]2%` → `[[1 3 5][2 4]]`</li> <li>`SS` - riffles `a` with `b`. `"abc""123"% -> "a1b2c3"`</li> <li>`SR` - splits `s` into matches and non-matches of `r`. ``"a1b2cd"'`d'%`` → `["a""1""b""2""cd"]`</li> <li>`AA` - riffles arrays. `[0 1 2][3 4 5]%` → `[0 3 1 4 2 5]`</li> </ul> </li> <li> <a class="expandable">`&`</a> <ul class="hidden"> <li>`NN` - binary AND. `a&b`</li> <li>`NS` - ???</li> <li>`NA` - filter? `[1 2 3 2]2&` → `[2 2]`</li> <li>`SS` - setwise intersection of `a` and `b`. `"bar""abc"&` → `"ba"`</li> <li>`SR` - ???</li> <li>`AA` - setwise intersection of `a` and `b`.</li> </ul> </li> <li> <a class="expandable">`|`</a> <ul class="hidden"> <li>`NN` - binary OR. `a|b`</li> <li>`NS` - ???</li> <li>`NA` - ???</li> <li>`SS` - setwise addition of `a` and `b`. `"bar""abc"|` → `"barc"`</li> <li>`SR` - ???</li> <li>`AA` - setwise addition of `a` and `b`.</li> </ul> </li> <li> <a class="expandable">`^`</a> <ul class="hidden"> <li>`NN` - binary XOR. `a^b`</li> <li>`NS` - ???</li> <li>`NA` - ???</li> <li>`SS` - setwise XOR of `a` and `b`. `"bar""abc"^` → `"rc"`</li> <li>`SR` - ???</li> <li>`AA` - setwise XOR of `a` and `b`.</li> </ul> </li> <li> <a class="expandable">`g`</a> <ul class="hidden"> <li>`NN` - power. `a**b`</li> <li>`NS` - get char at index `n` in `s`.</li> <li>`NA` - get item at index `n` in `a`.</li> <li>`SS` - ???</li> <li>`SR` - ???</li> <li>`AA` - ???</li> </ul> </li> <li> <a class="expandable">`C`</a> <ul class="hidden"> <li>`NN` - move crayon to `x`, `y`.</li> <li>`AO` - index.</li> <li>`SO` - index.</li> </ul> </li> <li> <a class="expandable">`c`</a> <ul class="hidden"> <li>`NN` - move crayon by `x`, `y`.</li> <li>`AO` - last index.</li> <li>`SO` - last index.</li> </ul> </li> <li> <a class="expandable">`B`</a> <ul class="hidden"> <li>`NN` - convert `a` to array of base-`b` digits.</li> <li>`NS` - convert `s` to array of base-`n` digits?</li> <li>`NA` - convert `a` to base-`n` string?</li> <li>`SS` - ???</li> <li>`SR` - ???</li> <li>`AA` - ???</li> </ul> </li> <li> <a class="expandable">`b`</a> <ul class="hidden"> <li>`NN` - convert `a` to string of base-`b` digits, using the alphabet `0-9a-zA-Z$_`.</li> <li>`NS` - convert `s` from string of base-`n` digits.</li> <li>`NA` - convert `a` from array of base-`n` digits.</li> <li>`SS` - ???</li> <li>`SR` - ???</li> <li>`AA` - ???</li> </ul> </li> </ul> </li> <li> <a class="expandable">Unassigned tasks</a> <ul class="hidden"> <li> <a class="expandable">`N`</a> <ul class="hidden"> <li>convert to char</li> <li>range (inverse of `A` command, either `[0...N-1]` or `[1...N]`)</li> </ul> </li> <li> <a class="expandable">`S`</a> <ul class="hidden"> <li>transpose</li> <li>rotate</li> </ul> </li> <li> <a class="expandable">`A`</a> <ul class="hidden"> <li>transpose</li> <li>rotate</li> <li>sort</li> <li>self-riffle (`[1 2 3 4 5 6]` → `[1 3 5 2 4 6]`</li> </ul> </li> </ul> </li> </ul>