Skip to content

Commit

Permalink
Examples: move examples into a astro data collection
Browse files Browse the repository at this point in the history
  • Loading branch information
MrTipson committed Sep 14, 2024
1 parent 59700b7 commit 552cfe5
Show file tree
Hide file tree
Showing 12 changed files with 211 additions and 205 deletions.
15 changes: 8 additions & 7 deletions src/components/Machine.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { useState } from "react";
import { stg_machine } from "@/stgmachine/machine";
import { sum_prg } from "@/stglang/test";
import ProgramView from "@/components/ProgramView";
import StackView from "@/components/StackView";
import HeapView from "@/components/HeapView";
Expand All @@ -13,6 +12,8 @@ import {
import { Toaster } from "@/components/ui/toaster";
import { useMediaQuery } from "@/hooks/use-media-query";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { build_ast } from "@/stglang/ASTBuilder";
import type { InferEntrySchema } from "astro:content";

export type STGSettings = {
garbage_collection: boolean,
Expand All @@ -22,11 +23,9 @@ export type STGSettings = {
run_limit: number
}

export const default_program = sum_prg;

export default function Machine() {
export default function Machine({ examples, default_program }: { examples: InferEntrySchema<"examples">[], default_program: string }) {
// set machine is called *only* when a new program is loaded, but will be mutated while stepping
const [machine, setMachine] = useState<stg_machine>(() => new stg_machine(default_program, false, true));
const [machine, setMachine] = useState<stg_machine>(() => new stg_machine(build_ast(examples.find(x => x.name === default_program)?.code as string), false, true));
const [loaded, setLoaded] = useState(false);
const [step, setStepOriginal] = useState(Number(new URLSearchParams(location.search).get('step')) || 0);
const [breakpoints, setBreakpoints] = useState<Map<number, number>>(new Map());
Expand Down Expand Up @@ -100,7 +99,8 @@ export default function Machine() {
settings={settings} setSettings={setSettings}
breakpoints={breakpoints} setBreakpoints={setBreakpoints}
enteredThunks={enteredThunks} setEnteredThunks={setEnteredThunks}
isDesktop={isDesktop} className="w-full h-0 grow" />
isDesktop={isDesktop} className="w-full h-0 grow"
examples={examples} default_program={default_program} />
</TabsContent>
<TabsContent value="heap"><HeapView machine={machine} className="absolute w-full top-12 bottom-0" step={step} settings={settings} /></TabsContent>
<TabsContent value="stack" className="contents"><StackView machine={machine} className="w-full h-0 grow" /></TabsContent>
Expand All @@ -124,7 +124,8 @@ export default function Machine() {
settings={settings} setSettings={setSettings}
breakpoints={breakpoints} setBreakpoints={setBreakpoints}
enteredThunks={enteredThunks} setEnteredThunks={setEnteredThunks}
isDesktop={isDesktop} className="h-full" />
isDesktop={isDesktop} className="h-full"
examples={examples} default_program={default_program} />
</Panel>
<Handle withHandle />
{loaded &&
Expand Down
11 changes: 6 additions & 5 deletions src/components/ProgramView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,13 @@ import {
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import examples from "@/stglang/examples";
import { binding, case_eval, case_expr, FUN, identifier, let_expr, letrec_expr, literal, THUNK, type expression } from "@/stglang/types";
import { Separator } from "@/components/ui/separator";
import HelpPopover from "@/components/HelpPopover";
import type { STGSettings } from "@/components/Machine";
import SettingsMenu from "@/components/SettingsMenu";
import { default_program } from "@/components/Machine";
import { inflate, deflate } from 'pako';
import type { InferEntrySchema } from "astro:content";

function compress(txt: string) {
return btoa(Array.from(deflate(txt), (byte) => String.fromCodePoint(byte)).join(""));
Expand Down Expand Up @@ -55,7 +54,7 @@ function findExpression(lineStart: number, nextLineStart: number, expr: expressi
return undefined;
}

export default function ProgramView({ className, machine, setMachine, step, setStep, loaded, setLoaded, settings, setSettings, breakpoints, setBreakpoints, isDesktop, enteredThunks, setEnteredThunks }:
export default function ProgramView({ className, machine, setMachine, step, setStep, loaded, setLoaded, settings, setSettings, breakpoints, setBreakpoints, isDesktop, enteredThunks, setEnteredThunks, examples, default_program }:
{
className?: string,
machine: stg_machine,
Expand All @@ -71,16 +70,18 @@ export default function ProgramView({ className, machine, setMachine, step, setS
isDesktop: boolean,
enteredThunks: [number, number][],
setEnteredThunks: React.Dispatch<typeof enteredThunks>,
examples: InferEntrySchema<"examples">[],
default_program: string,
}) {
const [selected, setSelected] = useState<string>('Sum foldl');
const [selected, setSelected] = useState<string>(default_program);
const [programText, setProgramText] = useState(() => {
const searchParams = new URLSearchParams(location.search);
const programParam = searchParams.get('program');
if (programParam) {
setSelected('');
return decompress(programParam);
} else {
return String(default_program);
return examples.find(x => x.name === default_program)?.code as string;
}
});
const [error, setError] = useState<{ from: number, to: number, step: number } | undefined>(undefined);
Expand Down
7 changes: 7 additions & 0 deletions src/content/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,11 @@ export const collections = {
draft: z.boolean(),
}),
}),
'examples': defineCollection({
type: 'data',
schema: z.object({
name: z.string(),
code: z.string(),
}),
}),
};
4 changes: 2 additions & 2 deletions src/content/docs/mdtest.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ title: "Example with STG machine components"
description: jsx components? In my markdown?
draft: true
---
import examples from "@/stglang/examples";
import { getEntry } from "astro:content";

export const code = examples.find(x => x.name === "Partial application").code;
export const code = (await getEntry("examples", "partial-application")).data.code;

# Hello world
This is the first test of markdown based examples!
Expand Down
52 changes: 52 additions & 0 deletions src/content/examples/fib-zipWith.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@

name: Fibonacci zipWith
code: |2
data Number a = Num a
data Boolean = True | False
data List a = Nil | Cons a (List a)
nil = CON Nil
plusInt = FUN(x y ->
case x of {
Num i -> case y of {
Num j -> case i +# j of {
x -> let result = CON(Num x)
in result;
};
};
}
)
zipWith = FUN(f x y ->
case x of {
Nil -> nil;
Cons hx tx -> case y of {
Nil -> nil;
Cons hy ty -> let fxy = THUNK(f hx hy)
fxys = THUNK(zipWith f tx ty)
zippedList = CON(Cons fxy fxys)
in zippedList;
};
}
)
forcen = FUN(n list ->
case n ># 0 of {
False -> nil;
True -> case list of {
Nil -> nil;
Cons h t -> case h of {
x -> case n -# 1 of {
n -> case forcen n t of {
y -> let result = CON(Cons x y)
in result;
};
};
};
};
}
)
zero = CON(Num 0)
one = CON(Num 1)
fib = THUNK(letrec fib0 = CON(Cons zero fib1)
fib1 = CON(Cons one fib2)
fib2 = THUNK(zipWith plusInt fib0 fib1)
in fib2)
main = THUNK(forcen 10 fib)
36 changes: 36 additions & 0 deletions src/content/examples/map-laziness.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: Not so simple map
code: |2
data Number a = Num a
data List a = Nil | Cons a (List a)
nil = CON Nil
one = CON(Num 1)
two = CON(Num 2)
three = CON(Num 3)
plusOne = FUN(x ->
case x of {
Num i -> case i +# 1 of {
y -> let result = CON(Num y)
in result;
};
}
)
list1 = CON(Cons one nil)
list2 = CON(Cons two list1)
list3 = CON(Cons three list2)
map = FUN(f xs ->
case xs of {
Nil -> nil;
Cons h t -> let fh = THUNK(f h)
ft = THUNK(map f t)
result = CON(Cons fh ft)
in result;
})
last = FUN(xs ->
case xs of {
Cons h t -> case t of {
Nil -> h;
Cons h2 t2 -> last t;
};
})
mapped = THUNK(map plusOne list3)
main = THUNK(last mapped)
43 changes: 43 additions & 0 deletions src/content/examples/partial-application.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: Partial application
code: |2
data Number a = Num a
data List a = Nil | Cons a (List a)
nil = CON Nil
map = FUN(f xs ->
case xs of {
Nil -> nil;
Cons y ys -> let h = THUNK(f y)
t = THUNK(map f ys)
r = CON(Cons h t)
in r;
}
)
times2 = FUN(x ->
case x of {
Num x -> case x *# 2 of {
x -> let result = CON(Num x)
in result;
};
}
)
times2list = THUNK(map times2)
forcelist = FUN(list ->
case list of {
Nil -> nil;
Cons h t -> case h of {
x -> case forcelist t of {
y -> let result = CON(Cons x y)
in result;
};
};
}
)
main = THUNK(let one = CON(Num 1)
two = CON(Num 2)
three = CON(Num 3)
list1 = CON(Cons one nil)
list2 = CON(Cons two list1)
list3 = CON(Cons three list2)
list_x2 = THUNK(times2list list3)
list_x4 = THUNK(times2list list_x2)
in forcelist list_x4)
7 changes: 7 additions & 0 deletions src/content/examples/primop.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
name: Primitive operator
code: |2
data Number a = Num a
main = THUNK(case 2 +# 3 of {
x -> let result = CON(Num x)
in result;
})
31 changes: 31 additions & 0 deletions src/content/examples/sum-foldl.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: Sum foldl
code: |2
data Number a = Num a
data List a = Nil | Cons a (List a)
nil = CON Nil
zero = CON(Num 0)
one = CON(Num 1)
two = CON(Num 2)
three = CON(Num 3)
plusInt = FUN(x y ->
case x of {
Num i -> case y of {
Num j -> case i +# j of {
x -> let result = CON(Num x)
in result;
};
};
}
)
foldl = FUN(f acc list ->
case list of {
Nil -> acc;
Cons h t -> let newAcc = THUNK(f acc h)
in foldl f newAcc t;
}
)
sum = FUN(list -> foldl plusInt zero list)
list1 = CON(Cons one nil)
list2 = CON(Cons two list1)
list3 = CON(Cons three list2)
main = THUNK(sum list3)
11 changes: 11 additions & 0 deletions src/content/examples/too-many.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
name: Too many args
code: |2
data Number a = Num a
plusN = FUN(n -> let f = FUN(a ->
case a of {
x -> case x +# n of {
y -> let result = CON(Num y)
in result;
};
}) in f)
main = THUNK(plusN 1 2)
10 changes: 8 additions & 2 deletions src/pages/index.astro
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
---
import { getCollection } from "astro:content";
import Layout from "@/layouts/Layout.astro";
import Machine from "@/components/Machine.tsx";
import "@/styles/syntax.css";
import "@/styles/react_flow_overrides.css";
---
const examples = (await getCollection("examples")).map(x => x.data);
const default_program = "Sum foldl";
if (!examples.find(x => x.name === default_program)) {
throw new Error("Default program not in examples")
}
---
<Layout title="Simulator" description="Web based simulator of the STG machine">
<Machine client:only="react" />
<Machine client:only="react" default_program={default_program} examples={examples}/>
</Layout>
Loading

0 comments on commit 552cfe5

Please sign in to comment.