Compare commits

..

1 Commits

Author SHA1 Message Date
Raymon Zutekouw b866f744a0
Add used version for mblf compiler as binary 3 years ago
  1. 26
      .github/workflows/node.js.yml
  2. 21
      LICENSE
  3. 52
      README.md
  4. 226
      bin/mblf
  5. 13
      package-lock.json
  6. 27
      package.json
  7. 18
      patches/AllArged.diff
  8. 7
      test/wordFactList.js

@ -0,0 +1,26 @@
name: Node.js CI
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [10.x, 12.x, 14.x, 15.x]
steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- run: npm ci
- run: npm run build --if-present
- run: npm test

@ -1,21 +0,0 @@
MIT License
Copyright (c) 2022 Raymon Zutekouw
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

@ -1,52 +1,22 @@
So instead of making yet another quine, it would be cool to generate an already existing quine from something that doesn't look like it at all.
So what if it is encoded in seemingly random words, like the programming language [Shakespeare](https://esolangs.org/wiki/Shakespeare) or [Chef](https://esolangs.org/wiki/chef).
So instead of making yet another quine, which many already did before me, with greater conciseness then could be achieved in these few days,, it would be cool to spark new life into an already existing quine.
So let us take this quine:
Take this one for example:
https://www.linusakesson.net/programming/brainfuck/index.php
```bf
+[-<+]-ÿ<<<<<<<[.>]
```
By the syntax, which is Brainfuck-syntax, it is obscure but clear it is encoding something.
What if it could be encoded more like the programming language [Shakespeare](https://esolangs.org/wiki/Shakespeare) or [Chef](https://esolangs.org/wiki/chef).
This would allow other humans *cough* interpreters to see it as something not out of the ordinary.
So the original development for the higher-level-quine went like this:
So:
- create a file that secretly compiles (almost completely) into the Brainfuck quine.
- in a language younger than two weeks to **ensure** nobody made this earlier.
- and propose features that improve both the language and help you with this ridiculous idea
- like variable-names of any size and composed of any\* characters which is kinda cool for any programming language to have
- then realize no editor has syntax highlighting for this language
- make that first yourself for a IDE you have not touched for years, yay first atom package published to apm!!!
- realize the rabbit hole has been entered...
So that is what this project is: a source-file containing what seems some oddly but still acceptable formatted text that compiles to the quine.
# How to run
Run `build.sh` with the mblf compiler installed.
The mblf compiler needs to be installed from [source](https://github.com/MBLF-Project/mblf/releases/tag/v0.1.0), as it needs the **AllArged patch**.
## Installing mblf from source with AllArged patch
```sh
git clone https://github.com/MBLF-Project/quine-stuff.git
git clone https://github.com/MBLF-Project/mblf.git
- like variable-names of any size and composed of any* characters which is kinda cool for any programming langugage to have
- then realise no editor has syntax highlighting for this language
- make that first yourself for a IDE you have not touched for years, yay first atom package published to apm!!!
- realise the rabbit hole has been entered...
cp quine-stuff/patches/AllArged.diff mblf/
cd mblf
git checkout tags/v0.1.0
git apply AllArged.diff
rm AllArged.diff
cargo install --path .
```
## Generate quine
```sh
cd ../quine-stuff
./build.sh
```
So that is what this project is: a sourcefile containing what seems some oddly but still acceptable formatted text that compiles to the quine.
If all steps went correctly, you should have the file quine.bf, which was generated from the wordFactList.mblf

@ -0,0 +1,226 @@
#!/usr/bin/env node
console.time("Compiled in");
const fs = require("fs");
const args = process.argv.slice(2, process.argv.length);
if (!args[0] && args[0] !== 0) {
console.error("Usage: mblf <input file> <output file>");
process.exit(1);
} else if (!args[1] && args[1] !== 0) {
console.error("Error: Please provide an output path.");
process.exit(1);
}
function parseNum(number) {
if (typeof number == "string") {
if (number.startsWith("0x")) {
return parseInt(number.slice(2, number.length), 16);
} else if (number.startsWith("\"") && number.endsWith("\"")) {
return number.charCodeAt(1);
} else {
return parseInt(number);
}
} else {
return number;
}
}
let bfOutput = [];
let variables = [];
let ptr = 0;
let prevPtr = 0;
function instruct(instruction, arg) {
let pointedVariable;
let number;
switch (instruction) {
case "var":
if (variables.indexOf(arg) != -1) {
return `${arg} already exists.`;
}
let emptyAddress = 0;
while (!(variables[emptyAddress] === undefined)) {
emptyAddress++;
}
variables[emptyAddress] = arg;
break;
case "delvar":
delete variables[variables.indexOf(arg)];
break;
case "point":
if (bfOutput[bfOutput.length-1] !== undefined &&
(bfOutput[bfOutput.length-1].endsWith("<") ||
bfOutput[bfOutput.length-1].endsWith(">"))) {
bfOutput.pop();
ptr = prevPtr;
}
let variable = variables.indexOf(arg);
if (variable == -1) {
return `${arg} is not a variable.`;
}
let distance = variable - ptr;
prevPtr = ptr;
if (distance > 0) {
bfOutput.push(">".repeat(distance));
} else if (distance < 0) {
bfOutput.push("<".repeat(-distance));
}
ptr = variable;
break;
case "pointm":
bfOutput.push("<+[-<+]-"); // thank you mixtela
ptr = variables.indexOf(arg);
break;
case "add":
number = parseNum(arg);
if (Number.isNaN(number)) {
return "Failed to parse number.";
}
bfOutput.push("+".repeat(number));
break;
case "addb":
number = parseNum(arg);
if (Number.isNaN(number)) {
return "Failed to parse number.";
}
pointedVariable = variables[ptr];
instruct("var", "__temp");
instruct("point", "__temp");
instruct("add", Math.floor(number / 16));
bfOutput.push("[");
instruct("sub", "1");
instruct("point", pointedVariable);
instruct("add", "16");
instruct("point", "__temp");
bfOutput.push("]");
instruct("point", pointedVariable);
instruct("add", number - Math.floor(number / 16) * 16);
instruct("delvar", "__temp");
break;
case "addv":
pointedVariable = variables[ptr];
bfOutput.push("[");
instruct("sub", "1");
instruct("point", arg);
instruct("add", "1");
instruct("point", pointedVariable);
bfOutput.push("]");
break;
case "sub":
number = parseNum(arg);
if (Number.isNaN(number)) {
return "Failed to parse number.";
}
bfOutput.push("-".repeat(number));
break;
case "subb":
number = parseNum(arg);
if (Number.isNaN(number)) {
return "Failed to parse number.";
}
pointedVariable = variables[ptr];
instruct("var", "__temp");
instruct("point", "__temp");
instruct("add", Math.floor(number / 10));
bfOutput.push("[");
instruct("sub", "1");
instruct("point", pointedVariable);
instruct("sub", "10");
instruct("point", "__temp");
bfOutput.push("]");
instruct("point", pointedVariable);
instruct("sub", number - Math.floor(number / 10) * 10);
instruct("delvar", "__temp");
break;
case "subv":
pointedVariable = variables[ptr];
bfOutput.push("[");
instruct("sub", "1");
instruct("point", arg);
instruct("sub", "1");
instruct("point", pointedVariable);
bfOutput.push("]");
break;
case "copy":
pointedVariable = variables[ptr];
instruct("var", "__temp");
bfOutput.push("[");
instruct("sub", "1");
instruct("point", arg);
instruct("add", "1");
instruct("point", "__temp");
instruct("add", "1");
instruct("point", pointedVariable);
bfOutput.push("]");
instruct("point", "__temp");
bfOutput.push("[");
instruct("sub", "1");
instruct("point", pointedVariable);
instruct("add", "1");
instruct("point", "__temp");
bfOutput.push("]");
instruct("delvar", "__temp");
break;
case "setz":
bfOutput.push("[-]");
break;
case "getchr":
bfOutput.push(",");
break;
case "print":
bfOutput.push(".");
break;
case "[":
bfOutput.push("[");
break;
case "]":
bfOutput.push("]");
break;
default:
if (instruction !== "") {
return `${instruction} is not an instruction.`
}
break;
}
}
function runMblf(inputFile) {
let file;
try {
file = fs.readFileSync(inputFile, "utf8")
} catch (e) {
console.error(`Error: ${e.message}`);
process.exit(1);
}
return file
.replace(/\r/gm, "")
.split("\n")
.forEach((item, line) => {
let statement = item.split(";;")[0].trim().split(" ");
if (statement[0] == "#include") {
try {
runMblf(item.split("\"")[1]);
} catch (e) {
if (e.name == "RangeError" && e.message == "Maximum call stack size exceeded") {
console.error(`[${inputFile}] Error in line ${line+1}: Call stack size exceeded. Check for cyclic dependencies.`);
process.exit(1);
} else {
throw e;
}
}
} else {
let instructAttempt = instruct(statement[0], statement.slice(1, statement.length).join(" "));
if (instructAttempt !== undefined) {
console.error(`[${inputFile}] Error in line ${line+1}: ${instructAttempt}`);
process.exit(1);
}
}
});
}
runMblf(args[0]);
fs.writeFileSync(args[1], bfOutput.join(""));
console.timeEnd("Compiled in");

13
package-lock.json generated

@ -0,0 +1,13 @@
{
"name": "BF",
"version": "1.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"mblf-lang": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/mblf-lang/-/mblf-lang-1.0.1.tgz",
"integrity": "sha512-pCyq6smnrfzQkZn1c+jlUuojc/Gs/R9MApPY8KqjFoPGhV6Bx+UdFQSWXReWBAkg7ipbetYSaCSq9aGj7PvU4g=="
}
}
}

@ -0,0 +1,27 @@
{
"name": "BF",
"version": "1.0.0",
"description": "So instead of making yet another quine, which many already did before me, with greater conciseness then could be achieved in these few days,, it would be cool to spark new life into an already existing quine.",
"main": "index.js",
"directories": {
"test": "test"
},
"scripts": {
"build": "./build.sh",
"test": "node test/wordFactList.js"
},
"repository": {
"type": "git",
"url": "git+https://github.com/MBLF-Project/Quine-stuff.git"
},
"keywords": [],
"author": "",
"license": "ISC",
"bugs": {
"url": "https://github.com/MBLF-Project/Quine-stuff/issues"
},
"homepage": "https://github.com/MBLF-Project/Quine-stuff#readme",
"dependencies": {
"mblf-lang": "^1.0.1"
}
}

@ -1,18 +0,0 @@
diff --git a/src/grammars/mblf.pest b/src/grammars/mblf.pest
index 07b9ed1..425ea76 100644
--- a/src/grammars/mblf.pest
+++ b/src/grammars/mblf.pest
@@ -28,10 +28,10 @@ subb =@{ "subb" ~ spacing+ ~ constant }
subv =@{ "subv" ~ spacing+ ~ variable }
copy =@{ "copy" ~ spacing+ ~ variable }
-setz =@{ "setz" }
+setz =@{ "setz" ~ spacing+ ~ variable }
-getchr =@{ "getchr" }
-print =@{ "print" }
+getchr =@{ "getchr" ~ spacing+ ~ variable }
+print =@{ "print" ~ spacing+ ~ variable }
macaroo =_{ include }
instruction =_{ macaroo

@ -0,0 +1,7 @@
#!/usr/bin/env node
const assert = require('assert')
const fs = require('fs')
fs.readFile("quine.bf", (_, output) => {
assert.equal(output, "<+[-<+]-ÿ<<<<<<<[.>]")
})
Loading…
Cancel
Save