From 36ed3328d1461dfdfa4db69109e87a6cd86f2e6d Mon Sep 17 00:00:00 2001 From: Atreya Bain Date: Fri, 15 Dec 2023 14:27:11 +0530 Subject: [PATCH] refactor --- client/src/BranFlakesExecutorVisitor.ts | 116 +++++++++++++++++ ...{bfGrammar.ts => BranFlakesParseRunner.ts} | 2 +- client/src/bfExecutor.ts | 117 ------------------ client/src/extension.ts | 6 +- server/src/server.ts | 4 +- 5 files changed, 123 insertions(+), 122 deletions(-) create mode 100644 client/src/BranFlakesExecutorVisitor.ts rename client/src/{bfGrammar.ts => BranFlakesParseRunner.ts} (95%) delete mode 100644 client/src/bfExecutor.ts diff --git a/client/src/BranFlakesExecutorVisitor.ts b/client/src/BranFlakesExecutorVisitor.ts new file mode 100644 index 0000000..f625a9b --- /dev/null +++ b/client/src/BranFlakesExecutorVisitor.ts @@ -0,0 +1,116 @@ +import { AbstractParseTreeVisitor } from 'antlr4ts/tree/AbstractParseTreeVisitor'; +import { LoopStmtContext } from './generated/bfParser'; +import { bfVisitor } from './generated/bfVisitor'; +import { DiagnosticSeverity } from 'vscode-languageclient'; +import { getTree } from './BranFlakesParseRunner'; + +export default class BranFlakesExecutorVisitor + extends AbstractParseTreeVisitor + implements bfVisitor { + + /** + * + * @param input Input string + * @param inputPtr Input pointer to start from + */ + constructor(protected input: string = '', protected inputPtr: number = 0) { + super(); + } + /** + * The memory cells (Can work with negative cells this way) + */ + protected cells: Map = new Map(); + protected byteArray: Int8Array = new Int8Array(30000); + /** + * Pointer + */ + protected ptr: number = 0; + /** Output string */ + protected outputStrArray: string[] = []; + + /** + * Output string (Available only after visiting) + */ + public get outputStr() { + return this.outputStrArray.join(''); + } + + + defaultResult() { } + /** + * Run a file + * @param text + * @param fn + * @param input + * @returns + */ + static run(text:string,fn: string, input:string){ + //get tree and issues + const { tree, issues } = getTree(text, fn); + + //get only errors + const x = issues.filter(e => e.type === DiagnosticSeverity.Error); + //if any error, drop + if (x.length > 0) { + throw Error('Errors exist'); + } + // make visitor + const vis = new BranFlakesExecutorVisitor(input); + + //visit the tree + vis.visit(tree); + + //get output + return vis.outputStr; + } + + + visitLoopStmt(ctx: LoopStmtContext) { + while ((this.cells.get(this.ptr) ?? 0) !== 0) { + this.visitChildren(ctx); + } + } + visitPtrLeft() { + + --this.ptr; + } + visitPtrRight() { + ++this.ptr; + } + visitPtrIncr() { + + const val = this.cells.get(this.ptr); + if (val === undefined) { + this.cells.set(this.ptr, 1); + } else if (val === 255) { + this.cells.delete(this.ptr); + } else { + this.cells.set(this.ptr, val + 1); + } + } + visitPtrDecr() { + // console.log('down',this.ptr,this.cells); + const val = this.cells.get(this.ptr); + if (val === undefined || val === 0) { + this.cells.set(this.ptr, 255); + } else if (val === 1) { + this.cells.delete(this.ptr); + } else { + this.cells.set(this.ptr, val - 1); + } + } + visitOutputStmt() { + const val = this.cells.get(this.ptr) ?? 0; + const str = String.fromCharCode(val); + // console.log('op',str); + this.outputStrArray.push(str); + } + + visitInputStmt() { + //get char + const char = this.input.charCodeAt(this.inputPtr) ?? 0; + //increment the input pointer after this + this.inputPtr++; + this.cells.set(this.ptr, char); + } +} diff --git a/client/src/bfGrammar.ts b/client/src/BranFlakesParseRunner.ts similarity index 95% rename from client/src/bfGrammar.ts rename to client/src/BranFlakesParseRunner.ts index f55fde3..2451507 100644 --- a/client/src/bfGrammar.ts +++ b/client/src/BranFlakesParseRunner.ts @@ -16,9 +16,9 @@ export interface TranslationError { export function getTree(str: string, fn: string) { const charStreams = CharStreams.fromString(str, fn); const lexer = new bfLexer(charStreams); - // const errorListener = this.errorManager.newErrorListener(); const issues: TranslationError[] = []; // remove the error listener. We want to put our own + lexer.removeErrorListeners(); lexer.addErrorListener({ syntaxError(source, o, line, charPositionInLine, msg, error) { diff --git a/client/src/bfExecutor.ts b/client/src/bfExecutor.ts deleted file mode 100644 index 0f71718..0000000 --- a/client/src/bfExecutor.ts +++ /dev/null @@ -1,117 +0,0 @@ -import { AbstractParseTreeVisitor } from 'antlr4ts/tree/AbstractParseTreeVisitor'; -import { LoopStmtContext, ProgramContext } from '../../client/src/generated/bfParser'; -import { bfVisitor } from '../../client/src/generated/bfVisitor'; -import {getTree} from './bfGrammar'; -import { DiagnosticSeverity } from 'vscode-languageserver-types'; - -/** - * Run BF code - * @param text - * @param fn - * @param input - * @returns - */ -export async function runBF(text:string,fn:string,input:string){ - //get tree and issues - const {tree,issues} = getTree(text,fn); - - //get only errors - const x = issues.filter(e=>e.type===DiagnosticSeverity.Error); - //if any error, drop - if(x.length>0) { - throw Error('Errors exist'); - } - // make visitor - const vis = new BFExecutor(input); - - //visit the tree - vis.visit(tree); - - //get output - return vis.outputStr; -} - - -class BFExecutor - extends AbstractParseTreeVisitor - implements bfVisitor { - - /** - * - * @param input Input string - * @param inputPtr Input pointer to start from - */ - constructor(protected input: string='', protected inputPtr: number = 0) { - super(); - } - /** - * The memory cells (Can work with negative cells this way) - */ - protected cells: Map = new Map(); - /** - * Pointer - */ - protected ptr: number = 0; - /** Output string */ - protected outputStrArray:string[]=[]; - - /** - * Output string (Available only after visiting) - */ - public get outputStr(){ - return this.outputStrArray.join(''); - } - - - defaultResult() {} - - visitLoopStmt(ctx:LoopStmtContext){ - while((this.cells.get(this.ptr)??0)!==0){ - this.visitChildren(ctx); - } - } - visitPtrLeft() { - - --this.ptr; - } - visitPtrRight() { - ++this.ptr; - } - visitPtrIncr() { - - const val = this.cells.get(this.ptr); - if (val === undefined) { - this.cells.set(this.ptr, 1); - } else if(val===255){ - this.cells.delete(this.ptr); - }else{ - this.cells.set(this.ptr, val + 1); - } - } - visitPtrDecr() { - // console.log('down',this.ptr,this.cells); - - const val = this.cells.get(this.ptr); - if (val === undefined || val === 0) { - this.cells.set(this.ptr, 255); - } else if(val===1){ - this.cells.delete(this.ptr); - }else{ - this.cells.set(this.ptr, val - 1); - } - } - visitOutputStmt() { - const val = this.cells.get(this.ptr)??0; - const str = String.fromCharCode(val); - // console.log('op',str); - this.outputStrArray.push(str); - } - - visitInputStmt(){ - //get char - const char = this.input.charCodeAt(this.inputPtr)??0; - //increment the input pointer after this - this.inputPtr++; - this.cells.set(this.ptr,char); - } -} diff --git a/client/src/extension.ts b/client/src/extension.ts index a240af6..a48840d 100644 --- a/client/src/extension.ts +++ b/client/src/extension.ts @@ -5,13 +5,13 @@ import * as path from 'path'; import { workspace, ExtensionContext,commands, window } from 'vscode'; -import {runBF} from './bfExecutor'; import { LanguageClient, LanguageClientOptions, ServerOptions, TransportKind } from 'vscode-languageclient'; +import BranFlakesExecutorVisitor from './BranFlakesExecutorVisitor'; let client: LanguageClient; @@ -47,7 +47,9 @@ export function activate(context: ExtensionContext) { const text= window.activeTextEditor.document.getText(); const fn = window.activeTextEditor.document.fileName; const input = await window.showInputBox({prompt:'Enter input (If not enough, program will assume 0)'}); - const output = await runBF(text,fn,input); + + const output = BranFlakesExecutorVisitor.run(text,fn,input); + await window.showInformationMessage(`Output: ${output}`); }; diff --git a/server/src/server.ts b/server/src/server.ts index beb1f66..37598db 100644 --- a/server/src/server.ts +++ b/server/src/server.ts @@ -18,10 +18,10 @@ import { Position, } from 'vscode-languageserver'; -// import * as path from 'path'; + import { TextDocument } from 'vscode-languageserver-textdocument'; -// import { getTree } from './bfGrammar'; + // Create a connection for the server. The connection uses Node's IPC as a transport. // Also include all preview / proposed LSP features.