shell: provide parser with expr_or_range() function

This commit is contained in:
Lephenixnoir 2022-12-08 22:51:34 +01:00
parent a277a4ffad
commit fb639962a5
Signed by: Lephenixnoir
GPG Key ID: 1BBA026E13FC0495
3 changed files with 36 additions and 22 deletions

View File

@ -75,8 +75,17 @@ static uint32_t parse_d(Session &session, Parser &parser)
return 0;
uint32_t address = session.current_space->cursor;
if(!parser.at_end())
address = parser.expr(session.current_space);
if(!parser.at_end()) {
auto v = parser.expr_or_range(session.current_space);
if(std::holds_alternative<long>(v)) {
address = std::get<long>(v);
}
else {
// TODO: Use an args struct etc. This is placeholder.
address = std::get<Range>(v).start;
}
}
parser.end();
return address;

View File

@ -142,24 +142,7 @@ void Parser::dump_command()
{
while(!at_end()) {
Token t = m_la;
if(t.type == T::NUM)
fmt::print("NUM {:#x}\n", t.value.NUM);
else if(t.type == T::SYSCALL)
fmt::print("SYSCALL %{:04x}\n", t.value.NUM);
else if(t.type == T::SYMBOL)
fmt::print("SYMBOL '{}'\n", t.value.STRING);
else if(t.type == T::OPTION)
fmt::print("OPTION '{}'\n", t.value.STRING);
else if(t.type == T::STRING)
fmt::print("STRING '{}'\n", t.value.STRING);
else if(t.type == '>')
fmt::print(">>\n");
else if(t.type == '<')
fmt::print("<<\n");
else
fmt::print("{}\n", (char)t.type);
fmt::print("{}\n", t.str());
feed();
}
}
@ -246,7 +229,7 @@ Range Parser::range(VirtualSpace *space, long before, long after)
{
long start = expr(space);
/* Accept non-rangs if (before) and (after) are provided */
/* Accept non-ranges if (before) and (after) are provided */
if(m_la.type != ':' && m_la.type != '.' && before >= 0 && after >= 0)
return {start - before, start + after};
@ -259,6 +242,25 @@ Range Parser::range(VirtualSpace *space, long before, long after)
return r;
}
std::variant<long, Range> Parser::expr_or_range(VirtualSpace *space)
{
long start = expr(space);
if(m_la.type == ':') {
expect(':');
long length = expr(space);
return (Range){start, start + length};
}
else if(m_la.type == '.') {
expect('.');
long end = expr(space);
return (Range){start, end};
}
else {
return (long)start;
}
}
FxOS::MemoryRegion Parser::region(VirtualSpace *space, long before, long after)
{
if(m_la.type == '$' || m_la.type == '(' || m_la.type == '-'

View File

@ -12,6 +12,7 @@
#include <vector>
#include <map>
#include <functional>
#include <variant>
#include <fxos/memory.h>
#include <fxos/vspace.h>
@ -144,8 +145,10 @@ public:
long expr(VirtualSpace *space);
/* Read a range; again $ and symbols are interpreted. If (before) and
(after) are both specified, a single value will also be accepted, and
the range [value+before, value.after) will be returned. */
the range [value-before, value+after) will be returned. */
Range range(VirtualSpace *space, long before=-1, long after=-1);
/* Read an expression or a range */
std::variant<long, Range> expr_or_range(VirtualSpace *space);
/* Read a memory region (allows both ranges and symbolic names) */
FxOS::MemoryRegion region(VirtualSpace *space, long before=-1,
long after=-1);