parser: allow implicit hex literals
This commit is contained in:
parent
8054ac43ac
commit
b60dbed70b
2
main.cc
2
main.cc
@ -130,7 +130,7 @@ int main(int argc, char * argv[])
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
serialize_program(program, symbol_table, 0x8000, out);
|
serialize_program(program, symbol_table, 0x8200, out);
|
||||||
|
|
||||||
out.close();
|
out.close();
|
||||||
return 0;
|
return 0;
|
||||||
|
59
parser.cc
59
parser.cc
@ -104,7 +104,7 @@ bool parse(std::string_view buf, assembler::program_t& program)
|
|||||||
if (s.back() == ':') {
|
if (s.back() == ':') {
|
||||||
std::string_view key = s.substr(0, s.length() - 1);
|
std::string_view key = s.substr(0, s.length() - 1);
|
||||||
auto symbol = get_symbol(key);
|
auto symbol = get_symbol(key);
|
||||||
std::cout << "label `" << symbol << "`\n";
|
std::cerr << "label `" << symbol << "`\n";
|
||||||
current_instruction.symbol = symbol;
|
current_instruction.symbol = symbol;
|
||||||
state = parser::state::op;
|
state = parser::state::op;
|
||||||
return true;
|
return true;
|
||||||
@ -124,11 +124,11 @@ bool parse(std::string_view buf, assembler::program_t& program)
|
|||||||
assert(row == current_row);
|
assert(row == current_row);
|
||||||
auto op_it = fromstring::op().find(s);
|
auto op_it = fromstring::op().find(s);
|
||||||
if (op_it == fromstring::op().end()) {
|
if (op_it == fromstring::op().end()) {
|
||||||
std::cout << "invalid op `" << s << "`\n";
|
std::cerr << "invalid op `" << s << "`\n";
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
current_instruction.op = op_it->second;
|
current_instruction.op = op_it->second;
|
||||||
std::cout << "ok op `" << static_cast<int>(op_it->second) << "`\n";
|
std::cerr << "ok op `" << static_cast<int>(op_it->second) << "`\n";
|
||||||
}
|
}
|
||||||
state = parser::state::mode;
|
state = parser::state::mode;
|
||||||
return true;
|
return true;
|
||||||
@ -138,11 +138,11 @@ bool parse(std::string_view buf, assembler::program_t& program)
|
|||||||
assert(row == current_row);
|
assert(row == current_row);
|
||||||
auto mode_it = fromstring::mode().find(s);
|
auto mode_it = fromstring::mode().find(s);
|
||||||
if (mode_it == fromstring::mode().end()) {
|
if (mode_it == fromstring::mode().end()) {
|
||||||
std::cout << "invalid mode `" << s << "`\n";
|
std::cerr << "invalid mode `" << s << "`\n";
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
current_instruction.mode = mode_it->second;
|
current_instruction.mode = mode_it->second;
|
||||||
std::cout << "ok mode `" << static_cast<int>(mode_it->second) << "`\n";
|
std::cerr << "ok mode `" << static_cast<int>(mode_it->second) << "`\n";
|
||||||
}
|
}
|
||||||
state = parser::state::value;
|
state = parser::state::value;
|
||||||
return true;
|
return true;
|
||||||
@ -152,7 +152,7 @@ bool parse(std::string_view buf, assembler::program_t& program)
|
|||||||
auto am_it = addressing_mode().find(current_instruction.mode);
|
auto am_it = addressing_mode().find(current_instruction.mode);
|
||||||
assert(am_it != addressing_mode().end());
|
assert(am_it != addressing_mode().end());
|
||||||
if (am_it->second.len == 0) {
|
if (am_it->second.len == 0) {
|
||||||
std::cout << "no value expected\n";
|
std::cerr << "no value expected\n";
|
||||||
assembler::implied_t i {};
|
assembler::implied_t i {};
|
||||||
current_instruction.value = i;
|
current_instruction.value = i;
|
||||||
state = parser::state::comment;
|
state = parser::state::comment;
|
||||||
@ -162,7 +162,7 @@ bool parse(std::string_view buf, assembler::program_t& program)
|
|||||||
assert(row == current_row);
|
assert(row == current_row);
|
||||||
|
|
||||||
auto parse_integer = [](std::string_view s, int base) -> std::optional<ssize_t> {
|
auto parse_integer = [](std::string_view s, int base) -> std::optional<ssize_t> {
|
||||||
std::string value_str {s.data() + 1, s.size() - 1};
|
std::string value_str {s.data(), s.length()};
|
||||||
size_t pos;
|
size_t pos;
|
||||||
ssize_t value;
|
ssize_t value;
|
||||||
value = std::stoll(value_str, &pos, base);
|
value = std::stoll(value_str, &pos, base);
|
||||||
@ -175,25 +175,50 @@ bool parse(std::string_view buf, assembler::program_t& program)
|
|||||||
std::optional<ssize_t> literal;
|
std::optional<ssize_t> literal;
|
||||||
auto as_literal = [](ssize_t n) -> assembler::literal_t { return {n}; };
|
auto as_literal = [](ssize_t n) -> assembler::literal_t { return {n}; };
|
||||||
switch (*s.cbegin()) {
|
switch (*s.cbegin()) {
|
||||||
case 'h':
|
case '0':
|
||||||
|
case '1':
|
||||||
|
case '2':
|
||||||
|
case '3':
|
||||||
|
case '4':
|
||||||
|
case '5':
|
||||||
|
case '6':
|
||||||
|
case '7':
|
||||||
|
case '8':
|
||||||
|
case '9':
|
||||||
|
case 'A':
|
||||||
|
case 'B':
|
||||||
|
case 'C':
|
||||||
|
case 'D':
|
||||||
|
case 'E':
|
||||||
|
case 'F':
|
||||||
{
|
{
|
||||||
literal = parse_integer(s, 16);
|
literal = parse_integer(s, 16);
|
||||||
if (literal == std::nullopt) {
|
if (literal == std::nullopt) {
|
||||||
std::cout << "invalid hex literal\n";
|
std::cerr << row << ": invalid hex literal\n";
|
||||||
}
|
}
|
||||||
current_instruction.value = as_literal(*literal);
|
current_instruction.value = as_literal(*literal);
|
||||||
std::cout << "value hex literal `" << *literal << "`\n";
|
std::cerr << "value hex literal `" << *literal << "`\n";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'h':
|
||||||
|
{
|
||||||
|
literal = parse_integer(s.substr(1, s.length() - 1), 16);
|
||||||
|
if (literal == std::nullopt) {
|
||||||
|
std::cerr << row << ": invalid hex literal\n";
|
||||||
|
}
|
||||||
|
current_instruction.value = as_literal(*literal);
|
||||||
|
std::cerr << "value hex literal `" << *literal << "`\n";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'd':
|
case 'd':
|
||||||
{
|
{
|
||||||
literal = parse_integer(s, 10);
|
literal = parse_integer(s.substr(1, s.length() - 1), 10);
|
||||||
if (literal == std::nullopt) {
|
if (literal == std::nullopt) {
|
||||||
std::cout << "invalid dec literal\n";
|
std::cerr << row << ": invalid dec literal\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
current_instruction.value = as_literal(*literal);
|
current_instruction.value = as_literal(*literal);
|
||||||
std::cout << "value dec literal `" << *literal << "`\n";
|
std::cerr << "value dec literal `" << *literal << "`\n";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ':':
|
case ':':
|
||||||
@ -201,11 +226,11 @@ bool parse(std::string_view buf, assembler::program_t& program)
|
|||||||
std::string_view key = s.substr(1, s.length() - 1);
|
std::string_view key = s.substr(1, s.length() - 1);
|
||||||
assembler::reference_t reference = { get_symbol(key) };
|
assembler::reference_t reference = { get_symbol(key) };
|
||||||
current_instruction.value = reference;
|
current_instruction.value = reference;
|
||||||
std::cout << "value reference `" << reference.symbol << "`\n";
|
std::cerr << "value reference `" << reference.symbol << "`\n";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
std::cout << "invalid base\n";
|
std::cerr << row << ": invalid base\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,7 +253,7 @@ bool parse(std::string_view buf, assembler::program_t& program)
|
|||||||
} else if (inside_comment) {
|
} else if (inside_comment) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
std::cout << "expected comment\n";
|
std::cerr << row << ": expected comment\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -246,7 +271,7 @@ bool parse(std::string_view buf, assembler::program_t& program)
|
|||||||
} else if (inside_comment) {
|
} else if (inside_comment) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
std::cout << "expected comment\n";
|
std::cerr << "expected comment\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user