diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/context.ts | 10 | ||||
| -rw-r--r-- | src/eval-env/builtins.ts | 71 | ||||
| -rw-r--r-- | src/eval.ts | 4 | ||||
| -rw-r--r-- | src/types.ts | 1 | ||||
| -rw-r--r-- | src/util.ts | 63 |
5 files changed, 81 insertions, 68 deletions
diff --git a/src/context.ts b/src/context.ts index fe33731..fab6653 100644 --- a/src/context.ts +++ b/src/context.ts @@ -56,6 +56,15 @@ export const createContext = (options: CtxOptions): Ctx => { return [resultKey, node] } + const removeResult = (key?: string) => { + if (!key) return + resultTypeNode + ?.asKind(SyntaxKind.TypeAliasDeclaration) + ?.getChildAtIndexIfKind(3, SyntaxKind.TypeLiteral) + ?.getProperty(key) + ?.remove() + } + const customEffects: Record<string, (args: Type[], ctx: Ctx) => any> = {} const getTypeValue = (ty: Type | undefined): any => { @@ -97,6 +106,7 @@ export const createContext = (options: CtxOptions): Ctx => { createResult, getResultExpr, + removeResult, printResultNode: () => console.log(resultTypeNode?.print()), addCustomEffect: (name, expr) => { diff --git a/src/eval-env/builtins.ts b/src/eval-env/builtins.ts index 35f8485..c5b0c82 100644 --- a/src/eval-env/builtins.ts +++ b/src/eval-env/builtins.ts @@ -1,63 +1,6 @@ -import { SyntaxKind, Type } from 'ts-morph' +import { Type } from 'ts-morph' import { Ctx } from '../types' -import { evalList } from '../util' - -const applyFunc = (ctx: Ctx, fn: Type | undefined, val: string): Type => { - const resultType = (() => { - const baseTypes = fn - ?.getBaseTypes() - .flatMap((t) => t.getSymbol()?.getName() ?? []) - - if (!!fn?.getProperty('return') || baseTypes?.includes('Kind1')) { - const [_key, resultNode] = ctx.createResult( - `(${ctx.typeToString(fn)} & { input: ${val} })['return']` - ) - return resultNode - ?.getType() - .getProperty('output') - ?.getTypeAtLocation(resultNode) - } else { - const [_key, resultNode] = ctx.createResult( - `ReturnType<${ctx.typeToString(fn)}>` - ) - - const resValueNode = resultNode - ?.asKind(SyntaxKind.PropertySignature) - ?.getChildAtIndexIfKind(2, SyntaxKind.TypeLiteral) - ?.getProperty('output') - ?.getChildAtIndexIfKind(2, SyntaxKind.TypeReference) - - const functionNode = resValueNode - ?.getChildAtIndexIfKind(1, SyntaxKind.SyntaxList) - ?.getFirstChildIfKind(SyntaxKind.FunctionType) - - if (functionNode) { - const typeParameters = functionNode.getTypeParameters() ?? [] - - if (typeParameters.length > 0) { - const constraint = typeParameters[0]?.getConstraint() - if (constraint) { - constraint?.replaceWithText(val) - } else { - typeParameters[0]?.setConstraint(val) - } - } - - return resValueNode?.getType() - } - } - - return undefined - })() - - // TODO: Cleanup unwanted result node values - - if (!resultType) { - throw new Error('Couldnt get result for function application') - } - - return resultType -} +import { applyFunc, evalList } from '../util' export default (ctx: Ctx, args: Type[]) => ({ SetEvalEnvironment: async () => { @@ -129,14 +72,12 @@ export default (ctx: Ctx, args: Type[]) => ({ Bind: ctx.withScope(async () => { const [inputTyp, chainToKind] = args - const [resultKey] = inputTyp ? await ctx.evaluateType(ctx, inputTyp) : [] - - // TODO: Handle resultKey undefined case + let [resultKey] = inputTyp ? await ctx.evaluateType(ctx, inputTyp) : [] const resultType = applyFunc( ctx, chainToKind, - `(${ctx.getResultExpr(resultKey)})['output']` + resultKey ? `(${ctx.getResultExpr(resultKey)})['output']` : 'never' ) return ctx.evaluateType(ctx, resultType) }), @@ -186,7 +127,7 @@ export default (ctx: Ctx, args: Type[]) => ({ return [resultKey] }, - Seq: async () => { + Seq: ctx.withScope(async () => { const [effectTyps] = args const effectResults = await evalList( ctx, @@ -196,7 +137,7 @@ export default (ctx: Ctx, args: Type[]) => ({ ${effectResults.map(ctx.getResultExpr).join(', ')} ]`) return [resultKey] - }, + }), Do: ctx.withScope(async () => { const [effectTyps] = args diff --git a/src/eval.ts b/src/eval.ts index 6eb72a1..37a8008 100644 --- a/src/eval.ts +++ b/src/eval.ts @@ -32,7 +32,7 @@ export const evaluateType = async ( const name = effTyp.getSymbol()?.getName() const args = effTyp.getTypeArguments() - // console.log('>>>>>', name) + //console.log('>>>>>', name) // console.log(ctx.typeToString(effTyp)) // console.log(name, args.map(ctx.typeToString)) @@ -67,7 +67,7 @@ export const evaluateType = async ( return match(name, { ...envEffects(ctx, args), _: async () => { - console.log(ctx.typeToString(effTyp)) + console.log('\n[EffectType]', ctx.typeToString(effTyp), '\n') throw new Error(`${name} effect is not handled`) }, }) diff --git a/src/types.ts b/src/types.ts index 6ea282e..55d2cce 100644 --- a/src/types.ts +++ b/src/types.ts @@ -14,6 +14,7 @@ export interface Ctx { getTypeValue: (ty: Type | undefined) => any createResult: (ty: string) => [string, Node | undefined] + removeResult: (key?: string) => void, getResultExpr: (key?: string) => string printResultNode: () => void diff --git a/src/util.ts b/src/util.ts index f7bb20a..2746746 100644 --- a/src/util.ts +++ b/src/util.ts @@ -1,4 +1,4 @@ -import { Type } from 'ts-morph' +import { SyntaxKind, Type } from 'ts-morph' import { Ctx } from './types' export const match = <K extends string, R>( @@ -13,3 +13,64 @@ export const evalList = async (ctx: Ctx, effectTyps: Type[]) => { } return effectResults } + +export const applyFunc = (ctx: Ctx, fn: Type | undefined, val: string): Type => { + const resultType = (() => { + const baseTypes = fn + ?.getBaseTypes() + .flatMap((t) => t.getSymbol()?.getName() ?? []) + + if (!!fn?.getProperty('return') || baseTypes?.includes('Kind1')) { + const [key, resultNode] = ctx.createResult( + `(${ctx.typeToString(fn)} & { input: ${val} })['return']` + ) + ctx.removeResult(key) + + return resultNode + ?.getType() + .getProperty('output') + ?.getTypeAtLocation(resultNode) + } else { + const [key, resultNode] = ctx.createResult( + `ReturnType<${ctx.typeToString(fn)}>` + ) + ctx.removeResult(key) + + const resValueNode = resultNode + ?.asKind(SyntaxKind.PropertySignature) + ?.getChildAtIndexIfKind(2, SyntaxKind.TypeLiteral) + ?.getProperty('output') + ?.getChildAtIndexIfKind(2, SyntaxKind.TypeReference) + + const functionNode = resValueNode + ?.getChildAtIndexIfKind(1, SyntaxKind.SyntaxList) + ?.getFirstChildIfKind(SyntaxKind.FunctionType) + + if (functionNode) { + const typeParameters = functionNode.getTypeParameters() ?? [] + + if (typeParameters.length > 0) { + const constraint = typeParameters[0]?.getConstraint() + if (constraint) { + constraint?.replaceWithText(val) + } else { + typeParameters[0]?.setConstraint(val) + } + } + + return resValueNode?.getType() + } + } + + return undefined + })() + + // TODO: Cleanup unwanted result node values + + if (!resultType) { + throw new Error('Couldnt get result for function application') + } + + return resultType +} + |
