diff options
author | Li Jin <dragon-fly@qq.com> | 2021-03-08 21:02:05 +0800 |
---|---|---|
committer | Li Jin <dragon-fly@qq.com> | 2021-03-08 21:02:05 +0800 |
commit | 8acb48264d3ae87e5cdae2fea4207be22cf08a97 (patch) | |
tree | 8f260c52388be52c9fd1b5b9d262300b21771ca8 /src | |
parent | 34326185b0aaf63c0af8b0e8a07f928aa5a74eaf (diff) | |
download | yuescript-8acb48264d3ae87e5cdae2fea4207be22cf08a97.tar.gz yuescript-8acb48264d3ae87e5cdae2fea4207be22cf08a97.tar.bz2 yuescript-8acb48264d3ae87e5cdae2fea4207be22cf08a97.zip |
add new syntax for issue #41. fix a issue for destructure syntax with TableBlock. try fix luarocks installing problem again for issue #42.
Diffstat (limited to 'src')
-rw-r--r-- | src/yuescript/ast.hpp | 2 | ||||
-rw-r--r-- | src/yuescript/yue_ast.h | 2 | ||||
-rw-r--r-- | src/yuescript/yue_compiler.cpp | 188 | ||||
-rw-r--r-- | src/yuescript/yue_parser.cpp | 4 |
4 files changed, 124 insertions, 72 deletions
diff --git a/src/yuescript/ast.hpp b/src/yuescript/ast.hpp index eb5cd69..162a82e 100644 --- a/src/yuescript/ast.hpp +++ b/src/yuescript/ast.hpp | |||
@@ -420,7 +420,7 @@ public: | |||
420 | return false; | 420 | return false; |
421 | } | 421 | } |
422 | 422 | ||
423 | const node_container& objects() const { | 423 | const node_container& objects() const { |
424 | return m_objects; | 424 | return m_objects; |
425 | } | 425 | } |
426 | 426 | ||
diff --git a/src/yuescript/yue_ast.h b/src/yuescript/yue_ast.h index b673eb3..96968c9 100644 --- a/src/yuescript/yue_ast.h +++ b/src/yuescript/yue_ast.h | |||
@@ -431,7 +431,7 @@ AST_NODE(meta_variable_pair) | |||
431 | AST_END(meta_variable_pair) | 431 | AST_END(meta_variable_pair) |
432 | 432 | ||
433 | AST_NODE(meta_normal_pair) | 433 | AST_NODE(meta_normal_pair) |
434 | ast_sel<true, Name_t, Exp_t> key; | 434 | ast_sel<false, Name_t, Exp_t> key; |
435 | ast_sel<true, Exp_t, TableBlock_t> value; | 435 | ast_sel<true, Exp_t, TableBlock_t> value; |
436 | AST_MEMBER(meta_normal_pair, &key, &value) | 436 | AST_MEMBER(meta_normal_pair, &key, &value) |
437 | AST_END(meta_normal_pair) | 437 | AST_END(meta_normal_pair) |
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp index a958462..e8d028d 100644 --- a/src/yuescript/yue_compiler.cpp +++ b/src/yuescript/yue_compiler.cpp | |||
@@ -59,7 +59,7 @@ inline std::string s(std::string_view sv) { | |||
59 | return std::string(sv); | 59 | return std::string(sv); |
60 | } | 60 | } |
61 | 61 | ||
62 | const std::string_view version = "0.7.1"sv; | 62 | const std::string_view version = "0.7.2"sv; |
63 | const std::string_view extension = "yue"sv; | 63 | const std::string_view extension = "yue"sv; |
64 | 64 | ||
65 | class YueCompilerImpl { | 65 | class YueCompilerImpl { |
@@ -1366,19 +1366,32 @@ private: | |||
1366 | 1366 | ||
1367 | std::list<DestructItem> destructFromExp(ast_node* node) { | 1367 | std::list<DestructItem> destructFromExp(ast_node* node) { |
1368 | const node_container* tableItems = nullptr; | 1368 | const node_container* tableItems = nullptr; |
1369 | if (ast_is<Exp_t>(node)) { | 1369 | switch (node->getId()) { |
1370 | auto item = singleValueFrom(node)->item.get(); | 1370 | case id<Exp_t>(): { |
1371 | if (!item) throw std::logic_error(_info.errorMessage("invalid destructure value"sv, node)); | 1371 | auto item = singleValueFrom(node)->item.get(); |
1372 | auto tbA = item->getByPath<TableLit_t>(); | 1372 | if (!item) throw std::logic_error(_info.errorMessage("invalid destructure value"sv, node)); |
1373 | if (tbA) { | 1373 | auto tbA = item->getByPath<TableLit_t>(); |
1374 | tableItems = &tbA->values.objects(); | 1374 | if (tbA) { |
1375 | } else { | 1375 | tableItems = &tbA->values.objects(); |
1376 | auto tbB = ast_cast<simple_table_t>(item); | 1376 | } else { |
1377 | if (tbB) tableItems = &tbB->pairs.objects(); | 1377 | auto tbB = ast_cast<simple_table_t>(item); |
1378 | if (tbB) tableItems = &tbB->pairs.objects(); | ||
1379 | } | ||
1380 | break; | ||
1381 | } | ||
1382 | case id<TableBlock_t>(): { | ||
1383 | auto table = ast_cast<TableBlock_t>(node); | ||
1384 | tableItems = &table->values.objects(); | ||
1385 | break; | ||
1378 | } | 1386 | } |
1379 | } else if (auto table = ast_cast<TableBlock_t>(node)) { | 1387 | case id<TableBlockIndent_t>(): { |
1380 | tableItems = &table->values.objects(); | 1388 | auto table = ast_cast<TableBlockIndent_t>(node); |
1389 | tableItems = &table->values.objects(); | ||
1390 | break; | ||
1391 | } | ||
1392 | default: YUEE("AST node mismatch", node); break; | ||
1381 | } | 1393 | } |
1394 | if (!tableItems) throw std::logic_error(_info.errorMessage("invalid destructure value"sv, node)); | ||
1382 | std::list<DestructItem> pairs; | 1395 | std::list<DestructItem> pairs; |
1383 | int index = 0; | 1396 | int index = 0; |
1384 | for (auto pair : *tableItems) { | 1397 | for (auto pair : *tableItems) { |
@@ -1412,7 +1425,7 @@ private: | |||
1412 | pairs.push_back({ | 1425 | pairs.push_back({ |
1413 | isVariable, | 1426 | isVariable, |
1414 | varName, | 1427 | varName, |
1415 | s("["sv) + std::to_string(index) + s("]"sv) | 1428 | '[' + std::to_string(index) + ']' |
1416 | }); | 1429 | }); |
1417 | } | 1430 | } |
1418 | break; | 1431 | break; |
@@ -1429,23 +1442,29 @@ private: | |||
1429 | } | 1442 | } |
1430 | case id<normal_pair_t>(): { | 1443 | case id<normal_pair_t>(): { |
1431 | auto np = static_cast<normal_pair_t*>(pair); | 1444 | auto np = static_cast<normal_pair_t*>(pair); |
1432 | auto key = np->key->getByPath<Name_t>(); | 1445 | std::string keyName; |
1433 | if (!key) throw std::logic_error(_info.errorMessage("invalid key for destructure"sv, np)); | 1446 | if (np->key) { |
1447 | auto key = np->key->getByPath<Name_t>(); | ||
1448 | if (!key) throw std::logic_error(_info.errorMessage("invalid key for destructure"sv, np)); | ||
1449 | keyName = _parser.toString(key); | ||
1450 | if (Keywords.find(keyName) != Keywords.end()) { | ||
1451 | keyName = s("[\""sv) + keyName + s("\"]"sv); | ||
1452 | } else { | ||
1453 | keyName = s("."sv) + keyName; | ||
1454 | } | ||
1455 | } | ||
1434 | if (auto exp = np->value.as<Exp_t>()) { | 1456 | if (auto exp = np->value.as<Exp_t>()) { |
1435 | if (!isAssignable(exp)) throw std::logic_error(_info.errorMessage("can't destructure value"sv, exp)); | 1457 | if (!isAssignable(exp)) throw std::logic_error(_info.errorMessage("can't destructure value"sv, exp)); |
1436 | auto item = singleValueFrom(exp)->item.get(); | 1458 | auto item = singleValueFrom(exp)->item.get(); |
1437 | if (ast_is<simple_table_t>(item) || | 1459 | if (ast_is<simple_table_t>(item) || |
1438 | item->getByPath<TableLit_t>()) { | 1460 | item->getByPath<TableLit_t>()) { |
1439 | auto subPairs = destructFromExp(exp); | 1461 | auto subPairs = destructFromExp(exp); |
1440 | auto name = _parser.toString(key); | ||
1441 | for (auto& p : subPairs) { | 1462 | for (auto& p : subPairs) { |
1442 | if (Keywords.find(name) != Keywords.end()) { | 1463 | pairs.push_back({ |
1443 | pairs.push_back({p.isVariable, p.name, | 1464 | p.isVariable, |
1444 | s("[\""sv) + name + s("\"]"sv) + p.structure}); | 1465 | p.name, |
1445 | } else { | 1466 | keyName + p.structure |
1446 | pairs.push_back({p.isVariable, p.name, | 1467 | }); |
1447 | s("."sv) + name + p.structure}); | ||
1448 | } | ||
1449 | } | 1468 | } |
1450 | } else { | 1469 | } else { |
1451 | bool lintGlobal = _config.lintGlobalVariable; | 1470 | bool lintGlobal = _config.lintGlobalVariable; |
@@ -1458,32 +1477,39 @@ private: | |||
1458 | varName = std::move(temp.back()); | 1477 | varName = std::move(temp.back()); |
1459 | } | 1478 | } |
1460 | _config.lintGlobalVariable = lintGlobal; | 1479 | _config.lintGlobalVariable = lintGlobal; |
1461 | auto name = _parser.toString(key); | 1480 | pairs.push_back({ |
1462 | if (Keywords.find(name) != Keywords.end()) { | 1481 | isVariable, |
1463 | pairs.push_back({ | 1482 | varName, |
1464 | isVariable, | 1483 | keyName |
1465 | varName, | 1484 | }); |
1466 | s("[\""sv) + name + s("\"]"sv) | ||
1467 | }); | ||
1468 | } else { | ||
1469 | pairs.push_back({ | ||
1470 | isVariable, | ||
1471 | varName, | ||
1472 | s("."sv) + name | ||
1473 | }); | ||
1474 | } | ||
1475 | } | 1485 | } |
1476 | break; | 1486 | break; |
1477 | } | 1487 | } |
1478 | if (np->value.is<TableBlock_t>()) { | 1488 | if (np->value.is<TableBlock_t>()) { |
1479 | auto subPairs = destructFromExp(pair); | 1489 | auto subPairs = destructFromExp(np->value); |
1480 | for (auto& p : subPairs) { | 1490 | for (auto& p : subPairs) { |
1481 | pairs.push_back({p.isVariable, p.name, | 1491 | pairs.push_back({ |
1482 | s("."sv) + _parser.toString(key) + p.structure}); | 1492 | p.isVariable, |
1493 | p.name, | ||
1494 | keyName + p.structure | ||
1495 | }); | ||
1483 | } | 1496 | } |
1484 | } | 1497 | } |
1485 | break; | 1498 | break; |
1486 | } | 1499 | } |
1500 | case id<TableBlockIndent_t>(): { | ||
1501 | auto tb = static_cast<TableBlockIndent_t*>(pair); | ||
1502 | ++index; | ||
1503 | auto subPairs = destructFromExp(tb); | ||
1504 | for (auto& p : subPairs) { | ||
1505 | pairs.push_back({ | ||
1506 | p.isVariable, | ||
1507 | p.name, | ||
1508 | '[' + std::to_string(index) + ']' + p.structure | ||
1509 | }); | ||
1510 | } | ||
1511 | break; | ||
1512 | } | ||
1487 | default: YUEE("AST node mismatch", pair); break; | 1513 | default: YUEE("AST node mismatch", pair); break; |
1488 | } | 1514 | } |
1489 | } | 1515 | } |
@@ -1498,9 +1524,10 @@ private: | |||
1498 | auto exprs = assignment->expList->exprs.objects(); | 1524 | auto exprs = assignment->expList->exprs.objects(); |
1499 | auto values = assignment->action.to<Assign_t>()->values.objects(); | 1525 | auto values = assignment->action.to<Assign_t>()->values.objects(); |
1500 | size_t size = std::max(exprs.size(), values.size()); | 1526 | size_t size = std::max(exprs.size(), values.size()); |
1501 | ast_ptr<false, Exp_t> var; | 1527 | ast_list<false, ast_node> cache; |
1502 | if (exprs.size() < size) { | 1528 | if (exprs.size() < size) { |
1503 | var = toAst<Exp_t>("_"sv, x); | 1529 | auto var = toAst<Exp_t>("_"sv, x); |
1530 | cache.push_back(var); | ||
1504 | while (exprs.size() < size) exprs.emplace_back(var); | 1531 | while (exprs.size() < size) exprs.emplace_back(var); |
1505 | } | 1532 | } |
1506 | ast_ptr<false, Exp_t> nullNode; | 1533 | ast_ptr<false, Exp_t> nullNode; |
@@ -1551,18 +1578,20 @@ private: | |||
1551 | case id<meta_normal_pair_t>(): { | 1578 | case id<meta_normal_pair_t>(): { |
1552 | auto mp = static_cast<meta_normal_pair_t*>(item); | 1579 | auto mp = static_cast<meta_normal_pair_t*>(item); |
1553 | auto newPair = item->new_ptr<normal_pair_t>(); | 1580 | auto newPair = item->new_ptr<normal_pair_t>(); |
1554 | switch (mp->key->getId()) { | 1581 | if (mp->key) { |
1555 | case id<Name_t>(): { | 1582 | switch (mp->key->getId()) { |
1556 | auto key = _parser.toString(mp->key); | 1583 | case id<Name_t>(): { |
1557 | _buf << "__"sv << key; | 1584 | auto key = _parser.toString(mp->key); |
1558 | auto newKey = toAst<KeyName_t>(clearBuf(), mp->key); | 1585 | _buf << "__"sv << key; |
1559 | newPair->key.set(newKey); | 1586 | auto newKey = toAst<KeyName_t>(clearBuf(), mp->key); |
1560 | break; | 1587 | newPair->key.set(newKey); |
1588 | break; | ||
1589 | } | ||
1590 | case id<Exp_t>(): | ||
1591 | newPair->key.set(mp->key); | ||
1592 | break; | ||
1593 | default: YUEE("AST node mismatch", mp->key); break; | ||
1561 | } | 1594 | } |
1562 | case id<Exp_t>(): | ||
1563 | newPair->key.set(mp->key); | ||
1564 | break; | ||
1565 | default: YUEE("AST node mismatch", mp->key); break; | ||
1566 | } | 1595 | } |
1567 | newPair->value.set(mp->value); | 1596 | newPair->value.set(mp->value); |
1568 | subMetaDestruct->values.push_back(newPair); | 1597 | subMetaDestruct->values.push_back(newPair); |
@@ -5150,6 +5179,7 @@ private: | |||
5150 | str_list temp; | 5179 | str_list temp; |
5151 | incIndentOffset(); | 5180 | incIndentOffset(); |
5152 | auto metatable = table->new_ptr<simple_table_t>(); | 5181 | auto metatable = table->new_ptr<simple_table_t>(); |
5182 | ast_sel<false, Exp_t, TableBlock_t> metatableItem; | ||
5153 | for (auto pair : pairs) { | 5183 | for (auto pair : pairs) { |
5154 | bool isMetamethod = false; | 5184 | bool isMetamethod = false; |
5155 | switch (pair->getId()) { | 5185 | switch (pair->getId()) { |
@@ -5161,6 +5191,9 @@ private: | |||
5161 | case id<meta_variable_pair_t>(): { | 5191 | case id<meta_variable_pair_t>(): { |
5162 | isMetamethod = true; | 5192 | isMetamethod = true; |
5163 | auto mp = static_cast<meta_variable_pair_t*>(pair); | 5193 | auto mp = static_cast<meta_variable_pair_t*>(pair); |
5194 | if (metatableItem) { | ||
5195 | throw std::logic_error(_info.errorMessage("too many metatable declarations"sv, mp->name)); | ||
5196 | } | ||
5164 | auto name = _parser.toString(mp->name); | 5197 | auto name = _parser.toString(mp->name); |
5165 | _buf << "__"sv << name << ':' << name; | 5198 | _buf << "__"sv << name << ':' << name; |
5166 | auto newPair = toAst<normal_pair_t>(clearBuf(), pair); | 5199 | auto newPair = toAst<normal_pair_t>(clearBuf(), pair); |
@@ -5171,21 +5204,31 @@ private: | |||
5171 | isMetamethod = true; | 5204 | isMetamethod = true; |
5172 | auto mp = static_cast<meta_normal_pair_t*>(pair); | 5205 | auto mp = static_cast<meta_normal_pair_t*>(pair); |
5173 | auto newPair = pair->new_ptr<normal_pair_t>(); | 5206 | auto newPair = pair->new_ptr<normal_pair_t>(); |
5174 | switch (mp->key->getId()) { | 5207 | if (mp->key) { |
5175 | case id<Name_t>(): { | 5208 | if (metatableItem) { |
5176 | auto key = _parser.toString(mp->key); | 5209 | throw std::logic_error(_info.errorMessage("too many metatable declarations"sv, mp->key)); |
5177 | _buf << "__"sv << key; | ||
5178 | auto newKey = toAst<KeyName_t>(clearBuf(), mp->key); | ||
5179 | newPair->key.set(newKey); | ||
5180 | break; | ||
5181 | } | 5210 | } |
5182 | case id<Exp_t>(): | 5211 | switch (mp->key->getId()) { |
5183 | newPair->key.set(mp->key); | 5212 | case id<Name_t>(): { |
5184 | break; | 5213 | auto key = _parser.toString(mp->key); |
5185 | default: YUEE("AST node mismatch", mp->key); break; | 5214 | _buf << "__"sv << key; |
5215 | auto newKey = toAst<KeyName_t>(clearBuf(), mp->key); | ||
5216 | newPair->key.set(newKey); | ||
5217 | break; | ||
5218 | } | ||
5219 | case id<Exp_t>(): | ||
5220 | newPair->key.set(mp->key); | ||
5221 | break; | ||
5222 | default: YUEE("AST node mismatch", mp->key); break; | ||
5223 | } | ||
5224 | newPair->value.set(mp->value); | ||
5225 | metatable->pairs.push_back(newPair); | ||
5226 | } else { | ||
5227 | if (!metatable->pairs.empty()) { | ||
5228 | throw std::logic_error(_info.errorMessage("too many metatable declarations"sv, mp->value)); | ||
5229 | } | ||
5230 | metatableItem.set(mp->value); | ||
5186 | } | 5231 | } |
5187 | newPair->value.set(mp->value); | ||
5188 | metatable->pairs.push_back(newPair); | ||
5189 | break; | 5232 | break; |
5190 | } | 5233 | } |
5191 | default: YUEE("AST node mismatch", pair); break; | 5234 | default: YUEE("AST node mismatch", pair); break; |
@@ -5194,7 +5237,7 @@ private: | |||
5194 | temp.back() = indent() + temp.back() + (pair == pairs.back() ? Empty : s(","sv)) + nll(pair); | 5237 | temp.back() = indent() + temp.back() + (pair == pairs.back() ? Empty : s(","sv)) + nll(pair); |
5195 | } | 5238 | } |
5196 | } | 5239 | } |
5197 | if (metatable->pairs.empty()) { | 5240 | if (metatable->pairs.empty() && !metatableItem) { |
5198 | out.push_back(s("{"sv) + nll(table) + join(temp)); | 5241 | out.push_back(s("{"sv) + nll(table) + join(temp)); |
5199 | decIndentOffset(); | 5242 | decIndentOffset(); |
5200 | out.back() += (indent() + s("}"sv)); | 5243 | out.back() += (indent() + s("}"sv)); |
@@ -5211,7 +5254,16 @@ private: | |||
5211 | } | 5254 | } |
5212 | tabStr += ", "sv; | 5255 | tabStr += ", "sv; |
5213 | str_list tmp; | 5256 | str_list tmp; |
5214 | transform_simple_table(metatable, tmp); | 5257 | if (!metatable->pairs.empty()) { |
5258 | transform_simple_table(metatable, tmp); | ||
5259 | } else switch (metatableItem->getId()) { | ||
5260 | case id<Exp_t>(): | ||
5261 | transformExp(static_cast<Exp_t*>(metatableItem.get()), tmp, ExpUsage::Closure); | ||
5262 | break; | ||
5263 | case id<TableBlock_t>(): | ||
5264 | transformTableBlock(static_cast<TableBlock_t*>(metatableItem.get()), tmp); | ||
5265 | break; | ||
5266 | } | ||
5215 | tabStr += tmp.back(); | 5267 | tabStr += tmp.back(); |
5216 | tabStr += s(")"sv); | 5268 | tabStr += s(")"sv); |
5217 | out.push_back(tabStr); | 5269 | out.push_back(tabStr); |
diff --git a/src/yuescript/yue_parser.cpp b/src/yuescript/yue_parser.cpp index ec6c997..2234a59 100644 --- a/src/yuescript/yue_parser.cpp +++ b/src/yuescript/yue_parser.cpp | |||
@@ -328,7 +328,7 @@ YueParser::YueParser() { | |||
328 | 328 | ||
329 | unary_operator = | 329 | unary_operator = |
330 | expr('-') >> not_(set(">=") | space_one) | | 330 | expr('-') >> not_(set(">=") | space_one) | |
331 | expr('#') | | 331 | expr('#') >> not_(':') | |
332 | expr('~') >> not_(expr('=') | space_one) | | 332 | expr('~') >> not_(expr('=') | space_one) | |
333 | expr("not") >> not_(AlphaNum); | 333 | expr("not") >> not_(AlphaNum); |
334 | unary_exp = *(Space >> unary_operator) >> expo_exp; | 334 | unary_exp = *(Space >> unary_operator) >> expo_exp; |
@@ -525,7 +525,7 @@ YueParser::YueParser() { | |||
525 | 525 | ||
526 | meta_variable_pair = sym(':') >> Variable >> expr('#'); | 526 | meta_variable_pair = sym(':') >> Variable >> expr('#'); |
527 | 527 | ||
528 | meta_normal_pair = (Space >> Name | sym('[') >> Exp >> sym(']')) >> expr("#:") >> | 528 | meta_normal_pair = Space >> -(Name | symx('[') >> Exp >> sym(']')) >> expr("#:") >> |
529 | (Exp | TableBlock | +(SpaceBreak) >> Exp); | 529 | (Exp | TableBlock | +(SpaceBreak) >> Exp); |
530 | 530 | ||
531 | KeyValue = variable_pair | normal_pair | meta_variable_pair | meta_normal_pair; | 531 | KeyValue = variable_pair | normal_pair | meta_variable_pair | meta_normal_pair; |