aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAkshay Nair <phenax5@gmail.com>2023-01-14 17:12:48 +0530
committerAkshay Nair <phenax5@gmail.com>2023-01-14 17:12:48 +0530
commitcd11925707c42843df195d9b2efb3c77b5de793b (patch)
tree0871b0041597096fdbf7c49416f96fa70da00e3c /src
parentd362ef26db894ea52c6abd34489aa9efdbc0c89b (diff)
downloadts-types-lang-cd11925707c42843df195d9b2efb3c77b5de793b.tar.gz
ts-types-lang-cd11925707c42843df195d9b2efb3c77b5de793b.zip
feat: adds cleanup of result nodes
Diffstat (limited to 'src')
-rw-r--r--src/context.ts10
-rw-r--r--src/eval-env/builtins.ts71
-rw-r--r--src/eval.ts4
-rw-r--r--src/types.ts1
-rw-r--r--src/util.ts63
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
+}
+