MeowScript reference
MeowScript is a small, dynamically typed scripting language. Its keywords are cat puns, its values are the usual ones under different names, and its interpreter is written in Rust. This page is the whole language.
If you just want to poke at it, the playground runs everything on this page. Every listing has a Try it button.
A first program
scratch cat = { name: "Whiskers", lives: 9 }; pawction describe(c) { tail c's name + " has " + c's lives + " lives";} meow(describe(cat));Statements end with a semicolon. You may leave it off before a closing } and at the very end of a file, and after anything that already ends in a } such as a purrhaps or a pawction declaration.
Comments are // to the end of the line or /* anywhere in between */.
Printing
meow prints its arguments separated by spaces, announced with Meow!. purr prints them without the announcement. log is the same as purr, for people who miss JavaScript.
meow("hello", 42, purrfect); // Meow! hello 42 purrfectpurr("hello", 42, purrfect); // hello 42 purrfectValues
| Type | Called | Looks like |
|---|---|---|
| number | number | 42, 3.5, 1_000, 2e3 |
| string | whiskers | "meow" |
| boolean | boolean | purrfect, clawful |
| null | mew | mew |
| array | furrball | [1, 2, 3] |
| object | object | { name: "Tom", age: 3 } |
| function | pawction | pawction(a, b) { tail a + b; } |
furreal tells you which one you have: furreal [] is "furrball".
Numbers
All numbers are 64-bit floats. Whole numbers print without a decimal point. Dividing by zero is an error rather than infinity.
Whiskers
Strings use double quotes and understand \n, \t, \", \\, and \u{1F431}. They may span lines.
+ joins whiskers with anything, converting the other side the way meow would print it. * repeats.
purr("cats: " + 3); // cats: 3purr("=^.^= " * 3); // =^.^= =^.^= =^.^=purr("meow"[0]); // mpurr("meow"[-1]); // wFurrballs
Furrballs are arrays. Indexes start at 0 and negative indexes count from the end. Reading past either end is an error, not mew.
scratch toys = ["yarn", "box"];purr(toys[0], toys[-1]); // yarn boxamew toys[1] = "sunbeam";purr(toys); // ["yarn", "sunbeam"]Furrballs and objects are shared, not copied. Two variables pointing at the same furrball see the same changes, like in JavaScript or Python. == compares contents, though, so [1, 2] == [1, 2] is purrfect.
Objects
Objects are ordered maps from whiskers to values. Keys can be written bare or quoted; { name } is short for { name: name }; [expr] computes a key.
Read a key with obj's key or obj["key"]. A key that isn't there gives mew. Write one with amew.
scratch cat = { name: "Tom", "fur color": "grey" };purr(cat's name, cat["fur color"]);amew cat's age = 4;purr("age" ~ cat); // purrfectVariables
scratch declares a variable in the current scope. amew changes one that already exists, searching outward through enclosing scopes. Using amew on a name that was never scratched is an error, and so is reading one, with a did you mean hint when there's a close match.
scratch lives = 9;purrhaps purrfect { amew lives = lives - 1; // changes the outer `lives` scratch lives = 100; // a new, inner `lives`}purr(lives); // 8Blocks, loops, and pawction calls each open a new scope.
Operators
From loosest to tightest binding. Operators on the same row are applied left to right.
| Operators | Meaning |
|---|---|
|| | or (short-circuits, returns the deciding value) |
&& | and (short-circuits, returns the deciding value) |
== != | equal, not equal (by contents) |
< > <= >= ~ | compare; ~ is "is in" |
| | bitwise or |
^ | bitwise xor |
& | bitwise and |
<< >> | shift |
+ - | add, subtract (and join whiskers or furrballs) |
* / % | multiply, divide, remainder (and repeat whiskers) |
-x !x furreal x | negate, not, type of |
f(x) a[i] a's b | call, index, property |
This is the ordering Python and Rust use, so 6 & 3 == 2 means (6 & 3) == 2.
~ works on all three containers: 2 ~ [1, 2], "age" ~ cat, and "ow" ~ "meow".
Only mew and clawful are falsy. 0, "", and [] are all truthy, so purrhaps count { ... } doesn't skip zero.
Conditions
purrhaps is if, meowtually is else. Parentheses around the condition are optional. Chains work as you'd expect.
purrhaps hour < 6 { meow("too early");} meowtually purrhaps hour < 12 { meow("breakfast time");} meowtually { meow("second breakfast time");}purrhaps is an expression. A block's value is the value of its last statement, so you can use it on the right of a scratch or as the last line of a pawction.
scratch mood = purrhaps fed { "purring" } meowtually { "plotting" };Loops
furrever loops forever, or while a condition holds if you give one. hiss breaks out; continue skips to the next round.
scratch n = 0;furrever { amew n = n + 1; purrhaps n % 2 == 0 { continue; } purrhaps n > 7 { hiss; } purr(n);} furrever n > 0 { amew n = n - 3;}fur walks over something: the items of a furrball, the characters of whiskers, the keys of an object, or the numbers from 0 up to (not including) a number.
fur toy ~ ["yarn", "box"] { purr(toy); }fur letter ~ "cat" { purr(letter); }fur key ~ { a: 1, b: 2 } { purr(key); }fur i ~ 3 { purr(i); } // 0 1 2Pawctions
Declare a named pawction, or make an anonymous one and keep it in a variable. Either way they are values: pass them around, return them, put them in furrballs.
pawction add(a, b) { tail a + b;} scratch double = pawction(x) { x * 2 }; purr(add(2, 3), double(4));tail returns. If a pawction runs off the end, it returns the value of its last statement, which is why double above works without one. A pawction with no useful last statement returns mew.
Pawctions close over the scope they were made in:
pawction counter() { scratch n = 0; tail pawction() { amew n = n + 1; tail n; };} scratch next = counter();next(); next();purr(next()); // 3Calling with the wrong number of arguments is an error. So is nesting calls more than a thousand deep, which usually means a recursion with no way out.
Pawckages
pawckage pulls in a library. The built-in ones start with nya: and are listed under Standard library.
pawckage "nya:furrball";pawckage "nya:catculator"; purr(map(range(5), pawction(n) { round(sqrt(n)) }));Any .meow file is also a pawckage. Everything scratched or declared at its top level becomes available to whoever imports it. Paths are relative to the importing file, and the .meow can be left off.
pawckage "./lib/kitty_math";purr(lives_left(2));File pawckages need a filesystem, so they work from the command line but not in the browser playground.
Errors
Every error says what went wrong and points at where:
Furbidden! type error: `-` doesn't work between whiskers and a number --> toys.meow:4:12 | 4 | scratch n = "nine" - 1; | ^^^^^^^^^^The exclamation tells you the kind: Meowch! for syntax, Meow-sterious! for an unknown name, Furbidden! for a type mismatch, Paws off! for the wrong number of arguments, Lost kitten! for a pawckage that can't be found, Scratched! for file trouble, and Hiss! for everything else at run time.
The command line
Prebuilt binaries are on the download page. With a Rust toolchain you can also build it yourself:
cargo install --git https://github.com/AlenVelocity/MeowScript meowscript-cli meowscript # start the REPLmeowscript hello.meow # run a filemeowscript eval "1 + 2" # evaluate a snippetmeowscript packages # list the nya: pawckagesThe REPL keeps reading lines while a block is open, prints the value of each expression, and leaves when you type scram.
Standard library
These tables come from the interpreter itself (meowscript packages --json), so they can't drift from the code. Arities are checked before a function runs: the wrong number of arguments is a Paws off! error, not a silent mew.
Always available
| Pawction | Takes | Does |
|---|---|---|
meow | at least 0 arguments | Print the arguments on one line, announced with "Meow!". |
purr | at least 0 arguments | Print the arguments on one line, separated by spaces. |
log | at least 0 arguments | The same as `purr`, for people who miss JavaScript. |
length | exactly 1 argument | How many characters, items, or keys something has. |
pawckage "nya:clawtility";
Input, timing, objects, and other everyday tools.
| Pawction | Takes | Does |
|---|---|---|
length | exactly 1 argument | How many characters, items, or keys something has. |
kibble | between 0 and 1 arguments | Read a line of input. Shows the prompt first if you give one. |
nap | exactly 1 argument | Pause for that many milliseconds. |
now | exactly 0 arguments | Milliseconds since the Unix epoch. |
keys | exactly 1 argument | A furrball of an object's keys, in insertion order. |
values | exactly 1 argument | A furrball of an object's values, in insertion order. |
remove | exactly 2 arguments | Remove a key from an object. Returns the removed value, or mew. |
assert | between 1 and 2 arguments | Stop with an error unless the first argument is truthy. |
apply | exactly 2 arguments | Call a pawction with a furrball of arguments. |
pawckage "nya:furrball";
Everything for furrballs (arrays).
| Pawction | Takes | Does |
|---|---|---|
push | at least 2 arguments | Add items to the end of a furrball. Changes it in place and returns it. |
pounce | exactly 1 argument | Remove and return the last item, or mew if the furrball is empty. |
top | exactly 1 argument | The first item, or mew. |
last | exactly 1 argument | The last item, or mew. |
bottom | exactly 1 argument | A new furrball with everything but the first item. |
includes | exactly 2 arguments | Whether a furrball has an item, or whiskers contain a substring. Same as `~`. |
index_of | exactly 2 arguments | Where an item (or substring) first appears, or -1. |
map | exactly 2 arguments | A new furrball made by calling the pawction on each item. |
filter | exactly 2 arguments | A new furrball of the items the pawction says purrfect to. |
reduce | between 2 and 3 arguments | Fold a furrball into one value with `pawction(total, item)`, starting from the optional initial value. |
each | exactly 2 arguments | Call the pawction on every item. Returns mew. |
find | exactly 2 arguments | The first item the pawction says purrfect to, or mew. |
range | between 1 and 3 arguments | Numbers from `start` (default 0) up to but not including `end`, in `step`s (default 1). |
reverse | exactly 1 argument | A reversed copy of a furrball or whiskers. |
sort | between 1 and 2 arguments | A sorted copy. Give a `pawction(a, b)` returning a number to decide the order. |
join | between 1 and 2 arguments | Glue the items into whiskers with a separator (default none). |
slice | between 2 and 3 arguments | A copy of part of a furrball or whiskers, from `start` up to (not including) `end`. Negative counts from the end. |
concat | at least 1 argument | A new furrball with the items of all the given furrballs. |
pawckage "nya:whiskers";
Everything for whiskers (strings).
| Pawction | Takes | Does |
|---|---|---|
in_whiskers | exactly 1 argument | Turn anything into whiskers, the way `meow` would print it. |
pawrse | exactly 1 argument | Read a number out of whiskers, or mew if there isn't one. |
replace | exactly 3 arguments | Replace every occurrence of `from` with `to`. |
split | between 1 and 2 arguments | Split into a furrball on a separator. With no separator, splits on whitespace. |
upper | exactly 1 argument | SHOUTING. |
lower | exactly 1 argument | whispering. |
trim | exactly 1 argument | Strip whitespace from both ends. |
starts_with | exactly 2 arguments | Whether the whiskers begin with the given prefix. |
ends_with | exactly 2 arguments | Whether the whiskers end with the given suffix. |
includes | exactly 2 arguments | Whether a furrball has an item, or whiskers contain a substring. Same as `~`. |
index_of | exactly 2 arguments | Where an item (or substring) first appears, or -1. |
chars | exactly 1 argument | A furrball of the individual characters. |
repeat | exactly 2 arguments | The whiskers repeated that many times. Same as `*`. |
pad_start | between 2 and 3 arguments | Pad on the left to a width, with spaces or the given filler. |
pad_end | between 2 and 3 arguments | Pad on the right to a width, with spaces or the given filler. |
reverse | exactly 1 argument | A reversed copy of a furrball or whiskers. |
slice | between 2 and 3 arguments | A copy of part of a furrball or whiskers, from `start` up to (not including) `end`. Negative counts from the end. |
pawckage "nya:catculator";
Maths. Angles are in radians.
| Pawction | Takes | Does |
|---|---|---|
random | between 0 and 2 arguments | A random number: in [0, 1) with no arguments, [0, n) with one, or [min, max) with two. |
round | exactly 1 argument | Round to the nearest whole number. |
ceil | exactly 1 argument | Round up. |
floor | exactly 1 argument | Round down. |
trunc | exactly 1 argument | Drop the fractional part. |
abs | exactly 1 argument | Distance from zero. |
sqrt | exactly 1 argument | Square root. |
sin | exactly 1 argument | Sine (radians). |
cos | exactly 1 argument | Cosine (radians). |
tan | exactly 1 argument | Tangent (radians). |
log2 | exactly 1 argument | Logarithm base 2. |
log10 | exactly 1 argument | Logarithm base 10. |
ln | exactly 1 argument | Natural logarithm. |
exp | exactly 1 argument | e raised to the power. |
pow | exactly 2 arguments | `base` raised to `exponent`. |
modulo | exactly 2 arguments | Remainder that is never negative for a positive divisor, unlike `%`. |
min | at least 1 argument | The smallest of the numbers, or of one furrball of numbers. |
max | at least 1 argument | The largest of the numbers, or of one furrball of numbers. |
clamp | exactly 3 arguments | Keep a number between `low` and `high`. |
| Constant | Value |
|---|---|
PI | 3.141592653589793 |
TAU | 6.283185307179586 |
E | 2.718281828459045 |
INFINITY | Infinity |
pawckage "nya:rundamn";
Random numbers, choices, and shuffles.
| Pawction | Takes | Does |
|---|---|---|
seed | exactly 1 argument | Restart the random sequence from a number, so runs repeat exactly. |
random | between 0 and 2 arguments | A random number: in [0, 1) with no arguments, [0, n) with one, or [min, max) with two. |
uniform | exactly 2 arguments | A random float in [a, b). |
randint | exactly 2 arguments | A random whole number from a to b, including both ends. |
choice | exactly 1 argument | A random item from a furrball. |
shuffle | exactly 1 argument | Shuffle a furrball in place and return it. |
pawckage "nya:scratchpad";
Reading and writing files. Not available in the browser.
| Pawction | Takes | Does |
|---|---|---|
read_file | exactly 1 argument | The whole contents of a file as whiskers. |
write_file | exactly 2 arguments | Write whiskers to a file, replacing what was there. |
append_file | exactly 2 arguments | Add whiskers to the end of a file. |
exists | exactly 1 argument | Whether a file or directory is there. |