Loading Pyodide... ( seconds/tick)
Hover over a dot while paused to see its value
Additional input needed
Input
Output

      

AsciiDots is an esoteric programming language based on ascii art. In this language, dots, represented by periods (.), travel down ascii art paths and undergo operations.

Feel free to learn AsciiDots below or watch Truttle1’s video on YouTube.

Movement

Let’s start by looking at a simple asciidots program, where a dot winds through an ascii-art path:

/-&        `` ... and ends here
| 
\-\ /-\ 
  | | |
/-/ | \-\  `` ... turns left then up
\---/   |
        |  `` ... goes up
        .  `` The dot starts here

Here’s what all those characters mean:

  • . represents the starting point of a dot
  • - and | move the dot horizontally and vertically
  • / and \ act like mirrors to change the direction of a dot
  • & immediately stops the program when a dot passes over it

This syntax for comments is the following:

  • `` starts a comment for the rest of the line
  • Inline comments look `like this`


Let’s see a more complicated example:

  /-\ /-& `` End
  | | |
  \-+-v
    | | /-\
(-<-/ | | |
  |   \-<-/
  \-\
    |
    .     `` Start

Here are the new characters introduced:

  • + allows paths to cross without interacting
  • ( and ) set the direction of a dot to right or left (respectively)
  • < > ^ v are arrows that set the direction of a dot that pass through it perpendicularly. If a dot passes through parallel to the arrow, its direction is unchanged.


There can be multiple dots in an asciidots program. This example sends two dots through the same path:

.-->---
   |
.--/

Data

Each dot stores a value and an id. The id can simply be thought as a second value that a dot can hold, and it can be used in any way.

You can set a dot’s value by having it pass over a # followed by a number:

.-#7

A dot’s value can be overwritten. In this example, the dot ends up with a value of 3:

.-#18-#0-#6-#148-#13-#3

The same applies to a dot’s id, except we use the @ symbol. The following example sets a dot’s value to 5 and its id to 6:

.-#5-@6

We can set a dot’s id and value in any direction. The following sets a dot’s value to 18 and its id to 100:

001@-\
     |
     8
     1
     #
     |
     .

Input

To read an integer from stdin, use #? (similar to the syntax for setting a dot to an integer literal). To read a byte from stdin as a number, use #a?, which sets the value to -1 at the end of the file. Similarly, use @ instead of # to set a dot’s id.

This program reads a single number from the program’s input then prints it back out:

.-#?-$#

Output

The $ character is used to output data to stdout. There are a few ways it can be used:

  • $# and $@ print the dot’s value/id in decimal
  • $a# and $a@ print the dot’s value/id as a raw byte
  • $"hello" prints hello with buffering (all at once)
  • $'hello' prints hello one character at a time

Using double quotes " is helpful to avoid race conditions when multiple dots print at once.

The characacter _ prints without adding a newline. It can go anywhere except the end newline from being added the the output.

This example prints a % without a newline, using its ASCII code 37:

.-#37-$_a#

Now we can read a number from the program’s input then print it back:

.-#?-$#

Operations

[*] multiplies the value that passes through vertically by the value that runs into it horizontally. When a dot arrive here, it waits for another dot to arrive from a perpendicular direction. When that dot arrives, the dot that arrived from the top or bottom has its value updated and it continues through the opposite side. The dot that passed through horizontally is deleted.

{*} does the same except it multiplies the value that enters horizontally by the value that enters vertically. The resulting dot exits horizontally.

Other operations work similarly:

       
+ add = equal
- subtract ! not equal
* multiply > greater
/ divide < less
% modulo G greater or equal
^ exponent L less or equal
       
& bitwise AND    
o bitwise OR    
x bitwise XOR    

These characters are only considered operators when located within brackets. Outside of brackets, symbols like + perform their regular functions as described earlier.

Example of subtraction (3 - 2 = 1):

 #
 $
 |
[-]-2#-.
 |
 3
 #
 |
 .

Calculating the sum of two input values:

.-#?-{+}-$#
      |
.-#?--/

Duplication

* duplicates a dot and distributes copies to all attached paths except the path where the original dot came from. These copies have the same id and value as the original dot.

This example creates three dots, each with a value of 7:

     /---$#
     |
.-#7-*---$#
     |
     \---$#

These three dots are entirely unrelated, and changing the value of one will not affect any others.

Control Flow

~ takes two dots, one from the side (the “input”) and one from the bottom (the “condition”). The input dot is directed upwards if the condition dot’s value is equal to zero. Otherwise, it’s directed horizontally:

     /-$"Equal to zero"
     |
.----~-$"Not equal to zero"
     !
.-#?-/

If an ! is placed under the ~, then the behavior is reversed: the input dot is now directed horizontally if the condition dot is equal to zero:

     /-$"Not equal to zero"
     |
.----~-$"Equal to zero"
     !
.-#?-/

Filters

A “filter” delete dots traveling over it that have a specific value:

  • : deletes dots with a value of 0 traveling over it
  • ; deletes dots with a value of 1 traveling over it

Advanced Features

A warp is a character that teleports, or ‘warps’, a dot to the other occurrence of the same letter in the program.

Define warps at the beginning of the file by listing them after a %$. The %$ must be at the beginning of the line.

This example outputs the number 9:

%$A

.-#9-A

A-$#

AsciiDots also supports libraries, which are documented here.