infer all types once at the root level, and pass the result down deeply

This commit is contained in:
Joeri Exelmans 2025-05-25 08:58:21 +02:00
parent b2584a2495
commit d000839878
6 changed files with 75 additions and 80 deletions

View file

@ -1,14 +1,13 @@
import { useContext } from "react";
import { ExprBlock, type ExprBlockState } from "./ExprBlock";
import { EnvContext } from "../../context/EnvContext";
import { type State2Props } from "./ExprBlock";
import { GlobalContext } from "../../context/GlobalContext";
import { type TypeInfoLet } from "../../eval/infer_type";
import { Input } from "../other/Input";
import { Type } from "../other/Type";
import { ExprBlock, type ExprBlockState, type State2Props } from "./ExprBlock";
import "./LetInBlock.css";
import { Input } from "../other/Input";
import { inferTypeLet } from "../../eval/infer_type";
import { Type } from "../other/Type";
export interface LetInBlockState {
kind: "let";
@ -19,6 +18,7 @@ export interface LetInBlockState {
}
export interface LetInBlockProps extends State2Props<LetInBlockState,ExprBlockState> {
typeInfo: TypeInfoLet;
}
export function LetInBlock(props: LetInBlockProps) {
@ -32,15 +32,13 @@ export function LetInBlock(props: LetInBlockProps) {
</span>
}
function DeclColumns({state, setState, score}) {
function DeclColumns({state, setState, score, typeInfo}) {
const env = useContext(EnvContext);
const globalContext = useContext(GlobalContext);
const setInner = callback => setState(state => ({...state, inner: callback(state.inner)}));
const setValue = callback => setState(state => ({...state, value: callback(state.value)}));
const {value: valueTypeInfo, innerEnv} = inferTypeLet(state, env);
return <>
<span className="keyword column">let&nbsp;</span>
<span className="column rightAlign">
@ -53,7 +51,7 @@ function DeclColumns({state, setState, score}) {
onTextChange={name => setState(state => ({...state, name}))}
extraHandlers={{}}
/>
:: <Type type={valueTypeInfo.type} />
:: <Type type={typeInfo.value.type} />
</span>
<span className="keyword column">&nbsp;=&nbsp;</span>
<span className="column">
@ -62,45 +60,46 @@ function DeclColumns({state, setState, score}) {
setState={setValue}
score={suggestion => score({ ...state, value: suggestion })}
onCancel={() => setState(state => state.inner)} // keep inner
typeInfo={typeInfo.value}
/>
</span>
{state.inner.kind === "let" &&
globalContext?.syntacticSugar &&
<EnvContext value={innerEnv}>
<EnvContext value={typeInfo.innerEnv}>
<DeclColumns
state={state.inner}
setState={setInner}
score={suggestion => score({ ...state, inner: suggestion })}
typeInfo={typeInfo.inner}
/>
</EnvContext>
}
</>;
}
function InnerMost({state, setState, score}) {
function InnerMost({state, setState, score, typeInfo}) {
const env = useContext(EnvContext);
const globalContext = useContext(GlobalContext);
const setInner = callback => setState(state => ({...state, inner: callback(state.inner)}));
// const [valueResolved] = evalExprBlock(state.value, env);
// const innerEnv = makeInnerEnv(env, state.name, valueResolved);
const {innerEnv} = inferTypeLet(state, env);
const onCancel = () => setState(state => state.value);
if (state.inner.kind === "let" && globalContext?.syntacticSugar) {
return <EnvContext value={innerEnv}>
return <EnvContext value={typeInfo.innerEnv}>
<InnerMost
state={state.inner}
setState={setInner}
score={suggestion => score({ ...state, inner: suggestion })}
typeInfo={typeInfo.inner}
/>
</EnvContext>;
}
else {
return <EnvContext value={innerEnv}>
return <EnvContext value={typeInfo.innerEnv}>
<ExprBlock
state={state.inner}
setState={setInner}
score={suggestion => score({ ...state, inner: suggestion })}
onCancel={onCancel} // keep value
typeInfo={typeInfo.inner}
/>
</EnvContext>
}