import {Function, ModuleMetaCircular, getIn, getOut} from "./metacircular.js"; import {ModuleTyped} from "./typed.js"; import {ModuleBool} from "./primitives/bool.js"; import { Double_to_Double_to_Double, ModuleDouble, mulDouble } from "./primitives/double.js"; import {Int_to_Int_to_Int, ModuleInt, mulInt} from "./primitives/int.js"; import {Int} from "./primitives/symbols.js"; import { makeSquare } from "./lib/square.js"; import {makeIdFn} from "./lib/id.js"; import {ModuleLiterals} from "./lib/literals.js"; import {DefaultMap} from "./util.js"; import { ModuleModule } from "./structures/module.js"; class Context { constructor(mod) { // input type -> Function-signature this.functionsFrom = new DefaultMap(() => []); this.functionsTo = new DefaultMap(() => []); this.types = new DefaultMap(() => []); this.instances = new DefaultMap(() => []); for (const {i, t} of mod) { this.addInstance({i, t}); } // console.log(this.instances.m); // const callEveryFunction = ({i,t}, indent=0) => { // for (const fntype of this.functionsFrom.getdefault(t)) { // for (const fn of this.instances.getdefault(fntype)) { // console.log(" ", fn, ':', fntype); // const result = fn(i); // const resultType = getOut(fntype); // console.log(" ".repeat(indent), i, '->', result); // if (this.types.getdefault(resultType).includes(Function)) { // if (indent < 2) { // callEveryFunction({i: result, t: resultType}, indent+1) // } // } // } // } // }; // const callFunction = (typ, fns) => { // console.log("Functions callable on", typ, ":"); // for (const fn of fns) { // console.log(" ", fn); // for (const FN of this.instances.getdefault(fn)) { // console.log(" ", FN); // for (const i of this.instances.getdefault(typ)) { // const result = FN(i); // const resultType = getOut(fn); // console.log(" ", i, '->', result); // if (this.types.getdefault(resultType).includes(Function)) { // callFunction(resultType, ) // } // } // } // } // }; const callFunctionOnEveryValue = (fn, fnType, indent=1) => { const inType = getIn(fnType); const outType = getOut(fnType); console.log("--".repeat(indent), fn, ':', fnType); for (const i of this.instances.getdefault(inType)) { const result = fn(i); console.log("--".repeat(indent+1), i, '->', result); if (this.types.getdefault(outType).includes(Function)) { if (indent < 5) { callFunctionOnEveryValue(result, outType, indent+2); } } } } for (const fntypes of this.functionsFrom.m.values()) { for (const fntype of fntypes) { for (const fn of this.instances.getdefault(fntype)) { callFunctionOnEveryValue(fn, fntype); } } } // for (const [i, ts] of this.types.m.entries()) { // for (const t of ts) { // callEveryFunction({i,t}); // } // } // // Conformance check // for (const fn of this.instances.getdefault(conformanceCheck)) { // const t = fn.inType; // for (const i of this.instances.getdefault(t)) { // if (!fn.fn(i)) { // console.warn(i, 'is not conform', 'to', t); // } // else { // console.info('👍', i, 'conforms to', t); // } // } // } // const MAXDEPTH = 0; // let calls = 0; // const tryEveryFunction = ({i, t}, maxDepth) => { // calls++; // for (const fn of this.functionsFrom.getdefault(t)) { // const outType = getOut(fn); // // console.log(" ".repeat(MAXDEPTH-maxDepth) + 'calling', fn, 'on', i); // const result = fn(i); // console.log(" ".repeat(MAXDEPTH-maxDepth), result, 'should be of type', outType); // if (outType === TypeLink && result.t === undefined) { // console.warn(" ".repeat(MAXDEPTH-maxDepth) + ' ^ invalid') // } // if (outType === Int && (typeof result) !== "number") { // console.warn(" ".repeat(MAXDEPTH-maxDepth) + ' ^ invalid') // } // this.addInstance({i: result, t: outType}); // if (maxDepth > 0) { // tryEveryFunction({i: result, t: outType}, maxDepth-1); // } // } // } // for (const {i, t} of mod) { // tryEveryFunction({i, t}, MAXDEPTH); // } // console.log("calls:", calls); } addInstance({i, t}) { const arr = this.types.getdefault(i, true); arr.push(t); const arrI = this.instances.getdefault(t, true); arrI.push(i); if (t === Function) { const arr = this.functionsFrom.getdefault(getIn(i), true); arr.push(i); const arrTo = this.functionsTo.getdefault(getOut(i), true); arrTo.push(i); } else { } } } const ctx = new Context([ ...ModuleMetaCircular, ...ModuleTyped, // ...ModuleConformable, // ...ModuleConformanceCheckConforms, // ...ModuleNum, // ...ModuleEq, ...ModuleBool, ...ModuleInt, ...ModuleDouble, // ...ModuleSquare, // ...ModuleList, ...makeIdFn(Int), ...makeSquare({i: mulInt, t: Int_to_Int_to_Int}), ...makeSquare({i: mulDouble, t: Double_to_Double_to_Double}), ...ModuleLiterals, ...ModuleModule, ]);