diff options
| author | Akshay Nair <phenax5@gmail.com> | 2023-01-11 16:02:26 +0530 |
|---|---|---|
| committer | Akshay Nair <phenax5@gmail.com> | 2023-01-11 16:02:26 +0530 |
| commit | 49d6379c3d40b684b28f4a957ff1ffb81a2560ee (patch) | |
| tree | fac62b2de1670ecfea6496949b028fa8fe0fe444 | |
| parent | a6ff70d09e1e5f161e401a3665bfe44b2abfc44e (diff) | |
| download | ts-types-lang-49d6379c3d40b684b28f4a957ff1ffb81a2560ee.tar.gz ts-types-lang-49d6379c3d40b684b28f4a957ff1ffb81a2560ee.zip | |
refactor: minor refactor all around
| -rw-r--r-- | examples/custom-effect.ts | 20 | ||||
| -rw-r--r-- | examples/ffi.ts | 19 | ||||
| -rw-r--r-- | examples/greeting.ts | 4 | ||||
| -rw-r--r-- | examples/guess-number.ts | 6 | ||||
| -rw-r--r-- | examples/test-runner.ts | 48 | ||||
| -rw-r--r-- | src/context.ts | 15 | ||||
| -rw-r--r-- | src/eval.ts | 23 | ||||
| -rw-r--r-- | src/types.ts | 1 |
8 files changed, 69 insertions, 67 deletions
diff --git a/examples/custom-effect.ts b/examples/custom-effect.ts deleted file mode 100644 index 74c96b0..0000000 --- a/examples/custom-effect.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Bind, Effect, Kind1 } from '../stdlib/effect' -import { DefineEffect } from '../stdlib/sys' -import { Print } from '../stdlib/stdio' - -interface Mathemagic<_A, _B> extends Effect {} - -interface PrintK extends Kind1 { - return: Print<this['input']> -} - -export type main = [ - DefineEffect< - 'Mathemagic', - `(a, b) => { - console.log(typeToString(a)) - return { result: 5 * b.getLiteralValue() } - }` - >, - Bind<Mathemagic<'a', 69>, PrintK> -] diff --git a/examples/ffi.ts b/examples/ffi.ts index f118085..a09aeef 100644 --- a/examples/ffi.ts +++ b/examples/ffi.ts @@ -6,19 +6,24 @@ interface PrintK<Label extends string = ''> extends Kind1 { return: Debug<Label, this['input']> } -type Square<N extends number> = JsExpr<`${N} ** 2`> +// Declare custom effect +interface CustomThingy<_A, _B extends number> extends Effect {} -interface Mathemagic<_A, _B extends number> extends Effect {} +// Alias for squaring a number +type Square<N extends number> = JsExpr<`${N} ** 2`> export type main = [ + // FFI via js expression Bind<JsExpr<'{ boobaa: [5 * 3, 5 * 2] }'>, PrintK<'|'>>, Bind<Square<69>, PrintK<'69^2 ='>>, + + // FFI via custom effect DefineEffect< - 'Mathemagic', - `(a, b) => { - console.log(typeToString(a)) - return { result: 5 * b.getLiteralValue() } + 'CustomThingy', + `([a, b], ctx) => { + console.log(ctx.typeToString(a)) + return { result: 5 * ctx.getTypeValue(b) } }` >, - Bind<Mathemagic<'a', 69>, PrintK<'69 * 5 ='>> + Bind<CustomThingy<'a', 69>, PrintK<'69 * 5 ='>> ] diff --git a/examples/greeting.ts b/examples/greeting.ts index e4c2161..d3d755f 100644 --- a/examples/greeting.ts +++ b/examples/greeting.ts @@ -1,8 +1,8 @@ -import { Bind, Kind1, Seq } from '../stdlib/effect' +import { Bind, Kind1 } from '../stdlib/effect' import { PutString, ReadLine, PutStringLn } from '../stdlib/stdio' interface GreetK extends Kind1<string> { - return: Seq<[PutString<'Hello, '>, PutString<`${this['input']}\n`>]> + return: PutStringLn<`Hello, ${this['input']}`> } export type main = [ diff --git a/examples/guess-number.ts b/examples/guess-number.ts index 169805f..45d60e6 100644 --- a/examples/guess-number.ts +++ b/examples/guess-number.ts @@ -7,15 +7,15 @@ export type main = [ Bind<JsExpr<'Math.floor(Math.random() * 10)'>, StartGuessing> ] +type Len<Ls extends any[]> = Ls['length'] extends number ? Ls['length'] : 0 + interface AskForGuess<N extends number, Attempts extends 0[]> extends Kind1<string> { return: `${this['input']}` extends `${N}` ? PutStringLn<'Yay! You got it right!'> : Do< [ PutString<'Wrong guess. Total attempts'>, - PutStringLn<` ${[...Attempts, 0] extends infer Ls extends 0[] - ? Ls['length'] - : 0}/5`>, + PutStringLn<` ${Len<[...Attempts, 0]>}/5`>, (StartGuessing<[...Attempts, 0]> & { input: N })['return'] ] > diff --git a/examples/test-runner.ts b/examples/test-runner.ts index 7093bf7..fecd3e4 100644 --- a/examples/test-runner.ts +++ b/examples/test-runner.ts @@ -1,39 +1,45 @@ import { Do, Effect } from '../stdlib/effect' -import { Print, PutStringLn } from '../stdlib/stdio' +import { PutStringLn } from '../stdlib/stdio' import { DefineEffect } from '../stdlib/sys' -type Testi<m extends string, effs extends Effect[]> = [ - PutStringLn<m>, +type Test<m extends string, effs extends Effect[]> = [ + PutStringLn<`* ${m}`>, ...effs, ] type Equals<Left, Right> = [Left] extends [Right] ? ([Right] extends [Left] ? true : false) : false +type Not<B extends boolean> = B extends true ? false : true -type CompileTimeErrors = false -interface Assert<_B extends (CompileTimeErrors extends true ? true : boolean)> extends Effect { } +interface TestConfig { + CompileTestFailures: false +} -type testCases = [ - ...Testi<"should do some stuff", [ - Assert<Equals<1, 2>>, - ]>, - - ...Testi<"hello world", [ - Print<2>, - ]>, - - ...Testi<"should do some other stuff", [ - Print<5>, - ]>, -] +type Assertion = TestConfig['CompileTestFailures'] extends true ? true : boolean +interface Assert<_B extends Assertion> extends Effect { } export type main = [ - DefineEffect<'Assert', `(b) => { - if (!b.getLiteralValue()) { + DefineEffect<'Assert', `([b], ctx) => { + if (!ctx.getTypeValue(b)) { throw new Error('AAAAAAA') } }`>, + PutStringLn<"Running tests...">, - Do<testCases>, + + Do<[ + ...Test<"should do some stuff", [ + Assert<Equals<1, 1>>, + Assert<Not<Equals<2, 1>>>, + ]>, + + ...Test<"hello world", [ + Assert<Equals<1, 1>>, + ]>, + + ...Test<"should do some other stuff", [ + Assert<Equals<1, 1>>, + ]>, + ]>, ] diff --git a/src/context.ts b/src/context.ts index 196c85d..14b5115 100644 --- a/src/context.ts +++ b/src/context.ts @@ -51,13 +51,20 @@ export const createContext = (options: CtxOptions): Ctx => { return [resultKey, node] } - const customEffects: Record<string, (...args: Type[]) => any> = {} + const customEffects: Record<string, (args: Type[], ctx: Ctx) => any> = {} - return { + const getTypeValue = (ty: Type | undefined): any => { + try { + return JSON.parse(typeToString(ty)) + } catch(_) { return } + } + + const ctx: Ctx = { sourceFile, typeChecker, entryPoint, typeToString, + getTypeValue, createResult, getResultExpr, @@ -68,7 +75,7 @@ export const createContext = (options: CtxOptions): Ctx => { Object.assign(customEffects, { [name]: func }) }, runCustomEffect: async (name, args) => { - const output = await customEffects[name]?.(...args) + const output = await customEffects[name]?.(args, ctx) if (output) { const [resultKey, _] = createResult(`${JSON.stringify(output)}`) return [resultKey] @@ -77,4 +84,6 @@ export const createContext = (options: CtxOptions): Ctx => { }, hasCustomEffect: (name) => customEffects[name] !== undefined, } + + return ctx } diff --git a/src/eval.ts b/src/eval.ts index 54036be..8c8940f 100644 --- a/src/eval.ts +++ b/src/eval.ts @@ -49,17 +49,14 @@ export const evaluateType = async ( PutString: async () => { const [strinTyp] = args - const typString = ctx.typeToString(strinTyp) - const string = JSON.parse( - !typString.startsWith('"') ? `"${typString}"` : typString - ) - process.stdout.write(string) + const typString = ctx.getTypeValue(strinTyp) ?? ctx.typeToString(strinTyp) + process.stdout.write(typString) return [] }, Debug: async () => { const [labelTyp, valueTyp] = args - const label = JSON.parse(ctx.typeToString(labelTyp)) + const label = ctx.getTypeValue(labelTyp) const value = ctx.typeToString(valueTyp) console.log(label, value) const [resultKey, _] = ctx.createResult(JSON.stringify(value)) @@ -68,7 +65,7 @@ export const evaluateType = async ( ReadFile: async () => { const [pathTyp] = args - const filePath = JSON.parse(ctx.typeToString(pathTyp)) + const filePath = ctx.getTypeValue(pathTyp) const contents = await fs.readFile(filePath, 'utf-8') const [resultKey, _] = ctx.createResult(JSON.stringify(contents)) return [resultKey] @@ -76,8 +73,8 @@ export const evaluateType = async ( WriteFile: async () => { const [pathTyp, contentsTyp] = args - const filePath = JSON.parse(ctx.typeToString(pathTyp)) - const contents = JSON.parse(ctx.typeToString(contentsTyp)) + const filePath = ctx.getTypeValue(pathTyp) + const contents = ctx.getTypeValue(contentsTyp) await fs.writeFile(filePath, contents) return [] }, @@ -86,6 +83,7 @@ export const evaluateType = async ( const [inputTyp, chainToKind] = args const [resultKey] = inputTyp ? await evaluateType(ctx, inputTyp) : [] + // TODO: Handle resultKey undefined case const [_, compNode] = ctx.createResult( `(${ctx.typeToString(chainToKind)} & { input: (${ctx.getResultExpr( resultKey @@ -102,7 +100,7 @@ export const evaluateType = async ( GetEnv: async () => { const [envTyp] = args - const envName = JSON.parse(ctx.typeToString(envTyp)) + const envName = ctx.getTypeValue(envTyp) const [resultKey, _] = ctx.createResult( `${JSON.stringify(process.env[envName] ?? '')}` ) @@ -124,7 +122,7 @@ export const evaluateType = async ( JsExpr: async () => { const [exprTyp] = args - const exprStr = JSON.parse(ctx.typeToString(exprTyp)) + const exprStr = ctx.getTypeValue(exprTyp) const result = eval(`JSON.stringify(${exprStr})`) const [resultKey, _] = ctx.createResult(`${result}`) return [resultKey] @@ -148,6 +146,7 @@ export const evaluateType = async ( ctx, effectTyps?.getTupleElements() ?? [] ) + // TODO: Use last type's result instead of last result key const lastResKey = effectResults[effectResults.length - 1] const [resultKey, _] = ctx.createResult( `(${ctx.getResultExpr(lastResKey)})['output']` @@ -161,6 +160,8 @@ export const evaluateType = async ( } console.log(`${name} effect is not handled`) + console.log(ctx.typeToString(effTyp)) + // TODO: Maybe throw? return [] }, }) diff --git a/src/types.ts b/src/types.ts index 3ffd416..e3ea7e9 100644 --- a/src/types.ts +++ b/src/types.ts @@ -11,6 +11,7 @@ export interface Ctx { typeChecker: TypeChecker entryPoint: ExportedDeclarations typeToString: (ty: Type | undefined) => string + getTypeValue: (ty: Type | undefined) => any createResult: (ty: string) => [string, Node | undefined] getResultExpr: (key?: string) => string |
