From 4d2b3e59a169a721e24f3ac576cf8bc81ff54699 Mon Sep 17 00:00:00 2001 From: Steve Tautonico Date: Sat, 7 Oct 2023 03:53:34 -0400 Subject: [PATCH] Added octal literal support --- src/lexer.cpp | 20 ++++++++++++++------ tests/01_int.py | 4 ++++ 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/lexer.cpp b/src/lexer.cpp index f033d504..1487033d 100644 --- a/src/lexer.cpp +++ b/src/lexer.cpp @@ -260,7 +260,7 @@ static bool is_unicode_Lo_char(uint32_t c) { } void Lexer::eat_number() { - PK_LOCAL_STATIC const std::regex pattern("^(0x)?[0-9a-fA-F]+(\\.[0-9]+)?(L)?"); + PK_LOCAL_STATIC const std::regex pattern("^(0[xo])?[0-9a-fA-F]+(\\.[0-9]+)?(L)?"); std::smatch m; const char* i = token_start; @@ -278,20 +278,28 @@ static bool is_unicode_Lo_char(uint32_t c) { } if(m[1].matched && m[2].matched){ - SyntaxError("hex literal should not contain a dot"); + SyntaxError("hex/octal literal should not contain a dot"); } try{ int base = 10; size_t size; - if (m[1].matched) base = 16; + if (m[1].matched) { + if (m[1].str() == "0o") base=8; + else base = 16; + } if (m[2].matched) { PK_ASSERT(base == 10); add_token(TK("@num"), Number::stof(m[0], &size)); } else { - add_token(TK("@num"), (i64)std::stoll(m[0], &size, base)); + // If we're base 8, chop off the "o" + std::string match = m[0].str(); + if (base == 8) match.erase(1, 1); + add_token(TK("@num"), (i64)std::stoll(match, &size, base)); } - PK_ASSERT((int)size == (int)m.length()); + // HACK: We need to check length-1 for octal since python octals are "0o..." and c/c++ octals are "0..." + if (base == 8) {PK_ASSERT((int)size == (int)m.length()-1);} + else {PK_ASSERT((int)size == (int)m.length());} }catch(...){ SyntaxError("invalid number literal"); } @@ -466,4 +474,4 @@ static bool is_unicode_Lo_char(uint32_t c) { return std::move(nexts); } -} // namespace pkpy \ No newline at end of file +} // namespace pkpy diff --git a/tests/01_int.py b/tests/01_int.py index 07b8d793..f95264a4 100644 --- a/tests/01_int.py +++ b/tests/01_int.py @@ -5,6 +5,10 @@ assert 0x7fffffff == 2147483647 # test 64-bit assert 2**60-1 + 546 - 0xfffffffffffff == 1148417904979477026 +# test oct literals +assert 0o1234 == 668 +assert 0o17777777777 == 2147483647 + # test == != >= <= < > assert -1 == -1 assert -1 != 1