/** * parser.ts - Unlambda parser. * * @author CismonX * @license MIT */ import { Expression, FuncChar, FuncNoChar, WhiteSpace } from './language'; /** * Parse result is a tuple `[E, R]`, where `E` is the parsed expression, * and `R` is the unparsed code fragment. * * If `E` is `never`, or `R` is more than whitespaces and comments, * the Unlambda code given to the parser is malformed. */ export type ParseResult = [Expression, string]; /** * Parse the given Unlambda code. Returns a `ParseResult`. */ export type Parse = // `C` is the first character of the code, `R` is the rest. Code extends `${infer C}${infer R}` ? // Trim comment line. C extends '#' ? Parse // Trim whitespace. : C extends WhiteSpace ? Parse // Apply the result of two consective parse. : C extends '`' ? ParseApply> // A single character function. : C extends FuncNoChar ? [C, R] // A `.x` or `?x` function. : R extends `${infer C1}${infer R1}` ? `${C}${C1}` extends FuncChar ? [`${C}${C1}`, R1] : [never, R] : [never, R] : [never, Code]; /** * Given the left part (the "operator") of an application, parse * the right part (the "operand"). */ type ParseApply = ParseApplyResult>; /** * Given the parse result of two parts of an application, return * the final parse result. */ type ParseApplyResult = [[L, R[0]], R[1]];