Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Underscore #43

Merged
merged 17 commits into from
Jan 31, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
78ead39
Consoleコンポーネントのスタイルを修正し、ReduceRowコンポーネントのプロパティを整理。コマンド実行後の処理を追加。
todays-mitsui Jan 30, 2025
7bd439c
ReduceRowコンポーネントからデバッグ用のconsole.logを削除し、コマンド実行時のunderscoreの更新処理を整理
todays-mitsui Jan 30, 2025
11dc8f0
単項の式を簡約する条件を追加
todays-mitsui Jan 30, 2025
e7d0980
テストケースを追加
todays-mitsui Jan 30, 2025
d279a04
エイリアス機能を追加し、calcモジュールに統合
todays-mitsui Jan 30, 2025
2fb895a
Revert "テストケースを追加"
todays-mitsui Jan 30, 2025
020c783
Revert "単項の式を簡約する条件を追加"
todays-mitsui Jan 30, 2025
8eaefae
エンジンモジュールを削除し、calcモジュールのエイリアス機能を強化
todays-mitsui Jan 30, 2025
05889d0
エイリアス機能のテストケースを追加し、setup関数を修正
todays-mitsui Jan 30, 2025
3416f61
コードの変更がありませんでした
todays-mitsui Jan 30, 2025
c2f24a7
テストケースを追加し、setup関数を修正してエイリアス機能を強化
todays-mitsui Jan 31, 2025
8817f4a
エイリアス機能を追加し、Reducer構造体に対応する変更を加えました
todays-mitsui Jan 31, 2025
fcf406f
ski:build
todays-mitsui Jan 31, 2025
4306f6c
エイリアス機能を追加し、関連するコンポーネントとサービスを更新
todays-mitsui Jan 31, 2025
ce22ca4
エイリアス機能の表示を改善し、コンテキストと設定のコンポーネントを更新
todays-mitsui Jan 31, 2025
87d701f
エイリアスの信号をセッションストレージに永続化するように変更
todays-mitsui Jan 31, 2025
a06d9e8
Unlambdaコマンドの結果をエイリアスに追加する機能を実装
todays-mitsui Jan 31, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions mogul/src/components/Console.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,9 @@
li:last-child :global(.expr-mark-reducible) {
display: none;
}
li:first-child :global(.expr-mark-reducible) {
display: inline;
}

li:hover {
:global(.reducible) {
Expand Down
4 changes: 2 additions & 2 deletions mogul/src/components/Console.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import classNames from "classnames";
import { For, Index, type JSX, Show, createEffect, onCleanup } from "solid-js";
import { For, Index, type JSX, Show, onMount, onCleanup } from "solid-js";
import { type DisplayStyle, renderFunc, sortFuncs } from "~/service/func";
import {
consoleOut,
Expand Down Expand Up @@ -29,7 +29,7 @@ interface ConsoleProps {

export default function Console(props: ConsoleProps): JSX.Element {
let wrapper: HTMLDivElement | undefined;
createEffect(() => {
onMount(() => {
if (wrapper == null) return;
const observer = createObserver(wrapper);
onCleanup(() => {
Expand Down
33 changes: 20 additions & 13 deletions mogul/src/components/ReduceRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,33 @@ import {
markReducible,
} from "~/lib/mark";

export function ReduceRow(props: {
interface ReduceRowProps {
expr: string;
reducedRange?: ExprRange | null;
reducibleRange?: ReducibleRange | null;
}): JSX.Element {
}

export function ReduceRow(props: ReduceRowProps): JSX.Element {
let reducedRef: HTMLSpanElement | undefined;
if (props.reducedRange != null) {
const reduced = markReduced(props.expr, props.reducedRange);
onMount(() => {
let reducibleRef: HTMLSpanElement | undefined;

onMount(() => {
if (props.reducedRange == null && props.reducibleRange == null) {
if (reducibleRef != null) {
reducibleRef.innerText = props.expr;
}
}

if (props.reducedRange != null) {
const reduced = markReduced(props.expr, props.reducedRange);
reducedRef?.appendChild(reduced);
});
}
}

let reducibleRef: HTMLSpanElement | undefined;
if (props.reducibleRange != null) {
const reducible = markReducible(props.expr, props.reducibleRange);
onMount(() => {
if (props.reducibleRange != null) {
const reducible = markReducible(props.expr, props.reducibleRange);
reducibleRef?.appendChild(reducible);
});
}
}
});

return (
<>
Expand Down
4 changes: 4 additions & 0 deletions mogul/src/components/SideTools/Context.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
font-size: .9rem;
font-weight: 500;
color: #666;

&:not(:first-child) {
margin-top: 1em;
}
}

li {
Expand Down
20 changes: 18 additions & 2 deletions mogul/src/components/SideTools/Context.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { type JSX, For } from "solid-js";
import { type JSX, For, Show } from "solid-js";
import { context } from "~/signals";
import { type DisplayStyle, renderFunc, sortFuncs } from "~/service/func";
import { aliases } from "~/service/aliases";
import styles from "./Context.module.css";

interface ContextProps {
Expand All @@ -9,10 +10,25 @@ interface ContextProps {

export default function Context(props: ContextProps): JSX.Element {
const funcs = () =>
sortFuncs(Object.values(context())).map((func) => renderFunc(func));
sortFuncs(Object.values(context())).map((func) =>
renderFunc(func, props.displayStyle),
);

return (
<div class={styles.context}>
<Show when={aliases().length > 0}>
<h2>Shortcut Reference</h2>
<ul>
<For each={aliases()}>
{(alias) => (
<li>
<code>{alias}</code>
</li>
)}
</For>
</ul>
</Show>

<h2>Context</h2>
<ul>
<For each={funcs()}>
Expand Down
9 changes: 2 additions & 7 deletions mogul/src/components/SideTools/Settings.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
import type { JSX } from "solid-js";
import styles from "./Settings.module.css";
import {
resetContext,
clearContext,
displayStyle,
setDisplayStyle,
sideTools,
} from "~/signals";
import { displayStyle, setDisplayStyle, sideTools } from "~/signals";
import { resetContext, clearContext } from "~/service/context";

export default function Settings(): JSX.Element {
return (
Expand Down
26 changes: 26 additions & 0 deletions mogul/src/service/aliases.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { aliases as getAliases, setAliases, displayStyle } from "~/signals";
import { type Aliases, type Expr, renderExpr } from "../../../ski3/pkg/index";
export { Aliases };

export function addAlias(expr: Expr) {
setAliases((prev) => {
const newAliases: Aliases = { _: expr };
if (prev._) newAliases._0 = prev._;
if (prev._0) newAliases._1 = prev._0;
if (prev._1) newAliases._2 = prev._1;
if (prev._2) newAliases._3 = prev._2;
if (prev._3) newAliases._4 = prev._3;
if (prev._4) newAliases._5 = prev._4;
if (prev._5) newAliases._6 = prev._5;
if (prev._6) newAliases._7 = prev._6;
if (prev._7) newAliases._8 = prev._7;
if (prev._8) newAliases._9 = prev._8;
return newAliases;
});
}

export function aliases(): string[] {
return Object.entries(getAliases())
.toSorted(([a], [b]) => a.localeCompare(b))
.map(([name, expr]) => `${name} = ${renderExpr(expr, displayStyle())}`);
}
32 changes: 26 additions & 6 deletions mogul/src/service/command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
reduceTail,
} from "~/service/reduce";
import { unlambda } from "~/service/unlambda";
import { addAlias } from "~/service/aliases";
import { type Command, parseCommand } from "../../../ski3/pkg/index";
export { type Command, parseCommand };

Expand Down Expand Up @@ -53,6 +54,9 @@ export async function runCommand(command: Command) {
},
]);
},
onEnd: (result) => {
addAlias(result.expr);
},
});
return;
}
Expand All @@ -63,19 +67,28 @@ export async function runCommand(command: Command) {
readonly formed: FormedReducedExpr;
} | null>(null);
await reduceLast(command.expr, {
onInit: ({ formed }) => {
putConsoleItem({
type: "ReduceLast",
formed,
reduceResult,
});
onInit: ({ formed, hasNext }) => {
hasNext
? putConsoleItem({
type: "ReduceLast",
formed,
reduceResult,
})
: putConsoleItem({
type: "Reduce",
formed,
reduceResults: () => [],
});
},
onReduce: ({ step, formed }) => {
setReduceResult({
step,
formed,
});
},
onEnd: (result) => {
addAlias(result.expr);
},
});
return;
}
Expand Down Expand Up @@ -105,6 +118,9 @@ export async function runCommand(command: Command) {
},
]);
},
onEnd: (result) => {
addAlias(result.expr);
},
});
return;
}
Expand Down Expand Up @@ -134,6 +150,9 @@ export async function runCommand(command: Command) {
},
]);
},
onEnd: (result) => {
addAlias(result.expr);
},
});
return;
}
Expand All @@ -159,6 +178,7 @@ export async function runCommand(command: Command) {
case "Unlambda": {
const result = unlambda(command.level, command.expr);
putConsoleItem({ type: "Unlambda", expr: command.expr, result });
addAlias(result);
return;
}
}
Expand Down
11 changes: 9 additions & 2 deletions mogul/src/service/context.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { context, setContext } from "~/signals";
import type { Func } from "../../../ski3/pkg/index";
export type { Context } from "../../../ski3/pkg/index";
import { type Func, defaultContext } from "../../../ski3/pkg/index";

export function updateFunction(func: Func) {
setContext((prev) => ({ ...prev, [func.name]: func }));
Expand All @@ -17,3 +16,11 @@ export function deleteFunction(identifier: string) {
export function queryFunction(identifier: string): Func | null {
return context()[identifier] ?? null;
}

export function resetContext() {
setContext(defaultContext());
}

export function clearContext() {
setContext({});
}
45 changes: 26 additions & 19 deletions mogul/src/service/reduce.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { context, displayStyle } from "~/signals";
import { context, aliases, displayStyle } from "~/signals";
import {
type Expr,
type FormedReducedExpr,
Expand All @@ -12,48 +12,51 @@ const MAX_STEPS = 1000;
interface ReduceOptions {
onInit?: (reducer: Reducer) => void;
onReduce?: (reduceResult: ReduceResult) => void;
onEnd?: (reduceResult: ReduceResult) => void;
maxSteps?: number;
}

export async function reduceHead(
expr: Expr,
options?: ReduceOptions,
): Promise<void> {
const { onInit, onReduce, maxSteps } = options ?? {};
const { onInit, onReduce, onEnd, maxSteps } = options ?? {};

const reducer = new Reducer(context(), expr, displayStyle());
const reducer = new Reducer(context(), aliases(), expr, displayStyle());

onInit?.(reducer);

let reduceResult: ReduceResult | null = null;
while (true) {
const result = reducer.next();

if (result.done) return;
if (result.done) break;

const reduceResult = result.value;
reduceResult = result.value;

if (reduceResult == null) continue;

onReduce?.(reduceResult);

if ((maxSteps ?? MAX_STEPS) <= reduceResult.step) return;
if ((maxSteps ?? MAX_STEPS) <= reduceResult.step) break;

await new Promise((resolve) => setTimeout(resolve, 0));
}

reduceResult && onEnd?.(reduceResult);
}

export async function reduceTail(
expr: Expr,
options: ReduceOptions & { count: number },
): Promise<void> {
const { onInit, onReduce, maxSteps, count } = options;
const { onInit, onReduce, onEnd, maxSteps, count } = options;

const reducer = new Reducer(context(), expr, displayStyle());
const reducer = new Reducer(context(), aliases(), expr, displayStyle());

onInit?.(reducer);

let reduceResults: ReduceResult[] = [];

while (true) {
const result = reducer.next();

Expand All @@ -79,34 +82,38 @@ export async function reduceTail(
for (const reduceResult of tail) {
onReduce?.(reduceResult);
}

if (tail.length > 0) {
onEnd?.(tail[tail.length - 1]);
}
}

export async function reduceLast(
expr: Expr,
options?: ReduceOptions,
): Promise<void> {
const { onInit, onReduce, maxSteps } = options ?? {};
const { onInit, onReduce, onEnd, maxSteps } = options ?? {};

const reducer = new Reducer(context(), expr, displayStyle());
const reducer = new Reducer(context(), aliases(), expr, displayStyle());

onInit?.(reducer);

let reduceResult: ReduceResult | null = null;
while (true) {
const result = reducer.next();

if (result.done) return;
if (result.done) break;

const reduceResult = result.value;
reduceResult = result.value;

if (reduceResult == null) continue;

if (!reducer.hasNext) {
onReduce?.(reduceResult);
return;
}

if ((maxSteps ?? MAX_STEPS) <= reduceResult.step) return;
if (!reducer.hasNext) break;
if ((maxSteps ?? MAX_STEPS) <= reduceResult.step) break;

await new Promise((resolve) => setTimeout(resolve, 0));
}

reduceResult && onReduce?.(reduceResult);
reduceResult && onEnd?.(reduceResult);
}
Loading