aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/yuescript/yue_compiler.cpp84
1 files changed, 45 insertions, 39 deletions
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp
index 92bf561..840ef3e 100644
--- a/src/yuescript/yue_compiler.cpp
+++ b/src/yuescript/yue_compiler.cpp
@@ -78,7 +78,7 @@ static std::unordered_set<std::string> Metamethods = {
78 "close"s // Lua 5.4 78 "close"s // Lua 5.4
79}; 79};
80 80
81const std::string_view version = "0.33.1"sv; 81const std::string_view version = "0.33.2"sv;
82const std::string_view extension = "yue"sv; 82const std::string_view extension = "yue"sv;
83 83
84class CompileError : public std::logic_error { 84class CompileError : public std::logic_error {
@@ -9955,9 +9955,11 @@ private:
9955 auto baseVar = getUnusedName("_base_"sv); 9955 auto baseVar = getUnusedName("_base_"sv);
9956 addToScope(baseVar); 9956 addToScope(baseVar);
9957 temp.push_back(indent() + "local "s + baseVar + " = "s); 9957 temp.push_back(indent() + "local "s + baseVar + " = "s);
9958 str_list builtins; 9958 using ClassMemberEntry = std::tuple<std::string, std::string, bool>;
9959 std::vector<std::pair<std::string, bool>> baseEntries; 9959 std::list<ClassMemberEntry> builtinFields;
9960 str_list statements; 9960 std::list<ClassMemberEntry> classFields;
9961 std::list<ClassMemberEntry> commentOrEmpty;
9962 str_list initStatements;
9961 if (body) { 9963 if (body) {
9962 std::list<ClassMember> members; 9964 std::list<ClassMember> members;
9963 for (auto content : classDecl->body->contents.objects()) { 9965 for (auto content : classDecl->body->contents.objects()) {
@@ -9969,11 +9971,19 @@ private:
9969 for (; it != members.end(); ++it) { 9971 for (; it != members.end(); ++it) {
9970 auto& member = *it; 9972 auto& member = *it;
9971 if (member.type == MemType::Property) { 9973 if (member.type == MemType::Property) {
9972 statements.push_back(indent() + member.item + nl(content)); 9974 initStatements.push_back(indent() + member.item + nl(content));
9973 } else if (member.type == MemType::Builtin) { 9975 } else if (member.type == MemType::Builtin) {
9974 builtins.push_back((builtins.empty() ? Empty : ',' + nl(member.node)) + indent(1) + member.item); 9976 if (!commentOrEmpty.empty()) {
9977 builtinFields.insert(builtinFields.end(), commentOrEmpty.begin(), commentOrEmpty.end());
9978 commentOrEmpty.clear();
9979 }
9980 builtinFields.emplace_back(indent(1) + member.item, nl(member.node), false);
9975 } else { 9981 } else {
9976 baseEntries.emplace_back(indent(1) + member.item + nl(member.node), true); 9982 if (!commentOrEmpty.empty()) {
9983 classFields.insert(classFields.end(), commentOrEmpty.begin(), commentOrEmpty.end());
9984 commentOrEmpty.clear();
9985 }
9986 classFields.emplace_back(indent(1) + member.item, nl(member.node), false);
9977 } 9987 }
9978 } 9988 }
9979 break; 9989 break;
@@ -9981,13 +9991,13 @@ private:
9981 case id<YueComment_t>(): { 9991 case id<YueComment_t>(): {
9982 if (_config.reserveComment) { 9992 if (_config.reserveComment) {
9983 auto comment = static_cast<YueComment_t*>(content); 9993 auto comment = static_cast<YueComment_t*>(content);
9984 baseEntries.emplace_back(indent(1) + comment->to_string(&_config) + '\n', false); 9994 commentOrEmpty.emplace_back(indent(1) + comment->to_string(&_config), "\n"s, true);
9985 } 9995 }
9986 break; 9996 break;
9987 } 9997 }
9988 case id<EmptyLine_t>(): { 9998 case id<EmptyLine_t>(): {
9989 if (_config.reserveComment) { 9999 if (_config.reserveComment) {
9990 baseEntries.emplace_back("\n"s, false); 10000 commentOrEmpty.emplace_back(Empty, "\n"s, true);
9991 } 10001 }
9992 break; 10002 break;
9993 } 10003 }
@@ -10002,37 +10012,23 @@ private:
10002 forceAddToScope("self"s); 10012 forceAddToScope("self"s);
10003 for (auto stmt_ : block->statementOrComments.objects()) { 10013 for (auto stmt_ : block->statementOrComments.objects()) {
10004 if (auto stmt = ast_cast<Statement_t>(stmt_)) { 10014 if (auto stmt = ast_cast<Statement_t>(stmt_)) {
10005 transformStatement(stmt, statements); 10015 transformStatement(stmt, initStatements);
10006 } 10016 }
10007 } 10017 }
10008 if (!baseEntries.empty()) { 10018 if (!classFields.empty()) {
10009 temp.back() += '{' + nl(body); 10019 temp.back() += '{' + nl(body);
10010 int lastValue = -1; 10020 str_list fieldItems;
10011 for (int i = static_cast<int>(baseEntries.size()) - 1; i >= 0; --i) { 10021 for (auto& field : classFields) {
10012 if (baseEntries[i].second) { 10022 auto [item, newLine, isComment] = std::move(field);
10013 lastValue = i; 10023 bool isLast = &field == &classFields.back();
10014 break; 10024 bool needComma = !isLast && !isComment;
10015 } 10025 if (needComma) {
10016 } 10026 fieldItems.emplace_back(item + ',' + newLine);
10017 str_list baseItems; 10027 } else {
10018 for (int i = 0; i < static_cast<int>(baseEntries.size()); ++i) { 10028 fieldItems.emplace_back(item + newLine);
10019 auto item = baseEntries[i].first;
10020 if (baseEntries[i].second && i != lastValue) {
10021 auto pos = item.rfind('\n');
10022 if (pos != std::string::npos) {
10023 auto comment = item.rfind("-- ");
10024 if (comment != std::string::npos && comment < pos) {
10025 item.insert(comment - 1, ",");
10026 } else {
10027 item.insert(pos, ",");
10028 }
10029 } else {
10030 item.push_back(',');
10031 }
10032 } 10029 }
10033 baseItems.push_back(std::move(item));
10034 } 10030 }
10035 temp.push_back(join(baseItems)); 10031 temp.push_back(join(fieldItems));
10036 temp.push_back(indent() + '}' + nl(body)); 10032 temp.push_back(indent() + '}' + nl(body));
10037 } else { 10033 } else {
10038 temp.back() += "{ }"s + nl(body); 10034 temp.back() += "{ }"s + nl(body);
@@ -10074,8 +10070,18 @@ private:
10074 _buf << indent() << "setmetatable("sv << baseVar << ", "sv << parentVar << ".__base)"sv << nl(classDecl); 10070 _buf << indent() << "setmetatable("sv << baseVar << ", "sv << parentVar << ".__base)"sv << nl(classDecl);
10075 } 10071 }
10076 _buf << indent() << classVar << " = "sv << globalVar("setmetatable"sv, classDecl, AccessType::Read) << "({"sv << nl(classDecl); 10072 _buf << indent() << classVar << " = "sv << globalVar("setmetatable"sv, classDecl, AccessType::Read) << "({"sv << nl(classDecl);
10077 if (!builtins.empty()) { 10073 if (!builtinFields.empty()) {
10078 _buf << join(builtins) << ',' << nl(classDecl); 10074 str_list builtinItems;
10075 for (auto& field : builtinFields) {
10076 auto [item, newLine, isComment] = std::move(field);
10077 bool needComma = !isComment;
10078 if (needComma) {
10079 builtinItems.emplace_back(item + ',' + newLine);
10080 } else {
10081 builtinItems.emplace_back(item + newLine);
10082 }
10083 }
10084 _buf << join(builtinItems);
10079 } else { 10085 } else {
10080 if (extend) { 10086 if (extend) {
10081 _buf << indent(1) << "__init = function(self, ...)"sv << nl(classDecl); 10087 _buf << indent(1) << "__init = function(self, ...)"sv << nl(classDecl);
@@ -10122,10 +10128,10 @@ private:
10122 _buf << indent(1) << "end"sv << nl(classDecl); 10128 _buf << indent(1) << "end"sv << nl(classDecl);
10123 _buf << indent() << "})"sv << nl(classDecl); 10129 _buf << indent() << "})"sv << nl(classDecl);
10124 _buf << indent() << baseVar << ".__class = "sv << classVar << nl(classDecl); 10130 _buf << indent() << baseVar << ".__class = "sv << classVar << nl(classDecl);
10125 if (!statements.empty()) { 10131 if (!initStatements.empty()) {
10126 _buf << indent() << "local self = "sv << classVar << ';' << nl(classDecl); 10132 _buf << indent() << "local self = "sv << classVar << ';' << nl(classDecl);
10127 } 10133 }
10128 _buf << join(statements); 10134 _buf << join(initStatements);
10129 if (extend) { 10135 if (extend) {
10130 _buf << indent() << "if "sv << parentVar << ".__inherited then"sv << nl(classDecl); 10136 _buf << indent() << "if "sv << parentVar << ".__inherited then"sv << nl(classDecl);
10131 _buf << indent(1) << parentVar << ".__inherited("sv << parentVar << ", "sv << classVar << ")"sv << nl(classDecl); 10137 _buf << indent(1) << parentVar << ".__inherited("sv << parentVar << ", "sv << classVar << ")"sv << nl(classDecl);