Reorganize ui
This commit is contained in:
parent
e841106029
commit
bf5eb54932
18 changed files with 31 additions and 28 deletions
58
src/ui/Component/Value.tsx
Normal file
58
src/ui/Component/Value.tsx
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
import { Closure, Value, Env, EnvFrame } from 'src/lang/eval/value';
|
||||
import { exprToString, productPatternToString } from './Expr';
|
||||
|
||||
export function Val(prop: { value: Value }) {
|
||||
return (
|
||||
<code>{ valueToString(prop.value) }</code>
|
||||
);
|
||||
}
|
||||
|
||||
export function valueToString(val: Value): string {
|
||||
switch (val.tag) {
|
||||
case "number": return val.value.toString();
|
||||
case "string": return `"${val.value}"`;
|
||||
case "tag": return `#${val.tag_name}`;
|
||||
case "tagged": return `#${val.tag_name} ${valueToString(val.value)}`;
|
||||
case "tuple": return `(${val.values.map(valueToString).join(", ")})`;
|
||||
case "record": {
|
||||
const entries = Array.from(val.fields.entries())
|
||||
.map(([k, v]) => `${k} = ${valueToString(v)}`)
|
||||
.join(", ");
|
||||
return `{ ${entries} }`;
|
||||
}
|
||||
case "closure": return closureToString(val.closure);
|
||||
}
|
||||
}
|
||||
|
||||
function closureToString(c: Closure): string {
|
||||
const params = c.parameters.map(productPatternToString).join(", ");
|
||||
const envStr = envToString(c.env);
|
||||
// We represent the closure as the code + a summary of its captured scope
|
||||
return `fn { ${params} . ${exprToString(c.body)} } [captured: ${envStr}]`;
|
||||
}
|
||||
|
||||
function envToString(env: Env): string {
|
||||
if (env.tag === "nil") return "∅";
|
||||
|
||||
const frames: string[] = [];
|
||||
let current: Env = env;
|
||||
|
||||
while (current.tag === "frame") {
|
||||
frames.push(frameToString(current.frame));
|
||||
current = current.parent;
|
||||
}
|
||||
|
||||
// Shows stack from inner-most to outer-most
|
||||
return frames.join(" ⮕ ");
|
||||
}
|
||||
|
||||
function frameToString(frame: EnvFrame): string {
|
||||
const entries = Array.from(frame.entries());
|
||||
if (entries.length === 0) return "{}";
|
||||
|
||||
const formattedEntries = entries.map(([name, val]) => {
|
||||
return `${name} = ${valueToString(val)}`;
|
||||
});
|
||||
|
||||
return `{ ${formattedEntries.join(", ")} }`;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue