{"id":15816679,"url":"https://github.com/andreas-schoch/dominoscript","last_synced_at":"2025-04-01T03:43:02.742Z","repository":{"id":251778383,"uuid":"838208551","full_name":"andreas-schoch/dominoscript","owner":"andreas-schoch","description":"A recreational stack-oriented concatenative two-dimensional non-linear self-modifying esoteric programming language that uses the dots on domino pieces to represent code.","archived":false,"fork":false,"pushed_at":"2024-10-22T07:16:32.000Z","size":3785,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-10-23T06:37:52.275Z","etag":null,"topics":["compiler","domino","domino-script","dominoscript","esolang","esoteric-programming-language","interpreter","programming-language","stack-oriented"],"latest_commit_sha":null,"homepage":"https://dominoscript.com/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/andreas-schoch.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-08-05T07:07:38.000Z","updated_at":"2024-10-22T07:16:35.000Z","dependencies_parsed_at":"2024-09-09T03:41:58.989Z","dependency_job_id":"aacd5ad6-5bbc-44be-a2ce-caffe627bd6e","html_url":"https://github.com/andreas-schoch/dominoscript","commit_stats":null,"previous_names":["andreas-schoch/dominoscript"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andreas-schoch%2Fdominoscript","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andreas-schoch%2Fdominoscript/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andreas-schoch%2Fdominoscript/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andreas-schoch%2Fdominoscript/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/andreas-schoch","download_url":"https://codeload.github.com/andreas-schoch/dominoscript/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246580461,"owners_count":20800108,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["compiler","domino","domino-script","dominoscript","esolang","esoteric-programming-language","interpreter","programming-language","stack-oriented"],"created_at":"2024-10-05T05:06:44.973Z","updated_at":"2025-04-01T03:43:02.722Z","avatar_url":"https://github.com/andreas-schoch.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"DominoScript\n================================================================================\n\n**Current version `0.5.0`**\n\nHave you ever wanted to write code using domino pieces? No?\n\nWell, now you can! Introducing DominoScript!\n\n\u003e [!NOTE]  \n\u003e A recreational stack-oriented concatenative two-dimensional non-linear self-modifying int32-based esoteric programming language that uses the dots on domino pieces to represent code.\n\nThis repository contains the reference implementation written in TypeScript as well as all the documentation and examples for the language.\n\nTry it in the [**Online Playground**](https://dominoscript.com/).\n\n**It's still very much a work-in-progress. Not everything is fully fleshed out yet.** Do you want to [contribute](#contributing)?\n\n\u003cp align=\"center\"\u003e\n  \u003cimg style=\"aspect-ratio: 1;\" src=\"docs/dominoscript-logo.png\" alt=\"Domino\" width=\"450\"\u003e\n\u003c/p\u003e\n\n## Table of Contents\n- **[Core Concepts](#core-concepts)**\n\n- **[How to run DominoScript](#how-to-run-dominoscript)**\n\n- **[How does it work](#how-does-it-work)**\n  - [Text Format](#text-format)\n  - [About the stack](#about-the-stack)\n  - [How to represent Strings](#how-to-represent-strings)\n  - [How to represent floating point numbers](#how-to-represent-floating-point-numbers)\n  - [How the Instruction Pointer Moves](#how-the-instruction-pointer-moves)\n  - [How Navigation Modes work](#how-navigation-modes-work)\n  - [How to read DominoScript](#how-to-read-dominoscript)\n\n- **[Instructions](#instructions)**\n  - [Stack Management](#stack-management)\n  - [Arithmetic](#arithmetic)\n  - [Comparison \u0026 Logical](#comparison-and-logical)\n  - [Bitwise](#bitwise) \n  - [Control Flow](#control-flow)\n  - [Input \u0026 Output](#input-and-output)\n  - [Misc](#misc)\n\n- **[Navigation Modes](#navigation-modes)**\n  - [Basic Three Way](#basic-three-way)\n  - [Basic Two Way](#basic-two-way)\n  - [Basic One Way](#basic-one-way)\n  - [Cycle Three Way](#cycle-three-way)\n  - [Cycle Two Way](#cycle-two-way)\n  - [Cycle One Way](#cycle-one-way)\n  - [Flip Flop](#flip-flop)\n\n- **[Error Types](#error-types)**\n\n- **[Contributing](#contributing)**\n\n- **[Roadmap](#roadmap)**\n\n- **[Examples](#examples)**\n\n\u003cbr\u003e\n\n## Core Concepts\n- **`Recreational Esolang`**: This isn't a serious programming language. I got inspired after watching \"The Art of Code\" by Dylan Beattie where I discovered \"Piet\" and eventually went down the esolang rabbit hole. I wanted to create a language that is not only weirdly powerful but can also look good when hanged on a wall.\n\n- **`Stack-Oriented`**: There is a global data stack that all instructions operate on. Internally every item on the stack is a signed 32-bit integer. Strings are just null-terminated sequences of integers representing Unicode char codes. Floats are not supported. No other data structures exist.\n\n- **`Concatenative`**: DominoScript at its core is just another concatenative reverse-polish language. The following code: `0—1 0—5 0—1 0—6 1—0 0—3 1—2 5—1` is the same as `5 6 + dup * .` in Forth.\n\n- **`Two-Dimensional`**: The code is represented on a rectangle grid. The instruction pointer can move in any cardinal direction. One domino takes up 2 cells on the grid. Direction changes are performed by placing dominos in a certain way (IP always moves from one half to the other half of the same domino) as well as the current [Navigation Mode](#how-navigation-modes-work).\n\n- **`Self-Modifying`**: The code can override itself similar to befunge.\n\n- **`Òbfuscated`**: Because all code is represented using domino pieces, reading it is somewhat like reading machine code. To \"de-obfuscate\" it you would need to replace the domino pieces with their corresponding instructions and literal values. The following: `NUM 5 NUM 6 SUM DUPE MULT NUMOUT` is a readable pseudocode representation of DominoScript.\n\n\u003cbr\u003e\n\n## How to run DominoScript\n\n\u003e [!WARNING]  \n\u003e Despite being well tested, the reference interpreter might not always work as expected. See the [Source code](https://github.com/andreas-schoch/dominoscript/tree/main/interpreters/node).\n\n\nThe easiest way to run DominoScript is the [**Online Playground**](https://dominoscript.com/) *(early prototype, might be more buggy than running it via the command line...)*.\n\n\nHowever, if you want to use dominoscript via the command line, you can install it globally like this:\n```\nnpm install -g dominoscript\n```\n\nThen you can run it like this:\n\n```\ndominoscript path/to/your/file.ds\n```\n\nOr you can use npx to run it without installing it:\n```\nnpx dominoscript path/to/your/file.ds\n```\n\n\u003cbr\u003e\n\n## How does it work\n\nDominoScript by default uses Double-Six (aka `D6`) dominos to represent code. Double-six here means that each domino has 2 sides with up to 6 dots on each side.\n\n\n\nEverything is either:\n- an instruction\n- a number literal\n- or a string literal\n\nUsing Double-Six dominos, we are essentially working with base7 numbers. This can be changed using the [BASE](#base) instruction.\n\nWith a higher base you can use dominos with more dots to represent larger numbers with fewer pieces.\n\n### The Grid\n\n- The grid is a rectangle of cells which can contain domino pieces.\n- The grid can contain up to 65408 cells (soft limit)\n- One domino takes up 2 cells and can be placed horizontally or vertically.\n- The top-left cell is address 0. The bottom-right cell is address `width * height - 1`.\n- When playing domino game variants you can usually place pieces \"outside\" the grid when both sides have the same number of dots: 🁈🁳🁀 - this is not allowed in DominoScript *(Maybe in future versions but for now not worth the extra complexity)*\n\nEach cell needs to be indexable using an `int32` popped from the stack, so in theory you could have something crazy like a 300k rows and columns. However, the interpreter will likely not be able to handle that. The artifical limit I decided on for now is a total of 65408 cells. That allows a square grid of `256x256` or various rectangular grids like `64x1024`, `128x512`, or `949x69` as long as the **total cell count is 65408 or less**. This limit will likely be configurable in future versions.\n\n### Text Format\n\nA text based format is used to represent domino pieces.\n\n\u003e [!NOTE]  \n\u003e This format is used as source code. At the beginning it will be the only way to write DominoScript until a visual editor is created that shows actual dominos. Eventually I want to be able to convert images of real dominos on a (reasonably sized) grid into the text format.\n\n- The digits `0` to `f` represent the dots on half of a domino. To indicate an empty cell, use a dot `.`\n- The \"long hyphen\" character `—` indicates a horizontal domino *(regular hyphen `-` also accepted to make it easier to type)*. It can only appear on **even** columns and **odd** rows.\n- The \"pipe\" character `|` indicates a vertical domino. It can only appear on **odd** columns and **even** rows.\n- Any other line \u003cins\u003ebefore\u003c/ins\u003e and \u003cins\u003eafter\u003c/ins\u003e the actual code is ignored.\n- It is just a text format, so the file extension doesn't matter for now. You can make it `.md` and comment using markdown if you want! [See example](./examples/002_hello_world_commented.md)\n\n**Example:**\n\n```markdown\nTITLE\n=====\n\nYou can write the soure code as a normal text file (.ds extension recommended) or as a .md file with markdown comments like here.\n\nBe aware of the following rules:\n\u003e 1. You cannot start a non-code line with a dot `.`\n\u003e 2. You cannot start a non-code line with a number `0 to f`\n\u003e 3. You cannot comment within the code. Only above and below it.\n\nFor comments starting with any non-allowed character, add a space or any other allowed char before it.\n\n## DominoScript\n\nThe below code NO-OPs forever because\nThe IP can always move to a new domino\n\n. . . . . . . .\n\n. 6 6 6—6 6 6 .\n  | |     | |\n. 6 6 6 6 6 6 .\n      | |\n. 6—6 6 6 6—6 .\n\n. 6—6 6—6 6—6 .\n\n. . . . . . . . \n\n\n## Some Notes\n\nBla bla bla\n  \n```\n\nWhen the source code is parsed it ignores everything except the actual code:\n\n```\n. . . . . . . .\n\n. 6 6 6—6 6 6 .\n  | |     | |\n. 6 6 6 6 6 6 .\n      | |\n. 6—6 6 6 6—6 .\n\n. 6—6 6—6 6—6 .\n\n. . . . . . . . \n```\n\nWhich is the equivalent of these dominos:\n\n\u003cimg style=\"margin: 0.5rem 0 2rem;\" src=\"docs/example-001-noop.png\" alt=\"Dominos\" width=\"400\"\u003e\n\n\nThe grid doesn't have to be a square but it must have a consistent number of columns and rows, otherwise an `InvalidGridError` will be thrown before execution starts:\n\n\u003ctable\u003e\n\u003ctr\u003e\n\u003cth\u003eGOOD ✅\u003c/th\u003e\n\u003cth\u003eBAD ❌\u003c/th\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n  \n```\n. . . . . . . .\n\n. . . . . . . .\n\n. . . . . . . .\n\n. . . . . . . .\n```\n  \n\u003c/td\u003e\n\u003ctd\u003e\n\n```\n . . . . . . .\n\n. . . . . . . .\n\n. . . . .\n\n. . .  . . . .\n```\n\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n\nConnecting to a domino half which is already connected results in `MultiConnectionError`:\n\n\u003ctable\u003e\n\u003ctr\u003e\n\u003cth\u003eGOOD ✅\u003c/th\u003e\n\u003cth\u003eBAD ❌\u003c/th\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n\n```\n6—6 6—6 .\n\n6 6—6 . .\n|\n6 . . . .\n```\n  \n\u003c/td\u003e\n\u003ctd\u003e\n\n```\n6—6—6—6 .\n\n6—6 . . .\n|\n6 . . . .\n```\n\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n\n\nHaving a domino half that is not connected to anything results in `MissingConnectionError`:\n\n\u003ctable\u003e\n\u003ctr\u003e\n\u003cth\u003eGOOD ✅\u003c/th\u003e\n\u003cth\u003eBAD ❌\u003c/th\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n\n```\n. . 6—6 .\n\n. 6 . . .\n  |\n. 6 . . .\n```\n  \n\u003c/td\u003e\n\u003ctd\u003e\n\n```\n. . 6 6 .\n\n. 6 . . .\n   \n. 6 . . .\n```\n\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n\nHaving a connection where 1 or both ends are empty results in a `ConnectionToEmptyCellError`:\n\n\u003ctable\u003e\n\u003ctr\u003e\n\u003cth\u003eGOOD ✅\u003c/th\u003e\n\u003cth\u003eBAD ❌\u003c/th\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n\n```\n6—6 . 6—6\n\n6 . . . 6\n|       |\n6 . . . 6\n```\n  \n\u003c/td\u003e\n\u003ctd\u003e\n\n```\n6—. . .—6\n\n6 . . . .\n|       |\n. . . . 6\n```\n\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n\n### About the stack\n\n- There is a single global stack that all instructions operate on.\n- It only stores signed 32-bit Integers\n- The interpreter will preallocate all the memory required to maintain the stack, therefore its size is limited to `512` items for now. (No particular reason for this rather small limit, it will likely be configurable in future versions)\n\n**Why not 64-bit integers?:** No good reason really. I wanted to implement the first reference interpreter in typescript and since JS converts numbers to 32-bit when doing bitwise operations, I decided to just stick with 32-bit integers instead of having to split the lower and upper 32-bits for every bitwise operation. If there is demand, I will change the spec to support 64-bit ints but for now it is what it is.\n\n### How to represent Strings\n\nDominoScript is a language where you cannot really tell what is going on just by looking at the code. It all depends on how the IP moves.\n\nWhen the IP encounters a [STR](#str) instruction, it will parse the next dominos as characters of a string. How that works exactly is explained in more detail in the description of the instruction.\n\n\u003e [!IMPORTANT]  \n\u003e It is important to understand that \u003cins\u003einternally\u003c/ins\u003e everything in DominoScript is represented as signed 32-bit integers and \u003cins\u003eexternally\u003c/ins\u003e everything is represented by the dots on the domino pieces.\n\u003cbr\u003e\u003cbr\u003eInternally strings are just \u003cins\u003enull-terminated sequences of integers representing Unicode char codes\u003c/ins\u003e. It is your job as the developer to keep track of which items on the stack are numbers and which ones are characters of a string.\n\nYou can use any instruction on characters of a \"string\" but most of them will not distinguish between what is a number and a character.\n\nSo far, there are only 7 instructions which are meant for the handling of strings: [STR](#str), [EQLSTR](#eqlstr), [STRIN](#strin), [STROUT](#strout) as well as [GET](#get) and [SET](#set) when used with a specific \"type\" argument.\n\nIn examples, you might see stack items that are meant to be char codes, represented in the following way:\"\n\n```\n[..., 'NUL', 's', 'e', 'y']\n```\n\nBut in reality, the stack will store them as integers and look like this:\n\n```\n[..., 0, 115, 101, 121]\n```\n\n### How to represent floating point numbers\n\nFloats don't exist in DominoScript. I'd suggest to scale up numbers by a factor of 10, 100, 1000 or whatever precision you need.\n\n*(I know that pico-8 uses 32-bits for numbers but treats them as 16.16 fixed point numbers. I am not quite sure if that is just a convention or if pico8's API actually treats them as fixed point numbers. I would like to eventually add some trigonometry instructions to DominoScript but am unsure what the most practical way would be)*\n\n### How the Instruction Pointer Moves\n\nThe instruction pointer (`IP`) keeps track of the current cell address that will be used for the next instruction. Since DominoScript is 2D and non-linear, it isn't obvious where the IP will move to without understanding the fundamental rules and the Navigation Modes.\n\n\u003cins\u003e**Before the program starts:** \u003c/ins\u003e\n- the interpreter will scan the grid from \u003cins\u003etop-left to top-right\u003c/ins\u003e, move down and repeat until it finds the first domino.\n- Upon reaching the first domino, the IP is placed at the address of the first found domino half.\n- If no domino could be found, the program is considered finished.\n\n\u003cins\u003e**During the program execution:**\u003c/ins\u003e The IP will adhere to the following rules:\n\n- \u003cspan id=\"rule_01\"\u003e**`Rule_01`**:\u003c/span\u003e The IP moves in all cardinal directions, never diagonally. How dominos are parsed, is all relative to that. For example, the horizontal domino `3—5` can be interpreted as the base7 number `35` (IP moves eastwards) or `53` (IP moves westwards). Same thing for vertical dominos.\n\n- \u003cspan id=\"rule_02\"\u003e**`Rule_02`**:\u003c/span\u003e The IP will always move from one half (entry) of the same domino to the other half (exit) of the same domino.\n\n- \u003cspan id=\"rule_03\"\u003e**`Rule_03`**:\u003c/span\u003e  If the IP cannot move to a new domino, the program is considered finished. If a `JUMP` happens to move to an empty cell, a `JumpToEmptyCellError` is thrown and the program terminates with a non-zero exit code.\n\n- \u003cspan id=\"rule_04\"\u003e**`Rule_04`**:\u003c/span\u003e At the exit half of a domino, the IP will never move back to the entry half. It will always try to move to a new domino. That means, there are at most \u003cins\u003e0 to 3 potential options for the IP to move\u003c/ins\u003e.\n\n- \u003cspan id=\"rule_05\"\u003e**`Rule_05`**:\u003c/span\u003e  When the IP needs to move to a new domino, it is possible that there are no valid moves despite there being dominos around. The [Navigation Mode](#how-navigation-modes-work) decides where the IP can and cannot move next.\n\n### How Navigation Modes work\n\nIn a nutshell: Navigation Modes are predefined priority patterns which change the way the Instruction Pointer moves.\n\n\u003e [!TIP]  \n\u003e Change navigation modes using the [NAVM](#navm) instruction.\n\nFirst I'm gonna bombard you with some jargon:\n- **`Priority Directions (PDs)`**: Primary, Secondary, Tertiary\n- **`Relative Directions (RDs)`**: Forward, Left, Right\n- **`Cardinal Directions (CDs)`**: North, East, South, West\n\nThe Cardinal directions don't matter much. It is all about the \u003cins\u003e**direction in relation to the exit half**\u003c/ins\u003e of the current domino *(If you ever did any kind of game dev you probably know the difference between world space and local space. It's kind of like that)*\n\nWhen the IP moves to a new domino, the half it enters to is called the \"**entry**\" while the other half is called the \"**exit**\". Now from the perspective of the exit half, the IP can potentially move in 3 directions: Forward, Left, Right. These are the **Relative Directions (RDs)**.\n\nWhich direction it chooses, depends on the current \"**Navigation Mode**\". Here are some of the most basic Nav Mode mappings:\n\n| index |`Primary` |`Secondary`|`Tertiary`|\n|-------|----------|-----------|----------|\n| 0     | Forward  | Left      | Right    |\n| 1     | Forward  | Right     | Left     |\n| 2     | Left     | Forward   | Right    |\n| 3     | Left     | Right     | Forward  |\n| 4     | Right    | Forward   | Left     |\n| 5     | Right    | Left      | Forward  |\n| ...   | ...      | ...       | ...      |\n\n*The \"index\" here is the argument for the `NAVM`instruction.*\n\n\u003cbr\u003e\n\n**If we imagine the `6` to be the exit half, what will be the next domino the IP moves to?:**\n\n\u003ctable\u003e\n\u003ctr\u003e\n\u003cth\u003eEast\u003c/th\u003e\n\u003cth\u003eWest\u003c/th\u003e\n\u003cth\u003eSouth\u003c/th\u003e\n\u003cth\u003eNorth\u003c/th\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n\n```\n. 2 . . .\n  |\n. 2 . . .\n\n5—6 1—1 .\n\n. 3 . . .\n  |\n. 3 . . .\n```\n  \n\u003c/td\u003e\n\u003ctd\u003e\n\n```\n. . . 3 .\n      |\n. . . 3 .\n\n. 1—1 6—5\n\n. . . 2 .\n      |\n. . . 2 .\n```\n\n\u003c/td\u003e\n\u003ctd\u003e\n\n```\n. . 5 . .\n    |\n3—3 6 2—2\n\n. . 1 . .\n    |\n. . 1 . .\n\n. . . . .\n```\n\n\u003c/td\u003e\n\u003ctd\u003e\n\n```\n. . . . .\n\n. . 1 . .\n    |\n. . 1 . .\n\n2—2 6 3—3\n    |\n. . 5 . .\n```\n\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n\n*All 4 snippets are exactly the same code with the difference that they are all flipped differently. This is what I mean by the cardinal direction not mattering much in DominoScript.*\n\n- When `index 0`, the IP will move to `1—1` (Primary, Forward)\n- When `index 1`, the IP will move to `1—1` (Primary, Forward)\n- When `index 2`, the IP will move to `2—2` (Primary, Left)\n- When `index 3`, the IP will move to `2—2` (Primary, Left)\n- When `index 4`, the IP will move to `3—3` (Primary, Right)\n- When `index 5`, the IP will move to `3—3` (Primary, Right)\n\n\u003cbr\u003e\n\n**What if we remove the `1—1` domino? Where will the IP go to then?:**\n\n\u003ctable\u003e\n\u003ctr\u003e\n\u003cth\u003eEast\u003c/th\u003e\n\u003cth\u003eWest\u003c/th\u003e\n\u003cth\u003eSouth\u003c/th\u003e\n\u003cth\u003eNorth\u003c/th\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n\n```\n. 2 . . .\n  |\n. 2 . . .\n\n5—6 . . .\n\n. 3 . . .\n  |\n. 3 . . .\n```\n  \n\u003c/td\u003e\n\u003ctd\u003e\n\n```\n. . . 3 .\n      |\n. . . 3 .\n\n. . . 6—5\n\n. . . 2 .\n      |\n. . . 2 .\n```\n\n\u003c/td\u003e\n\u003ctd\u003e\n\n```\n. . 5 . .\n    |\n3—3 6 2—2\n\n. . . . .\n     \n. . . . .\n\n. . . . .\n```\n\n\u003c/td\u003e\n\u003ctd\u003e\n\n```\n. . . . .\n\n. . . . .\n     \n. . . . .\n\n2—2 6 3—3\n    |\n. . 5 . .\n```\n\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n\n- When `index 0`, the IP will move to `2—2` (Secondary, Left)\n- When `index 1`, the IP will move to `3—3` (Secondary, Right)\n- When `index 2`, the IP will move to `2—2` (Primary, Left)\n- When `index 3`, the IP will move to `2—2` (Primary, Left)\n- When `index 4`, the IP will move to `3—3` (Primary, Right)\n- When `index 5`, the IP will move to `3—3` (Primary, Right)\n\n\u003cbr\u003e\n\n**And what if we remove both the `1—1` and the `2—2` domino?:**\n\n\u003ctable\u003e\n\u003ctr\u003e\n\u003cth\u003eEast\u003c/th\u003e\n\u003cth\u003eWest\u003c/th\u003e\n\u003cth\u003eSouth\u003c/th\u003e\n\u003cth\u003eNorth\u003c/th\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n\n```\n. . . . .\n   \n. . . . .\n\n5—6 . . .\n\n. 3 . . .\n  |\n. 3 . . .\n```\n  \n\u003c/td\u003e\n\u003ctd\u003e\n\n```\n. . . 3 .\n      |\n. . . 3 .\n\n. . . 6—5\n\n. . . . .\n       \n. . . . .\n```\n\n\u003c/td\u003e\n\u003ctd\u003e\n\n```\n. . 5 . .\n    |\n3—3 6 . .\n\n. . . . .\n     \n. . . . .\n\n. . . . .\n```\n\n\u003c/td\u003e\n\u003ctd\u003e\n\n```\n. . . . .\n\n. . . . .\n     \n. . . . .\n\n. . 6 3—3\n    |\n. . 5 . .\n```\n\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n\n- When `index 0`, the IP will move to `3—3` (Tertiary, Right)\n- When `index 1`, the IP will move to `3—3` (Secondary, Right)\n- When `index 2`, the IP will move to `3—3` (Tertiary, Right)\n- When `index 3`, the IP will move to `3—3` (Secondary, Right)\n- When `index 4`, the IP will move to `3—3` (Primary, Right)\n- When `index 5`, the IP will move to `3—3` (Primary, Right)\n\n\u003cbr\u003e\n\nThese are only variations of the \"Basic-Three-Way\" kind of NavModes. See the [Reference](#navigation-modes) for a full list of available modes.\n\n## How to read DominoScript\n\nDS isn't meant to be easily human readable but there are patterns that, once you recognize them, will make it much easier to understand what is going on.\n\nAll of these patterns revolve around how the `NUM` and `STR` instructions behave differently than any other instruction.\n\nOnce you understand how they are different, reading the rest of DominoScript is mostly a matter of keeping track of how the other instructions affect:\n- the Stack (most of them do)\n- the Instruction Pointer (e.g. [JUMP](#jump), [CALL](#call), [NAVM](#navm)).\n- The way Domino pieces are parsed (e.g. [LIT](#lit), [BASE](#base), [EXT](#ext))\n\n\u003cbr\u003e\n\nThe following patterns and examples assume that the default [LIT](#lit) mode was not changed:\n\n\u003e [!TIP]  \n\u003e \u003cins\u003e**PATTERN 1**\u003cins\u003e:\n\u003e\n\u003e Look out for `0—1` and `0—2` dominos.\n\u003e\n\u003e These are often opcodes for the `NUM` and `STR` instructions and indicate the start of a \u003cins\u003enumber literal\u003c/ins\u003e or a \u003cins\u003estring literal\u003c/ins\u003e *(unless they themselves are part of a literal)*.\n\n\n\u003e [!TIP]  \n\u003e \u003cins\u003e**PATTERN 2**\u003cins\u003e:\n\u003e\n\u003e Look out for the first half of a domino right after a `NUM` instruction.\n\u003e\n\u003e If the default [LIT](#lit) mode was not changed, they will decide how many more dominos will be part of the number literal before the next instruction is executed.\n\n**The below code results in the number 6 being pushed and popped of the stack:**\n```\n0—1 0—6 0—0\n```\n\n- `0—1` is a `NUM` instruction (**PATTERN 1**)\n- `0—6` is the number literal\n  - first half is 0 which, in default LIT mode, means no more dominos will follow and only the second half is parsed as a literal value (see **PATTERN 2**)\n  - Second half is 6 in both base7 and decimal so the decimal number 6 is pushed to the stack\n- `0—0` is the next instruction. We know that because the first half of previous domino told us that no more dominos will be part of the literal. (see **PATTERN 2**)\n\n**The below code results in the number 1000 being pushed and popped off the stack:**\n```\n0—1 2—0 2—6 2—6 0—0\n```\n\n- `0—1` is a `NUM` instruction (see **PATTERN 1**)\n- `2—0 2—6 2—6` is parsed as a literal value.\n  - the first half is 2, which means 2 more dominos will be parsed as a literal value (see **PATTERN 2**)\n  - the remaining 2.5 dominos are parsed as 2626 in base7 which is 1000 in decimal.\n  - `0—0` is the next instruction. We know that because the first half of the domino after `NUM` told us that 2 more dominos will be parsed as part of the number literal, so 3rd one after will be an instruction (see **PATTERN 2**).\n\n\u003cbr\u003e\n\n\u003e [!TIP]  \n\u003e \u003cins\u003e**PATTERN 3**\u003cins\u003e:\n\u003e\n\u003e While in default [LIT](#lit) mode, look out for the first half of a domino right after a `STR` instruction.\n\u003e\n\u003e For the same reason as after a `NUM` instruction. It will decide how many more dominos will be part of the \u003cins\u003e character\u003c/ins\u003e before the next character of the string literal is parsed.\n\n\u003e [!TIP]  \n\u003e \u003cins\u003e**PATTERN 4**\u003cins\u003e:\n\u003e\n\u003e Look out for the NULL terminator `0—0` during a `STR` instruction.\n\u003e\n\u003e It indicates that the string literal is complete and that the next domino will be parsed as an instruction.\n\n**The below code results in the string \"abc\" being pushed to the stack.**\n```\n0—2 1—1 6—6 1—2 0—0 1—2 0—1 0—0 0—1 0—6 0—0\n```\n- `0—2` is a `STR` instruction\n- `1—1 6—6` is the Unicode value for \"a\"\n- `1—2 0—0` is the Unicode value for \"b\"\n- `1—2 0—1` is the Unicode value for \"c\"\n-  `0—0` is the null terminator. We know that because `STR` only ends once it encounters a `0—0` (see **PATTERN 4**)\n- `0—1 0—6 0—0` is the code from the first example above. It will push the number 6 to the stack and then pop it off again *(notice how the same amount of dots can mean different things depending on the context!)*\n\n\u003cbr\u003e\n\nThe patterns are valid for all cardinal directions the Instruction Pointer can move in.\n\nYou have to understand, that the same domino can represent something completely different depending on the direction it is read from and what instruction preceded it.\n\n```\n0—1 . 1—0 . 1 . 0 . . .\n            |   |\n. . . . . . 0 . 1 . . .\n```\n\nThe above domino can be interpreted as either a 10 or a 1. A 10 can mean different values depending on the current [BASE](#base) (e.g. in base7 a 10 is 7 in decimal, in base16 a 10 is 16 in decimal). If a NUM or a STR instruction directly preceeded it, they are interpreted as literal values. If not, they are interpreted as opcodes.\n\n\u003cbr\u003e\n\n## Instructions\n\nThe \"core\" instruction set consists of 49 opcodes and is meant to fit within the value range a single \"double-six\" domino can represent (0 to 48).\n\nIn the below overview, you can see the instructions on a 7x7 matrix representing the \"opcode-to-instruction\" mapping while in the default base7 mode *(Base7 means \"double-six\" dominos are used which can have 0 to 6 dots on each half)*.\n\n\u003e [!IMPORTANT]  \n\u003e Keep in mind that if you change into a higher [BASE](#base), you will need to use different dominos to represent the same opcode!\n\u003e\n\u003e The images of dominos shown alongside each instruction, are only valid while in base7 mode. \n\u003e\n\u003e For example: The opcode for [NOOP](#noop) is 48 in decimal. To represent it in base7, a `6—6` domino is used. To represent it in base16, a `3—0` domino is used.\n\u003e\n\u003e If that is too confusing, I recommend to simply switch to base10 mode where the decimal number 48 *(aka the opcode for NOOP)* is represented by a `4—8` domino.\n\n|     |  0                | 1               | 2                | 3                | 4            | 5                | 6                | CATEGORY                                      |\n|-----|-------------------|-----------------|------------------|------------------|--------------|------------------|------------------|-----------------------------------------------|\n|**0**|[POP](#pop)       |[NUM](#num)       |[STR](#str)       |[DUPE](#dupe)     |[ROLL](#roll) |[LEN](#len)       |[CLR](#clr)       |[Stack Management](#stack-management)          |\n|**1**|[ADD](#add)       |[SUB](#sub)       |[MULT](#mult)     |[DIV](#div)       |[MOD](#mod)   |[NEG](#neg)       |[CLAMP](#clamp)   |[Arithmetic](#arithmetic)                      |\n|**2**|[NOT](#not)       |[AND](#and)       |[OR](#or)         |[EQL](#eql)       |[GTR](#gtr)   |[EQLSTR](#eqlstr) |[_](#reserved_2_6)|[Comparison \u0026 Logical](#comparison-and-logical)|\n|**3**|[BNOT](#bnot)     |[BAND](#band)     |[BOR](#bor)       |[BXOR](#bxor)     |[LSL](#lsl)   |[LSR](#lsr)       |[ASR](#asr)       |[Bitwise](#bitwise)                            |\n|**4**|[NAVM](#navm)     |[BRANCH](#branch) |[LABEL](#label)   |[JUMP](#jump)     |[CALL](#call) |[IMPORT](#import) |[WAIT](#wait)     |[Control Flow](#control-flow)                  |\n|**5**|[NUMIN](#numin)   |[NUMOUT](#numout) |[STRIN](#strin)   |[STROUT](#strout) |[KEY](#key)   |[KEYRES](#keyres) |[_](#reserved_5_6)|[Input \u0026 Output](#input-and-output)            |\n|**6**|[GET](#get)       |[SET](#set)       |[LIT](#lit)       |[BASE](#base)     |[EXT](#ext)   |[TIME](#time)     |[NOOP](#noop)     |[Misc](#misc)                                  |\n\n*(DominoScript isn't limited to these 49 instructions. Opcodes 0-99 are reserved for \"official\" instructions, while opcodes 100+ can be used to extend the language using the  [LABEL](#label) instruction as well as eventually via the JS API. TODO explain in more detail.)*\n\n\u003cbr\u003e\n\u003ch3 id=\"stack-management\"\u003eStack Management\u003c/h3\u003e\n\n#### `POP`\n\u003cimg src=\"assets/horizontal/0-0.png\" alt=\"Domino\" width=\"128\"\u003e\n\nDiscards the top of the stack.\n\n#### `NUM`\n\u003cimg src=\"assets/horizontal/0-1.png\" alt=\"Domino\" width=\"128\"\u003e\n\nSwitch to \"number mode\". By default the first half of the next domino will indicate how many dominos to read as a number. Then the other halfs will all be read as base7 digits (in D6 mode) to form the number that will be pushed to the stack.\n\nWith 7 dominos, 13 out of 14 halfs are used for the number. You can theoretically represent a number much larger than the max int32 value. However, if the number exceeds the maximum int32 value, it will wrap around from the minimum value, and vice versa *(exactly the same as when doing bitwise operations in JS --\u003e `(96889010406 | 0) === -1895237402`)*.\n\nYou might think that since internally numbers are int32s, that we parse from base7 to two's complement. That is not the case. We simple push the decimal version of the positive base7 number to the stack\n\n**\u003cins\u003eFor example:\u003c/ins\u003e**\n- `0—0` represents the number `0` in both decimal and base7\n- `0—6` represents the number `6` in both decimal and base7\n- `1—6 6—6` represents the number `342` in decimal and `666` in base7\n- `2—6 6—6 6—6` represents the number `16,806` in decimal and `6,666` in base7\n- `6—6 6—6 6—6 6—6 6—6 6—6` represents the number `1,977,326,742` in decimal and `66,666,666,666` in base7 (about 92.1% of the max int32 value)\n- `6—0 1—0 4—1 3—4 2—1 1—1 6—1` represents the number `2,147,483,647` in decimal and `104,134,211,161` in base7 (exactly the max int32 value)\n- `6—6 6—6 6—6 6—6 6—6 6—6 6—6` represents the number -1,895,237,402. **WHY?**: The actual decimal number the dominos represent is `96,889,010,406` which is ~45x larger than the max int32 value. It wraps around about that many times before it reaches the final value.\n\n**\u003cins\u003eWhat if numbers are read from the other direction?\u003cins\u003e**\n- `1—1 1—1`, `2—2 2—2 2—2` for example will be exactly the same numbers (216 in decimal) eastwards and westwards.\n- `1—2 3—1` when parsed backwards is `1—3 2—1` and can therefore represent different numbers if the IP moves to the east or to the west.\n- `1—6 6—6` represents 666 in base7 (342 in decimal) but when parsed backwards the interpreter will raise an `UnexpectedEndOfNumberError`. Remember that the first half of the first domino indicates how many more will follow. In this case it expects to read 6 more dominos but the number ends prematurely after 1 domino.\n\n**\u003cins\u003eTo push the number 10 and 5 to the stack you would use the following dominos:\u003cins\u003e**\n- In pseudo code: `NUM 10 NUM 5`\n- In DominoScript: `0—1 1—0 1—3 0—1 0—5`\n  - `0—1` is NUM\n  - `1—0 1—3` is the number 13 in base7 which is 10 in decimal\n  - `0—1` is NUM again\n  - `0—5` is the number 5 in both base7 and decimal\n\n**\u003cins\u003eTo push the number -10 and -5 to the stack you would use the following dominos:\u003cins\u003e**\n- In pseudo code: `NUM 10 NEG NUM 5 NEG`\n- In DominoScript: `0—1 1—0 1—3 1—5 0—1 0—5 1—5` \n  - `0—1` is NUM\n  - `1—0 1—3` is 13 in base7 which is 10 in decimal\n  - `1—5` is NEG\n  - `0—1` is NUM again\n  - `0—5` is 5 in both base7 and decimal\n  - `1—5` is NEG\n\n**\u003cins\u003eWhat if I want to use a fixed amount of dominos for each number?\u003cins\u003e**  \n\nUse the [LIT](#lit) instruction to permanently change how literals are parsed. For example with parse mode `2` it will use 2 dominos for each number. While `6—6 6—6` in default parse mode 0 results in `UnexpectedEndOfNumberError` (because it expects 6 more dominos to follow but only got 1 more), in parse mode `2` it represents the decimal number `2400`.\n\n#### `STR`\n\n\u003cimg src=\"assets/horizontal/0-2.png\" alt=\"Domino\" width=\"128\"\u003e\n\nWith `STR` you switch to \"string mode\" and can push multiple integers to the stack to represent Unicode characters.\n\nThe way the dominos are parsed to numbers is identical to `NUM`: First half of first domino indicates how many more will follow for a single number.\n\nThe difference is that it doesn't stop with just one number. It will keep reading numbers until it encounters the NULL character represented by domino `0—0`. \n\nOnly once the interpreter does encounter the NULL character, will it push the characters to the stack in \u003cins\u003ereverse\u003c/ins\u003e order.\n\n*(Note: I decided to parse strings like this because I wanted a single int32 based stack and, out of all options I could think of, this one felt the least annoying. If you can think of better ways, I am open for suggestions!)*\n\nThis is how you push the string `\"hi!\"` to the stack and output it:\n```\n0—2 1—2 0—6 1—2 1—0 1—0 4—5 0—0 5—3\n```\n\nIt equals the following pseudo code: `STR \"hi!\" STROUT`\n\n- `0—2` is the `STR` instruction\n- `1—2 0—6` is the Unicode value 105 representing the character `h`\n- `1—2 1—0` is the Unicode value 105 representing the character `i`\n- `0—0 4—5` is the Unicode value 33 representing the character `!`\n- `0—0` is the Unicode value for the NULL character which terminates the string.\n- `5—3` is the [STROUT](#strout) instruction. It will pop items from the stack, parse them as Unicode chars and once it encounters the NULL character, it will output the string to stdout all at once.\n\nThis is the resulting stack: \n\n\u003ctable\u003e\n\u003ctr\u003e\n\u003cth\u003eImaginative\u003c/th\u003e\n\u003cth\u003eReality\u003c/th\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n  \n```\n[..., 'NUL', '!', 'i', 'h']\n```\n  \n\u003c/td\u003e\n\u003ctd\u003e\n\n```\n[..., 0, 33, 105, 104]\n```\n\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n\nKeep in mind that the IP can move in 4 cardinal direction so the following variations would also push the string `\"hi!\"` to the stack:\n\nIP moves right to left:\n```\n3—5 0—0 5—4 0—1 0—1 2—1 6—0 2—1 2—0\n```\n\nIP moves in multiple directions:\n```\n0 . . . . 0 4—5\n|         |\n2 . . . . 1 . 0\n              |\n1 . . 2 1—0 . 0\n|     | \n2 0—6 1 . . 3—5\n```\n\n#### `DUPE`\n\u003cimg src=\"assets/horizontal/0-3.png\" alt=\"Domino\" width=\"128\"\u003e\n\nDuplicate the top item on the stack.\n\n| Stack Before    | Stack After    |\n|-----------------|----------------|\n| `[a, b]`        | `[a, b, b]`    |\n\n#### `ROLL`\n\u003cimg src=\"assets/horizontal/0-4.png\" alt=\"Domino\" width=\"128\"\u003e\n\nPops one argument from the stack to be used as \"depth\".\n\n- With a negative depth, the item at the \u003cins\u003etop\u003c/ins\u003e is moved to the \u003cins\u003enth depth\u003c/ins\u003e\n- With a positive depth, the item at the \u003cins\u003enth depth\u003c/ins\u003e is moved to the \u003cins\u003etop\u003c/ins\u003e\n\nWith roll you can implement common stack operations like `SWAP` and `ROT`:\n\n| Roll Depth |  Equivalent to | Stack Before    | Stack After    |\n|------------|----------------|-----------------|----------------|\n| -3         | -              | `[a, b, c, d]`  | `[d, a, b, c]` |\n| -2         | ROTR           | `[a, b, c]`     | `[c, a, b]`    |\n| -1         | SWAP           | `[a, b]`        | `[b, a]`       |\n| 0          | NOOP           | `[a]`           | `[a]`          |\n| 1          | SWAP           | `[a, b]`        | `[b, a]`       |\n| 2          | ROTL           | `[a, b, c]`     | `[b, c, a]`    |\n| 3          | -              | `[a, b, c, d]`  | `[b, c, d, a]` |\n\n#### `LEN`\n\u003cimg src=\"assets/horizontal/0-5.png\" alt=\"Domino\" width=\"128\"\u003e\n\nPushes the number of items on the stack.\n\n#### `CLR`\n\u003cimg src=\"assets/horizontal/0-6.png\" alt=\"Domino\" width=\"128\"\u003e\n\nRemoves all items from the stack.\n\n\u003cbr\u003e\n\u003ch3 id=\"arithmetic\"\u003eArithmetic\u003c/h3\u003e\n\n#### `ADD`\n\u003cimg src=\"assets/horizontal/1-0.png\" alt=\"Domino\" width=\"128\"\u003e\n\nPops 2 numbers from the stack. The sum is pushed to the stack.\n\n#### `SUB`\n\u003cimg src=\"assets/horizontal/1-1.png\" alt=\"Domino\" width=\"128\"\u003e\n\nPops 2 numbers from the stack. The result of `numberA - numberB` is pushed to the stack.\n\n#### `MULT`\n\u003cimg src=\"assets/horizontal/1-2.png\" alt=\"Domino\" width=\"128\"\u003e\n\nPops 2 numbers to multiply. The result is pushed to the stack.\n\n#### `DIV`\n\u003cimg src=\"assets/horizontal/1-3.png\" alt=\"Domino\" width=\"128\"\u003e\n\nPops 2 numbers. The result of the division of numberA by numberB is pushed to the stack.\n\nKeep in mind that DominoScript is integer based and any remainder is discarded.\n\n**\u003cins\u003ePseudocode:\u003cins\u003e**\n- `NUM 5 NUM 3 DIV` is `5 / 3` and equals `1`\n- `NUM 5 NEG NUM 3 DIV` is `-5 / 3` and equals `-1`\n\n#### `MOD`\n\u003cimg src=\"assets/horizontal/1-4.png\" alt=\"Domino\" width=\"128\"\u003e\n\nPops 2 numbers. The remainder of division of `numberA / numberB` is pushed to the stack.\n\n\u003e [!IMPORTANT]  \n\u003e When numberA is positive modulo behaves identical in most languages (afaik). However, there are some differences across programming languages when numberA is negative. In DominoScript modulo behaves like in JavaScript, Java, C++ and Go and \u003cins\u003eNOT\u003c/ins\u003e like in Python or Ruby!\n\n**\u003cins\u003ePseudocode:\u003cins\u003e**\n- `NUM 5 NUM 3 MOD` is `5 % 3` and equals `2`\n- `NUM 5 NEG NUM 3 MOD` is `-5 % 3` and equals `-2` *(in python, ruby and calculators it would equal `1`)*\n\n#### `NEG`\n\u003cimg src=\"assets/horizontal/1-5.png\" alt=\"Domino\" width=\"128\"\u003e\n\nPops the top item off the stack. Negates it. Then pushes the negated version back onto the stack. Essentially a `num  * -1` operation.\n\n\n#### `CLAMP`\n\u003cimg src=\"assets/horizontal/1-6.png\" alt=\"Domino\" width=\"128\"\u003e\n\nPops 3 numbers from the stack: \n\n```\n[..., value, min, max]\n```\n\nAnd pushes back the clamped value onto the stack.\n\n\u003cbr\u003e\n\n\u003ch3 id=\"comparison-and-logical\"\u003eComparison \u0026 Logical\u003c/h3\u003e\n\n#### `NOT`\n\u003cimg src=\"assets/horizontal/2-0.png\" alt=\"Domino\" width=\"128\"\u003e\n\nPops the top item off the stack. If it is `0`, it pushes `1` to the stack. Otherwise it pushes `0`.\n\n#### `AND`\n\u003cimg src=\"assets/horizontal/2-1.png\" alt=\"Domino\" width=\"128\"\u003e\n\nPops the top 2 items off the stack, performs the logical AND operation and pushes the result back onto the stack.\n\n#### `OR`\n\u003cimg src=\"assets/horizontal/2-2.png\" alt=\"Domino\" width=\"128\"\u003e\n\nPops the top 2 items off the stack, performs the logical OR operation and push the result back onto the stack.\n\n#### `EQL`\n\u003cimg src=\"assets/horizontal/2-3.png\" alt=\"Domino\" width=\"128\"\u003e\n\nPops the top 2 items off the stack, compares them and pushes the result back onto the stack. If the items are equal, it pushes `1` to the stack, otherwise `0`.\n\n#### `GTR`\n\u003cimg src=\"assets/horizontal/2-4.png\" alt=\"Domino\" width=\"128\"\u003e\n\nPops the top 2 items off the stack, compares them and pushes the result back onto the stack. If the first item is greater than the second, it pushes `1` to the stack, otherwise `0`.\n\n#### `EQLSTR`\n\u003cimg src=\"assets/horizontal/2-5.png\" alt=\"Domino\" width=\"128\"\u003e\n\nAssumes that 2 strings are on the stack. It pops them, compares them and pushes `1` to the stack if equal, otherwise `0`.\n\n**\u003cins\u003eFor example:\u003cins\u003e**  \nYou push the strings `\"AC\"` then `\"DC\"`. They are represented on the stack as `[NULL, C, A, NULL, C, D]` (In reality it is `[0, 67, 65, 0, 67, 68]`). Since the strings are not equal, it will push `0` to the stack. It is now `[0]`.\n\n**\u003cins\u003eAnother example:\u003cins\u003e**  \nImagine you want to check if the user pressed arrow left. You execute the `KEY` instruction after which the stack looks like `[\u003cexisting\u003e, 0, 68, 91, 27]` then you push the \u003cins\u003eescape sequence\u003c/ins\u003e which represents the left arrow key. The stack is now `[\u003cexisting\u003e, 0, 68, 91, 27, 0, 68, 91, 27]`. You then execute the `EQLSTR` instruction which will pop the top 2 strings and since the strings are equal, it will push `1` to the stack. It is now `[\u003cexisting\u003e, 1]` *(See the [KEY](#key) instruction for more info about escape sequences)*.\n\n#### `RESERVED_2_6`\n\u003cimg src=\"assets/horizontal/2-6.png\" alt=\"Domino\" width=\"128\"\u003e\n\nUnmapped opcode. Will throw `InvalidInstructionError` if executed.\n\n\u003cbr\u003e\n\u003ch3 id=\"bitwise\"\u003eBitwise\u003c/h3\u003e\n\n#### `BNOT`\n\u003cimg src=\"assets/horizontal/3-0.png\" alt=\"Domino\" width=\"128\"\u003e\n\nBitwise NOT. Pops the top item off the stack, inverts all bits and pushes the result back onto the stack.\n\n#### `BAND`\n\u003cimg src=\"assets/horizontal/3-1.png\" alt=\"Domino\" width=\"128\"\u003e\n\nBitwise AND. Pops the top 2 items off the stack, performs bitwise AND and pushes the result back onto the stack.\n\n#### `BOR`\n\u003cimg src=\"assets/horizontal/3-2.png\" alt=\"Domino\" width=\"128\"\u003e\n\nBitwise OR. Pops the top 2 items off the stack, performs bitwise OR and pushes the result back onto the stack.\n\n#### `BXOR`\n\u003cimg src=\"assets/horizontal/3-3.png\" alt=\"Domino\" width=\"128\"\u003e\n\nBitwise XOR. Pops the top 2 items off the stack, performs bitwise XOR and pushes the result back onto the stack.\n\n#### `LSL`\n\u003cimg src=\"assets/horizontal/3-4.png\" alt=\"Domino\" width=\"128\"\u003e\n\nLogical Shift Left. Performs the equivalent of `argA \u003c\u003c argB` and pushes the result back onto the stack.\n\n#### `LSR`\n\u003cimg src=\"assets/horizontal/3-5.png\" alt=\"Domino\" width=\"128\"\u003e\n\nLogical Shift Right. Performs the equivalent of `argA \u003e\u003e\u003e argB` and pushes the result back onto the stack.\n\n#### `ASR`\n\u003cimg src=\"assets/horizontal/3-6.png\" alt=\"Domino\" width=\"128\"\u003e\n\nArithmetic Shift Right. Performs the equivalent of `argA \u003e\u003e argB` and pushes the result back onto the stack.\n\n\u003ch3 id=\"control-flow\"\u003eControl Flow\u003c/h3\u003e\n\n#### `NAVM`\n\u003cimg src=\"assets/horizontal/4-0.png\" alt=\"Domino\" width=\"128\"\u003e\n\nChanges the Navigation Mode. The default Mode is `0`. \n\nSee [Navigation Modes](#navigation-modes) to see all possible nav modes and their indexes.\n\n#### `BRANCH`\n\u003cimg src=\"assets/horizontal/4-1.png\" alt=\"Domino\" width=\"128\"\u003e\n\nLike an IF-ELSE statement.\n\nIt pops the top of the stack as a condition and then:\n\n```\n. . . . . 6 . .\n          |\n. . . . . 6 . .\n\n0—1 0—1 4—1 . .\n          \n. . . . . 5 . .\n          |\n. . . . . 5 . .\n```\n\n- When popped value is `true`: The IP will move to the relative **LEFT** (the `6-6`domino)\n- When popped value is `false`: The IP will move to the relative **RIGHT** (the `5-5`domino)\n\n\n\n\u003e [!IMPORTANT]  \n\u003e It ignores the current Navigation Mode. You can always be assured that the IP will either move to the relative left or right.\n\u003e\n\u003e Keep in mind that: \u003cins\u003eall non-zero numbers are considered true\u003c/ins\u003e. Only `0` is false! `-1`, `-2` etc. ares all true *(This fact might be obvious, but I felt like mentioning it as, when using `==,` `\u003c` or `\u003e` for most conditions, it might be easy to forget)*.\n\n#### `LABEL`\n\u003cimg src=\"assets/horizontal/4-2.png\" alt=\"Domino\" width=\"128\"\u003e\n\nLabel are like a bookmarks or an alternative identifier of a specific Cell address. They can be used by the `JUMP`, `CALL`, `GET` and `SET` instructions.\n\n**\u003cins\u003eLabels are probably not what you expect them to be.\u003c/ins\u003e** \n- They are \u003cins\u003enot\u003c/ins\u003e strings, but negative numbers.\n- They are auto generated and self decrementing: `-1`, `-2`, `-3`, etc. ...\n- You can kind of imagine them as pointers to a specific cell address.\n\nExecuting the LABEL instruction pops the address of the cell you want to label from the stack and assigns it to the next available negative number label.\n\nThe negative number label will \u003cins\u003eNOT\u003c/ins\u003e be pushed to the stack. First label will be `-1`, second label will be `-2` and so on. You need to keep track of them yourself.\n\nFor clarity, I'd generally recommend adding comments like the following to your source files:\n```markdown\n## Label Mappings\n| Label | Address | Function name |\n|-------|---------|---------------|\n| -1    | 340     | main          |\n| -2    | 675     | update        |\n| -3    | 704     | whatever      |\n```\n\nIt is not mandatory to use labels. The 4 mentioned instructions that can use them also work with addresses directly!\n\n**\u003cins\u003eAbout Labels in imported files:\u003c/ins\u003e**  \nDominoScript has an `IMPORT` instruction that allows source files to be imported into others. The imported functions can only be called via labels, so in that regard a label also acts like an export. If the parent file doesn't define labels of their own, the label values will be the same in both parent and child. However if the parent file creates labels \u003cins\u003ebefore\u003c/ins\u003e importing a child file, the exported child labels will have a different value in the parent. For example:  \n1. Parent creates label `-1`, `-2`, `-3` and then imports the child file\n2. The child file defines labels `-1`, `-2`, `-3` and gives back control to parent\n3. The parent file will now have the labels `-1`, `-2`, `-3` and the child labels will be `-4`, `-5`, `-6`\n4. Now when the parent wants to call a child function which internally is labelled with `-1`, it needs to use label `-4` instead.\n\n#### `JUMP`\n\u003cimg src=\"assets/horizontal/4-3.png\" alt=\"Domino\" width=\"128\"\u003e\n\nMoves the IP to an address on the grid. You can either use a label or an address as an argument.\n\nIf the IP cannot move anymore, the interpreter will throw a `StepToEmptyCellError`.\n\nIf label is unknown it will throw an `UnknownLabelError`.\n\n#### `CALL`\n\u003cimg src=\"assets/horizontal/4-4.png\" alt=\"Domino\" width=\"128\"\u003e\n\nLike the name suggests, it is similar to a function call.\n\nExactly like JUMP with one crucial difference: When it cannot move anymore, the IP will return to where it was called from instead of terminating the program.\n\nInternally there is a return stack that keeps track of the return addresses.\n\n**Alternative way to CALL**\nInstead of doing `ǸUM 1 NEG CALL` to call by label, you can just do `OPCODE_100`. Why? Because labels are mapped to opcodes 100+. So when you create the labels `-1`, `-2`, `-3`, etc. they are automatically mapped to opcodes `100`, `101`, `102`.\n\n\u003e [!IMPORTANT]  \n\u003e You can perform recursive calls (See [factorial example](./examples/009_recursive_factorial.md)) but be aware that the depth is limited by the size of the return stack. By default its size is 512.\n\n#### `IMPORT`\n\u003cimg src=\"assets/horizontal/4-5.png\" alt=\"Domino\" width=\"128\"\u003e\n\nPop a \"string\" from the stack to indicate the file name of the source file to import.\n\nOn import the interpreter will load the file and start running it until its Instruction Pointer cannot move anymore.\n\nLabels defined in the imported file are accessible from the file which imports it. That means you can call functions from the imported file via the `CALL` instruction.\n\nIf the importing file defined a label before the import, the labels from the imported file will have different identifiers. For example:\n- `FileChild.ds` defines a label `-1`.\n- `FileAParent.ds` defines labels `-1`, `-2`, then imports FileChilds.ds.s\n\nThe \u003cins\u003einternal\u003c/ins\u003e label `-1` in `FileChild.ds` will be `-3` \u003cins\u003eexternally\u003c/ins\u003e in `FileAParent.ds` because labels are always auto decrementing. \u003cins\u003e**Why?**\u003c/ins\u003e Because it is the simplest way to avoid conflicts and be able to use labels internally and externally.\n\n\u003e [!IMPORTANT]  \n\u003e The data stack is shared between parent and all imported files. Apart from that, the parent and child imports run in their own contexts. Imported files can have imports themselves but you should avoid circular dependencies.\n\nIf you import the same file into more than one other file, it will result in multiple instances of the imported file. This is probably not a problem as long as you are aware of it.\n\n#### `WAIT`\n\u003cimg src=\"assets/horizontal/4-6.png\" alt=\"Domino\" width=\"128\"\u003e\n\nPops the top item off the stack and waits for that many milliseconds before continuing.\n\n*(You could simulate a delay without using `WAIT` using a 'busy loop' like in example [011_basic_game_loop](./examples/011_basic_game_loop.md) but it is not recommended)*\n\n\u003cbr\u003e\n\u003ch3 id=\"input-and-output\"\u003eInput \u0026 Output\u003c/h3\u003e\n\n#### `NUMIN`\n\u003cimg src=\"assets/horizontal/5-0.png\" alt=\"Domino\" width=\"128\"\u003e\n\nPrompt the user for a number. The user input will be pushed to the stack.\n\n#### `NUMOUT`\n\u003cimg src=\"assets/horizontal/5-1.png\" alt=\"Domino\" width=\"128\"\u003e\n\nPop the top item from the stack and output it to stdout.\n\n#### `STRIN`\n\u003cimg src=\"assets/horizontal/5-2.png\" alt=\"Domino\" width=\"128\"\u003e\n\nPrompt the user for a string. The user input will be pushed to the stack as individual Unicode characters in reverse order.\n\nSo if the user inputs `\"yes\"`, the stack will look like this:\n\n```\n[..., 0, 115, 101, 121]\n```\n\nFor convenience you might often see the stack represented  But remember that in reality it just stores int32s.\n\n```\n[..., NUL 's', 'e', 'y']\n```\n\n\n#### `STROUT`\n\u003cimg src=\"assets/horizontal/5-3.png\" alt=\"Domino\" width=\"128\"\u003e\n\nPops numbers (representing Unicode char codes) from the stack until it encounters a null terminator (number 0). It will then output the string to stdout.\n\n\u003cins\u003e**There is one special case:**\u003c/ins\u003e If the parser encounters the `Unit Separator` (ascii 31), it stringifies the \u003cins\u003enext\u003c/ins\u003e number instead of treating it as a unicode char code. This is very useful to generate ANSI escape sequences like `\\x1b[15;20H[-]` which tells the terminal to draw `[-]` at row 15 and column 20. Without the `Unit Separator` you would have to push the char code for 1, 5 and 2, 0 individually. This is a pain if you are dealing with dynamic numbers. The [example_023](./examples/023_input_controls_advanced.md) uses this to  create an escape sequence.\n\n#### `KEY`\n\u003cimg src=\"assets/horizontal/5-4.png\" alt=\"Domino\" width=\"128\"\u003e\n\nCheck if the user pressed a specific key since the last reset with `KEYRES`. If the key was pressed, it pushes `1` to the stack, otherwise `0`.\n\nIt pops a \u003cins\u003estring sequence\u003c/ins\u003e of the stack to represent the key you want to check for.\n\nUnlike `NUMIN` and `STRIN` it doesn't block the program, so you can use it in a loop to check for user input.\n\n**\u003cins\u003eWhat string sequence?:\u003c/ins\u003e**\n- If a key is a printable character, the sequence is the Unicode value of the key. For example, to check if the user pressed the `a` key, you would push the string `a`.\n- If a key is a special key like arrow left, right etc, the sequence is an escape sequence. For example, to check if the user pressed the left arrow key, you would push the escape sequence `\\u001b[D` to the stack.\n\n**\u003cins\u003eWhat is an escape sequence?:\u003c/ins\u003e**  \n\nEscape sequences are sequences of characters that are used to represent special non-printable keyboard keys like arrow keys but can also be used to control terminal behavior, such as cursor position, text color and more. You can google them. Then just transform them to the correct domino sequence.\n\n#### `KEYRES`\n\u003cimg src=\"assets/horizontal/5-5.png\" alt=\"Domino\" width=\"128\"\u003e\n\nResets the state of all keys to \"not pressed\". It is used in combination with `KEY` to check if a key was pressed since the last reset. It has no effect on the stack.\n\nImagine you have a game running at 20fps. Every 50ms you check if the user pressed any of the arrow keys and act accordingly. Then at the end of the frame you reset the state of all keys to \"not pressed\" with `KEYRES`.\n\n#### `RESERVED_5_6`\n\u003cimg src=\"assets/horizontal/5-6.png\" alt=\"Domino\" width=\"128\"\u003e\n\nUnmapped opcode. Will throw `InvalidInstructionError` if executed.\n\n*(Might be used as opcode for a `MOUSE` instruction which pushes the clickX and clickY position of the mouse since the last KEYRES reset)*\n\n\u003cbr\u003e\n\n\u003ch3 id=\"misc\"\u003eMisc\u003c/h3\u003e\n\n#### `GET`\n\u003cimg src=\"assets/horizontal/6-0.png\" alt=\"Domino\" width=\"128\"\u003e\n\nReads data from the board and pushes it to the stack. Takes 2 arguments from the stack:\n- The type Index to parse it as. It indicates the type and the direction of the data.\n- The address of the first domino half\n\n\u003cins\u003e**There are essentially 4 types you can parse it as**\u003c/ins\u003e:\n- **Domino**: The value of the cell at the address and its connection. Essentially a single domino\n- **Unsigned Number**: A number between 0 to 2147483647 *(Hold on! Why not 4294967295? Because the data stack uses int32 and 2147483647 is the max value you can have in the stack. \"Unsigned\" here doesn't mean uint32, just that we don't \"waste\" half a domino to represent the sign)*.\n- **Signed Number**:  A number between -2147483648 to 2147483647 (int32 range).\n- **String**: A string is a sequence of null terminated unicode char codes.\n\n\u003cins\u003e**And the following directions**\u003c/ins\u003e:\n\n- **SingleStraightLine**: The IP moves in a straight line towards the \u003cins\u003econnection direction of the cell at the address\u003c/ins\u003e. No wrap around like in \"RawIncrement\" mode. If you have a 10x20 grid you can get at most 5 dominos in horizontal direction or 10 dominos in vertical direction.\n\n- **RawIncrement** (to be implemented): Reads domino halfs using incrementing addresses. It disregards the grids bounds and wraps around from right edge left edge on the next line *(Remember that addresses are essentially the indices to a 1D array of Cells which represent the Grid. Address 0 is at the top left of the grid. In a 10x10 grid, the largest address is 99 in the bottom right)*\n\n- **NavMode** (to be implemented): In this mode the [NavigationMode](#how-navigation-modes-work) used for regular InstructionPointer movement is used to determine the direction. \n\n\u003cins\u003e**Here a table of supported type mappings:**\u003c/ins\u003e\n\n| Type Index | Type              | Direction                |\n|------------|-------------------|--------------------------|\n| 0          | Domino            | connection direction     |\n| 1          | Unsigned Number   | SingleStraightLine       |\n| 2          | Signed Number     | SingleStraightLine       |\n| 3          | String            | SingleStraightLine       |\n| 4 (TODO)   | Unsigned Number   | RawIncrement             |\n| 5 (TODO)   | Signed Number     | RawIncrement             |\n| 6 (TODO)   | String            | RawIncrement             |\n\n#### `SET`\n\u003cimg src=\"assets/horizontal/6-1.png\" alt=\"Domino\" width=\"128\"\u003e\n\nWrites data to the board. Takes \u003cins\u003eat least\u003c/ins\u003e 2 arguments from the stack:\n- The type Index to parse it as. It indicates the type and the direction of the data\n- The address of the first domino half\n- The data to write to the board. This can either be a single item from the stack or multiple if we write a string\n\n\n\u003cins\u003e**There are essentially 4 types you can write it as**\u003c/ins\u003e\n\n(See list under [GET](#get)):\n\n\u003cins\u003e**And the following directions**\u003c/ins\u003e:\n\n- **SingleStraightLine**: The IP moves in a straight line towards the \u003cins\u003elast Instruction Pointer direction\u003c/ins\u003e. No wrap around like in \"RawIncrement\" mode. If you have a 10x20 grid you can set at most 5 dominos in horizontal direction or 10 dominos in vertical direction.\n\n- **RawIncrement** (to be implemented): Writes domino halfs using incrementing addresses. It disregards the grids bounds and wraps around from right edge left edge on the next line *(Remember that addresses are essentially the indices to a 1D array of Cells which represent the Grid. Address 0 is at the top left of the grid. In a 10x10 grid, the largest address is 99 in the bottom right)*\n\n- **NavMode** (to be implemented): In this mode the [NavigationMode](#how-navigation-modes-work) used for regular InstructionPointer movement is used to determine the direction. \n\n\u003cins\u003e**Here a table of supported type mappings:**\u003c/ins\u003e\n\n(See table under [GET](#get)):\n\n#### `LIT`\n\u003cimg src=\"assets/horizontal/6-2.png\" alt=\"Domino\" width=\"128\"\u003e\n\nChanges how number and string literals are parsed. It pops a number from the stack to use as the \"literal parse mode\". The popped number must be between 0 to 6. If the number is out of bounds, an `DSInvalidLiteralParseModeError` is thrown. \n\n**\u003cins\u003eIf the popped argument is:\u003cins\u003e**\n- `0`: Dynamic parse mode. Used by default. The first domino half of every number literal indicates how many more dominos should be parsed as part of the number. For string literals it is exactly the same but for each character.\n- `1` to `6`: Static parse modes. Uses 1 to 6 dominos for each number literal or each character in a string literal.\n\nIn the following 3 examples `\"Hello world\"` is encoded in 3 different ways:\n\nIn Base7 with Literal Parse Mode 0 (default): \n```\n// Every character requires 2 dominos to be encoded on dominos\n0—2 1—2 0—6 1—2 0—3 1—2 1—3 1—2 1—3 1—2 1—6 1—0 4—4 1—2 3—0 1—2 1—6 1—2 2—2 1—2 1—3 1—2 0—2 0—0\n```\n\nIn Base 16 with Literal Parse Mode 0:\n```\n// Still every character requires 2 dominos to be encoded. Considering that we are in base 16, very wasteful!\n0—2 1—0 6—8 1—0 6—5 1—0 6—c 1—0 6—c 1—0 6—f 1—0 2—0 1—0 7—7 1—0 6—f 1—0 7—2 1—0 6—c 1—0 6—4 0—0\n```\n\nIn Base 16 with Literal Parse Mode 1:\n```\n// Every character requires 1 domino to be encoded.\n// Notice how now it is pretty much just hexadecimal\n0—2 6—8 6—5 6—c 6—c 6—f 2—0 7—7 6—f 7—2 6—c 6—4 0—0\n```\n\nAs you can see, \u003cins\u003echanging the default parse mode can significantly reduce the amount of dominos required to encode strings\u003c/ins\u003e. For numbers it is less impactful but can still be significant if you are working mostly within a specific range.\n\n#### `BASE`\n\u003cimg src=\"assets/horizontal/6-3.png\" alt=\"Domino\" width=\"128\"\u003e\n\nPops one number from the stack to use as the \"base\" for future parsing of dominos (opcodes, number literals, string literals)\n\nBy default, DominoScript uses double six (D6) dominos to represent everything, so the default base is 7.\n\nThe max cell value of half of a domino is always 1 less than the Base. So in base 7, the max value is 6. In base 10, the max value is 9. In base 16, the max value is 15 (aka `f`).\n\n\u003e [!IMPORTANT]  \n\u003e If the number of dots on a domino half exceeds the max amount of possible dots for the current base, it is clamped!  \n\u003e\n\u003e For example: when you are in Base 7 and the interpreter encounters a `f—f` domino, it will be parsed as `6—6`. If you are in base 10, it will be parsed as `9—9` etc.\n\nIn below table you can see how the same domino sequence results in different decimal numbers depending on the base:\n\n| Domino Sequence     | Base 7 (D6)   | Base 10 (D9) | Base 16 (D15) |\n|---------------------|---------------|--------------|---------------|\n| `0—6`               | 6             | 6            | 6             |\n| `0—9`               | 6             | 9            | 9             |\n| `0—f`               | 6             | 9            | 15            |\n| `1—6 6—6`           | 342           | 666          | 1638          |\n| `1—9 9—9`           | 342           | 999          | 2457          |\n| `1—f f—f`           | 342           | 999          | 4095          |\n| `2—6 6—6 6—6`       | 16806         | 66666        | 419430        |\n| `2—9 9—9 9—9`       | 16806         | 99999        | 629145        |\n| `2—f f—f f—f`       | 16806         | 99999        | 1048575       |\n\nWith a higher Base, you have access to higher opcodes without needing to switch to extended mode.\n\n| Base | Opcode Range |\n|------|--------------|\n| 7    | 0 to 48      |\n| 10   | 0 to 99      |\n| 16   | 0 to 255     |\n\nWhile the \u003cins\u003eopcode-to-instruction\u003c/ins\u003e mapping never changes, the \u003cins\u003edomino-to-opcode\u003c/ins\u003e mapping is completely different in each base.\n\nThe below table shows how the domino `3—0` is mapped to different opcodes depending on the base.\n\n| Base | Opcode | Instruction |\n|------|--------|-------------|\n| 7    | 21     | `BNOT`      |\n| 8    | 24     | `BOR`       |\n| 9    | 27     | `LSL`       |\n| 10   | 30     | `BRANCH`    |\n| 11   | 33     | `IMPORT`    |\n| 12   | 36     | `NUMIN`     |\n| 13   | 39     | undefined   |\n| 14   | 42     | `GET`       |\n| 15   | 45     | `BASE`      |\n| 16   | 48     | `NOOP`      |\n\n#### `EXT`\n\u003cimg src=\"assets/horizontal/6-4.png\" alt=\"Domino\" width=\"128\"\u003e\n\nToggle extended mode on or off. If extended mode is active the interpreter will use 2 dominos instead of 1 for each instruction which extends the opcode range from 0-48 to 0-2400 when using Double six dominos.\n\n#### `TIME`\n\u003cimg src=\"assets/horizontal/6-5.png\" alt=\"Domino\" width=\"128\"\u003e\n\nPushes the milliseconds since program start to the stack.\n\nUseful for things like a gameloop, animations, cooldowns etc.\n\n#### `NOOP`\n\u003cimg src=\"assets/horizontal/6-6.png\" alt=\"Domino\" width=\"128\"\u003e\n\nNo operation. The IP will move to the next domino without doing anything.\n\nUseful to move the IP to a specific address (e.g. start of loop body) or to \"reserve\" space in case you think that you might need to add more instructions later on and don't want to move dominos around.\n\n\u003cbr\u003e\n\n ## Navigation Modes\n\n*(F=Forward, L=Left, R=Right)*\n\nThere are `49` total navigation modes in DominoScript. This section is a reference for all of them.\n\n- `Basic`: The IP will prioritize moving in specific directions\n  - [Basic Three Way](#basic-three-way)\n  - [Basic Two Way](#basic-two-way)\n  - [Basic One Way](#basic-one-way)\n- `Cycle`: The IP will prioritize moving in specific directions but the priority will change every cycle.\n  - [Cycle Three Way](#cycle-three-way)\n  - [Cycle Two Way](#cycle-two-way)\n  - [Cycle One Way](#cycle-one-way)\n- `Flip Flop`: The IP will alternate between two primary directions.\n  - [Flip Flop](#flip-flop)\n\n### Basic Three Way\n\nOut of three directions, the IP will prioritize moving to the one with the highest priority.\n\n| Index       | Priorities               | Domino -\u003e |\n|-------------|--------------------------|-----------|\n| 0 (Default) | `Forward` `Left` `Right` | `0—0`     |\n| 1           | `Forward` `Right` `Left` | `0—1`     |\n| 2           | `Left` `Forward` `Right` | `0—2`     |\n| 3           | `Left` `Right` `Forward` | `0—3`     |\n| 4           | `Right` `Forward` `Left` | `0—4`     |\n| 5           | `Right` `Left` `Forward` | `0—5`     |\n| 6           | `RANDOM`                 | `0—6`     |\n\n### Basic Two Way\n\nOut of two directions, the IP will prioritize moving to the one with the highest priority.\n\n| Index  | Priorities               | Domino -\u003e |\n|--------|--------------------------|-----------|\n| 7      | `Forward` `Left`         | `1—0`     |\n| 8      | `Forward` `Right`        | `1—1`     |\n| 9      | `Left` `Forward`         | `1—2`     |\n| 10     | `Left` `Right`           | `1—3`     |\n| 11     | `Right` `Forward`        | `1—4`     |\n| 12     | `Right` `Left`           | `1—5`     |\n| 13     | `RANDOM`                 | `1—6`     |\n\n### Basic One Way\n\nIP can only move in one direction.\n\n| Index  | Only Direction           | Domino -\u003e |\n|--------|--------------------------|-----------|\n| 14     | `Forward`                | `2—0`     |\n| 15     | `Forward`                | `2—1`     |\n| 16     | `Left`                   | `2—2`     |\n| 17     | `Left`                   | `2—3`     |\n| 18     | `Right`                  | `2—4`     |\n| 19     | `Right`                  | `2—5`     |\n| 20     | `RANDOM`                 | `2—6`     |\n\n### Cycle Three Way\n\nThe direction with the highest priority becomes the least prioritized in the next cycle.\n\nAll 3 directions are available in all cycles.\n\n| Index | Cycle 1     | Cycle 2     | Cycle 3     | Domino -\u003e |\n|-------|-------------|-------------|-------------|-----------|\n| 21    | `F` `L` `R` | `L` `R` `F` | `R` `F` `L` | `3—0`     |\n| 22    | `F` `R` `L` | `R` `F` `F` | `L` `F` `R` | `3—1`     |\n| 23    | `L` `F` `R` | `F` `R` `F` | `R` `L` `F` | `3—2`     |\n| 24    | `L` `R` `F` | `R` `F` `L` | `F` `L` `R` | `3—3`     |\n| 25    | `R` `F` `L` | `F` `L` `R` | `L` `R` `F` | `3—4`     |\n| 26    | `R` `L` `F` | `L` `F` `R` | `F` `R` `L` | `3—5`     |\n| 27    | (unmapped)  | (unmapped)  | (unmapped)  | `3—6`     |\n\n### Cycle Two Way\n\nThe direction with the highest priority becomes the least prioritized in the next cycle.\n\nOnly 2 directions are available in a single cycle.\n\n| Index | Cycle 1     | Cycle 2     | Cycle 3     | Domino -\u003e |\n|-------|-------------|-------------|-------------|-----------|\n| 28    | `F` `L`     | `L` `R`     | `R` `F`     | `4—0`     |\n| 29    | `F` `R`     | `R` `F`     | `L` `F`     | `4—1`     |\n| 30    | `L` `F`     | `F` `R`     | `R` `L`     | `4—2`     |\n| 31    | `L` `R`     | `R` `F`     | `F` `L`     | `4—3`     |\n| 32    | `R` `F`     | `F` `L`     | `L` `R`     | `4—4`     |\n| 33    | `R` `L`     | `L` `F`     | `F` `R`     | `4—5`     |\n| 34    | (unmapped)  | (unmapped)  | (unmapped)  | `4—6`     |\n\n### Cycle One Way\n\nThe direction with the highest priority becomes the least prioritized in the next cycle.\n\nOnly 1 direction is available in a single cycle.\n\n| Index | Cycle 1     | Cycle 2     | Cycle 3     | Domino -\u003e |\n|-------|-------------|-------------|-------------|-----------|\n| 35    | `F`         | `L`         | `R`         | `5—0`     |\n| 36    | `F`         | `R`         | `L`         | `5—1`     |\n| 37    | `L`         | `F`         | `R`         | `5—2`     |\n| 38    | `L`         | `R`         | `F`         | `5—3`     |\n| 39    | `R`         | `F`         | `L`         | `5—4`     |\n| 40    | `R`         | `L`         | `F`         | `5—5`     |\n| 41    | (unmapped)  | (unmapped)  | (unmapped)  | `5—6`     |\n\n### Flip Flop\n\nThe priority flip flops between 2 primary directions.\n\n| Index  | Flip       | Flop       | Domino -\u003e |\n|--------|------------|------------|-----------|\n| 42     | `F`        | `L`        | `6—0`     |\n| 43     | `F`        | `R`        | `6—1`     |\n| 44     | `L`        | `F`        | `6—2`     |\n| 45     | `L`        | `R`        | `6—3`     |\n| 46     | `R`        | `F`        | `6—4`     |\n| 47     | `R`        | `L`        | `6—5`     |\n| 48     | (unmapped) | (unmapped) | `6—6`     |\n\n\u003cbr\u003e\n\n\n## Error Types\nThe spec doesn't define a way to recover from errors gracefully yet. For now, whenever an error occurs, the program will terminate immediately and the interpreter will print the error message to the console in an attempt to help you understand what went wrong.\n\n\u003e [!TIP]  \n\u003e If the error message isn't helpful to you, try using the `--debug` flag when using the reference interpreter. This will print out every instruction, address and the state of the stack at any point in time.\n\nHere is a list of errors that can occur:\n\n- **InterpreterError**: Something wrong with the Interpreter: {message}\n- **SyntaxError**: Unexpected token '{token}' at line {line}, column {column}\n- **InvalidGridError**: Invalid grid. All lines containing code must be the same length (for now)\n- **MultiConnectionError**: {type} connection at line {line}, column {column} is trying to connect a cell that is already connected\n- **MissingConnectionError**: Non-empty cell at line {line}, column {column} does not have a connection\n- **ConnectionToEmptyCellError**: Connection to an empty cell at line {line}, column {column}\n- **ConnectionToEmptyCellsError**: There are connectors that are not connected to anything (Cannot give you the exact location of the error atm)\n- **UnexpectedEndOfInputError**: Unexpected end of input at line {line}, column {column}\n- **AddressError**: Address '{address}' out of bounds\n- **InvalidLabelError**: Label {name} is not a valid label\n- **StepToEmptyCellError**: Trying to step from cell {currentAddress} to empty cell {emptyAddress}\n- **JumpToItselfError**: Jumping to itself at address {address} is forbidden as it results in an infinite loop\n- **JumpToExternalLabelError**: Jumping to an external label from {name} at address {address} is forbidden. External labels can only be used by CALL instruction\n- **CallToItselfError**:Calling to itself at address {address} is forbidden as it results in an infinite loop\n- **UnexpectedEndOfNumberError**: Unexpected end of number at address {address}\n- **ValueTooLargeError**: The value {value} is too large. Currently LIT {literalParseMode} is set. Meaning each number must fit on {literalParseMode} domino(s). Try increasing the LIT or use a higher BASE`.\n- **UnexpectedChangeInDirectionError**: Unexpected change in direction at address {address}. When using GET or SET the direction is dictated by the first domino and cannot change\n- **EmptyStackError**: Cannot pop from an empty stack\n- **FullStackError**: Cannot push to a full stack\n- **InvalidInstructionError**: Invalid instruction opcode {opcode}\n- **InvalidNavigationModeError**: Invalid navigation mode {mode}\n- **InvalidValueError**: Invalid value {value}\n- **InvalidSignError**: Invalid sign {value} at address {address}. When getting a signed number, the sign cell must be either 0 (pos) or 1 (neg)\n- **DSInvalidBaseError**: Invalid base {base}. You can only set the base to a number between 7 and 16\n- **DSInvalidLiteralParseModeError**: Invalid literal parse mode {value}. You can only set the parse mode to a number between 0 and 6\n- **InvalidInputError**: Invalid input {reason}\n- **MissingListenerError**: NUMIN, NUMOUT, STRIN or STROUT instructions were called and the DominoScript \"runtime\" did not provide a way on how to handle input or output\n\n\u003cbr\u003e\n\n## Contributing\n\nDo you have any feature suggestions? Do you have any questions? Have you written any code in DominoScript and would like to share it? - Feel free to open issues and start discussions in this repo!\n\nI am grateful for any interest and help in finding bugs, fixing spelling errors and improving the documentation. If you create any programs or use DominoScript in any way, please let me know. I would love to see what you come up with!\n\nThis silly language is still in its early stages but most of the \"core\" features have already been implemented. I am very hesitant to introduce breaking changes but until the release of `v1.0.0` there might still be some.\n\nSee the [roadmap](#roadmap) for ideas.\n\nIf you are curious, see my [Notes](./docs/notes.md) to learn about the thought process that went into making DominoScript.\n\n\u003cbr\u003e\n\n## Roadmap\n\nNot sure if the term \"roadmap\" is appropriate. This is more of a list of things that I would like to see implemented:\n\n- \u003cins\u003eMore instructions\u003c/ins\u003e for fixed point arithmetic, string manipulations, networking, syscalls etc. could be useful *(in theory DS can support up to 1000 opcodes. Only ~47 are used at the moment)*\n- \u003cins\u003eMore Navigation Modes\u003c/ins\u003e The nav mode decides where the Instruction Pointer will move to next. We already have quite a lot of [nav modes](#navigation-modes). Most of which are just variations of each other. Currently the IP can only move in cardinal directons to direct neighbours. New nav modes might introduce diagonal movement, or allow the IP to move to non-direct neighbours etc.\n- \u003cins\u003eBetter Documentation\u003c/ins\u003e that is more concise and better structured. A short tutorial would be useful to familiarize new users with the language. Maybe on its own website with interactive snippets.\n- \u003cins\u003eMore Interpreters\u003c/ins\u003e Once I am happy with the core functionality, I want to create at least 1-2 more reference interpreters in different languages. Probably in C and/or Go.\n- \u003cins\u003eA Simple CLI Game\u003c/ins\u003e like Snake or Breakout. When I started designing the language my goal was to eventually create a pong-like game with it.\n- \u003cins\u003eA brainf\"ck interpreter\u003c/ins\u003e written in DominoScript.\n- \u003cins\u003eInteractive online playground\u003c/ins\u003e where you can write and run DominoScript code in the browser. Maybe allow users to share their code and let others rate it.\n- \u003cins\u003eA minimal game engine\u003c/ins\u003e written in a sane language that uses DominoScript as its primary scripting language.\n- \u003cins\u003eA Compiler\u003c/ins\u003e. Probably not an easy task given the self-modifying 2D nature of the language and its [NavModes](#navigation-modes). Maybe some form of JIT compilation for frequently used paths or special instructions indicating \"compile-safe-mode\".\n- \u003cins\u003eA Scanner\u003c/ins\u003e that can read DominoScript from images of real Domino pieces like a QR code scanner *(minus the redundancy and error correction)*. It could probably work fairly reliably with a good enough camera and a limited grid size.\n\n\u003cbr\u003e\n\n## Examples\nA list of examples to help you understand the language better.\n\n1. [Hello World minimal](./examples/001_hello_world_minimal.ds)\n2. [Hello World Commented](./examples/002_hello_world_commented.md)\n3. [Hello World 2D](./examples/003_hello_world_2d.md)\n4. [Loop Simple](./examples/004_loop_simple.md)\n5. [Loop using jump](./examples/005_loop_using_jump.md)\n6. [Loop using jump and label](./examples/006_loop_using_jump_and_label.md)\n7. [Call function by address](./examples/007_calling_functions_by_address.md)\n8. [Call function by label](./examples//008_calling_functions_by_label.md)\n9. [Recursion: Factorial](./examples/009_recursive_factorial.md)\n10. [Navigation Mode changes](./examples/010_navigation_mode_changes.md)\n11. [Basic game loop](./examples/011_basic_game_loop.md)\n12. [Number Input](./examples/012_number_input.md)\n13. [String Input](./examples/013_string_input.md)\n14. [Import script into another](./examples/014_import_parent.md)\n15. [Call imported function](./examples/015_import_call_parent.md)\n16. [Ansi clear screen](./examples/016_game_loop_ansi_clear_screen.md)\n17. [Using delay](./examples/017_using_wait.md)\n18. [Reverse String](./examples/018_reverse_string.md)\n19. [Input Controls](./examples/019_input_controls.md)\n20. [Check String Equality](./examples/020_check_string_equality.md)\n21. [Reduce domino amount](./examples/021_reduce_domino_amount.md)\n22. [Modify Code using SET](./examples/022_modify_code_using_set.md)\n23. [WASD Controls](./examples/023_wasd_controls.md)\n24. [Benchmark 01](./examples/024_benchmark_01.md)\n\n*If you want your example to be added to this list, please create a PR.*\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandreas-schoch%2Fdominoscript","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fandreas-schoch%2Fdominoscript","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandreas-schoch%2Fdominoscript/lists"}