diff options
Diffstat (limited to '')
| -rw-r--r-- | src/eval.ts | 40 | ||||
| -rw-r--r-- | src/parser.ts (renamed from src/parse-expr.ts) | 0 | ||||
| -rw-r--r-- | src/utils/adt.ts | 5 | ||||
| -rw-r--r-- | src/utils/parser-comb.ts | 15 | ||||
| -rw-r--r-- | src/utils/result.ts | 14 |
5 files changed, 61 insertions, 13 deletions
diff --git a/src/eval.ts b/src/eval.ts new file mode 100644 index 0000000..1e18457 --- /dev/null +++ b/src/eval.ts @@ -0,0 +1,40 @@ +import { Expr } from "./parser"; +import { match, matchString } from "./utils/adt"; + +export type Dependencies = { + addClass(id: string, classes: string): Promise<void> + removeClass(id: string, classes: string): Promise<void> + // requestGetCss(url: string): Promise<string> + // getVarable(name: string, def?: string): Promise<string> + // updateVariable(id: string, varName: string, value: string): Promise<void> + // calculate ?? +} + +export const evalExpr = async (expr: Expr, deps: Dependencies): Promise<string | undefined> => + match<Promise<string | undefined>, Expr>(expr, { + Call: async ({ name, args }) => { + await matchString(name, { + 'add-class': async () => { + const id = await evalExpr(args[0], deps) + const classes = await evalExpr(args[1], deps) + if (id && classes) { + await deps.addClass(id, classes) + } + }, + 'remove-class': async () => { + const id = await evalExpr(args[0], deps) + const classes = await evalExpr(args[1], deps) + if (id && classes) { + await deps.removeClass(id, classes) + } + }, + _: () => Promise.reject(new Error('not supposed to be here')), + }) + return undefined + }, + LiteralString: async s => s, + Identifier: async s => s, + VarIdentifier: async s => s, + _: async _ => undefined, + }) + diff --git a/src/parse-expr.ts b/src/parser.ts index 1c5c08f..1c5c08f 100644 --- a/src/parse-expr.ts +++ b/src/parser.ts diff --git a/src/utils/adt.ts b/src/utils/adt.ts index e9a6c51..7234f67 100644 --- a/src/utils/adt.ts +++ b/src/utils/adt.ts @@ -5,6 +5,11 @@ export const match = [key in T['tag'] | '_']?: (v: TagValue<T, key>) => R }): R => ((pattern as any)[tag.tag] || (pattern._ as any))(tag.value) +export const matchString = + <R, T extends string>(key: T, pattern: { + [key in T | '_']?: (key: key) => R + }): R => ((pattern as any)[key] || (pattern._ as any))(key) + type Tag<N, V> = { tag: N; value: V } export type Enum<T> = { [N in keyof T]: Tag<N, T[N]> }[keyof T] diff --git a/src/utils/parser-comb.ts b/src/utils/parser-comb.ts index 49f633e..e0665f6 100644 --- a/src/utils/parser-comb.ts +++ b/src/utils/parser-comb.ts @@ -1,16 +1,5 @@ -import { Enum, constructors, match } from './adt'; - -export type Result<V, E> = Enum<{ Ok: V, Err: E }> -export const Result = constructors<Result<any, any>>() - -export const mapResult = <A, B, E>(res: Result<A, E>, fn: (_: A) => B): Result<B, E> => - chainResult(res, a => Result.Ok(fn(a))) - -export const chainResult = <A, B, E>(res: Result<A, E>, fn: (_: A) => Result<B, E>): Result<B, E> => - match(res, { - Ok: a => fn(a), - Err: e => Result.Err(e), - }); +import { match } from './adt'; +import { Result, mapResult, chainResult } from './result'; export type ParseResult<T> = Result<{ value: T, input: string }, { error: string, input: string }>; diff --git a/src/utils/result.ts b/src/utils/result.ts new file mode 100644 index 0000000..c0120b8 --- /dev/null +++ b/src/utils/result.ts @@ -0,0 +1,14 @@ +import { Enum, constructors, match } from "./adt"; + +export type Result<V, E> = Enum<{ Ok: V, Err: E }> +export const Result = constructors<Result<any, any>>() + +export const mapResult = <A, B, E>(res: Result<A, E>, fn: (_: A) => B): Result<B, E> => + chainResult(res, a => Result.Ok(fn(a))) + +export const chainResult = <A, B, E>(res: Result<A, E>, fn: (_: A) => Result<B, E>): Result<B, E> => + match(res, { + Ok: a => fn(a), + Err: e => Result.Err(e), + }); + |
