aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.prettierrc.json7
-rw-r--r--examples/custom-effect.ts15
-rw-r--r--examples/ffi.ts23
-rw-r--r--examples/file.ts6
-rw-r--r--examples/greeting.ts13
-rw-r--r--examples/guess-number.ts50
-rw-r--r--src/context.ts12
-rw-r--r--src/eval.ts59
-rw-r--r--src/index.ts11
-rw-r--r--src/types.ts9
-rw-r--r--src/util.ts8
-rw-r--r--stdlib/fs.ts6
-rw-r--r--stdlib/io.ts14
-rw-r--r--stdlib/stdio.ts9
-rw-r--r--stdlib/sys.ts7
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> {}