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",
types_to_str[
static_cast<std::size_t
>(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());
444 const std::unordered_map<Instruction, ArgKind> arg_kinds = {
449 {
STORE, ArgKind::Symbol },
452 {
JUMP, ArgKind::Raw },
453 {
CALL, ArgKind::Raw },
457 {
DEL, ArgKind::Symbol },
460 {
PLUGIN, ArgKind::Value },
461 {
LIST, ArgKind::Raw },
468 const auto color_print_inst = [&syms, &vals, &stringify_value](
const std::string& name, std::optional<Arg> arg = std::nullopt) {
469 fmt::print(
"{}", fmt::styled(name, fmt::fg(fmt::color::gold)));
472 switch (
auto [kind, idx] = arg.value(); kind)
474 case ArgKind::Symbol:
475 fmt::print(fmt::fg(fmt::color::green),
" {}\n", syms.symbols[idx]);
478 fmt::print(fmt::fg(fmt::color::magenta),
" {}\n", stringify_value(vals.values[idx]));
480 case ArgKind::Builtin:
484 fmt::print(fmt::fg(fmt::color::red),
" ({})\n", idx);
496 for (
const auto& page : code_block.pages)
498 bool displayCode =
true;
500 if (
auto wanted_page = cPage)
501 displayCode = pp == wanted_page.value();
505 "{} {} (length: {})",
506 fmt::styled(
"Code segment", fmt::fg(fmt::color::magenta)),
507 fmt::styled(pp, fmt::fg(fmt::color::magenta)),
517 if (cPage.value_or(pp) != pp)
521 if (sStart.has_value() && sEnd.has_value() && ((sStart.value() > page.size()) || (sEnd.value() > page.size())))
523 fmt::print(fmt::fg(fmt::color::red),
"Slice start or end can't be greater than the segment size: {}\n", page.size());
527 for (std::size_t j = sStart.value_or(0), end = sEnd.value_or(page.size()); j < end; j += 4)
529 const uint8_t inst = page[j];
531 const uint8_t padding = page[j + 1];
532 const auto arg =
static_cast<uint16_t
>((page[j + 2] << 8) + page[j + 3]);
535 fmt::print(fmt::fg(fmt::color::cyan),
"{:>4}", j / 4);
537 fmt::print(
" {:02x} {:02x} {:02x} {:02x} ", inst, padding, page[j + 2], page[j + 3]);
539 if (
const auto idx =
static_cast<std::size_t
>(inst); idx <
InstructionNames.size())
542 if (
const auto iinst =
static_cast<Instruction>(inst); arg_kinds.contains(iinst))
543 color_print_inst(inst_name, Arg { arg_kinds.at(iinst), arg });
545 color_print_inst(inst_name);
548 fmt::println(
"Unknown instruction");