Introduction

What is Mewl?

Mewl is an esoteric programming language. It has syntax very similar to Lisp. Mewl can be very confusing, because many of its design choices I made, for example there are no concept of traditional number system in mewl, or there are no strings, no arrays, and cherry on top, you can not use any word except mew (Comments are exception).

🤔 What,Why?

Well, 2 years ago in 2020, I created an esoteric programming language called Mewmew. It was just a fun and experimental language I made while tinkering with ANTLR, cause I was (am still) fascinated about programming languages, interpreter/compilers; how they work; how they basically become the medium of interaction between humans and computers and/or machines. But with ANTLR, I didn't actually learn much about compiler/interpreter construction. It just worked! No fun! So, In the October of 2021, I started re-writing the whole thing from scratch with Rust. I was able to build a lexer; a basic parser; But then I realized, syntax of 'mewmew' is ugly. I hurts my eyes to look at a 'mewmew' source code. Again in, March 2022, I started experimenting with mewmew lanugage but with lisp style syntax, 'cause lisp is awesome. So, here is the result, Mewl , mewmew reborn with the syntax similar to lisp. Most important thing, I am having fun while developing mewl, and the syntax doesn't hurt my eyes that much.

Numbers

There is no concept of traditional numbers in mewl instead we use mews. For example you want to write 5 you could do something like this

mewmewmewmewmew

or maybe 2

mewmew

So basically 1 mew is equivalent to 1; 2 mews is equivalent to 2 and so on.

:warning: Important Note: We don't have zero, to get zero we use subtraction [- mew mew] (it's like 1-1 = 0) [Mathematical operations will be discussed later]

But what about large numbers like 100 , 2022 , 500 or maybe -10 , -3.1, for that we have some shortcuts, like these : To write large numbers we can use mathematics, like [* mewmew mewmewmewmewmew] is equal to 10, or multiplying that expression with itself we can get 100. But that's cumbersome and complicated! Instead we have a simpler (relatively) syntax shortcut. Lets write 100:

[mew [- mew mew] [- mew mew]]

How about 2022:

[mewmew [- mew mew] mewmew mewmew]

Above two examples will only work when assigning to a variable, but if we want to use these expressions anywhere we have to put this ' single single quote character just after the opening bracket. Something like this:

[' mew mew [+ mew mew]] //is equal to 112

It is being evaluated like this:

flowchart TD;
    A["[' mew mew [+ mew mew]"] --> B["[' mew mew [2]]"]
    B-->C["[' 1 1 2]"]
    C -- Output --> D[112]

But If we remove this ' character and it is not being assigned to a variable or being printed to the stdout, it is going to be evaluated like this and will throw an error:

flowchart TD;
    A["[ mew mew [+ mew mew]]"] --> B["[mew mew 2]"]
    B-->C["[ 1 1 2]"]
    C-->D{Error: No operation to do!}

Identifiers and Assignment

In mewl, identifiers just look like mew numbers, so be careful when reading/writing mewl programs.

Some backstory:

While I was designing mewl identifiers, I was confused about identifiers, I wanted something crazy but usable. So I just decided to go with mew, but to distinguish numbers from identifiers, I needed something special . Now, please continue.

Identifiers/Variables

In mewl, identifiers look something like this -> ~mew , ~mewmew etc.

So basically, Identifiers follow the same syntax as mew numbers but with a leading ~ (tilde) character.

~mew , ~mewmew , ~mewmewmewmewmew , these all are identifiers.

Assignment

Assignments are little awkward, it'd be easy to understand with examples:

[=mew [+ mew mew]]

This expression assigns 2 to the variable ~mew and this expression [:: ~mew] would print the value of variable ~mew (which is 2 )

If you want to assign something to variable, write the identifier with a leading = (equal sign) without any space(s).

In short, =mew tells the interpreter to evaluate the following expression(s) and store it in variable ~mew.

For example,

[=mewmew [* mewmew mewmew]] would store 9 in a variable which can be accessed via ~mewmew.

I know, it is confusing.

More examples:

  • [=mewmewmew [+ mew mew [* mewmew mewmew]]] would store 6 to a variable which to be accessed via ~mewmewmew

  • Another one

    [=mewmewmewmewmew [' mew mew mewmew]]
    [:: ~mewmewmewmewmew]
    

    it would print 112 to stdout

[Info Note]: Assiging something using =mewmewmewmewmew wouldn't change the meaning of mewmewmewmewmew as a mew number which still is 5

Basic Operations

Binary Operations

Mewl supports few commonly used binary operators such as addition, subtraction, division, multiplication etc.

OperationSymbolNotes
Addition+-
Subtraction--
Multiplication*-
Division/[/ m1 m2 m3] -> m1 ÷ m2 ÷ m3
Power**Evaluates just like division
Remainder%evaluates just like division

Unary Minus Operation

There're not specific way to use unary minus Operations in mewl, for example, [+ mew -mew] This should've been evaluated like this , (+1 -1) = 0. But mewl will throw an error if you do something like that. If we want to get -1, we have to do something like this

[- [- mew mew] mew]

It's basically, \(0-x = -x\)

Bitwise Operations

⚠️ Important Reminder : As Bitwise operations cannot be applied on floating point numbers; and in mewl all numbers are 64bit floats, so before doing any bitwise operation numbers are converted to 64bit signed integers and the answer returned is converted to float from signed integer

OperationSymbolNotes
Shift right>>[>> m1 m2 m3] -> m1 >> m2 >> m3
Shift Left<<Same as above
XOR^"
AND&&"
OR##"
NOT!![Note1]

🙀 [Note1] : As bitwise not !! Is an unary operation there can be unexpected behaviors if applied to an expression list, for that it will only be applied on the first element of an expression.

Comparisons (Boolean Operations)

Important Note: In mewl True = 1.0 (mew) and False = 0.0 ([- mew mew])

OperationSymbolNote
Is equal==[== m1 m2 m3] -> m1== m2==m3
Not equal!=similar to previous
Less than<"
Less than or equal<="
Greater than>"
Greater than or equal>="
Or#"
And&"
Not!As this is an unary operation so it's applied on the first element of the given expression

Reading from Stdin and Writing to Stdout

Writing to Stdout

To print something on the stdout we have two options, first we can print the expression or atom as is or we can convert the expression values to ASCII characters and print them to stdout.

SymbolWhatNotes
::Print the expression or atom to stdout as-is[:: mew mew] will print 1 1 to stdout
:::Convert the next atom/expression to ASCII characters and print to stdout[:::['[+[* mewmewmew mewmew] mew] mewmew]] will print H to stdout

Examples

Here's a overly complicated Hello World program in mewl

[=mew [[+[* mewmewmew mewmew] mew] mewmew] ] //H
[=mewmew [mew [- mew mew] mew]] //e
[=mewmewmew [mew [- mew mew] [* mewmewmewmew mewmew]]] //l
[=mewmewmewmew [mew mew mew]] //o
[=mewmewmewmewmew [mewmewmew mewmew]] //SPACE
[=mewmewmewmewmewmew [[* mewmewmewmew mewmew] mewmewmewmewmewmewmew]] //W
[=mewmewmewmewmewmewmew [mew mew mewmewmewmew]] //r
[=mewmewmewmewmewmewmewmew [mew [- mew mew] [- mew mew]]] //d
[=mewmewmewmewmewmewmewmewmew [mewmewmew mewmewmew]] //!

[::: ~mew //H
~mewmew //e
~mewmewmew //l
~mewmewmew //l
~mewmewmewmew //o
~mewmewmewmewmew //SPACE 
~mewmewmewmewmewmew //W
~mewmewmewmew //o
~mewmewmewmewmewmewmew //r
~mewmewmew //l
~mewmewmewmewmewmewmewmew //d
~mewmewmewmewmewmewmewmewmew //!
]

Reading From Stdin

SymbolWhat?Notes
\|>Read a mew number or normal number from Stdin and store to a variableTrailing whitespace gets trimmed
`|>`Read a string from stdin, calculate the length of the string and store to a variable

Read Mew/Normal Number from Stdin

Syntax of reading mew/normal number from stdin is:

[|> Variable_To_Store_Number]

Here's a simple example,

[|> =mew]
[:: ~mew]

This example, reads a number/mewnum from stdin and prints it to stdout.

Read a String from Stdin and store the length

Syntax is just like reading number from stdin,

[||> =mew]
[:: ~mew]

Just like before, read a string from stdin and print the length of the string.

Example/Usage

a. Count the character of a file using mewl

First, let's create a simple script (it is just the above example code)

[||> =mew]
[:: ~mew]

save it with filename char_len.mew.txt

Now, we need the target file, from which we will count characters from, for this example we will create a file,

$ echo "Foo bar" >foobar.txt

Now, run

$ cat foobar.txt | mewl char_len.mew.txt

If everything is right, you'll see 7 in the terminal!

Example Programs

Hello World

[=mew [[+[* mewmewmew mewmew] mew] mewmew] ] //H
[=mewmew [mew [- mew mew] mew]] //e
[=mewmewmew [mew [- mew mew] [* mewmewmewmew mewmew]]] //l
[=mewmewmewmew [mew mew mew]] //o
[=mewmewmewmewmew [mewmewmew mewmew]] //SPACE
[=mewmewmewmewmewmew [[* mewmewmewmew mewmew] mewmewmewmewmewmewmew]] //W
[=mewmewmewmewmewmewmew [mew mew mewmewmewmew]] //r
[=mewmewmewmewmewmewmewmew [mew [- mew mew] [- mew mew]]] //d
[=mewmewmewmewmewmewmewmewmew [mewmewmew mewmewmew]] //!

[::: ~mew //H
~mewmew //e
~mewmewmew //l
~mewmewmew //l
~mewmewmewmew //o
~mewmewmewmewmew //SPACE 
~mewmewmewmewmewmew //W
~mewmewmewmew //o
~mewmewmewmewmewmewmew //r
~mewmewmew //l
~mewmewmewmewmewmewmewmew //d
~mewmewmewmewmewmewmewmewmew //!
]

Fibonacci