298 const std::optional<uint16_t> sStart,
299 const std::optional<uint16_t> sEnd,
300 const std::optional<uint16_t> cPage)
const
304 fmt::println(
"Invalid format");
310 auto [major, minor, patch] =
version();
311 fmt::println(
"Version: {}.{}.{}", major, minor, patch);
312 fmt::println(
"Timestamp: {}",
timestamp());
313 fmt::print(
"SHA256: ");
314 for (
const auto sha =
sha256();
unsigned char h : sha)
315 fmt::print(
"{:02x}", h);
321 if ((sStart.has_value() && !sEnd.has_value()) || (!sStart.has_value() && sEnd.has_value()))
323 fmt::print(fmt::fg(fmt::color::red),
"Both start and end parameter need to be provided together\n");
326 if (sStart.has_value() && sEnd.has_value() && sStart.value() >= sEnd.value())
328 fmt::print(fmt::fg(fmt::color::red),
"Invalid slice start and end arguments\n");
333 const auto vals =
values(syms);
336 const auto code_block =
code(inst_locs);
340 std::size_t size = syms.symbols.size();
341 std::size_t sliceSize = size;
344 if (showSym && sStart.has_value() && sEnd.has_value() && (sStart.value() > size || sEnd.value() > size))
345 fmt::print(fmt::fg(fmt::color::red),
"Slice start or end can't be greater than the segment size: {}\n", size);
346 else if (showSym && sStart.has_value() && sEnd.has_value())
347 sliceSize = sEnd.value() - sStart.value() + 1;
350 fmt::println(
"{} (length: {})", fmt::styled(
"Symbols table", fmt::fg(fmt::color::cyan)), sliceSize);
352 for (std::size_t j = 0; j < size; ++j)
354 if (
auto start = sStart;
auto end = sEnd)
355 showSym = showSym && (j >= start.value() && j <= end.value());
358 fmt::println(
"{}) {}", j, syms.symbols[j]);
369 std::size_t size = vals.values.size();
370 std::size_t sliceSize = size;
373 if (showVal && sStart.has_value() && sEnd.has_value() && (sStart.value() > size || sEnd.value() > size))
374 fmt::print(fmt::fg(fmt::color::red),
"Slice start or end can't be greater than the segment size: {}\n", size);
375 else if (showVal && sStart.has_value() && sEnd.has_value())
376 sliceSize = sEnd.value() - sStart.value() + 1;
379 fmt::println(
"{} (length: {})", fmt::styled(
"Constants table", fmt::fg(fmt::color::cyan)), sliceSize);
381 for (std::size_t j = 0; j < size; ++j)
383 if (
auto start = sStart;
auto end = sEnd)
384 showVal = showVal && (j >= start.value() && j <= end.value());
388 switch (
const auto val = vals.values[j]; val.valueType())
391 fmt::println(
"{}) (Number) {}", j, val.number());
394 fmt::println(
"{}) (String) {}", j, val.string());
397 fmt::println(
"{}) (PageAddr) {}", j, val.pageAddr());
400 fmt::print(fmt::fg(fmt::color::red),
"Value type not handled: {}\n",
std::to_string(val.valueType()));
414 std::size_t size = inst_locs.locations.size();
415 std::size_t sliceSize = size;
418 if (showVal && sStart.has_value() && sEnd.has_value() && (sStart.value() > size || sEnd.value() > size))
419 fmt::print(fmt::fg(fmt::color::red),
"Slice start or end can't be greater than the segment size: {}\n", size);
420 else if (showVal && sStart.has_value() && sEnd.has_value())
421 sliceSize = sEnd.value() - sStart.value() + 1;
424 fmt::println(
"{} (length: {})", fmt::styled(
"Instruction locations table", fmt::fg(fmt::color::cyan)), sliceSize);
425 if (showVal && size > 0)
426 fmt::println(
" PP, IP");
428 for (std::size_t j = 0; j < size; ++j)
430 if (
auto start = sStart;
auto end = sEnd)
431 showVal = showVal && (j >= start.value() && j <= end.value());
433 const auto& location = inst_locs.locations[j];
435 fmt::println(
"{:>3},{:>3} -> {}:{}", location.page_pointer, location.inst_pointer, files.filenames[location.filename_id], location.line);
442 const auto stringify_value = [](
const Value& val) -> std::string {
443 switch (val.valueType())
446 return fmt::format(
"{} (Number)", val.number());
448 return fmt::format(
"{} (String)", val.string());
450 return fmt::format(
"{} (PageAddr)", val.pageAddr());
481 [[nodiscard]] uint16_t primary()
const
486 [[nodiscard]] uint16_t secondary()
const
488 return static_cast<uint16_t
>((padding << 4) | (arg & 0xf000) >> 12);
492 const std::unordered_map<Instruction, ArgKind> arg_kinds = {
497 {
STORE, ArgKind::Symbol },
501 {
JUMP, ArgKind::Raw },
502 {
CALL, ArgKind::Raw },
506 {
DEL, ArgKind::Symbol },
509 {
PLUGIN, ArgKind::Constant },
510 {
LIST, ArgKind::Raw },
564 {
MUL_BY, ArgKind::RawRaw },
570 const auto builtin_name = [](
const uint16_t idx) {
573 const auto value_str = [&stringify_value, &vals](
const uint16_t idx) {
574 return stringify_value(vals.values[idx]);
576 const auto symbol_name = [&syms](
const uint16_t idx) {
577 return syms.symbols[idx];
580 const auto color_print_inst = [=](
const std::string& name, std::optional<Arg> arg = std::nullopt) {
581 fmt::print(
"{}", fmt::styled(name, fmt::fg(fmt::color::gold)));
584 constexpr auto sym_color = fmt::fg(fmt::color::green);
585 constexpr auto const_color = fmt::fg(fmt::color::magenta);
586 constexpr auto raw_color = fmt::fg(fmt::color::red);
588 switch (
auto [kind, _, idx] = arg.value(); kind)
590 case ArgKind::Symbol:
591 fmt::print(sym_color,
" {}\n", symbol_name(idx));
593 case ArgKind::Constant:
594 fmt::print(const_color,
" {}\n", value_str(idx));
596 case ArgKind::Builtin:
597 fmt::print(
" {}\n", builtin_name(idx));
600 fmt::print(raw_color,
" ({})\n", idx);
602 case ArgKind::ConstConst:
603 fmt::print(
" {}, {}\n", fmt::styled(value_str(arg->primary()), const_color), fmt::styled(value_str(arg->secondary()), const_color));
605 case ArgKind::ConstSym:
606 fmt::print(
" {}, {}\n", fmt::styled(value_str(arg->primary()), const_color), fmt::styled(symbol_name(arg->secondary()), sym_color));
608 case ArgKind::SymConst:
609 fmt::print(
" {}, {}\n", fmt::styled(symbol_name(arg->primary()), sym_color), fmt::styled(value_str(arg->secondary()), const_color));
611 case ArgKind::SymSym:
612 fmt::print(
" {}, {}\n", fmt::styled(symbol_name(arg->primary()), sym_color), fmt::styled(symbol_name(arg->secondary()), sym_color));
614 case ArgKind::BuiltinRaw:
615 fmt::print(
" {}, {}\n", builtin_name(arg->primary()), fmt::styled(arg->secondary(), raw_color));
617 case ArgKind::ConstRaw:
618 fmt::print(
" {}, {}\n", fmt::styled(value_str(arg->primary()), const_color), fmt::styled(arg->secondary(), raw_color));
620 case ArgKind::SymRaw:
621 fmt::print(
" {}, {}\n", fmt::styled(symbol_name(arg->primary()), sym_color), fmt::styled(arg->secondary(), raw_color));
623 case ArgKind::RawSym:
624 fmt::print(
" {}, {}\n", fmt::styled(arg->primary(), raw_color), fmt::styled(symbol_name(arg->secondary()), sym_color));
626 case ArgKind::RawConst:
627 fmt::print(
" {}, {}\n", fmt::styled(arg->primary(), raw_color), fmt::styled(value_str(arg->secondary()), const_color));
629 case ArgKind::RawRaw:
630 fmt::print(
" {}, {}\n", fmt::styled(arg->primary(), raw_color), fmt::styled(arg->secondary(), raw_color));
632 case ArgKind::RawRawRaw:
633 fmt::print(
" {}, {}, {}\n", fmt::styled(arg->padding, raw_color), fmt::styled((arg->arg & 0xff00) >> 8, raw_color), fmt::styled(arg->arg & 0x00ff, raw_color));
645 for (
const auto& page : code_block.pages)
647 bool displayCode =
true;
649 if (
auto wanted_page = cPage)
650 displayCode = pp == wanted_page.value();
654 "{} {} (length: {})",
655 fmt::styled(
"Code segment", fmt::fg(fmt::color::magenta)),
656 fmt::styled(pp, fmt::fg(fmt::color::magenta)),
666 if (sStart.has_value() && sEnd.has_value() && ((sStart.value() > page.size()) || (sEnd.value() > page.size())))
668 fmt::print(fmt::fg(fmt::color::red),
"Slice start or end can't be greater than the segment size: {}\n", page.size());
672 std::optional<InstLoc> previous_loc = std::nullopt;
674 for (std::size_t j = sStart.value_or(0), end = sEnd.value_or(page.size()); j < end; j += 4)
676 const uint8_t inst = page[j];
677 const uint8_t padding = page[j + 1];
678 const auto arg =
static_cast<uint16_t
>((page[j + 2] << 8) + page[j + 3]);
684 if (maybe_loc && (!previous_loc || maybe_loc != previous_loc))
686 if (!previous_loc || previous_loc->filename_id != maybe_loc->filename_id)
687 fmt::println(
"{}", files.filenames[maybe_loc->filename_id]);
688 fmt::print(
"{:>4}", maybe_loc->line + 1);
689 previous_loc = maybe_loc;
694 fmt::print(fmt::fg(fmt::color::cyan),
"{:>4}", j / 4);
696 fmt::print(
" {:02x} {:02x} {:02x} {:02x} ", inst, padding, page[j + 2], page[j + 3]);
698 if (
const auto idx =
static_cast<std::size_t
>(inst); idx <
InstructionNames.size())
701 if (
const auto iinst =
static_cast<Instruction>(inst); arg_kinds.contains(iinst))
702 color_print_inst(inst_name, Arg { arg_kinds.at(iinst), padding, arg });
704 color_print_inst(inst_name);
707 fmt::println(
"Unknown instruction");