Compare commits

..

No commits in common. "735e80748872cadcf690e5a162f32a274f566aab" and "25f50b1100d9d00403349dd169a72c175c310249" have entirely different histories.

6 changed files with 55 additions and 148 deletions

View File

@ -1,13 +0,0 @@
Ludus CLI (v0.1.0)
The Ludus CLI has five modes: `help`, `version`, `run`, `listen`, and `send`.
* `help`: Output this text and exit.
* `version`: Ouput the current version number.
* `run`: Runs a Ludus script: `ludus run {script}`.
* `listen`: Starts a Ludus "listener" server, which receives Ludus source code on a given port and outputs the results. Similar to a REPL, intended to be used in conjunction with `send`, from a text editor.
* `send`: Sends text from `stdin` to a listening server. Any text editor that can send highlighted text to a command line program can evaluate Ludus source.

View File

@ -1,19 +0,0 @@
import { listen } from "./listener"
import { run_file } from "./runner"
import { send } from "./sender"
const help_text = await Bun.file("./help.txt").text()
export async function main() {
const cmd = Bun.argv[2]
switch (cmd) {
case "listen": { return listen() }
case "send": { return send() }
case "run": { return run_file(Bun.argv[3]) }
case "help": { return console.log(help_text) }
case "version": { return console.log("0.1.0") }
default: console.log("Usage: ludus {help | version | run | listen | send}")
}
}
await main()

View File

@ -1,73 +1,35 @@
import { run } from "@ludus/ludus-js-pure" import { run } from "@ludus/ludus-js-pure"
import { unlinkSync, readFileSync } from "node:fs"
export async function listen () { const port = Math.floor((Math.random() * 1000) + 50000)
const port = Math.floor((Math.random() * 1000) + 50000)
const session_token = crypto.randomUUID();
const repl_file_path = ".lrepl"
const repl_info = { port, session: session_token }
const repl_file = Bun.file(repl_file_path)
await Bun.write(repl_file, JSON.stringify(repl_info))
console.log(`Ludus REPL listening on localhost:${port}`) const repl_info = { port }
console.log(`Session token: ${session_token}`)
Bun.listen({ const repl_file = Bun.file("./.lrepl")
hostname: "localhost",
port, await Bun.write(repl_file, JSON.stringify(repl_info))
socket: {
data: (_, data) => { console.log(`Ludus REPL listening on localhost:${port}`)
const payload = data.toString("utf-8")
let session, source Bun.listen({
try { hostname: "localhost",
const json_msg = JSON.parse(payload) port,
session = json_msg.session socket: {
source = json_msg.source data: (socket, data) => {
} catch (e) { const source = data.toString("utf-8")
console.log("Received malformed message.") const result = run(source)
return const msgs = result.console
} for (const msg of msgs) {
if (session !== session_token) { console.log(msg)
console.log("Received message not from this REPL session.") }
return if (!result.errors) console.log(result.result)
} else {
const result = run(source) console.log("Ludus had some errors:")
if (!result.errors) console.log("=>", result.result) console.log(result.errors)
else { }
console.log("Ludus had some errors:") },
console.log(result.errors) error: (socket, error) => { console.log(error); socket.end() }
} }
}, })
error: (socket, error) => { console.log(error); socket.end() }
}
})
process.on("exit", async function () {
try { cleanup(repl_file_path, session_token) } catch (e) {}
console.log("\nGoodbye.")
})
process.on("SIGINT", () => process.exit())
// Below here, I'm trying to get ctrl-d to work to close the listener
// the while (true) loop locks the listener
// see: https://github.com/oven-sh/bun/issues/3255
// this should be doable with process.stdin.on("close"...)
//const mystdin = Bun.file("/dev/stdin").stream().getReader()
// while (true) {
// const {done, value} = await mystdin.read()
// if (done) process.exit()
// console.log(value)
// }
}
// Don't delete an .lrepl we don't own
function cleanup (path: string, session_token: string) {
const repl_file = readFileSync(path).toString("utf-8")
const {session} = JSON.parse(repl_file)
if (session === session_token) unlinkSync(path)
}

View File

@ -1,11 +1,7 @@
{ {
"name": "@ludus/cli", "name": "ludus-repl",
"version": "0.1.0",
"description": "A CLI interface to Ludus.",
"main": "index.ts",
"module": "index.ts", "module": "index.ts",
"type": "module", "type": "module",
"license": "GPL-3.0",
"devDependencies": { "devDependencies": {
"@types/bun": "latest" "@types/bun": "latest"
}, },

View File

@ -1,20 +1,13 @@
import { run } from "@ludus/ludus-js-pure" import {run} from "@ludus/ludus-js-pure"
export async function run_file (path: string): Promise<void> { const script = Bun.argv[2]
const handle = Bun.file(path) const file = Bun.file(script)
const file_exists = await handle.exists() const source = await file.text()
if (!file_exists) { console.log(`Source to run:
console.log(`File not found: ${path}`) ${source}`)
return
} const result = run(source)
const source = await handle.text()
const output = run(source) if (!result.errors) console.log(result.result)
else console.log(result.errors)
if (output.errors) {
for (const error of output.errors) {
console.log(error)
}
} else {
console.log(output.result)
}
}

View File

@ -1,31 +1,19 @@
export async function send() { const repl_file = Bun.file("./.lrepl")
const repl_file = Bun.file("./.lrepl") const repl_info = await repl_file.json()
let repl_info const port = repl_info.port
try {
repl_info = await repl_file.json()
} catch (e) {
console.log("No .lrepl file found.")
process.exit(1)
}
const port = repl_info.port
const session = repl_info.session
const socket = await Bun.connect({ const socket = await Bun.connect({
hostname: "localhost", hostname: "localhost",
port, port,
socket: { socket: {
data: () => process.exit() data: (_, data) => process.exit()
}
})
for await (const input of Bun.stdin.stream()) {
const chunk = Buffer.from(input).toString("utf-8")
const payload = {source: chunk, session}
// console.log("Sending:", payload)
// console.log(`To: ${port}`)
socket.write(JSON.stringify(payload))
socket.end()
process.exit()
} }
})
for await (const input of Bun.stdin.stream()) {
const chunk = Buffer.from(input).toString("utf-8")
socket.write(chunk)
socket.end()
process.exit()
} }