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. --- makefile | 2 ++ spec/inputs/literals.yue | 9 +++++++++ spec/outputs/5.1/literals.lua | 44 ++++++++++++++++++++++++++++++++++++++++++ spec/outputs/literals.lua | 8 ++++++++ src/yuescript/yue_compiler.cpp | 31 ++++++++++++++++++++++++++++- src/yuescript/yue_parser.cpp | 28 +++++++++++++++------------ src/yuescript/yue_parser.h | 1 + 7 files changed, 110 insertions(+), 13 deletions(-) create mode 100644 spec/outputs/5.1/literals.lua diff --git a/makefile b/makefile index d7e85d3..d1b074a 100644 --- a/makefile +++ b/makefile @@ -391,6 +391,7 @@ test: debug @./$(BIN_NAME) $(TEST_INPUT)/try_catch.yue -o $(TEST_OUTPUT)/5.1/try_catch.lua --target=5.1 @./$(BIN_NAME) $(TEST_INPUT)/attrib.yue -o $(TEST_OUTPUT)/5.1/attrib.lua --target=5.1 @./$(BIN_NAME) $(TEST_INPUT)/test/loops_spec.yue -o $(TEST_OUTPUT)/5.1/test/loops_spec.lua --target=5.1 + @./$(BIN_NAME) $(TEST_INPUT)/literals.yue -o $(TEST_OUTPUT)/5.1/literals.lua --target=5.1 @./$(BIN_NAME) -e spec/inputs/compile_doc.yue $(TEST_OUTPUT) @echo -en "Compile time: " @$(END_TIME) @@ -409,6 +410,7 @@ gen: release @./$(BIN_NAME) $(TEST_INPUT)/loops.yue -o $(GEN_OUTPUT)/5.1/loops.lua --target=5.1 @./$(BIN_NAME) $(TEST_INPUT)/try_catch.yue -o $(GEN_OUTPUT)/5.1/try_catch.lua --target=5.1 @./$(BIN_NAME) $(TEST_INPUT)/attrib.yue -o $(GEN_OUTPUT)/5.1/attrib.lua --target=5.1 + @./$(BIN_NAME) $(TEST_INPUT)/literals.yue -o $(GEN_OUTPUT)/5.1/literals.lua --target=5.1 @./$(BIN_NAME) $(TEST_INPUT)/test/loops_spec.yue -o $(GEN_OUTPUT)/5.1/test/loops_spec.lua --target=5.1 @./$(BIN_NAME) -e spec/inputs/compile_doc.yue $(GEN_OUTPUT) @echo -en "Compile time: " diff --git a/spec/inputs/literals.yue b/spec/inputs/literals.yue index 6b666f0..32cf7e7 100644 --- a/spec/inputs/literals.yue +++ b/spec/inputs/literals.yue @@ -10,10 +10,19 @@ _ = { 0xfF2323 0xabcdef 0xABCDEF + 0XFB_C4_00 0x123p-123 0xABCP+321 0x.1p-111 0xA_B_CP-3_2_1 + 0x0.1E + 0xA23p-4 + 0X1.921FB54442D18P+1 + + 0b01 + 0b00_00_10_00 + 0B1111 + 0B00_11_00_10_01 .2323 .2323e-1 diff --git a/spec/outputs/5.1/literals.lua b/spec/outputs/5.1/literals.lua new file mode 100644 index 0000000..36c705a --- /dev/null +++ b/spec/outputs/5.1/literals.lua @@ -0,0 +1,44 @@ +local _ = { + 121, + 121.2323, + 121.2323e-1, + 121.2323e13434, + 2323E34, + 0x12323, + 0xfF2323, + 0xabcdef, + 0xABCDEF, + 0XFBC400, + 2.7365508487142853e-35, + 0xABCP321, + 2.4074124304840448e-35, + 6.4326233113470805e-94, + 0.1171875, + 162.1875, + 3.1415926535897931, + 1, + 8, + 15, + 201, + .2323, + .2323e-1, + .2323e13434, + 1LL, + 1ULL, + 9332LL, + 9332, + 0x2aLL, + 0x2aULL, + 1000000.0000001, + 1234e5678, + 1234E-5678, + 0xDEADBEEF, + [[ hello world ]], + [=[ hello world ]=], + [====[ hello world ]====], + "another world", + 'what world', + "\n hello world\n ", + 'yeah\n what is going on\n here is something cool' +} +return nil diff --git a/spec/outputs/literals.lua b/spec/outputs/literals.lua index a578d58..6de5411 100644 --- a/spec/outputs/literals.lua +++ b/spec/outputs/literals.lua @@ -8,10 +8,18 @@ local _ = { 0xfF2323, 0xabcdef, 0xABCDEF, + 0XFBC400, 0x123p-123, 0xABCP+321, 0x.1p-111, 0xABCP-321, + 0x0.1E, + 0xA23p-4, + 0X1.921FB54442D18P+1, + 1, + 8, + 15, + 201, .2323, .2323e-1, .2323e13434, 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