diff options
| author | Akshay Nair <phenax5@gmail.com> | 2023-01-14 10:24:18 +0530 |
|---|---|---|
| committer | Akshay Nair <phenax5@gmail.com> | 2023-01-14 10:24:18 +0530 |
| commit | 2979eda13e25725683aa10292b31f22793c4e0c0 (patch) | |
| tree | 7ec461ec25e06719f6f3344152b9344bfee1f97b | |
| parent | 518a6a9ee31f0b03f08cb77bc613b4d708bb640b (diff) | |
| download | ts-types-lang-2979eda13e25725683aa10292b31f22793c4e0c0.tar.gz ts-types-lang-2979eda13e25725683aa10292b31f22793c4e0c0.zip | |
chore: adds fancy syntax for bind functions
| -rw-r--r-- | examples/greeting.ts | 15 | ||||
| -rw-r--r-- | src/eval-env/builtins.ts | 66 | ||||
| -rw-r--r-- | stdlib/effect.ts | 6 |
3 files changed, 71 insertions, 16 deletions
diff --git a/examples/greeting.ts b/examples/greeting.ts index d3d755f..8ed2181 100644 --- a/examples/greeting.ts +++ b/examples/greeting.ts @@ -1,12 +1,21 @@ import { Bind, Kind1 } from '../stdlib/effect' import { PutString, ReadLine, PutStringLn } from '../stdlib/stdio' -interface GreetK extends Kind1<string> { - return: PutStringLn<`Hello, ${this['input']}`> +interface ResponseK extends Kind1<string> { + return: PutStringLn<`Interesting that you believe "${this['input']}" is your purpose. Hmmmm...`> } export type main = [ PutStringLn<'Greetotron 6000 initializing...'>, + + PutStringLn<'----------------'>, PutString<'Your name? '>, - Bind<ReadLine, GreetK> + Bind<ReadLine, <name extends string>() => + PutStringLn<`Hello, ${name}`>>, + + PutStringLn<'----------------'>, + PutString<'Your purpose in life? '>, + Bind<ReadLine, ResponseK>, + + PutStringLn<'----------------'>, ] diff --git a/src/eval-env/builtins.ts b/src/eval-env/builtins.ts index 7e00253..f67fcc6 100644 --- a/src/eval-env/builtins.ts +++ b/src/eval-env/builtins.ts @@ -1,7 +1,55 @@ -import { Type } from 'ts-morph' +import { SyntaxKind, 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 (baseTypes?.includes('Kind1')) { + const [_, 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) { + typeParameters[0]?.getConstraint()?.replaceWithText(val) + } + + return resValueNode?.getType() + } + } + + return undefined + })() + + // TODO: Cleanup unwanted result node values + + if (!resultType) { + throw new Error('Fuck shit') + } + + return resultType +} + export default (ctx: Ctx, args: Type[]) => ({ SetEvalEnvironment: async () => { ctx.setEnv(ctx.getTypeValue(args[0])) @@ -75,18 +123,12 @@ export default (ctx: Ctx, args: Type[]) => ({ const [resultKey] = inputTyp ? await ctx.evaluateType(ctx, inputTyp) : [] // TODO: Handle resultKey undefined case - const [_, compNode] = ctx.createResult( - `(${ctx.typeToString(chainToKind)} & { input: (${ctx.getResultExpr( - resultKey - )})['output'] })['return']` - ) - // TODO: Avoid using getTypeAtLocation? - const compTyp = compNode - ?.getType() - .getProperty('output') - ?.getTypeAtLocation(ctx.entryPoint) - return compTyp ? await ctx.evaluateType(ctx, compTyp) : [] + const resultType = + applyFunc(ctx, chainToKind, `(${ctx.getResultExpr(resultKey)})['output']`) + const res = await ctx.evaluateType(ctx, resultType) + + return res }, Try: async () => { diff --git a/stdlib/effect.ts b/stdlib/effect.ts index 5ae9cd9..0662d00 100644 --- a/stdlib/effect.ts +++ b/stdlib/effect.ts @@ -7,7 +7,11 @@ export interface Kind1<Inp = unknown, Out = unknown> { return: Out } -export interface Bind<_Eff extends Effect, _Fn extends Kind1> extends Effect {} +type Func<Inp = unknown, Out = unknown> + = Kind1<Inp, Out> + | (<_T extends Inp>() => Out) + +export interface Bind<_Eff extends Effect, _Fn extends Func> extends Effect {} export interface Seq<_Effs extends Effect[]> extends Effect {} |
