[fix] aborting

This commit is contained in:
2025-07-20 04:12:13 +01:00
parent 3656d71e6d
commit 3f8f515262
6 changed files with 145 additions and 122 deletions

View File

@@ -13,14 +13,21 @@ A simple language server based VSCode Extension for the (Branflakes?) (BrainFuck
### Execution
Use the command to execute the code.
Issue is, because BF is a **turing complete** language, there is no way to know if the program will terminate or not. Hence for now, the command may lead to infinite execution.
Use the BF execute task to execute the code.
Because JS is single threaded+.
If the program requires input, it will be requested as a prompt.
TODO: Implement a timeout.
### Changelog
#### 0.3.0
- Added a task for execution
- Press Control C to halt it while its waiting for input
- Close task to abort execution
#### 0.2.1
- Change category

View File

@@ -0,0 +1,11 @@
export class AbortClassRequestor{
private abortRequest=false;
requestAbort(){
this.abortRequest=true;
}
isAborted(){
return this.abortRequest;
}
}

View File

@@ -5,11 +5,11 @@ import { DiagnosticSeverity } from 'vscode-languageclient';
import { getTree } from '../BranFlakesParseRunner';
import { RuleNode } from 'antlr4ts/tree/RuleNode';
import type InputStrategy from '../input/InputStrategy';
import { AbortClassRequestor } from './AbortRequestor';
export class BranFlakesExecutorVisitor
extends AbstractParseTreeVisitor<Promise<void>>
implements bfVisitor<Promise<void>>
{
implements bfVisitor<Promise<void>> {
/**
*
* @param input Input string
@@ -18,6 +18,7 @@ export class BranFlakesExecutorVisitor
constructor(
private inputStrategy: InputStrategy,
private logger: (val: string) => Thenable<void>,
private abortRequestor?: AbortClassRequestor,
private inputPtr: number = 0
) {
super();
@@ -37,7 +38,6 @@ export class BranFlakesExecutorVisitor
private outputStr: string = '';
defaultResult() {
return Promise.resolve();
}
@@ -52,7 +52,8 @@ export class BranFlakesExecutorVisitor
text: string,
fn: string,
inputStrategy: InputStrategy,
logger: (str: string) => Thenable<void>
logger: (str: string) => Thenable<void>,
aborter?: AbortClassRequestor
) {
//get tree and issues
const { tree, issues } = getTree(text, fn);
@@ -64,7 +65,7 @@ export class BranFlakesExecutorVisitor
throw Error('Errors exist');
}
// make visitor
const vis = new BranFlakesExecutorVisitor(inputStrategy, logger);
const vis = new BranFlakesExecutorVisitor(inputStrategy, logger, aborter);
//visit the tree
await vis.visit(tree);
@@ -129,7 +130,11 @@ export class BranFlakesExecutorVisitor
result = this.aggregateResult(result, childResult);
await result;
}
return Promise.resolve();
// break for any close requests
return new Promise((res, rej) => {
setTimeout(() => { if (this.abortRequestor?.isAborted()??false) {rej('aborted');} else {res(undefined);} }, 0);
});
}
// override for maintaining async
protected async aggregateResult(

View File

@@ -1,6 +1,7 @@
import * as vscode from 'vscode';
import * as path from 'path';
import { BranFlakesExecutorVisitor } from '../exec/BranFlakesExecutorVisitor';
import { AbortClassRequestor } from '../exec/AbortRequestor';
interface BFRunTaskDefinition extends vscode.TaskDefinition {
file?: string;
@@ -63,7 +64,7 @@ class CustomBuildTaskTerminal implements vscode.Pseudoterminal {
private openDocument: vscode.TextDocument | undefined;
onDidWrite: vscode.Event<string> = this.writeEmitter.event;
onDidClose?: vscode.Event<number> = this.closeEmitter.event;
abortRequestor = new AbortClassRequestor();
handleInput(data: string): void {
// this.writeEmitter.fire(`Echo(${data.length})` + data);
@@ -106,6 +107,8 @@ class CustomBuildTaskTerminal implements vscode.Pseudoterminal {
close(): void {
// The terminal has been closed. Shutdown the build.
console.log('Forced close');
this.abortRequestor.requestAbort();
}
private async doExecution(): Promise<void> {
@@ -120,13 +123,11 @@ class CustomBuildTaskTerminal implements vscode.Pseudoterminal {
return new Promise((res, rej) => {
if (cus.inputQueue.length > 0) {
const char = cus.inputQueue.shift();
console.log('consumed input', char);
res(char);
} else {
const dispose: vscode.Disposable[] = [];
cus.readEmitter.event(e => {
const char = cus.inputQueue.shift();
console.log('consumed input async', char);
//clear the earliest disposable
dispose.shift()?.dispose();
res(char);
@@ -137,9 +138,8 @@ class CustomBuildTaskTerminal implements vscode.Pseudoterminal {
},
},
async (data) => {
// console.log('output', data);
this.writeEmitter.fire(replaceLFWithCRLF(data));
}
},this.abortRequestor
);
this.closeEmitter.fire(0);
} catch (e) {

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "bfc-server",
"version": "0.2.1",
"version": "0.3.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "bfc-server",
"version": "0.2.1",
"version": "0.3.0",
"hasInstallScript": true,
"license": "MIT",
"dependencies": {

View File

@@ -5,7 +5,7 @@
"author": "Atreya Bain",
"license": "MIT",
"publisher": "atreyabain",
"version": "0.2.1",
"version": "0.3.0",
"icon": "assets/128.png",
"categories": ["Programming Languages","Linters"],
"keywords": [