From 47293b4cf555212d4ff9a6fcdda381ed81709cf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Grodzi=C5=84ski?= Date: Sun, 22 Jun 2025 13:24:17 +0900 Subject: [PATCH] Binary literals --- src/Lexer/Lexer.cpp | 30 ++++++++++++++++++++++++++++++ src/Lexer/Lexer.h | 2 ++ src/Lexer/Token.cpp | 3 +++ src/Lexer/Token.h | 1 + src/Parser/Expression.cpp | 8 ++++++++ 5 files changed, 44 insertions(+) diff --git a/src/Lexer/Lexer.cpp b/src/Lexer/Lexer.cpp index 535fd97..2569005 100644 --- a/src/Lexer/Lexer.cpp +++ b/src/Lexer/Lexer.cpp @@ -216,6 +216,9 @@ shared_ptr Lexer::nextToken() { if (token != nullptr) return token; + token = matchIntegerBin(); + if (token != nullptr) + return token; // type token = match(TokenKind::TYPE, "bool", true); @@ -302,6 +305,28 @@ shared_ptr Lexer::matchIntegerHex() { return token; } +shared_ptr Lexer::matchIntegerBin() { + int nextIndex = currentIndex; + + // match 0b + if (nextIndex > source.length()-2) + return nullptr; + + if (source.at(nextIndex++) != '0' || source.at(nextIndex++) != 'b') + return nullptr; + + while (nextIndex < source.length() && isBinDigit(nextIndex)) + nextIndex++; + + if (nextIndex == currentIndex || !isSeparator(nextIndex)) + return nullptr; + + string lexme = source.substr(currentIndex, nextIndex - currentIndex); + shared_ptr token = make_shared(TokenKind::INTEGER_BIN, lexme, currentLine, currentColumn); + advanceWithToken(token); + return token; +} + shared_ptr Lexer::matchReal() { int nextIndex = currentIndex; @@ -366,6 +391,11 @@ bool Lexer::isHexDigit(int index) { return (character >= '0' && character <= '9') || (character >= 'a' && character <= 'f'); } +bool Lexer::isBinDigit(int index) { + char character = source.at(index); + return character == '0' || character == '1'; +} + bool Lexer::isIdentifier(int index) { char character = source.at(index); bool isDigit = character >= '0' && character <= '9'; diff --git a/src/Lexer/Lexer.h b/src/Lexer/Lexer.h index b4cb848..f0fe2bb 100644 --- a/src/Lexer/Lexer.h +++ b/src/Lexer/Lexer.h @@ -20,6 +20,7 @@ private: shared_ptr match(TokenKind kind, string lexme, bool needsSeparator); shared_ptr matchIntegerDec(); shared_ptr matchIntegerHex(); + shared_ptr matchIntegerBin(); shared_ptr matchReal(); shared_ptr matchIdentifier(); shared_ptr matchEnd(); @@ -28,6 +29,7 @@ private: bool isWhiteSpace(int index); bool isDecDigit(int index); bool isHexDigit(int index); + bool isBinDigit(int index); bool isIdentifier(int index); bool isSeparator(int index); void advanceWithToken(shared_ptr token); diff --git a/src/Lexer/Token.cpp b/src/Lexer/Token.cpp index 0980d69..a4fed2d 100644 --- a/src/Lexer/Token.cpp +++ b/src/Lexer/Token.cpp @@ -39,6 +39,7 @@ vector Token::tokensLiteral = { TokenKind::BOOL, TokenKind::INTEGER_DEC, TokenKind::INTEGER_HEX, + TokenKind::INTEGER_BIN, TokenKind::REAL }; @@ -126,6 +127,8 @@ string Token::toString() { return "INTEGER_DEC(" + lexme + ")"; case TokenKind::INTEGER_HEX: return "INTEGER_HEX(" + lexme + ")"; + case TokenKind::INTEGER_BIN: + return "INTEGER_BIN(" + lexme + ")"; case TokenKind::REAL: return "REAL(" + lexme + ")"; case TokenKind::IDENTIFIER: diff --git a/src/Lexer/Token.h b/src/Lexer/Token.h index 617ef7e..ac0ac5e 100644 --- a/src/Lexer/Token.h +++ b/src/Lexer/Token.h @@ -37,6 +37,7 @@ enum class TokenKind { BOOL, INTEGER_DEC, INTEGER_HEX, + INTEGER_BIN, REAL, IDENTIFIER, TYPE, diff --git a/src/Parser/Expression.cpp b/src/Parser/Expression.cpp index 1966f52..0622f14 100644 --- a/src/Parser/Expression.cpp +++ b/src/Parser/Expression.cpp @@ -138,6 +138,14 @@ Expression(ExpressionKind::LITERAL, ValueType::NONE) { sint32Value = stoi(token->getLexme(), nullptr, 16); valueType = ValueType::SINT32; break; + case TokenKind::INTEGER_BIN: + sint32Value = stoi( + token->getLexme().substr(2, token->getLexme().size()-1), + nullptr, + 2 + ); + valueType = ValueType::SINT32; + break; case TokenKind::REAL: real32Value = stof(token->getLexme()); valueType = ValueType::REAL32;