[refactor] commands

This commit is contained in:
2024-01-02 17:15:19 +05:30
parent 6e143cd4d0
commit 0a2a6c4db6
8 changed files with 127 additions and 90 deletions

View File

@@ -16,32 +16,27 @@ export default class BranFlakesExecutorVisitor
* @param inputPtr Input pointer to start from
*/
constructor(
protected inputStrategy: InputStrategy,
protected logger: (val: string) => Thenable<string>,
protected inputPtr: number = 0
private inputStrategy: InputStrategy,
private logger: (val: string) => Thenable<string>,
private inputPtr: number = 0
) {
super();
}
// /**
// * The memory cells (Can work with negative cells this way)
// */
// protected cells: Map<number, number> = new Map();
// private cells: Map<number, number> = new Map();
protected byteArraySize: number = 30000;
protected byteArray: Int8Array = new Int8Array(this.byteArraySize);
private byteArraySize: number = 30000;
private byteArray: Int8Array = new Int8Array(this.byteArraySize);
/**
* Pointer
*/
protected ptr: number = 0;
private ptr: number = 0;
/** Output string */
protected outputStrArray: string[] = [];
private outputStr: string = '';
/**
* Output string (Available only after visiting)
*/
public get outputStr() {
return this.outputStrArray.join('');
}
defaultResult() {
return Promise.resolve();
@@ -57,7 +52,7 @@ export default class BranFlakesExecutorVisitor
text: string,
fn: string,
inputStrategy: InputStrategy,
logger: (str:string) => Thenable<string>
logger: (str: string) => Thenable<string>
) {
//get tree and issues
const { tree, issues } = getTree(text, fn);
@@ -90,10 +85,10 @@ export default class BranFlakesExecutorVisitor
}
}
async visitPtrLeft() {
--this.ptr;
this.ptr = (this.ptr + this.byteArraySize - 1) % this.byteArraySize;
}
async visitPtrRight() {
++this.ptr;
this.ptr = (this.ptr + this.byteArraySize + 1) % this.byteArraySize;
}
async visitPtrIncr() {
const val = this.getCell(this.ptr);
@@ -107,12 +102,12 @@ export default class BranFlakesExecutorVisitor
const val = this.getCell(this.ptr) ?? 0;
const str = String.fromCharCode(val);
this.outputStrArray.push(str);
this.outputStr += str;
}
async visitInputStmt() {
//get char
const char = await this.inputStrategy.getInput() ?? 0;
const char = (await this.inputStrategy.getInput()) ?? 0;
//increment the input pointer after this
this.inputPtr++;
this.setCell(this.ptr, char);
@@ -120,7 +115,6 @@ export default class BranFlakesExecutorVisitor
// override for maintaining async
async visitChildren(node: RuleNode): Promise<void> {
// await this.logger("checking "+node.constructor.name)
let result = this.defaultResult();
await result;
let n = node.childCount;

View File

@@ -0,0 +1,5 @@
export interface Command{
getCommandName():string;
getCommandHandler():(...args:any)=>Promise<any>;
}

View File

@@ -0,0 +1,26 @@
import { window } from 'vscode';
import { Command as BranFlakesCommand } from './Command';
import { VSCodePromptInputStrategy } from '../input/VSCodePromptInputStrategy';
import BranFlakesExecutorVisitor from '../BranFlakesExecutorVisitor';
export class CompileBranFlakesCommand implements BranFlakesCommand {
getCommandName() {
return 'bf.execute';
}
getCommandHandler() {
return async () => {
const text = window.activeTextEditor.document.getText();
const fn = window.activeTextEditor.document.fileName;
const inputStrategy = new VSCodePromptInputStrategy(
window.showInputBox
);
const output = await BranFlakesExecutorVisitor.run(
text,
fn,
inputStrategy,
window.showInformationMessage
);
await window.showInformationMessage(`Output: ${output}`);
};
}
}

View File

@@ -4,71 +4,68 @@
* ------------------------------------------------------------------------------------------ */
import * as path from 'path';
import { ExtensionContext,commands, window } from 'vscode';
import { ExtensionContext, commands, window } from 'vscode';
import {
LanguageClient,
LanguageClientOptions,
ServerOptions,
TransportKind
LanguageClient,
LanguageClientOptions,
ServerOptions,
TransportKind,
} from 'vscode-languageclient';
import BranFlakesExecutorVisitor from './BranFlakesExecutorVisitor';
import { VSCodePromptInputStrategy } from './input/VSCodePromptInputStrategy';
import { CompileBranFlakesCommand } from './command/CompileCommand';
let client: LanguageClient;
export function activate(context: ExtensionContext) {
// The server is implemented in node
let serverModule = context.asAbsolutePath(
path.join('server', 'dist', 'server.js')
);
// The debug options for the server
// --inspect=6009: runs the server in Node's Inspector mode so VS Code can attach to the server for debugging
let debugOptions = { execArgv: ['--nolazy', '--inspect=6009'] };
// The server is implemented in node
let serverModule = context.asAbsolutePath(
path.join('server', 'dist', 'server.js')
);
// The debug options for the server
// --inspect=6009: runs the server in Node's Inspector mode so VS Code can attach to the server for debugging
let debugOptions = { execArgv: ['--nolazy', '--inspect=6009'] };
// If the extension is launched in debug mode then the debug server options are used
// Otherwise the run options are used
let serverOptions: ServerOptions = {
run: { module: serverModule, transport: TransportKind.ipc },
debug: {
module: serverModule,
transport: TransportKind.ipc,
options: debugOptions
}
};
// If the extension is launched in debug mode then the debug server options are used
// Otherwise the run options are used
let serverOptions: ServerOptions = {
run: { module: serverModule, transport: TransportKind.ipc },
debug: {
module: serverModule,
transport: TransportKind.ipc,
options: debugOptions,
},
};
// Options to control the language client
let clientOptions: LanguageClientOptions = {
// Register the server for plain text documents
documentSelector: [{ scheme: 'file', language: 'bf' }]
};
// Options to control the language client
let clientOptions: LanguageClientOptions = {
// Register the server for plain text documents
documentSelector: [{ scheme: 'file', language: 'bf' }],
};
const command = 'bf.execute';
const commandHandler = async()=>{
const text= window.activeTextEditor.document.getText();
const fn = window.activeTextEditor.document.fileName;
const inputStrategy = new VSCodePromptInputStrategy(window.showInputBox);
const output = await BranFlakesExecutorVisitor.run(text,fn,inputStrategy,window.showInformationMessage);
await window.showInformationMessage(`Output: ${output}`);
};
const branFlakesCommands = [new CompileBranFlakesCommand()];
for (let branFlakesCommand of branFlakesCommands) {
context.subscriptions.push(
commands.registerCommand(
branFlakesCommand.getCommandName(),
branFlakesCommand.getCommandHandler()
)
);
}
context.subscriptions.push(commands.registerCommand(command,commandHandler));
// Create the language client and start the client.
client = new LanguageClient(
'brainfucklanguageserver',
'Brainfuck Language Server',
serverOptions,
clientOptions
);
// Create the language client and start the client.
client = new LanguageClient(
'brainfucklanguageserver',
'Brainfuck Language Server',
serverOptions,
clientOptions
);
// Start the client. This will also launch the server
client.start();
// Start the client. This will also launch the server
client.start();
}
export function deactivate(): Thenable<void> | undefined {
if (!client) {
return undefined;
}
return client.stop();
if (!client) {
return undefined;
}
return client.stop();
}

View File

@@ -2,8 +2,13 @@ import { CancellationToken, InputBoxOptions } from 'vscode';
import InputStrategy from './InputStrategy';
export class VSCodePromptInputStrategy implements InputStrategy {
private inputQueue:string;
constructor(private requestor:(promptOptions?:InputBoxOptions,cancelToken?:CancellationToken)=>Thenable<string>) {}
private inputQueue: string = '';
constructor(
private requestor: (
promptOptions?: InputBoxOptions,
cancelToken?: CancellationToken
) => Thenable<string>
) {}
async getInput(): Promise<number> {
while (this.inputQueue.length == 0) {
@@ -11,11 +16,13 @@ export class VSCodePromptInputStrategy implements InputStrategy {
}
const character = this.inputQueue.charCodeAt(0);
this.inputQueue = this.inputQueue.substring(1);
return character;
}
private async requestInputFromPrompt() {
const inputPrompt = await this.requestor({prompt:"More input is required. Please provide input:"});
const inputPrompt = await this.requestor({
prompt: 'More input is required. Please provide input:',
});
this.inputQueue += inputPrompt;
}
}