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   // maybe add 0b support
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 }