Metadata-Version: 2.4
Name: splang
Version: 1.0.6
Summary: An interpreter for Splang : an esoteric programming language written in a playlist.
Author-email: Naman Satish <naman.satish@gmail.com>
Maintainer-email: Naman Satish <naman.satish@gmail.com>
License-Expression: MIT
Project-URL: Homepage, https://satish.dev/projects/splang/
Project-URL: Documentation, https://satish.dev/projects/splang/
Project-URL: Repository, https://github.com/namansatish/splang
Keywords: playlist,interpreter,music,esoteric programming language,esolang,spotify
Classifier: Development Status :: 4 - Beta
Classifier: Programming Language :: Python :: 3.11
Classifier: Intended Audience :: Developers
Classifier: Topic :: Software Development :: Interpreters
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: spotipy>=2.25.1
Provides-Extra: dev
Requires-Dist: pytest>=7.4.0; extra == "dev"
Dynamic: license-file

![logo](https://satish.dev/assets/img/splang/logo.svg)
# splang

**splang** is an esoteric programming language written in the form of a playlist. Programs, or splangs, are playlists whose track metadata encode operations. Use the Splang interpreter to execute these playlists programmatically.

The most convenient way to run Splang code is by creating a Spotify playlist and using a developer token. Refer to the [Spotify API documentation](https://developer.spotify.com/documentation/web-api/) and [Spotipy API documentation](https://spotipy.readthedocs.io/en/latest/) for environment setup.


## 🛠️ Installation and Use

### 📦 Development Setup

Ensure Python **>=3.11+** is installed. It's recommended to use a virtual environment:

```bash
python3 -m venv .venv
source .venv/bin/activate
```

Install dependencies:

```bash
pip install --upgrade pip setuptools wheel
pip install -e ".[dev]"
```

This installs the project in editable mode along with development tools like `pytest`.

### 🚀 Installing Splang

To install Splang, run:

```bash
pip install splang
```

#### ▶️ Run with Spotify developer access:

```bash
splang
```

Ensure you have a valid Spotify developer token set up in your environment, i.e export `SPOTIPY_CLIENT_ID`, `SPOTIPY_CLIENT_SECRET`, and `SPOTIPY_REDIRECT_URI` as per the Spotipy documentation.

#### ▶️ Run with a local playlist file:

```bash
splang examples/helloworld.json
```

---

## 📜 Splang v1.0 Language Reference

<!-- Retain the full language reference table from your current README below this point -->

... *(Language Reference remains unchanged from your original content)* ...


Splang is an esoteric programming language written in the form of a playlist. The most convenient way to run Splang code is to create your splang in a Spotify playlist and using a developer token to run it. Please refer to the [Spotify API documentation](https://developer.spotify.com/documentation/web-api/) and [Spotipy API documentation](https://spotipy.readthedocs.io/en/latest/) for more information on how to set up your environment.

To build: 
```bash
pip install --upgrade pip setuptools wheel
pip install -e .
``` 

To run with Spotify developer access:
```bash
splang
```

To run with a local playlist:
```bash
python3 scripts/splang_dev.py examples/helloworld.json
```

# Splang v1.0 Language Reference

| **Keyterm** | **Description**                                                                       |
| ----------- | ------------------------------------------------------------------------------------- |
| LS          | Last Second's place, e.g 3:45 --> 5                                                   |
| FS          | First Second's place , e.g 3:45 --> 4                                                 |
| TrackID     | The unique ID of a song in Spotify's database.                                        |
| (song + n)  | The song n positions after the current song in the playlist.                          |
| Stack       | A LIFO data structure, operates on single elements.                                   |
| Heap        | A data structure that stores values at a specific index, operates on single elements. |
| RA Stack    | A LIFO data structure that stores return addresses for function calls.                |

| **Time** | **Command**       | **Parameter(s)** | **Description**                                                                                                                    |
| -------- | ----------------- | ---------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| 0:00     | `NOP`             | None             | No operation, does nothing.                                                                                                        |
| 0:01     | `HALT`            | None             | Halts the program.                                                                                                                 |
| 0:02     | `LABEL`           | 1                | Label, defines the (song + 1)'s trackID as a label.                                                                                |
| 0:03     | `JUMP`            | 1                | Jumps to the label defined by the (song + 1) trackID.                                                                              |
| 0:04     | `JUMPZ`           | 1                | Jumps to the label defined by the (song + 1) trackID if the top of the stack is 0.                                                 |
| 0:05     | `JUMPNZ`          | 1                | Jumps to the label defined by the (song + 1) trackID if the top of the stack is not 0.                                             |
| 0:06     | `JUMPZ_HEAP`      | 1                | Jumps to the label defined by the (song + 1) trackID if the value at the index defined by the (song + 1) trackID in heap is 0.     |
| 0:07     | `JUMPNZ_HEAP`     | 1                | Jumps to the label defined by the (song + 1) trackID if the value at the index defined by the (song + 1) trackID in heap is not 0. |
| 0:08     | `CALL`            | 1                | Pushes return address to RA stack and jumps to the label defined by the (song + 1) trackID.                                        |
| 0:09     | `RETURN`          | None             | Pops the return address from the RA stack and jumps to it.                                                                         |
| 0:10     | `ADD`             | None             | Adds the top two elements of the stack and pushes the result.                                                                      |
| 0:11     | `SUB`             | None             | Subtracts the top two elements of the stack and pushes the result.                                                                 |
| 0:12     | `MUL`             | None             | Multiplies the top two elements of the stack and pushes the result.                                                                |
| 0:13     | `DIV`             | None             | Divides the top two elements of the stack and pushes the result.                                                                   |
| 0:14     | `MOD`             | None             | Modulus of the top two elements of the stack (b mod a) and pushes the result.                                                      |
| 0:15     | `POW`             | None             | Raises the top element of the stack to the power of the second top element and pushes the result.                                  |
| 0:16     | `Not_implemented` | None             | Not implemented.                                                                                                                   |
| 0:17     | `Not_implemented` | None             | Not implemented.                                                                                                                   |
| 0:18     | `Not_implemented` | None             | Not implemented.                                                                                                                   |
| 0:19     | `Not_implemented` | None             | Not implemented.                                                                                                                   |
| 0:20     | `PUSH_LS`         | 1                | Pushes the LS of the (song + 1) duration to the stack.                                                                             |
| 0:21     | `PUSH_FS`         | 1                | Pushes the FS of the (song + 1) duration to the stack.                                                                             |
| 0:22     | `SHIFT_R_LS`      | 1                | Shifts the value of the top element of the stack to the right, adding the LS of the (song + 1)'s duration.                         |
| 0:23     | `SHIFT_L_LS`      | 1                | Shifts the value of the top element of the stack to the left, adding the LS of the (song + 1)'s duration.                          |
| 0:24     | `SHIFT_R_FS`      | 1                | Shifts the value of the top element of the stack to the right, adding the FS of the (song + 1)'s duration.                         |
| 0:25     | `SHIFT_L_FS`      | 1                | Shifts the value of the top element of the stack to the left, adding the FS of the (song + 1)'s duration.                          |
| 0:26     | `POP`             | None             | Pops the top element of the stack.                                                                                                 |
| 0:27     | `DUP`             | None             | Duplicates the top element of the stack.                                                                                           |
| 0:28     | `SWAP`            | None             | Swaps the top two elements of the stack.                                                                                           |
| 0:29     | `Not_implemented` | None             | Not implemented.                                                                                                                   |
| 0:30     | `STORE`           | 1                | Stores the top element of the stack in heap at the index defined by the (song + 1)'s trackID.                                      |
| 0:31     | `STORE_TOP`       | None             | Stores the top element of the stack in the heap at the index defined by the second element of the stack.                           |
| 0:32     | `LOAD`            | 1                | Loads the value at the index defined by the (song + 1)'s trackID from heap to the stack.                                           |
| 0:33     | `LOAD_TOP`        | None             | Loads the value at the index defined by the top element of the stack from heap to the stack.                                       |
| 0:34     | `INC_HEAP`        | 1                | Increments the value at the index defined by the (song + 1)'s trackID in heap.                                                     |
| 0:35     | `DEC_HEAP`        | 1                | Decrements the value at the index defined by the (song + 1)'s trackID in heap.                                                     |
| 0:36     | `INC`             | None             | Increments the top element of the stack.                                                                                           |
| 0:37     | `DEC`             | None             | Decrements the top element of the stack.                                                                                           |
| 0:38     | `Not_implemented` | None             | Not implemented.                                                                                                                   |
| 0:39     | `Not_implemented` | None             | Not implemented.                                                                                                                   |
| 0:40     | `STDIN_INT`       | None             | Reads an integer until a newline from stdin and pushes it to the stack.                                                            |
| 0:41     | `STDIN`           | None             | Reads a string until a newline from stdin and pushes each character to the stack as an ASCII value.                                |
| 0:42     | `STDOUT_INT`      | None             | Pops the top element of the stack and prints it to stdout as an integer.                                                           |
| 0:43     | `STDOUT`          | None             | Pops the top element of the stack and prints it to stdout as an ASCII character.                                                   |
| 0:44     | `READ_CHAR`       | 1                | Reads the first character of the (song + 1)'s title and pushes it to the stack as an ASCII value.                                  |
| 0:45     | `LISTEN`          | 1                | Sleeps for the full duration of the (song + 1).                                                                                    |
| 0:46     | `Not_implemented` | None             | Not implemented.                                                                                                                   |
| 0:47     | `Not_implemented` | None             | Not implemented.                                                                                                                   |
| 0:48     | `Not_implemented` | None             | Not implemented.                                                                                                                   |
| 0:49     | `Not_implemented` | None             | Not implemented.                                                                                                                   |
| 0:50     | `AND`             | None             | Logical AND of the top two elements of the stack and pushes the result.                                                            |
| 0:51     | `OR`              | None             | Logical OR of the top two elements of the stack and pushes the result.                                                             |
| 0:52     | `XOR`             | None             | Logical XOR of the top two elements of the stack and pushes the result.                                                            |
| 0:53     | `NOT`             | None             | Logical NOT of the top element of the stack and pushes the result.                                                                 |
| 0:54     | `EQUAL`           | None             | Checks if the top two elements of the stack are equal and pushes the result.                                                       |
| 0:55     | `NOT_EQUAL`       | None             | Checks if the top two elements of the stack are not equal and pushes the result.                                                   |
| 0:56     | `GREATER`         | None             | Checks if the top element of the stack is greater than the second top element and pushes the result.                               |
| 0:57     | `LESS`            | None             | Checks if the top element of the stack is less than the second top element and pushes the result.                                  |
| 0:58     | `GREATER_EQUAL`   | None             | Checks if the top element of the stack is greater than or equal to the second top element and pushes the result.                   |
| 0:59     | `LESS_EQUAL`      | None             | Checks if the top element of the stack is less than or equal to the second top element and pushes the result.                      |
