import * as ut from './type-util.js'; import { N4, T4 } from './type-util.js'; import type Cion from '@taiyakihitotsu/cion'; export type t4 = string | ut.T4; type ArgReg = '([a-Z_-]+)?( [a-Z_-]+)*'; export type pickArgs = Fn extends string ? Cion.Lisp<`(re-find '\\[${ArgReg}\\]' (re-find '^\\(fn \\[${ArgReg}\\]' '${Fn}'))`> extends infer r extends string ? r extends `''` ? never : r : never : never; type makeArgs = N extends 0 ? '' : N extends 1 ? `x` : N extends 2 ? `x y` : N extends 3 ? `x y z` : N extends 4 ? `x y z zz` : never; type expandArgs = `(fn [${makeArgs}] (${S} ${makeArgs}))`; export type resolveLambda = S extends keyof bi ? expandArgs extends infer r extends N4 ? r : never> : S; type resolveLambdaPre = S extends keyof bi ? bi[S] extends keyof bi ? resolveLambdaPre : bi[S] : S; export type countArgsString = Cion.Lisp<`(let [r (split ${S} ' ')] (if (= r ['[]']) 0 (count r)))`>; type _snmap = { '0': 0; '1': 1; '2': 2; '3': 3; '4': 4; }; export type countArgs = countArgsString>> extends infer C extends keyof _snmap ? _snmap[C] : never; type _MergeTuple = Fns extends [infer F extends string, ...infer R extends T4] ? Args extends [infer AF extends string, ...infer AR extends string[]] ? _MergeTuple : never : [] extends Fns ? `(fn [${Used}] (and${SS}))` : never; export type MergeTuple = _MergeTuple; export type MergePreStr = _MergePreStr; export type _MergePreStr = countArgs & countArgs extends never ? false : XPre extends '' | 'any?' ? YPre : YPre extends '' | 'any?' ? XPre : XPre extends keyof bi ? _MergePreStr, YPre, XPre, shrinkY> : YPre extends keyof bi ? _MergePreStr, shrinkX, YPre> : pickArgs extends `'[${infer Args}]'` ? `(fn [${Args}] (and (${shrinkX extends '' ? XPre : shrinkX} ${Args}) (${shrinkY extends '' ? YPre : shrinkY} ${Args})))` : never; type Primitive = boolean | string | number; type PreNum = string | number; export type Zero = `zero?`; export type One = `(fn [n] (= n 1))`; export type NotZero = `(fn [n] (-> n zero? not))`; export type VectN = `(fn [n] (and (vector? n) (= ${N} (count n))))`; export type Range = `(fn [n] (< ${N} n ${M}))`; export type Eq = `(fn [n] (= ${N} n))`; export type Vect = `(fn [n] (= ${N} (count n)))`; export type Greater = `(fn [n] (< ${N} n))`; export type Less = `(fn [n] (> ${N} n))`; export type PosInt = 'pos-int?'; export type NegInt = 'neg-int?'; export type Num = 'number?'; export type EmailRegex = `'(([^<>()[\\].,;: @"]+(\\.[^<>()[\\].,;: @"]+)*)|(".+"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\])|(([a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,}))'`; export type Email = `(fn [n] (let [r (re-find ${EmailRegex} n)] (not (= '' r))))`; export type match = `(fn [a b] (let [x (re-find a b)] (if (not (= '' x)) x nil)))`; type checkPreMap> = Map; export type arithmetic2 = `(fn [x y] (and (number? x) (number? y)))`; export type number0 = `number?`; export type compare = arithmetic2; type _notdiv0 = `(fn [x y] (and (number? x) ((fn [n] (and (number? n) (not (zero? n)))) y)))`; type arithmetic = checkPreMap<{ add: arithmetic2; sub: arithmetic2; mul: arithmetic2; div: _notdiv0; mod: _notdiv0; rem: _notdiv0; trunc: number0; floor: number0; inc: number0; dec: number0; abs: number0; numnot: number0; gt: compare; lt: compare; gte: compare; lte: compare; }>; type signs = checkPreMap<{ "+": bi['add']; "-": bi['sub']; "*": bi['mul']; "/": bi['div']; "%": bi['rem']; ">": bi['gt']; "<": bi['lt']; "=": bi['eq']; ">=": bi['gte']; "<=": bi['lte']; }>; type checkOne = `(fn [x] (any? x))`; type checker = checkPreMap<{ 'number?': checkOne; 'string?': checkOne; 'vector?': checkOne; 'map?': checkOne; 'fn?': checkOne; 'ifn?': checkOne; 'int?': checkOne; 'pos?': checkOne; 'neg?': checkOne; 'nat?': checkOne; 'pos-int?': checkOne; 'neg-int?': checkOne; 'odd?': checkOne; 'even?': checkOne; 'zero?': checkOne; 'keyword?': checkOne; 'empty?': checkOne; 'boolean?': checkOne; 'type': checkOne; 'some?': checkOne; 'nil?': checkOne; 'any?': checkOne; }>; type checkPrim = `(fn [x] (or (number? x) (string? x) (boolean? x)))`; type isstr2 = `(fn [x y] (and (string? x) (string? y)))`; type isstr3 = `(fn [x y z] (and (string? x) (string? y) (string? z)))`; type stringf = checkPreMap<{ str1: checkPrim; str2: `(fn [x y] (and (${checkPrim} x) (${checkPrim} y)))`; str3: `(fn [x y z] (and (${checkPrim} x) (${checkPrim} y) (${checkPrim} z)))`; refind: isstr2; rematch: isstr2; split: isstr2; subs: `(fn [x y z] (and (string? x) (nat? y) (nat? z) (< y z)))`; replace: isstr3; join: `(fn [x y] (and (string? x) (vector? y) (every? prim? y)))`; }>; type logical1 = `boolean?`; type logical2 = `(fn [x y] (and (boolean? x) (boolean? y))`; type logical = checkPreMap<{ and: logical2; or: logical2; not: logical1; if: `(fn [x y z] (boolean? x))`; eq: `(fn [x y] (and (some? x) (some? y)))`; }>; type _getIn = `(fn [x y] (some? (get-in x y)))`; type checkFmap = `(fn [x y] (and (fn? x) (vector? y)))`; type data = checkPreMap<{ get: `(fn [x y] (some? (get x y)))`; 'get-in': _getIn; first: `(fn [m] (-> m first some?))`; second: `(fn [m] (-> m second some?))`; third: `(fn [m] (-> m third some?))`; last: `(fn [m] (-> m last some?))`; butlast: `(fn [m] (-> m count dec zero?))`; mapLax: checkFmap; reduceLax: `(fn [x y z] (and (fn? x) (vector? z)))`; map: `(fn [x y] (let [v y tf (fn [v] (map type v))] (= (tf v) (tf (map x v)))))`; filter: checkFmap; remove: checkFmap; 'every?': checkFmap; some: checkFmap; apply: `(fn [f v] (and (vector? v) (fn? f) (apply f v)))`; zipmap: `(fn [v vv] (and (vector? v) (vector? vv)))`; count: 'vector?'; drop: `(fn [n v] (and (pos-int? n) (vector? v)))`; take: `(fn [n v] (and (pos-int? n) (vector? v)))`; reverse: 'vector?'; conj: `(fn [v e] (vector? v))`; concat: `(fn [v vv] (and (vector? v) (vector? vv)))`; interleave: `(fn [v vv] (and (vector? v) (vector? vv)))`; reduce: `(fn [f init vs] (let [letf f a init rvs (map (fn [n] (take n vs)) (range 1 (inc (count vs)))) redpartf (fn [v] (reduce letf a v))] (->> rvs (map redpartf) (map type) )))`; assocLax: `(fn [x y z] (not (and (vector? x) (keyword? y))))`; updateLax: `(fn [x y z] (and (${data['assocLax']} x y z) (fn? z)))`; assocInLax: `(fn [x y z] (and (${data['get-in']} x y z) (vector? y)))`; updateInLax: `(fn [x y z] (and (${_getIn} x y z) (fn? z) (vector? y)))`; }>; type _expandCheck = `(= (type (get-in x y)) (type (get-in r y)))`; type _assocInStrict = `(fn [x y z] (let [r (assoc-in x y z)] ${_expandCheck}))`; type _updateInStrict = `(fn [x y z] (let [r (update-in x y z)] ${_expandCheck}))`; type _get3 = `(fn [x y z] (get x y))`; type dataStrict = checkPreMap<{ assoc: MergePreStr<_get3, MergePreStr>; update: MergePreStr<_get3, MergePreStr>; 'assoc-in': MergePreStr; 'update-in': MergePreStr; }>; export type bi = arithmetic & signs & checker & logical & data & dataStrict & stringf; export declare namespace bi { type add = bi['add']; type sub = bi['sub']; type mul = bi['mul']; type div = bi['div']; type mod = bi['mod']; type rem = bi['rem']; type floor = bi['floor']; type trunc = bi['trunc']; type gt = bi['gt']; type lt = bi['lt']; type eq = bi['eq']; type gte = bi['gte']; type lte = bi['lte']; type inc = bi['inc']; type dec = bi['dec']; type abs = bi['abs']; type isnum = bi['number?']; type isstr = bi['string?']; type isvec = bi['vector?']; type ismap = bi['map?']; type isfn = bi['fn?']; type ififn = bi['ifn?']; type isint = bi['int?']; type ispos = bi['pos?']; type isneg = bi['neg?']; type isnat = bi['nat?']; type isposint = bi['pos-int?']; type isnegint = bi['neg-int?']; type isodd = bi['odd?']; type iseven = bi['even?']; type iszero = bi['zero?']; type iskey = bi['keyword?']; type isempty = bi['empty?']; type isbool = bi['boolean?']; type Type = bi['type']; type isevery = bi['every?']; type some = bi['some']; type isnil = bi['nil?']; type issome = bi['some?']; type or = bi['or']; type and = bi['and']; type not = bi['not']; type If = `(fn [x y z] (boolean? x))`; type update = bi['update']; type assoc = bi['assoc']; type get = bi['get']; type updateIn = bi['update-in']; type assocIn = bi['assoc-in']; type getIn = bi['get-in']; type updateLax = bi['updateLax']; type assocLax = bi['assocLax']; type updateInLax = bi['updateInLax']; type assocInLax = bi['assocInLax']; type first = bi['first']; type second = bi['second']; type third = bi['third']; type last = bi['last']; type butlast = bi['butlast']; type map = bi['map']; type filter = bi['filter']; type remove = bi['remove']; type apply = bi['apply']; type zipmap = bi['zipmap']; type reduce = bi['reduce']; type count = bi['count']; type drop = bi['drop']; type take = bi['take']; type reverse = bi['reverse']; type conj = bi['conj']; type concat = bi['concat']; type interleave = bi['interleave']; type str1 = bi['str1']; type str2 = bi['str2']; type str3 = bi['str3']; type refind = bi['refind']; type rematch = bi['rematch']; type split = bi['split']; type subs = bi['subs']; type replace = bi['replace']; type join = bi['join']; } export type getPre = S extends keyof bi ? bi[S] : S; export type * as pre from './pre.js';