add binexpr ctor to TS
This commit is contained in:
parent
d47f5ff606
commit
93e55bc3bb
|
@ -59,6 +59,13 @@ export const DIGITS = primStringToList("0123456789");
|
|||
export const OPERS = primStringToList("-+*/");
|
||||
export const SKIPS = primStringToList(" ");
|
||||
|
||||
export function bin(oper: Token, lhs: Token, rhs: Token): BinExpr {
|
||||
return {
|
||||
oper,
|
||||
lhs,
|
||||
rhs,
|
||||
};
|
||||
}
|
||||
/**
|
||||
* emit the Result of some attempt to parse T.
|
||||
*/
|
||||
|
@ -89,6 +96,10 @@ export function emitCont<T>(val: T, rem: ReadonlyArray<string>): Result<T> {
|
|||
};
|
||||
}
|
||||
|
||||
export function remain<T>(r: Result<T>): ReadonlyArray<string> {
|
||||
return r.rem;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the value from a result.
|
||||
*/
|
||||
|
@ -190,9 +201,9 @@ export function parseNat(a: Maybe<number>, cs: ReadonlyArray<string>): Result<nu
|
|||
if (n.type === 'digit') {
|
||||
const na = (defaultTo(0, a) * 10) + n.val;
|
||||
return parseNat(just(na), xs);
|
||||
} else {
|
||||
return emitBack(cs);
|
||||
}
|
||||
|
||||
return emitBack(cs);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -205,11 +216,11 @@ export function takeNat(s: ReadonlyArray<string>): Result<number> {
|
|||
const n = parseNat(nothing(), result(cs));
|
||||
|
||||
if (isCont(n)) {
|
||||
return emitCont(result(n), cs.rem);
|
||||
return emitCont(result(n), remain(cs));
|
||||
}
|
||||
}
|
||||
|
||||
return emitBack(cs.rem);
|
||||
return emitBack(s);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -225,9 +236,9 @@ export function parseOper(s: ReadonlyArray<string>): Result<Token> {
|
|||
|
||||
if (o.type === 'oper') {
|
||||
return emitCont(o, xs);
|
||||
} else {
|
||||
return emitBack(xs);
|
||||
}
|
||||
|
||||
return emitBack(s);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -244,19 +255,13 @@ export function takeBin(s: ReadonlyArray<string>): Result<BinExpr> {
|
|||
const lhs = takeNat(ignoreCons(SKIPS, s));
|
||||
|
||||
if (isCont(lhs)) {
|
||||
const oper = takeOper(ignoreCons(SKIPS, lhs.rem));
|
||||
const oper = takeOper(ignoreCons(SKIPS, remain(lhs)));
|
||||
|
||||
if (isCont(oper)) {
|
||||
const rhs = takeNat(ignoreCons(SKIPS, oper.rem));
|
||||
const rhs = takeNat(ignoreCons(SKIPS, remain(oper)));
|
||||
|
||||
if (isCont(rhs)) {
|
||||
const bin: BinExpr = {
|
||||
lhs: digit(result(lhs)),
|
||||
rhs: digit(result(rhs)),
|
||||
oper: result(oper),
|
||||
};
|
||||
|
||||
return emitCont(bin, rhs.rem);
|
||||
return emitCont(bin(result(oper), digit(result(lhs)), digit(result(rhs))), remain(rhs));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { SymbolJust } from './Maybe.js';
|
||||
import { isCont, Result } from './Parse.js';
|
||||
import { isCont, remain, Result, result } from './Parse.js';
|
||||
import { primStringFromList } from './Util.js';
|
||||
|
||||
/**
|
||||
* functional wrapper for `number -> string`
|
||||
|
@ -20,8 +20,8 @@ export function showList<T>(f: (t: T) => string, arr: ReadonlyArray<T>): string
|
|||
*/
|
||||
export function showResult<T>(f: (t: T) => string, r: Result<T>): string {
|
||||
if (isCont(r)) {
|
||||
return 'result: ' + f(r.res[SymbolJust]);
|
||||
return 'result: ' + f(result(r));
|
||||
} else {
|
||||
return 'remainder: ' + r.rem.join('');
|
||||
return 'remainder: ' + primStringFromList(remain(r));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,3 +51,7 @@ export function split<T>(cs: Array<T>, xs: Array<T>): Array<Array<T>> {
|
|||
export function primStringToList(s: string): Array<string> {
|
||||
return s.split('');
|
||||
}
|
||||
|
||||
export function primStringFromList(s: ReadonlyArray<string>): string {
|
||||
return s.join('');
|
||||
}
|
Loading…
Reference in New Issue