refactor a bit more
This commit is contained in:
parent
230916ceb1
commit
fdbf43a4e9
11 changed files with 79 additions and 90 deletions
|
|
@ -3,8 +3,7 @@ import './App.css';
|
||||||
import { ExprBlock, type ExprBlockState } from './ExprBlock';
|
import { ExprBlock, type ExprBlockState } from './ExprBlock';
|
||||||
import { GlobalContext } from './GlobalContext';
|
import { GlobalContext } from './GlobalContext';
|
||||||
import { biggerExample, higherOrder, higherOrder2Params, inc, initialEditorState, lambda2Params, nonEmptyEditorState, pushBool, tripleFunctionCallEditorState } from "./configurations";
|
import { biggerExample, higherOrder, higherOrder2Params, inc, initialEditorState, lambda2Params, nonEmptyEditorState, pushBool, tripleFunctionCallEditorState } from "./configurations";
|
||||||
import { removeFocus } from "./eval";
|
import { actionShortcuts } from './actions';
|
||||||
import { actionShortcuts, getActions } from './actions';
|
|
||||||
|
|
||||||
|
|
||||||
const examples: [string, ExprBlockState][] = [
|
const examples: [string, ExprBlockState][] = [
|
||||||
|
|
@ -168,9 +167,6 @@ export function App() {
|
||||||
// console.log('suggestionPriority of App, always 0');
|
// console.log('suggestionPriority of App, always 0');
|
||||||
return 0;
|
return 0;
|
||||||
}}
|
}}
|
||||||
addParam={() => {
|
|
||||||
getActions({doHighlight}, pushHistory).c();
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</GlobalContext>
|
</GlobalContext>
|
||||||
</main>
|
</main>
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,8 @@ import { Value } from "./Value";
|
||||||
|
|
||||||
import "./CallBlock.css";
|
import "./CallBlock.css";
|
||||||
import { initialEditorState } from "./configurations";
|
import { initialEditorState } from "./configurations";
|
||||||
|
import { CallContext } from "./CallContext";
|
||||||
|
import { getActions } from "./actions";
|
||||||
|
|
||||||
export interface CallBlockState {
|
export interface CallBlockState {
|
||||||
kind: "call";
|
kind: "call";
|
||||||
|
|
@ -55,31 +57,26 @@ function nestedInputProperties({state, setState, suggestionPriority}: CallBlockP
|
||||||
export function CallBlock(props: CallBlockProps) {
|
export function CallBlock(props: CallBlockProps) {
|
||||||
const env = useContext(EnvContext);
|
const env = useContext(EnvContext);
|
||||||
const globalContext = useContext(GlobalContext);
|
const globalContext = useContext(GlobalContext);
|
||||||
const addParam = (s: ExprBlockState) => {
|
const addParam = getActions(globalContext, props.setState).c;
|
||||||
props.setState(state => ({
|
|
||||||
kind: "call",
|
|
||||||
fn: removeFocus(state),
|
|
||||||
input: s,
|
|
||||||
}));
|
|
||||||
globalContext?.doHighlight.call();
|
|
||||||
};
|
|
||||||
const [resolved] = evalEditorBlock(props.state, env);
|
const [resolved] = evalEditorBlock(props.state, env);
|
||||||
return <span className={"functionBlock" + ((resolved.kind === "error") ? " unifyError" : "")}>
|
return <span className={"functionBlock" + ((resolved.kind === "error") ? " unifyError" : "")}>
|
||||||
<FunctionHeader {...props} addParam={addParam} />
|
<CallContext value={{addParam}}>
|
||||||
<div className="functionParams">
|
<FunctionHeader {...props} addParam={addParam} />
|
||||||
<div className="outputParam">
|
<div className="functionParams">
|
||||||
{/* Sequence of input parameters */}
|
<div className="outputParam">
|
||||||
<InputParams
|
{/* Sequence of input parameters */}
|
||||||
{...props}
|
<InputParams
|
||||||
depth={0}
|
{...props}
|
||||||
errorDepth={(resolved.kind === "error") ? (resolved.depth) : -1}
|
depth={0}
|
||||||
addParam={addParam}
|
errorDepth={(resolved.kind === "error") ? (resolved.depth) : -1}
|
||||||
/>
|
addParam={addParam}
|
||||||
{ (resolved.kind === "error") && resolved.e.toString()
|
/>
|
||||||
|| (resolved.kind === "value") && <Value dynamic={resolved} />
|
{ (resolved.kind === "error") && resolved.e.toString()
|
||||||
|| "unknown" }
|
|| (resolved.kind === "value") && <Value dynamic={resolved} />
|
||||||
|
|| "unknown" }
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</CallContext>
|
||||||
</span>;
|
</span>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -102,12 +99,12 @@ function FunctionHeader(props) {
|
||||||
// end of recursion - draw function name
|
// end of recursion - draw function name
|
||||||
return <span className="functionName">
|
return <span className="functionName">
|
||||||
𝑓𝑛
|
𝑓𝑛
|
||||||
<ExprBlock {...nestedProperties} addParam={props.addParam} />
|
<ExprBlock {...nestedProperties} />
|
||||||
</span>;
|
</span>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function InputParams({ depth, errorDepth, addParam, ...rest }) {
|
function InputParams({ depth, errorDepth, ...rest }) {
|
||||||
const env = useContext(EnvContext);
|
const env = useContext(EnvContext);
|
||||||
const globalContext = useContext(GlobalContext);
|
const globalContext = useContext(GlobalContext);
|
||||||
const isOffending = depth === errorDepth;
|
const isOffending = depth === errorDepth;
|
||||||
|
|
@ -118,12 +115,10 @@ function InputParams({ depth, errorDepth, addParam, ...rest }) {
|
||||||
{...nestedFnProperties(rest as CallBlockProps, env)}
|
{...nestedFnProperties(rest as CallBlockProps, env)}
|
||||||
depth={depth+1}
|
depth={depth+1}
|
||||||
errorDepth={errorDepth}
|
errorDepth={errorDepth}
|
||||||
addParam={addParam}
|
|
||||||
/>}
|
/>}
|
||||||
{/* Our own input param */}
|
{/* Our own input param */}
|
||||||
<ExprBlock
|
<ExprBlock
|
||||||
{...nestedInputProperties(rest as CallBlockProps, env)}
|
{...nestedInputProperties(rest as CallBlockProps, env)}
|
||||||
addParam={addParam}
|
|
||||||
/>
|
/>
|
||||||
</div>;
|
</div>;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
7
src/CallContext.ts
Normal file
7
src/CallContext.ts
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
import { createContext } from "react";
|
||||||
|
|
||||||
|
interface ICallContext {
|
||||||
|
addParam?: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const CallContext = createContext<ICallContext>({});
|
||||||
|
|
@ -31,10 +31,9 @@ export interface State2Props<InType, OutType = InType> {
|
||||||
|
|
||||||
interface ExprBlockProps extends State2Props<ExprBlockState> {
|
interface ExprBlockProps extends State2Props<ExprBlockState> {
|
||||||
onCancel: () => void;
|
onCancel: () => void;
|
||||||
addParam: (e: ExprBlockState) => void;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ExprBlock({state, setState, suggestionPriority, onCancel, addParam}: ExprBlockProps) {
|
export function ExprBlock({state, setState, suggestionPriority, onCancel}: ExprBlockProps) {
|
||||||
const env = useContext(EnvContext);
|
const env = useContext(EnvContext);
|
||||||
const globalContext = useContext(GlobalContext);
|
const globalContext = useContext(GlobalContext);
|
||||||
|
|
||||||
|
|
@ -44,7 +43,6 @@ export function ExprBlock({state, setState, suggestionPriority, onCancel, addPar
|
||||||
setState={setState as (callback:(p:InputBlockState)=>ExprBlockState)=>void}
|
setState={setState as (callback:(p:InputBlockState)=>ExprBlockState)=>void}
|
||||||
suggestionPriority={suggestionPriority}
|
suggestionPriority={suggestionPriority}
|
||||||
onCancel={onCancel}
|
onCancel={onCancel}
|
||||||
addParam={addParam}
|
|
||||||
/>,
|
/>,
|
||||||
call: () => <CallBlock
|
call: () => <CallBlock
|
||||||
state={state as CallBlockState}
|
state={state as CallBlockState}
|
||||||
|
|
@ -55,13 +53,11 @@ export function ExprBlock({state, setState, suggestionPriority, onCancel, addPar
|
||||||
state={state as LetInBlockState}
|
state={state as LetInBlockState}
|
||||||
setState={setState as (callback:(p:LetInBlockState)=>ExprBlockState)=>void}
|
setState={setState as (callback:(p:LetInBlockState)=>ExprBlockState)=>void}
|
||||||
suggestionPriority={suggestionPriority}
|
suggestionPriority={suggestionPriority}
|
||||||
addParam={addParam}
|
|
||||||
/>,
|
/>,
|
||||||
lambda: () => <LambdaBlock
|
lambda: () => <LambdaBlock
|
||||||
state={state as LambdaBlockState}
|
state={state as LambdaBlockState}
|
||||||
setState={setState as (callback:(p:LambdaBlockState)=>ExprBlockState)=>void}
|
setState={setState as (callback:(p:LambdaBlockState)=>ExprBlockState)=>void}
|
||||||
suggestionPriority={suggestionPriority}
|
suggestionPriority={suggestionPriority}
|
||||||
addParam={addParam}
|
|
||||||
/>,
|
/>,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -79,11 +75,9 @@ export function ExprBlock({state, setState, suggestionPriority, onCancel, addPar
|
||||||
placeholder="<c>"
|
placeholder="<c>"
|
||||||
text=""
|
text=""
|
||||||
suggestion=""
|
suggestion=""
|
||||||
focus={false}
|
|
||||||
onEnter={() => {}}
|
onEnter={() => {}}
|
||||||
onCancel={onCancel}
|
onCancel={onCancel}
|
||||||
onTextChange={() => {}}
|
onTextChange={() => {}}
|
||||||
setFocus={() => {}}
|
|
||||||
extraHandlers={extraHandlers}
|
extraHandlers={extraHandlers}
|
||||||
/>
|
/>
|
||||||
</span>;
|
</span>;
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,6 @@ interface InputProps {
|
||||||
text: string;
|
text: string;
|
||||||
suggestion: string;
|
suggestion: string;
|
||||||
onTextChange: (text: string) => void;
|
onTextChange: (text: string) => void;
|
||||||
focus: boolean;
|
|
||||||
setFocus: (focus: boolean) => void;
|
|
||||||
|
|
||||||
onEnter: () => void;
|
onEnter: () => void;
|
||||||
onCancel: () => void;
|
onCancel: () => void;
|
||||||
|
|
@ -57,22 +55,14 @@ function focusPrevElement() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function Input({placeholder, text, suggestion, onTextChange, focus, setFocus, onEnter, onCancel, extraHandlers, children}: InputProps) {
|
export function Input({placeholder, text, suggestion, onTextChange, onEnter, onCancel, extraHandlers, children}: InputProps) {
|
||||||
const ref = useRef<HTMLInputElement>(null);
|
const ref = useRef<HTMLInputElement>(null);
|
||||||
const [hideChildren, setHideChildren] = useState(false);
|
const [focus, setFocus] = useState<"yes"|"hide"|"no">("no");
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (focus) {
|
|
||||||
ref.current?.focus();
|
|
||||||
setHideChildren(false);
|
|
||||||
}
|
|
||||||
}, [focus]);
|
|
||||||
|
|
||||||
useEffect(() => autoInputWidth(ref, (text+(focus?suggestion:'')) || placeholder), [ref, text, suggestion, focus]);
|
useEffect(() => autoInputWidth(ref, (text+(focus?suggestion:'')) || placeholder), [ref, text, suggestion, focus]);
|
||||||
|
|
||||||
const onKeyDown = (e: KeyboardEvent) => {
|
const onKeyDown = (e: KeyboardEvent) => {
|
||||||
setHideChildren(false);
|
setFocus("yes");
|
||||||
|
|
||||||
const keys = {
|
const keys = {
|
||||||
// auto-complete
|
// auto-complete
|
||||||
Tab: () => {
|
Tab: () => {
|
||||||
|
|
@ -123,8 +113,8 @@ export function Input({placeholder, text, suggestion, onTextChange, focus, setFo
|
||||||
},
|
},
|
||||||
|
|
||||||
Escape: () => {
|
Escape: () => {
|
||||||
if (!hideChildren) {
|
if (focus === "yes") {
|
||||||
setHideChildren(true);
|
setFocus("hide");
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -138,7 +128,7 @@ export function Input({placeholder, text, suggestion, onTextChange, focus, setFo
|
||||||
};
|
};
|
||||||
|
|
||||||
return <span className="inputBlock">
|
return <span className="inputBlock">
|
||||||
{focus && !hideChildren && children}
|
{(focus === "yes") && children}
|
||||||
<span className="editable suggest">{text}{focus && suggestion}</span>
|
<span className="editable suggest">{text}{focus && suggestion}</span>
|
||||||
<input ref={ref}
|
<input ref={ref}
|
||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
|
|
@ -148,8 +138,8 @@ export function Input({placeholder, text, suggestion, onTextChange, focus, setFo
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
onTextChange(e.target.value)}
|
onTextChange(e.target.value)}
|
||||||
onKeyDown={onKeyDown}
|
onKeyDown={onKeyDown}
|
||||||
onFocus={() => setFocus(true)}
|
onFocus={() => setFocus("yes")}
|
||||||
onBlur={() => setFocus(false)}
|
onBlur={() => setFocus("no")}
|
||||||
spellCheck={false}
|
spellCheck={false}
|
||||||
/>
|
/>
|
||||||
</span>;
|
</span>;
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,9 @@ import type { ExprBlockState, State2Props } from "./ExprBlock";
|
||||||
import { attemptParseLiteral } from "./eval";
|
import { attemptParseLiteral } from "./eval";
|
||||||
import { Input } from "./Input";
|
import { Input } from "./Input";
|
||||||
import { initialEditorState } from "./configurations";
|
import { initialEditorState } from "./configurations";
|
||||||
|
import { CallContext } from "./CallContext";
|
||||||
|
import { getActions } from "./actions";
|
||||||
|
import { GlobalContext } from "./GlobalContext";
|
||||||
|
|
||||||
interface Literal {
|
interface Literal {
|
||||||
kind: "literal";
|
kind: "literal";
|
||||||
|
|
@ -35,7 +38,6 @@ export type PrioritizedSuggestionType = [number, ...SuggestionType];
|
||||||
|
|
||||||
interface InputBlockProps extends State2Props<InputBlockState,ExprBlockState> {
|
interface InputBlockProps extends State2Props<InputBlockState,ExprBlockState> {
|
||||||
onCancel: () => void;
|
onCancel: () => void;
|
||||||
addParam: (e: ExprBlockState) => void;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const computeSuggestions = (text, env, suggestionPriority: (s: ResolvedType) => number): PrioritizedSuggestionType[] => {
|
const computeSuggestions = (text, env, suggestionPriority: (s: ResolvedType) => number): PrioritizedSuggestionType[] => {
|
||||||
|
|
@ -61,9 +63,11 @@ const computeSuggestions = (text, env, suggestionPriority: (s: ResolvedType) =>
|
||||||
.sort(([priorityA], [priorityB]) => priorityB - priorityA)
|
.sort(([priorityA], [priorityB]) => priorityB - priorityA)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function InputBlock({ state, setState, suggestionPriority, onCancel, addParam }: InputBlockProps) {
|
export function InputBlock({ state, setState, suggestionPriority, onCancel }: InputBlockProps) {
|
||||||
const {text, focus} = state;
|
const {text, focus} = state;
|
||||||
|
const globalContext = useContext(GlobalContext);
|
||||||
const env = useContext(EnvContext);
|
const env = useContext(EnvContext);
|
||||||
|
const callContext = useContext(CallContext);
|
||||||
const inputRef = useRef<HTMLInputElement>(null);
|
const inputRef = useRef<HTMLInputElement>(null);
|
||||||
const [i, setI] = useState(0); // selected suggestion idx
|
const [i, setI] = useState(0); // selected suggestion idx
|
||||||
|
|
||||||
|
|
@ -121,7 +125,13 @@ export function InputBlock({ state, setState, suggestionPriority, onCancel, addP
|
||||||
},
|
},
|
||||||
" ": (e) => {
|
" ": (e) => {
|
||||||
if (text.length > 0) {
|
if (text.length > 0) {
|
||||||
addParam(initialEditorState);
|
if (callContext.addParam) {
|
||||||
|
callContext.addParam();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const actions = getActions(globalContext, setState);
|
||||||
|
actions.c();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
},
|
},
|
||||||
|
|
@ -129,8 +139,6 @@ export function InputBlock({ state, setState, suggestionPriority, onCancel, addP
|
||||||
|
|
||||||
return <Input
|
return <Input
|
||||||
placeholder="<name or literal>"
|
placeholder="<name or literal>"
|
||||||
focus={focus}
|
|
||||||
setFocus={focus => setState(state => ({...state, focus}))}
|
|
||||||
onCancel={onCancel}
|
onCancel={onCancel}
|
||||||
onEnter={onSelectSuggestion}
|
onEnter={onSelectSuggestion}
|
||||||
onTextChange={onTextChange}
|
onTextChange={onTextChange}
|
||||||
|
|
@ -138,12 +146,12 @@ export function InputBlock({ state, setState, suggestionPriority, onCancel, addP
|
||||||
suggestion={singleSuggestion}
|
suggestion={singleSuggestion}
|
||||||
extraHandlers={extraHandlers}
|
extraHandlers={extraHandlers}
|
||||||
>
|
>
|
||||||
{focus && <span className="suggestionsPlaceholder">
|
<span className="suggestionsPlaceholder">
|
||||||
<Suggestions
|
<Suggestions
|
||||||
suggestions={suggestions}
|
suggestions={suggestions}
|
||||||
onSelect={onSelectSuggestion}
|
onSelect={onSelectSuggestion}
|
||||||
i={i} setI={setI} />
|
i={i} setI={setI} />
|
||||||
</span>}
|
</span>
|
||||||
</Input>
|
</Input>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,11 +21,10 @@ interface LambdaBlockProps<
|
||||||
FnState=ExprBlockState,
|
FnState=ExprBlockState,
|
||||||
InputState=ExprBlockState,
|
InputState=ExprBlockState,
|
||||||
> extends State2Props<LambdaBlockState,ExprBlockState> {
|
> extends State2Props<LambdaBlockState,ExprBlockState> {
|
||||||
addParam: (e: ExprBlockState) => void;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export function LambdaBlock({state, setState, suggestionPriority, addParam}: LambdaBlockProps) {
|
export function LambdaBlock({state, setState, suggestionPriority}: LambdaBlockProps) {
|
||||||
const env = useContext(EnvContext);
|
const env = useContext(EnvContext);
|
||||||
|
|
||||||
const setParamName = paramName => setState(state => ({
|
const setParamName = paramName => setState(state => ({
|
||||||
|
|
@ -59,11 +58,9 @@ export function LambdaBlock({state, setState, suggestionPriority, addParam}: Lam
|
||||||
placeholder="<name>"
|
placeholder="<name>"
|
||||||
text={state.paramName}
|
text={state.paramName}
|
||||||
suggestion=""
|
suggestion=""
|
||||||
focus={state.focus}
|
|
||||||
onEnter={() => {}}
|
onEnter={() => {}}
|
||||||
onCancel={() => {}}
|
onCancel={() => {}}
|
||||||
onTextChange={txt => setParamName(txt)}
|
onTextChange={txt => setParamName(txt)}
|
||||||
setFocus={focus => setState(state => ({...state, focus}))}
|
|
||||||
extraHandlers={{}}
|
extraHandlers={{}}
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
|
|
@ -83,7 +80,6 @@ export function LambdaBlock({state, setState, suggestionPriority, addParam}: Lam
|
||||||
// console.log('suggestionPriority of lambdaInner... just passing through');
|
// console.log('suggestionPriority of lambdaInner... just passing through');
|
||||||
return suggestionPriority(s);
|
return suggestionPriority(s);
|
||||||
}}
|
}}
|
||||||
addParam={addParam}
|
|
||||||
/>
|
/>
|
||||||
</EnvContext>
|
</EnvContext>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ export interface LetInBlockState {
|
||||||
}
|
}
|
||||||
|
|
||||||
interface LetInBlockProps extends State2Props<LetInBlockState,ExprBlockState> {
|
interface LetInBlockProps extends State2Props<LetInBlockState,ExprBlockState> {
|
||||||
addParam: (e: ExprBlockState) => void;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function LetInBlock(props: LetInBlockProps) {
|
export function LetInBlock(props: LetInBlockProps) {
|
||||||
|
|
@ -32,7 +31,7 @@ export function LetInBlock(props: LetInBlockProps) {
|
||||||
</span>
|
</span>
|
||||||
}
|
}
|
||||||
|
|
||||||
function DeclColumns({state: {name, value, inner, focus}, setState, suggestionPriority, addParam}) {
|
function DeclColumns({state: {name, value, inner, focus}, setState, suggestionPriority}) {
|
||||||
const env = useContext(EnvContext);
|
const env = useContext(EnvContext);
|
||||||
const globalContext = useContext(GlobalContext);
|
const globalContext = useContext(GlobalContext);
|
||||||
|
|
||||||
|
|
@ -55,11 +54,9 @@ function DeclColumns({state: {name, value, inner, focus}, setState, suggestionPr
|
||||||
placeholder="<name>"
|
placeholder="<name>"
|
||||||
text={name}
|
text={name}
|
||||||
suggestion=""
|
suggestion=""
|
||||||
focus={focus}
|
|
||||||
onEnter={() => {}}
|
onEnter={() => {}}
|
||||||
onCancel={() => {}}
|
onCancel={() => {}}
|
||||||
onTextChange={name => setState(state => ({...state, name}))}
|
onTextChange={name => setState(state => ({...state, name}))}
|
||||||
setFocus={focus => setState(state => ({...state, focus}))}
|
|
||||||
extraHandlers={{}}
|
extraHandlers={{}}
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
|
|
@ -70,7 +67,6 @@ function DeclColumns({state: {name, value, inner, focus}, setState, suggestionPr
|
||||||
setState={setValue}
|
setState={setValue}
|
||||||
suggestionPriority={valueSuggestionPriority}
|
suggestionPriority={valueSuggestionPriority}
|
||||||
onCancel={() => setState(state => state.inner)} // keep inner
|
onCancel={() => setState(state => state.inner)} // keep inner
|
||||||
addParam={addParam}
|
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
{inner.kind === "let" &&
|
{inner.kind === "let" &&
|
||||||
|
|
@ -80,14 +76,13 @@ function DeclColumns({state: {name, value, inner, focus}, setState, suggestionPr
|
||||||
state={inner}
|
state={inner}
|
||||||
setState={setInner}
|
setState={setInner}
|
||||||
suggestionPriority={suggestionPriority}
|
suggestionPriority={suggestionPriority}
|
||||||
addParam={addParam}
|
|
||||||
/>
|
/>
|
||||||
</EnvContext>
|
</EnvContext>
|
||||||
}
|
}
|
||||||
</>;
|
</>;
|
||||||
}
|
}
|
||||||
|
|
||||||
function InnerMost({state, setState, suggestionPriority, addParam}) {
|
function InnerMost({state, setState, suggestionPriority}) {
|
||||||
const env = useContext(EnvContext);
|
const env = useContext(EnvContext);
|
||||||
const globalContext = useContext(GlobalContext);
|
const globalContext = useContext(GlobalContext);
|
||||||
const setInner = callback => setState(state => ({...state, inner: callback(state.inner)}));
|
const setInner = callback => setState(state => ({...state, inner: callback(state.inner)}));
|
||||||
|
|
@ -100,7 +95,6 @@ function InnerMost({state, setState, suggestionPriority, addParam}) {
|
||||||
state={state.inner}
|
state={state.inner}
|
||||||
setState={setInner}
|
setState={setInner}
|
||||||
suggestionPriority={suggestionPriority}
|
suggestionPriority={suggestionPriority}
|
||||||
addParam={addParam}
|
|
||||||
/>
|
/>
|
||||||
</EnvContext>;
|
</EnvContext>;
|
||||||
}
|
}
|
||||||
|
|
@ -111,7 +105,6 @@ function InnerMost({state, setState, suggestionPriority, addParam}) {
|
||||||
setState={setInner}
|
setState={setInner}
|
||||||
suggestionPriority={suggestionPriority}
|
suggestionPriority={suggestionPriority}
|
||||||
onCancel={onCancel} // keep value
|
onCancel={onCancel} // keep value
|
||||||
addParam={addParam}
|
|
||||||
/>
|
/>
|
||||||
</EnvContext>
|
</EnvContext>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import {getType, getInst, getSymbol, Double, Int, symbolFunction, symbolProduct, symbolSum, symbolDict, symbolSet, symbolList, eqType, match, getLeft, getRight, dict, Bool, set, Unit, symbolType, symbolUUID, getHumanReadableName} from "dope2";
|
import {getType, getInst, getSymbol, Double, Int, symbolFunction, symbolProduct, symbolSum, symbolDict, symbolSet, symbolList, eqType, match, getLeft, getRight, dict, Bool, set, Unit, symbolType, symbolUUID, getHumanReadableName, Ordering} from "dope2";
|
||||||
|
|
||||||
import "./Value.css";
|
import "./Value.css";
|
||||||
import { Type } from "./Type";
|
import { Type } from "./Type";
|
||||||
|
|
@ -18,6 +18,9 @@ export function Value({dynamic}) {
|
||||||
if (eqType(type)(Unit)) {
|
if (eqType(type)(Unit)) {
|
||||||
return <ValueUnit/>;
|
return <ValueUnit/>;
|
||||||
}
|
}
|
||||||
|
if (eqType(type)(Ordering)) {
|
||||||
|
return <ValueOrdering val={inst}/>;
|
||||||
|
}
|
||||||
|
|
||||||
const symbol = getSymbol(type);
|
const symbol = getSymbol(type);
|
||||||
switch (symbol) {
|
switch (symbol) {
|
||||||
|
|
@ -82,3 +85,6 @@ function ValueUnit() {
|
||||||
function ValueUUID({val}) {
|
function ValueUUID({val}) {
|
||||||
return <span className="valueUUID">{getHumanReadableName(val)}</span>;
|
return <span className="valueUUID">{getHumanReadableName(val)}</span>;
|
||||||
}
|
}
|
||||||
|
function ValueOrdering({val}) {
|
||||||
|
return <span className="valueOrdering">{{[-1]: "LessThan", [0]: "Equal", [1]: "GreaterThan" }[val]}</span>
|
||||||
|
}
|
||||||
|
|
@ -3,7 +3,7 @@ import { removeFocus } from "./eval";
|
||||||
|
|
||||||
export const actionShortcuts: [string, string[], string][] = [
|
export const actionShortcuts: [string, string[], string][] = [
|
||||||
["call" , ['c'], "expr ⌴" ],
|
["call" , ['c'], "expr ⌴" ],
|
||||||
["transform", ['.'], "⌴ expr" ],
|
["transform", ['t'], "⌴ expr" ],
|
||||||
["assign" , ['a'], "let (⌴ = expr) in ⌴"],
|
["assign" , ['a'], "let (⌴ = expr) in ⌴"],
|
||||||
["declare" , ['d'], "let (⌴ = ⌴) in expr"],
|
["declare" , ['d'], "let (⌴ = ⌴) in expr"],
|
||||||
["lambda" , ['l'], "λ⌴. expr" ],
|
["lambda" , ['l'], "λ⌴. expr" ],
|
||||||
|
|
@ -19,7 +19,7 @@ export function getActions(globalContext, setState) {
|
||||||
}));
|
}));
|
||||||
globalContext?.doHighlight.call();
|
globalContext?.doHighlight.call();
|
||||||
},
|
},
|
||||||
'.': () => {
|
t: () => {
|
||||||
setState(state => ({
|
setState(state => ({
|
||||||
kind: "call",
|
kind: "call",
|
||||||
fn: initialEditorState,
|
fn: initialEditorState,
|
||||||
|
|
|
||||||
24
src/eval.ts
24
src/eval.ts
|
|
@ -1,4 +1,4 @@
|
||||||
import { Double, fnType, getHumanReadableName, getSymbol, Int, mergeUnifications, NotAFunctionError, occurring, prettyT, prettyU, recomputeTypeVars, reduceUnification, substitute, symbolFunction, trie, TYPE_VARS, UNBOUND_SYMBOLS, UnifyError, unifyLL, transitivelyGrow, isTypeVar, set, compareTypes, recomputeTypeVarsWithInverse } from "dope2";
|
import { Double, fnType, getHumanReadableName, getSymbol, Int, isTypeVar, mergeUnifications, NotAFunctionError, occurring, prettyT, prettyU, recomputeTypeVarsWithInverse, reduceUnification, substitute, symbolFunction, trie, TYPE_VARS, UNBOUND_SYMBOLS, UnifyError, unifyLL } from "dope2";
|
||||||
|
|
||||||
import type { ExprBlockState } from "./ExprBlock";
|
import type { ExprBlockState } from "./ExprBlock";
|
||||||
import type { InputValueType } from "./InputBlock";
|
import type { InputValueType } from "./InputBlock";
|
||||||
|
|
@ -90,13 +90,15 @@ export function evalInputBlock(text: string, value: InputValueType, env: Environ
|
||||||
export function evalCallBlock(fn: ExprBlockState, input: ExprBlockState, env: Environment): [ResolvedType,Environment] {
|
export function evalCallBlock(fn: ExprBlockState, input: ExprBlockState, env: Environment): [ResolvedType,Environment] {
|
||||||
const [fnResolved, env2] = evalEditorBlock(fn, env);
|
const [fnResolved, env2] = evalEditorBlock(fn, env);
|
||||||
const [inputResolved, env3] = evalEditorBlock(input, env2);
|
const [inputResolved, env3] = evalEditorBlock(input, env2);
|
||||||
console.log('==== evalCallBlock ====');
|
if (VERBOSE) {
|
||||||
console.log('env :', env);
|
console.log('==== evalCallBlock ====');
|
||||||
console.log('fnResolved :', fnResolved);
|
console.log('env :', env);
|
||||||
console.log('env2 :', env2);
|
console.log('fnResolved :', fnResolved);
|
||||||
console.log('inputResolved:', inputResolved);
|
console.log('env2 :', env2);
|
||||||
console.log('env3 :', env3);
|
console.log('inputResolved:', inputResolved);
|
||||||
console.log('=======================');
|
console.log('env3 :', env3);
|
||||||
|
console.log('=======================');
|
||||||
|
}
|
||||||
return evalCallBlock2(fnResolved, inputResolved, env3);
|
return evalCallBlock2(fnResolved, inputResolved, env3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -236,7 +238,7 @@ function evalCallBlock3(fnResolved: ResolvedType, inputResolved: ResolvedType, e
|
||||||
// if the above statement did not throw => types are compatible...
|
// if the above statement did not throw => types are compatible...
|
||||||
if (inputResolved.kind === "value" && fnResolved.kind === "value") {
|
if (inputResolved.kind === "value" && fnResolved.kind === "value") {
|
||||||
const outValue = fnResolved.i(inputResolved.i);
|
const outValue = fnResolved.i(inputResolved.i);
|
||||||
console.log('outValue:', outValue);
|
// console.log('outValue:', outValue);
|
||||||
return [{
|
return [{
|
||||||
kind: "value",
|
kind: "value",
|
||||||
i: outValue,
|
i: outValue,
|
||||||
|
|
@ -255,7 +257,9 @@ function evalCallBlock3(fnResolved: ResolvedType, inputResolved: ResolvedType, e
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
// if ((e instanceof UnifyError)) {
|
// if ((e instanceof UnifyError)) {
|
||||||
console.log('UnifyError!', (e as Error).message);
|
if (VERBOSE) {
|
||||||
|
console.log('UnifyError!', (e as Error).message);
|
||||||
|
}
|
||||||
// even though fn was incompatible with the given parameter, we can still suppose that our output-type will be that of fn...?
|
// even though fn was incompatible with the given parameter, we can still suppose that our output-type will be that of fn...?
|
||||||
const outType = fnResolved.t.params[1](fnResolved.t);
|
const outType = fnResolved.t.params[1](fnResolved.t);
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue