mirror of
https://github.com/Noratrieb/brainfuck.git
synced 2026-01-14 13:35:00 +01:00
blocking mode
This commit is contained in:
parent
2202c79521
commit
e9d3a88bb6
7 changed files with 63 additions and 27 deletions
2
bfi-rust/.gitignore
vendored
2
bfi-rust/.gitignore
vendored
|
|
@ -1,5 +1,3 @@
|
||||||
/target
|
/target
|
||||||
.idea
|
.idea
|
||||||
# brainfuck testing code, get your own
|
# brainfuck testing code, get your own
|
||||||
*.b
|
|
||||||
*.bf
|
|
||||||
|
|
@ -34,6 +34,10 @@ $medium-color: #78787f;
|
||||||
height: 400px;
|
height: 400px;
|
||||||
font-size: 100px;
|
font-size: 100px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.code-options-wrapper > * {
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.code-display-wrapper {
|
.code-display-wrapper {
|
||||||
|
|
@ -67,12 +71,18 @@ $medium-color: #78787f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.run-button {
|
||||||
|
height: 50px;
|
||||||
|
width: 200px;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
.bf-run {
|
.bf-run {
|
||||||
margin: 20px;
|
margin: 20px;
|
||||||
|
|
||||||
button {
|
|
||||||
height: 50px;
|
.speed-control-wrapper > * {
|
||||||
width: 200px;
|
margin: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.small-speed-button {
|
.small-speed-button {
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,12 @@
|
||||||
import './App.scss';
|
import '../App.scss';
|
||||||
import CodeInput, {CodeOptions} from "./components/CodeInput";
|
import CodeInput, {CodeOptions} from "./CodeInput";
|
||||||
import ProgramOutput from "./components/ProgramOutput";
|
import ProgramOutput from "./ProgramOutput";
|
||||||
import React, {useCallback, useState} from "react";
|
import React, {useCallback, useState} from "react";
|
||||||
import Runner from "./components/Runner";
|
import Runner from "./Runner";
|
||||||
|
|
||||||
export const OptionContext = React.createContext<CodeOptions>({});
|
export const OptionContext = React.createContext<CodeOptions>({});
|
||||||
|
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
const [out, setOut] = useState("");
|
const [out, setOut] = useState("");
|
||||||
const [input, setInput] = useState<[string, CodeOptions]>(["", {}]);
|
const [input, setInput] = useState<[string, CodeOptions]>(["", {}]);
|
||||||
|
|
@ -4,6 +4,7 @@ import presets from "../presets.json";
|
||||||
export interface CodeOptions {
|
export interface CodeOptions {
|
||||||
minify?: boolean,
|
minify?: boolean,
|
||||||
directStart?: boolean,
|
directStart?: boolean,
|
||||||
|
startSuperSpeed?: boolean,
|
||||||
enableBreakpoints?: boolean
|
enableBreakpoints?: boolean
|
||||||
asciiView?: boolean
|
asciiView?: boolean
|
||||||
}
|
}
|
||||||
|
|
@ -26,7 +27,7 @@ const CodeInput = ({input: [code, options], setInput}: CodeInputProps) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="bf-input">
|
<div className="bf-input">
|
||||||
<div>
|
<div className="code-options-wrapper">
|
||||||
<div>
|
<div>
|
||||||
<label htmlFor="bf-input-fontsize-range">Font Size</label>
|
<label htmlFor="bf-input-fontsize-range">Font Size</label>
|
||||||
<input type="range" id="bf-input-fontsize-range" onChange={v => setFontSize(+v.target.value)}/>
|
<input type="range" id="bf-input-fontsize-range" onChange={v => setFontSize(+v.target.value)}/>
|
||||||
|
|
@ -35,6 +36,8 @@ const CodeInput = ({input: [code, options], setInput}: CodeInputProps) => {
|
||||||
<CodeOption displayName="Minify Code" name="minify" options={options} onChange={changeHandler}/>
|
<CodeOption displayName="Minify Code" name="minify" options={options} onChange={changeHandler}/>
|
||||||
<CodeOption displayName="Start Directly" name="directStart" options={options}
|
<CodeOption displayName="Start Directly" name="directStart" options={options}
|
||||||
onChange={changeHandler}/>
|
onChange={changeHandler}/>
|
||||||
|
<CodeOption displayName="Start in blocking mode" name="startSuperSpeed" options={options}
|
||||||
|
onChange={changeHandler}/>
|
||||||
<CodeOption displayName="Breakpoints (•)" name="enableBreakpoints" options={options}
|
<CodeOption displayName="Breakpoints (•)" name="enableBreakpoints" options={options}
|
||||||
onChange={changeHandler}/>
|
onChange={changeHandler}/>
|
||||||
<CodeOption displayName="Show ASCII in memory" name="asciiView" options={options}
|
<CodeOption displayName="Show ASCII in memory" name="asciiView" options={options}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import React, {useContext, useRef, useState} from 'react';
|
import React, {useContext, useRef, useState} from 'react';
|
||||||
import Interpreter from "../brainfuck/Interpreter";
|
import Interpreter from "../brainfuck/Interpreter";
|
||||||
import {OptionContext} from "../App";
|
import {OptionContext} from "./App";
|
||||||
|
|
||||||
const MAX_TABLE_COLUMNS = 20;
|
const MAX_TABLE_COLUMNS = 20;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,12 +2,13 @@ import React, {useCallback, useContext, useEffect, useRef, useState} from 'react
|
||||||
import Interpreter from "../brainfuck/Interpreter";
|
import Interpreter from "../brainfuck/Interpreter";
|
||||||
import CodeDisplay from "./CodeDisplay";
|
import CodeDisplay from "./CodeDisplay";
|
||||||
import RunDisplay from "./RunDisplay";
|
import RunDisplay from "./RunDisplay";
|
||||||
import {OptionContext} from "../App";
|
import {OptionContext} from "./App";
|
||||||
|
|
||||||
|
|
||||||
interface RunInfoProps {
|
interface RunInfoProps {
|
||||||
code: string,
|
running: boolean,
|
||||||
setRunning: (running: boolean) => void,
|
setRunning: (running: boolean) => void,
|
||||||
running: boolean
|
code: string,
|
||||||
outHandler: (char: number) => void,
|
outHandler: (char: number) => void,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -41,7 +42,11 @@ const Runner = ({setRunning, running, outHandler, code}: RunInfoProps) => {
|
||||||
|
|
||||||
const startHandler = useCallback(() => {
|
const startHandler = useCallback(() => {
|
||||||
if (options.directStart) {
|
if (options.directStart) {
|
||||||
setSpeed(100);
|
if (options.startSuperSpeed) {
|
||||||
|
setSpeed(-1);
|
||||||
|
} else {
|
||||||
|
setSpeed(100);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
setSpeed(0);
|
setSpeed(0);
|
||||||
}
|
}
|
||||||
|
|
@ -72,20 +77,35 @@ const Runner = ({setRunning, running, outHandler, code}: RunInfoProps) => {
|
||||||
rerender();
|
rerender();
|
||||||
}, [interpreter, startTime]);
|
}, [interpreter, startTime]);
|
||||||
|
|
||||||
|
const runBlocking = useCallback(() => {
|
||||||
|
try {
|
||||||
|
while (speed === -1 && !interpreter?.reachedEnd) {
|
||||||
|
interpreter?.next();
|
||||||
|
}
|
||||||
|
setSpeed(0);
|
||||||
|
setInfo(`Finished Execution. Took ${(Date.now() - startTime) / 1000}s`)
|
||||||
|
} catch (e) {
|
||||||
|
setInfo(e.message);
|
||||||
|
setSpeed(0);
|
||||||
|
}
|
||||||
|
}, [speed, interpreter, startTime]);
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (running) {
|
if (running) {
|
||||||
if (speed === 0) {
|
if (speed === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const interval = setInterval(() => {
|
if (speed > 0) {
|
||||||
nextHandler();
|
const interval = setInterval(() => {
|
||||||
}, 1000 / (speed * 10));
|
nextHandler();
|
||||||
|
}, 1000 / (speed * 10));
|
||||||
return () => clearInterval(interval);
|
return () => clearInterval(interval);
|
||||||
|
}
|
||||||
|
runBlocking();
|
||||||
}
|
}
|
||||||
}, [running, nextHandler, speed]);
|
}, [runBlocking, running, nextHandler, speed]);
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="bf-run">
|
<div className="bf-run">
|
||||||
|
|
@ -96,9 +116,9 @@ const Runner = ({setRunning, running, outHandler, code}: RunInfoProps) => {
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
<div>
|
<div>
|
||||||
{running && <button onClick={stopHandler}>Back</button>}
|
{running && <button className="run-button" onClick={stopHandler}>Back</button>}
|
||||||
<button onClick={startHandler}>{running ? "Restart" : "Start"}</button>
|
<button className="run-button" onClick={startHandler}>{running ? "Restart" : "Start"}</button>
|
||||||
{running && <button onClick={nextHandler}>Next</button>}
|
{running && <button className="run-button" onClick={nextHandler}>Next</button>}
|
||||||
</div>
|
</div>
|
||||||
{
|
{
|
||||||
running && interpreter &&
|
running && interpreter &&
|
||||||
|
|
@ -126,7 +146,7 @@ interface SpeedControlProps {
|
||||||
const SpeedControl = ({speed, setSpeed}: SpeedControlProps) => {
|
const SpeedControl = ({speed, setSpeed}: SpeedControlProps) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div className="speed-control-wrapper">
|
||||||
<label htmlFor="run-info-speed-range">Speed</label>
|
<label htmlFor="run-info-speed-range">Speed</label>
|
||||||
<input type="range" id="run-info-speed-range" value={speed}
|
<input type="range" id="run-info-speed-range" value={speed}
|
||||||
onChange={e => setSpeed(+e.target.value)}/>
|
onChange={e => setSpeed(+e.target.value)}/>
|
||||||
|
|
@ -139,6 +159,10 @@ const SpeedControl = ({speed, setSpeed}: SpeedControlProps) => {
|
||||||
<button onClick={() => setSpeed(s => s === 100 ? 100 : s + 1)}
|
<button onClick={() => setSpeed(s => s === 100 ? 100 : s + 1)}
|
||||||
className="small-speed-button">+</button>
|
className="small-speed-button">+</button>
|
||||||
</span>
|
</span>
|
||||||
|
<span>
|
||||||
|
<label>Superspeed Mode (blocking)</label>
|
||||||
|
<input id="superspeed-mode-check" type="checkbox" checked={speed === -1} onChange={() => setSpeed(-1)}/>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
import './index.css';
|
import './index.css';
|
||||||
import App from './App';
|
import App from './components/App';
|
||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
<React.StrictMode>
|
<React.StrictMode>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue