/src/components/App.js
https://gitlab.com/bxt/brainfuck-debugger · JavaScript · 117 lines · 102 code · 15 blank · 0 comment · 1 complexity · 08a74dad61a5a3e25a525c871f4c153d MD5 · raw file
- import React from 'react'
- import Box from './Box'
- import Button from './Button'
- import CodeEditor from './CodeEditor'
- import CodeViewer from './CodeViewer'
- import Extra from './Extra'
- import InputEditor from './InputEditor'
- import InputViewer from './InputViewer'
- import MemoryViewer from './MemoryViewer'
- import OutputViewer from './OutputViewer'
- import Player from './Player'
- import Step from './Step'
- import { isDone, restart, run, step } from '../brainfuck'
- import type { Machine } from '../brainfuck'
- import sampleProgram from '../sampleProgram'
- export default class App extends React.Component {
- state = {
- input: `!dlroW olleH\nstep on no pets\nfoo\n`,
- inputPointer: 0,
- instructionPointer: 0,
- instructions: sampleProgram,
- memory: [0],
- memoryPointer: 0,
- output: '',
- running: false,
- }
- modifyMachineState(f: Machine => void) {
- this.setState((oldState) => {
- let {running, ...machine} = oldState
- void running // unused var bug in linter
- f(machine)
- return {running: !isDone(machine), ...machine}
- })
- }
- handleInputChange = (value: string) => {
- this.setState({input: value})
- }
- handleInstructionsChange = (value: string) => {
- this.setState({instructions: value})
- }
- start = () => {
- this.modifyMachineState(restart)
- }
- step = (n: number) => {
- this.modifyMachineState(machine => {
- for (let i = 0; i < n; i++) step(machine)
- })
- }
- finish = () => {
- this.modifyMachineState((m) => { run(m) })
- }
- abort = () => {
- this.setState({running: false})
- }
- render() {
- const {
- input,
- inputPointer,
- instructionPointer,
- instructions,
- memory,
- memoryPointer,
- output,
- running,
- } = this.state
- const instructionPane = running
- ? (
- <Box>
- <Button onClick={this.finish}>finish</Button>
- <Step onStep={this.step} />
- <Player onTick={() => this.step(1)} />
- <Button onClick={this.abort}>abort</Button>
- <CodeViewer {...{instructionPointer, instructions}} />
- </Box>
- )
- : (
- <Box>
- <Button onClick={this.start}>start</Button>
- <CodeEditor {...{instructions}} onChange={this.handleInstructionsChange} />
- </Box>
- )
- const inputPane = running
- ? <InputViewer {...{input, inputPointer}} />
- : <InputEditor {...{input}} onChange={this.handleInputChange}/>
- return (
- <div>
- {instructionPane}
- <Box>
- <MemoryViewer {...{memory, memoryPointer}} />
- </Box>
- <Box>
- {inputPane}
- </Box>
- <Box>
- <OutputViewer {...{output}} />
- </Box>
- <br style={{clear: 'left'}} />
- <Extra {...{instructions}} />
- </div>
- )
- }
- }