esolang/engines/brainfuck/renderer.tsx
Nilay Majorwar 01ba292b9f 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
2021-12-14 22:30:41 +05:30

61 lines
1.6 KiB
TypeScript

import { CSSProperties } from "react";
import { RendererProps } from "../types";
import { BFRS } from "./constants";
const styles: { [k: string]: CSSProperties } = {
container: {
padding: 10,
height: "100%",
display: "flex",
flexWrap: "wrap",
alignContent: "flex-start",
overflowY: "auto",
},
cell: {
// Sizing
width: "12%",
height: "50px",
margin: "5px 0.25%",
padding: 12,
// Center-align values
display: "flex",
justifyContent: "center",
alignItems: "center",
// Border and colors
border: "1px solid gray",
borderRadius: 5,
background: "#394B59",
color: "#E1E8ED",
},
activeCell: {
background: "#CED9E0",
color: "#182026",
},
};
/** Component for displaying a single tape cell */
const Cell = ({ value, active }: { value: number; active: boolean }) => {
const cellStyle = { ...styles.cell, ...(active ? styles.activeCell : {}) };
return <div style={cellStyle}>{value}</div>;
};
/** Renderer for Brainfuck */
export const Renderer = ({ state }: RendererProps<BFRS>) => {
/** Serialize tape from object format into linear array */
const serializeTapeObj = (tape: BFRS["tape"]) => {
const cellIdxs = Object.keys(tape).map((s) => parseInt(s, 10));
const maxCellIdx = Math.max(15, ...cellIdxs);
const linearTape = Array(maxCellIdx + 1).fill(0);
cellIdxs.forEach((i) => (linearTape[i] = tape[i] || 0));
return linearTape;
};
return (
<div style={styles.container}>
{serializeTapeObj(state?.tape || {}).map((num, i) => (
<Cell value={num} key={i} active={(state?.pointer || 0) === i} />
))}
</div>
);
};