aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2022-07-05 11:25:59 +0800
committerLi Jin <dragon-fly@qq.com>2022-07-05 11:25:59 +0800
commit3106afc2473ce12787e1fcae2e2c3a101214045d (patch)
treed85296ea11e389fcd989ed5a4d3a71add73dde02
parentce9338c540ac3397f3d15c442033a618d12c5105 (diff)
downloadyuescript-3106afc2473ce12787e1fcae2e2c3a101214045d.tar.gz
yuescript-3106afc2473ce12787e1fcae2e2c3a101214045d.tar.bz2
yuescript-3106afc2473ce12787e1fcae2e2c3a101214045d.zip
disable exporting macro from a normal module.
-rw-r--r--spec/inputs/macro-export.yue25
-rw-r--r--spec/inputs/macro.yue2
-rw-r--r--spec/outputs/macro-export.lua2
-rw-r--r--spec/outputs/macro-teal.tl2
-rw-r--r--spec/outputs/macro-todo.lua2
-rw-r--r--src/yue.cpp3
-rwxr-xr-xsrc/yuescript/yue_compiler.cpp59
-rwxr-xr-xsrc/yuescript/yue_parser.cpp7
-rwxr-xr-xsrc/yuescript/yue_parser.h2
9 files changed, 80 insertions, 24 deletions
diff --git a/spec/inputs/macro-export.yue b/spec/inputs/macro-export.yue
index d669975..22ef424 100644
--- a/spec/inputs/macro-export.yue
+++ b/spec/inputs/macro-export.yue
@@ -1,15 +1,22 @@
1$ -> package.path = "?.lua;./spec/inputs/?.lua"
2
3import "macro-todo" as $
4
5import "macro-todo" as {$, :$todo}
6
1export macro config = (debugging = true)-> 7export macro config = (debugging = true)->
2 global debugMode = debugging == "true" 8 global debugMode = debugging == "true"
3 global debugMacro = true 9 global debugMacro = true
4 "" 10 ""
5 11
6export macro showMacro = (name,res)-> 12export macro showMacro = (name, res)->
7 if debugMacro 13 if debugMacro then "
8 "do 14do
9 txt = #{res} 15 txt = #{res}
10 print '[macro '..#{name}..']' 16 print '[macro ' .. #{name} .. ']'
11 print txt 17 print txt
12 txt" 18 txt
19"
13 else 20 else
14 res 21 res
15 22
@@ -25,5 +32,7 @@ export macro assert = (cond)->
25 else 32 else
26 "#{cond}" 33 "#{cond}"
27 34
28$config! 35$ ->
36 global debugMode = true
37 global debugMacro = true
29 38
diff --git a/spec/inputs/macro.yue b/spec/inputs/macro.yue
index 37702d1..e391b9e 100644
--- a/spec/inputs/macro.yue
+++ b/spec/inputs/macro.yue
@@ -3,7 +3,7 @@ $ ->
3 3
4import "macro-export" as { 4import "macro-export" as {
5 $, -- import all macros 5 $, -- import all macros
6 $config:$myconfig, -- rename macro $config to $myconfig 6 $config: $myconfig, -- rename macro $config to $myconfig
7} 7}
8 8
9import "macro-todo" as $ 9import "macro-todo" as $
diff --git a/spec/outputs/macro-export.lua b/spec/outputs/macro-export.lua
deleted file mode 100644
index b5a63f8..0000000
--- a/spec/outputs/macro-export.lua
+++ /dev/null
@@ -1,2 +0,0 @@
1local _module_0 = { }
2return _module_0
diff --git a/spec/outputs/macro-teal.tl b/spec/outputs/macro-teal.tl
deleted file mode 100644
index b5a63f8..0000000
--- a/spec/outputs/macro-teal.tl
+++ /dev/null
@@ -1,2 +0,0 @@
1local _module_0 = { }
2return _module_0
diff --git a/spec/outputs/macro-todo.lua b/spec/outputs/macro-todo.lua
deleted file mode 100644
index b5a63f8..0000000
--- a/spec/outputs/macro-todo.lua
+++ /dev/null
@@ -1,2 +0,0 @@
1local _module_0 = { }
2return _module_0
diff --git a/src/yue.cpp b/src/yue.cpp
index 04b7099..96649c4 100644
--- a/src/yue.cpp
+++ b/src/yue.cpp
@@ -498,6 +498,9 @@ int main(int narg, const char** args) {
498 if (!targetPath.empty()) { 498 if (!targetPath.empty()) {
499 fs::create_directories(targetFile.parent_path()); 499 fs::create_directories(targetFile.parent_path());
500 } 500 }
501 if (result.codes.empty()) {
502 return std::tuple{0, targetFile.string(), std::string("Built "sv) + file.first + '\n'};
503 }
501 std::ofstream output(targetFile, std::ios::trunc | std::ios::out); 504 std::ofstream output(targetFile, std::ios::trunc | std::ios::out);
502 if (output) { 505 if (output) {
503 const auto& codes = result.codes; 506 const auto& codes = result.codes;
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp
index 3a4ef8c..84cbf37 100755
--- a/src/yuescript/yue_compiler.cpp
+++ b/src/yuescript/yue_compiler.cpp
@@ -56,7 +56,7 @@ using namespace parserlib;
56 56
57typedef std::list<std::string> str_list; 57typedef std::list<std::string> str_list;
58 58
59const std::string_view version = "0.11.1"sv; 59const std::string_view version = "0.12.0"sv;
60const std::string_view extension = "yue"sv; 60const std::string_view extension = "yue"sv;
61 61
62class YueCompilerImpl { 62class YueCompilerImpl {
@@ -104,19 +104,55 @@ public:
104 DEFER(clear()); 104 DEFER(clear());
105 if (_info.node) { 105 if (_info.node) {
106 try { 106 try {
107 auto block = _info.node.to<File_t>()->block.get();
108 if (_info.exportMacro) {
109 for (auto _stmt : block->statements.objects()) {
110 auto stmt = static_cast<Statement_t*>(_stmt);
111 switch (stmt->content->getId()) {
112 case id<MacroInPlace_t>():
113 case id<Macro_t>():
114 break;
115 case id<Import_t>():
116 case id<Export_t>():
117 if (auto importNode = stmt->content.as<Import_t>()) {
118 if (auto importAs = importNode->content.as<ImportAs_t>()) {
119 if (importAs->target.is<import_all_macro_t>()) {
120 break;
121 } else if (auto tab = importAs->target.as<ImportTabLit_t>()) {
122 bool macroImportingOnly = true;
123 for (auto item : tab->items.objects()) {
124 if (!ast_is<
125 MacroName_t,
126 macro_name_pair_t,
127 import_all_macro_t>(item)) {
128 macroImportingOnly = false;
129 }
130 }
131 if (macroImportingOnly) break;
132 }
133 }
134 } else if (auto exportNode = stmt->content.as<Export_t>()) {
135 if (exportNode->target.is<Macro_t>()) break;
136 }
137 default:
138 throw std::logic_error(_info.errorMessage("macro exporting module only accepts macro definition, macro importing and macro expansion in place", stmt));
139 break;
140 }
141 }
142 }
107 str_list out; 143 str_list out;
108 pushScope(); 144 pushScope();
109 _enableReturn.push(_info.moduleName.empty()); 145 _enableReturn.push(_info.moduleName.empty());
110 _varArgs.push({true, false}); 146 _varArgs.push({true, false});
111 transformBlock(_info.node.to<File_t>()->block, out, 147 transformBlock(block, out,
112 config.implicitReturnRoot ? ExpUsage::Return : ExpUsage::Common, 148 config.implicitReturnRoot ? ExpUsage::Return : ExpUsage::Common,
113 nullptr, true); 149 nullptr, true);
114 popScope(); 150 popScope();
115 if (config.lintGlobalVariable) { 151 if (config.lintGlobalVariable) {
116 globals = std::make_unique<GlobalVars>(); 152 globals = std::make_unique<GlobalVars>();
117 for (const auto& var : _globals) { 153 for (const auto& var : _globals) {
118 int line,col; 154 int line, col;
119 std::tie(line,col) = var.second; 155 std::tie(line, col) = var.second;
120 globals->push_back({var.first, line, col}); 156 globals->push_back({var.first, line, col});
121 } 157 }
122 } 158 }
@@ -205,7 +241,7 @@ private:
205 }; 241 };
206 std::stack<ContinueVar> _continueVars; 242 std::stack<ContinueVar> _continueVars;
207 std::list<std::unique_ptr<input>> _codeCache; 243 std::list<std::unique_ptr<input>> _codeCache;
208 std::unordered_map<std::string,std::pair<int,int>> _globals; 244 std::unordered_map<std::string,std::pair<int, int>> _globals;
209 std::ostringstream _buf; 245 std::ostringstream _buf;
210 std::ostringstream _joinBuf; 246 std::ostringstream _joinBuf;
211 const std::string _newLine = "\n"; 247 const std::string _newLine = "\n";
@@ -286,7 +322,7 @@ private:
286 } 322 }
287 } 323 }
288 decltype(_scopes.back().allows.get()) allows = nullptr; 324 decltype(_scopes.back().allows.get()) allows = nullptr;
289 for (auto it = _scopes.rbegin(); it != _scopes.rend(); ++it) { 325 for (auto it = _scopes.rbegin(); it != _scopes.rend(); ++it) {
290 if (it->allows) allows = it->allows.get(); 326 if (it->allows) allows = it->allows.get();
291 } 327 }
292 bool checkShadowScopeOnly = false; 328 bool checkShadowScopeOnly = false;
@@ -1281,6 +1317,13 @@ private:
1281 temp.push_back(clearBuf()); 1317 temp.push_back(clearBuf());
1282 } else if (ast_is<table_appending_op_t>(chainValue->items.back())) { 1318 } else if (ast_is<table_appending_op_t>(chainValue->items.back())) {
1283 chainValue->items.pop_back(); 1319 chainValue->items.pop_back();
1320 if (chainValue->items.empty()) {
1321 if (_withVars.empty()) {
1322 throw std::logic_error(_info.errorMessage("short table appending must be called within a with block"sv, x));
1323 } else {
1324 chainValue->items.push_back(toAst<Callable_t>(_withVars.top(), chainValue));
1325 }
1326 }
1284 auto varName = singleVariableFrom(chainValue); 1327 auto varName = singleVariableFrom(chainValue);
1285 bool isScoped = false; 1328 bool isScoped = false;
1286 if (varName.empty() || !isLocal(varName)) { 1329 if (varName.empty() || !isLocal(varName)) {
@@ -3045,7 +3088,7 @@ private:
3045 } 3088 }
3046 } 3089 }
3047 } 3090 }
3048 if (isRoot && !_info.moduleName.empty()) { 3091 if (isRoot && !_info.moduleName.empty() && !_info.exportMacro) {
3049 block->statements.push_front(toAst<Statement_t>(_info.moduleName + (_info.exportDefault ? "=nil"s : "={}"s), block)); 3092 block->statements.push_front(toAst<Statement_t>(_info.moduleName + (_info.exportDefault ? "=nil"s : "={}"s), block));
3050 } 3093 }
3051 switch (usage) { 3094 switch (usage) {
@@ -3125,7 +3168,7 @@ private:
3125 } else { 3168 } else {
3126 out.push_back(Empty); 3169 out.push_back(Empty);
3127 } 3170 }
3128 if (isRoot && !_info.moduleName.empty()) { 3171 if (isRoot && !_info.moduleName.empty() && !_info.exportMacro) {
3129 out.back().append(indent() + "return "s + _info.moduleName + nlr(block)); 3172 out.back().append(indent() + "return "s + _info.moduleName + nlr(block));
3130 } 3173 }
3131 } 3174 }
diff --git a/src/yuescript/yue_parser.cpp b/src/yuescript/yue_parser.cpp
index 5c42963..78b4713 100755
--- a/src/yuescript/yue_parser.cpp
+++ b/src/yuescript/yue_parser.cpp
@@ -532,7 +532,11 @@ YueParser::YueParser() {
532 return true; 532 return true;
533 } 533 }
534 }) >> ExpList >> -Assign) 534 }) >> ExpList >> -Assign)
535 | Space >> Macro) >> not_(Space >> statement_appendix); 535 | Space >> pl::user(Macro, [](const item_t& item) {
536 State* st = reinterpret_cast<State*>(item.user_data);
537 st->exportMacro = true;
538 return true;
539 })) >> not_(Space >> statement_appendix);
536 540
537 variable_pair = sym(':') >> Variable >> not_('#'); 541 variable_pair = sym(':') >> Variable >> not_('#');
538 542
@@ -664,6 +668,7 @@ ParseInfo YueParser::parse(std::string_view codes, rule& r) {
664 if (state.exportCount > 0) { 668 if (state.exportCount > 0) {
665 res.moduleName = std::move(state.moduleName); 669 res.moduleName = std::move(state.moduleName);
666 res.exportDefault = state.exportDefault; 670 res.exportDefault = state.exportDefault;
671 res.exportMacro = state.exportMacro;
667 } 672 }
668 } catch (const std::logic_error& err) { 673 } catch (const std::logic_error& err) {
669 res.error = err.what(); 674 res.error = err.what();
diff --git a/src/yuescript/yue_parser.h b/src/yuescript/yue_parser.h
index 1532adf..eea3027 100755
--- a/src/yuescript/yue_parser.h
+++ b/src/yuescript/yue_parser.h
@@ -28,6 +28,7 @@ struct ParseInfo {
28 std::string error; 28 std::string error;
29 std::unique_ptr<input> codes; 29 std::unique_ptr<input> codes;
30 bool exportDefault = false; 30 bool exportDefault = false;
31 bool exportMacro = false;
31 std::string moduleName; 32 std::string moduleName;
32 std::string errorMessage(std::string_view msg, const input_range* loc) const; 33 std::string errorMessage(std::string_view msg, const input_range* loc) const;
33}; 34};
@@ -72,6 +73,7 @@ protected:
72 indents.push(0); 73 indents.push(0);
73 } 74 }
74 bool exportDefault = false; 75 bool exportDefault = false;
76 bool exportMacro = false;
75 int exportCount = 0; 77 int exportCount = 0;
76 int moduleFix = 0; 78 int moduleFix = 0;
77 size_t stringOpen = 0; 79 size_t stringOpen = 0;