now it really works!

This commit is contained in:
Joeri Exelmans 2025-05-13 20:56:16 +02:00
parent c31ba88dfd
commit 174bab79e4
5 changed files with 55 additions and 34 deletions

View file

@ -90,6 +90,13 @@
.functionBlock.unifyError > .functionParams > .outputParam > .inputParam > .inputParam > .inputParam:after { .functionBlock.unifyError > .functionParams > .outputParam > .inputParam > .inputParam > .inputParam:after {
border-left-color: pink; border-left-color: pink;
} }
.functionBlock.unifyError > .functionParams > .outputParam > .inputParam > .inputParam > .inputParam > .inputParam {
background-color: pink;
color: black;
}
.functionBlock.unifyError > .functionParams > .outputParam > .inputParam > .inputParam > .inputParam > .inputParam:after {
border-left-color: pink;
}
.inputParam.offending { .inputParam.offending {
background-color: darkred !important; background-color: darkred !important;

View file

@ -7,7 +7,16 @@ import type { Dynamic, SetStateFn, State2Props } from "./util/extra";
import { useEffect } from "react"; import { useEffect } from "react";
import "./CallBlock.css"; import "./CallBlock.css";
type ResolvedType = Dynamic | Error | undefined; export class DeepError {
e: Error;
depth: number;
constructor(e, depth) {
this.e = e;
this.depth = depth;
}
};
type ResolvedType = Dynamic | DeepError | undefined;
export interface CallBlockState< export interface CallBlockState<
FnState=EditorState, FnState=EditorState,
@ -27,7 +36,7 @@ interface CallBlockProps<
function have(resolved: ResolvedType) { function have(resolved: ResolvedType) {
return resolved && !(resolved instanceof Error); return resolved && !(resolved instanceof DeepError);
} }
function headlessCallBlock({state, setState}: CallBlockProps) { function headlessCallBlock({state, setState}: CallBlockProps) {
@ -53,17 +62,16 @@ function headlessCallBlock({state, setState}: CallBlockProps) {
if (!(e instanceof UnifyError) && !(e instanceof NotAFunctionError)) { if (!(e instanceof UnifyError) && !(e instanceof NotAFunctionError)) {
throw e; throw e;
} }
setResolved(() => e as Error); // eval error setResolved(() => new DeepError(e, 0)); // eval error
} }
} }
else if (input.resolved instanceof Error) { else if (input.resolved instanceof DeepError) {
setResolved(() => input.resolved); // bubble up the error setResolved(() => input.resolved); // bubble up the error
} }
else if (fn.resolved instanceof Error) { else if (fn.resolved instanceof DeepError) {
// @ts-ignore
setResolved(() => { setResolved(() => {
// @ts-ignore // @ts-ignore
return Object.assign(fn.resolved, {depth: (fn.resolved.depth || 0) + 1}); return new DeepError(fn.resolved.e, fn.resolved.depth+1);
}); // bubble up the error }); // bubble up the error
} }
else { else {
@ -82,13 +90,8 @@ function headlessCallBlock({state, setState}: CallBlockProps) {
export function CallBlock({ state, setState }: CallBlockProps) { export function CallBlock({ state, setState }: CallBlockProps) {
const {setFn, setInput, onFnCancel, onInputCancel} const {setFn, setInput, onFnCancel, onInputCancel}
= headlessCallBlock({ state, setState }); = headlessCallBlock({ state, setState });
return <span className={"functionBlock" + ((state.resolved instanceof DeepError) ? " unifyError" : "")}>
// @ts-ignore
console.log('depth:', state.resolved?.depth);
return <span className={"functionBlock" + ((state.resolved instanceof Error) ? " unifyError" : "")}>
<FunctionHeader <FunctionHeader
fn={state.fn} fn={state.fn}
setFn={setFn} setFn={setFn}
@ -102,18 +105,17 @@ export function CallBlock({ state, setState }: CallBlockProps) {
input={state.input} setInput={setInput} input={state.input} setInput={setInput}
onInputCancel={onInputCancel} onInputCancel={onInputCancel}
depth={0} depth={0}
// @ts-ignore errorDepth={state.resolved instanceof DeepError ? (state.resolved.depth) : -1}
errorDepth={state.resolved instanceof Error ? (state.resolved.depth || 0) : -1}
/> />
{/* Output (or Error) */} {/* Output (or Error) */}
{ state.resolved instanceof Error && state.resolved.toString() { state.resolved instanceof DeepError && state.resolved.e.toString()
|| state.resolved && <><Value dynamic={state.resolved} />&#x2611;</>} || state.resolved && <><Value dynamic={state.resolved} />&#x2611;</>}
</div> </div>
</div> </div>
</span>; </span>;
} }
function filterFnInputs(fn: Dynamic|Error|undefined, input: Dynamic|Error|undefined) { function filterFnInputs(fn: ResolvedType, input: ResolvedType) {
if (!have(fn) || !have(input)) { if (!have(fn) || !have(input)) {
return false; return false;
} }

View file

@ -1,7 +1,7 @@
import { getSymbol, getType, symbolFunction } from "dope2"; import { getSymbol, getType, symbolFunction } from "dope2";
import { useContext, useEffect, useReducer, useRef, useState } from "react"; import { useContext, useEffect, useReducer, useRef, useState } from "react";
import { CallBlock, type CallBlockState } from "./CallBlock"; import { CallBlock, DeepError, type CallBlockState } from "./CallBlock";
import { InputBlock, type InputBlockState } from "./InputBlock"; import { InputBlock, type InputBlockState } from "./InputBlock";
import { Type } from "./Type"; import { Type } from "./Type";
import { type Dynamic, type State2Props } from "./util/extra"; import { type Dynamic, type State2Props } from "./util/extra";
@ -170,7 +170,7 @@ export function Editor({state, setState, onCancel, filter}: EditorProps) {
return <> return <>
{renderBlock()} {renderBlock()}
{ {
(state.resolved && !(state.resolved instanceof Error)) (state.resolved && !(state.resolved instanceof DeepError))
? <div className="typeSignature"> ? <div className="typeSignature">
:: <Type type={getType(state.resolved)} /> :: <Type type={getType(state.resolved)} />
</div> </div>

View file

@ -4,6 +4,7 @@ import { getDefaultTypeParser, module2Env, ModuleStd } from "dope2";
const mkType = getDefaultTypeParser(); const mkType = getDefaultTypeParser();
export const extendedEnv = module2Env(ModuleStd.concat([ export const extendedEnv = module2Env(ModuleStd.concat([
["functionWith3Params", { i: i => j => k => i + j + k, t: mkType("Int->Int->Int->Int") }], ["functionWith3Params", { i: i => j => k => i + j + k, t: mkType("Int->Int->Int->Int") }],
["functionWith4Params", { i: i => j => k => l => i+j+k+l, t: mkType("Int->Int->Int->Int->Int")}]
])); ]));
export const EnvContext = createContext(extendedEnv); export const EnvContext = createContext(extendedEnv);

View file

@ -42,9 +42,10 @@ export const nonEmptyEditorState: EditorState = {
resolved: undefined, resolved: undefined,
}; };
const functionWith3Params = trie.get(extendedEnv.name2dyn)("functionWith3Params"); const functionWith4Params = trie.get(extendedEnv.name2dyn)("functionWith4Params");
const fourtyThree = { i: 43n, t: Int }; const fourtyThree = { i: 43n, t: Int };
const fourtyFour = { i: 44n, t: Int }; const fourtyFour = { i: 44n, t: Int };
const fourtyFive = { i: 45n, t: Int };
export const tripleFunctionCallEditorState: EditorState = { export const tripleFunctionCallEditorState: EditorState = {
kind: "call", kind: "call",
@ -53,33 +54,43 @@ export const tripleFunctionCallEditorState: EditorState = {
fn: { fn: {
kind: "call", kind: "call",
fn: { fn: {
kind: "input", kind: "call",
text: "functionWith3Params", fn: {
resolved: functionWith3Params, kind: "input",
focus: false, text: "functionWith4Params",
resolved: functionWith4Params,
focus: false,
},
input: {
kind: "input",
text: "42",
resolved: fourtyTwo,
focus: false,
},
resolved: apply(fourtyTwo)(functionWith4Params),
}, },
input: { input: {
kind: "input", kind: "input",
text: "42", text: "43",
resolved: fourtyTwo, resolved: fourtyThree,
focus: false, focus: false,
}, },
resolved: apply(fourtyTwo)(functionWith3Params), resolved: apply(fourtyThree)(apply(fourtyTwo)(functionWith4Params)),
}, },
input: { input: {
kind: "input", kind: "input",
text: "43", text: "44",
resolved: fourtyThree, resolved: fourtyFour,
focus: false, focus: false,
}, },
resolved: apply(fourtyThree)(apply(fourtyTwo)(functionWith3Params)), resolved: apply(fourtyFour)(apply(fourtyThree)(apply(fourtyTwo)(functionWith4Params))),
}, },
input: { input: {
kind: "input", kind: "input",
text: "44", text: "45",
resolved: fourtyFour, resolved: fourtyFive,
focus: false, focus: false,
}, },
resolved: apply(fourtyFour)(apply(fourtyThree)(apply(fourtyTwo)(functionWith3Params))), resolved: apply(fourtyFive)(apply(fourtyFour)(apply(fourtyThree)(apply(fourtyTwo)(functionWith4Params)))),
}; };