Compare commits
1 Commits
master
...
deprecated
Author | SHA1 | Date |
---|---|---|
Raymon Zutekouw | b866f744a0 | 3 years ago |
8 changed files with 310 additions and 80 deletions
@ -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. |
|
@ -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"); |
@ -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…
Reference in new issue