Sebastian Walz 860d31cee1
Tohu vaBohu
2023-04-21 00:22:52 +02:00

91 lines
3.2 KiB
Nix

{ debug, list, string, type, ... }:
let
Indentation
= type.enum "Indentation"
{
less = null;
more = null;
};
in
{
inherit(Indentation) less more;
# string -> string | [ string | bool | null ] -> string
__functor#: self -> string | [ string | Indentation | null ] -> string
= self:
{ initial ? "", tab ? " ", ... }:
body:
(
list.fold
(
# S -> null | string | bool -> S
# where S: { depth: uint, indent: string, result: string }
{ cache, depth, indent, lineNumber, result, tab } @ state:
line:
type.matchPrimitiveOrPanic line
{
null = state;
string
= state
// {
lineNumber = lineNumber + 1;
result = "${result}${indent}${line}\n";
};
set
= state
// (
if Indentation.isInstanceOf line
then
Indentation.match line
{
more
= let
depth' = depth + 1;
cache'
= if list.length cache <= depth'
then
cache ++ [ "${list.foot cache}${tab}" ]
else
cache;
in
{
cache = cache';
depth = depth';
indent = list.get cache' depth';
};
less
= if depth > 0
then
let
depth'= depth - 1;
in
{
depth = depth';
indent= list.get cache depth';
}
else
debug.panic [] "Cannot indent less than zero." null;
}
else
debug.panic [] "Got set, but either string or Indentation was expected!" null
);
}
)
{
cache = [ initial ];
depth = 0;
indent = initial;
lineNumber = 0;
result = "";
inherit tab;
}
(
type.matchPrimitiveOrPanic body
{
list = body;
string = string.splitLines body;
}
)
).result;
}