diff options
| author | Li Jin <dragon-fly@qq.com> | 2017-07-19 11:05:45 +0800 |
|---|---|---|
| committer | Li Jin <dragon-fly@qq.com> | 2017-07-19 11:05:45 +0800 |
| commit | 65dd230959dbab99b52b99fd807534c254fb4ed9 (patch) | |
| tree | fb5b2718be96bf1f67bf8b015fcc8e2b1dfd5d7e /MoonParser/main.cpp | |
| parent | 2531792fa8da2a2f2ae218c43937f88028d26888 (diff) | |
| download | yuescript-65dd230959dbab99b52b99fd807534c254fb4ed9.tar.gz yuescript-65dd230959dbab99b52b99fd807534c254fb4ed9.tar.bz2 yuescript-65dd230959dbab99b52b99fd807534c254fb4ed9.zip | |
add codes.
Diffstat (limited to 'MoonParser/main.cpp')
| -rw-r--r-- | MoonParser/main.cpp | 1652 |
1 files changed, 0 insertions, 1652 deletions
diff --git a/MoonParser/main.cpp b/MoonParser/main.cpp deleted file mode 100644 index d0ef5c8..0000000 --- a/MoonParser/main.cpp +++ /dev/null | |||
| @@ -1,1652 +0,0 @@ | |||
| 1 | #include <iostream> | ||
| 2 | #include <string> | ||
| 3 | #include <codecvt> | ||
| 4 | #include <unordered_set> | ||
| 5 | #include <stack> | ||
| 6 | #include <algorithm> | ||
| 7 | #include <sstream> | ||
| 8 | #include <vector> | ||
| 9 | #include "parserlib.hpp" | ||
| 10 | using namespace parserlib; | ||
| 11 | |||
| 12 | template<class Facet> | ||
| 13 | struct deletable_facet : Facet | ||
| 14 | { | ||
| 15 | template<class ...Args> | ||
| 16 | deletable_facet(Args&& ...args): Facet(std::forward<Args>(args)...) {} | ||
| 17 | ~deletable_facet() {} | ||
| 18 | }; | ||
| 19 | typedef std::wstring_convert<deletable_facet<std::codecvt<char32_t, char, std::mbstate_t>>, char32_t> Converter; | ||
| 20 | |||
| 21 | static inline std::string& trim(std::string& s) | ||
| 22 | { | ||
| 23 | s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](unsigned char ch) | ||
| 24 | { | ||
| 25 | return !std::isspace(ch); | ||
| 26 | })); | ||
| 27 | s.erase(std::find_if(s.rbegin(), s.rend(), [](unsigned char ch) | ||
| 28 | { | ||
| 29 | return !std::isspace(ch); | ||
| 30 | }).base(), s.end()); | ||
| 31 | return s; | ||
| 32 | } | ||
| 33 | |||
| 34 | #define p(expr) user(expr, [](const item_t& item) \ | ||
| 35 | { \ | ||
| 36 | stringstream stream; \ | ||
| 37 | for (input_it i = item.begin; i != item.end; ++i) stream << static_cast<char>(*i); \ | ||
| 38 | cout << #expr << ": [" << stream.str() << "]\n"; \ | ||
| 39 | return true; \ | ||
| 40 | }) | ||
| 41 | |||
| 42 | struct State | ||
| 43 | { | ||
| 44 | State() | ||
| 45 | { | ||
| 46 | indents.push(0); | ||
| 47 | stringOpen = -1; | ||
| 48 | } | ||
| 49 | std::stringstream buffer; | ||
| 50 | size_t stringOpen; | ||
| 51 | std::stack<int> indents; | ||
| 52 | std::stack<bool> doStack; | ||
| 53 | std::unordered_set<std::string> keywords = { | ||
| 54 | "and", "while", "else", "using", "continue", | ||
| 55 | "local", "not", "then", "return", "from", | ||
| 56 | "extends", "for", "do", "or", "export", | ||
| 57 | "class", "in", "unless", "when", "elseif", | ||
| 58 | "switch", "break", "if", "with", "import" | ||
| 59 | }; | ||
| 60 | }; | ||
| 61 | |||
| 62 | class Data | ||
| 63 | { | ||
| 64 | public: | ||
| 65 | Data() | ||
| 66 | { | ||
| 67 | indent = 0; | ||
| 68 | callerStack.push(false); | ||
| 69 | } | ||
| 70 | |||
| 71 | Converter conv; | ||
| 72 | std::stringstream temp; | ||
| 73 | std::stringstream buffer; | ||
| 74 | std::vector<int> lineTable; | ||
| 75 | std::stack<bool> callerStack; | ||
| 76 | std::stack<std::string> withStack; | ||
| 77 | |||
| 78 | void beginLine(int line = -1) | ||
| 79 | { | ||
| 80 | for (int i = 0; i < indent; i++) | ||
| 81 | { | ||
| 82 | buffer << '\t'; | ||
| 83 | } | ||
| 84 | lineTable.push_back(line == -1 ? lineTable.back() : line); | ||
| 85 | } | ||
| 86 | |||
| 87 | void endLine() | ||
| 88 | { | ||
| 89 | buffer << '\n'; | ||
| 90 | } | ||
| 91 | |||
| 92 | int indent; | ||
| 93 | struct Scope | ||
| 94 | { | ||
| 95 | Scope() | ||
| 96 | { | ||
| 97 | localObjIndex = 0; | ||
| 98 | localFnIndex = 0; | ||
| 99 | localBaseIndex = 0; | ||
| 100 | localWithIndex = 0; | ||
| 101 | } | ||
| 102 | int localObjIndex; | ||
| 103 | int localFnIndex; | ||
| 104 | int localBaseIndex; | ||
| 105 | int localWithIndex; | ||
| 106 | std::vector<std::string> locals; | ||
| 107 | }; | ||
| 108 | |||
| 109 | std::string getNewLocalObj() | ||
| 110 | { | ||
| 111 | temp << "_obj_" << scope().localObjIndex; | ||
| 112 | scope().localObjIndex++; | ||
| 113 | std::string local = temp.str(); | ||
| 114 | temp.str(""); | ||
| 115 | temp.clear(); | ||
| 116 | return local; | ||
| 117 | } | ||
| 118 | |||
| 119 | std::string getNewLocalFn() | ||
| 120 | { | ||
| 121 | temp << "_fn_" << scope().localObjIndex; | ||
| 122 | scope().localFnIndex++; | ||
| 123 | std::string local = temp.str(); | ||
| 124 | temp.str(""); | ||
| 125 | temp.clear(); | ||
| 126 | return local; | ||
| 127 | } | ||
| 128 | |||
| 129 | std::string getNewLocalBase() | ||
| 130 | { | ||
| 131 | temp << "_base_" << scope().localBaseIndex; | ||
| 132 | scope().localBaseIndex++; | ||
| 133 | std::string local = temp.str(); | ||
| 134 | temp.str(""); | ||
| 135 | temp.clear(); | ||
| 136 | return local; | ||
| 137 | } | ||
| 138 | |||
| 139 | bool isLocal(const std::string& var) | ||
| 140 | { | ||
| 141 | return _localVars.find(var) != _localVars.end(); | ||
| 142 | } | ||
| 143 | |||
| 144 | void putLocal(const std::string& var) | ||
| 145 | { | ||
| 146 | if (_localVars.find(var) == _localVars.end()) | ||
| 147 | { | ||
| 148 | _localVars.insert(var); | ||
| 149 | _scopeStack.top().locals.push_back(var); | ||
| 150 | } | ||
| 151 | } | ||
| 152 | |||
| 153 | void pushScope() | ||
| 154 | { | ||
| 155 | int lastWithIndex = scope().localWithIndex; | ||
| 156 | _scopeStack.emplace(); | ||
| 157 | scope().localWithIndex = lastWithIndex + 1; | ||
| 158 | indent++; | ||
| 159 | } | ||
| 160 | |||
| 161 | Scope& scope() | ||
| 162 | { | ||
| 163 | return _scopeStack.top(); | ||
| 164 | } | ||
| 165 | |||
| 166 | void popScope() | ||
| 167 | { | ||
| 168 | const auto& scope = _scopeStack.top(); | ||
| 169 | for (const auto& var : scope.locals) | ||
| 170 | { | ||
| 171 | _localVars.erase(var); | ||
| 172 | } | ||
| 173 | _scopeStack.pop(); | ||
| 174 | indent--; | ||
| 175 | } | ||
| 176 | private: | ||
| 177 | std::unordered_set<std::string> _localVars; | ||
| 178 | std::stack<Scope> _scopeStack; | ||
| 179 | }; | ||
| 180 | |||
| 181 | rule Any = any(); | ||
| 182 | rule plain_space = *set(" \t"); | ||
| 183 | rule Break = nl(-expr('\r') >> '\n'); | ||
| 184 | rule White = *(set(" \t") | Break); | ||
| 185 | rule Stop = Break | eof(); | ||
| 186 | rule Comment = "--" >> *(not_(set("\r\n")) >> Any) >> and_(Stop); | ||
| 187 | rule Indent = *set(" \t"); | ||
| 188 | rule Space = plain_space >> -Comment; | ||
| 189 | rule SomeSpace = +set(" \t") >> -Comment; | ||
| 190 | rule SpaceBreak = Space >> Break; | ||
| 191 | rule EmptyLine = SpaceBreak; | ||
| 192 | rule AlphaNum = range('a', 'z') | range('A', 'Z') | range('0', '9') | '_'; | ||
| 193 | rule _Name = (range('a', 'z') | range('A', 'Z') | '_') >> *AlphaNum; | ||
| 194 | rule SpaceName = Space >> _Name; | ||
| 195 | rule _Num = | ||
| 196 | ( | ||
| 197 | "0x" >> | ||
| 198 | +(range('0', '9') | range('a', 'f') | range('A', 'F')) >> | ||
| 199 | -(-set("uU") >> set("lL") >> set("lL")) | ||
| 200 | ) | ( | ||
| 201 | +range('0', '9') >> -set("uU") >> set("lL") >> set("lL") | ||
| 202 | ) | ( | ||
| 203 | ( | ||
| 204 | (+range('0', '9') >> -('.' >> +range('0', '9'))) | | ||
| 205 | ('.' >> +range('0', '9')) | ||
| 206 | ) >> -(set("eE") >> -expr('-') >> +range('0', '9')) | ||
| 207 | ); | ||
| 208 | rule Num = Space >> _Num; | ||
| 209 | rule Cut = false_(); | ||
| 210 | rule Seperator = true_(); | ||
| 211 | |||
| 212 | #define sym(str) (Space >> str) | ||
| 213 | #define symx(str) expr(str) | ||
| 214 | #define ensure(patt, finally) (((patt) >> (finally)) | ((finally) >> (Cut))) | ||
| 215 | #define key(str) (Space >> str >> not_(AlphaNum)) | ||
| 216 | #define opWord(str) (Space >> str >> not_(AlphaNum)) | ||
| 217 | #define op(str) (Space >> str) | ||
| 218 | |||
| 219 | rule Name = user(SpaceName, [](const item_t& item) | ||
| 220 | { | ||
| 221 | State* st = reinterpret_cast<State*>(item.user_data); | ||
| 222 | for (auto it = item.begin; it != item.end; ++it) st->buffer << static_cast<char>(*it); | ||
| 223 | std::string name; | ||
| 224 | st->buffer >> name; | ||
| 225 | st->buffer.str(""); | ||
| 226 | st->buffer.clear(); | ||
| 227 | auto it = st->keywords.find(name); | ||
| 228 | return it == st->keywords.end(); | ||
| 229 | }); | ||
| 230 | |||
| 231 | rule self = expr('@'); | ||
| 232 | rule self_name = '@' >> _Name; | ||
| 233 | rule self_class = expr("@@"); | ||
| 234 | rule self_class_name = "@@" >> _Name; | ||
| 235 | |||
| 236 | rule SelfName = Space >> (self_class_name | self_class | self_name | self); | ||
| 237 | rule KeyName = SelfName | Space >> _Name; | ||
| 238 | rule VarArg = Space >> "..."; | ||
| 239 | |||
| 240 | rule check_indent = user(Indent, [](const item_t& item) | ||
| 241 | { | ||
| 242 | int indent = 0; | ||
| 243 | for (input_it i = item.begin; i != item.end; ++i) | ||
| 244 | { | ||
| 245 | switch (*i) | ||
| 246 | { | ||
| 247 | case ' ': indent++; break; | ||
| 248 | case '\t': indent += 4; break; | ||
| 249 | } | ||
| 250 | } | ||
| 251 | State* st = reinterpret_cast<State*>(item.user_data); | ||
| 252 | return st->indents.top() == indent; | ||
| 253 | }); | ||
| 254 | rule CheckIndent = and_(check_indent); | ||
| 255 | |||
| 256 | rule advance = user(Indent, [](const item_t& item) | ||
| 257 | { | ||
| 258 | int indent = 0; | ||
| 259 | for (input_it i = item.begin; i != item.end; ++i) | ||
| 260 | { | ||
| 261 | switch (*i) | ||
| 262 | { | ||
| 263 | case ' ': indent++; break; | ||
| 264 | case '\t': indent += 4; break; | ||
| 265 | } | ||
| 266 | } | ||
| 267 | State* st = reinterpret_cast<State*>(item.user_data); | ||
| 268 | int top = st->indents.top(); | ||
| 269 | if (top != -1 && indent > top) | ||
| 270 | { | ||
| 271 | st->indents.push(indent); | ||
| 272 | return true; | ||
| 273 | } | ||
| 274 | return false; | ||
| 275 | }); | ||
| 276 | rule Advance = and_(advance); | ||
| 277 | |||
| 278 | rule push_indent = user(Indent, [](const item_t& item) | ||
| 279 | { | ||
| 280 | int indent = 0; | ||
| 281 | for (input_it i = item.begin; i != item.end; ++i) | ||
| 282 | { | ||
| 283 | switch (*i) | ||
| 284 | { | ||
| 285 | case ' ': indent++; break; | ||
| 286 | case '\t': indent += 4; break; | ||
| 287 | } | ||
| 288 | } | ||
| 289 | State* st = reinterpret_cast<State*>(item.user_data); | ||
| 290 | st->indents.push(indent); | ||
| 291 | return true; | ||
| 292 | }); | ||
| 293 | rule PushIndent = and_(push_indent); | ||
| 294 | |||
| 295 | rule PreventIndent = user(true_(), [](const item_t& item) | ||
| 296 | { | ||
| 297 | State* st = reinterpret_cast<State*>(item.user_data); | ||
| 298 | st->indents.push(-1); | ||
| 299 | return true; | ||
| 300 | }); | ||
| 301 | |||
| 302 | rule PopIndent = user(true_(), [](const item_t& item) | ||
| 303 | { | ||
| 304 | State* st = reinterpret_cast<State*>(item.user_data); | ||
| 305 | st->indents.pop(); | ||
| 306 | return true; | ||
| 307 | }); | ||
| 308 | |||
| 309 | extern rule Block; | ||
| 310 | |||
| 311 | rule InBlock = Advance >> Block >> PopIndent; | ||
| 312 | |||
| 313 | extern rule NameList; | ||
| 314 | |||
| 315 | rule local_flag = op('*') | op('^'); | ||
| 316 | rule Local = key("local") >> (local_flag | NameList); | ||
| 317 | |||
| 318 | rule colon_import_name = sym('\\') >> Name; | ||
| 319 | rule ImportName = colon_import_name | Name; | ||
| 320 | rule ImportNameList = Seperator >> *SpaceBreak >> ImportName >> *((+SpaceBreak | sym(',') >> *SpaceBreak) >> ImportName); | ||
| 321 | |||
| 322 | extern rule Exp; | ||
| 323 | |||
| 324 | rule Import = key("import") >> ImportNameList >> *SpaceBreak >> key("from") >> Exp; | ||
| 325 | rule BreakLoop = key("break") | key("continue"); | ||
| 326 | |||
| 327 | extern rule ExpListLow, ExpList, Assign; | ||
| 328 | |||
| 329 | rule Return = key("return") >> -ExpListLow; | ||
| 330 | rule WithExp = ExpList >> -Assign; | ||
| 331 | |||
| 332 | extern rule DisableDo, PopDo, Body; | ||
| 333 | |||
| 334 | rule With = key("with") >> DisableDo >> ensure(WithExp, PopDo) >> -key("do") >> Body; | ||
| 335 | rule SwitchCase = key("when") >> ExpList >> -key("then") >> Body; | ||
| 336 | rule SwitchElse = key("else") >> Body; | ||
| 337 | |||
| 338 | rule SwitchBlock = *EmptyLine >> | ||
| 339 | Advance >> Seperator >> | ||
| 340 | SwitchCase >> | ||
| 341 | *(+Break >> SwitchCase) >> | ||
| 342 | -(+Break >> SwitchElse) >> | ||
| 343 | PopIndent; | ||
| 344 | |||
| 345 | rule Switch = key("switch") >> | ||
| 346 | DisableDo >> ensure(Exp, PopDo) >> | ||
| 347 | -key("do") >> -Space >> Break >> SwitchBlock; | ||
| 348 | |||
| 349 | rule IfCond = Exp >> -Assign; | ||
| 350 | rule IfElseIf = -(Break >> *EmptyLine >> CheckIndent) >> key("elseif") >> IfCond >> -key("then") >> Body; | ||
| 351 | rule IfElse = -(Break >> *EmptyLine >> CheckIndent) >> key("else") >> Body; | ||
| 352 | rule If = key("if") >> IfCond >> -key("then") >> Body >> Seperator >> *IfElseIf >> -IfElse; | ||
| 353 | rule Unless = key("unless") >> IfCond >> -key("then") >> Body >> Seperator >> *IfElseIf >> -IfElse; | ||
| 354 | |||
| 355 | rule While = key("while") >> DisableDo >> ensure(Exp, PopDo) >> -key("do") >> Body; | ||
| 356 | |||
| 357 | rule for_step_value = sym(',') >> Exp; | ||
| 358 | rule for_args = Name >> sym('=') >> Exp >> sym(',') >> Exp >> -for_step_value; | ||
| 359 | |||
| 360 | rule For = key("for") >> DisableDo >> | ||
| 361 | ensure(for_args, PopDo) >> | ||
| 362 | -key("do") >> Body; | ||
| 363 | |||
| 364 | extern rule AssignableNameList; | ||
| 365 | |||
| 366 | rule for_in = sym('*') >> Exp | ExpList; | ||
| 367 | |||
| 368 | rule ForEach = key("for") >> AssignableNameList >> key("in") >> | ||
| 369 | DisableDo >> ensure(for_in, PopDo) >> | ||
| 370 | -key("do") >> Body; | ||
| 371 | |||
| 372 | rule Do = user(key("do") >> Body, [](const item_t& item) | ||
| 373 | { | ||
| 374 | State* st = reinterpret_cast<State*>(item.user_data); | ||
| 375 | return st->doStack.empty() || st->doStack.top(); | ||
| 376 | }); | ||
| 377 | |||
| 378 | rule DisableDo = user(true_(), [](const item_t& item) | ||
| 379 | { | ||
| 380 | State* st = reinterpret_cast<State*>(item.user_data); | ||
| 381 | st->doStack.push(false); | ||
| 382 | return true; | ||
| 383 | }); | ||
| 384 | |||
| 385 | rule PopDo = user(true_(), [](const item_t& item) | ||
| 386 | { | ||
| 387 | State* st = reinterpret_cast<State*>(item.user_data); | ||
| 388 | st->doStack.pop(); | ||
| 389 | return true; | ||
| 390 | }); | ||
| 391 | |||
| 392 | extern rule CompInner; | ||
| 393 | |||
| 394 | rule Comprehension = sym('[') >> Exp >> CompInner >> sym(']'); | ||
| 395 | rule comp_value = sym(',') >> Exp; | ||
| 396 | rule TblComprehension = sym('{') >> (Exp >> -comp_value) >> CompInner >> sym('}'); | ||
| 397 | |||
| 398 | extern rule CompForEach, CompFor, CompClause; | ||
| 399 | |||
| 400 | rule CompInner = (CompForEach | CompFor) >> Seperator >> *CompClause; | ||
| 401 | rule star_exp = sym('*') >> Exp; | ||
| 402 | rule CompForEach = key("for") >> AssignableNameList >> key("in") >> (star_exp | Exp); | ||
| 403 | rule CompFor = key("for") >> Name >> sym('=') >> Exp >> sym(',') >> Exp >> -for_step_value; | ||
| 404 | rule CompClause = CompFor | CompForEach | key("when") >> Exp; | ||
| 405 | |||
| 406 | extern rule TableBlock; | ||
| 407 | |||
| 408 | rule Assign = sym('=') >> (With | If | Switch | TableBlock | ExpListLow); | ||
| 409 | |||
| 410 | rule update_op = | ||
| 411 | sym("..=") | | ||
| 412 | sym("+=") | | ||
| 413 | sym("-=") | | ||
| 414 | sym("*=") | | ||
| 415 | sym("/=") | | ||
| 416 | sym("%=") | | ||
| 417 | sym("or=") | | ||
| 418 | sym("and=") | | ||
| 419 | sym("&=") | | ||
| 420 | sym("|=") | | ||
| 421 | sym(">>=") | | ||
| 422 | sym("<<="); | ||
| 423 | |||
| 424 | rule Update = update_op >> Exp; | ||
| 425 | |||
| 426 | rule CharOperators = Space >> set("+-*/%^><|&"); | ||
| 427 | rule WordOperators = | ||
| 428 | opWord("or") | | ||
| 429 | opWord("and") | | ||
| 430 | op("<=") | | ||
| 431 | op(">=") | | ||
| 432 | op("~=") | | ||
| 433 | op("!=") | | ||
| 434 | op("==") | | ||
| 435 | op("..") | | ||
| 436 | op("<<") | | ||
| 437 | op(">>") | | ||
| 438 | op("//"); | ||
| 439 | |||
| 440 | rule BinaryOperator = (WordOperators | CharOperators) >> *SpaceBreak; | ||
| 441 | |||
| 442 | extern rule Chain; | ||
| 443 | |||
| 444 | rule Assignable = Chain | Name | SelfName; | ||
| 445 | |||
| 446 | extern rule Value; | ||
| 447 | |||
| 448 | rule exp_op_value = BinaryOperator >> Value; | ||
| 449 | rule Exp = Value >> *exp_op_value; | ||
| 450 | |||
| 451 | extern rule Callable, InvokeArgs; | ||
| 452 | |||
| 453 | rule ChainValue = (Chain | Callable) >> -InvokeArgs; | ||
| 454 | |||
| 455 | extern rule KeyValue, String, SimpleValue; | ||
| 456 | |||
| 457 | rule simple_table = Seperator >> KeyValue >> *(sym(',') >> KeyValue); | ||
| 458 | rule Value = SimpleValue | simple_table | ChainValue | String; | ||
| 459 | |||
| 460 | extern rule LuaString; | ||
| 461 | |||
| 462 | rule single_string_inner = expr("\\'") | "\\\\" | not_(expr('\'')) >> Any; | ||
| 463 | rule SingleString = symx('\'') >> *single_string_inner >> sym('\''); | ||
| 464 | rule interp = symx("#{") >> Exp >> sym('}'); | ||
| 465 | rule double_string_plain = expr("\\\"") | "\\\\" | not_(expr('"')) >> Any; | ||
| 466 | rule double_string_inner = +(not_(interp) >> double_string_plain); | ||
| 467 | rule double_string_content = double_string_inner | interp; | ||
| 468 | rule DoubleString = symx('"') >> Seperator >> *double_string_content >> sym('"'); | ||
| 469 | rule String = Space >> (DoubleString | SingleString | LuaString); | ||
| 470 | |||
| 471 | rule lua_string_open = '[' >> *expr('=') >> '['; | ||
| 472 | rule lua_string_close = ']' >> *expr('=') >> ']'; | ||
| 473 | |||
| 474 | rule LuaStringOpen = user(lua_string_open, [](const item_t& item) | ||
| 475 | { | ||
| 476 | size_t count = std::distance(item.begin, item.end); | ||
| 477 | State* st = reinterpret_cast<State*>(item.user_data); | ||
| 478 | st->stringOpen = count; | ||
| 479 | return true; | ||
| 480 | }); | ||
| 481 | |||
| 482 | rule LuaStringClose = user(lua_string_close, [](const item_t& item) | ||
| 483 | { | ||
| 484 | size_t count = std::distance(item.begin, item.end); | ||
| 485 | State* st = reinterpret_cast<State*>(item.user_data); | ||
| 486 | return st->stringOpen == count; | ||
| 487 | }); | ||
| 488 | |||
| 489 | rule LuaStringContent = *(not_(LuaStringClose) >> (Break | Any)); | ||
| 490 | |||
| 491 | rule LuaString = user(LuaStringOpen >> -Break >> LuaStringContent >> LuaStringClose, [](const item_t& item) | ||
| 492 | { | ||
| 493 | State* st = reinterpret_cast<State*>(item.user_data); | ||
| 494 | st->stringOpen = -1; | ||
| 495 | return true; | ||
| 496 | }); | ||
| 497 | |||
| 498 | rule Parens = sym('(') >> *SpaceBreak >> Exp >> *SpaceBreak >> sym(')'); | ||
| 499 | rule Callable = Name | SelfName | VarArg | Parens; | ||
| 500 | rule FnArgsExpList = Exp >> *((Break | sym(',')) >> White >> Exp); | ||
| 501 | |||
| 502 | rule FnArgs = Seperator >> | ||
| 503 | ( | ||
| 504 | ( | ||
| 505 | symx('(') >> *SpaceBreak >> -FnArgsExpList >> *SpaceBreak >> sym(')') | ||
| 506 | ) | ( | ||
| 507 | sym('!') >> not_(expr('=')) | ||
| 508 | ) | ||
| 509 | ); | ||
| 510 | |||
| 511 | extern rule ChainItems, DotChainItem, ColonChain; | ||
| 512 | |||
| 513 | rule chain_call = (Callable | String) >> ChainItems; | ||
| 514 | rule chain_item = not_(set(".\\")) >> ChainItems; | ||
| 515 | rule chain_dot_chain = DotChainItem >> -ChainItems; | ||
| 516 | |||
| 517 | rule Chain = | ||
| 518 | chain_call | | ||
| 519 | chain_item | | ||
| 520 | Space >> (chain_dot_chain | ColonChain); | ||
| 521 | |||
| 522 | extern rule ChainItem; | ||
| 523 | |||
| 524 | rule chain_with_colon = +ChainItem >> -ColonChain; | ||
| 525 | rule ChainItems = Seperator >> (chain_with_colon | ColonChain); | ||
| 526 | |||
| 527 | extern rule Invoke, Slice; | ||
| 528 | |||
| 529 | rule Index = symx('[') >> Exp >> sym(']'); | ||
| 530 | rule ChainItem = Invoke | DotChainItem | Slice | Index; | ||
| 531 | rule DotChainItem = symx('.') >> _Name; | ||
| 532 | rule ColonChainItem = symx('\\') >> _Name; | ||
| 533 | rule invoke_chain = Invoke >> -ChainItems; | ||
| 534 | rule ColonChain = ColonChainItem >> -invoke_chain; | ||
| 535 | |||
| 536 | rule default_value = true_(); | ||
| 537 | rule Slice = | ||
| 538 | symx('[') >> | ||
| 539 | (Exp | default_value) >> | ||
| 540 | sym(',') >> | ||
| 541 | (Exp | default_value) >> | ||
| 542 | (sym(',') >> Exp | default_value) >> | ||
| 543 | sym(']'); | ||
| 544 | |||
| 545 | rule Invoke = | ||
| 546 | FnArgs | | ||
| 547 | SingleString | | ||
| 548 | DoubleString | | ||
| 549 | and_(expr('[')) >> LuaString; | ||
| 550 | |||
| 551 | extern rule TableValueList, TableLitLine; | ||
| 552 | |||
| 553 | rule TableValue = KeyValue | Exp; | ||
| 554 | |||
| 555 | rule table_lit_lines = SpaceBreak >> TableLitLine >> *(-sym(',') >> SpaceBreak >> TableLitLine) >> -sym(','); | ||
| 556 | |||
| 557 | rule TableLit = | ||
| 558 | sym('{') >> Seperator >> | ||
| 559 | -TableValueList >> | ||
| 560 | -sym(',') >> | ||
| 561 | -table_lit_lines >> | ||
| 562 | White >> sym('}'); | ||
| 563 | |||
| 564 | rule TableValueList = TableValue >> *(sym(',') >> TableValue); | ||
| 565 | |||
| 566 | rule TableLitLine = | ||
| 567 | ( | ||
| 568 | PushIndent >> (TableValueList >> PopIndent | PopIndent) | ||
| 569 | ) | ( | ||
| 570 | Space | ||
| 571 | ); | ||
| 572 | |||
| 573 | extern rule KeyValueLine; | ||
| 574 | |||
| 575 | rule TableBlockInner = Seperator >> KeyValueLine >> *(+(SpaceBreak) >> KeyValueLine); | ||
| 576 | rule TableBlock = +(SpaceBreak) >> Advance >> ensure(TableBlockInner, PopIndent); | ||
| 577 | |||
| 578 | extern rule Statement; | ||
| 579 | |||
| 580 | rule class_member_list = Seperator >> KeyValue >> *(sym(',') >> KeyValue); | ||
| 581 | rule ClassLine = CheckIndent >> (class_member_list | Statement | Exp) >> -sym(','); | ||
| 582 | rule ClassBlock = +(SpaceBreak) >> Advance >>Seperator >> ClassLine >> *(+(SpaceBreak) >> ClassLine) >> PopIndent; | ||
| 583 | |||
| 584 | rule ClassDecl = | ||
| 585 | key("class") >> not_(expr(':')) >> | ||
| 586 | -Assignable >> | ||
| 587 | -(key("extends") >> PreventIndent >> ensure(Exp, PopIndent)) >> | ||
| 588 | -ClassBlock; | ||
| 589 | |||
| 590 | rule export_values = NameList >> -(sym('=') >> ExpListLow); | ||
| 591 | rule export_op = op('*') | op('^'); | ||
| 592 | rule Export = key("export") >> (ClassDecl | export_op | export_values); | ||
| 593 | |||
| 594 | rule variable_pair = sym(':') >> not_(SomeSpace) >> Name; | ||
| 595 | |||
| 596 | rule normal_pair = | ||
| 597 | ( | ||
| 598 | KeyName | | ||
| 599 | sym('[') >> Exp >> sym(']') | | ||
| 600 | Space >> DoubleString | | ||
| 601 | Space >> SingleString | ||
| 602 | ) >> | ||
| 603 | symx(':') >> | ||
| 604 | (Exp | TableBlock | +(SpaceBreak) >> Exp); | ||
| 605 | |||
| 606 | rule KeyValue = variable_pair | normal_pair; | ||
| 607 | |||
| 608 | rule KeyValueList = KeyValue >> *(sym(',') >> KeyValue); | ||
| 609 | rule KeyValueLine = CheckIndent >> KeyValueList >> -sym(','); | ||
| 610 | |||
| 611 | rule FnArgDef = (Name | SelfName) >> -(sym('=') >> Exp); | ||
| 612 | |||
| 613 | rule FnArgDefList = Seperator >> | ||
| 614 | ( | ||
| 615 | ( | ||
| 616 | FnArgDef >> | ||
| 617 | *((sym(',') | Break) >> White >> FnArgDef) >> | ||
| 618 | -((sym(',') | Break) >> White >> VarArg) | ||
| 619 | ) | ( | ||
| 620 | VarArg | ||
| 621 | ) | ||
| 622 | ); | ||
| 623 | |||
| 624 | rule outer_var_shadow = key("using") >> (NameList | Space >> expr("nil")); | ||
| 625 | |||
| 626 | rule FnArgsDef = sym('(') >> White >> -FnArgDefList >> -outer_var_shadow >> White >> sym(')'); | ||
| 627 | rule fn_arrow = sym("->") | sym("=>"); | ||
| 628 | rule FunLit = -FnArgsDef >> fn_arrow >> -Body; | ||
| 629 | |||
| 630 | rule NameList = Seperator >> Name >> *(sym(',') >> Name); | ||
| 631 | rule NameOrDestructure = Name | TableLit; | ||
| 632 | rule AssignableNameList = Seperator >> NameOrDestructure >> *(sym(',') >> NameOrDestructure); | ||
| 633 | |||
| 634 | rule ExpList = Seperator >> Exp >> *(sym(',') >> Exp); | ||
| 635 | rule ExpListLow = Seperator >> Exp >> *((sym(',') | sym(';')) >> Exp); | ||
| 636 | |||
| 637 | rule ArgLine = CheckIndent >> Exp >> *(sym(',') >> Exp); | ||
| 638 | rule ArgBlock = Seperator >> ArgLine >> *(sym(',') >> SpaceBreak >> ArgLine) >> PopIndent; | ||
| 639 | |||
| 640 | rule invoke_args_with_table = | ||
| 641 | sym(',') >> | ||
| 642 | ( | ||
| 643 | TableBlock | | ||
| 644 | SpaceBreak >> Advance >> ArgBlock >> -TableBlock | ||
| 645 | ); | ||
| 646 | |||
| 647 | rule InvokeArgs = | ||
| 648 | not_(expr('-')) >> | ||
| 649 | ( | ||
| 650 | ExpList >> -(invoke_args_with_table | TableBlock) | | ||
| 651 | TableBlock | ||
| 652 | ); | ||
| 653 | |||
| 654 | rule const_value = key("nil") | key("true") | key("false"); | ||
| 655 | rule minus_exp = sym('-') >> not_(SomeSpace) >> Exp; | ||
| 656 | rule sharp_exp = sym('#') >> Exp; | ||
| 657 | rule tilde_exp = sym('~') >> Exp; | ||
| 658 | rule not_exp = key("not") >> Exp; | ||
| 659 | rule unary_exp = minus_exp | sharp_exp | tilde_exp | not_exp; | ||
| 660 | |||
| 661 | rule SimpleValue = | ||
| 662 | const_value | | ||
| 663 | If | Unless | Switch | With | ClassDecl | ForEach | For | While | Do | | ||
| 664 | unary_exp | | ||
| 665 | TblComprehension | TableLit | Comprehension | FunLit | Num; | ||
| 666 | |||
| 667 | rule Assignment = ExpList >> (Update | Assign); | ||
| 668 | |||
| 669 | rule if_else_line = key("if") >> Exp >> (key("else") >> Exp | default_value); | ||
| 670 | rule unless_line = key("unless") >> Exp; | ||
| 671 | |||
| 672 | rule statement_appendix = (if_else_line | unless_line | CompInner) >> Space; | ||
| 673 | rule Statement = | ||
| 674 | ( | ||
| 675 | Import | While | With | For | ForEach | | ||
| 676 | Switch | Return | Local | Export | BreakLoop | | ||
| 677 | Assignment | ExpList | ||
| 678 | ) >> Space >> | ||
| 679 | -statement_appendix; | ||
| 680 | |||
| 681 | rule Body = -Space >> Break >> *EmptyLine >> InBlock | Statement; | ||
| 682 | |||
| 683 | rule empty_line_stop = Space >> and_(Stop); | ||
| 684 | rule Line = CheckIndent >> Statement | empty_line_stop; | ||
| 685 | rule Block = Seperator >> Line >> *(+Break >> Line); | ||
| 686 | rule BlockEnd = Block >> eof(); | ||
| 687 | |||
| 688 | class AstLeaf : public ast_node | ||
| 689 | { | ||
| 690 | public: | ||
| 691 | const std::string& getValue() | ||
| 692 | { | ||
| 693 | if (_value.empty()) | ||
| 694 | { | ||
| 695 | for (auto it = m_begin.m_it; it != m_end.m_it; ++it) | ||
| 696 | { | ||
| 697 | char ch = static_cast<char>(*it); | ||
| 698 | _value.append(&ch, 1); | ||
| 699 | } | ||
| 700 | return trim(_value); | ||
| 701 | } | ||
| 702 | return _value; | ||
| 703 | } | ||
| 704 | private: | ||
| 705 | std::string _value; | ||
| 706 | }; | ||
| 707 | |||
| 708 | #define AST_LEAF(type) \ | ||
| 709 | class type##_t : public AstLeaf \ | ||
| 710 | { \ | ||
| 711 | public: \ | ||
| 712 | virtual int get_type() override { return ast_type<type##_t>(); } | ||
| 713 | |||
| 714 | #define AST_NODE(type) \ | ||
| 715 | class type##_t : public ast_container \ | ||
| 716 | { \ | ||
| 717 | public: \ | ||
| 718 | virtual int get_type() override { return ast_type<type##_t>(); } | ||
| 719 | |||
| 720 | #define AST_END(type) \ | ||
| 721 | }; \ | ||
| 722 | ast<type##_t> __##type##_t(type); | ||
| 723 | |||
| 724 | AST_LEAF(Num) | ||
| 725 | virtual void visit(void* ud) override | ||
| 726 | { | ||
| 727 | Data* data = static_cast<Data*>(ud); | ||
| 728 | std::string str = data->conv.to_bytes(&*m_begin.m_it, &*m_end.m_it); | ||
| 729 | data->buffer << trim(str); | ||
| 730 | } | ||
| 731 | AST_END(Num) | ||
| 732 | |||
| 733 | AST_LEAF(_Name) | ||
| 734 | virtual void visit(void* ud) override | ||
| 735 | { | ||
| 736 | Data* data = static_cast<Data*>(ud); | ||
| 737 | data->buffer << getValue(); | ||
| 738 | } | ||
| 739 | AST_END(_Name) | ||
| 740 | |||
| 741 | AST_NODE(Name) | ||
| 742 | ast_ptr<_Name_t> name; | ||
| 743 | virtual void visit(void* ud) override | ||
| 744 | { | ||
| 745 | name->visit(ud); | ||
| 746 | } | ||
| 747 | AST_END(Name) | ||
| 748 | |||
| 749 | AST_LEAF(self) | ||
| 750 | virtual void visit(void* ud) override | ||
| 751 | { | ||
| 752 | Data* data = static_cast<Data*>(ud); | ||
| 753 | data->buffer << "self"; | ||
| 754 | } | ||
| 755 | AST_END(self) | ||
| 756 | |||
| 757 | AST_NODE(self_name) | ||
| 758 | ast_ptr<_Name_t> name; | ||
| 759 | virtual void visit(void* ud) override | ||
| 760 | { | ||
| 761 | Data* data = static_cast<Data*>(ud); | ||
| 762 | data->buffer << (data->callerStack.top() ? "self:" : "self."); | ||
| 763 | name->visit(ud); | ||
| 764 | } | ||
| 765 | AST_END(self_name) | ||
| 766 | |||
| 767 | AST_LEAF(self_class) | ||
| 768 | virtual void visit(void* ud) override | ||
| 769 | { | ||
| 770 | Data* data = static_cast<Data*>(ud); | ||
| 771 | data->buffer << "self.__class"; | ||
| 772 | } | ||
| 773 | AST_END(self_class) | ||
| 774 | |||
| 775 | AST_NODE(self_class_name) | ||
| 776 | ast_ptr<_Name_t> name; | ||
| 777 | virtual void visit(void* ud) override | ||
| 778 | { | ||
| 779 | Data* data = static_cast<Data*>(ud); | ||
| 780 | data->buffer << (data->callerStack.top() ? "self.__class:" : "self.__class."); | ||
| 781 | name->visit(ud); | ||
| 782 | } | ||
| 783 | AST_END(self_class_name) | ||
| 784 | |||
| 785 | AST_NODE(SelfName) | ||
| 786 | ast_ptr<ast_node> name; // self_class_name_t | self_class_t | self_name_t | self_t | ||
| 787 | virtual void visit(void* ud) override | ||
| 788 | { | ||
| 789 | name->visit(ud); | ||
| 790 | } | ||
| 791 | AST_END(SelfName) | ||
| 792 | |||
| 793 | AST_NODE(KeyName) | ||
| 794 | ast_ptr<ast_node> name; // SelfName_t | _Name_t | ||
| 795 | virtual void visit(void* ud) override | ||
| 796 | { | ||
| 797 | name->visit(ud); | ||
| 798 | } | ||
| 799 | AST_END(KeyName) | ||
| 800 | |||
| 801 | AST_LEAF(VarArg) | ||
| 802 | virtual void visit(void* ud) override | ||
| 803 | { | ||
| 804 | Data* data = static_cast<Data*>(ud); | ||
| 805 | data->buffer << "..."; | ||
| 806 | } | ||
| 807 | AST_END(VarArg) | ||
| 808 | |||
| 809 | AST_LEAF(local_flag) | ||
| 810 | AST_END(local_flag) | ||
| 811 | |||
| 812 | AST_LEAF(Seperator) | ||
| 813 | AST_END(Seperator) | ||
| 814 | |||
| 815 | AST_NODE(NameList) | ||
| 816 | ast_ptr<Seperator_t> sep; | ||
| 817 | ast_list<Name_t> names; | ||
| 818 | virtual void visit(void* ud) override | ||
| 819 | { | ||
| 820 | Data* data = static_cast<Data*>(ud); | ||
| 821 | auto it = names.objects().begin(); | ||
| 822 | Name_t* name = *it; | ||
| 823 | name->visit(ud); | ||
| 824 | ++it; | ||
| 825 | for (; it != names.objects().end(); ++it) | ||
| 826 | { | ||
| 827 | name = *it; | ||
| 828 | data->buffer << ", "; | ||
| 829 | name->visit(ud); | ||
| 830 | } | ||
| 831 | } | ||
| 832 | AST_END(NameList) | ||
| 833 | |||
| 834 | AST_NODE(Local) | ||
| 835 | ast_ptr<ast_node> name; // local_flag_t | NameList_t | ||
| 836 | AST_END(Local) | ||
| 837 | |||
| 838 | AST_NODE(colon_import_name) | ||
| 839 | ast_ptr<Name_t> name; | ||
| 840 | AST_END(colon_import_name) | ||
| 841 | |||
| 842 | class Exp_t; | ||
| 843 | |||
| 844 | AST_NODE(ImportName) | ||
| 845 | ast_ptr<ast_node> name; // colon_import_name_t | Name_t | ||
| 846 | AST_END(ImportName) | ||
| 847 | |||
| 848 | AST_NODE(Import) | ||
| 849 | ast_ptr<Seperator_t> sep; | ||
| 850 | ast_list<ImportName_t> names; | ||
| 851 | ast_ptr<Exp_t> exp; | ||
| 852 | virtual void visit(void* ud) override | ||
| 853 | { | ||
| 854 | Data* data = static_cast<Data*>(ud); | ||
| 855 | std::vector<std::tuple<const std::string*, bool>> nameItems; | ||
| 856 | nameItems.reserve(names.objects().size()); | ||
| 857 | for (ImportName_t* importName : names.objects()) | ||
| 858 | { | ||
| 859 | if (Name_t* name = ast_cast<Name_t>(importName->name)) | ||
| 860 | { | ||
| 861 | nameItems.push_back(std::make_tuple(&name->name->getValue(), false)); | ||
| 862 | } | ||
| 863 | else | ||
| 864 | { | ||
| 865 | colon_import_name_t* colonName = ast_cast<colon_import_name_t>(importName->name); | ||
| 866 | nameItems.push_back(std::make_tuple(&colonName->name->name->getValue(), true)); | ||
| 867 | } | ||
| 868 | } | ||
| 869 | data->buffer << "local "; | ||
| 870 | for (const auto& item : nameItems) | ||
| 871 | { | ||
| 872 | data->buffer << *std::get<0>(item); | ||
| 873 | if (&item != &nameItems.back()) | ||
| 874 | { | ||
| 875 | data->buffer << ", "; | ||
| 876 | } | ||
| 877 | } | ||
| 878 | data->endLine(); | ||
| 879 | |||
| 880 | data->beginLine(); | ||
| 881 | data->pushScope(); | ||
| 882 | data->buffer << "do"; | ||
| 883 | data->endLine(); | ||
| 884 | |||
| 885 | std::string fromObj = data->getNewLocalObj(); | ||
| 886 | |||
| 887 | data->beginLine(); | ||
| 888 | data->buffer << "local " << fromObj << " = "; | ||
| 889 | ((ast_node*)exp.get())->visit(ud); | ||
| 890 | data->endLine(); | ||
| 891 | |||
| 892 | data->beginLine(); | ||
| 893 | for (const auto& item : nameItems) | ||
| 894 | { | ||
| 895 | data->buffer << *std::get<0>(item); | ||
| 896 | if (&item != &nameItems.back()) | ||
| 897 | { | ||
| 898 | data->buffer << ", "; | ||
| 899 | } | ||
| 900 | } | ||
| 901 | data->buffer << " = "; | ||
| 902 | for (const auto& item : nameItems) | ||
| 903 | { | ||
| 904 | if (std::get<1>(item)) | ||
| 905 | { | ||
| 906 | data->pushScope(); | ||
| 907 | data->buffer << "(function()"; | ||
| 908 | data->endLine(); | ||
| 909 | |||
| 910 | std::string varBase = data->getNewLocalBase(); | ||
| 911 | |||
| 912 | data->beginLine(); | ||
| 913 | data->buffer << "local " << varBase << " = " << fromObj; | ||
| 914 | data->endLine(); | ||
| 915 | |||
| 916 | std::string varFn = data->getNewLocalFn(); | ||
| 917 | |||
| 918 | data->beginLine(); | ||
| 919 | data->buffer << "local " << varFn << " = " << varBase << '.' << *std::get<0>(item); | ||
| 920 | data->endLine(); | ||
| 921 | |||
| 922 | data->beginLine(); | ||
| 923 | data->buffer << "return function(...)"; | ||
| 924 | data->endLine(); | ||
| 925 | |||
| 926 | data->beginLine(); | ||
| 927 | data->pushScope(); | ||
| 928 | data->buffer << varFn << '(' << varBase << ", ...)"; | ||
| 929 | data->endLine(); | ||
| 930 | |||
| 931 | data->beginLine(); | ||
| 932 | data->buffer << "end"; | ||
| 933 | data->popScope(); | ||
| 934 | data->endLine(); | ||
| 935 | |||
| 936 | data->beginLine(); | ||
| 937 | data->buffer << "end)()"; | ||
| 938 | data->popScope(); | ||
| 939 | } | ||
| 940 | else | ||
| 941 | { | ||
| 942 | data->buffer << fromObj << '.' << *std::get<0>(item); | ||
| 943 | } | ||
| 944 | if (&item != &nameItems.back()) | ||
| 945 | { | ||
| 946 | data->buffer << ", "; | ||
| 947 | } | ||
| 948 | } | ||
| 949 | data->endLine(); | ||
| 950 | |||
| 951 | data->beginLine(); | ||
| 952 | data->buffer << "end"; | ||
| 953 | data->popScope(); | ||
| 954 | } | ||
| 955 | AST_END(Import) | ||
| 956 | |||
| 957 | AST_NODE(ExpListLow) | ||
| 958 | ast_ptr<Seperator_t> sep; | ||
| 959 | ast_list<Exp_t> exprs; | ||
| 960 | virtual void visit(void* ud) override | ||
| 961 | { | ||
| 962 | Data* data = static_cast<Data*>(ud); | ||
| 963 | for (Exp_t* expr : exprs.objects()) | ||
| 964 | { | ||
| 965 | ((ast_node*)expr)->visit(ud); | ||
| 966 | if (expr != exprs.objects().back()) | ||
| 967 | { | ||
| 968 | data->buffer << ", "; | ||
| 969 | } | ||
| 970 | } | ||
| 971 | } | ||
| 972 | AST_END(ExpListLow) | ||
| 973 | |||
| 974 | AST_NODE(ExpList) | ||
| 975 | ast_ptr<Seperator_t> sep; | ||
| 976 | ast_list<Exp_t> exprs; | ||
| 977 | virtual void visit(void* ud) override | ||
| 978 | { | ||
| 979 | Data* data = static_cast<Data*>(ud); | ||
| 980 | for (Exp_t* expr : exprs.objects()) | ||
| 981 | { | ||
| 982 | ((ast_node*)expr)->visit(ud); | ||
| 983 | if (expr != exprs.objects().back()) | ||
| 984 | { | ||
| 985 | data->buffer << ", "; | ||
| 986 | } | ||
| 987 | } | ||
| 988 | } | ||
| 989 | AST_END(ExpList) | ||
| 990 | |||
| 991 | AST_NODE(Return) | ||
| 992 | ast_ptr<ExpListLow_t, true> valueList; | ||
| 993 | virtual void visit(void* ud) override | ||
| 994 | { | ||
| 995 | Data* data = static_cast<Data*>(ud); | ||
| 996 | data->buffer << "return"; | ||
| 997 | if (valueList && !valueList->exprs.objects().empty()) | ||
| 998 | { | ||
| 999 | data->buffer << ' '; | ||
| 1000 | valueList->visit(ud); | ||
| 1001 | } | ||
| 1002 | } | ||
| 1003 | AST_END(Return) | ||
| 1004 | |||
| 1005 | class Assign_t; | ||
| 1006 | class Body_t; | ||
| 1007 | |||
| 1008 | AST_NODE(With) | ||
| 1009 | ast_ptr<ExpList_t> valueList; | ||
| 1010 | ast_ptr<Assign_t, true> assigns; | ||
| 1011 | ast_ptr<Body_t> body; | ||
| 1012 | /* | ||
| 1013 | (function() | ||
| 1014 | do | ||
| 1015 | local _with_0 = Something() | ||
| 1016 | _with_0:write("hello world") | ||
| 1017 | return _with_0 | ||
| 1018 | end | ||
| 1019 | end)() | ||
| 1020 | */ | ||
| 1021 | virtual void visit(void* ud) override | ||
| 1022 | { | ||
| 1023 | } | ||
| 1024 | AST_END(With) | ||
| 1025 | |||
| 1026 | AST_NODE(SwitchCase) | ||
| 1027 | ast_ptr<ExpList_t> valueList; | ||
| 1028 | ast_ptr<Body_t> body; | ||
| 1029 | AST_END(SwitchCase) | ||
| 1030 | |||
| 1031 | AST_NODE(Switch) | ||
| 1032 | ast_ptr<Exp_t> target; | ||
| 1033 | ast_ptr<Seperator_t> sep; | ||
| 1034 | ast_list<SwitchCase_t> branches; | ||
| 1035 | ast_ptr<Body_t, true> lastBranch; | ||
| 1036 | AST_END(Switch) | ||
| 1037 | |||
| 1038 | AST_NODE(IfCond) | ||
| 1039 | ast_ptr<Exp_t> condition; | ||
| 1040 | ast_ptr<Assign_t, true> assign; | ||
| 1041 | AST_END(IfCond) | ||
| 1042 | |||
| 1043 | AST_NODE(IfElseIf) | ||
| 1044 | ast_ptr<IfCond_t> condition; | ||
| 1045 | ast_ptr<Body_t> body; | ||
| 1046 | AST_END(IfElseIf) | ||
| 1047 | |||
| 1048 | AST_NODE(If) | ||
| 1049 | ast_ptr<IfCond_t> firstCondition; | ||
| 1050 | ast_ptr<Body_t> firstBody; | ||
| 1051 | ast_ptr<Seperator_t> sep; | ||
| 1052 | ast_list<IfElseIf_t> branches; | ||
| 1053 | ast_ptr<Body_t, true> lastBranch; | ||
| 1054 | AST_END(If) | ||
| 1055 | |||
| 1056 | AST_NODE(Unless) | ||
| 1057 | ast_ptr<IfCond_t> firstCondition; | ||
| 1058 | ast_ptr<Body_t> firstBody; | ||
| 1059 | ast_ptr<Seperator_t> sep; | ||
| 1060 | ast_list<IfElseIf_t> branches; | ||
| 1061 | ast_ptr<Body_t, true> lastBranch; | ||
| 1062 | AST_END(Unless) | ||
| 1063 | |||
| 1064 | AST_NODE(While) | ||
| 1065 | ast_ptr<Exp_t> condition; | ||
| 1066 | ast_ptr<Body_t> body; | ||
| 1067 | AST_END(While) | ||
| 1068 | |||
| 1069 | AST_NODE(for_step_value) | ||
| 1070 | ast_ptr<Exp_t> value; | ||
| 1071 | AST_END(for_step_value) | ||
| 1072 | |||
| 1073 | AST_NODE(For) | ||
| 1074 | ast_ptr<Name_t> varName; | ||
| 1075 | ast_ptr<Exp_t> startValue; | ||
| 1076 | ast_ptr<Exp_t> stopValue; | ||
| 1077 | ast_ptr<for_step_value_t, true> stepValue; | ||
| 1078 | ast_ptr<Body_t> body; | ||
| 1079 | AST_END(For) | ||
| 1080 | |||
| 1081 | class AssignableNameList_t; | ||
| 1082 | |||
| 1083 | AST_NODE(ForEach) | ||
| 1084 | ast_ptr<AssignableNameList_t> nameList; | ||
| 1085 | ast_ptr<ast_node> loopValue; // Exp_t | ExpList_t | ||
| 1086 | ast_ptr<Body_t> body; | ||
| 1087 | AST_END(ForEach) | ||
| 1088 | |||
| 1089 | AST_NODE(Do) | ||
| 1090 | ast_ptr<Body_t> body; | ||
| 1091 | AST_END(Do) | ||
| 1092 | |||
| 1093 | class CompInner_t; | ||
| 1094 | |||
| 1095 | AST_NODE(Comprehension) | ||
| 1096 | ast_ptr<Exp_t> value; | ||
| 1097 | ast_ptr<CompInner_t> forLoop; | ||
| 1098 | AST_END(Comprehension) | ||
| 1099 | |||
| 1100 | AST_NODE(comp_value) | ||
| 1101 | ast_ptr<Exp_t> value; | ||
| 1102 | AST_END(comp_value) | ||
| 1103 | |||
| 1104 | AST_NODE(TblComprehension) | ||
| 1105 | ast_ptr<Exp_t> key; | ||
| 1106 | ast_ptr<comp_value_t, true> value; | ||
| 1107 | ast_ptr<CompInner_t> forLoop; | ||
| 1108 | AST_END(TblComprehension) | ||
| 1109 | |||
| 1110 | AST_NODE(star_exp) | ||
| 1111 | ast_ptr<Exp_t> value; | ||
| 1112 | AST_END(star_exp) | ||
| 1113 | |||
| 1114 | AST_NODE(CompForEach) | ||
| 1115 | ast_ptr<AssignableNameList_t> nameList; | ||
| 1116 | ast_ptr<ast_node> loopValue; // star_exp_t | Exp_t | ||
| 1117 | AST_END(CompForEach) | ||
| 1118 | |||
| 1119 | AST_NODE(CompFor) | ||
| 1120 | ast_ptr<Name_t> varName; | ||
| 1121 | ast_ptr<Exp_t> startValue; | ||
| 1122 | ast_ptr<Exp_t> stopValue; | ||
| 1123 | ast_ptr<for_step_value_t, true> stepValue; | ||
| 1124 | AST_END(CompFor) | ||
| 1125 | |||
| 1126 | AST_NODE(CompClause) | ||
| 1127 | ast_ptr<ast_node> nestExp; // CompFor_t | CompForEach_t | Exp_t | ||
| 1128 | AST_END(CompClause) | ||
| 1129 | |||
| 1130 | AST_NODE(CompInner) | ||
| 1131 | ast_ptr<ast_node> compFor; // CompFor_t | CompForEach_t | ||
| 1132 | ast_ptr<Seperator_t> sep; | ||
| 1133 | ast_list<CompClause_t> clauses; | ||
| 1134 | AST_END(CompInner) | ||
| 1135 | |||
| 1136 | class TableBlock_t; | ||
| 1137 | |||
| 1138 | AST_NODE(Assign) | ||
| 1139 | ast_ptr<ast_node> value; // With_t | If_t | Switch_t | TableBlock_t | ExpListLow_t | ||
| 1140 | AST_END(Assign) | ||
| 1141 | |||
| 1142 | AST_LEAF(update_op) | ||
| 1143 | AST_END(update_op) | ||
| 1144 | |||
| 1145 | AST_NODE(Update) | ||
| 1146 | ast_ptr<update_op_t> op; | ||
| 1147 | ast_ptr<Exp_t> value; | ||
| 1148 | AST_END(Update) | ||
| 1149 | |||
| 1150 | AST_LEAF(BinaryOperator) | ||
| 1151 | AST_END(BinaryOperator) | ||
| 1152 | |||
| 1153 | class Chain_t; | ||
| 1154 | |||
| 1155 | AST_NODE(Assignable) | ||
| 1156 | ast_ptr<ast_node> item; // Chain_t | Name_t | SelfName_t | ||
| 1157 | AST_END(Assignable) | ||
| 1158 | |||
| 1159 | class Value_t; | ||
| 1160 | |||
| 1161 | AST_NODE(exp_op_value) | ||
| 1162 | ast_ptr<BinaryOperator_t> op; | ||
| 1163 | ast_ptr<Value_t> value; | ||
| 1164 | AST_END(exp_op_value) | ||
| 1165 | |||
| 1166 | AST_NODE(Exp) | ||
| 1167 | ast_ptr<Value_t> value; | ||
| 1168 | ast_list<exp_op_value_t> opValues; | ||
| 1169 | AST_END(Exp) | ||
| 1170 | |||
| 1171 | AST_NODE(Callable) | ||
| 1172 | ast_ptr<ast_node> item; // Name_t | SelfName_t | VarArg_t | Parens_t | ||
| 1173 | AST_END(Callable) | ||
| 1174 | |||
| 1175 | class InvokeArgs_t; | ||
| 1176 | |||
| 1177 | AST_NODE(ChainValue) | ||
| 1178 | ast_ptr<ast_node> caller; // Chain_t | Callable_t | ||
| 1179 | ast_ptr<InvokeArgs_t, true> arguments; | ||
| 1180 | |||
| 1181 | virtual void visit(void* ud) override | ||
| 1182 | { | ||
| 1183 | |||
| 1184 | } | ||
| 1185 | AST_END(ChainValue) | ||
| 1186 | |||
| 1187 | class KeyValue_t; | ||
| 1188 | |||
| 1189 | AST_NODE(simple_table) | ||
| 1190 | ast_ptr<Seperator_t> sep; | ||
| 1191 | ast_list<KeyValue_t> pairs; | ||
| 1192 | AST_END(simple_table) | ||
| 1193 | |||
| 1194 | class String_t; | ||
| 1195 | |||
| 1196 | AST_NODE(SimpleValue) | ||
| 1197 | ast_ptr<ast_node> value; /* | ||
| 1198 | const_value_t | | ||
| 1199 | If_t | Unless_t | Switch_t | With_t | ClassDecl_t | ForEach_t | For_t | While_t | Do_t | | ||
| 1200 | unary_exp_t | | ||
| 1201 | TblComprehension_t | TableLit_t | Comprehension_t | FunLit_t | Num_t; | ||
| 1202 | */ | ||
| 1203 | AST_END(SimpleValue) | ||
| 1204 | |||
| 1205 | AST_NODE(Chain) | ||
| 1206 | ast_ptr<ast_node> item; // chain_call_t | chain_item_t | chain_dot_chain_t | ColonChain_t | ||
| 1207 | AST_END(Chain) | ||
| 1208 | |||
| 1209 | AST_NODE(Value) | ||
| 1210 | ast_ptr<ast_node> item; // SimpleValue_t | simple_table_t | ChainValue_t | String_t | ||
| 1211 | virtual ast_node* get_flattened() override | ||
| 1212 | { | ||
| 1213 | if (SimpleValue_t* simpleValue = ast_cast<SimpleValue_t>(item)) | ||
| 1214 | { | ||
| 1215 | return simpleValue->value; | ||
| 1216 | } | ||
| 1217 | else if (simple_table_t* simple_table = ast_cast<simple_table_t>(item)) | ||
| 1218 | { | ||
| 1219 | return simple_table; | ||
| 1220 | } | ||
| 1221 | else if (ChainValue_t* chainValue = ast_cast<ChainValue_t>(item)) | ||
| 1222 | { | ||
| 1223 | if (chainValue->arguments) | ||
| 1224 | { | ||
| 1225 | return chainValue; | ||
| 1226 | } | ||
| 1227 | else | ||
| 1228 | { | ||
| 1229 | if (Chain_t* chain = ast_cast<Chain_t>(chainValue->caller)) | ||
| 1230 | { | ||
| 1231 | return chain->item; | ||
| 1232 | } | ||
| 1233 | else if (Callable_t* callable = ast_cast<Callable_t>(chainValue->caller)) | ||
| 1234 | { | ||
| 1235 | return callable->item; | ||
| 1236 | } | ||
| 1237 | } | ||
| 1238 | } | ||
| 1239 | return item; | ||
| 1240 | } | ||
| 1241 | AST_END(Value) | ||
| 1242 | |||
| 1243 | AST_LEAF(LuaString) | ||
| 1244 | AST_END(LuaString) | ||
| 1245 | |||
| 1246 | AST_LEAF(SingleString) | ||
| 1247 | AST_END(SingleString) | ||
| 1248 | |||
| 1249 | AST_LEAF(double_string_inner) | ||
| 1250 | AST_END(double_string_inner) | ||
| 1251 | |||
| 1252 | AST_NODE(double_string_content) | ||
| 1253 | ast_ptr<ast_node> content; // double_string_inner_t | Exp_t | ||
| 1254 | AST_END(double_string_content) | ||
| 1255 | |||
| 1256 | AST_NODE(DoubleString) | ||
| 1257 | ast_ptr<Seperator_t> sep; | ||
| 1258 | ast_list<double_string_content_t> segments; | ||
| 1259 | AST_END(DoubleString) | ||
| 1260 | |||
| 1261 | AST_NODE(String) | ||
| 1262 | ast_ptr<ast_node> str; // DoubleString_t | SingleString_t | LuaString_t | ||
| 1263 | AST_END(String) | ||
| 1264 | |||
| 1265 | AST_NODE(Parens) | ||
| 1266 | ast_ptr<Exp_t> expr; | ||
| 1267 | AST_END(Parens) | ||
| 1268 | |||
| 1269 | AST_NODE(FnArgs) | ||
| 1270 | ast_ptr<Seperator_t> sep; | ||
| 1271 | ast_list<Exp_t> args; | ||
| 1272 | AST_END(FnArgs) | ||
| 1273 | |||
| 1274 | class ChainItems_t; | ||
| 1275 | |||
| 1276 | AST_NODE(chain_call) | ||
| 1277 | ast_ptr<ast_node> caller; // Callable_t | String_t | ||
| 1278 | ast_ptr<ChainItems_t> chain; | ||
| 1279 | AST_END(chain_call) | ||
| 1280 | |||
| 1281 | AST_NODE(chain_item) | ||
| 1282 | ast_ptr<ChainItems_t> chain; | ||
| 1283 | AST_END(chain_item) | ||
| 1284 | |||
| 1285 | AST_NODE(DotChainItem) | ||
| 1286 | ast_ptr<_Name_t> name; | ||
| 1287 | AST_END(DotChainItem) | ||
| 1288 | |||
| 1289 | AST_NODE(ColonChainItem) | ||
| 1290 | ast_ptr<_Name_t> name; | ||
| 1291 | AST_END(ColonChainItem) | ||
| 1292 | |||
| 1293 | AST_NODE(chain_dot_chain) | ||
| 1294 | ast_ptr<DotChainItem_t> caller; | ||
| 1295 | ast_ptr<ChainItems_t, true> chain; | ||
| 1296 | AST_END(chain_dot_chain) | ||
| 1297 | |||
| 1298 | class ColonChain_t; | ||
| 1299 | |||
| 1300 | class Invoke_t; | ||
| 1301 | class Slice_t; | ||
| 1302 | |||
| 1303 | AST_NODE(ChainItem) | ||
| 1304 | ast_ptr<ast_node> item; // Invoke_t | DotChainItem_t | Slice_t | [Exp_t] | ||
| 1305 | AST_END(ChainItem) | ||
| 1306 | |||
| 1307 | AST_NODE(ChainItems) | ||
| 1308 | ast_ptr<Seperator_t> sep; | ||
| 1309 | ast_list<ChainItem_t> simpleChain; | ||
| 1310 | ast_ptr<ColonChain_t, true> colonChain; | ||
| 1311 | AST_END(ChainItems) | ||
| 1312 | |||
| 1313 | AST_NODE(invoke_chain) | ||
| 1314 | ast_ptr<Invoke_t> invoke; | ||
| 1315 | ast_ptr<ChainItems_t, true> chain; | ||
| 1316 | AST_END(invoke_chain) | ||
| 1317 | |||
| 1318 | AST_NODE(ColonChain) | ||
| 1319 | ast_ptr<ColonChainItem_t> colonChain; | ||
| 1320 | ast_ptr<invoke_chain_t, true> invokeChain; | ||
| 1321 | AST_END(ColonChain) | ||
| 1322 | |||
| 1323 | AST_LEAF(default_value) | ||
| 1324 | AST_END(default_value) | ||
| 1325 | |||
| 1326 | AST_NODE(Slice) | ||
| 1327 | ast_ptr<ast_node> startValue; // Exp_t | default_value_t | ||
| 1328 | ast_ptr<ast_node> stopValue; // Exp_t | default_value_t | ||
| 1329 | ast_ptr<ast_node> stepValue; // Exp_t | default_value_t | ||
| 1330 | AST_END(Slice) | ||
| 1331 | |||
| 1332 | AST_NODE(Invoke) | ||
| 1333 | ast_ptr<ast_node> argument; // FnArgs_t | SingleString_t | DoubleString_t | LuaString_t | ||
| 1334 | AST_END(Invoke) | ||
| 1335 | |||
| 1336 | class KeyValue_t; | ||
| 1337 | |||
| 1338 | AST_NODE(TableValue) | ||
| 1339 | ast_ptr<ast_node> value; // KeyValue_t | Exp_t | ||
| 1340 | AST_END(TableValue) | ||
| 1341 | |||
| 1342 | AST_NODE(TableLit) | ||
| 1343 | ast_ptr<Seperator_t> sep; | ||
| 1344 | ast_list<TableValue_t> values; | ||
| 1345 | AST_END(TableLit) | ||
| 1346 | |||
| 1347 | AST_NODE(TableBlock) | ||
| 1348 | ast_ptr<Seperator_t> sep; | ||
| 1349 | ast_list<KeyValue_t> values; | ||
| 1350 | AST_END(TableBlock) | ||
| 1351 | |||
| 1352 | AST_NODE(class_member_list) | ||
| 1353 | ast_ptr<Seperator_t> sep; | ||
| 1354 | ast_list<KeyValue_t> values; | ||
| 1355 | AST_END(class_member_list) | ||
| 1356 | |||
| 1357 | AST_NODE(ClassLine) | ||
| 1358 | ast_ptr<ast_node> content; // class_member_list_t | Statement_t | Exp_t | ||
| 1359 | AST_END(ClassLine) | ||
| 1360 | |||
| 1361 | AST_NODE(ClassBlock) | ||
| 1362 | ast_ptr<Seperator_t> sep; | ||
| 1363 | ast_list<ClassLine_t> lines; | ||
| 1364 | AST_END(ClassBlock) | ||
| 1365 | |||
| 1366 | AST_NODE(ClassDecl) | ||
| 1367 | ast_ptr<Assignable_t, true> name; | ||
| 1368 | ast_ptr<Exp_t, true> extend; | ||
| 1369 | ast_ptr<ClassBlock_t, true> body; | ||
| 1370 | AST_END(ClassDecl) | ||
| 1371 | |||
| 1372 | AST_NODE(export_values) | ||
| 1373 | ast_ptr<NameList_t> nameList; | ||
| 1374 | ast_ptr<ExpListLow_t, true> valueList; | ||
| 1375 | AST_END(export_values) | ||
| 1376 | |||
| 1377 | AST_LEAF(export_op) | ||
| 1378 | AST_END(export_op) | ||
| 1379 | |||
| 1380 | AST_NODE(Export) | ||
| 1381 | ast_ptr<ast_node> item; // ClassDecl_t | export_op_t | export_values_t | ||
| 1382 | AST_END(Export) | ||
| 1383 | |||
| 1384 | AST_NODE(variable_pair) | ||
| 1385 | ast_ptr<Name_t> name; | ||
| 1386 | AST_END(variable_pair) | ||
| 1387 | |||
| 1388 | AST_NODE(normal_pair) | ||
| 1389 | ast_ptr<ast_node> key; // KeyName_t | [Exp_t] | DoubleString_t | SingleString_t | ||
| 1390 | ast_ptr<ast_node> value; // Exp_t | TableBlock_t | ||
| 1391 | AST_END(normal_pair) | ||
| 1392 | |||
| 1393 | AST_NODE(KeyValue) | ||
| 1394 | ast_ptr<ast_node> item; // variable_pair_t | normal_pair_t | ||
| 1395 | AST_END(KeyValue) | ||
| 1396 | |||
| 1397 | AST_NODE(FnArgDef) | ||
| 1398 | ast_ptr<ast_node> name; // Name_t | SelfName_t | ||
| 1399 | ast_ptr<Exp_t, true> defaultValue; | ||
| 1400 | AST_END(FnArgDef) | ||
| 1401 | |||
| 1402 | AST_NODE(FnArgDefList) | ||
| 1403 | ast_ptr<Seperator_t> sep; | ||
| 1404 | ast_list<FnArgDef_t> definitions; | ||
| 1405 | ast_ptr<VarArg_t, true> varArg; | ||
| 1406 | AST_END(FnArgDefList) | ||
| 1407 | |||
| 1408 | AST_NODE(outer_var_shadow) | ||
| 1409 | ast_ptr<NameList_t, true> varList; | ||
| 1410 | AST_END(outer_var_shadow) | ||
| 1411 | |||
| 1412 | AST_NODE(FnArgsDef) | ||
| 1413 | ast_ptr<FnArgDefList_t, true> defList; | ||
| 1414 | ast_ptr<outer_var_shadow_t, true> shadowOption; | ||
| 1415 | AST_END(FnArgsDef) | ||
| 1416 | |||
| 1417 | AST_LEAF(fn_arrow) | ||
| 1418 | AST_END(fn_arrow) | ||
| 1419 | |||
| 1420 | AST_NODE(FunLit) | ||
| 1421 | ast_ptr<FnArgsDef_t, true> argsDef; | ||
| 1422 | ast_ptr<fn_arrow_t> arrow; | ||
| 1423 | ast_ptr<Body_t, true> body; | ||
| 1424 | AST_END(FunLit) | ||
| 1425 | |||
| 1426 | AST_NODE(NameOrDestructure) | ||
| 1427 | ast_ptr<ast_node> item; // Name_t | TableLit_t | ||
| 1428 | AST_END(NameOrDestructure) | ||
| 1429 | |||
| 1430 | AST_NODE(AssignableNameList) | ||
| 1431 | ast_ptr<Seperator_t> sep; | ||
| 1432 | ast_list<NameOrDestructure_t> items; | ||
| 1433 | AST_END(AssignableNameList) | ||
| 1434 | |||
| 1435 | AST_NODE(ArgBlock) | ||
| 1436 | ast_ptr<Seperator_t> sep; | ||
| 1437 | ast_list<Exp_t> arguments; | ||
| 1438 | AST_END(ArgBlock) | ||
| 1439 | |||
| 1440 | AST_NODE(invoke_args_with_table) | ||
| 1441 | ast_ptr<ArgBlock_t, true> argBlock; | ||
| 1442 | ast_ptr<TableBlock_t, true> tableBlock; | ||
| 1443 | AST_END(invoke_args_with_table) | ||
| 1444 | |||
| 1445 | AST_NODE(InvokeArgs) | ||
| 1446 | ast_ptr<ExpList_t, true> argsList; | ||
| 1447 | ast_ptr<invoke_args_with_table_t, true> argsTableBlock; | ||
| 1448 | ast_ptr<TableBlock_t, true> tableBlock; | ||
| 1449 | AST_END(InvokeArgs) | ||
| 1450 | |||
| 1451 | AST_LEAF(const_value) | ||
| 1452 | AST_END(const_value) | ||
| 1453 | |||
| 1454 | AST_NODE(unary_exp) | ||
| 1455 | ast_ptr<Exp_t> item; | ||
| 1456 | AST_END(unary_exp) | ||
| 1457 | |||
| 1458 | AST_NODE(Assignment) | ||
| 1459 | ast_ptr<ExpList_t> assignable; | ||
| 1460 | ast_ptr<ast_node> target; // Update_t | Assign_t | ||
| 1461 | AST_END(Assignment) | ||
| 1462 | |||
| 1463 | AST_NODE(if_else_line) | ||
| 1464 | ast_ptr<Exp_t> condition; | ||
| 1465 | ast_ptr<ast_node> elseExpr; // Exp_t | default_value_t | ||
| 1466 | AST_END(if_else_line) | ||
| 1467 | |||
| 1468 | AST_NODE(unless_line) | ||
| 1469 | ast_ptr<Exp_t> condition; | ||
| 1470 | AST_END(unless_line) | ||
| 1471 | |||
| 1472 | AST_NODE(statement_appendix) | ||
| 1473 | ast_ptr<ast_node> item; // if_else_line_t | unless_line_t | CompInner_t | ||
| 1474 | AST_END(statement_appendix) | ||
| 1475 | |||
| 1476 | AST_LEAF(BreakLoop) | ||
| 1477 | AST_END(BreakLoop) | ||
| 1478 | |||
| 1479 | AST_NODE(Statement) | ||
| 1480 | ast_ptr<ast_node> content; /* | ||
| 1481 | Import_t | While_t | With_t | For_t | ForEach_t | | ||
| 1482 | Switch_t | Return_t | Local_t | Export_t | BreakLoop_t | | ||
| 1483 | Assignment_t | ExpList_t | ||
| 1484 | */ | ||
| 1485 | ast_ptr<statement_appendix_t, true> appendix; | ||
| 1486 | |||
| 1487 | virtual void construct(ast_stack& st) override | ||
| 1488 | { | ||
| 1489 | std::wstring_convert<deletable_facet<std::codecvt<char32_t, char, std::mbstate_t>>, char32_t> conv; | ||
| 1490 | value = conv.to_bytes(&*m_begin.m_it, &*m_end.m_it); | ||
| 1491 | ast_container::construct(st); | ||
| 1492 | } | ||
| 1493 | |||
| 1494 | virtual void visit(void* ud) override | ||
| 1495 | { | ||
| 1496 | std::cout << value << '\n'; | ||
| 1497 | } | ||
| 1498 | std::string value; | ||
| 1499 | AST_END(Statement) | ||
| 1500 | |||
| 1501 | class Block_t; | ||
| 1502 | |||
| 1503 | AST_NODE(Body) | ||
| 1504 | ast_ptr<ast_node> content; // Block | Statement | ||
| 1505 | virtual void visit(void* ud) override | ||
| 1506 | { | ||
| 1507 | Data* data = static_cast<Data*>(ud); | ||
| 1508 | data->pushScope(); | ||
| 1509 | content->visit(ud); | ||
| 1510 | data->popScope(); | ||
| 1511 | } | ||
| 1512 | AST_END(Body) | ||
| 1513 | |||
| 1514 | AST_NODE(Line) | ||
| 1515 | ast_ptr<Statement_t, true> statment; | ||
| 1516 | int line; | ||
| 1517 | |||
| 1518 | virtual void construct(ast_stack& st) override | ||
| 1519 | { | ||
| 1520 | ast_container::construct(st); | ||
| 1521 | line = m_begin.m_line; | ||
| 1522 | } | ||
| 1523 | |||
| 1524 | virtual void visit(void* ud) override | ||
| 1525 | { | ||
| 1526 | if (statment) | ||
| 1527 | { | ||
| 1528 | std::cout << line << ": "; | ||
| 1529 | statment->visit(ud); | ||
| 1530 | } | ||
| 1531 | } | ||
| 1532 | AST_END(Line) | ||
| 1533 | |||
| 1534 | AST_NODE(Block) | ||
| 1535 | ast_ptr<Seperator_t> sep; | ||
| 1536 | ast_list<Line_t> lines; | ||
| 1537 | virtual void visit(void* ud) override | ||
| 1538 | { | ||
| 1539 | Data* data = static_cast<Data*>(ud); | ||
| 1540 | const auto& objs = lines.objects(); | ||
| 1541 | for (auto it = objs.begin(); it != objs.end(); ++it) | ||
| 1542 | { | ||
| 1543 | Line_t* line = *it; | ||
| 1544 | if (!line->statment) continue; | ||
| 1545 | if (Local_t* local = ast_cast<Local_t>(line->statment->content)) | ||
| 1546 | { | ||
| 1547 | if (local_flag_t* local_flag = ast_cast<local_flag_t>(local->name)) | ||
| 1548 | { | ||
| 1549 | std::vector<const std::string*> names; | ||
| 1550 | for (auto cur = it; cur != objs.end(); ++cur) | ||
| 1551 | { | ||
| 1552 | Line_t* item = *cur; | ||
| 1553 | if (!item->statment) continue; | ||
| 1554 | if (Assignment_t* assignment = ast_cast<Assignment_t>(item->statment->content)) | ||
| 1555 | { | ||
| 1556 | for (Exp_t* expr : assignment->assignable->exprs.objects()) | ||
| 1557 | { | ||
| 1558 | if (ChainValue_t* chainValue = ast_cast<ChainValue_t>(expr->value->item)) | ||
| 1559 | if (Callable_t* callable = ast_cast<Callable_t>(chainValue->caller)) | ||
| 1560 | if (Name_t* name = ast_cast<Name_t>(callable->item)) | ||
| 1561 | { | ||
| 1562 | const std::string& value = name->name->getValue(); | ||
| 1563 | if (local_flag->getValue() == "*") | ||
| 1564 | { | ||
| 1565 | names.push_back(&value); | ||
| 1566 | } | ||
| 1567 | else if (std::isupper(value[0])) | ||
| 1568 | { | ||
| 1569 | names.push_back(&value); | ||
| 1570 | } | ||
| 1571 | } | ||
| 1572 | } | ||
| 1573 | } | ||
| 1574 | } | ||
| 1575 | if (!names.empty()) | ||
| 1576 | { | ||
| 1577 | data->beginLine(line->m_begin.m_line); | ||
| 1578 | data->buffer << "local "; | ||
| 1579 | auto nameIt = names.begin(); | ||
| 1580 | auto name = *(*nameIt); | ||
| 1581 | data->putLocal(name); | ||
| 1582 | data->buffer << name; | ||
| 1583 | nameIt++; | ||
| 1584 | for (; nameIt != names.end(); ++nameIt) | ||
| 1585 | { | ||
| 1586 | auto name = *(*nameIt); | ||
| 1587 | data->putLocal(name); | ||
| 1588 | data->buffer << ", "; | ||
| 1589 | data->buffer << name; | ||
| 1590 | } | ||
| 1591 | data->endLine(); | ||
| 1592 | } | ||
| 1593 | } | ||
| 1594 | else | ||
| 1595 | { | ||
| 1596 | NameList_t* nameList = static_cast<NameList_t*>(local->name.get()); | ||
| 1597 | data->beginLine(line->m_begin.m_line); | ||
| 1598 | data->buffer << "local "; | ||
| 1599 | nameList->visit(ud); | ||
| 1600 | for (Name_t* name : nameList->names.objects()) | ||
| 1601 | { | ||
| 1602 | data->putLocal(name->name->getValue()); | ||
| 1603 | } | ||
| 1604 | data->endLine(); | ||
| 1605 | } | ||
| 1606 | } | ||
| 1607 | else | ||
| 1608 | { | ||
| 1609 | line->visit(ud); | ||
| 1610 | } | ||
| 1611 | } | ||
| 1612 | } | ||
| 1613 | AST_END(Block) | ||
| 1614 | |||
| 1615 | AST_NODE(BlockEnd) | ||
| 1616 | ast_ptr<Block_t> block; | ||
| 1617 | virtual void visit(void* ud) override | ||
| 1618 | { | ||
| 1619 | Data* data = static_cast<Data*>(ud); | ||
| 1620 | data->pushScope(); | ||
| 1621 | block->visit(ud); | ||
| 1622 | data->popScope(); | ||
| 1623 | } | ||
| 1624 | AST_END(BlockEnd) | ||
| 1625 | |||
| 1626 | int main() | ||
| 1627 | { | ||
| 1628 | std::wstring_convert<deletable_facet<std::codecvt<char32_t, char, std::mbstate_t>>, char32_t> conv; | ||
| 1629 | std::string s = R"baddog(import \x, func, \memFunc from require "utils")baddog"; | ||
| 1630 | input i = conv.from_bytes(s); | ||
| 1631 | |||
| 1632 | error_list el; | ||
| 1633 | Import_t* root = nullptr; | ||
| 1634 | State st; | ||
| 1635 | if (parse(i, Import, el, root, &st)) | ||
| 1636 | { | ||
| 1637 | std::cout << "matched!\n"; | ||
| 1638 | Data data; | ||
| 1639 | root->visit(&data); | ||
| 1640 | } | ||
| 1641 | else | ||
| 1642 | { | ||
| 1643 | std::cout << "not matched!\n"; | ||
| 1644 | for (error_list::iterator it = el.begin(); it != el.end(); ++it) | ||
| 1645 | { | ||
| 1646 | const error& err = *it; | ||
| 1647 | std::cout << "line " << err.m_begin.m_line << ", col " << err.m_begin.m_col << ": syntax error\n"; | ||
| 1648 | } | ||
| 1649 | } | ||
| 1650 | system("pause"); | ||
| 1651 | return 0; | ||
| 1652 | } | ||
