diff --git a/Makefile b/Makefile index 5939e7d..8aafc0b 100644 --- a/Makefile +++ b/Makefile @@ -7,6 +7,7 @@ CXX = $(TARGET)clang++ SRC = main.cpp SRC += lexer.cpp SRC += ast.cpp +SRC += parser.cpp OBJ = $(patsubst %.cpp,%.o,$(SRC)) DEP = $(patsubst %.cpp,%.d,$(SRC)) diff --git a/ast.cpp b/ast.cpp index 6d8cf8b..8dbfc4f 100644 --- a/ast.cpp +++ b/ast.cpp @@ -4,7 +4,7 @@ namespace dsp { void ast_printer_t::visit(const unary_t * unary) const { - parenthesize((unary->oper).lexeme, unary->expr); + parenthesize((unary->oper).lexeme, unary->right); } void ast_printer_t::visit(const binary_t * binary) const diff --git a/build_radix_tree.py b/build_radix_tree.py index 089e4e8..e1c4648 100644 --- a/build_radix_tree.py +++ b/build_radix_tree.py @@ -1,3 +1,5 @@ +import sys + def build_radix_tree(ops: list[str]) -> dict: root = dict() for op in ops: @@ -62,38 +64,123 @@ def print_keyword_func(root): p() p("}") -from pprint import pprint -d = build_radix_tree([ - "alh", - "all", - "alu", - "m0", "m1", "m2", "m3", - "mc0", "mc1", "mc2", "mc3", - "mul", - "nop", - "and", - "or", - "xor", - "add", - "sub", + +alu_keywords = [ "ad2", - "sr", - "rr", - "sl", + "add", + "and", + "nop", + "or", "rl", "rl8", + "rr", + "sl", + "sr", + "sub", + "xor", +] + +x_bus_keywords = [ + "mov", # Mn, MCn + "x", + "p", + "mul", +] + +mn = ["m0", "m1", "m2", "m3"] +mcn = ["mc0", "mc1", "mc2", "mc3"] + +y_bus_keywords = [ + "mov", # Mn, MCn "clr", - "mov", + "y", + "a", + "alu", +] + +d1_bus_keywords = [ + "mov", # MCn + "alh", + "all", +] + +reg_keywords = [ + "rx", + "pl", + "ra0", + "wa0", + "lop", + "top", +] + +cond_keywords = [ + "z", + "nz", + "s", + "ns", + "c", + "nc", + "t0", + "nt0", + "zs", + "nzs", +] + +move_immediate_keywords = [ "mvi", +] + +dma_keywords = [ "dma", "dmah", + "d0", + "prg", +] + +jmp_keywords = [ "jmp", +] + +loop_keywords = [ "btm", "lps", +] + +halt_keywords = [ "end", "endi", +] + +directive_keywords = [ "equ", "org", - "ends", -]) -print_keyword_func(d) +] + +keywords = sorted(set([ + *alu_keywords, + *x_bus_keywords, + *mn, + *mcn, + *y_bus_keywords, + *d1_bus_keywords, + *reg_keywords, + *cond_keywords, + *move_immediate_keywords, + *dma_keywords, + *jmp_keywords, + *loop_keywords, + *halt_keywords, + *directive_keywords, +])) + +if sys.argv[1] == 'hpp': + d = build_radix_tree(keywords) + print_keyword_func(d) +elif sys.argv[1] == 'enum_inc': + for k in keywords: + print(f"_{k},") +elif sys.argv[1] == 'case_inc': + for k in keywords: + print(f'case _{k.ljust(4, " ")} : return os << "{k.upper()}";') +else: + assert False, sys.argv diff --git a/expr.hpp b/expr.hpp index d425858..0d8318d 100644 --- a/expr.hpp +++ b/expr.hpp @@ -1,3 +1,5 @@ +#pragma once + #include #include "token.hpp" diff --git a/keyword.case_inc b/keyword.case_inc new file mode 100644 index 0000000..d9d9b71 --- /dev/null +++ b/keyword.case_inc @@ -0,0 +1,58 @@ +case _a : return os << "A"; +case _ad2 : return os << "AD2"; +case _add : return os << "ADD"; +case _alh : return os << "ALH"; +case _all : return os << "ALL"; +case _alu : return os << "ALU"; +case _and : return os << "AND"; +case _btm : return os << "BTM"; +case _c : return os << "C"; +case _clr : return os << "CLR"; +case _d0 : return os << "D0"; +case _dma : return os << "DMA"; +case _dmah : return os << "DMAH"; +case _end : return os << "END"; +case _endi : return os << "ENDI"; +case _equ : return os << "EQU"; +case _jmp : return os << "JMP"; +case _lop : return os << "LOP"; +case _lps : return os << "LPS"; +case _m0 : return os << "M0"; +case _m1 : return os << "M1"; +case _m2 : return os << "M2"; +case _m3 : return os << "M3"; +case _mc0 : return os << "MC0"; +case _mc1 : return os << "MC1"; +case _mc2 : return os << "MC2"; +case _mc3 : return os << "MC3"; +case _mov : return os << "MOV"; +case _mul : return os << "MUL"; +case _mvi : return os << "MVI"; +case _nc : return os << "NC"; +case _nop : return os << "NOP"; +case _ns : return os << "NS"; +case _nt0 : return os << "NT0"; +case _nz : return os << "NZ"; +case _nzs : return os << "NZS"; +case _or : return os << "OR"; +case _org : return os << "ORG"; +case _p : return os << "P"; +case _pl : return os << "PL"; +case _prg : return os << "PRG"; +case _ra0 : return os << "RA0"; +case _rl : return os << "RL"; +case _rl8 : return os << "RL8"; +case _rr : return os << "RR"; +case _rx : return os << "RX"; +case _s : return os << "S"; +case _sl : return os << "SL"; +case _sr : return os << "SR"; +case _sub : return os << "SUB"; +case _t0 : return os << "T0"; +case _top : return os << "TOP"; +case _wa0 : return os << "WA0"; +case _x : return os << "X"; +case _xor : return os << "XOR"; +case _y : return os << "Y"; +case _z : return os << "Z"; +case _zs : return os << "ZS"; diff --git a/keyword.enum_inc b/keyword.enum_inc new file mode 100644 index 0000000..cba7772 --- /dev/null +++ b/keyword.enum_inc @@ -0,0 +1,58 @@ +_a, +_ad2, +_add, +_alh, +_all, +_alu, +_and, +_btm, +_c, +_clr, +_d0, +_dma, +_dmah, +_end, +_endi, +_equ, +_jmp, +_lop, +_lps, +_m0, +_m1, +_m2, +_m3, +_mc0, +_mc1, +_mc2, +_mc3, +_mov, +_mul, +_mvi, +_nc, +_nop, +_ns, +_nt0, +_nz, +_nzs, +_or, +_org, +_p, +_pl, +_prg, +_ra0, +_rl, +_rl8, +_rr, +_rx, +_s, +_sl, +_sr, +_sub, +_t0, +_top, +_wa0, +_x, +_xor, +_y, +_z, +_zs, diff --git a/keyword.hpp b/keyword.hpp index 0d057e5..726668b 100644 --- a/keyword.hpp +++ b/keyword.hpp @@ -15,8 +15,23 @@ find(const std::string_view s) switch (s[ix++]) { case 'A': [[fallthrough]]; case 'a': - if (ix < s.length()) { + if (ix == s.length()) return { token_t::type_t::_a }; + else { switch (s[ix++]) { + case 'D': [[fallthrough]]; + case 'd': + if (ix < s.length()) { + switch (s[ix++]) { + case '2': + if (ix == s.length()) return { token_t::type_t::_ad2 }; + break; + case 'D': [[fallthrough]]; + case 'd': + if (ix == s.length()) return { token_t::type_t::_add }; + break; + } + } + break; case 'L': [[fallthrough]]; case 'l': if (ix < s.length()) { @@ -47,16 +62,152 @@ find(const std::string_view s) } } break; - case 'D': [[fallthrough]]; - case 'd': + } + } + break; + case 'B': [[fallthrough]]; + case 'b': + if (ix < s.length()) { + switch (s[ix++]) { + case 'T': [[fallthrough]]; + case 't': + if (ix < s.length()) { + switch (s[ix++]) { + case 'M': [[fallthrough]]; + case 'm': + if (ix == s.length()) return { token_t::type_t::_btm }; + break; + } + } + break; + } + } + break; + case 'C': [[fallthrough]]; + case 'c': + if (ix == s.length()) return { token_t::type_t::_c }; + else { + switch (s[ix++]) { + case 'L': [[fallthrough]]; + case 'l': + if (ix < s.length()) { + switch (s[ix++]) { + case 'R': [[fallthrough]]; + case 'r': + if (ix == s.length()) return { token_t::type_t::_clr }; + break; + } + } + break; + } + } + break; + case 'D': [[fallthrough]]; + case 'd': + if (ix < s.length()) { + switch (s[ix++]) { + case '0': + if (ix == s.length()) return { token_t::type_t::_d0 }; + break; + case 'M': [[fallthrough]]; + case 'm': + if (ix < s.length()) { + switch (s[ix++]) { + case 'A': [[fallthrough]]; + case 'a': + if (ix == s.length()) return { token_t::type_t::_dma }; + else { + switch (s[ix++]) { + case 'H': [[fallthrough]]; + case 'h': + if (ix == s.length()) return { token_t::type_t::_dmah }; + break; + } + } + break; + } + } + break; + } + } + break; + case 'E': [[fallthrough]]; + case 'e': + if (ix < s.length()) { + switch (s[ix++]) { + case 'N': [[fallthrough]]; + case 'n': if (ix < s.length()) { switch (s[ix++]) { case 'D': [[fallthrough]]; case 'd': - if (ix == s.length()) return { token_t::type_t::_add }; + if (ix == s.length()) return { token_t::type_t::_end }; + else { + switch (s[ix++]) { + case 'I': [[fallthrough]]; + case 'i': + if (ix == s.length()) return { token_t::type_t::_endi }; + break; + } + } break; - case '2': - if (ix == s.length()) return { token_t::type_t::_ad2 }; + } + } + break; + case 'Q': [[fallthrough]]; + case 'q': + if (ix < s.length()) { + switch (s[ix++]) { + case 'U': [[fallthrough]]; + case 'u': + if (ix == s.length()) return { token_t::type_t::_equ }; + break; + } + } + break; + } + } + break; + case 'J': [[fallthrough]]; + case 'j': + if (ix < s.length()) { + switch (s[ix++]) { + case 'M': [[fallthrough]]; + case 'm': + if (ix < s.length()) { + switch (s[ix++]) { + case 'P': [[fallthrough]]; + case 'p': + if (ix == s.length()) return { token_t::type_t::_jmp }; + break; + } + } + break; + } + } + break; + case 'L': [[fallthrough]]; + case 'l': + if (ix < s.length()) { + switch (s[ix++]) { + case 'O': [[fallthrough]]; + case 'o': + if (ix < s.length()) { + switch (s[ix++]) { + case 'P': [[fallthrough]]; + case 'p': + if (ix == s.length()) return { token_t::type_t::_lop }; + break; + } + } + break; + case 'P': [[fallthrough]]; + case 'p': + if (ix < s.length()) { + switch (s[ix++]) { + case 'S': [[fallthrough]]; + case 's': + if (ix == s.length()) return { token_t::type_t::_lps }; break; } } @@ -99,17 +250,6 @@ find(const std::string_view s) } } break; - case 'U': [[fallthrough]]; - case 'u': - if (ix < s.length()) { - switch (s[ix++]) { - case 'L': [[fallthrough]]; - case 'l': - if (ix == s.length()) return { token_t::type_t::_mul }; - break; - } - } - break; case 'O': [[fallthrough]]; case 'o': if (ix < s.length()) { @@ -121,6 +261,17 @@ find(const std::string_view s) } } break; + case 'U': [[fallthrough]]; + case 'u': + if (ix < s.length()) { + switch (s[ix++]) { + case 'L': [[fallthrough]]; + case 'l': + if (ix == s.length()) return { token_t::type_t::_mul }; + break; + } + } + break; case 'V': [[fallthrough]]; case 'v': if (ix < s.length()) { @@ -139,6 +290,10 @@ find(const std::string_view s) case 'n': if (ix < s.length()) { switch (s[ix++]) { + case 'C': [[fallthrough]]; + case 'c': + if (ix == s.length()) return { token_t::type_t::_nc }; + break; case 'O': [[fallthrough]]; case 'o': if (ix < s.length()) { @@ -150,6 +305,32 @@ find(const std::string_view s) } } break; + case 'S': [[fallthrough]]; + case 's': + if (ix == s.length()) return { token_t::type_t::_ns }; + break; + case 'T': [[fallthrough]]; + case 't': + if (ix < s.length()) { + switch (s[ix++]) { + case '0': + if (ix == s.length()) return { token_t::type_t::_nt0 }; + break; + } + } + break; + case 'Z': [[fallthrough]]; + case 'z': + if (ix == s.length()) return { token_t::type_t::_nz }; + else { + switch (s[ix++]) { + case 'S': [[fallthrough]]; + case 's': + if (ix == s.length()) return { token_t::type_t::_nzs }; + break; + } + } + break; } } break; @@ -172,9 +353,134 @@ find(const std::string_view s) } } break; + case 'P': [[fallthrough]]; + case 'p': + if (ix == s.length()) return { token_t::type_t::_p }; + else { + switch (s[ix++]) { + case 'L': [[fallthrough]]; + case 'l': + if (ix == s.length()) return { token_t::type_t::_pl }; + break; + case 'R': [[fallthrough]]; + case 'r': + if (ix < s.length()) { + switch (s[ix++]) { + case 'G': [[fallthrough]]; + case 'g': + if (ix == s.length()) return { token_t::type_t::_prg }; + break; + } + } + break; + } + } + break; + case 'R': [[fallthrough]]; + case 'r': + if (ix < s.length()) { + switch (s[ix++]) { + case 'A': [[fallthrough]]; + case 'a': + if (ix < s.length()) { + switch (s[ix++]) { + case '0': + if (ix == s.length()) return { token_t::type_t::_ra0 }; + break; + } + } + break; + case 'L': [[fallthrough]]; + case 'l': + if (ix == s.length()) return { token_t::type_t::_rl }; + else { + switch (s[ix++]) { + case '8': + if (ix == s.length()) return { token_t::type_t::_rl8 }; + break; + } + } + break; + case 'R': [[fallthrough]]; + case 'r': + if (ix == s.length()) return { token_t::type_t::_rr }; + break; + case 'X': [[fallthrough]]; + case 'x': + if (ix == s.length()) return { token_t::type_t::_rx }; + break; + } + } + break; + case 'S': [[fallthrough]]; + case 's': + if (ix == s.length()) return { token_t::type_t::_s }; + else { + switch (s[ix++]) { + case 'L': [[fallthrough]]; + case 'l': + if (ix == s.length()) return { token_t::type_t::_sl }; + break; + case 'R': [[fallthrough]]; + case 'r': + if (ix == s.length()) return { token_t::type_t::_sr }; + break; + case 'U': [[fallthrough]]; + case 'u': + if (ix < s.length()) { + switch (s[ix++]) { + case 'B': [[fallthrough]]; + case 'b': + if (ix == s.length()) return { token_t::type_t::_sub }; + break; + } + } + break; + } + } + break; + case 'T': [[fallthrough]]; + case 't': + if (ix < s.length()) { + switch (s[ix++]) { + case '0': + if (ix == s.length()) return { token_t::type_t::_t0 }; + break; + case 'O': [[fallthrough]]; + case 'o': + if (ix < s.length()) { + switch (s[ix++]) { + case 'P': [[fallthrough]]; + case 'p': + if (ix == s.length()) return { token_t::type_t::_top }; + break; + } + } + break; + } + } + break; + case 'W': [[fallthrough]]; + case 'w': + if (ix < s.length()) { + switch (s[ix++]) { + case 'A': [[fallthrough]]; + case 'a': + if (ix < s.length()) { + switch (s[ix++]) { + case '0': + if (ix == s.length()) return { token_t::type_t::_wa0 }; + break; + } + } + break; + } + } + break; case 'X': [[fallthrough]]; case 'x': - if (ix < s.length()) { + if (ix == s.length()) return { token_t::type_t::_x }; + else { switch (s[ix++]) { case 'O': [[fallthrough]]; case 'o': @@ -190,189 +496,18 @@ find(const std::string_view s) } } break; - case 'S': [[fallthrough]]; - case 's': - if (ix < s.length()) { - switch (s[ix++]) { - case 'U': [[fallthrough]]; - case 'u': - if (ix < s.length()) { - switch (s[ix++]) { - case 'B': [[fallthrough]]; - case 'b': - if (ix == s.length()) return { token_t::type_t::_sub }; - break; - } - } - break; - case 'R': [[fallthrough]]; - case 'r': - if (ix == s.length()) return { token_t::type_t::_sr }; - break; - case 'L': [[fallthrough]]; - case 'l': - if (ix == s.length()) return { token_t::type_t::_sl }; - break; - } - } + case 'Y': [[fallthrough]]; + case 'y': + if (ix == s.length()) return { token_t::type_t::_y }; break; - case 'R': [[fallthrough]]; - case 'r': - if (ix < s.length()) { + case 'Z': [[fallthrough]]; + case 'z': + if (ix == s.length()) return { token_t::type_t::_z }; + else { switch (s[ix++]) { - case 'R': [[fallthrough]]; - case 'r': - if (ix == s.length()) return { token_t::type_t::_rr }; - break; - case 'L': [[fallthrough]]; - case 'l': - if (ix == s.length()) return { token_t::type_t::_rl }; - else { - switch (s[ix++]) { - case '8': - if (ix == s.length()) return { token_t::type_t::_rl8 }; - break; - } - } - break; - } - } - break; - case 'C': [[fallthrough]]; - case 'c': - if (ix < s.length()) { - switch (s[ix++]) { - case 'L': [[fallthrough]]; - case 'l': - if (ix < s.length()) { - switch (s[ix++]) { - case 'R': [[fallthrough]]; - case 'r': - if (ix == s.length()) return { token_t::type_t::_clr }; - break; - } - } - break; - } - } - break; - case 'D': [[fallthrough]]; - case 'd': - if (ix < s.length()) { - switch (s[ix++]) { - case 'M': [[fallthrough]]; - case 'm': - if (ix < s.length()) { - switch (s[ix++]) { - case 'A': [[fallthrough]]; - case 'a': - if (ix == s.length()) return { token_t::type_t::_dma }; - else { - switch (s[ix++]) { - case 'H': [[fallthrough]]; - case 'h': - if (ix == s.length()) return { token_t::type_t::_dmah }; - break; - } - } - break; - } - } - break; - } - } - break; - case 'J': [[fallthrough]]; - case 'j': - if (ix < s.length()) { - switch (s[ix++]) { - case 'M': [[fallthrough]]; - case 'm': - if (ix < s.length()) { - switch (s[ix++]) { - case 'P': [[fallthrough]]; - case 'p': - if (ix == s.length()) return { token_t::type_t::_jmp }; - break; - } - } - break; - } - } - break; - case 'B': [[fallthrough]]; - case 'b': - if (ix < s.length()) { - switch (s[ix++]) { - case 'T': [[fallthrough]]; - case 't': - if (ix < s.length()) { - switch (s[ix++]) { - case 'M': [[fallthrough]]; - case 'm': - if (ix == s.length()) return { token_t::type_t::_btm }; - break; - } - } - break; - } - } - break; - case 'L': [[fallthrough]]; - case 'l': - if (ix < s.length()) { - switch (s[ix++]) { - case 'P': [[fallthrough]]; - case 'p': - if (ix < s.length()) { - switch (s[ix++]) { - case 'S': [[fallthrough]]; - case 's': - if (ix == s.length()) return { token_t::type_t::_lps }; - break; - } - } - break; - } - } - break; - case 'E': [[fallthrough]]; - case 'e': - if (ix < s.length()) { - switch (s[ix++]) { - case 'N': [[fallthrough]]; - case 'n': - if (ix < s.length()) { - switch (s[ix++]) { - case 'D': [[fallthrough]]; - case 'd': - if (ix == s.length()) return { token_t::type_t::_end }; - else { - switch (s[ix++]) { - case 'I': [[fallthrough]]; - case 'i': - if (ix == s.length()) return { token_t::type_t::_endi }; - break; - case 'S': [[fallthrough]]; - case 's': - if (ix == s.length()) return { token_t::type_t::_ends }; - break; - } - } - break; - } - } - break; - case 'Q': [[fallthrough]]; - case 'q': - if (ix < s.length()) { - switch (s[ix++]) { - case 'U': [[fallthrough]]; - case 'u': - if (ix == s.length()) return { token_t::type_t::_equ }; - break; - } - } + case 'S': [[fallthrough]]; + case 's': + if (ix == s.length()) return { token_t::type_t::_zs }; break; } } diff --git a/lexer.cpp b/lexer.cpp index 8deb0d3..1f69039 100644 --- a/lexer.cpp +++ b/lexer.cpp @@ -139,7 +139,7 @@ token_t lexer_t::_identifier() else return {pos, token_t::identifier, lexeme()}; } -std::optional lexer_t::scan_token() +std::optional lexer_t::lex_token() { using enum token_t::type_t; @@ -215,4 +215,17 @@ std::optional lexer_t::scan_token() __builtin_unreachable(); } +std::vector lexer_t::lex_tokens() +{ + std::vector tokens; + + while (true) { + std::optional token_o = lex_token(); + if (!token_o) continue; + tokens.push_back(*token_o); + if (token_o->type == token_t::eof) break; + } + return tokens; +} + } diff --git a/lexer.hpp b/lexer.hpp index 0665962..42f0618 100644 --- a/lexer.hpp +++ b/lexer.hpp @@ -2,6 +2,7 @@ #include #include +#include #include "token.hpp" @@ -19,7 +20,8 @@ struct lexer_t { : source(source), start_ix(0), current_ix(0), pos{ .line = 1, .col = 0 } { } - std::optional scan_token(); + std::optional lex_token(); + std::vector lex_tokens(); private: bool at_end_p(); diff --git a/lexer_iterator.cpp b/lexer_iterator.cpp new file mode 100644 index 0000000..8c2daa0 --- /dev/null +++ b/lexer_iterator.cpp @@ -0,0 +1,35 @@ +#include "lexer.hpp" +#include "token.hpp" + +namespace dsp { + +struct lexer_iterator_t +{ + token_t previous_token; + token_t current_token; + lexer_t& lexer; + + lexer_iterator_t(lexer_t& lexer) + : lexer(lexer), previous_token(lexer.scan_token()), current_token(previous_token) + { + } + + token_t& advance() + { + previous_token = current_token; + current_token = lexer.scan_token(); + return previous_token; + } + + token_t& peek() + { + return current_token; + } + + token_t& previous() + { + return previous_token; + } +}; + +} diff --git a/main.cpp b/main.cpp index 544e9ac..053d9db 100644 --- a/main.cpp +++ b/main.cpp @@ -5,6 +5,7 @@ #include "lexer.hpp" #include "token.hpp" #include "ast.hpp" +#include "parser.hpp" namespace dsp { @@ -12,28 +13,18 @@ bool had_error = false; } -static void print() -{ - dsp::literal_t l(56); - std::string_view s("-"); - dsp::token_t t({0, 0}, dsp::token_t::minus, s); - dsp::unary_t a(t, &l); - dsp::ast_printer_t p(std::cout); - p.visit(&a); -} - static void run(std::string source) { using namespace dsp; - std::string_view buf {source}; - lexer_t lexer {buf}; - while (std::optional token_o = lexer.scan_token()) { - std::cout << *token_o << std::endl; - if (token_o->type == token_t::type_t::eof) { - break; - } - } + std::string_view buf(source); + lexer_t lexer(buf); + std::vector tokens = lexer.lex_tokens(); + parser_t parser(tokens); + expr_t * expr = parser.expression(); + dsp::ast_printer_t p(std::cout); + expr->accept(&p); + std::cout << std::endl << std::flush; } static void run_prompt() @@ -67,7 +58,6 @@ static int run_file(char const * const filename) int main(const int argc, char const * const argv[]) { - print(); switch (argc) { case 1: run_prompt(); return dsp::had_error; case 2: return run_file(argv[1]); diff --git a/token.hpp b/token.hpp index 6a7e184..a36b841 100644 --- a/token.hpp +++ b/token.hpp @@ -45,47 +45,12 @@ struct token_t { string, number, - // keywords - _alh, - _all, - _alu, - _m0, - _m1, - _m2, - _m3, - _mc0, - _mc1, - _mc2, - _mc3, - _mul, - _nop, - _and, - _or, - _xor, - _add, - _sub, - _ad2, - _sr, - _rr, - _sl, - _rl, - _rl8, - _clr, - _mov, - _mvi, - _dma, - _dmah, - _jmp, - _btm, - _lps, - _end, - _endi, - _equ, - _org, - _ends, - + // ends eof, eol, + + // keywords + #include "keyword.enum_inc" }; using literal_t = std::variant; @@ -133,44 +98,8 @@ struct token_t { case string : return os << "STRING"; case number : return os << "NUMBER"; - // keywords - case _alh : return os << "ALH"; - case _all : return os << "ALL"; - case _alu : return os << "ALU"; - case _m0 : return os << "M0"; - case _m1 : return os << "M1"; - case _m2 : return os << "M2"; - case _m3 : return os << "M3"; - case _mc0 : return os << "MC0"; - case _mc1 : return os << "MC1"; - case _mc2 : return os << "MC2"; - case _mc3 : return os << "MC3"; - case _mul : return os << "MUL"; - case _nop : return os << "NOP"; - case _and : return os << "AND"; - case _or : return os << "OR"; - case _xor : return os << "XOR"; - case _add : return os << "ADD"; - case _sub : return os << "SUB"; - case _ad2 : return os << "AD2"; - case _sr : return os << "SR"; - case _rr : return os << "RR"; - case _sl : return os << "SL"; - case _rl : return os << "RL"; - case _rl8 : return os << "RL8"; - case _clr : return os << "CLR"; - case _mov : return os << "MOV"; - case _mvi : return os << "MVI"; - case _dma : return os << "DMA"; - case _dmah : return os << "DMAH"; - case _jmp : return os << "JMP"; - case _btm : return os << "BTM"; - case _lps : return os << "LPS"; - case _end : return os << "END"; - case _endi : return os << "ENDI"; - case _equ : return os << "EQU"; - case _org : return os << "ORG"; - case _ends : return os << "ENDS"; + // keywords + #include "keyword.case_inc" case eof : return os << "EOF"; case eol : return os << "EOL";