# Meow5: "Meow. Meow. Meow. Meow. Meow."

<img src="raw/meow5cat.svg" alt="SVG meow5 kitty cat logo" align="right">

**Update 2023-11-21** Meow5 is done!
<a href="https://www.ratfactor.com/meow5/done">Read my conclusion here!</a>

Meow5 is a stack-based pure inlining concatenative programming language.

Running Meow5 interactively looks like this:

    5 5 +
    "The answer is $." print$
    The answer is 10.

In the above example, the first line puts two fives on the
stack and adds them.

The second line prints the answer. (The "$" character pops a number from the stack and includes it in the printed string.)

Now we can see that 5 + 5 is 10.

A block of code can be given a name and is called a "def"
(short for definition). Here's one:

    def meow
        "Meow!" print
    ;

    meow
    Meow!

Defs can include other defs. Here's a silly example:

    def five 5 ;
    def plus + ;
    def ten five five plus ;

    ten "Ten is $" print$
    Ten is 10

Meow5 can write *any* def as a stand-alone 32-bit Linux ELF
executable. (But not all defs are position-independent at
this time, so some executables will segfault!)  Here's an
example session:

    $ ./meow5

    def forty-two
        42 exit
    ;

    elf forty-two
    Wrote to "forty-two".

    $ ./forty-two
    $ echo $?
    42

Note that `$?` contains the exit code of the previous command.

The file `forty-two` is a 97-byte program that will run on
any Linux system!

The canonical Meow5 program writes five meows. Here is a
self-contained meow file:

    $ cat 5.meow 
    def meow
        "Meow!\n" print
    ;

    def five-meows
        meow
        meow
        meow
        meow
        meow
        exit
    ;

    elf five-meows

That last line tells the interpreter to write out the
five-meows def as a stand-alone executable. Let's see what
happens when we redirect this file to the interpreter:

    $ ./meow5 < 5.meow
    Wrote to "five-meows".

It wrote a 317 byte executable named `five-meows`. Let's run it:

    $ ./five-meows
    Meow!
    Meow!
    Meow!
    Meow!
    Meow!

Now I can have meowing in my terminal any time I want!

### Now with loops!

Ah, but now it gets better! I've added ifs and loops.
A looped version of the five-meows program is much
more efficient with space. Here's `five-loop.meow`:

    def meow
        "Meow!\n" print

        # decrement the stack each time or
        # we'll end up with an infinite loop!
        dec
    ;

    # Another def that loops!
    def five-meows-loop
        5 loop? meow
        exit
    ;

    # Write an executable :-)
    elf five-meows-loop

It works exactly like the five copy inline version:

    $ ./meow5 <five-loop.meow 
    Wrote to "five-meows-loop".

    $ ./five-meows-loop 
    Meow!
    Meow!
    Meow!
    Meow!
    Meow!

Except this executable is a mere **160 bytes**. Cool!


## What is Meow5? (and what is "pure inlining"?)

A Forth-like language that is conCATenative in two ways:

1. Concatenative data flow (traditional)
2. Concatenated machine code (weird)

There's a lot of information on the Web about concatenative
programming in the first, traditional sense. But that second
part is what's unique about Meow5.

Luckily, really easy to explain how this works, thanks to
Meow5's introspection abilities:

Using `inspect`, we can view the machine code of any def:

    inspect +
    +: 5 bytes IMMEDIATE COMPILE
        58 5b 1 d8 50

We can see that the `+` def contains five bytes of machine
code.

By the way, that machine code disassembles into this assembly
language:

    pop eax
    pop ebx
    add eax, ebx
    push eax

If we define a new def that uses an existing def, the
machine code simply gets concatenated together:

    def ++
      +
      +
    ;

Let's use this new def to see that it adds three numbers
together:

    10 10 10 ++ printnum
    30

And since we can see that the contents of our new def is,
indeed, the simple concatenation of its constituents (two
copies of the 5 byte `+`):

    inspect ++
    ++: 10 bytes IMMEDIATE COMPILE
        58 5b 1 d8 50 58 5b 1 d8 50

The consequence of this is that any def in Meow5 is a
_complete, stand-alone sequence of instructions_. That's why
writing an executable for any def is as simple as writing
its contents to disk! (Plus the ELF header to make it valid,
of course.)

Q: Is this wasteful? Doesn't this cause a lot of redundant
copies of code?

A: Yes.

But it's interesting because we're also avoiding a lot of
branching - most Meow5 code is a continuous stream of
actions with very tiny relative local jumps. I think it
produces unusual code.

See also:

<a href="http://ratfactor.com/assembly-nights2">Assembly Nights 2</a> - This actually part of a series, a personal exploration of the joy of computing.

<a href="http://ratfactor.com/meow5/">ratfactor.com/meow5/</a> - Meow5's page on the World Wide Web (though this README is more up to date).


## Why?

My idea came about while studying Forth. A traditional
"threaded interpreted" Forth goes to some pretty extreme
lengths to conserve memory. The execution model is not only
complicated, but seems also likely to not be all that great
for efficiency on modern machines where memory is much more
abundant and the bottleneck oftenseems to be getting data
into the CPU fast enough.

In particular, the old Forth literature I have been reading
is full of statements about needing to conserve the **few
kilobytes of core memory** on a late 1960s machine.  But
even my most modest low-powered Celeron and Atom-based
computers have **L1 CPU caches** that dwarf those
quantities!

So, given the tiny size of the programs I was writing with
my JONESFORTH port, I kept thinking, "how far could I get if
I just inlined _everything_?" As in, actually made a copy of
every word's machine instructions every time it is
"compiled".

I expect this will be silly but fun and educational.
