-
Notifications
You must be signed in to change notification settings - Fork 10
Tutorial
We'll start with examples in the Charcoal REPL.
To use the REPL, simply run the command ./charcoal.py
, python charcoal.py
or python3 charcoal.py
. Note that ./charcoal.py
will not work on Windows. Alternatively, you can run charcoal.py
from Idle.
The central concept in Charcoal is printing strings to a canvas using a cursor. Any expression not preceded by a command is implicitly printed left-to-right. An expression preceded by one of the arrows ←↑→↓↖↗↘↙
is printed in that direction. Each print begins from the location where the previous one left off.
Charcoal> foo
foo
Charcoal> ↘bar
foob
a
r
Note that the second and third lines are left-padded with spaces, and the first and second lines are right-padded. You can change the background character to something other than space; more on that later.
After a few REPL commands, the canvas can get crowded. To clear it, hit Ctrl+C or use the ⎚
Clear command.
Charcoal> ^C
Cleared canvas
Any run of printable ASCII--including space (0x20
)--is a string literal. Strings can also include ¶
, which represents a newline.
Charcoal> Hello, World!¶123
Hello, World!
123
Since the ASCII digits are used in string literals, integer literals consist of the superscript digits ⁰¹²³⁴⁵⁶⁷⁸⁹
. Printing an integer results in a line, using a character selected from /\|-
based on the direction of printing.
Charcoal> ⁷
-------
Charcoal> ↙³
-------/
/
/
To output a number instead of a line, we need the Cast operator I
. This converts strings to numbers and vice versa.
Charcoal> I⁴
4
Arithmetic behaves mostly as expected, though the symbols are different: ⁺⁻×÷
and X
for exponentiation. Division rounds down to the nearest integer.
All operators are prefix. This sometimes creates the need to use the separator ¦
between operands to prevent them from being parsed as a single literal.
Charcoal> I⁺⁴¦⁴
8
Charcoal> ,I⁻⁴¦⁴
8,0
Charcoal> ,I×⁴¦⁴
8,0,16
Charcoal> ^C
Cleared canvas
Charcoal> I÷⁶¦⁴
1
Charcoal> ,IX³¦³
1,27
A variable in Charcoal is any Greek lowercase letter from αβγδεζηθικλμνξπρσςτυφχψω
. (Omicron was omitted because it looks too much like o
.) You can assign values to them using the A
command:
Charcoal> A⁵β
Charcoal> ×$β
$$$$$
There are two ways to take input -- to store it as a variable, and to use it directly.
If there is no variable after the command, it is treated as an operator with no arguments, returning the next input:
Charcoal> N
Input number: 5
-----
If there is a variable, input is instead stored in the variable, and nothing is returned.
Charcoal> Nβ
Input number: 3
Charcoal> β
---
¿
is the if
command. It is followed by an expression (we shall call this x
), and two bodies y
and z
, which are either an expression or multiple expressions surrounded by the double angle brackets «»
. y
gets executed if x
evaluates to a truthy value, else y
gets executed.
Charcoal> ¿⁰foo¦bar
foo
Charcoal> ¿a«←ab»cd
foba
F
is the for
command. It is followed by an expression x
and a body y
. If x
is a number, it is converted to a range from 0
to x
, excluding x
itself. Then, x
is iterated over, y
being run once for each element in x
, the element being stored in the first free variable in ικλμνξπρςστυφχψωαβγδεζηθ
.
Charcoal> F²⁴na¦batman
nanananananananananananananananananananananananabatman
Charcoal> ^C
Cleared canvas
Charcoal> FHello, World!ײι
HHeelllloo,, WWoorrlldd!!
W
is the while
command. It is followed by an expression x
and a body y
. While x
evaluates to truthy, y
is run, the value of x
being stored in ικλμνξπρςστυφχψωαβγδεζηθ
.
Charcoal>A¹⁰βWβ«⁺ι A⁻β¹β»
10 9 8 7 6 5 4 3 2 1
HF
is RefreshFor
- the same as for
but with a numeric delay in milliseconds before x
.
Similarly, HW
is RefreshWhile
- the same as while
but with a numeric delay in milliseconds before x
.
Finally we have ⎇
, the ternary operator. This accepts three expressions x
, y
and z
, returning y
if x
evaluates to true else z
.
Charcoal> ײ⎇¹b²
bb
Multiprint (P
) acts the same as print except that it accepts a multidirection instead of a directions, which is either a list of directions multidirections (+X*|-\/<>^KLTVY7¬
).
Below is a list of directions and the directions they expand to:
Symbol | Directions |
---|---|
+ |
Right, Down, Left, Up |
X |
Up Right, Down Right, Down Left, Up Left |
* |
Right, Down Right, Down, Down Left, Left, Up Left, Up, Up Right |
| |
Up, Down |
- |
Left, Right |
\ |
Up Left, Down Right |
/ |
Up Right, Down Left |
< |
Up Right, Down Right |
> |
Down Left, Up Left |
^ |
Down Right, Down Left |
K |
Up, Up Right, Down Right, Down |
L |
Up, Right |
T |
Right, Down, Left |
V |
Up Left, Up Right |
Y |
Up Left, Up Right, Down |
7 |
Down Left, Left |
¬ |
Down, Left |
The general rule is the directions start from Right, and continue clockwise. The exceptions to this are V
and Y
.
Charcoal> P*abc
c c c
bbb
cbabc
bbb
c c c
Rectangle (UR
) creates a rectangle with the specified width and height, using |
and -
as edges and +
as corners.
Charcoal> UR⁵¦⁵
+---+
| |
| |
| |
+---+
Box (B
) creates a rectangle with the specified width and height, and using the specified characters as the edge, starting from the top edge.
Charcoal> B⁵¦⁵¦abc
abcab
a c
c a
b b
acbac
Polygon (G
) accepts a list of sides, which are alternating numbers and directions