275 const std::optional<uint16_t> sStart,
276 const std::optional<uint16_t> sEnd,
277 const std::optional<uint16_t> cPage)
const
281 fmt::println(
"Invalid format");
285 auto [major, minor, patch] =
version();
286 fmt::println(
"Version: {}.{}.{}", major, minor, patch);
287 fmt::println(
"Timestamp: {}",
timestamp());
288 fmt::print(
"SHA256: ");
289 for (
const auto sha =
sha256();
unsigned char h : sha)
290 fmt::print(
"{:02x}", h);
295 if ((sStart.has_value() && !sEnd.has_value()) || (!sStart.has_value() && sEnd.has_value()))
297 fmt::print(fmt::fg(fmt::color::red),
"Both start and end parameter need to be provided together\n");
300 if (sStart.has_value() && sEnd.has_value() && sStart.value() >= sEnd.value())
302 fmt::print(fmt::fg(fmt::color::red),
"Invalid slice start and end arguments\n");
307 const auto vals =
values(syms);
310 const auto code_block =
code(inst_locs);
314 std::size_t size = syms.symbols.size();
315 std::size_t sliceSize = size;
318 if (showSym && sStart.has_value() && sEnd.has_value() && (sStart.value() > size || sEnd.value() > size))
319 fmt::print(fmt::fg(fmt::color::red),
"Slice start or end can't be greater than the segment size: {}\n", size);
320 else if (showSym && sStart.has_value() && sEnd.has_value())
321 sliceSize = sEnd.value() - sStart.value() + 1;
324 fmt::println(
"{} (length: {})", fmt::styled(
"Symbols table", fmt::fg(fmt::color::cyan)), sliceSize);
326 for (std::size_t j = 0; j < size; ++j)
328 if (
auto start = sStart;
auto end = sEnd)
329 showSym = showSym && (j >= start.value() && j <= end.value());
332 fmt::println(
"{}) {}", j, syms.symbols[j]);
343 std::size_t size = vals.values.size();
344 std::size_t sliceSize = size;
347 if (showVal && sStart.has_value() && sEnd.has_value() && (sStart.value() > size || sEnd.value() > size))
348 fmt::print(fmt::fg(fmt::color::red),
"Slice start or end can't be greater than the segment size: {}\n", size);
349 else if (showVal && sStart.has_value() && sEnd.has_value())
350 sliceSize = sEnd.value() - sStart.value() + 1;
353 fmt::println(
"{} (length: {})", fmt::styled(
"Constants table", fmt::fg(fmt::color::cyan)), sliceSize);
355 for (std::size_t j = 0; j < size; ++j)
357 if (
auto start = sStart;
auto end = sEnd)
358 showVal = showVal && (j >= start.value() && j <= end.value());
362 switch (
const auto val = vals.values[j]; val.valueType())
365 fmt::println(
"{}) (Number) {}", j, val.number());
368 fmt::println(
"{}) (String) {}", j, val.string());
371 fmt::println(
"{}) (PageAddr) {}", j, val.pageAddr());
374 fmt::print(fmt::fg(fmt::color::red),
"Value type not handled: {}\n",
std::to_string(val.valueType()));
388 std::size_t size = inst_locs.locations.size();
389 std::size_t sliceSize = size;
392 if (showVal && sStart.has_value() && sEnd.has_value() && (sStart.value() > size || sEnd.value() > size))
393 fmt::print(fmt::fg(fmt::color::red),
"Slice start or end can't be greater than the segment size: {}\n", size);
394 else if (showVal && sStart.has_value() && sEnd.has_value())
395 sliceSize = sEnd.value() - sStart.value() + 1;
398 fmt::println(
"{} (length: {})", fmt::styled(
"Instruction locations table", fmt::fg(fmt::color::cyan)), sliceSize);
399 if (showVal && size > 0)
400 fmt::println(
" PP, IP");
402 for (std::size_t j = 0; j < size; ++j)
404 if (
auto start = sStart;
auto end = sEnd)
405 showVal = showVal && (j >= start.value() && j <= end.value());
407 const auto& location = inst_locs.locations[j];
409 fmt::println(
"{:>3},{:>3} -> {}:{}", location.page_pointer, location.inst_pointer, files.filenames[location.filename_id], location.line);
416 const auto stringify_value = [](
const Value& val) -> std::string {
417 switch (val.valueType())
420 return fmt::format(
"{} (Number)", val.number());
422 return fmt::format(
"{} (String)", val.string());
424 return fmt::format(
"{} (PageAddr)", val.pageAddr());
454 [[nodiscard]] uint16_t primary()
const
459 [[nodiscard]] uint16_t secondary()
const
461 return static_cast<uint16_t
>((padding << 4) | (arg & 0xf000) >> 12);
465 const std::unordered_map<Instruction, ArgKind> arg_kinds = {
470 {
STORE, ArgKind::Symbol },
473 {
JUMP, ArgKind::Raw },
474 {
CALL, ArgKind::Raw },
478 {
DEL, ArgKind::Symbol },
481 {
PLUGIN, ArgKind::Constant },
482 {
LIST, ArgKind::Raw },
538 const auto builtin_name = [](
const uint16_t idx) {
541 const auto value_str = [&stringify_value, &vals](
const uint16_t idx) {
542 return stringify_value(vals.values[idx]);
544 const auto symbol_name = [&syms](
const uint16_t idx) {
545 return syms.symbols[idx];
548 const auto color_print_inst = [=](
const std::string& name, std::optional<Arg> arg = std::nullopt) {
549 fmt::print(
"{}", fmt::styled(name, fmt::fg(fmt::color::gold)));
552 constexpr auto sym_color = fmt::fg(fmt::color::green);
553 constexpr auto const_color = fmt::fg(fmt::color::magenta);
554 constexpr auto raw_color = fmt::fg(fmt::color::red);
556 switch (
auto [kind, _, idx] = arg.value(); kind)
558 case ArgKind::Symbol:
559 fmt::print(sym_color,
" {}\n", symbol_name(idx));
561 case ArgKind::Constant:
562 fmt::print(const_color,
" {}\n", value_str(idx));
564 case ArgKind::Builtin:
565 fmt::print(
" {}\n", builtin_name(idx));
568 fmt::print(raw_color,
" ({})\n", idx);
570 case ArgKind::ConstConst:
571 fmt::print(
" {}, {}\n", fmt::styled(value_str(arg->primary()), const_color), fmt::styled(value_str(arg->secondary()), const_color));
573 case ArgKind::ConstSym:
574 fmt::print(
" {}, {}\n", fmt::styled(value_str(arg->primary()), const_color), fmt::styled(symbol_name(arg->secondary()), sym_color));
576 case ArgKind::SymConst:
577 fmt::print(
" {}, {}\n", fmt::styled(symbol_name(arg->primary()), sym_color), fmt::styled(value_str(arg->secondary()), const_color));
579 case ArgKind::SymSym:
580 fmt::print(
" {}, {}\n", fmt::styled(symbol_name(arg->primary()), sym_color), fmt::styled(symbol_name(arg->secondary()), sym_color));
582 case ArgKind::BuiltinRaw:
583 fmt::print(
" {}, {}\n", builtin_name(arg->primary()), fmt::styled(arg->secondary(), raw_color));
585 case ArgKind::ConstRaw:
586 fmt::print(
" {}, {}\n", fmt::styled(value_str(arg->primary()), const_color), fmt::styled(arg->secondary(), raw_color));
588 case ArgKind::SymRaw:
589 fmt::print(
" {}, {}\n", fmt::styled(symbol_name(arg->primary()), sym_color), fmt::styled(arg->secondary(), raw_color));
591 case ArgKind::RawSym:
592 fmt::print(
" {}, {}\n", fmt::styled(arg->primary(), raw_color), fmt::styled(symbol_name(arg->secondary()), sym_color));
594 case ArgKind::RawConst:
595 fmt::print(
" {}, {}\n", fmt::styled(arg->primary(), raw_color), fmt::styled(value_str(arg->secondary()), const_color));
597 case ArgKind::RawRaw:
598 fmt::print(
" {}, {}\n", fmt::styled(arg->primary(), raw_color), fmt::styled(arg->secondary(), raw_color));
610 for (
const auto& page : code_block.pages)
612 bool displayCode =
true;
614 if (
auto wanted_page = cPage)
615 displayCode = pp == wanted_page.value();
619 "{} {} (length: {})",
620 fmt::styled(
"Code segment", fmt::fg(fmt::color::magenta)),
621 fmt::styled(pp, fmt::fg(fmt::color::magenta)),
631 if (cPage.value_or(pp) != pp)
635 if (sStart.has_value() && sEnd.has_value() && ((sStart.value() > page.size()) || (sEnd.value() > page.size())))
637 fmt::print(fmt::fg(fmt::color::red),
"Slice start or end can't be greater than the segment size: {}\n", page.size());
641 for (std::size_t j = sStart.value_or(0), end = sEnd.value_or(page.size()); j < end; j += 4)
643 const uint8_t inst = page[j];
645 const uint8_t padding = page[j + 1];
646 const auto arg =
static_cast<uint16_t
>((page[j + 2] << 8) + page[j + 3]);
649 fmt::print(fmt::fg(fmt::color::cyan),
"{:>4}", j / 4);
651 fmt::print(
" {:02x} {:02x} {:02x} {:02x} ", inst, padding, page[j + 2], page[j + 3]);
653 if (
const auto idx =
static_cast<std::size_t
>(inst); idx <
InstructionNames.size())
656 if (
const auto iinst =
static_cast<Instruction>(inst); arg_kinds.contains(iinst))
657 color_print_inst(inst_name, Arg { arg_kinds.at(iinst), padding, arg });
659 color_print_inst(inst_name);
662 fmt::println(
"Unknown instruction");