Implement basic execution system and UI

This is a rather large commit that includes all of the following:
- React UI with code editor, runtime renderer and input-output panes
- Language providers for a sample language and Brainfuck
- Implementation of code execution in a web worker
- All-at-once unabortable execution of program fully functional
This commit is contained in:
Nilay Majorwar
2021-12-14 21:58:13 +05:30
parent 8746c803d7
commit 01ba292b9f
35 changed files with 3532 additions and 3529 deletions

View File

@@ -0,0 +1,60 @@
import { LanguageEngine, StepExecutionResult } from "./types";
type ExecuteAllArgs<RS> = {
/** Interval between two execution steps, in milliseconds */
interval?: number;
/**
* Pass to run in streaming-response mode.
* Callback is called with exeuction result on every execution step.
*/
onResult?: (result: StepExecutionResult<RS>) => void;
};
class ExecutionController<RS> {
private _engine: LanguageEngine<RS>;
private _result: StepExecutionResult<RS> | null;
/**
* Create a new ExecutionController.
* @param engine Language engine to use for execution
*/
constructor(engine: LanguageEngine<RS>) {
this._engine = engine;
this._engine.resetState();
this._result = null;
}
/**
* Reset execution state in controller and engine.
* Clears out state from the current execution cycle.
*/
resetState() {
this._engine.resetState();
this._result = null;
}
/**
* Load code and user input into the engine to prepare for execution.
* @param code Code content, lines separated by `\n`
* @param input User input, lines separated by '\n'
*/
prepare(code: string, input: string) {
this._engine.prepare(code, input);
}
async executeAll({ interval, onResult }: ExecuteAllArgs<RS>) {
while (true) {
this._result = this._engine.executeStep();
onResult && onResult(this._result);
if (!this._result.nextStepLocation) break;
if (interval) await this.sleep(interval);
}
return this._result;
}
private async sleep(millis: number) {
return new Promise<void>((resolve) => setTimeout(resolve, millis));
}
}
export default ExecutionController;