diff --git a/ibfi-ts/src/App.scss b/ibfi-ts/src/App.scss index 7d50644..8316c9a 100644 --- a/ibfi-ts/src/App.scss +++ b/ibfi-ts/src/App.scss @@ -35,6 +35,31 @@ $font-color: ghostwhite; } } +.code-display-wrapper { + max-width: 80vw; + + span { + word-wrap: break-word; + } +} + +.memory-display-table { + $border: 1px solid $font-color; + + th, .cell { + border: $border; + } + + .pointer { + + } + + th, td { + width: 30px; + text-align: center; + } +} + .bf-run { margin: 20px; diff --git a/ibfi-ts/src/App.tsx b/ibfi-ts/src/App.tsx index f78223e..da6bf5b 100644 --- a/ibfi-ts/src/App.tsx +++ b/ibfi-ts/src/App.tsx @@ -1,33 +1,31 @@ import './App.scss'; import CodeInput from "./components/CodeInput"; import ProgramOutput from "./components/ProgramOutput"; -import React, {useState} from "react"; -import Interpreter from "./brainfuck/Interpreter"; -import RunInfo from "./components/RunInfo"; +import React, {useCallback, useState} from "react"; +import Runner from "./components/Runner"; function App() { - const [interpreter, setInterpreter] = useState(null); - const [out, setOut] = useState(""); const [input, setInput] = useState(""); + const [running, setRunning] = useState(false); - const outHandler = (char: number) => { + const outHandler = useCallback((char: number) => { setOut(out => out + String.fromCharCode(char)) - } + }, []); - const inHandler = (): number => { + const inHandler = useCallback((): number => { return 65; - } - - const start = () => setInterpreter(new Interpreter(input, outHandler, inHandler)); - const next = () => interpreter?.next(); - const prev = () => interpreter?.prev(); + }, []); return (
- setInput(input)}/> - - + { + !running && setInput(input)}/> + } + + { + running && + }
); } diff --git a/ibfi-ts/src/brainfuck/Interpreter.ts b/ibfi-ts/src/brainfuck/Interpreter.ts index 8353192..ab40799 100644 --- a/ibfi-ts/src/brainfuck/Interpreter.ts +++ b/ibfi-ts/src/brainfuck/Interpreter.ts @@ -4,8 +4,8 @@ export default class Interpreter { private readonly _code: string; private _codePointer: number; - private _inHandler: (() => number); - private _outHandler: ((char: number) => void); + private readonly _inHandler: (() => number); + private readonly _outHandler: ((char: number) => void); constructor(code: string, outHandler: ((char: number) => void), inHandler: (() => number)) { const buf = new ArrayBuffer(32000); @@ -18,7 +18,7 @@ export default class Interpreter { } public next() { - switch (this._code[++this._codePointer]) { + switch (this._code[this._codePointer++]) { case '+': this._array[this._pointer]++; break; @@ -32,27 +32,47 @@ export default class Interpreter { this._pointer--; break; case '.': - this._outHandler(this._array[this._pointer]); + this._outHandler(this.value); break; case ',': this._array[this._pointer] = this._inHandler(); break; case '[': - console.error("does not support [ for now") + if (this.value === 0) { + let level = 0; + while (this.instruction !== ']' || level > -1) { + this._codePointer++; + if (this.instruction === '[') level++; + else if (this.instruction === ']') level--; + } + } break; case ']': - console.error("does not support ] for now") + if (this.value !== 0) { + let level = 0; + while (this.instruction !== '[' || level > -1) { + this._codePointer--; + if (this.instruction === '[') level--; + else if (this.instruction === ']') level++; + } + } + break; + case undefined: + console.warn("reached end"); break; default: { } } - console.log("next step") + console.log(`char: ${this.code[this.codePointer - 1]} pointer: ${this.pointer} value: ${this.array[this.pointer]}`) } public prev() { } + get instruction(): string { + return this._code[this._codePointer]; + } get value(): number { return this._array[this._pointer]; diff --git a/ibfi-ts/src/components/CodeDisplay.tsx b/ibfi-ts/src/components/CodeDisplay.tsx new file mode 100644 index 0000000..0affb6f --- /dev/null +++ b/ibfi-ts/src/components/CodeDisplay.tsx @@ -0,0 +1,22 @@ +import React from 'react'; + +interface CodeDisplayProps { + code: string, + index: number, +} + +const CodeDisplay = ({code, index}: CodeDisplayProps) => { + + const firstCodePart = code.substr(0, index); + const secondCodePart = code.substr(index + 1, code.length - index + 1); + + return ( +
+ {firstCodePart} + {code[index]} + {secondCodePart} +
+ ); +}; + +export default CodeDisplay; \ No newline at end of file diff --git a/ibfi-ts/src/components/CodeInput.tsx b/ibfi-ts/src/components/CodeInput.tsx index 8b3f403..036fe5e 100644 --- a/ibfi-ts/src/components/CodeInput.tsx +++ b/ibfi-ts/src/components/CodeInput.tsx @@ -7,14 +7,23 @@ interface CodeInputProps { const CodeInput = ({setInput}: CodeInputProps) => { const [fontSize, setFontSize] = useState(40); + const setStart = () => { + setInput( + "+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+." + + "+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+." + ); + } + return (
setFontSize(+v.target.value)}/> +
-