mirror of
https://github.com/osmarks/random-stuff
synced 2025-09-10 06:16:00 +00:00
initial commit v2
This commit is contained in:
17
esolangs-interpreter-race/hello.ms
Normal file
17
esolangs-interpreter-race/hello.ms
Normal file
@@ -0,0 +1,17 @@
|
||||
_mulloop := (pop warp new new new new new new new new new new warp _mulloop)
|
||||
10* := warp new enter warp _mulloop exit pop warp exit send warp enter
|
||||
[ := new enter
|
||||
0 := 10*
|
||||
1 := 10* new
|
||||
2 := 10* new new
|
||||
3 := 10* new new new
|
||||
4 := 10* new new new new
|
||||
5 := 10* new new new new new
|
||||
6 := 10* new new new new new new
|
||||
7 := 10* new new new new new new new
|
||||
8 := 10* new new new new new new new new
|
||||
9 := 10* new new new new new new new new new
|
||||
] := exit
|
||||
. := ] write [
|
||||
|
||||
main := [ 7 2 . 1 0 1 . 1 0 8 . 1 0 8 . 1 1 1 . 4 4 . 3 2 . 1 1 9 . 1 1 1 . 1 1 4 . 1 0 8 . 1 0 0 . 3 3 . 1 0 . ]
|
178
esolangs-interpreter-race/orig.js
Normal file
178
esolangs-interpreter-race/orig.js
Normal file
@@ -0,0 +1,178 @@
|
||||
const { regex, sequenceOf, char, choice, many1, many, str, coroutine, possibly } = require("arcsecond")
|
||||
const readline = require("readline-sync")
|
||||
|
||||
const spaces = regex(/^ */)
|
||||
const whitespace = regex(/^[ \n\t]*/)
|
||||
const name = regex(/^[^ \n\t():]+/)
|
||||
const code = many(coroutine(function*() {
|
||||
yield spaces
|
||||
return yield choice([
|
||||
coroutine(function*() {
|
||||
yield char("(")
|
||||
const x = yield code
|
||||
yield spaces
|
||||
yield char(")")
|
||||
return x
|
||||
}),
|
||||
name
|
||||
])
|
||||
}))
|
||||
const program = sequenceOf([
|
||||
many1(coroutine(function*() {
|
||||
yield whitespace
|
||||
const n = yield name
|
||||
yield whitespace
|
||||
yield str(":=")
|
||||
const c = yield code
|
||||
return { code: c, name: n }
|
||||
})),
|
||||
possibly(whitespace)
|
||||
]).map(([x, _]) => x)
|
||||
|
||||
const parsed = program.run(`_mulloop := (pop warp new new new new new new new new new new warp _mulloop)
|
||||
10* := warp new enter warp _mulloop exit pop warp exit send warp enter
|
||||
[ := new enter
|
||||
0 := 10*
|
||||
1 := 10* new
|
||||
2 := 10* new new
|
||||
3 := 10* new new new
|
||||
4 := 10* new new new new
|
||||
5 := 10* new new new new new
|
||||
6 := 10* new new new new new new
|
||||
7 := 10* new new new new new new new
|
||||
8 := 10* new new new new new new new new
|
||||
9 := 10* new new new new new new new new new
|
||||
] := exit
|
||||
. := ] write [
|
||||
|
||||
main := [ 7 2 . 1 0 1 . 1 0 8 . 1 0 8 . 1 1 1 . 4 4 . 3 2 . 1 1 9 . 1 1 1 . 1 1 4 . 1 0 8 . 1 0 0 . 3 3 . 1 0 . ]
|
||||
`).result
|
||||
//const parsed = program.run(`main := read write main`).result
|
||||
|
||||
// ---------
|
||||
|
||||
let stackL = {depth: 0, children: []}, stackR = {depth: 0, children: []};
|
||||
let currentIsLeft = true;
|
||||
|
||||
function depthDelta(x) {
|
||||
if(currentIsLeft)
|
||||
stackL["depth"]+=x;
|
||||
else
|
||||
stackR["depth"]+=x;
|
||||
}
|
||||
|
||||
function currentStack() {
|
||||
let depth, currentStack;
|
||||
|
||||
if(currentIsLeft) {
|
||||
depth = stackL["depth"];
|
||||
currentStack = stackL["children"];
|
||||
} else {
|
||||
depth = stackR["depth"];
|
||||
currentStack = stackR["children"];
|
||||
}
|
||||
|
||||
for(let i = 0; i < depth; i++) {
|
||||
const s = currentStack.length - 1
|
||||
currentStack = currentStack[s];
|
||||
}
|
||||
|
||||
return currentStack;
|
||||
}
|
||||
|
||||
// ---------
|
||||
|
||||
function wrap_new() {
|
||||
currentStack().push([]);
|
||||
}
|
||||
|
||||
function wrap_pop() {
|
||||
currentStack().pop();
|
||||
}
|
||||
|
||||
function wrap_enter() {
|
||||
depthDelta(1)
|
||||
}
|
||||
|
||||
function wrap_exit() {
|
||||
depthDelta(-1)
|
||||
}
|
||||
|
||||
function wrap_warp() {
|
||||
currentIsLeft = !currentIsLeft;
|
||||
}
|
||||
|
||||
function wrap_send() {
|
||||
let toMove = currentStack().pop();
|
||||
|
||||
wrap_warp();
|
||||
|
||||
currentStack().push(toMove);
|
||||
|
||||
wrap_warp()
|
||||
}
|
||||
|
||||
function wrap_read(n) {
|
||||
let thisStack = [];
|
||||
|
||||
for(let i = 0; i < n; i++) {
|
||||
thisStack.push([]);
|
||||
}
|
||||
|
||||
currentStack().push(thisStack);
|
||||
}
|
||||
|
||||
function wrap_write() {
|
||||
return currentStack().pop().length;
|
||||
}
|
||||
|
||||
// ---------
|
||||
|
||||
const env = {
|
||||
warp: wrap_warp,
|
||||
read: () => {
|
||||
wrap_read(readline.question("input char: ").codePointAt(0))
|
||||
},
|
||||
write: () => {
|
||||
console.log("output char:", String.fromCodePoint(wrap_write()))
|
||||
},
|
||||
send: wrap_send,
|
||||
exit: wrap_exit,
|
||||
enter: wrap_enter,
|
||||
pop: wrap_pop,
|
||||
new: wrap_new,
|
||||
}
|
||||
|
||||
for (const def of parsed) {
|
||||
env[def.name] = def.code
|
||||
}
|
||||
|
||||
const DEBUG = false
|
||||
|
||||
const execute = code => {
|
||||
for (const fn of code) {
|
||||
//console.log("stacks", stackL, stackR)
|
||||
// is bracketed, run if stack not empty
|
||||
if (Array.isArray(fn)) {
|
||||
if (currentStack().length !== 0) {
|
||||
if (DEBUG) console.log("brackets", fn)
|
||||
execute(fn)
|
||||
}
|
||||
// is a regular function call or whatever, run it
|
||||
} else {
|
||||
const v = env[fn]
|
||||
if (!v) {
|
||||
throw new Error(fn + " is undefined")
|
||||
}
|
||||
if (typeof v === "function") {
|
||||
if (DEBUG) console.log("builtin", fn)
|
||||
v()
|
||||
} else {
|
||||
if (DEBUG) console.log("normal", fn)
|
||||
execute(v)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
execute(env.main)
|
16
esolangs-interpreter-race/package-lock.json
generated
Normal file
16
esolangs-interpreter-race/package-lock.json
generated
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"requires": true,
|
||||
"lockfileVersion": 1,
|
||||
"dependencies": {
|
||||
"arcsecond": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/arcsecond/-/arcsecond-2.0.4.tgz",
|
||||
"integrity": "sha512-7ZJLP7dlS4Qs6eccHQDGZIDGutTjVmpU3GawAHNcBiX3xo3kRC1y5KLlJSU/XIk24ahgmpsWSYVcElW239WDVQ=="
|
||||
},
|
||||
"readline-sync": {
|
||||
"version": "1.4.10",
|
||||
"resolved": "https://registry.npmjs.org/readline-sync/-/readline-sync-1.4.10.tgz",
|
||||
"integrity": "sha512-gNva8/6UAe8QYepIQH/jQ2qn91Qj0B9sYjMBBs3QOB8F2CXcKgLxQaJRP76sWVRQt+QU+8fAkCbCvjjMFu7Ycw=="
|
||||
}
|
||||
}
|
||||
}
|
189
esolangs-interpreter-race/thing.js
Normal file
189
esolangs-interpreter-race/thing.js
Normal file
@@ -0,0 +1,189 @@
|
||||
const { regex, sequenceOf, char, choice, many1, many, str, coroutine, possibly } = require("arcsecond")
|
||||
const fs = require("fs").promises
|
||||
|
||||
const spaces = regex(/^ */)
|
||||
const whitespace = regex(/^[ \n\t]*/)
|
||||
const name = regex(/^[^ \n\t():]+/)
|
||||
const code = many(coroutine(function*() {
|
||||
yield spaces
|
||||
return yield choice([
|
||||
coroutine(function*() {
|
||||
yield char("(")
|
||||
const x = yield code
|
||||
yield spaces
|
||||
yield char(")")
|
||||
return x
|
||||
}),
|
||||
name
|
||||
])
|
||||
}))
|
||||
const program = sequenceOf([
|
||||
many1(coroutine(function*() {
|
||||
yield whitespace
|
||||
const n = yield name
|
||||
yield whitespace
|
||||
yield str(":=")
|
||||
const c = yield code
|
||||
return { code: c, name: n }
|
||||
})),
|
||||
possibly(whitespace)
|
||||
]).map(([x, _]) => x)
|
||||
|
||||
// ---------
|
||||
|
||||
let stackL = {depth: 0, children: []}, stackR = {depth: 0, children: []};
|
||||
let currentIsLeft = true;
|
||||
|
||||
function depthDelta(x) {
|
||||
if(currentIsLeft)
|
||||
stackL["depth"]+=x;
|
||||
else
|
||||
stackR["depth"]+=x;
|
||||
}
|
||||
|
||||
function currentStack() {
|
||||
let depth, currentStack;
|
||||
|
||||
if(currentIsLeft) {
|
||||
depth = stackL["depth"];
|
||||
currentStack = stackL["children"];
|
||||
} else {
|
||||
depth = stackR["depth"];
|
||||
currentStack = stackR["children"];
|
||||
}
|
||||
|
||||
for(let i = 0; i < depth; i++) {
|
||||
const s = currentStack.length - 1
|
||||
currentStack = currentStack[s];
|
||||
}
|
||||
|
||||
return currentStack;
|
||||
}
|
||||
|
||||
// ---------
|
||||
|
||||
function wrap_new() {
|
||||
currentStack().push([]);
|
||||
}
|
||||
|
||||
function wrap_pop() {
|
||||
currentStack().pop();
|
||||
}
|
||||
|
||||
function wrap_enter() {
|
||||
depthDelta(1)
|
||||
}
|
||||
|
||||
function wrap_exit() {
|
||||
depthDelta(-1)
|
||||
}
|
||||
|
||||
function wrap_warp() {
|
||||
currentIsLeft = !currentIsLeft;
|
||||
}
|
||||
|
||||
function wrap_send() {
|
||||
let toMove = currentStack().pop();
|
||||
|
||||
wrap_warp();
|
||||
|
||||
currentStack().push(toMove);
|
||||
|
||||
wrap_warp()
|
||||
}
|
||||
|
||||
function wrap_read(n) {
|
||||
let thisStack = [];
|
||||
|
||||
for(let i = 0; i < n; i++) {
|
||||
thisStack.push([]);
|
||||
}
|
||||
|
||||
currentStack().push(thisStack);
|
||||
}
|
||||
|
||||
function wrap_write() {
|
||||
return currentStack().pop().length;
|
||||
}
|
||||
|
||||
// ---------
|
||||
|
||||
const stdin = process.stdin
|
||||
stdin.setRawMode(true)
|
||||
stdin.resume()
|
||||
let resolveNext = null
|
||||
stdin.on("data", key => {
|
||||
// ctrl+C and ctrl+D
|
||||
if (key[0] === 3 || key[0] === 4) {
|
||||
return process.exit()
|
||||
}
|
||||
if (resolveNext) { resolveNext(key[0]) }
|
||||
})
|
||||
stdin.on("end", () => process.exit())
|
||||
const awaitKeypress = () => new Promise((resolve, reject) => { resolveNext = resolve })
|
||||
|
||||
const DEBUG = false
|
||||
|
||||
const execute = async (code, env) => {
|
||||
let fn
|
||||
let queue = code
|
||||
while (fn = queue.shift()) {
|
||||
// is bracketed, run if stack not empty
|
||||
if (Array.isArray(fn)) {
|
||||
if (currentStack().length !== 0) {
|
||||
if (DEBUG) console.log("brackets", fn)
|
||||
queue = fn.concat(queue)
|
||||
}
|
||||
// is a regular function call or whatever, run it
|
||||
} else {
|
||||
const v = env[fn]
|
||||
if (!v) {
|
||||
throw new Error(fn + " is undefined")
|
||||
}
|
||||
if (typeof v === "function") {
|
||||
if (DEBUG) console.log("builtin", fn)
|
||||
await v()
|
||||
} else {
|
||||
if (DEBUG) console.log("normal", fn)
|
||||
queue = v.concat(queue)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const run = async () => {
|
||||
const code = await fs.readFile(process.argv[2], { encoding: "utf8" })
|
||||
const parseResult = program.run(code)
|
||||
if (parseResult.isError) {
|
||||
console.log(parseResult.error)
|
||||
process.exit(1)
|
||||
}
|
||||
const parsed = parseResult.result
|
||||
|
||||
const env = {
|
||||
warp: wrap_warp,
|
||||
read: async () => {
|
||||
wrap_read(await awaitKeypress())
|
||||
},
|
||||
write: () => {
|
||||
//console.log(wrap_write())
|
||||
process.stdout.write(Buffer.from([wrap_write()]))
|
||||
},
|
||||
send: wrap_send,
|
||||
exit: wrap_exit,
|
||||
enter: wrap_enter,
|
||||
pop: wrap_pop,
|
||||
new: wrap_new,
|
||||
}
|
||||
|
||||
for (const def of parsed) {
|
||||
env[def.name] = def.code
|
||||
}
|
||||
|
||||
await execute(env.main, env)
|
||||
}
|
||||
|
||||
const cleanup = () => {
|
||||
process.exit(0)
|
||||
}
|
||||
run().then(cleanup, cleanup)
|
186
esolangs-interpreter-race/v2.js
Normal file
186
esolangs-interpreter-race/v2.js
Normal file
@@ -0,0 +1,186 @@
|
||||
const { regex, sequenceOf, char, choice, many1, many, str, coroutine, possibly } = require("arcsecond")
|
||||
const fs = require("fs").promises
|
||||
|
||||
const spaces = regex(/^ */)
|
||||
const whitespace = regex(/^[ \n\t]*/)
|
||||
const name = regex(/^[^ \n\t():]+/)
|
||||
const code = many(coroutine(function*() {
|
||||
yield spaces
|
||||
return yield choice([
|
||||
coroutine(function*() {
|
||||
yield char("(")
|
||||
const x = yield code
|
||||
yield spaces
|
||||
yield char(")")
|
||||
return x
|
||||
}),
|
||||
name
|
||||
])
|
||||
}))
|
||||
const program = sequenceOf([
|
||||
many1(coroutine(function*() {
|
||||
yield whitespace
|
||||
const n = yield name
|
||||
yield whitespace
|
||||
yield str(":=")
|
||||
const c = yield code
|
||||
return { code: c, name: n }
|
||||
})),
|
||||
possibly(whitespace)
|
||||
]).map(([x, _]) => x)
|
||||
|
||||
// ---------
|
||||
|
||||
let stackL = {depth: 0, children: []}, stackR = {depth: 0, children: []};
|
||||
let currentIsLeft = true;
|
||||
|
||||
function depthDelta(x) {
|
||||
if(currentIsLeft)
|
||||
stackL["depth"]+=x;
|
||||
else
|
||||
stackR["depth"]+=x;
|
||||
}
|
||||
|
||||
function currentStack() {
|
||||
let depth, currentStack;
|
||||
|
||||
if(currentIsLeft) {
|
||||
depth = stackL["depth"];
|
||||
currentStack = stackL["children"];
|
||||
} else {
|
||||
depth = stackR["depth"];
|
||||
currentStack = stackR["children"];
|
||||
}
|
||||
|
||||
for(let i = 0; i < depth; i++) {
|
||||
const s = currentStack.length - 1
|
||||
currentStack = currentStack[s];
|
||||
}
|
||||
|
||||
return currentStack;
|
||||
}
|
||||
|
||||
// ---------
|
||||
|
||||
function wrap_new() {
|
||||
currentStack().push([]);
|
||||
}
|
||||
|
||||
function wrap_pop() {
|
||||
currentStack().pop();
|
||||
}
|
||||
|
||||
function wrap_enter() {
|
||||
depthDelta(1)
|
||||
}
|
||||
|
||||
function wrap_exit() {
|
||||
depthDelta(-1)
|
||||
}
|
||||
|
||||
function wrap_warp() {
|
||||
currentIsLeft = !currentIsLeft;
|
||||
}
|
||||
|
||||
function wrap_send() {
|
||||
let toMove = currentStack().pop();
|
||||
|
||||
wrap_warp();
|
||||
|
||||
currentStack().push(toMove);
|
||||
|
||||
wrap_warp()
|
||||
}
|
||||
|
||||
function wrap_read(n) {
|
||||
let thisStack = [];
|
||||
|
||||
for(let i = 0; i < n; i++) {
|
||||
thisStack.push([]);
|
||||
}
|
||||
|
||||
currentStack().push(thisStack);
|
||||
}
|
||||
|
||||
function wrap_write() {
|
||||
return currentStack().pop().length;
|
||||
}
|
||||
|
||||
// ---------
|
||||
|
||||
const stdin = process.stdin
|
||||
stdin.setRawMode(true)
|
||||
stdin.resume()
|
||||
let resolveNext = null
|
||||
stdin.on("data", key => {
|
||||
// ctrl+C and ctrl+D
|
||||
if (key[0] === 3 || key[0] === 4) {
|
||||
return process.exit()
|
||||
}
|
||||
if (resolveNext) { resolveNext(key[0]) }
|
||||
})
|
||||
const awaitKeypress = () => new Promise((resolve, reject) => { resolveNext = resolve })
|
||||
|
||||
const DEBUG = false
|
||||
|
||||
const execute = async (code, env) => {
|
||||
for (const fn of code) {
|
||||
//console.log("stacks", stackL, stackR)
|
||||
// is bracketed, run if stack not empty
|
||||
if (Array.isArray(fn)) {
|
||||
if (currentStack().length !== 0) {
|
||||
if (DEBUG) console.log("brackets", fn)
|
||||
await execute(fn, env)
|
||||
}
|
||||
// is a regular function call or whatever, run it
|
||||
} else {
|
||||
const v = env[fn]
|
||||
if (!v) {
|
||||
throw new Error(fn + " is undefined")
|
||||
}
|
||||
if (typeof v === "function") {
|
||||
if (DEBUG) console.log("builtin", fn)
|
||||
await v()
|
||||
} else {
|
||||
if (DEBUG) console.log("normal", fn)
|
||||
await execute(v, env)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const run = async () => {
|
||||
const code = await fs.readFile(process.argv[2], { encoding: "utf8" })
|
||||
const parseResult = program.run(code)
|
||||
if (parseResult.isError) {
|
||||
console.log(parseResult.error)
|
||||
process.exit(1)
|
||||
}
|
||||
const parsed = parseResult.result
|
||||
|
||||
const env = {
|
||||
warp: wrap_warp,
|
||||
read: async () => {
|
||||
wrap_read(await awaitKeypress())
|
||||
},
|
||||
write: () => {
|
||||
process.stdout.write(Buffer.from([wrap_write()]))
|
||||
},
|
||||
send: wrap_send,
|
||||
exit: wrap_exit,
|
||||
enter: wrap_enter,
|
||||
pop: wrap_pop,
|
||||
new: wrap_new,
|
||||
}
|
||||
|
||||
for (const def of parsed) {
|
||||
env[def.name] = def.code
|
||||
}
|
||||
|
||||
await execute(env.main, env)
|
||||
}
|
||||
|
||||
const cleanup = () => {
|
||||
process.exit(0)
|
||||
}
|
||||
run().then(cleanup, cleanup)
|
Reference in New Issue
Block a user