diff options
| -rw-r--r-- | .prettierrc.json | 7 | ||||
| -rw-r--r-- | examples/custom-effect.ts | 15 | ||||
| -rw-r--r-- | examples/ffi.ts | 23 | ||||
| -rw-r--r-- | examples/file.ts | 6 | ||||
| -rw-r--r-- | examples/greeting.ts | 13 | ||||
| -rw-r--r-- | examples/guess-number.ts | 50 | ||||
| -rw-r--r-- | src/context.ts | 12 | ||||
| -rw-r--r-- | src/eval.ts | 59 | ||||
| -rw-r--r-- | src/index.ts | 11 | ||||
| -rw-r--r-- | src/types.ts | 9 | ||||
| -rw-r--r-- | src/util.ts | 8 | ||||
| -rw-r--r-- | stdlib/fs.ts | 6 | ||||
| -rw-r--r-- | stdlib/io.ts | 14 | ||||
| -rw-r--r-- | stdlib/stdio.ts | 9 | ||||
| -rw-r--r-- | stdlib/sys.ts | 7 |
15 files changed, 147 insertions, 102 deletions
diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000..801819d --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,7 @@ +{ + "tabWidth": 2, + "semi": false, + "trailingComma": "es5", + "bracketSpacing": true, + "singleQuote": true +} diff --git a/examples/custom-effect.ts b/examples/custom-effect.ts index 5fbffed..3dbe395 100644 --- a/examples/custom-effect.ts +++ b/examples/custom-effect.ts @@ -1,15 +1,18 @@ import { Bind, DefineEffect, Effect, Kind1, Print } from '../stdlib' -interface Mathemagic<_A, _B> extends Effect { } +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>, + 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 484e84d..0840ff6 100644 --- a/examples/ffi.ts +++ b/examples/ffi.ts @@ -1,19 +1,22 @@ -import { Bind, Debug, DefineEffect, Effect, JsExpr, Kind1 } from "../stdlib" +import { Bind, Debug, DefineEffect, Effect, JsExpr, Kind1 } from '../stdlib' -interface PrintK<Label extends string = ""> extends Kind1 { +interface PrintK<Label extends string = ''> extends Kind1 { return: Debug<Label, this['input']> } type Square<N extends number> = JsExpr<`${N} ** 2`> -interface Mathemagic<_A, _B extends number> extends Effect { } +interface Mathemagic<_A, _B extends number> extends Effect {} export type main = [ - Bind<JsExpr<"{ boobaa: [5 * 3, 5 * 2] }">, PrintK<'|'>>, - Bind<Square<69>, PrintK<"69^2 =">>, - DefineEffect<"Mathemagic", `(a, b) => { - console.log(typeToString(a)) - return { result: 5 * b.getLiteralValue() } - }`>, - Bind<Mathemagic<"a", 69>, PrintK<'69 * 5 ='>>, + Bind<JsExpr<'{ boobaa: [5 * 3, 5 * 2] }'>, PrintK<'|'>>, + Bind<Square<69>, PrintK<'69^2 ='>>, + DefineEffect< + 'Mathemagic', + `(a, b) => { + console.log(typeToString(a)) + return { result: 5 * b.getLiteralValue() } + }` + >, + Bind<Mathemagic<'a', 69>, PrintK<'69 * 5 ='>> ] diff --git a/examples/file.ts b/examples/file.ts index 279a51b..287f108 100644 --- a/examples/file.ts +++ b/examples/file.ts @@ -1,9 +1,7 @@ -import { Bind, Kind1, ReadFile, WriteFile, PutStringLn } from '../stdlib' +import { Bind, Kind1, ReadFile, PutStringLn } from '../stdlib' interface PrintK extends Kind1<string> { return: PutStringLn<this['input']> } -export type main = [ - Bind<ReadFile<"./default.nix">, PrintK>, -] +export type main = Bind<ReadFile<'./default.nix'>, PrintK> diff --git a/examples/greeting.ts b/examples/greeting.ts index ac59151..20ed4fe 100644 --- a/examples/greeting.ts +++ b/examples/greeting.ts @@ -1,14 +1,11 @@ -import { PutString, Bind, Kind1, ReadLine, Seq } from '../stdlib' +import { PutString, Bind, Kind1, ReadLine, Seq, PutStringLn } from '../stdlib' interface GreetK extends Kind1<string> { - return: Seq<[ - PutString<"Hello, ">, - PutString<`${this['input']}\n`> - ]>, + return: Seq<[PutString<'Hello, '>, PutString<`${this['input']}\n`>]> } export type main = [ - PutString<"Your name? ">, - Bind<ReadLine, GreetK>, + PutStringLn<'Greetotron 6000 initializing...'>, + PutString<'Your name? '>, + Bind<ReadLine, GreetK> ] - diff --git a/examples/guess-number.ts b/examples/guess-number.ts index a20c993..d08c616 100644 --- a/examples/guess-number.ts +++ b/examples/guess-number.ts @@ -1,33 +1,39 @@ -import { Print, PutString, Bind, Kind1, JsExpr, ReadLine, Do, PutStringLn } from '../stdlib' +import { + Print, + PutString, + Bind, + Kind1, + JsExpr, + ReadLine, + Do, + PutStringLn, +} from '../stdlib' export type main = [ - PutStringLn<"Guess a number between 0 & 9. You have 5 guesses">, - Bind< - JsExpr<"Math.floor(Math.random() * 10)">, - StartGuessing - > + PutStringLn<'Guess a number between 0 & 9. You have 5 guesses'>, + Bind<JsExpr<'Math.floor(Math.random() * 10)'>, StartGuessing> ] -interface AskForGuess<N extends number, Attempts extends 0[]> extends Kind1<string> { +interface AskForGuess<N extends number, Attempts extends 0[]> + extends Kind1<string> { return: `${this['input']}` extends `${N}` - ? PutStringLn<"Yay! You got it right!"> - : Do<[ - Print<`Wrong guess. Total attempts: ${ - [...Attempts, 0] extends infer Ls extends 0[] ? Ls['length'] : 0 - }/5`>, - (StartGuessing<[...Attempts, 0]> & { input: N })['return'], - ]> + ? PutStringLn<'Yay! You got it right!'> + : Do< + [ + PutString<'Wrong guess. Total attempts'>, + Print<`${[...Attempts, 0] extends infer Ls extends 0[] + ? Ls['length'] + : 0}/5`>, + (StartGuessing<[...Attempts, 0]> & { input: N })['return'] + ] + > } interface StartGuessing<Attempts extends 0[] = []> extends Kind1<number> { return: Attempts['length'] extends 5 - ? PutStringLn<"Max attempts exceeded. Game over!"> + ? PutStringLn<'Max attempts exceeded. Game over!'> : Bind< - Do<[ - PutString<"Your guess? ">, - ReadLine - ]>, - AskForGuess<this['input'], Attempts> - > + Do<[PutString<'Your guess? '>, ReadLine]>, + AskForGuess<this['input'], Attempts> + > } - diff --git a/src/context.ts b/src/context.ts index 35fa1ae..7759215 100644 --- a/src/context.ts +++ b/src/context.ts @@ -1,7 +1,7 @@ import { Project, ScriptTarget, Type, Node, SyntaxKind } from 'ts-morph' import path from 'path' -import { v4 as uuid } from 'uuid'; -import { Ctx } from './types'; +import { v4 as uuid } from 'uuid' +import { Ctx } from './types' const RESULT_TYPE_NAME = '__$result' @@ -31,9 +31,12 @@ export const createContext = (): Ctx => { const typeToString = (ty: Type | undefined): string => ty ? typeChecker.compilerObject.typeToString(ty.compilerType) : '' - const [resultTypeNode] = sourceFile.addStatements(`type ${RESULT_TYPE_NAME} = {}`) + const [resultTypeNode] = sourceFile.addStatements( + `type ${RESULT_TYPE_NAME} = {}` + ) - const getResultExpr = (resultKey?: string) => `${RESULT_TYPE_NAME}[${JSON.stringify(resultKey)}` + const getResultExpr = (resultKey?: string) => + `${RESULT_TYPE_NAME}[${JSON.stringify(resultKey)}` const addResult = (name: string, ty: string): Node | undefined => resultTypeNode @@ -77,4 +80,3 @@ export const createContext = (): Ctx => { hasCustomEffect: (name) => customEffects[name] !== undefined, } } - diff --git a/src/eval.ts b/src/eval.ts index 4ba7033..9829194 100644 --- a/src/eval.ts +++ b/src/eval.ts @@ -1,20 +1,23 @@ import { Type } from 'ts-morph' import { promises as fs } from 'fs' -import readline from 'readline'; +import readline from 'readline' -import { match } from './util'; -import { Ctx } from './types'; +import { match } from './util' +import { Ctx } from './types' const rl = readline.createInterface({ input: process.stdin, output: process.stdout, - terminal: false -}); + terminal: false, +}) -const readLineFromStdin = (): Promise<string> => new Promise((res) => - rl.on('line', res)) +const readLineFromStdin = (): Promise<string> => + new Promise((res) => rl.on('line', res)) -export const evaluateType = async (ctx: Ctx, effTyp: Type): Promise<string[]> => { +export const evaluateType = async ( + ctx: Ctx, + effTyp: Type +): Promise<string[]> => { const name = effTyp.getSymbol()?.getName() return match(name, { @@ -28,15 +31,17 @@ export const evaluateType = async (ctx: Ctx, effTyp: Type): Promise<string[]> => }, Print: async () => { - console.log(...effTyp.getTypeArguments().map(ctx.typeToString)); + console.log(...effTyp.getTypeArguments().map(ctx.typeToString)) return [] }, PutString: async () => { const [strinTyp] = effTyp.getTypeArguments() const typString = ctx.typeToString(strinTyp) - const string = JSON.parse(!typString.startsWith('"') ? `"${typString}"` : typString) - process.stdout.write(string); + const string = JSON.parse( + !typString.startsWith('"') ? `"${typString}"` : typString + ) + process.stdout.write(string) return [] }, @@ -70,9 +75,15 @@ export const evaluateType = async (ctx: Ctx, effTyp: Type): Promise<string[]> => const [resultKey] = inputTyp ? await evaluateType(ctx, inputTyp) : [] const [_, compNode] = ctx.createResult( - `(${ctx.typeToString(chainToKind)} & { input: (${ctx.getResultExpr(resultKey)})['output'] })['return']`) + `(${ctx.typeToString(chainToKind)} & { input: (${ctx.getResultExpr( + resultKey + )})['output'] })['return']` + ) // TODO: Avoid using getTypeAtLocation? - const compTyp = compNode?.getType().getProperty('output')?.getTypeAtLocation(ctx.entryPoint) + const compTyp = compNode + ?.getType() + .getProperty('output') + ?.getTypeAtLocation(ctx.entryPoint) return compTyp ? await evaluateType(ctx, compTyp) : [] }, @@ -80,12 +91,16 @@ export const evaluateType = async (ctx: Ctx, effTyp: Type): Promise<string[]> => GetEnv: async () => { const [envTyp] = effTyp.getTypeArguments() const envName = JSON.parse(ctx.typeToString(envTyp)) - const [resultKey, _] = ctx.createResult(`${JSON.stringify(process.env[envName] ?? '')}`) + const [resultKey, _] = ctx.createResult( + `${JSON.stringify(process.env[envName] ?? '')}` + ) return [resultKey] }, GetArgs: async () => { - const [resultKey, _] = ctx.createResult(`${JSON.stringify(process.argv.slice(2))}`) + const [resultKey, _] = ctx.createResult( + `${JSON.stringify(process.argv.slice(2))}` + ) return [resultKey] }, @@ -105,7 +120,10 @@ export const evaluateType = async (ctx: Ctx, effTyp: Type): Promise<string[]> => Seq: async () => { const [effectTyps] = effTyp.getTypeArguments() - const effectResults = await evalList(ctx, effectTyps?.getTupleElements() ?? []) + const effectResults = await evalList( + ctx, + effectTyps?.getTupleElements() ?? [] + ) const [resultKey, _] = ctx.createResult(`[ ${effectResults.map(ctx.getResultExpr).join(', ')} ]`) @@ -114,9 +132,14 @@ export const evaluateType = async (ctx: Ctx, effTyp: Type): Promise<string[]> => Do: async () => { const [effectTyps] = effTyp.getTypeArguments() - const effectResults = await evalList(ctx, effectTyps?.getTupleElements() ?? []) + const effectResults = await evalList( + ctx, + effectTyps?.getTupleElements() ?? [] + ) const lastResKey = effectResults[effectResults.length - 1] - const [resultKey, _] = ctx.createResult(`${ctx.getResultExpr(lastResKey)}['output']`) + const [resultKey, _] = ctx.createResult( + `${ctx.getResultExpr(lastResKey)}['output']` + ) return [resultKey] }, diff --git a/src/index.ts b/src/index.ts index 2fa1f96..65349fc 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,14 +1,15 @@ -import { createContext } from './context'; -import { evalList } from './eval'; +import { createContext } from './context' +import { evalList } from './eval' const main = async () => { const ctx = createContext() const resultType = ctx.entryPoint.getType() - const effects = resultType.isTuple() ? resultType.getTupleElements() : [resultType] + const effects = resultType.isTuple() + ? resultType.getTupleElements() + : [resultType] await evalList(ctx, effects) } main() .then(() => process.exit(0)) - .catch(e => (console.error(e), process.exit(1))) - + .catch((e) => (console.error(e), process.exit(1))) diff --git a/src/types.ts b/src/types.ts index a3cf3bb..3ffd416 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,4 +1,10 @@ -import { ExportedDeclarations, Node, SourceFile, Type, TypeChecker } from "ts-morph" +import { + ExportedDeclarations, + Node, + SourceFile, + Type, + TypeChecker, +} from 'ts-morph' export interface Ctx { sourceFile: SourceFile @@ -14,4 +20,3 @@ export interface Ctx { runCustomEffect: (name: string, args: Type[]) => Promise<string[]> hasCustomEffect: (name: string) => boolean } - diff --git a/src/util.ts b/src/util.ts index 0b60bb1..136815e 100644 --- a/src/util.ts +++ b/src/util.ts @@ -1,4 +1,4 @@ - -export const match = <K extends string, R>(k: K | undefined, pattern: { [key in K | '_']: () => R }) => - k && pattern[k] ? pattern[k]() : pattern._() - +export const match = <K extends string, R>( + k: K | undefined, + pattern: { [key in K | '_']: () => R } +) => (k && pattern[k] ? pattern[k]() : pattern._()) diff --git a/stdlib/fs.ts b/stdlib/fs.ts index 1374da5..f7014ff 100644 --- a/stdlib/fs.ts +++ b/stdlib/fs.ts @@ -1,6 +1,6 @@ import { Effect } from './io' -export interface WriteFile<_Path extends string, _Content extends string> extends Effect { } - -export interface ReadFile<_Path extends string> extends Effect<string> { } +export interface WriteFile<_Path extends string, _Content extends string> + extends Effect {} +export interface ReadFile<_Path extends string> extends Effect<string> {} diff --git a/stdlib/io.ts b/stdlib/io.ts index c78204f..c37cd32 100644 --- a/stdlib/io.ts +++ b/stdlib/io.ts @@ -1,15 +1,17 @@ -export interface Effect<T = unknown> { output: T } +export interface Effect<T = unknown> { + output: T +} export interface Kind1<Inp = unknown, Out = unknown> { input: Inp return: Out } -export interface Bind<_Eff extends Effect, _Fn extends Kind1> extends Effect { } - -export interface Seq<_Effs extends Effect[]> extends Effect { } +export interface Bind<_Eff extends Effect, _Fn extends Kind1> extends Effect {} -export interface Do<_Effs extends Effect[]> extends Effect { } +export interface Seq<_Effs extends Effect[]> extends Effect {} -export interface DefineEffect<_Name extends string, _Func extends string> extends Effect { } +export interface Do<_Effs extends Effect[]> extends Effect {} +export interface DefineEffect<_Name extends string, _Func extends string> + extends Effect {} diff --git a/stdlib/stdio.ts b/stdlib/stdio.ts index 365aead..77aa031 100644 --- a/stdlib/stdio.ts +++ b/stdlib/stdio.ts @@ -1,12 +1,11 @@ import { Effect } from './io' -export interface PutString<_ extends string> extends Effect { } +export interface PutString<_ extends string> extends Effect {} -export interface Print<_ extends any> extends Effect { } +export interface Print<_ extends any> extends Effect {} -export interface Debug<_ extends string, T> extends Effect<T> { } +export interface Debug<_ extends string, T> extends Effect<T> {} -export interface ReadLine extends Effect<string> { } +export interface ReadLine extends Effect<string> {} export type PutStringLn<S extends string> = PutString<`${S}\n`> - diff --git a/stdlib/sys.ts b/stdlib/sys.ts index 03541be..afa5dbd 100644 --- a/stdlib/sys.ts +++ b/stdlib/sys.ts @@ -1,8 +1,7 @@ import { Effect } from './io' -export interface GetEnv<_Name extends string> extends Effect<string> { } +export interface GetEnv<_Name extends string> extends Effect<string> {} -export interface GetArgs extends Effect<string[]> { } - -export interface JsExpr<_Expr extends string> extends Effect<any> { } +export interface GetArgs extends Effect<string[]> {} +export interface JsExpr<_Expr extends string> extends Effect<any> {} |
