Basis support for inspecting types

This commit is contained in:
Ayaz Hafiz 2023-07-16 20:39:27 -05:00
parent 8b7823a237
commit 9e055dcf53
No known key found for this signature in database
GPG key ID: 0E2A37416A25EF58
8 changed files with 753 additions and 7 deletions

View file

@ -0,0 +1,53 @@
import { AllEvents } from "../schema";
export type EventsOk = {
kind: "ok";
events: AllEvents;
};
export type EventsErr = {
kind: "err";
error: string;
};
export type LoadedEvents = EventsOk | EventsErr;
interface FileInputProps {
setResult(result: LoadedEvents): void;
}
export default function FileInput({ setResult }: FileInputProps) {
async function setFile(e: React.ChangeEvent<HTMLInputElement>) {
e.preventDefault();
const files = e.target.files;
if (!files) {
setResult({ kind: "err", error: "Please choose a checkmate file." });
return;
}
const file = files[0];
const buf = await file.arrayBuffer();
try {
const events: AllEvents = JSON.parse(new TextDecoder().decode(buf));
setResult({ kind: "ok", events });
} catch (e) {
setResult({ kind: "err", error: "Invalid checkmate file." });
return;
}
}
return (
<div>
<label htmlFor="small-file-input" className="sr-only">
Choose file
</label>
<input
type="file"
name="small-file-input"
id="small-file-input"
onChange={(e) => setFile(e)}
className="block w-full border border-gray-200 shadow-sm rounded-md text-sm
file:bg-roc-purple-bg file:border-0 file:mr-4 file:py-2 file:px-4"
></input>
</div>
);
}

View file

@ -0,0 +1,107 @@
import React from "react";
import { AllEvents, Event, UnificationMode } from "../schema";
import { Refine } from "../utils/refine";
import clsx from "clsx";
interface UiProps {
events: AllEvents;
}
export default function Ui({ events }: UiProps): JSX.Element {
return (
<div className="font-mono">
<EventList root events={events}></EventList>
</div>
);
}
interface EventListProps {
events: Event[];
root?: boolean;
}
function EventList({ events, root }: EventListProps): JSX.Element {
return (
<ul className={clsx(root ? "ml-2 mt-4" : "ml-[1.5em]", "relative")}>
{events.map((event, i) => (
<li key={i} className="mt-2">
<OneEvent event={event} />
</li>
))}
</ul>
);
}
interface OneEventProps {
event: Event;
}
function OneEvent({ event }: OneEventProps): JSX.Element {
switch (event.type) {
case "Unification":
return <Unification event={event} />;
case "VariableUnified":
return <></>;
case "VariableSetDescriptor":
return <></>;
}
}
const DROPDOWN_CLOSED = "▶";
const DROPDOWN_OPEN = "▼";
const UN_UNKNOWN = "❔";
const UN_SUCCESS = "✅";
const UN_FAILURE = "❌";
function Unification({
event,
}: {
event: Refine<Event, "Unification">;
}): JSX.Element {
const { left, right, mode, subevents, success } = event;
const [isOpen, setIsOpen] = React.useState(false);
const result = success ? UN_SUCCESS : UN_FAILURE;
const modeIcon = <UnificationModeIcon mode={mode} />;
const dropdownIcon = isOpen ? DROPDOWN_OPEN : DROPDOWN_CLOSED;
const headLineIcon = isOpen ? UN_UNKNOWN : result;
const headLine = (
<button onClick={() => setIsOpen(!isOpen)} className="w-full text-left">
<span className="text-slate-400 mr-2">{dropdownIcon}</span>
{headLineIcon} {left} {modeIcon} {right}
</button>
);
if (!isOpen) {
return <div className="opacity-60">{headLine}</div>;
} else {
const dropdownTransparent = (
<span className="text-transparent mr-2">{dropdownIcon}</span>
);
return (
<div>
<div>{headLine}</div>
<EventList events={subevents} />
<div className="mt-2">
{dropdownTransparent}
{result} {left} {modeIcon} {right}
</div>
</div>
);
}
}
function UnificationModeIcon({ mode }: { mode: UnificationMode }): JSX.Element {
switch (mode.type) {
case "Eq":
return <>~</>;
case "Present":
return <>+=</>;
case "LambdaSetSpecialization":
return <>|~|</>;
}
}