From 8258df216e261a7a5206235ba4726490b1c188e1 Mon Sep 17 00:00:00 2001 From: Bobby Lucero Date: Fri, 2 Jun 2023 14:43:33 -0400 Subject: [PATCH] Added simple escape character support --- headers/Lexer.h | 2 ++ source/Lexer.cpp | 56 +++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 53 insertions(+), 5 deletions(-) diff --git a/headers/Lexer.h b/headers/Lexer.h index 8459ae6..82fb12d 100644 --- a/headers/Lexer.h +++ b/headers/Lexer.h @@ -80,4 +80,6 @@ private: char peekNext(); void advance(int by = 1); + + std::string parseEscapeCharacters(const std::string &input); }; diff --git a/source/Lexer.cpp b/source/Lexer.cpp index 25b2b37..377366e 100644 --- a/source/Lexer.cpp +++ b/source/Lexer.cpp @@ -142,15 +142,25 @@ std::vector Lexer::Tokenize(std::string source){ } else if(t == '"') { + bool last_was_escape = false; std::string str; advance(); - while(!src.empty() && src[0] != '"') - { - if(src[0] == '\n') line++; - str += src[0]; + while(!src.empty()) + { + std::string next_c = std::string(1, src[0]); + if(next_c == "\"") break; + if(next_c == "\\") + { + advance(); + next_c = "\\" + std::string(1, src[0]); + } + + if(next_c == "\n") line++; + str += next_c; advance(); } + if(src.empty()) { throw std::runtime_error("LEXER: Unterminated string at line: " + std::to_string(this->line)); @@ -159,7 +169,10 @@ std::vector Lexer::Tokenize(std::string source){ { advance(); - tokens.push_back(Token{STRING, str, line}); + + + std::string escaped_str = parseEscapeCharacters(str); + tokens.push_back(Token{STRING, escaped_str, line}); } @@ -311,4 +324,37 @@ char Lexer::peekNext() return '\0'; } +std::string Lexer::parseEscapeCharacters(const std::string& input) { + std::string output; + bool escapeMode = false; + + for (char c : input) { + if (escapeMode) { + switch (c) { + case 'n': + output += '\n'; + break; + case 't': + output += '\t'; + break; + case '"': + output += '\"'; + break; + case '\\': + output += '\\'; + break; + default: + throw runtime_error("Invalid escape character: " + std::string(1, c)); + } + escapeMode = false; + } else if (c == '\\') { + escapeMode = true; + } else { + output += c; + } + } + + return output; +} +