From 0446b12d7be2ba4e8534987864fedfc586510291 Mon Sep 17 00:00:00 2001 From: Li Jin Date: Thu, 17 Apr 2025 11:05:06 +0800 Subject: Fixed issue #209. --- src/yuescript/yue_compiler.cpp | 31 ++++++++++++++++++++++++++++++- src/yuescript/yue_parser.cpp | 28 ++++++++++++++++------------ src/yuescript/yue_parser.h | 1 + 3 files changed, 47 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp index 68ce9b5..d5db8a1 100644 --- a/src/yuescript/yue_compiler.cpp +++ b/src/yuescript/yue_compiler.cpp @@ -16,6 +16,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #include #include #include +#include +#include #include "yuescript/yue_compiler.h" #include "yuescript/yue_parser.h" @@ -75,7 +77,7 @@ static std::unordered_set Metamethods = { "close"s // Lua 5.4 }; -const std::string_view version = "0.27.4"sv; +const std::string_view version = "0.27.5"sv; const std::string_view extension = "yue"sv; class CompileError : public std::logic_error { @@ -7144,6 +7146,33 @@ private: void transformNum(Num_t* num, str_list& out) { std::string numStr = _parser.toString(num); numStr.erase(std::remove(numStr.begin(), numStr.end(), '_'), numStr.end()); + if (numStr.size() > 2 && numStr[0] == '0') { + if (numStr[1] == 'b' || numStr[1] == 'B') { + std::string binaryPart = numStr.substr(2); + try { + unsigned long long value = std::stoull(binaryPart, nullptr, 2); + numStr = std::to_string(value); + } catch (const std::exception& e) { + throw CompileError("invalid binary literal"sv, num); + } + } else if (getLuaTarget(num) < 502) { + if (numStr[1] == 'x' || numStr[1] == 'X') { + if (numStr.find_first_of(".-"sv) != std::string::npos) { + std::stringstream ss(numStr); + double v; + ss >> std::hexfloat >> v; + if (ss.fail() || !std::isfinite(v)) { + throw CompileError("invalid hex‑float literal"sv, num); + } + std::ostringstream outSs; + outSs << std::setprecision(17) << v; + numStr = outSs.str(); + } else { + numStr.erase(std::remove(numStr.begin(), numStr.end(), '+'), numStr.end()); + } + } + } + } out.push_back(numStr); } diff --git a/src/yuescript/yue_parser.cpp b/src/yuescript/yue_parser.cpp index ceb1f7c..77c5901 100644 --- a/src/yuescript/yue_parser.cpp +++ b/src/yuescript/yue_parser.cpp @@ -67,24 +67,28 @@ YueParser::YueParser() { num_char = range('0', '9') >> *(range('0', '9') | '_' >> and_(range('0', '9'))); num_char_hex = range('0', '9') | range('a', 'f') | range('A', 'F'); num_lit = num_char_hex >> *(num_char_hex | '_' >> and_(num_char_hex)); + num_bin_lit = set("01") >> *(set("01") | '_' >> and_(set("01"))); Num = - "0x" >> ( - +num_lit >> ( - '.' >> +num_lit >> -num_expo_hex | - num_expo_hex | - lj_num | - true_() - ) | ( - '.' >> +num_lit >> -num_expo_hex - ) + '0' >> ( + set("xX") >> ( + num_lit >> ( + '.' >> num_lit >> -num_expo_hex | + num_expo_hex | + lj_num | + true_() + ) | ( + '.' >> num_lit >> -num_expo_hex + ) + ) | + set("bB") >> num_bin_lit ) | - +num_char >> ( - '.' >> +num_char >> -num_expo | + num_char >> ( + '.' >> num_char >> -num_expo | num_expo | lj_num | true_() ) | - '.' >> +num_char >> -num_expo; + '.' >> num_char >> -num_expo; cut = false_(); Seperator = true_(); diff --git a/src/yuescript/yue_parser.h b/src/yuescript/yue_parser.h index 02292e1..7281ec3 100644 --- a/src/yuescript/yue_parser.h +++ b/src/yuescript/yue_parser.h @@ -164,6 +164,7 @@ private: NONE_AST_RULE(num_char); NONE_AST_RULE(num_char_hex); NONE_AST_RULE(num_lit); + NONE_AST_RULE(num_bin_lit); NONE_AST_RULE(num_expo); NONE_AST_RULE(num_expo_hex); NONE_AST_RULE(lj_num); -- cgit v1.2.3-55-g6feb