so much meaningless stuff :]
This commit is contained in:
parent
0f348a7e07
commit
83dc103386
2 changed files with 105 additions and 28 deletions
28
src/App.css
28
src/App.css
|
@ -35,19 +35,21 @@ html {
|
||||||
display: grid;
|
display: grid;
|
||||||
width: 50%;
|
width: 50%;
|
||||||
grid-template-areas: "ops stack" "states states";
|
grid-template-areas: "ops stack" "states states";
|
||||||
grid-template-rows: max-content;
|
grid-template-columns: 50% 50%;
|
||||||
|
grid-template-rows: 50% 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* .ops,
|
.ops,
|
||||||
.states {
|
.stack {
|
||||||
width: 50vw;
|
overflow: scroll;
|
||||||
} */
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.ops {
|
.ops {
|
||||||
/* position: fixed; */
|
/* position: fixed; */
|
||||||
/* top: 0;
|
/* top: 0;
|
||||||
left: 50%; */
|
left: 50%; */
|
||||||
min-height: 25vh;
|
/* height: 100%; */
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
background-color: var(--bg);
|
background-color: var(--bg);
|
||||||
border: 1px solid var(--fg);
|
border: 1px solid var(--fg);
|
||||||
|
@ -66,6 +68,7 @@ html {
|
||||||
border-bottom: 1px solid var(--fg);
|
border-bottom: 1px solid var(--fg);
|
||||||
/* margin: 5px; */
|
/* margin: 5px; */
|
||||||
padding-left: 5px;
|
padding-left: 5px;
|
||||||
|
background-color: var(--bg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* .state > * {
|
/* .state > * {
|
||||||
|
@ -79,9 +82,9 @@ html {
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.stack::before {
|
/* .stack::before {
|
||||||
content: "Stack: ";
|
content: "Stack: ";
|
||||||
}
|
} */
|
||||||
|
|
||||||
/* later i can do .op.active and .state.active if necessary */
|
/* later i can do .op.active and .state.active if necessary */
|
||||||
.active {
|
.active {
|
||||||
|
@ -92,15 +95,24 @@ html {
|
||||||
background-color: var(--accent);
|
background-color: var(--accent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.jumped-from {
|
||||||
|
backdrop-filter: brightness(1.8);
|
||||||
|
}
|
||||||
|
|
||||||
.op {
|
.op {
|
||||||
display: flex;
|
display: flex;
|
||||||
white-space: pre;
|
white-space: pre;
|
||||||
|
overflow: clip;
|
||||||
}
|
}
|
||||||
|
|
||||||
.output {
|
.output {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.just-popped {
|
||||||
|
backdrop-filter: hue-rotate(180deg);
|
||||||
|
}
|
||||||
|
|
||||||
/* https://www.joshwcomeau.com/css/custom-css-reset/ */
|
/* https://www.joshwcomeau.com/css/custom-css-reset/ */
|
||||||
/*
|
/*
|
||||||
1. Use a more-intuitive box-sizing model.
|
1. Use a more-intuitive box-sizing model.
|
||||||
|
|
105
src/App.tsx
105
src/App.tsx
|
@ -15,6 +15,8 @@ export default function App() {
|
||||||
let [activeStateIdx, setActiveStateIdx] = useState(0);
|
let [activeStateIdx, setActiveStateIdx] = useState(0);
|
||||||
let parsed = somes(input.split(/[^a-z0-9-]+/).map(parse_op));
|
let parsed = somes(input.split(/[^a-z0-9-]+/).map(parse_op));
|
||||||
let states = steps(INITIAL_STATE, parsed);
|
let states = steps(INITIAL_STATE, parsed);
|
||||||
|
let state = states[activeStateIdx] ?? INITIAL_STATE;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<TextArea
|
<TextArea
|
||||||
|
@ -38,11 +40,11 @@ type Op =
|
||||||
<div className="info">
|
<div className="info">
|
||||||
<Ops
|
<Ops
|
||||||
parsed={parsed}
|
parsed={parsed}
|
||||||
ip={states[activeStateIdx]?.ip ?? 0}
|
state={state}
|
||||||
// // hack
|
// // hack
|
||||||
// top={document.getElementById("input")?.clientHeight ?? 0}
|
// top={document.getElementById("input")?.clientHeight ?? 0}
|
||||||
/>
|
/>
|
||||||
<Stack stack={states[activeStateIdx]?.stack ?? []} />
|
<Stack state={state} just_popped={state.just_popped} />
|
||||||
<States
|
<States
|
||||||
states={states}
|
states={states}
|
||||||
activeStateIdx={activeStateIdx}
|
activeStateIdx={activeStateIdx}
|
||||||
|
@ -55,18 +57,24 @@ type Op =
|
||||||
|
|
||||||
function Ops({
|
function Ops({
|
||||||
parsed,
|
parsed,
|
||||||
ip,
|
state,
|
||||||
}: // top,
|
}: // top,
|
||||||
{
|
{
|
||||||
parsed: Op[];
|
parsed: Op[];
|
||||||
ip: number;
|
state: State;
|
||||||
// top: number;
|
// top: number;
|
||||||
}): JSX.Element {
|
}): JSX.Element {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="ops"
|
className="ops"
|
||||||
children={parsed.map((op, i) => (
|
children={parsed.map((op, i) => (
|
||||||
<Op op={op} highlighted={i == ip} num={i} key={i} />
|
<Op
|
||||||
|
op={op}
|
||||||
|
highlighted={i == state.ip}
|
||||||
|
jumped_from={i == state.jumped_from}
|
||||||
|
num={i}
|
||||||
|
key={i}
|
||||||
|
/>
|
||||||
))}
|
))}
|
||||||
// style={{
|
// style={{
|
||||||
// top: `${top + 5}px`,
|
// top: `${top + 5}px`,
|
||||||
|
@ -79,15 +87,19 @@ function Op({
|
||||||
op,
|
op,
|
||||||
highlighted,
|
highlighted,
|
||||||
num,
|
num,
|
||||||
|
jumped_from,
|
||||||
...props
|
...props
|
||||||
}: {
|
}: {
|
||||||
op: Op;
|
op: Op;
|
||||||
num: number;
|
num: number;
|
||||||
highlighted: boolean;
|
highlighted: boolean;
|
||||||
|
jumped_from: boolean;
|
||||||
}): JSX.Element {
|
}): JSX.Element {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={`op ${highlighted ? "active" : ""}`}
|
className={`op ${highlighted ? "active" : ""} ${
|
||||||
|
jumped_from ? "jumped-from" : ""
|
||||||
|
}`}
|
||||||
key={num}
|
key={num}
|
||||||
{...props}
|
{...props}
|
||||||
>
|
>
|
||||||
|
@ -146,23 +158,55 @@ function State({
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function Stack({ stack, ...props }: { stack: number[] }): JSX.Element {
|
function Stack({
|
||||||
let ns = [...stack];
|
state,
|
||||||
|
just_popped,
|
||||||
|
...props
|
||||||
|
}: {
|
||||||
|
state: State;
|
||||||
|
just_popped?: number[];
|
||||||
|
}): JSX.Element {
|
||||||
|
let ns = [...state.stack];
|
||||||
ns.reverse();
|
ns.reverse();
|
||||||
return (
|
console.log(just_popped);
|
||||||
<div
|
let children = (just_popped ?? []).map((just_popped, i) => (
|
||||||
className="stack"
|
<StackItem
|
||||||
children={ns.map((item, i) => (
|
item={just_popped}
|
||||||
<StackItem item={item} key={i} />
|
key={-(i + 1)}
|
||||||
))}
|
highlighted={false}
|
||||||
{...props}
|
just_popped={true}
|
||||||
/>
|
/>
|
||||||
);
|
));
|
||||||
|
ns.map((item, i) => (
|
||||||
|
<StackItem
|
||||||
|
item={item}
|
||||||
|
key={i}
|
||||||
|
highlighted={
|
||||||
|
(state.just_pushed && i == 0) || (state.just_swapped && i < 2)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
)).forEach(child => children.push(child));
|
||||||
|
|
||||||
|
return <div className="stack" children={children} {...props} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
function StackItem({ item, ...props }: { item: number }): JSX.Element {
|
function StackItem({
|
||||||
|
item,
|
||||||
|
highlighted = false,
|
||||||
|
just_popped = false,
|
||||||
|
...props
|
||||||
|
}: {
|
||||||
|
item: number;
|
||||||
|
highlighted: boolean;
|
||||||
|
just_popped?: boolean;
|
||||||
|
}): JSX.Element {
|
||||||
return (
|
return (
|
||||||
<div className="stack-item" {...props}>
|
<div
|
||||||
|
className={`stack-item ${highlighted ? "active" : ""} ${
|
||||||
|
just_popped ? "just-popped" : ""
|
||||||
|
}`}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
{item}
|
{item}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -252,12 +296,19 @@ type State = {
|
||||||
ip: number;
|
ip: number;
|
||||||
stack: number[];
|
stack: number[];
|
||||||
output: number[];
|
output: number[];
|
||||||
|
jumped_from: Option<number>;
|
||||||
|
just_pushed: boolean;
|
||||||
|
just_swapped: boolean;
|
||||||
|
just_popped?: number[];
|
||||||
};
|
};
|
||||||
|
|
||||||
const INITIAL_STATE: State = {
|
const INITIAL_STATE: State = {
|
||||||
ip: 0,
|
ip: 0,
|
||||||
stack: [],
|
stack: [],
|
||||||
output: [],
|
output: [],
|
||||||
|
jumped_from: undefined,
|
||||||
|
just_pushed: false,
|
||||||
|
just_swapped: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
function steps(state: State, ops: Op[], limit = 300, num_steps = 0): State[] {
|
function steps(state: State, ops: Op[], limit = 300, num_steps = 0): State[] {
|
||||||
|
@ -273,7 +324,11 @@ function steps(state: State, ops: Op[], limit = 300, num_steps = 0): State[] {
|
||||||
// all but jmp advance the ip by one
|
// all but jmp advance the ip by one
|
||||||
// cmp: lt => -1, eq => 0, gt => 1
|
// cmp: lt => -1, eq => 0, gt => 1
|
||||||
function step(state: State, op: Op): State {
|
function step(state: State, op: Op): State {
|
||||||
let ns = JSON.parse(JSON.stringify(state));
|
let ns = JSON.parse(JSON.stringify(state)) as State;
|
||||||
|
ns.jumped_from = ns.ip;
|
||||||
|
ns.just_pushed = false;
|
||||||
|
ns.just_swapped = false;
|
||||||
|
ns.just_popped = undefined;
|
||||||
ns.ip++;
|
ns.ip++;
|
||||||
|
|
||||||
function binary_op(
|
function binary_op(
|
||||||
|
@ -287,7 +342,6 @@ function step(state: State, op: Op): State {
|
||||||
|
|
||||||
if (typeof op == "number") {
|
if (typeof op == "number") {
|
||||||
ns.stack.push(op);
|
ns.stack.push(op);
|
||||||
return ns;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
|
@ -312,6 +366,7 @@ function step(state: State, op: Op): State {
|
||||||
}
|
}
|
||||||
case "jmp":
|
case "jmp":
|
||||||
ns.ip--;
|
ns.ip--;
|
||||||
|
// ns.jumped_from = ns.ip;
|
||||||
ns.ip += ns.stack.pop() ?? 1;
|
ns.ip += ns.stack.pop() ?? 1;
|
||||||
break;
|
break;
|
||||||
case "dup": {
|
case "dup": {
|
||||||
|
@ -335,11 +390,21 @@ function step(state: State, op: Op): State {
|
||||||
if (typeof a == "undefined" || typeof b == "undefined") {
|
if (typeof a == "undefined" || typeof b == "undefined") {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
ns.just_swapped = true;
|
||||||
ns.stack.push(a, b);
|
ns.stack.push(a, b);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ns.stack.length > state.stack.length) {
|
||||||
|
ns.just_pushed = true;
|
||||||
|
} else if (ns.stack.length < state.stack.length) {
|
||||||
|
ns.just_popped = state.stack.slice(ns.stack.length - 1).reverse();
|
||||||
|
if (state.stack.length - ns.stack.length == 1) {
|
||||||
|
ns.just_pushed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return ns;
|
return ns;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue