From c9d2fad4c84b9d5dbb9a86f0e8ba43648da5f7c9 Mon Sep 17 00:00:00 2001 From: sfja Date: Mon, 19 Jan 2026 19:43:54 +0100 Subject: [PATCH] add const keyword --- Makefile | 2 +- src/assembler.cpp | 32 +++----------------------------- src/assembler.hpp | 12 ++++++++++++ src/scanner.cpp | 47 ++++++++++++++++++++++++++++++++++++++++++++++- src/scanner.hpp | 4 ++++ 5 files changed, 66 insertions(+), 31 deletions(-) diff --git a/Makefile b/Makefile index 23d99cc..c54650f 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ MAKEFLAGS += -j16 -CXXFLAGS := -std=c++23 -Wall -Wextra -pedantic-errors -fsanitize=address,undefined +CXXFLAGS := -std=c++23 -Wall -Wextra -pedantic-errors -fsanitize=address LDFLAGS := CXXFLAGS += $(shell pkgconf sdl2 --cflags) diff --git a/src/assembler.cpp b/src/assembler.cpp index 5256ad2..3348f01 100644 --- a/src/assembler.cpp +++ b/src/assembler.cpp @@ -365,23 +365,6 @@ const auto reg_idents = std::unordered_map { { "Rip", vc5::Reg::Rip }, }; -char escape_char(char ch) -{ - - switch (ch) { - case 'n': - return '\n'; - case 'r': - return '\r'; - case 't': - return '\t'; - case '0': - return '\0'; - default: - return ch; - } -} - } auto Parser::parse_operand() -> std::unique_ptr @@ -425,7 +408,8 @@ auto Parser::parse_operand() -> std::unique_ptr auto text = std::string(m_tok.text); step(); - int value = text.at(1) == '\\' ? escape_char(text.at(2)) : text.at(1); + int value = text.at(1) == '\\' ? unescape_escape_char(text.at(2)) + : text.at(1); return std::make_unique( loc, Expr::Ty::Int, static_cast(value)); @@ -433,17 +417,7 @@ auto Parser::parse_operand() -> std::unique_ptr auto text = std::string(m_tok.text); step(); - auto value = std::string(); - size_t i = 1; - while (i < text.size() - 1) { - if (text.at(i) == '\\') { - i += 1; - value.push_back(escape_char(text.at(i))); - } else { - value.push_back(text.at(i)); - } - i += 1; - } + auto value = unescape_string(text.substr(1, text.size() - 2)); return std::make_unique(loc, Expr::Ty::Str, std::move(value)); } else if (eat('(')) { diff --git a/src/assembler.hpp b/src/assembler.hpp index 1f02c5a..6bf595d 100644 --- a/src/assembler.hpp +++ b/src/assembler.hpp @@ -89,6 +89,18 @@ namespace asmer { Args args; }; + struct Const { + Loc loc; + std::string_view ident; + std::unique_ptr expr; + }; + + struct Align { + Loc loc; + std::string_view ident; + std::unique_ptr expr; + }; + class Parser { public: explicit Parser(std::string_view text) diff --git a/src/scanner.cpp b/src/scanner.cpp index 7696354..89b98ea 100644 --- a/src/scanner.cpp +++ b/src/scanner.cpp @@ -1,7 +1,9 @@ #include "scanner.hpp" +#include #include #include #include +#include using namespace vc5::tools; using namespace std::literals; @@ -32,7 +34,18 @@ auto Scanner::next() -> Tok or test_range('a', 'z')) { step(); } - return tok(TT::Ident, loc); + + auto ident_tok = tok(TT::Ident, loc); + + static const auto keywords = std::unordered_map { + { "const", TT::KwConst }, + }; + + if (keywords.contains(ident_tok.text)) { + return tok(keywords.at(ident_tok.text), loc); + } + + return ident_tok; } if (test_range('1', '9')) { while (test_range('0', '9')) { @@ -232,3 +245,35 @@ void Loc::print_error(std::string_view text, std::string_view message) const message, clear); } + +auto vc5::tools::unescape_escape_char(char ch) -> char +{ + switch (ch) { + case 'n': + return '\n'; + case 'r': + return '\r'; + case 't': + return '\t'; + case '0': + return '\0'; + default: + return ch; + } +} + +auto vc5::tools::unescape_string(std::string_view value) -> std::string +{ + auto result = std::string(); + size_t i = 0; + while (i < value.size()) { + if (value[0] == '\\') { + i += 1; + result += unescape_escape_char(value[i]); + } else { + result += value[i]; + } + i += 1; + } + return result; +} diff --git a/src/scanner.hpp b/src/scanner.hpp index 8229ba7..5a17e22 100644 --- a/src/scanner.hpp +++ b/src/scanner.hpp @@ -22,6 +22,7 @@ struct Tok { Bin, Char, Str, + KwConst, Newline = '\n', LParen = '(', RParen = ')', @@ -76,4 +77,7 @@ private: bool m_error_occured = false; }; +auto unescape_escape_char(char ch) -> char; +auto unescape_string(std::string_view value) -> std::string; + }