Skip to content

Commit

Permalink
make some stuff work/break some other stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
mcnuttandrew committed Jan 20, 2025
1 parent 7ada22e commit e6f6cee
Show file tree
Hide file tree
Showing 5 changed files with 221 additions and 33 deletions.
25 changes: 24 additions & 1 deletion apps/lil-buddy/src/lib/SmallStepEvaluator.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { expect, test } from "vitest";
import { makePalFromString } from "color-buddy-palette";
import { GenerateAST } from "color-buddy-palette-lint";
import { GenerateAST, PREBUILT_LINTS } from "color-buddy-palette-lint";
import { generateEvaluations } from "./small-step-evaluator";

const defaultPal = makePalFromString(["red", "green"]);
Expand Down Expand Up @@ -42,3 +42,26 @@ test("Agg Test", () => {
const result = generateEvaluations(ast, {}, defaultPal);
expect(result).toMatchSnapshot();
});

test("Fair Test", () => {
const fair = {
"<": {
left: { extent: { sort: "colors", varb: "x", func: { "lch.l": "x" } } },
right: 50,
},
};
const ast = (GenerateAST(fair as any).value as any).children[0] as any;
const result = generateEvaluations(ast, {}, defaultPal);
expect(result).toMatchSnapshot();
});

// test("All Test", () => {
// for (const test in PREBUILT_LINTS) {
// const lint = PREBUILT_LINTS[test as keyof typeof PREBUILT_LINTS];
// console.log(lint);
// const lintProgram = JSON.parse(lint.program);
// const ast = (GenerateAST(lintProgram).value as any).children[0] as any;
// const result = generateEvaluations(ast, {}, defaultPal);
// expect(result).toMatchSnapshot();
// }
// });
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,88 @@ exports[`Agg Test 1`] = `
]
`;

exports[`Fair Test 1`] = `
[
LLExpression {
"nodeType": "expression",
"value": LLPredicate {
"left": LLAggregate {
"children": LLMap {
"children": LLVariable {
"nodeType": "variable",
"value": "colors",
},
"func": LLValueFunction {
"input": LLVariable {
"nodeType": "variable",
"value": "x",
},
"nodeType": "valueFunction",
"params": {},
"type": "lch.l",
},
"nodeType": "map",
"type": "sort",
"varb": "x",
},
"nodeType": "aggregate",
"type": "extent",
},
"nodeType": "predicate",
"right": LLNumber {
"nodeType": "number",
"value": 50,
},
"threshold": undefined,
"type": "<",
},
},
LLPredicate {
"left": LLAggregate {
"children": LLValueArray {
"children": [
LLNumber {
"nodeType": "number",
"value": 46.278,
},
LLNumber {
"nodeType": "number",
"value": 54.291,
},
],
"nodeType": "array",
},
"nodeType": "aggregate",
"type": "extent",
},
"nodeType": "predicate",
"right": LLNumber {
"nodeType": "number",
"value": 50,
},
"threshold": undefined,
"type": "<",
},
LLPredicate {
"left": LLNumber {
"nodeType": "number",
"value": 8.012999999999998,
},
"nodeType": "predicate",
"right": LLNumber {
"nodeType": "number",
"value": 50,
},
"threshold": undefined,
"type": "<",
},
LLBool {
"nodeType": "bool",
"value": true,
},
]
`;

exports[`SmallStepEvaluator works 1`] = `
[
LLExpression {
Expand Down
73 changes: 47 additions & 26 deletions apps/lil-buddy/src/lib/small-step-evaluator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ export function evaluateNode(
(acc, [key, value]) => acc.set(key, toVal(value)),
new Environment(pal, {}, opts, {})
);
return node.evaluate(newEnv);
const result = node.evaluate(newEnv);
return result;
}

function isValue(node: any) {
Expand All @@ -31,6 +32,8 @@ function isValue(node: any) {
case "variable":
case undefined:
return true;
case "array":
return node.children.every(isValue);
default:
return false;
}
Expand All @@ -41,17 +44,23 @@ function subTreeIsPureOp(node: any): boolean {
case "numberOp":
case "predicate":
return isValue(node.left) && isValue(node.right);
case "conjunction":
case "aggregate":
case "array":
case "map":
// special thing for conjunction
if (node.type === "not") {
return isValue(node.children[0]);
}
return node.children.every((x: any) => subTreeIsPureOp(x));
case "aggregate":
case "array":
if (node.children?.nodeType === "variable") {
return true;
}
return node.children.every((x: any) => subTreeIsPureOp(x));
const children = node.children;
if (Array.isArray(children)) {
return children.every((x: any) => isValue(x));
} else {
// for variables and such
return isValue(children);
}
case "node":
case "expression":
return subTreeIsPureOp(node.value);
Expand All @@ -64,7 +73,7 @@ function subTreeIsPureOp(node: any): boolean {
case "valueFunction":
return isValue(node.input);
case "quantifier":
case "map":
throw new Error("Quantifiers should not be evaluated here", node);
default:
return false;
}
Expand All @@ -80,7 +89,12 @@ function traverseAndMaybeExecute(
const thisIsPureOp = subTreeIsPureOp(node);
if (thisIsPureOp) {
const result = evaluateNode(node, inducedVariables, pal).result;
const astResult = LLTypes.LLValue.tryToConstruct(result, {} as any);
let astResult;
if (Array.isArray(result)) {
astResult = LLTypes.LLValueArray.tryToConstruct(result, {} as any);
} else {
astResult = LLTypes.LLValue.tryToConstruct(result, {} as any);
}
return { result: astResult, didEval: true };
}
let updatedNode = node.copy();
Expand All @@ -102,36 +116,44 @@ function traverseAndMaybeExecute(
inducedVariables,
pal
);
if (rightTraverse) {
if (rightTraverse.didEval) {
updatedNode.right = rightTraverse.result;
return { result: updatedNode, didEval: true };
}
return { result: updatedNode, didEval: false };
case "conjunction":
case "array":
case "aggregate":
const newChildren = [];
let found = false;
for (let idx = 0; idx < updatedNode.children.length; idx++) {
if (found) {
newChildren.push(updatedNode.children[idx]);
continue;
case "map":
const children = updatedNode.children;
if (Array.isArray(children)) {
const newChildren = [];
let found = false;
for (let idx = 0; idx < updatedNode.children.length; idx++) {
if (found) {
newChildren.push(updatedNode.children[idx]);
continue;
}
const child = updatedNode.children[idx];
const childResult = traverseAndMaybeExecute(
child,
inducedVariables,
pal
);
newChildren.push(childResult.result);
found = childResult.didEval;
}
const child = updatedNode.children[idx];
updatedNode.children = newChildren;
return { result: updatedNode, didEval: found };
} else {
const childResult = traverseAndMaybeExecute(
child,
updatedNode.children,
inducedVariables,
pal
);
newChildren.push(childResult.result);
found = childResult.didEval;
updatedNode.children = childResult.result;
return { result: updatedNode, didEval: childResult.didEval };
}
// let found = false
// updatedNode.children = updatedNode.children.map(x => {

// })
updatedNode.children = newChildren;
return { result: updatedNode, didEval: found };
case "node":
case "expression":
return traverseAndMaybeExecute(node.value, inducedVariables, pal);
Expand All @@ -154,7 +176,6 @@ function traverseAndMaybeExecute(
case "quantifier":
throw new Error("Quantifiers should not be evaluated here", node);

case "map":
default:
console.log(node.nodeType, " not implemented yet", node);
throw new Error(`${node.nodeType} not implemented yet`, node);
Expand Down
28 changes: 24 additions & 4 deletions apps/lil-buddy/src/linting/summary-nodes/DispatchNode.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import type { Palette, Color } from "color-buddy-palette";
import InlineNode from "./InlineNode.svelte";
import QuantifierNode from "./QuantifierNode.svelte";
import { getPredNodes } from "./visual-summary-utils";
import { getPredNodes, handleEval } from "./visual-summary-utils";
export let node: any;
export let pal: Palette;
Expand All @@ -11,12 +11,32 @@
$: predicateNodes = getPredNodes(node, inducedVariables, pal) as any[];
$: isNotNode = node.nodeType === "conjunction" && node.type === "not";
function shouldComputeResult(node: any) {
const conjTypes = new Set(["and", "or"]);
return node.nodeType === "conjunction" && conjTypes.has(node.type);
}
</script>

{#if node.nodeType == "conjunction" && !isNotNode}
{#each node.children as child}
<svelte:self node={child.value} {pal} {inducedVariables} />
{/each}
<div class="flex items-center">
<div
class="flex flex-col ml-2"
class:border={node.type !== "id"}
class:p-2={node.type !== "id"}
>
{#if node.type !== "id"}
<div>{node.type}</div>
{/if}
{#each node.children as child}
<div class="flex">
<svelte:self node={child.value} {pal} {inducedVariables} />
</div>
{/each}
</div>
{#if shouldComputeResult(node)}
<div>→{handleEval(node, inducedVariables, pal).result}</div>
{/if}
</div>
{:else if node.nodeType === "expression"}
<svelte:self node={node.value} {pal} {inducedVariables} />
{:else if predicateNodes.length}
Expand Down
46 changes: 44 additions & 2 deletions apps/lil-buddy/src/linting/summary-nodes/InlineNode.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,15 @@
<span class="mr-2">NOT</span>
<svelte:self node={node.children[0]} {pal} {inducedVariables} />
</div>
{:else if node.nodeType === "conjunction"}
<div class="flex flex-col">
<div>{node.type}</div>
{#each node.children as child}
<svelte:self node={child} {pal} {inducedVariables} />
{/each}
</div>
{:else if node.nodeType === "number"}
<div>{node.value}</div>
<div>{Math.round(node.value * 1000) / 1000}</div>
{:else if node.nodeType === "variable"}
{#if inducedVariables[node.value]}
<div
Expand Down Expand Up @@ -70,16 +77,51 @@
<div class="flex">
{node.type}
<span>{"("}</span>
{#if node.children?.nodeType === "variable"}
{#if Array.isArray(node.children)}
{#each node.children as child}
<svelte:self node={child} {pal} {inducedVariables} />
{#if child !== node.children[node.children.length - 1]}
<span>{","}</span>
{/if}
{/each}
{:else}
<svelte:self node={node.children} {pal} {inducedVariables} />
{/if}
<span>{")"}</span>
</div>
{:else if node.nodeType === "array"}
<div class="flex">
<span>{"["}</span>
{#if Array.isArray(node.children)}
{#each node.children as child}
<svelte:self node={child} {pal} {inducedVariables} />
{#if child !== node.children[node.children.length - 1]}
<span>{","}</span>
{/if}
{/each}
{:else}
<svelte:self node={node.children} {pal} {inducedVariables} />
{/if}
<span>{"]"}</span>
</div>
{:else if node.nodeType === "map"}
<div class="flex">
{node.type}
<span>{"("}</span>
{#if Array.isArray(node.children)}
{#each node.children as child}
<svelte:self node={child} {pal} {inducedVariables} />
{#if child !== node.children[node.children.length - 1]}
<span>{","}</span>
{/if}
{/each}
{:else}
<svelte:self node={node.children} {pal} {inducedVariables} />
{/if}
<span>{","}</span>
<div>{node.varb}</div>
<span>{"=>"}</span>
<svelte:self node={node.func} {pal} {inducedVariables} />
<span>{")"}</span>
</div>
{:else if node.nodeType === "expression"}
Expand Down

0 comments on commit e6f6cee

Please sign in to comment.