import type { TypeInstance } from './type.js'; import { typeSystem } from './type-system.js'; type MatcherData = { type: Type; data: Data; }; export class MatcherCreator { createMatcher(type: Type, data: Data) { return { type, data }; } } export class Matcher { constructor( private readonly list: MatcherData[], private readonly _match: (type: Type, target: TypeInstance) => boolean = ( type, target ) => typeSystem.unify(target, type) ) {} all(): MatcherData[] { return this.list; } allMatched(type: TypeInstance): MatcherData[] { const result: MatcherData[] = []; for (const t of this.list) { if (this._match(t.type, type)) { result.push(t); } } return result; } allMatchedData(type: TypeInstance): Data[] { const result: Data[] = []; for (const t of this.list) { if (this._match(t.type, type)) { result.push(t.data); } } return result; } find( f: (data: MatcherData) => boolean ): MatcherData | undefined { return this.list.find(f); } findData(f: (data: Data) => boolean): Data | undefined { return this.list.find(data => f(data.data))?.data; } isMatched(type: Type, target: TypeInstance) { return this._match(type, target); } match(type: TypeInstance) { for (const t of this.list) { if (this._match(t.type, type)) { return t.data; } } return; } } export class Matcher_ { constructor( private readonly list: Value[], private readonly getType: (value: Value) => Type, private readonly matchFunc: ( type: Type, target: TypeInstance ) => boolean = (type, target) => typeSystem.unify(target, type) ) {} all(): Value[] { return this.list; } allMatched(type: TypeInstance): Value[] { const result: Value[] = []; for (const t of this.list) { const tType = this.getType(t); if (this.matchFunc(tType, type)) { result.push(t); } } return result; } find(f: (data: Value) => boolean): Value | undefined { return this.list.find(f); } isMatched(type: Type, target: TypeInstance) { return this.matchFunc(type, target); } match(type: TypeInstance) { for (const t of this.list) { const tType = this.getType(t); if (this.matchFunc(tType, type)) { return t; } } return; } }