more progress

This commit is contained in:
Joeri Exelmans 2025-05-12 11:11:18 +02:00
parent 2b0d8bc2c6
commit ebae0afc81
7 changed files with 94 additions and 21 deletions

8
pnpm-lock.yaml generated
View file

@ -10,7 +10,7 @@ importers:
dependencies: dependencies:
dope2: dope2:
specifier: git+https://deemz.org/git/joeri/dope2.git specifier: git+https://deemz.org/git/joeri/dope2.git
version: git+https://deemz.org/git/joeri/dope2.git#d531c48a9298f318d089b900009f32cb9f04a53a version: git+https://deemz.org/git/joeri/dope2.git#a9e21d7d94a7c75c34a95116931b458507131694
react: react:
specifier: ^19.1.0 specifier: ^19.1.0
version: 19.1.0 version: 19.1.0
@ -633,8 +633,8 @@ packages:
resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==}
engines: {node: '>= 0.8'} engines: {node: '>= 0.8'}
dope2@git+https://deemz.org/git/joeri/dope2.git#d531c48a9298f318d089b900009f32cb9f04a53a: dope2@git+https://deemz.org/git/joeri/dope2.git#a9e21d7d94a7c75c34a95116931b458507131694:
resolution: {commit: d531c48a9298f318d089b900009f32cb9f04a53a, repo: https://deemz.org/git/joeri/dope2.git, type: git} resolution: {commit: a9e21d7d94a7c75c34a95116931b458507131694, repo: https://deemz.org/git/joeri/dope2.git, type: git}
version: 0.0.1 version: 0.0.1
dunder-proto@1.0.1: dunder-proto@1.0.1:
@ -1758,7 +1758,7 @@ snapshots:
depd@2.0.0: {} depd@2.0.0: {}
dope2@git+https://deemz.org/git/joeri/dope2.git#d531c48a9298f318d089b900009f32cb9f04a53a: dope2@git+https://deemz.org/git/joeri/dope2.git#a9e21d7d94a7c75c34a95116931b458507131694:
dependencies: dependencies:
functional-red-black-tree: 1.0.1 functional-red-black-tree: 1.0.1

View file

@ -4,9 +4,18 @@
margin: 1px; margin: 1px;
} }
.functionBlock.unifyError {
/* background-color: pink; */
/* color:white; */
}
.functionName { .functionName {
/* text-align: center; */ /* text-align: center; */
background-color: white;
}
.functionBlock.unifyError .functionName {
/* background-color: pink; */
} }
@ -43,3 +52,15 @@
/* border-radius: 10px; */ /* border-radius: 10px; */
width: 100%; width: 100%;
} }
.functionBlock.unifyError .inputParam {
background-color: darkred;
color: white;
}
.functionBlock.unifyError .inputParam:after {
border-left-color: darkred;
}
.functionBlock.unifyError .outputParam {
background-color: pink;
}

View file

@ -1,9 +1,9 @@
import { apply, getType, getInst } from "dope2"; import { apply, getType, getInst, assignFn, UnifyError } from "dope2";
import type { Dynamic, State2Props } from "./util/extra"; import type { Dynamic, State2Props } from "./util/extra";
import { Editor, type EditorState } from "./Editor"; import { Editor, type EditorState } from "./Editor";
import "./CallBlock.css"; import "./CallBlock.css";
import { useEffect } from "react"; import { useEffect, useState } from "react";
import { Type } from "./Type"; import { Type } from "./Type";
import { Value } from "./Value"; import { Value } from "./Value";
import { focusPrevElement } from "./util/dom_trickery"; import { focusPrevElement } from "./util/dom_trickery";
@ -22,6 +22,7 @@ interface CallBlockProps extends State2Props<CallBlockState> {
} }
export function CallBlock({ state: {kind, env, fn, input, resolved, rollback }, setState, onResolve }: CallBlockProps) { export function CallBlock({ state: {kind, env, fn, input, resolved, rollback }, setState, onResolve }: CallBlockProps) {
const [unifyError, setUnifyError] = useState<UnifyError | undefined>(undefined);
const setResolved = (resolved?: Dynamic) => { const setResolved = (resolved?: Dynamic) => {
setState({kind, env, fn, input, resolved, rollback}); setState({kind, env, fn, input, resolved, rollback});
} }
@ -35,9 +36,16 @@ export function CallBlock({ state: {kind, env, fn, input, resolved, rollback },
onResolve({ onResolve({
kind, env, fn, input, resolved: outputResolved, rollback kind, env, fn, input, resolved: outputResolved, rollback
}); });
setUnifyError(undefined);
} }
catch (e) { catch (e) {
console.log('makeTheCall:', e); if (!(e instanceof UnifyError)) {
throw e;
}
setUnifyError(e);
onResolve({
kind, env, fn, input, resolved: undefined, rollback
})
} }
} }
@ -84,7 +92,21 @@ export function CallBlock({ state: {kind, env, fn, input, resolved, rollback },
} }
} }
return <span className="functionBlock"> const filterCompatibleInputs = ([_name, dynamic]: [string, Dynamic]) => {
if (fn.resolved) {
try {
assignFn(getType(fn.resolved), getType(dynamic));
} catch (e) {
if (!(e instanceof UnifyError)) {
throw e;
}
return false;
}
}
return true;
}
return <span className={"functionBlock" + (unifyError ? " unifyError" : "")}>
<div className="functionName"> <div className="functionName">
&#119891;&#119899;&nbsp; &#119891;&#119899;&nbsp;
<Editor state={fn} setState={setFn} <Editor state={fn} setState={setFn}
@ -98,6 +120,10 @@ export function CallBlock({ state: {kind, env, fn, input, resolved, rollback },
{ resolved { resolved
? <Value dynamic={resolved} /> ? <Value dynamic={resolved} />
: <></> } : <></> }
{ unifyError
? <>{unifyError.toString()}</>
: <></>
}
</div> </div>
</div> </div>
</span>; </span>;

View file

@ -16,6 +16,7 @@
} }
.suggestions { .suggestions {
display: none; display: none;
color: black;
} }
.suggestions { .suggestions {
display: block; display: block;
@ -24,7 +25,7 @@
border: solid 1px dodgerblue; border: solid 1px dodgerblue;
cursor: pointer; cursor: pointer;
max-height: calc(100vh - 44px); max-height: calc(100vh - 44px);
overflow: scroll; overflow: auto;
z-index: 10; z-index: 10;
background-color: white; background-color: white;
} }
@ -52,6 +53,7 @@
font-variation-settings: "wdth" 100; font-variation-settings: "wdth" 100;
background-color: transparent; background-color: transparent;
color: inherit;
} }
.border-around-input { .border-around-input {
border: 1px solid black; border: 1px solid black;

View file

@ -19,7 +19,7 @@ export interface InputBlockState {
} }
interface InputBlockProps extends State2Props<InputBlockState> { interface InputBlockProps extends State2Props<InputBlockState> {
filter: (ls: any[]) => boolean; filter: (suggestion: [string, Dynamic]) => boolean;
onResolve: (state: InputBlockState) => void; onResolve: (state: InputBlockState) => void;
onCancel: () => void; onCancel: () => void;
} }
@ -120,7 +120,7 @@ export function InputBlock({ state: {kind, env, text, resolved, rollback}, setSt
e.preventDefault(); e.preventDefault();
}, },
ArrowUp: () => { ArrowUp: () => {
setI((i - 1) % suggestions.length); setI((suggestions.length + i - 1) % suggestions.length);
e.preventDefault(); e.preventDefault();
}, },
ArrowLeft: () => { ArrowLeft: () => {

View file

@ -1,4 +1,4 @@
.value { .valuePrimitive {
border: 1px solid black; border: 1px solid black;
border-radius: 10px; border-radius: 10px;
margin-left: 2px; margin-left: 2px;

View file

@ -1,4 +1,4 @@
import {getType, getInst, getSymbol, Double, Int, symbolFunction, symbolProduct, symbolSum, symbolDict, symbolSet, symbolList, eqType, match, getLeft, getRight} from "dope2"; import {getType, getInst, getSymbol, Double, Int, symbolFunction, symbolProduct, symbolSum, symbolDict, symbolSet, symbolList, eqType, match, getLeft, getRight, dict} from "dope2";
import "./Value.css"; import "./Value.css";
@ -11,6 +11,7 @@ export function Value({dynamic}) {
if (eqType(type)(Int)) { if (eqType(type)(Int)) {
return <ValueInt val={inst}/>; return <ValueInt val={inst}/>;
} }
const symbol = getSymbol(type); const symbol = getSymbol(type);
switch (symbol) { switch (symbol) {
case symbolFunction: case symbolFunction:
@ -20,10 +21,13 @@ export function Value({dynamic}) {
// return <BinaryType type={type} cssClass="productType" infix="&#10799;" prefix="" suffix=""/>; // return <BinaryType type={type} cssClass="productType" infix="&#10799;" prefix="" suffix=""/>;
case symbolSum: case symbolSum:
return <ValueSum val={inst} leftType={type.params[0](type)} rightType={type.params[1](type)}/>; return <ValueSum val={inst} leftType={type.params[0](type)} rightType={type.params[1](type)}/>;
case symbolProduct: case symbolProduct:
return <ValueProduct val={inst} leftType={type.params[0](type)} rightType={type.params[1](type)}/>; return <ValueProduct val={inst} leftType={type.params[0](type)} rightType={type.params[1](type)}/>;
// case symbolDict: case symbolDict:
return <ValueDict val={inst} keyType={type.params[0](type)} valueType={type.params[1](type)}/>;
// return <BinaryType type={type} cssClass="dictType" infix="&rArr;" prefix="{" suffix="}"/>; // return <BinaryType type={type} cssClass="dictType" infix="&rArr;" prefix="{" suffix="}"/>;
// case symbolSet: // case symbolSet:
// return <UnaryType type={type} cssClass="setType" prefix="{" suffix="}" />; // return <UnaryType type={type} cssClass="setType" prefix="{" suffix="}" />;
@ -36,10 +40,10 @@ export function Value({dynamic}) {
} }
function ValueDouble({val}) { function ValueDouble({val}) {
return <span className="value">{val.toString()}</span>; return <span className="valuePrimitive">{val.toString()}</span>;
} }
function ValueInt({val}) { function ValueInt({val}) {
return <span className="value">{val.toString()}</span>; return <span className="valuePrimitive">{val.toString()}</span>;
} }
function ValueFunction() { function ValueFunction() {
return <>&#119891;&#119899;&nbsp;</>; return <>&#119891;&#119899;&nbsp;</>;
@ -52,9 +56,29 @@ function List({val, elemType}) {
} }
function ValueSum({val, leftType, rightType}) { function ValueSum({val, leftType, rightType}) {
return match(val) return match(val)
(l => <>L <Value dynamic={{i:l, t:leftType}}/></>) (l => <span className="sumType">L <Value dynamic={{i:l, t:leftType}}/></span>)
(r => <>R <Value dynamic={{i:r, t:rightType}}/></>); (r => <span className="sumType">R <Value dynamic={{i:r, t:rightType}}/></span>);
} }
function ValueProduct({val, leftType, rightType}) { function ValueProduct({val, leftType, rightType}) {
return <>(<Value dynamic={{i:getLeft(val), t:leftType}}/>,&nbsp;<Value dynamic={{i:getRight(val), t:rightType}} />)</>; return <span className="productType">(<Value dynamic={{i:getLeft(val), t:leftType}}/>,&nbsp;<Value dynamic={{i:getRight(val), t:rightType}} />)</span>;
}
function ValueDict({val, keyType, valueType}) {
let i=0;
return <span className="dictType">{'{'}<>{
dict.fold
(acc => key => value => {
console.log({acc, key, value});
return acc.concat([<>
<Value key={i++} dynamic={{i: key, t: keyType}}/>
&rArr;
<Value key={i++} dynamic={{i: value, t: valueType}}/>
</>]);
})
([])
(val)
.map(result => {
console.log(result);
return result;
})
}</>{'}'}</span>;
} }