21 { LOAD_FAST, ArgKind::Symbol },
22 { LOAD_FAST_BY_INDEX, ArgKind::Raw },
23 { LOAD_SYMBOL, ArgKind::Symbol },
24 { LOAD_CONST, ArgKind::Constant },
25 { POP_JUMP_IF_TRUE, ArgKind::Raw },
26 { STORE, ArgKind::Symbol },
27 { STORE_REF, ArgKind::Symbol },
28 { SET_VAL, ArgKind::Symbol },
29 { POP_JUMP_IF_FALSE, ArgKind::Raw },
30 { JUMP, ArgKind::Raw },
31 { PUSH_RETURN_ADDRESS, ArgKind::RawHex },
32 { CALL, ArgKind::Raw },
33 { CAPTURE, ArgKind::Symbol },
34 { RENAME_NEXT_CAPTURE, ArgKind::Symbol },
35 { BUILTIN, ArgKind::Builtin },
36 { DEL, ArgKind::Symbol },
37 { MAKE_CLOSURE, ArgKind::Constant },
38 { GET_FIELD, ArgKind::Symbol },
39 { PLUGIN, ArgKind::Constant },
40 { LIST, ArgKind::Raw },
41 { APPEND, ArgKind::Raw },
42 { CONCAT, ArgKind::Raw },
43 { APPEND_IN_PLACE, ArgKind::Raw },
44 { CONCAT_IN_PLACE, ArgKind::Raw },
45 { POP_LIST, ArgKind::Raw },
46 { POP_LIST_IN_PLACE, ArgKind::Raw },
47 { SET_AT_INDEX, ArgKind::Raw },
48 { SET_AT_2_INDEX, ArgKind::Raw },
49 { RESET_SCOPE_JUMP, ArgKind::Raw },
50 { LOAD_CONST_LOAD_CONST, ArgKind::ConstConst },
51 { LOAD_CONST_STORE, ArgKind::ConstSym },
52 { LOAD_CONST_SET_VAL, ArgKind::ConstSym },
53 { STORE_FROM, ArgKind::SymSym },
54 { STORE_FROM_INDEX, ArgKind::RawSym },
55 { SET_VAL_FROM, ArgKind::SymSym },
56 { SET_VAL_FROM_INDEX, ArgKind::RawSym },
57 { INCREMENT, ArgKind::SymRaw },
58 { INCREMENT_BY_INDEX, ArgKind::RawRaw },
59 { INCREMENT_STORE, ArgKind::RawRaw },
60 { DECREMENT, ArgKind::SymRaw },
61 { DECREMENT_BY_INDEX, ArgKind::RawRaw },
62 { DECREMENT_STORE, ArgKind::SymRaw },
63 { STORE_TAIL, ArgKind::SymSym },
64 { STORE_TAIL_BY_INDEX, ArgKind::RawSym },
65 { STORE_HEAD, ArgKind::SymSym },
66 { STORE_HEAD_BY_INDEX, ArgKind::RawSym },
67 { STORE_LIST, ArgKind::RawSym },
68 { SET_VAL_TAIL, ArgKind::SymSym },
69 { SET_VAL_TAIL_BY_INDEX, ArgKind::RawSym },
70 { SET_VAL_HEAD, ArgKind::SymSym },
71 { SET_VAL_HEAD_BY_INDEX, ArgKind::RawSym },
72 { CALL_BUILTIN, ArgKind::BuiltinRaw },
73 { CALL_BUILTIN_WITHOUT_RETURN_ADDRESS, ArgKind::BuiltinRaw },
74 { LT_CONST_JUMP_IF_FALSE, ArgKind::ConstRaw },
75 { LT_CONST_JUMP_IF_TRUE, ArgKind::ConstRaw },
76 { LT_SYM_JUMP_IF_FALSE, ArgKind::SymRaw },
77 { GT_CONST_JUMP_IF_TRUE, ArgKind::ConstRaw },
78 { GT_CONST_JUMP_IF_FALSE, ArgKind::ConstRaw },
79 { GT_SYM_JUMP_IF_FALSE, ArgKind::SymRaw },
80 { EQ_CONST_JUMP_IF_TRUE, ArgKind::ConstRaw },
81 { EQ_SYM_INDEX_JUMP_IF_TRUE, ArgKind::SymRaw },
82 { NEQ_CONST_JUMP_IF_TRUE, ArgKind::ConstRaw },
83 { NEQ_SYM_JUMP_IF_FALSE, ArgKind::SymRaw },
84 { CALL_SYMBOL, ArgKind::SymRaw },
85 { CALL_SYMBOL_BY_INDEX, ArgKind::RawRaw },
86 { CALL_CURRENT_PAGE, ArgKind::SymRaw },
87 { GET_FIELD_FROM_SYMBOL, ArgKind::SymSym },
88 { GET_FIELD_FROM_SYMBOL_INDEX, ArgKind::RawSym },
89 { AT_SYM_SYM, ArgKind::SymSym },
90 { AT_SYM_INDEX_SYM_INDEX, ArgKind::RawRaw },
91 { AT_SYM_INDEX_CONST, ArgKind::RawConst },
92 { CHECK_TYPE_OF, ArgKind::SymConst },
93 { CHECK_TYPE_OF_BY_INDEX, ArgKind::RawConst },
94 { APPEND_IN_PLACE_SYM, ArgKind::SymRaw },
95 { APPEND_IN_PLACE_SYM_INDEX, ArgKind::RawRaw },
96 { STORE_LEN, ArgKind::RawSym },
97 { LT_LEN_SYM_JUMP_IF_FALSE, ArgKind::SymRaw },
98 { MUL_BY, ArgKind::RawRaw },
99 { MUL_BY_INDEX, ArgKind::RawRaw },
100 { MUL_SET_VAL, ArgKind::RawRaw },
101 { FUSED_MATH, ArgKind::RawRawRaw }
386 const std::optional<uint16_t> sStart,
387 const std::optional<uint16_t> sEnd,
388 const std::optional<uint16_t> cPage)
const
392 fmt::println(
"Invalid format");
398 auto [major, minor, patch] =
version();
399 fmt::println(
"Version: {}.{}.{}", major, minor, patch);
400 fmt::println(
"Timestamp: {}",
timestamp());
401 fmt::print(
"SHA256: ");
402 for (
const auto sha =
sha256();
unsigned char h : sha)
403 fmt::print(
"{:02x}", h);
409 if ((sStart.has_value() && !sEnd.has_value()) || (!sStart.has_value() && sEnd.has_value()))
411 fmt::print(fmt::fg(fmt::color::red),
"Both start and end parameter need to be provided together\n");
414 if (sStart.has_value() && sEnd.has_value() && sStart.value() >= sEnd.value())
416 fmt::print(fmt::fg(fmt::color::red),
"Invalid slice start and end arguments\n");
421 const auto vals =
values(syms);
424 const auto code_block =
code(inst_locs);
428 std::size_t size = syms.symbols.size();
429 std::size_t sliceSize = size;
432 if (showSym && sStart.has_value() && sEnd.has_value() && (sStart.value() > size || sEnd.value() > size))
433 fmt::print(fmt::fg(fmt::color::red),
"Slice start or end can't be greater than the segment size: {}\n", size);
434 else if (showSym && sStart.has_value() && sEnd.has_value())
435 sliceSize = sEnd.value() - sStart.value() + 1;
438 fmt::println(
"{} (length: {})", fmt::styled(
"Symbols table", fmt::fg(fmt::color::cyan)), sliceSize);
440 for (std::size_t j = 0; j < size; ++j)
442 if (
auto start = sStart;
auto end = sEnd)
443 showSym = showSym && (j >= start.value() && j <= end.value());
446 fmt::println(
"{}) {}", j, syms.symbols[j]);
457 std::size_t size = vals.values.size();
458 std::size_t sliceSize = size;
461 if (showVal && sStart.has_value() && sEnd.has_value() && (sStart.value() > size || sEnd.value() > size))
462 fmt::print(fmt::fg(fmt::color::red),
"Slice start or end can't be greater than the segment size: {}\n", size);
463 else if (showVal && sStart.has_value() && sEnd.has_value())
464 sliceSize = sEnd.value() - sStart.value() + 1;
467 fmt::println(
"{} (length: {})", fmt::styled(
"Constants table", fmt::fg(fmt::color::cyan)), sliceSize);
469 for (std::size_t j = 0; j < size; ++j)
471 if (
auto start = sStart;
auto end = sEnd)
472 showVal = showVal && (j >= start.value() && j <= end.value());
476 switch (
const auto val = vals.values[j]; val.valueType())
479 fmt::println(
"{}) (Number) {}", j, val.number());
482 fmt::println(
"{}) (String) {}", j, val.string());
485 fmt::println(
"{}) (PageAddr) {}", j, val.pageAddr());
488 fmt::print(fmt::fg(fmt::color::red),
"Value type not handled: {}\n",
std::to_string(val.valueType()));
502 std::size_t size = inst_locs.locations.size();
503 std::size_t sliceSize = size;
506 if (showVal && sStart.has_value() && sEnd.has_value() && (sStart.value() > size || sEnd.value() > size))
507 fmt::print(fmt::fg(fmt::color::red),
"Slice start or end can't be greater than the segment size: {}\n", size);
508 else if (showVal && sStart.has_value() && sEnd.has_value())
509 sliceSize = sEnd.value() - sStart.value() + 1;
512 fmt::println(
"{} (length: {})", fmt::styled(
"Instruction locations table", fmt::fg(fmt::color::cyan)), sliceSize);
513 if (showVal && size > 0)
514 fmt::println(
" PP, IP");
516 for (std::size_t j = 0; j < size; ++j)
518 if (
auto start = sStart;
auto end = sEnd)
519 showVal = showVal && (j >= start.value() && j <= end.value());
521 const auto& location = inst_locs.locations[j];
523 fmt::println(
"{:>3},{:>3} -> {}:{}", location.page_pointer, location.inst_pointer, files.filenames[location.filename_id], location.line);
534 for (
const auto& page : code_block.pages)
536 bool displayCode =
true;
538 if (
auto wanted_page = cPage)
539 displayCode = pp == wanted_page.value();
543 "{} {} (length: {})",
544 fmt::styled(
"Code segment", fmt::fg(fmt::color::magenta)),
545 fmt::styled(pp, fmt::fg(fmt::color::magenta)),
555 if (sStart.has_value() && sEnd.has_value() && ((sStart.value() > page.size()) || (sEnd.value() > page.size())))
557 fmt::print(fmt::fg(fmt::color::red),
"Slice start or end can't be greater than the segment size: {}\n", page.size());
561 std::optional<InstLoc> previous_loc = std::nullopt;
563 for (std::size_t j = sStart.value_or(0), end = sEnd.value_or(page.size()); j < end; j += 4)
565 const uint8_t inst = page[j];
566 const uint8_t padding = page[j + 1];
567 const auto arg =
static_cast<uint16_t
>((page[j + 2] << 8) + page[j + 3]);
573 if (maybe_loc && (!previous_loc || maybe_loc != previous_loc))
575 if (!previous_loc || previous_loc->filename_id != maybe_loc->filename_id)
576 fmt::println(
"{}", files.filenames[maybe_loc->filename_id]);
577 fmt::print(
"{:>4}", maybe_loc->line + 1);
578 previous_loc = maybe_loc;
583 fmt::print(fmt::fg(fmt::color::cyan),
"{:>4x}", j / 4);
585 fmt::print(
" {:02x} {:02x} {:02x} {:02x} ", inst, padding, page[j + 2], page[j + 3]);
614 const auto stringify_value = [](
const Value& val) -> std::string {
615 switch (val.valueType())
618 return fmt::format(
"{} (Number)", val.number());
620 return fmt::format(
"{} (String)", val.string());
622 return fmt::format(
"{} (PageAddr)", val.pageAddr());
628 const auto builtin_name = [](
const uint16_t idx) -> std::string {
631 const auto value_str = [&stringify_value, &vals](
const uint16_t idx) -> std::string {
632 if (idx < vals.
values.size())
633 return stringify_value(vals.
values[idx]);
636 const auto symbol_name = [&syms](
const uint16_t idx) -> std::string {
642 if (
const auto inst_idx =
static_cast<std::size_t
>(inst); inst_idx <
InstructionNames.size())
645 std::optional<Arg> arg = std::nullopt;
649 fmt::print(os,
"{}", fmt::styled(name,
withForeColor(fmt::color::gold, colorize)));
652 const auto sym_color =
withForeColor(fmt::color::green, colorize);
653 const auto const_color =
withForeColor(fmt::color::magenta, colorize);
654 const auto raw_color =
withForeColor(fmt::color::red, colorize);
656 switch (
auto [kind, _, idx] = arg.value(); kind)
658 case ArgKind::Symbol:
659 fmt::print(os,
" {}\n", fmt::styled(symbol_name(idx), sym_color));
661 case ArgKind::Constant:
662 fmt::print(os,
" {}\n", fmt::styled(value_str(idx), const_color));
664 case ArgKind::Builtin:
665 fmt::print(os,
" {}\n", builtin_name(idx));
668 fmt::print(os,
" ({})\n", fmt::styled(idx, raw_color));
670 case ArgKind::RawHex:
671 fmt::print(os,
" ({:#x})\n", fmt::styled(idx, raw_color));
673 case ArgKind::ConstConst:
674 fmt::print(os,
" {}, {}\n", fmt::styled(value_str(arg->primary()), const_color), fmt::styled(value_str(arg->secondary()), const_color));
676 case ArgKind::ConstSym:
677 fmt::print(os,
" {}, {}\n", fmt::styled(value_str(arg->primary()), const_color), fmt::styled(symbol_name(arg->secondary()), sym_color));
679 case ArgKind::SymConst:
680 fmt::print(os,
" {}, {}\n", fmt::styled(symbol_name(arg->primary()), sym_color), fmt::styled(value_str(arg->secondary()), const_color));
682 case ArgKind::SymSym:
683 fmt::print(os,
" {}, {}\n", fmt::styled(symbol_name(arg->primary()), sym_color), fmt::styled(symbol_name(arg->secondary()), sym_color));
685 case ArgKind::BuiltinRaw:
686 fmt::print(os,
" {}, {}\n", builtin_name(arg->primary()), fmt::styled(arg->secondary(), raw_color));
688 case ArgKind::ConstRaw:
689 fmt::print(os,
" {}, {}\n", fmt::styled(value_str(arg->primary()), const_color), fmt::styled(arg->secondary(), raw_color));
691 case ArgKind::SymRaw:
692 fmt::print(os,
" {}, {}\n", fmt::styled(symbol_name(arg->primary()), sym_color), fmt::styled(arg->secondary(), raw_color));
694 case ArgKind::RawSym:
695 fmt::print(os,
" {}, {}\n", fmt::styled(arg->primary(), raw_color), fmt::styled(symbol_name(arg->secondary()), sym_color));
697 case ArgKind::RawConst:
698 fmt::print(os,
" {}, {}\n", fmt::styled(arg->primary(), raw_color), fmt::styled(value_str(arg->secondary()), const_color));
700 case ArgKind::RawRaw:
701 fmt::print(os,
" {}, {}\n", fmt::styled(arg->primary(), raw_color), fmt::styled(arg->secondary(), raw_color));
703 case ArgKind::RawRawRaw:
704 fmt::print(os,
" {}, {}, {}\n", fmt::styled(arg->padding, raw_color), fmt::styled((arg->arg & 0xff00) >> 8, raw_color), fmt::styled(arg->arg & 0x00ff, raw_color));
709 fmt::print(os,
"\n");
712 fmt::println(os,
"Unknown instruction");