Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: use the interpreter to evaluate top-level definitions #1169

Merged
merged 2 commits into from
Apr 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion argocd/base/statefulset.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ spec:
# Note: use the *dev* version of the package here, so that
# PRs can deploy `primer-service` container images that have
# not yet been merged to `primer` `main`.
image: ghcr.io/hackworthltd/primer-service-dev:git-17171c78abafc8c46e2eea69109320f90e06a6ab
image: ghcr.io/hackworthltd/primer-service-dev:git-e692f818faee0e4005c24ea1f87c1464000a91ca
ports:
- containerPort: 8081
env:
Expand Down
66 changes: 33 additions & 33 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

# Note: don't override any of primer's Nix flake inputs, or else
# we won't hit its binary cache.
primer.url = github:hackworthltd/primer/17171c78abafc8c46e2eea69109320f90e06a6ab;
primer.url = github:hackworthltd/primer/e692f818faee0e4005c24ea1f87c1464000a91ca;

flake-parts.url = "github:hercules-ci/flake-parts";
};
Expand Down
6 changes: 5 additions & 1 deletion orval.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ import { defineConfig } from "orval";
// This lists the operation IDs for such requests.
// We configure Orval to generate simple `useQuery`-based code, as it would for a GET request,
// rather than its default `useMutation` approach for POSTs.
const getStylePostRequests = ["getAvailableActions", "eval-full"];
const getStylePostRequests = [
"getAvailableActions",
"eval-full",
"eval-bounded-interp",
];
const useQueryPost: {
[key: string]: OperationOptions;
} = Object.assign(
Expand Down
33 changes: 33 additions & 0 deletions src/components/EvalBoundedInterp/EvalBoundedInterp.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { Meta, StoryObj } from "@storybook/react";
import { tree3 } from "../examples/trees";

import { EvalBoundedInterp } from "./";

const meta: Meta<typeof EvalBoundedInterp> = {
title: "Application/Component Library/EvalBoundedInterp",
component: EvalBoundedInterp,
decorators: [
(Story) => (
<div className="h-screen">
<Story />
</div>
),
],
};

export default meta;
type Story = StoryObj<typeof EvalBoundedInterp>;

export const Default: Story = {
args: {
moduleName: ["Primer", "Examples"],
evalBoundedInterp: {
request: () => {
return;
},
result: { tag: "EvalBoundedInterpRespNormal", contents: tree3 },
},
level: "Expert",
defs: ["footballGame", "whatsopposite"],
},
};
105 changes: 105 additions & 0 deletions src/components/EvalBoundedInterp/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import { useState } from "react";
import { NodeChange, ReactFlowProvider, useReactFlow } from "reactflow";
import { EvalBoundedInterpResp, GlobalName, Level } from "@/primer-api";
import { SelectMenu, TreeReactFlowOne } from "@/components";
import {
TreeReactFlowOneProps,
defaultTreeReactFlowProps,
} from "../TreeReactFlow";

export type EvalBoundedInterpProps = {
moduleName: string[];
evalBoundedInterp: {
request: (baseName: string | undefined) => void;
result?: EvalBoundedInterpResp;
};
level: Level;
defs: string[];
initialEvalDef: string | undefined;
extraTreeProps: Partial<TreeReactFlowOneProps>;
};

const Evaluated = (p: {
defName: GlobalName;
evaluated?: EvalBoundedInterpResp;
level: Level;
extraTreeProps: Partial<TreeReactFlowOneProps>;
}) => {
const padding = 1.0;
const { fitView } = useReactFlow();
const onNodesChange = (_: NodeChange[]) => {
fitView({ padding });
};
const resultTree = () => {
switch (p?.evaluated?.tag) {
case "EvalBoundedInterpRespNormal":
return { tree: p.evaluated.contents };
default:
// This should be some indication of an error having occurred,
// but our UI is a bit too limited for that at the moment.
return {};
}
};

return (
<TreeReactFlowOne
{...defaultTreeReactFlowProps}
{...resultTree()}
level={p.level}
zoomBarProps={{ padding }}
onNodesChange={onNodesChange}
fitViewOptions={{ padding }}
{...p.extraTreeProps}
/>
);
};

const disableEval = "<disabled>";

// We only offer to evaluate the definitions in the "main" module
export const EvalBoundedInterp = ({
defs,
evalBoundedInterp,
moduleName,
level,
initialEvalDef,
extraTreeProps,
}: EvalBoundedInterpProps): JSX.Element => {
const [evalDef, setEvalDef0] = useState(initialEvalDef ?? disableEval);
const setEvalDef = (e: string) => {
setEvalDef0(e);
evalBoundedInterp.request(e === disableEval ? undefined : e);
};
return (
<div className="flex h-full flex-col overflow-auto">
<div className="mx-2">
<SelectMenu
label="Definition"
selected={evalDef}
options={[disableEval].concat(defs)}
optionType="code"
onChange={(selection: string) => setEvalDef(selection)}
/>
</div>
{evalDef !== disableEval && (
<>
<div className="grow">
<ReactFlowProvider>
<Evaluated
key={evalDef}
defName={{ qualifiedModule: moduleName, baseName: evalDef }}
{...(evalBoundedInterp.result
? { evaluated: evalBoundedInterp.result }
: {})}
level={level}
extraTreeProps={extraTreeProps}
/>
</ReactFlowProvider>
</div>
</>
)}
</div>
);
};

export default EvalBoundedInterp;
1 change: 1 addition & 0 deletions src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export { default as CreateDefModal } from "./CreateDefModal";
export { default as DefsToolbar } from "./DefsToolbar";
export { default as Edit } from "./Edit";
export { default as Error } from "./Error";
export { default as EvalBoundedInterp } from "./EvalBoundedInterp";
export { default as EvalFull } from "./EvalFull";
export { default as GroupedButtonList } from "./GroupedButtonList";
export { default as NoMatch } from "./NoMatch";
Expand Down
11 changes: 11 additions & 0 deletions src/primer-api/model/evalBoundedInterpParams.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/**
* Generated by orval v6.26.0 🍺
* Do not edit manually.
* Primer backend API
* A backend service implementing a pedagogic functional programming language.
* OpenAPI spec version: 0.7
*/

export type EvalBoundedInterpParams = {
timeoutMicroseconds?: number;
};
14 changes: 14 additions & 0 deletions src/primer-api/model/evalBoundedInterpResp.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/**
* Generated by orval v6.26.0 🍺
* Do not edit manually.
* Primer backend API
* A backend service implementing a pedagogic functional programming language.
* OpenAPI spec version: 0.7
*/
import type { EvalBoundedInterpRespOneOf } from './evalBoundedInterpRespOneOf';
import type { EvalBoundedInterpRespOneOfThree } from './evalBoundedInterpRespOneOfThree';
import type { EvalBoundedInterpRespOneOfFive } from './evalBoundedInterpRespOneOfFive';
import type { EvalBoundedInterpRespOneOfSeven } from './evalBoundedInterpRespOneOfSeven';
import type { EvalBoundedInterpRespOneOfNine } from './evalBoundedInterpRespOneOfNine';

export type EvalBoundedInterpResp = EvalBoundedInterpRespOneOf | EvalBoundedInterpRespOneOfThree | EvalBoundedInterpRespOneOfFive | EvalBoundedInterpRespOneOfSeven | EvalBoundedInterpRespOneOfNine;
12 changes: 12 additions & 0 deletions src/primer-api/model/evalBoundedInterpRespOneOf.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/**
* Generated by orval v6.26.0 🍺
* Do not edit manually.
* Primer backend API
* A backend service implementing a pedagogic functional programming language.
* OpenAPI spec version: 0.7
*/
import type { EvalBoundedInterpRespOneOfTag } from './evalBoundedInterpRespOneOfTag';

export type EvalBoundedInterpRespOneOf = {
tag: EvalBoundedInterpRespOneOfTag;
};
Loading
Loading