Skip to content

Commit

Permalink
vaev+karm: Update from paper-muncher.
Browse files Browse the repository at this point in the history
  • Loading branch information
sleepy-monax committed Feb 1, 2025
1 parent 04c0f46 commit e374efc
Show file tree
Hide file tree
Showing 35 changed files with 763 additions and 645 deletions.
2 changes: 2 additions & 0 deletions src/.clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ SpaceBeforeParens: ControlStatementsExceptForEachMacros
QualifierAlignment: Right
AlignAfterOpenBracket: BlockIndent
SeparateDefinitionBlocks: Always
NamespaceIndentation: None
PointerAlignment: Left

IncludeBlocks: Regroup
IncludeCategories:
Expand Down
5 changes: 4 additions & 1 deletion src/.clang-tidy
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ Checks: >
modernize-use-default-member-init,
readability-non-const-parameter,
readability-function-cognitive-complexity,
readability-isolate-declaration,
cppcoreguidelines-pro-type-member-init,
clang-diagnostic-*,
llvm-*,
misc-*
misc-*,
-misc-non-private-member-variables-in-classes
2 changes: 1 addition & 1 deletion src/libs/karm-base/buf.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ struct Buf {
}

Buf(Move, T* buf, usize len)
: _buf(buf),
: _buf(reinterpret_cast<Manual<T>*>(buf)),
_cap(len),
_len(len) {
}
Expand Down
1 change: 1 addition & 0 deletions src/libs/karm-base/manual.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,6 @@ struct Manual {

static_assert(Meta::Trivial<Manual<isize>>);
static_assert(sizeof(Manual<isize>) == sizeof(isize));
static_assert(alignof(Manual<isize>) == alignof(isize));

} // namespace Karm
10 changes: 7 additions & 3 deletions src/libs/karm-base/string.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,12 +108,12 @@ struct _String {

static constexpr Array<Unit, 1> _EMPTY = {0};

Unit const* _buf = nullptr;
Unit* _buf = nullptr;
usize _len = 0;

constexpr _String() = default;

always_inline _String(Move, Unit const* buf, usize len)
always_inline _String(Move, Unit* buf, usize len)
: _buf(buf),
_len(len) {
}
Expand Down Expand Up @@ -276,6 +276,10 @@ struct _StringBuilder {
_StringBuilder(usize cap = 16)
: _buf(cap) {}

_StringBuilder(String&& str)
: _buf(MOVE, std::exchange(str._buf, nullptr), std::exchange(str._len, 0)) {
}

void ensure(usize cap) {
// NOTE: This way client code don't have to take
// the null-terminator into account
Expand Down Expand Up @@ -304,7 +308,7 @@ struct _StringBuilder {
return _buf.size();
}

_Str<E> str() lifetimebound {
_Str<E> str() const lifetimebound {
return _buf;
}

Expand Down
12 changes: 12 additions & 0 deletions src/libs/karm-base/tests/test-opt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,16 @@ test$("opt-take") {
return Ok();
}

test$("opt-equal") {
Opt<int> opt = NONE;
expectEq$(opt, NONE);
expectNe$(opt, 42);

opt = 42;
expectEq$(opt, 42);
expectNe$(opt, NONE);

return Ok();
}

} // namespace Karm::Base::Tests
179 changes: 179 additions & 0 deletions src/libs/karm-io/fmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,39 @@

namespace Karm::Io {

// MARK: Format ----------------------------------------------------------------

Res<usize> _format(Io::TextWriter& writer, Str format, _Args& args) {
Io::SScan scan{format};
usize written = 0;
usize index = 0;

while (not scan.ended()) {
Rune c = scan.next();

if (c == '{') {
scan.skip(':');
scan.begin();
while (scan.peek() != '}') {
scan.next();
}
scan.next();
Io::SScan inner{scan.end()};
written += try$(args.format(inner, writer, index));
index++;
} else if (c == '\n') {
// normalize newlines
written += try$(writer.writeStr(Str{Sys::LINE_ENDING}));
} else {
written += try$(writer.writeRune(c));
}
}

return Ok(written);
};

// MARK: Change case -----------------------------------------------------------

static auto const RE_SEP =
Re::single(' ', '\t', '.', '_', '/', '-');

Expand Down Expand Up @@ -300,4 +333,150 @@ Res<String> changeCase(Str str, Case toCase) {
}
}

// MARK: Number formatting -----------------------------------------------------

Str NumberFormatter::formatPrefix() {
if (base == 16)
return "0x";

if (base == 8)
return "0o";

if (base == 2)
return "0b";

return "";
}

void NumberFormatter::parse(Str str) {
Io::SScan scan{str};
parse(scan);
}

void NumberFormatter::parse(Io::SScan& scan) {
if (scan.skip('#'))
prefix = true;

if (scan.skip('0'))
fillChar = '0';

width = atoi(scan).unwrapOr(0);

if (scan.ended())
return;

Rune c = scan.next();
switch (c) {
case 'b':
base = 2;
break;

case 'o':
base = 8;
break;

case 'd':
base = 10;
break;

case 'x':
base = 16;
break;

case 'p':
prefix = true;
base = 16;
fillChar = '0';
width = sizeof(usize) * 2;
break;

case 'c':
isChar = true;
break;

default:
break;
}
}

Res<usize> NumberFormatter::formatUnsigned(Io::TextWriter& writer, usize val) {
auto digit = [](usize v) {
if (v < 10)
return '0' + v;
return 'a' + (v - 10);
};

InlineVec<char, 128> buf;

do {
buf.pushBack(digit(val % base));
val /= base;
} while (val != 0 and buf.len() < buf.cap());

while (width > buf.len())
buf.pushBack(fillChar);

reverse(mutSub(buf));

usize written = 0;
if (prefix)
written += try$(writer.writeStr(formatPrefix()));
written += try$(writer.writeStr(Str{buf}));

return Ok(written);
}

Res<usize> NumberFormatter::formatSigned(Io::TextWriter& writer, isize val) {
usize written = 0;
if (val < 0) {
written += try$(writer.writeRune('-'));
val = -val;
}
written += try$(formatUnsigned(writer, val));
return Ok(written);
}

Res<usize> NumberFormatter::formatRune(Io::TextWriter& writer, Rune val) {
if (not prefix)
return writer.writeRune(val);

if (val == '\'')
return writer.writeStr("\\'"s);

if (val == '\"')
return writer.writeStr("\\\""s);

if (val == '\?')
return writer.writeStr("\\?"s);

if (val == '\\')
return writer.writeStr("\\\\"s);

if (val == '\a')
return writer.writeStr("\\a"s);

if (val == '\b')
return writer.writeStr("\\b"s);

if (val == '\f')
return writer.writeStr("\\f"s);

if (val == '\n')
return writer.writeStr("\\n"s);

if (val == '\r')
return writer.writeStr("\\r"s);

if (val == '\t')
return writer.writeStr("\\t"s);

if (val == '\v')
return writer.writeStr("\\v"s);

if (not isAsciiPrint(val))
return Io::format(writer, "\\u{x}", val);

return writer.writeRune(val);
}

} // namespace Karm::Io
Loading

0 comments on commit e374efc

Please sign in to comment.