{"id":28695884,"url":"https://github.com/jserv/muxleq","last_synced_at":"2025-06-14T09:08:47.924Z","repository":{"id":265815258,"uuid":"859748287","full_name":"jserv/muxleq","owner":"jserv","description":"16-bit virtual machine with a two-instruction set CPU capable of running Forth","archived":false,"fork":false,"pushed_at":"2025-06-04T13:30:34.000Z","size":232,"stargazers_count":7,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-08T07:07:47.213Z","etag":null,"topics":["eforth","esoteric-compiler","forth","meta-compiler","subleq"],"latest_commit_sha":null,"homepage":"","language":"Forth","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"unlicense","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jserv.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-09-19T08:02:33.000Z","updated_at":"2025-06-04T13:30:35.000Z","dependencies_parsed_at":"2024-12-02T00:33:56.968Z","dependency_job_id":null,"html_url":"https://github.com/jserv/muxleq","commit_stats":null,"previous_names":["jserv/muxleq"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/jserv/muxleq","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jserv%2Fmuxleq","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jserv%2Fmuxleq/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jserv%2Fmuxleq/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jserv%2Fmuxleq/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jserv","download_url":"https://codeload.github.com/jserv/muxleq/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jserv%2Fmuxleq/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259790455,"owners_count":22911548,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["eforth","esoteric-compiler","forth","meta-compiler","subleq"],"created_at":"2025-06-14T09:08:39.311Z","updated_at":"2025-06-14T09:08:47.908Z","avatar_url":"https://github.com/jserv.png","language":"Forth","funding_links":[],"categories":[],"sub_categories":[],"readme":"# MUXLEQ\n\n```\n       ______         _   _\n       |  ____|       | | | |\n  ___  | |__ ___  _ __| |_| |__\n / _ \\ |  __/ _ \\| '__| __| '_ \\\n|  __/ | | | (_) | |  | |_| | | |\n \\___| |_|  \\___/|_|   \\__|_| |_|\n _____ ______   ___  ___     ___    ___ ___       _______   ________\n|\\   _ \\  _   \\|\\  \\|\\  \\   |\\  \\  /  /|\\  \\     |\\  ___ \\ |\\   __  \\\n\\ \\  \\\\\\__\\ \\  \\ \\  \\\\\\  \\  \\ \\  \\/  / \\ \\  \\    \\ \\   __/|\\ \\  \\|\\  \\\n \\ \\  \\\\|__| \\  \\ \\  \\\\\\  \\  \\ \\    / / \\ \\  \\    \\ \\  \\_|/_\\ \\  \\\\\\  \\\n  \\ \\  \\    \\ \\  \\ \\  \\\\\\  \\  /     \\/   \\ \\  \\____\\ \\  \\_|\\ \\ \\  \\\\\\  \\\n   \\ \\__\\    \\ \\__\\ \\_______\\/  /\\   \\    \\ \\_______\\ \\_______\\ \\_____  \\\n    \\|__|     \\|__|\\|_______/__/ /\\ __\\    \\|_______|\\|_______|\\|___| \\__\\\n                            |__|/ \\|__|                              \\|__|\n```\n\n## Introduction\nThis project encompasses an assembler for a [SUBLEQ](https://esolangs.org/wiki/Subleq)\nCPU variant called MUXLEQ, a virtual machine built upon that assembler capable\nof running [Forth](https://www.forth.com/forth/), and a cross-compiler designed\nto target the Forth VM, based on the eForth family of the Forth programming\nlanguage. The system is self-hosted, allowing users to create new and modified\nsystems seamlessly.\n\nSUBLEQ is an esoteric and impractical single-instruction CPU, yet it achieves\nTuring-completeness, demonstrating that even with such a limited instruction set,\nit can perform any computable task given sufficient memory and time. Porting\na Forth implementation to SUBLEQ serves as a testament to its versatility —- if\nyou can adapt Forth to run on SUBLEQ, you can port it to virtually any platform.\nThere is a saying about Forth: \"Forth is Sudoku for programmers.\" This aptly\ncaptures an intricate and satisfying relationship with the language and the\nproject, serving as an experimental platform for demonstrating execution of\nhigh-level programming languages with minimal effort.\n\n## Build and Run\nThis setup requires the installation of a C compiler, [Gforth](https://gforth.org/),\nand GNU Make.\n* macOS: `brew install gforth`\n* Ubuntu Linux / Debian: `sudo apt-get install gforth build-essential`\n\nTo run eForth on MUXLEQ, simply type:\n```shell\n$ make run\n```\n\nBelow is an example session demonstrating basic usage:\n```\nwords\n21 21 + . cr\n: hello .\" Hello, World!\" cr ;\nhello\nbye\n```\n\nThis allows you to operate eForth within the system. For a list of available\ncommands, enter `words` and press Enter. In Forth, the term \"word\" refers to\na function. It is called a \"word\" because Forth functions are typically named\nusing space-delimited characters, often forming a single, descriptive term.\nWords are organized into vocabularies, which collectively make up the dictionary\nin Forth. Numbers are input in Reverse Polish Notation (RPN); for instance,\ninputting:\n```\n2 2 + . cr\n```\n\nwill display `4`.\n\nTo define a new function, use the following format:\n```\n: hello cr .\" Hello, World!\" ;\n```\n\nRemember that spaces are critical in eForth syntax. After defining a function,\nsimply type `hello` to execute it.\n\nThe system is self-hosting, meaning it can generate new eForth images using\nthe current eForth image and source code. While Gforth is used to compile the\nimage from `muxleq.fth`, the Forth system's self-hosting capability also allows\nfor building new images after modifying any Forth source files. To initiate\nself-hosting and validation, run `make bootstrap`.\n\n## MUXLEQ\nThe MUXLEQ architecture is an enhancement of the classic SUBLEQ\n[one-instruction set computer](https://en.wikipedia.org/wiki/One-instruction_set_computer) (OISC),\noffering an additional instruction that improves performance and reduces program\nsize. The MUXLEQ system retains simplicity, making it nearly as straightforward\nto implement in hardware as SUBLEQ. Existing SUBLEQ programs typically run on\nMUXLEQ without alterations.\n\nBelow is the pseudo code for the MUXLEQ variant:\n```python\nwhile pc \u003e= 0:\n    a = m[pc + 0]\n    b = m[pc + 1]\n    c = m[pc + 2]\n    pc += 3\n    if a == -1:\n        m[b] = get_byte()  # Input a byte to memory at address b\n    elif b == -1:\n        put_byte(m[a])     # Output the byte stored at memory address a\n    elif c != -1 and c \u003c 0:\n        m[b] = (m[a] \u0026 ~m[c]) | (m[b] \u0026 m[c])  # Multiplex operation\n    else:\n        r = m[b] - m[a]   # SUBLEQ subtraction\n        if r \u003c= 0:\n            pc = c        # Branch if the result is less than or equal to zero\n        m[b] = r\n```\n\nRemoving the `elif c != -1 and c \u003c 0:` clause effectively reverts MUXLEQ to a\ntypical SUBLEQ machine, as this conditional handles the multiplexing logic unique\nto MUXLEQ.\n\nSUBLEQ machines belong to a class called OISC, which uses a single instruction\nto perform any computable task, albeit inefficiently. SUBLEQ originated from the\n\"URISC\" concept introduced in the 1988 paper\n[URISC: The Ultimate Reduced Instruction Set Computer](https://web.ece.ucsb.edu/~parhami/pubs_folder/parh88-ijeee-ultimate-risc.pdf).\nThe intent was to provide a simple platform for computer engineering students to\ndesign their own instruction sets and microcode. SUBLEQ falls under arithmetic-based\nOISCs, in contrast to other types like bit-manipulation or Transport Triggered\nArchitectures (MOVE-based). Despite its simplicity, SUBLEQ could be made more\nefficient with the addition of just one extra instruction, such as NAND or a\nRight Shift.\n\nA single SUBLEQ instruction is structured as follows:\n```\nSUBLEQ a, b, c\n```\n\nSince SUBLEQ is the only available instruction, it is often abbreviated simply\nas:\n```\na b c\n```\n\nThe three operands `a`, `b`, and `c` are stored in three consecutive memory\nlocations. Each operand represents an address in memory. The SUBLEQ instruction\nperforms the following operations in pseudo-code:\n```python\n    r = m[b] - m[a]\n    if r \u003c= 0:\n        pc = c\n    m[b] = r\n```\n\nThere are three notable exceptions to the standard operation:\n1. Halting Execution: If the address `c` is negative or refers to an invalid\n   memory location outside the addressable range, the program halts.\n2. Input Operation: If the address `a` is `-1`, a byte is read from the input\n   and stored at address `b`.\n3. Output Operation: If the address `b` is negative, a byte from address `a` is\n   sent to the output.\n\nThe SUBLEQ specification does not dictate how numbers are represented. Key\nconsiderations include:\n- Bit Length: Numbers can be 8-bit, 16-bit, 32-bit, 64-bit, or even arbitrary\n  precision.\n- Negative Numbers: Typically implemented using two's complement, but other\n  methods like sign-magnitude can also be used.\n\nThe simplicity of the MUXLEQ design allows for further optimizations by packing\nadditional functionality into the instruction set.\nSome possible variants include:\n* Bit Reversal: The multiplexed value could have its bits reversed during the\n  operation. This functionality could be integrated into the `mux` instruction,\n  allowing for efficient bit manipulation.\n* Right Shift: Incorporating a right shift operation, even by just one position,\n  would significantly enhance the arithmetic capabilities of the system.\n* Comparison, the result of comparing `m[a]` and `m[b]` could be stored in\n  `m[a]`, useful comparisons would be `is zero?`, signed or unsigned less than\n  or greater than. Any of those five would be useful.\n* The paper \"[Subleq: An Area-Efficient Two-Instruction-Set Computer](https://janders.eecg.utoronto.ca/pdfs/esl.pdf)\"\n  introduces bit-reversal to enhance hardware efficiency. When the c operand is\n  negative, the operation `r = reverse(reverse(m[b]) - reverse(m[a]))` is\n  performed, where `reverse` flips the bits of a value. This modification turns\n  the \"less than or equal to zero\" branch into a branch on evenness, allowing\n  an efficient right shift with minimal additional hardware resources.\n\nAlthough the current MUXLEQ variant already demonstrates considerable\nimprovements over SUBLEQ, there are a few missing features, such as the\n\"self-interpreter\" feature found in some extended SUBLEQ variants. With further\neffort, additional performance gains and capabilities could be implemented,\nfurther closing the gap between minimalistic architecture and more conventional\ndesigns.\n\n## eForth\nThe image is a variant of Forth known as \"eForth.\" This implementation of eForth\ndiffers from standard ANS Forth implementations, notably lacking constructs like\nthe \"do...loop\" and its variants. The concept behind eForth was to develop a\nsystem that required only a small set of primitives, around 30, written in\nassembly to create a highly portable and reasonably efficient Forth. Bill\nMuench originally developed eForth, with later enhancements made by Dr.\nChen-Hanson Ting.\n\n`muxleq.fth` functions as both a cross-compiler and an eForth interpreter,\nspecifically designed for MUXLEQ. Written entirely in Forth, `muxleq.fth` has\nbeen verified for compatibility with Gforth and can also be executed using\na pre-generated eForth image running on a MUXLEQ machine.\n\nThe cross-compilation process functions as\noutlined below:\n1. Assembler: A specialized assembler for the MUXLEQ architecture enables\n   low-level machine code generation tailored to the instruction set.\n2. Virtual machine: Leveraging the MUXLEQ assembler, a virtual machine is\n   constructed. This VM is capable of supporting higher-level programming\n   constructs, facilitating the seamless execution of Forth code within the\n   MUXLEQ environment.\n3. Forth word definitions: These definitions are instrumental in building\n   a full-fledged Forth interpreter, allowing for the creation, compilation,\n   and execution of Forth programs.\n4. Forth image: The finalized Forth image, encapsulating the interpreter and\n   its environment, is output to the standard output stream. This image\n   initializes the VM with the necessary configurations and word definitions to\n   operate effectively.\n\n\"Meta-compilation\" in Forth refers to a process similar to cross-compilation,\nthough the term carries a distinct meaning in the Forth community compared to\nits use in broader computer science. This difference stems from Forth's\nevolution within the microcomputer scene, which was separate from the academic\nenvironment of the 1980s and earlier. The term \"meta-compilation\" may have been\nsomewhat mistranslated. While most modern programs employ unit testing\nframeworks, here, a meta-compilation system serves as an extensive testing\nmechanism. If the system compiles image \"A,\" which can then compile another\nimage \"B,\" and \"B\" matches \"A\" byte-for-byte, this gives reasonable confidence\nthat the image is correct, or at least correct enough for self-compilation.\n\nThis process is performed with the following commands:\n```shell\n$ gforth muxleq.fth \u003e stage0.dec\n$ sed 's/$/,/' stage0.dec \u003e stage0.c\n$ cc -o muxleq muxleq.c\n$ ./muxleq \u003c muxleq.fth \u003e stage1.dec\n$ diff -w stage0.dec stage1.dec\n```\n\nThe `stage0.dec` image was initially generated using Gforth to create the first\nfunctional eForth for the MUXLEQ machine. Once the eForth image is ready, it\nserves as the meta-compiler, capable of compiling itself and generating\n`stage1.dec`. The image generated by Gforth should be identical to the one\nproduced by MUXLEQ eForth when using the same `muxleq.fth` file. If the two\nimages are identical, the bootstrapping process is considered complete. Although\nthe Gforth interpreter is no longer required, it is retained because it is\nsignificantly faster than using MUXLEQ eForth to compile a new image.\n\nIt is noteworthy that approximately half of the memory allocated is dedicated to\nthe virtual machine, which facilitates the writing and execution of Forth code.\nThe `BLOCK` word-set within this implementation does not interact directly with\nmass storage. Instead, it maps blocks to memory, enabling efficient memory\nmanagement and access.\n\n## License\nThis package is released under the Public Domain and was initially written\nby [Richard James Howe](https://github.com/howerj).\n\n## Reference\n* [SUBLEQ EFORTH: Forth Metacompilation for a SUBLEQ Machine](https://www.amazon.com/dp/B0B5VZWXPL)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjserv%2Fmuxleq","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjserv%2Fmuxleq","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjserv%2Fmuxleq/lists"}