Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions examples/be.coem
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#as palimpsest

let flag be black
let flag be yellow
let flag be red

know—flag—
6 changes: 6 additions & 0 deletions examples/briefly.coem
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
say—surrender—
say—alabaster—
let (switchblade|honeysuckle|goldenrod)
say—autumn— † despite the green in my eyes.
say—beauty— † despite daylight.
say—“i’d kill for it”—
10 changes: 10 additions & 0 deletions examples/cat-detected.be.coem
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
let (ch|k)at(|tze) be “🐈”

let savoir be know
savoir—chat is “🐈”—

let weten be know
weten—kat is “🐈”—

let wissen be know
wissen—katze is “🐈”—
6 changes: 6 additions & 0 deletions examples/docks.coem
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
let se(e|a) be “blue”
let mis(t|sed) be “thick”
let mou?rning be “dark”
let me be nothing
know—see, mist, morning—
know—sea, missed, mourning—
38 changes: 38 additions & 0 deletions examples/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>coem-lang sandbox</title>
</head>
<body>
<main>
<button id="echo">echo</button>
<label for="debug">debug</label><input id="debug" type="checkbox" />

<br />

<textarea id="coem" rows="30" cols="60"></textarea>

<hr />

<pre id="echoed"></pre>
</main>

<script type="module">
import { run, Environment } from "../src/main.js";

echo.addEventListener("click", () => {
try {
const echoem = run(coem.value, new Environment(), debug.checked);
echoed.innerText = echoem;
console.log(echoem);
} catch (e) {
echoed.innerText =
e.msg + "\n\n(full error description is logged to the console)";
console.error(e);
}
});
</script>
</body>
</html>
23 changes: 23 additions & 0 deletions examples/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// $ .../index.js file-name.coem

import { readFile } from "fs/promises";
import { join } from "path";

import { run, Environment } from "../src/main.js";

const coemFileName = process.argv[2];

if (!coemFileName) {
console.log("no coem file name provided");
process.exit();
}

const coem = await readFile(join(import.meta.dirname, coemFileName), "utf8");

const debug = false;
try {
const echo = run(coem, new Environment(), debug);
console.log(echo);
} catch (e) {
console.error(e);
}
10 changes: 10 additions & 0 deletions examples/peace.coem
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#as palimpsest

to sleep—still—:
cold & still.

let death be sleep—eternal—
know—death—

let death be patience
death †
9 changes: 9 additions & 0 deletions examples/reminder.coem
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
† this is a reminder

to breathe?——:
† in and out, and thus to
know—myself—.

let me|myself|I be “present”
if—I am “present”—:
let me be breath——.
6 changes: 6 additions & 0 deletions examples/sleep.coem
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
to sl?eep—when—:
“dreams”.

sleep—“now”—
sleep—“never”—
seep—“continually”—
1 change: 1 addition & 0 deletions examples/snail-train.coem
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
print—“i_@”—
28 changes: 3 additions & 25 deletions index.js → examples/test.coem
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
import { run, Environment } from './src/main.js';

const debug = true;

const source = `#as palimpsest
#as palimpsest

to conditional——:
let tomorrow be not coming
Expand All @@ -28,29 +24,11 @@ to conditional——:
let end be “watching the sky burn”.

† conditional——

say—“It doesn’t matter.”—
say—“That would be enough.”—
let this be “us alive”
let this be “right here”
let this be “feeling lucky”
let you be wanting
this`;

function handleError(e, source = "") {
if (!e) return null;
console.error(e);
}

function handleOutput(...txt) {
console.log(...txt);
}

const browserEnv = new Environment();
try {
// console.log(run(source, browserEnv, handleOutput, false));
let echo = run(source, browserEnv, debug);
console.log(echo);
handleError(null);
} catch (e) {
handleError(e, source);
}
this
10 changes: 10 additions & 0 deletions examples/woman.coem
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
† based on Emmy Meli's “I Am Woman”

#as palimpsest

let I|me|myself be “woman”
let me be “fearless”
let me be “sexy”
let me be “divine”

know—myself—
14 changes: 6 additions & 8 deletions src/environment.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { runtimeError } from './errors.js';
import { runtimeError } from "./errors.js";

class Environment {

constructor(enclosing = null) {
this.values = new Map();
this.enclosing = enclosing;
this.asPalimpsest = false;
}

get(token) {
Expand Down Expand Up @@ -39,7 +39,7 @@ class Environment {

setNameValue(name, value) {
if (name === "as" && value.literal === "palimpsest") {
Environment.asPalimpsest = true;
this.asPalimpsest = true;
return;
}

Expand All @@ -48,7 +48,7 @@ class Environment {

// redefine in current environment
if (set) {
if (Environment.asPalimpsest) {
if (this.asPalimpsest) {
let values = set[1];
values.push(value);
return this.values.set(set[0], values);
Expand All @@ -66,7 +66,7 @@ class Environment {
}

// define new in current environment
if (Environment.asPalimpsest) {
if (this.asPalimpsest) {
return this.values.set(pattern, [value]);
} else {
return this.values.set(pattern, value);
Expand All @@ -79,6 +79,4 @@ class Environment {
}
}

Environment.asPalimpsest = false;

export { Environment };
export { Environment };
46 changes: 24 additions & 22 deletions src/interpreter.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { runtimeError, ReturnError } from './errors.js';
import { runtimeError, ReturnError } from "./errors.js";
import {
Binary,
Unary,
Expand All @@ -14,19 +14,19 @@ import {
VarStatement,
Condition,
Directive,
Comment
} from './types.js';
import { Environment } from './environment.js';
import { Tokenizer } from './tokenizer.js';
Comment,
} from "./types.js";
import { Environment } from "./environment.js";
import { Tokenizer } from "./tokenizer.js";
const token = Tokenizer.tokenEnum;

const isTruthy = val => Boolean(val);
const isTruthy = (val) => Boolean(val);
const isEqual = (a, b) => a === b;

class CoemCallable {
constructor(declaration, closure) {
this.declaration = declaration
this.closure = closure
this.declaration = declaration;
this.closure = closure;
}

// call(interpreter, args) {
Expand All @@ -48,10 +48,9 @@ class CoemCallable {
}

toString() {
return `<${this.declaration.name.lexeme}()>`
};
return `<${this.declaration.name.lexeme}()>`;
}
}
;
class Interpreter {
// constructor(environment, printfunc = console.log) {
constructor(environment, source) {
Expand Down Expand Up @@ -88,18 +87,18 @@ class Interpreter {
} else {
this.lines[line].push(print);
}
}
};

const getArgPrint = (arg) => {
if (Array.isArray(arg)) {
return arg.join(", ");
}
return arg;
}
};

this.environment.setBuiltin('print', nativePrint);
this.environment.setBuiltin('know', nativePrint);
this.environment.setBuiltin('say', nativePrint);
this.environment.setBuiltin("print", nativePrint);
this.environment.setBuiltin("know", nativePrint);
this.environment.setBuiltin("say", nativePrint);
}

interpret(expr) {
Expand All @@ -117,7 +116,8 @@ class Interpreter {
else if (expr instanceof VarStatement) return this.visitVarStatement(expr);
else if (expr instanceof Return) return this.visitReturnStatement(expr);
// Doesn't need its own, it can just evaluate like grouping
else if (expr instanceof ExpressionStatement) return this.visitExpressionStmt(expr);
else if (expr instanceof ExpressionStatement)
return this.visitExpressionStmt(expr);
else if (expr instanceof Var) return this.visitVar(expr);
else if (expr instanceof Literal) return this.visitLiteral(expr);
else if (expr instanceof Unary) return this.visitUnary(expr);
Expand Down Expand Up @@ -218,15 +218,17 @@ class Interpreter {
}

visitCall(expr) {
const callee = this.evaluate(expr.callee);
let callee = this.evaluate(expr.callee);

if (Array.isArray(callee)) callee = callee[0];

let args = expr.arguments.map(arg => this.evaluate(arg));
let args = expr.arguments.map((arg) => this.evaluate(arg));

if (!callee.call) {
throw runtimeError('Can only call functions.', expr.dash);
throw runtimeError("Can only call functions.", expr.dash);
}

return callee.call(this, args, expr.callee)
return callee.call(this, args, expr.callee);
}

visitUnary(expr) {
Expand Down Expand Up @@ -268,4 +270,4 @@ class Interpreter {
}
}

export { Interpreter };
export { Interpreter };