Skip to content

Commit

Permalink
Merge pull request #2 from StavromulaBeta/main
Browse files Browse the repository at this point in the history
feat: `Begin`
  • Loading branch information
hedyhli authored Aug 27, 2024
2 parents 48c63fc + a434df2 commit 160791f
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 4 deletions.
1 change: 1 addition & 0 deletions builtins.js
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,7 @@ export function initIdent2kind(preludeEnv) {
"Stack",
"Clear",
"Error",
"Begin",
].forEach(name => { ident2kind[name] = "builtin" });

if (preludeEnv)
Expand Down
59 changes: 55 additions & 4 deletions cognate.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ export class PreludeError extends Error {
}
}

export class BeginSignal extends Error {
constructor() {
super("This is the signal for the 'Begin' continuation. This is only an error if outside the source 'Begin'.");
}
}

// Global state
const G = {
preludeEnv: {},
Expand Down Expand Up @@ -41,7 +47,13 @@ export function initPrelude(preludeText) {
throw new PreludeError("failed to parse prelude");
}
// Exec
result = runner.process(result.rootBlock, []);
try {
result = runner.process(result.rootBlock, []);
}
catch (err) {
if (err instanceof BeginSignal) result.error = "cannot exit 'Begin' block when not inside it";
else throw(err);
}
if (result.error != '') {
throw new PreludeError(`failed to execute prelude: ${result.error}`);
}
Expand Down Expand Up @@ -475,9 +487,14 @@ export class Runner {
this.redrawErrors();
// Exec
this.callStackSize = 0;
result = this.process(result.rootBlock, []);
this.$stack.innerHTML = this.reprArr(result.stack);

try {
result = this.process(result.rootBlock, []);
}
catch (err) {
if (err instanceof BeginSignal) result.error = "cannot exit 'Begin' block when not inside it first";
else throw(err);
}
if (result.stack !== undefined) this.$stack.innerHTML = this.reprArr(result.stack);
if (result.error != '') {
this.appendError(result.error);
this.redrawErrors("Runtime error!");
Expand Down Expand Up @@ -799,6 +816,40 @@ export class Runner {
}
break;
}
case 'Begin': {
let block = expect(exists(op.pop(), 'block'), 'block');
if (block == undefined) {
error = `in ${this.textMarked('List')}: ${error}`;
break;
}

let id_err = new BeginSignal();

op.push({
type: 'block',
body: [{type: 'identifier', value: '_endBegin'}],
env: { id_err },
});

let result = { error: "" }
try {
result = this.process(block, op);
}
catch (id2) {
if (id_err !== id2) throw(id2);
}

if (result.error != "") {
error = `in ${this.textMarked('Begin')}: ${result.error}`;
break;
}

break;
}

case '_endBegin': {
throw(env.id_err);
}

// I/O
case 'Show': {
Expand Down

0 comments on commit 160791f

Please sign in to comment.