Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/fionafibration/owoScript

An OwO based, stack-oriented programming language
https://github.com/fionafibration/owoScript

antlr4-grammar antlr4-python3 esoteric-programming-language owo owo-whats-this programming-language programming-languages python python3

Last synced: about 2 months ago
JSON representation

An OwO based, stack-oriented programming language

Awesome Lists containing this project

README

        

# owoScript

owoScript is a stack based, imperative, and Turing complete programming language.
owoScript works with a simple and descriptive language
that is then compiled to the best bytecode to ever exist on this planet.

Why is owoScript bytecode the best on the planet? Because it's entirely made out of
OwO faces! Why have the speed and portability of the JVM when you can have the most *adorable*
code out of almost any language you can write in? And never fear, your owoScript bytecode can easily be turned
back into the higher level form at any time.

Additionally, owoScript leaves its syntax and parsing files easily accessible to be inspected and verified by
anyone. owoScript's grammar is written in ANTLR4, a parsing tool so out of this world reliable and efficient that
you'll wonder why your favorite programming language isn't using it yet.

### Examples
See the `/examples` directory for a hello world, truth machine, and a proof of turing completeness via
brainfuck equivalents (does your fancy OOP language prove that it is capable of universal computation?
Can you trust it if it doesn't?)

### Usage

##### Stack

owoScript is written in a descriptive language consisting of stack operations, number literals,
`while` loops, and `if {} else {}` statements.
Whitespace is ignored.

owoScript is stack-based, with only integer types. For example,
the following literal will push `6` onto the stack:
```
literal 6;
```
and the following command will take that number off the stack and print it:
```
printnum;
```
operations take their values off the stack in the order they came onto it:
```
literal 8;
literal 2;
div;
```
corresponds to 8 / 2, not 2 / 8. However, in addition to the stack, an optional "hashmap",
mapping integer keys to integer values, is available through the `store` and `get` commands

##### Arithmetic

Because owoScript is stack-based, arithmetic is performed in postfix notation.
This means that writing something like (2+3)*(5/7)
is written by taking the operator out of the middle of the expression and adding it on to the end.
So 2+3 is written as `literal 2; literal 3; add;` and 5/7 is written as `literal 5; literal 7; div;`

The final expression would thus be written as:

```
literal 2;
literal 3;
add;
literal 5;
literal 7;
div;
mult;
```

##### Flow control

Flow control is provided in `while` loops, functions, and `if {} else {}` statements

While loops simply repeat the operation inside them until the top of the stack is 0, or falsy.
They do not pop values, and instead simply inspect the stack without changing it. While loops are skipped
if the top of the stack is 0 when they are made.

Example:
```
// Truth machine
// When a truthy number is inputted, continue printing it forever
// Otherwise print once and stop
inputnum;
dupe;
printnum;
while {
dupe;
printnum;
}
```

Functions are defined at the top of the file and called like so,
and can call other functions. Putting a function anywhere other than
at the top of the file will result in very undefined behavior.
Functions do not take argument, and simply operate off of the stack.
```
func square {
dupe;
mult;
}
literal 3;
square();
```

If statements have the syntax
```
if {
// statements or nop;
}
else {
// statements or nop;
}
```
and pop the top value of the stack. If it is truthy, the first block is executed. Otherwise,
the second one is.

##### Commands

Commands are single word operations (except for number literals and bignumber literals, see below)

| Keyword | Pops | Pushes |
|------------|------|------------------------------------------------------------|
| literal x | None | hex value of x, x must be single hex digit (0-9, a-f) |
| number x | None | int value of x, x is signed number [*] |
| add | a, b | a + b |
| sub | a, b | a - b |
| mult | a, b | a * b |
| div | a, b | a // b (floor division) |
| mod | a, b | a % b (modulus) |
| exp | a, b | a ^ b (exponent) |
| print | a | prints the character with code *a* |
| printnum | a | prints the number literally |
| printstack | None | prints entire stack |
| input | None | number of character read from stdin |
| inputnum | None | decimal number read from stdin |
| lt | a, b | 1 if a < b else 0 |
| gt | a, b | 1 if a > b else 0 |
| eq | a, b | 1 if a == b else 0 |
| neq | a, b | 1 if a != b else 0 |
| cmp | a, b | if a == b: 0, if a > b: 1, if a < b: -1 |
| dupe | a | a, a (a repeated) |
| dupedeep | a | extend stack with last a values on stack |
| swap | a, b | b, a (top two values swapped) |
| push | a, b | puts a *b* layers deep in the stack |
| fetch | a | pulls the number *a* deep in the stack to the top |
| stacklength| None | length of stack |
| store | a, b | stores b in the *a* slot in the hashmap |
| get | a | pushes the value stored in *a* slot in the hashmap |
| stop | a | exits with return code a |
| fetchdupe | a, b | same as fetch but doesn't remove number from inside stack |
| pushdupe | a | same as push but doesn't remove number from top of stack |
| nop | None | no operation, used for code clarity in if/else statements |
| hexmult | a, b | a * 16 + b (hexadecimal digit appending) |
| printhash | None | prints entire hashmap |

\* these number literals will be less space efficient in OwO form, so if your
number is representable by a single hex digit, that form is recommended.

##### CLI Usage

The python script `owo.py` is used for running owoScript bytecode or psuedocode, while the python
script `owoc.py` is the compiler/decompiler used to transform code from pseudocode or bytecode.

The script `bfowo.py` is used to convert brainfuck programs into owoscript. This conversion is moderately optimized,
but is still less efficient than really writing in owoscript would be.

A command line option can be used to specify whether you'd like the transpiler to "wrap" the brainfuck cells
(like an 8-bit unsigned int) or whether you'd like python-style ints.

See `sierpinski_bf.owop` and `mandelbrot_bf.owop` for examples of these conversions.

### Turing completeness
owoScript is provably Turing complete, via a simple reduction to brainfuck

```/*

Brainfuck equivalents for OwOScript

Stack is used to hold current pointer while hashmap is used for cells

*/

// > Move pointer right
literal 1;
add;

// < Move pointer left
literal 1;
sub;

// + Increment cell
dupe;
dupe;
get;
literal 1;
add;

/*
Mod 256 wrapping if desired
literal 1;
literal 0;
hexmult;
literal 0;
hexmult;
mod;
*/

store;

// - Decrement cell
dupe;
dupe;
get;
literal 1;
sub;

/*
Mod 256 wrapping if desired
literal 1;
literal 0;
hexmult;
literal 0;
hexmult;
mod;
*/

store;

// . Output char
dupe;
get;
print;

// , Input char
dupe;
input;
store;

// [ ] Begin and end while loop
dupe;
get;
while {
discard;
//statements
dupe;
get;
}
discard;
```

### Why

"The only reason someone would do something like this if they could, which they can't, would be because they could, which they can't." - Rick Sanchez

I'm sure the question everyone is thinking is "why." Why make a programming language entirely in OwO faces?
Why go out of my way to implement a formal grammar with a parser for a meme?

The simple answer, of course, is because
I hate myself. The more accurate answer is because I wanted to try out writing a basic interpreter and grammar in
ANTLR, in preparation for possibly writing an LLVM compiler for a few esoteric programming languages in the near future

### Credits
I dedicate this project to all of my friends who answer the phone with "hewwo" so often I want to bash my head in.

### Final Note
This project is mostly a joke I embarked on as a fun way of learning parsing and the basics of imperative language design. Any ridiculous statements inside this project are purely satire.