S-expressions: Difference between revisions

Content added Content deleted
m (→‎JavaScript :: Functional: Some reduction and tidying.)
Line 3,792: Line 3,792:
// A tuple of (parsed trees, residual tokens)
// A tuple of (parsed trees, residual tokens)
// derived from a list of tokens.
// derived from a list of tokens.
until(finished)(readToken)(
until(finished)(readToken)([
Tuple([])(tokens)
[], tokens
);
]);




// finished :: ([Expr], [String]) -> Bool
// finished :: ([Expr], [String]) -> Bool
const finished = ([, tkns]) =>
const finished = ([, tokens]) =>
0 === tkns.length || ")" === tkns[0];
// True if no tokens remain, or the next
// closes a sub-expression.
0 === tokens.length || ")" === tokens[0];




// readToken :: ([Expr], [String]) -> ([Expr], [String])
// readToken :: ([Expr], [String]) -> ([Expr], [String])
const readToken = ([exprs, tkns]) =>
const readToken = ([xs, tokens]) => {
0 < tkns.length ? (() => {
// A tuple of enriched expressions and
const [t, ...ts] = tkns;
// depleted tokens.
const [token, ...ts] = tokens;


// Subforests are introduced by brackets,
// An open bracket introduces recursion over
return "(" === t ? (
// a sub-expression to define a sub-list.
bimap(
return "(" === token ? (() => {
xs => exprs.concat([xs])
const [expr, rest] = parseExpr(ts);
)(tail)(parseExpr(ts))

// and conclude where brackets close.
) : ")" === t ? (
Tuple(exprs)(ts)

// Other tokens are appended leaves.
) : Tuple(
exprs.concat(atom(t))
)(ts);
})() : Tuple(exprs)(tkns);


return [xs.concat([expr]), rest.slice(1)];
})() : ")" === token ? (
[xs, token]
) : [xs.concat(atom(token)), ts];
};


// ------------------- ATOM PARSER -------------------
// ------------------- ATOM PARSER -------------------
Line 3,883: Line 3,880:


// --------------------- GENERIC ---------------------
// --------------------- GENERIC ---------------------

// Tuple (,) :: a -> b -> (a, b)
const Tuple = a =>
b => ({
type: "Tuple",
"0": a,
"1": b,
length: 2,
*[Symbol.iterator]() {
for (const k in this) {
if (!isNaN(k)) {
yield this[k];
}
}
}
});


// bimap :: (a -> b) -> (c -> d) -> (a, c) -> (b, d)
const bimap = f =>
// Tuple instance of bimap.
// A tuple of the application of f and g to the
// first and second values respectively.
g => ([a, b]) => Tuple(f(a))(g(b));



// even :: Int -> Bool
// even :: Int -> Bool
Line 3,922: Line 3,894:
f => {
f => {
const go = x =>
const go = x =>
p(x) ? (
p(x) ? x : go(f(x));
x
) : go(f(x));


return go;
return go;
};
};


// tail :: [a] -> [a]
const tail = xs =>
// A new list consisting of all
// items of xs except the first.
0 < xs.length ? (
xs.slice(1)
) : undefined;


return main();
return main();