aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAkshay Nair <phenax5@gmail.com>2023-01-11 16:02:26 +0530
committerAkshay Nair <phenax5@gmail.com>2023-01-11 16:02:26 +0530
commit49d6379c3d40b684b28f4a957ff1ffb81a2560ee (patch)
treefac62b2de1670ecfea6496949b028fa8fe0fe444
parenta6ff70d09e1e5f161e401a3665bfe44b2abfc44e (diff)
downloadts-types-lang-49d6379c3d40b684b28f4a957ff1ffb81a2560ee.tar.gz
ts-types-lang-49d6379c3d40b684b28f4a957ff1ffb81a2560ee.zip
refactor: minor refactor all around
-rw-r--r--examples/custom-effect.ts20
-rw-r--r--examples/ffi.ts19
-rw-r--r--examples/greeting.ts4
-rw-r--r--examples/guess-number.ts6
-rw-r--r--examples/test-runner.ts48
-rw-r--r--src/context.ts15
-rw-r--r--src/eval.ts23
-rw-r--r--src/types.ts1
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