#include "shell.h" #include "parser.h" #include "commands.h" #include #include //--- // e //--- static std::vector parse_e(Session &session, Parser &parser) { std::vector values; while(!parser.at_end()) { values.push_back(parser.expr(session.current_space)); } parser.end(); return values; } void _e(Session &session, std::vector const &values) { for(long value: values) { /* Hexa format */ int length = (labs(value) <= (1ll << 32) ? 8 : 16) + 2 + (value < 0); std::string format = fmt::format("{{:#0{}x}}", length); fmt::print(format, value); long a = abs(value); if(a <= 100 || a % 100 <= 1 || a % 100 >= 99) fmt::print(" = {}", a); VirtualSpace *space = session.current_space; if(space) { std::optional opt; /* Promote to syscall ID */ OS *os = space->os_analysis(); int syscall_id; if(os && (syscall_id = os->find_syscall(value)) != -1) { fmt::print(" = %{:03x}", syscall_id); opt = space->symbols.query(Symbol::Syscall, syscall_id); if(opt) fmt::print(" = {}", *opt); } opt = space->symbols.query(Symbol::Address, value); if(opt) fmt::print(" = {}", *opt); } fmt::print("\n"); } } //--- // ev //--- struct _ev_args { std::string space_name; std::vector values; }; static _ev_args parse_ev(Session &session, Parser &parser) { _ev_args args {}; args.space_name = parser.symbol("vspace_name"); VirtualSpace *space = session.get_space(args.space_name); if(space) { while(!parser.at_end()) { args.values.push_back(parser.expr(space)); } } // TODO: Error message when session specified in _ev does not exist parser.end(); return args; } void _ev(Session &, std::string, std::vector const &values) { for(long value: values) { /* Hexa format */ int length = (labs(value) <= (1ll << 32) ? 8 : 16) + 2 + (value < 0); std::string format = fmt::format("{{:#0{}x}}", length); fmt::print(format, value); long a = abs(value); if(a <= 100 || a % 100 <= 1 || a % 100 >= 99) fmt::print(" = {}", a); fmt::print("\n"); } } static ShellCommand _e_cmd( "e", [](Session &s, Parser &p) { _e(s, parse_e(s, p)); }, [](Session &s, Parser &p) { parse_e(s, p); }, "Evaluate expression", R"( e [...] Evaluates the specified expressions. The expressions may include syscall references (%0ab), named symbols (TRA), the current cursor ($), and arithmetic expressions. The parser doesn't accept arithmetic expressions directly on the command-line; they must be placed within parentheses. The resulting values undergo a simple analysis which recovers symbol names and syscall addresses. e TRA ($+2) Evaluate the address of the TRA register, and the address of the next instruction. )"); static ShellCommand _ev_cmd( "ev", [](Session &s, Parser &p) { auto const &args = parse_ev(s, p); _ev(s, args.space_name, args.values); }, [](Session &s, Parser &p) { parse_ev(s, p); }, "Evaluate expression in Virtual space", R"( ev [...] Same as e, but resolves symbols within the named virtual space rather than the current one. See e? for more information. )");