1 #include "parse-asm.h"
2
3 #include <charconv>
4
5 namespace mcasm {
6
7 std::map<std::string, dword> registers = {
8 {"$au", 0},
9 {"$lu", 1},
10 {"$addr", 12},
11 {"$iptr", 14},
12 {"$data", 15},
13 {"r0", 0},
14 {"r1", 1},
15 {"r2", 2},
16 {"r3", 3},
17 {"r4", 4},
18 {"r5", 5},
19 {"r6", 6},
20 {"r7", 7},
21 {"r8", 8},
22 {"r9", 9},
23 {"r10", 10},
24 {"r11", 11},
25 {"r12", 12},
26 {"r13", 13},
27 {"r14", 14},
28 {"r15", 15},
29 {"ra", 10},
30 {"rb", 11},
31 {"rc", 12},
32 {"rd", 13},
33 {"re", 14},
34 {"rf", 15},
35 };
36
37
38 std::map<std::string, ParseFn> instructionParsers = {
39 {"hcf", &Parser::parseSimple<IHcf>},
40 {"nop", &Parser::parseSimple<INop>},
41 {"inc", &Parser::parseSimple<IInc>},
42
43 {"mov", &Parser::parseMov<false>},
44 {"mvi", &Parser::parseMov<true>},
45
46 {"tlt", &Parser::parseCond<0b01, false>},
47 {"tli", &Parser::parseCond<0b01, true>},
48 {"teq", &Parser::parseCond<0b11, false>},
49 {"tei", &Parser::parseCond<0b11, true>},
50 {"tez", &Parser::parseCond<0b10, false>},
51
52 {"sbi", &Parser::parseOp<Register::eAU, 0b111, true>},
53 {"sub", &Parser::parseOp<Register::eAU, 0b111, false>},
54 {"adi", &Parser::parseOp<Register::eAU, 0b100, true>},
55 {"add", &Parser::parseOp<Register::eAU, 0b100, false>},
56
57 {"ori", &Parser::parseOp<Register::eLU, 0b001, true>},
58 {"orr", &Parser::parseOp<Register::eLU, 0b001, false>},
59 {"ndi", &Parser::parseOp<Register::eLU, 0b000, true>},
60 {"and", &Parser::parseOp<Register::eLU, 0b000, false>},
61 {"shl", &Parser::parseSimpleOp<Register::eLU, 0b011>},
62 {"shr", &Parser::parseSimpleOp<Register::eLU, 0b100>},
63
64 {"jmp", &Parser::parseJump},
65 };
66
67 dword tokenToNumber(Token& t) {
68 std::string_view s = t.lexeme;
69 int base = 10;
70 if(t.lexeme[0] == '0') {
71 if(t.lexeme[1] == 'x') {
72 s = s.substr(2);
73 base = 16;
74 }
75 else if(t.lexeme[1] == 'b') {
76 s = s.substr(2);
77 base = 2;
78 }
79 }
80
81
82 dword result;
83 auto res = std::from_chars(s.begin(), s.end(), result, base);
84
85 if(res.ec == std::errc::result_out_of_range)
86 throw ParseError{fmt::format("Number '{}' is out of range.\n", t.lexeme), t};
87 if(res.ec != std::errc{})
88 throw ParseError{fmt::format("Token '{}' is not a valid number.\n", t.lexeme), t};
89
90 return result;
91 }
92
93 }