diff options
| author | Li Jin <dragon-fly@qq.com> | 2017-07-11 15:29:00 +0800 |
|---|---|---|
| committer | Li Jin <dragon-fly@qq.com> | 2017-07-11 15:29:00 +0800 |
| commit | 975c3c7dfa032229272c3b225de1127f1605e2d2 (patch) | |
| tree | e58e2813ee4ff4981b0adcbc2f056814718ef116 | |
| parent | 2dc481058998344b7f97721d47987be3ac053768 (diff) | |
| download | yuescript-pegtl.tar.gz yuescript-pegtl.tar.bz2 yuescript-pegtl.zip | |
fail to build AST, but the grammar rules are all ok.pegtl
| -rw-r--r-- | MoonParser.xcodeproj/project.pbxproj | 2 | ||||
| -rw-r--r-- | MoonParser/main.cpp | 1121 |
2 files changed, 712 insertions, 411 deletions
diff --git a/MoonParser.xcodeproj/project.pbxproj b/MoonParser.xcodeproj/project.pbxproj index 2585cd1..8f027f1 100644 --- a/MoonParser.xcodeproj/project.pbxproj +++ b/MoonParser.xcodeproj/project.pbxproj | |||
| @@ -526,6 +526,7 @@ | |||
| 526 | "$(OTHER_CFLAGS)", | 526 | "$(OTHER_CFLAGS)", |
| 527 | "-ftemplate-depth=512", | 527 | "-ftemplate-depth=512", |
| 528 | ); | 528 | ); |
| 529 | OTHER_LDFLAGS = ""; | ||
| 529 | PRODUCT_NAME = "$(TARGET_NAME)"; | 530 | PRODUCT_NAME = "$(TARGET_NAME)"; |
| 530 | }; | 531 | }; |
| 531 | name = Debug; | 532 | name = Debug; |
| @@ -537,6 +538,7 @@ | |||
| 537 | "$(OTHER_CFLAGS)", | 538 | "$(OTHER_CFLAGS)", |
| 538 | "-ftemplate-depth=512", | 539 | "-ftemplate-depth=512", |
| 539 | ); | 540 | ); |
| 541 | OTHER_LDFLAGS = ""; | ||
| 540 | PRODUCT_NAME = "$(TARGET_NAME)"; | 542 | PRODUCT_NAME = "$(TARGET_NAME)"; |
| 541 | }; | 543 | }; |
| 542 | name = Release; | 544 | name = Release; |
diff --git a/MoonParser/main.cpp b/MoonParser/main.cpp index 332b1b4..e692732 100644 --- a/MoonParser/main.cpp +++ b/MoonParser/main.cpp | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | #include <vector> | 11 | #include <vector> |
| 12 | #include <queue> | 12 | #include <queue> |
| 13 | #include <stack> | 13 | #include <stack> |
| 14 | #include <memory> | ||
| 14 | #include "pegtl.hpp" | 15 | #include "pegtl.hpp" |
| 15 | #include "pegtl/analyze.hpp" | 16 | #include "pegtl/analyze.hpp" |
| 16 | #include "slice.h" | 17 | #include "slice.h" |
| @@ -192,12 +193,28 @@ namespace helloworld // with operator precedence climbing | |||
| 192 | 193 | ||
| 193 | namespace moon | 194 | namespace moon |
| 194 | { | 195 | { |
| 196 | int moonType = 0; | ||
| 197 | |||
| 198 | template <class T> | ||
| 199 | int MoonType() | ||
| 200 | { | ||
| 201 | static int type = moonType++; | ||
| 202 | return type; | ||
| 203 | } | ||
| 204 | |||
| 205 | struct Node | ||
| 206 | { | ||
| 207 | virtual ~Node() {} | ||
| 208 | slice::Slice token; | ||
| 209 | }; | ||
| 210 | |||
| 195 | struct State | 211 | struct State |
| 196 | { | 212 | { |
| 197 | State() | 213 | State() |
| 198 | { | 214 | { |
| 199 | indents.push(0); | 215 | indents.push(0); |
| 200 | stringOpen = -1; | 216 | stringOpen = -1; |
| 217 | astStack.emplace_back(); | ||
| 201 | } | 218 | } |
| 202 | size_t stringOpen; | 219 | size_t stringOpen; |
| 203 | std::stack<int> indents; | 220 | std::stack<int> indents; |
| @@ -210,13 +227,15 @@ namespace moon | |||
| 210 | "class", "in", "unless", "when", "elseif", | 227 | "class", "in", "unless", "when", "elseif", |
| 211 | "switch", "break", "if", "with", "import" | 228 | "switch", "break", "if", "with", "import" |
| 212 | }; | 229 | }; |
| 230 | std::stack<size_t> indexStack; | ||
| 231 | std::vector<std::vector<std::shared_ptr<Node>>> astStack; | ||
| 213 | }; | 232 | }; |
| 214 | 233 | ||
| 215 | struct White : star<one<' ', '\t', '\r', '\n'>> {}; | 234 | struct White : star<one<' ', '\t', '\r', '\n'>> {}; |
| 216 | struct plain_space : star<one<' ', '\t'>> {}; | 235 | struct plain_space : star<one<' ', '\t'>> {}; |
| 217 | struct Break : seq<opt<one<'\r'>>, one<'\n'>> {}; | 236 | struct Break : seq<opt<one<'\r'>>, one<'\n'>> {}; |
| 218 | struct Stop : sor<Break, eof> {}; | 237 | struct Stop : sor<Break, eof> {}; |
| 219 | struct Comment : seq<string<'-', '-'>, star<not_one<'\r', '\n'>>, Stop> {}; | 238 | struct Comment : seq<string<'-', '-'>, star<not_at<one<'\r', '\n'>>, any>, at<Stop>> {}; |
| 220 | struct Indent : star<one<' ', '\t'>> {}; | 239 | struct Indent : star<one<' ', '\t'>> {}; |
| 221 | struct Space : seq<plain_space, opt<Comment>> {}; | 240 | struct Space : seq<plain_space, opt<Comment>> {}; |
| 222 | struct SomeSpace : seq<plus<blank>, opt<Comment>> {}; | 241 | struct SomeSpace : seq<plus<blank>, opt<Comment>> {}; |
| @@ -268,7 +287,8 @@ namespace moon | |||
| 268 | struct ensure : sor<seq<patt, finally>, seq<finally, Cut>> {}; | 287 | struct ensure : sor<seq<patt, finally>, seq<finally, Cut>> {}; |
| 269 | 288 | ||
| 270 | template<char... Cs> struct key : seq<Space, string<Cs...>, not_at<AlphaNum>> {}; | 289 | template<char... Cs> struct key : seq<Space, string<Cs...>, not_at<AlphaNum>> {}; |
| 271 | template<char... Cs> struct op : seq<Space, string<Cs...>, not_at<AlphaNum>> {}; | 290 | template<char... Cs> struct opWord : seq<Space, string<Cs...>, not_at<AlphaNum>> {}; |
| 291 | template<char... Cs> struct op : seq<Space, string<Cs...>> {}; | ||
| 272 | 292 | ||
| 273 | struct Name | 293 | struct Name |
| 274 | { | 294 | { |
| @@ -278,16 +298,19 @@ namespace moon | |||
| 278 | template<typename...> class Action, | 298 | template<typename...> class Action, |
| 279 | template<typename...> class Control, | 299 | template<typename...> class Control, |
| 280 | typename Input> | 300 | typename Input> |
| 281 | static bool match(Input& in, const State& st) | 301 | static bool match(Input& in, State& st) |
| 282 | { | 302 | { |
| 283 | const char* current = in.current(); | 303 | const char* current = in.current(); |
| 284 | if (SpaceName::match<A, M, Action, Control>(in, st)) | 304 | memory_input<> memIn(current, in.end() - current, current); |
| 305 | if (SpaceName::match<A, M, Action, Control>(memIn, st)) | ||
| 285 | { | 306 | { |
| 286 | auto name = slice::Slice(current, in.current() - current + 1); | 307 | auto name = slice::Slice(current, memIn.current() - current); |
| 287 | name.trimSpace(); | 308 | auto trimed = name; |
| 288 | auto it = st.keywords.find(name); | 309 | trimed.trimSpace(); |
| 310 | auto it = st.keywords.find(trimed); | ||
| 289 | if (it == st.keywords.end()) | 311 | if (it == st.keywords.end()) |
| 290 | { | 312 | { |
| 313 | in.bump(name.size()); | ||
| 291 | return true; | 314 | return true; |
| 292 | } | 315 | } |
| 293 | } | 316 | } |
| @@ -301,10 +324,10 @@ namespace moon | |||
| 301 | struct self_class_name : seq<string<'@', '@'>, _Name> {}; | 324 | struct self_class_name : seq<string<'@', '@'>, _Name> {}; |
| 302 | 325 | ||
| 303 | struct SelfName : seq<Space, sor<self_class_name, self_class, self_name, self>> {}; | 326 | struct SelfName : seq<Space, sor<self_class_name, self_class, self_name, self>> {}; |
| 304 | struct KeyName : sor<SelfName, SpaceName> {}; | 327 | struct KeyName : sor<SelfName, seq<Space, _Name>> {}; |
| 305 | struct VarArg : seq<Space, string<'.', '.', '.'>> {}; | 328 | struct VarArg : seq<Space, string<'.', '.', '.'>> {}; |
| 306 | 329 | ||
| 307 | struct CheckIndent | 330 | struct CheckIndentBump |
| 308 | { | 331 | { |
| 309 | using analyze_t = analysis::generic<analysis::rule_type::ANY>; | 332 | using analyze_t = analysis::generic<analysis::rule_type::ANY>; |
| 310 | 333 | ||
| @@ -312,7 +335,7 @@ namespace moon | |||
| 312 | template<typename...> class Action, | 335 | template<typename...> class Action, |
| 313 | template<typename...> class Control, | 336 | template<typename...> class Control, |
| 314 | typename Input> | 337 | typename Input> |
| 315 | static bool match(Input& in, const State& st) | 338 | static bool match(Input& in, State& st) |
| 316 | { | 339 | { |
| 317 | const char* current = in.current(); | 340 | const char* current = in.current(); |
| 318 | if (Indent::match<A, M, Action, Control>(in, st)) | 341 | if (Indent::match<A, M, Action, Control>(in, st)) |
| @@ -331,8 +354,9 @@ namespace moon | |||
| 331 | return false; | 354 | return false; |
| 332 | } | 355 | } |
| 333 | }; | 356 | }; |
| 357 | struct CheckIndent : at<CheckIndentBump> {}; | ||
| 334 | 358 | ||
| 335 | struct Advance | 359 | struct AdvanceBump |
| 336 | { | 360 | { |
| 337 | using analyze_t = analysis::generic<analysis::rule_type::ANY>; | 361 | using analyze_t = analysis::generic<analysis::rule_type::ANY>; |
| 338 | 362 | ||
| @@ -343,7 +367,7 @@ namespace moon | |||
| 343 | static bool match(Input& in, State& st) | 367 | static bool match(Input& in, State& st) |
| 344 | { | 368 | { |
| 345 | const char* current = in.current(); | 369 | const char* current = in.current(); |
| 346 | if (Indent::match<A, M, Action, Control>(in)) | 370 | if (Indent::match<A, M, Action, Control>(in, st)) |
| 347 | { | 371 | { |
| 348 | int indent = 0; | 372 | int indent = 0; |
| 349 | for (const char* ch = current; ch < in.current(); ch++) | 373 | for (const char* ch = current; ch < in.current(); ch++) |
| @@ -358,14 +382,16 @@ namespace moon | |||
| 358 | if (top != -1 && indent > top) | 382 | if (top != -1 && indent > top) |
| 359 | { | 383 | { |
| 360 | st.indents.push(indent); | 384 | st.indents.push(indent); |
| 385 | return true; | ||
| 361 | } | 386 | } |
| 362 | return true; | 387 | return false; |
| 363 | } | 388 | } |
| 364 | return false; | 389 | return false; |
| 365 | } | 390 | } |
| 366 | }; | 391 | }; |
| 392 | struct Advance : at<AdvanceBump> {}; | ||
| 367 | 393 | ||
| 368 | struct PushIndent | 394 | struct PushIndentBump |
| 369 | { | 395 | { |
| 370 | using analyze_t = analysis::generic<analysis::rule_type::ANY>; | 396 | using analyze_t = analysis::generic<analysis::rule_type::ANY>; |
| 371 | 397 | ||
| @@ -376,7 +402,7 @@ namespace moon | |||
| 376 | static bool match(Input& in, State& st) | 402 | static bool match(Input& in, State& st) |
| 377 | { | 403 | { |
| 378 | const char* current = in.current(); | 404 | const char* current = in.current(); |
| 379 | if (Indent::match<A, M, Action, Control>(in)) | 405 | if (Indent::match<A, M, Action, Control>(in, st)) |
| 380 | { | 406 | { |
| 381 | int indent = 0; | 407 | int indent = 0; |
| 382 | for (const char* ch = current; ch < in.current(); ch++) | 408 | for (const char* ch = current; ch < in.current(); ch++) |
| @@ -393,8 +419,9 @@ namespace moon | |||
| 393 | return false; | 419 | return false; |
| 394 | } | 420 | } |
| 395 | }; | 421 | }; |
| 422 | struct PushIndent : at<PushIndentBump> {}; | ||
| 396 | 423 | ||
| 397 | struct PreventIndent | 424 | struct PreventIndentBump |
| 398 | { | 425 | { |
| 399 | using analyze_t = analysis::generic<analysis::rule_type::ANY>; | 426 | using analyze_t = analysis::generic<analysis::rule_type::ANY>; |
| 400 | 427 | ||
| @@ -408,8 +435,9 @@ namespace moon | |||
| 408 | return true; | 435 | return true; |
| 409 | } | 436 | } |
| 410 | }; | 437 | }; |
| 438 | struct PreventIndent : at<PreventIndentBump> {}; | ||
| 411 | 439 | ||
| 412 | struct PopIndent | 440 | struct PopIndentBump |
| 413 | { | 441 | { |
| 414 | using analyze_t = analysis::generic<analysis::rule_type::ANY>; | 442 | using analyze_t = analysis::generic<analysis::rule_type::ANY>; |
| 415 | 443 | ||
| @@ -419,10 +447,11 @@ namespace moon | |||
| 419 | typename Input> | 447 | typename Input> |
| 420 | static bool match(Input& in, State& st) | 448 | static bool match(Input& in, State& st) |
| 421 | { | 449 | { |
| 422 | if (st.indents.size() > 1) st.indents.pop(); | 450 | st.indents.pop(); |
| 423 | return true; | 451 | return true; |
| 424 | } | 452 | } |
| 425 | }; | 453 | }; |
| 454 | struct PopIndent : at<PopIndentBump> {}; | ||
| 426 | 455 | ||
| 427 | struct Block; | 456 | struct Block; |
| 428 | 457 | ||
| @@ -430,15 +459,24 @@ namespace moon | |||
| 430 | 459 | ||
| 431 | struct NameList; | 460 | struct NameList; |
| 432 | 461 | ||
| 433 | struct Local : seq<key<'l', 'o', 'c', 'a', 'l'>, sor<sor<op<'*'>, op<'^'>>>, NameList> {}; | 462 | struct Local : seq< |
| 463 | key<'l', 'o', 'c', 'a', 'l'>, | ||
| 464 | sor< | ||
| 465 | sor<op<'*'>, op<'^'>>, | ||
| 466 | NameList | ||
| 467 | > | ||
| 468 | > {}; | ||
| 434 | 469 | ||
| 435 | struct colon_import_name : seq<one<'\\'>, Name> {}; | 470 | struct colon_import_name : seq<sym<'\\'>, Name> {}; |
| 436 | struct ImportName : sor<colon_import_name, Name> {}; | 471 | struct ImportName : sor<colon_import_name, Name> {}; |
| 437 | struct ImportNameList : seq< | 472 | struct ImportNameList : seq< |
| 438 | star<SpaceBreak>, | 473 | star<SpaceBreak>, |
| 439 | ImportName, | 474 | ImportName, |
| 440 | star< | 475 | star< |
| 441 | sor<plus<SpaceBreak>, seq<sym<','>, star<SpaceBreak>>>, | 476 | sor< |
| 477 | plus<SpaceBreak>, | ||
| 478 | seq<sym<','>, star<SpaceBreak>> | ||
| 479 | >, | ||
| 442 | ImportName | 480 | ImportName |
| 443 | > | 481 | > |
| 444 | > {}; | 482 | > {}; |
| @@ -481,8 +519,9 @@ namespace moon | |||
| 481 | 519 | ||
| 482 | struct IfElse : seq< | 520 | struct IfElse : seq< |
| 483 | opt<Break, star<EmptyLine>, CheckIndent>, | 521 | opt<Break, star<EmptyLine>, CheckIndent>, |
| 484 | string<'e', 'l', 's', 'e'>, Body | 522 | key<'e', 'l', 's', 'e'>, Body |
| 485 | > {}; | 523 | > {}; |
| 524 | |||
| 486 | struct IfElseIf : seq< | 525 | struct IfElseIf : seq< |
| 487 | opt<Break, star<EmptyLine>, CheckIndent>, | 526 | opt<Break, star<EmptyLine>, CheckIndent>, |
| 488 | key<'e', 'l', 's', 'e', 'i', 'f'>, IfCond, | 527 | key<'e', 'l', 's', 'e', 'i', 'f'>, IfCond, |
| @@ -515,7 +554,9 @@ namespace moon | |||
| 515 | seq<sym<'*'>, Exp>, ExpList | 554 | seq<sym<'*'>, Exp>, ExpList |
| 516 | >, | 555 | >, |
| 517 | PopDo | 556 | PopDo |
| 518 | > | 557 | >, |
| 558 | opt<key<'d', 'o'>>, | ||
| 559 | Body | ||
| 519 | > {}; | 560 | > {}; |
| 520 | 561 | ||
| 521 | struct Do | 562 | struct Do |
| @@ -528,7 +569,7 @@ namespace moon | |||
| 528 | typename Input> | 569 | typename Input> |
| 529 | static bool match(Input& in, State& st) | 570 | static bool match(Input& in, State& st) |
| 530 | { | 571 | { |
| 531 | if (seq<key<'d', 'o'>, Body>::match<A, M, Action, Control>(in, st)) | 572 | if (at<seq<key<'d', 'o'>, Body>>::match<A, M, Action, Control>(in, st)) |
| 532 | { | 573 | { |
| 533 | if (st.doStack.empty() || st.doStack.top()) | 574 | if (st.doStack.empty() || st.doStack.top()) |
| 534 | { | 575 | { |
| @@ -611,8 +652,8 @@ namespace moon | |||
| 611 | 652 | ||
| 612 | struct CharOperators : seq<Space, one<'+', '-', '*' ,'/', '%', '^', '>', '<', '|', '&'>> {}; | 653 | struct CharOperators : seq<Space, one<'+', '-', '*' ,'/', '%', '^', '>', '<', '|', '&'>> {}; |
| 613 | struct WordOperators : sor< | 654 | struct WordOperators : sor< |
| 614 | op<'o', 'r'>, | 655 | opWord<'o', 'r'>, |
| 615 | op<'a', 'n', 'd'>, | 656 | opWord<'a', 'n', 'd'>, |
| 616 | op<'<', '='>, | 657 | op<'<', '='>, |
| 617 | op<'>', '='>, | 658 | op<'>', '='>, |
| 618 | op<'~', '='>, | 659 | op<'~', '='>, |
| @@ -622,11 +663,11 @@ namespace moon | |||
| 622 | op<'<', '<'>, | 663 | op<'<', '<'>, |
| 623 | op<'>', '>'>, | 664 | op<'>', '>'>, |
| 624 | op<'/', '/'>> {}; | 665 | op<'/', '/'>> {}; |
| 625 | struct BinaryOperator : seq<sor<CharOperators, WordOperators>, star<SpaceBreak>> {}; | 666 | struct BinaryOperator : seq<sor<WordOperators, CharOperators>, star<SpaceBreak>> {}; |
| 626 | 667 | ||
| 627 | struct Chain; | 668 | struct Chain; |
| 628 | 669 | ||
| 629 | struct Assignable : sor<Chain, Name, SelfName> {}; | 670 | struct Assignable : sor<at<Chain>, Name, SelfName> {}; |
| 630 | 671 | ||
| 631 | struct Value; | 672 | struct Value; |
| 632 | 673 | ||
| @@ -641,15 +682,15 @@ namespace moon | |||
| 641 | struct String; | 682 | struct String; |
| 642 | struct SimpleValue; | 683 | struct SimpleValue; |
| 643 | 684 | ||
| 644 | struct Value : sor<String, SimpleValue, KeyValueList, ChainValue> {}; | 685 | struct Value : sor<SimpleValue, KeyValueList, ChainValue, String> {}; |
| 645 | struct SliceValue : Exp {}; | 686 | struct SliceValue : Exp {}; |
| 646 | 687 | ||
| 647 | struct LuaString; | 688 | struct LuaString; |
| 648 | 689 | ||
| 649 | struct single_string_inner : sor<string<'\\','\''>, string<'\\', '\\'>, not_one<'\''>> {}; | 690 | struct single_string_inner : sor<string<'\\', '\''>, string<'\\', '\\'>, not_one<'\''>> {}; |
| 650 | struct SingleString : seq<symx<'\''>, star<single_string_inner>, sym<'\''>> {}; | 691 | struct SingleString : seq<symx<'\''>, star<single_string_inner>, sym<'\''>> {}; |
| 651 | struct interp : seq<symx<'#', '{'>, Exp, sym<'}'>> {}; | 692 | struct interp : seq<symx<'#', '{'>, Exp, sym<'}'>> {}; |
| 652 | struct double_string_plain : sor<string<'\\','\"'>, string<'\\', '\\'>, not_one<'\"'>> {}; | 693 | struct double_string_plain : sor<string<'\\', '\"'>, string<'\\', '\\'>, not_one<'\"'>> {}; |
| 653 | struct double_string_inner : plus<seq<not_at<interp>, double_string_plain>> {}; | 694 | struct double_string_inner : plus<seq<not_at<interp>, double_string_plain>> {}; |
| 654 | struct DoubleString : seq<symx<'\"'>, star<sor<double_string_inner, interp>>, sym<'\"'>> {}; | 695 | struct DoubleString : seq<symx<'\"'>, star<sor<double_string_inner, interp>>, sym<'\"'>> {}; |
| 655 | struct String : sor<seq<Space, DoubleString>, seq<Space, SingleString>, LuaString> {}; | 696 | struct String : sor<seq<Space, DoubleString>, seq<Space, SingleString>, LuaString> {}; |
| @@ -717,7 +758,14 @@ namespace moon | |||
| 717 | struct Parens : seq<sym<'('>, star<SpaceBreak>, Exp, star<SpaceBreak>, sym<')'>> {}; | 758 | struct Parens : seq<sym<'('>, star<SpaceBreak>, Exp, star<SpaceBreak>, sym<')'>> {}; |
| 718 | struct Callable : sor<Name, SelfName, VarArg, Parens> {}; | 759 | struct Callable : sor<Name, SelfName, VarArg, Parens> {}; |
| 719 | 760 | ||
| 720 | struct FnArgsExpList : seq<Exp, star<sor<Break, one<','>>, White, Exp>> {}; | 761 | struct FnArgsExpList : seq< |
| 762 | Exp, | ||
| 763 | star< | ||
| 764 | sor<Break, sym<','>>, | ||
| 765 | White, Exp | ||
| 766 | > | ||
| 767 | > {}; | ||
| 768 | |||
| 721 | struct FnArgs : sor< | 769 | struct FnArgs : sor< |
| 722 | seq<symx<'('>, star<SpaceBreak>, opt<FnArgsExpList>, star<SpaceBreak>, sym<')'>>, | 770 | seq<symx<'('>, star<SpaceBreak>, opt<FnArgsExpList>, star<SpaceBreak>, sym<')'>>, |
| 723 | seq<sym<'!'>, not_at<one<'='>>> | 771 | seq<sym<'!'>, not_at<one<'='>>> |
| @@ -728,7 +776,10 @@ namespace moon | |||
| 728 | struct ColonChain; | 776 | struct ColonChain; |
| 729 | 777 | ||
| 730 | struct Chain : sor< | 778 | struct Chain : sor< |
| 731 | seq<sor<Callable, String, not_one<'.', '\\'>>, ChainItems>, | 779 | seq< |
| 780 | sor<Callable, String, not_at<one<'.', '\\'>>>, | ||
| 781 | ChainItems | ||
| 782 | >, | ||
| 732 | seq<Space, | 783 | seq<Space, |
| 733 | sor< | 784 | sor< |
| 734 | seq<DotChainItem, opt<ChainItems>>, | 785 | seq<DotChainItem, opt<ChainItems>>, |
| @@ -866,34 +917,41 @@ namespace moon | |||
| 866 | > {}; | 917 | > {}; |
| 867 | 918 | ||
| 868 | struct outer_value_shadow : seq<string<'u', 's', 'i', 'n', 'g'>, sor<NameList, seq<Space, string<'n', 'i', 'l'>>>> {}; | 919 | struct outer_value_shadow : seq<string<'u', 's', 'i', 'n', 'g'>, sor<NameList, seq<Space, string<'n', 'i', 'l'>>>> {}; |
| 869 | struct outer_value_no_shadowing : success {}; | 920 | struct outer_value_no_shadow : success {}; |
| 870 | struct without_args_def : success {}; | 921 | struct without_args_def : success {}; |
| 871 | 922 | ||
| 872 | struct FnArgsDef : sor< | 923 | struct FnArgsDef : sor< |
| 873 | seq<sym<'('>, White, opt<FnArgDefList>, | 924 | seq<sym<'('>, White, opt<FnArgDefList>, |
| 874 | sor< | 925 | sor< |
| 875 | outer_value_shadow, | 926 | outer_value_shadow, |
| 876 | outer_value_no_shadowing | 927 | outer_value_no_shadow |
| 877 | >, | 928 | >, |
| 878 | White, sym<')'> | 929 | White, sym<')'> |
| 879 | >, | 930 | >, |
| 880 | without_args_def | 931 | without_args_def |
| 881 | > {}; | 932 | > {}; |
| 882 | 933 | ||
| 883 | struct FunLit : seq<FnArgsDef, sor<sym<'-', '>'>, sym<'=', '>'>>, sor<Body, success>> {}; | 934 | struct FunLit : seq< |
| 935 | FnArgsDef, | ||
| 936 | sor< | ||
| 937 | sym<'-', '>'>, | ||
| 938 | sym<'=', '>'> | ||
| 939 | >, | ||
| 940 | sor<Body, success> | ||
| 941 | > {}; | ||
| 884 | 942 | ||
| 885 | struct NameList : seq<Name, star<sym<','>, Name>> {}; | 943 | struct NameList : seq<Name, star<sym<','>, Name>> {}; |
| 886 | struct NameOrDestructure : sor<Name, TableLit> {}; | 944 | struct NameOrDestructure : sor<Name, TableLit> {}; |
| 887 | struct AssignableNameList : seq<NameOrDestructure, star<sym<','>, NameOrDestructure>> {}; | 945 | struct AssignableNameList : seq<NameOrDestructure, star<sym<','>, NameOrDestructure>> {}; |
| 888 | 946 | ||
| 889 | struct ExpList : seq<Exp, star<sym<','>, Exp>> {}; | 947 | struct ExpList : seq<Exp, star<sym<','>, Exp>> {}; |
| 890 | struct ExpListLow : seq<Exp, star<sor<sym<','>, sym<';'>, Exp>>> {}; | 948 | struct ExpListLow : seq<Exp, star<sor<sym<','>, sym<';'>>, Exp>> {}; |
| 891 | 949 | ||
| 892 | struct ArgLine : seq<CheckIndent, ExpList> {}; | 950 | struct ArgLine : seq<CheckIndent, ExpList> {}; |
| 893 | struct ArgBlock : seq<ArgLine, star<sym<','>, SpaceBreak, ArgLine>, PopIndent> {}; | 951 | struct ArgBlock : seq<ArgLine, star<sym<','>, SpaceBreak, ArgLine>, PopIndent> {}; |
| 894 | 952 | ||
| 895 | struct InvokeArgs : seq< | 953 | struct InvokeArgs : seq< |
| 896 | at<not_one<'-'>>, | 954 | not_at<one<'-'>>, |
| 897 | sor< | 955 | sor< |
| 898 | seq< | 956 | seq< |
| 899 | ExpList, | 957 | ExpList, |
| @@ -932,14 +990,12 @@ namespace moon | |||
| 932 | sor<Update, Assign> | 990 | sor<Update, Assign> |
| 933 | > {}; | 991 | > {}; |
| 934 | 992 | ||
| 935 | struct Sentence : sor< | ||
| 936 | Import, While, With, For, ForEach, | ||
| 937 | Switch, Return, Local, Export, BreakLoop, | ||
| 938 | Assignment, ExpList | ||
| 939 | > {}; | ||
| 940 | |||
| 941 | struct Statement : seq< | 993 | struct Statement : seq< |
| 942 | Sentence, | 994 | sor< |
| 995 | Import, While, With, For, ForEach, | ||
| 996 | Switch, Return, Local, Export, BreakLoop, | ||
| 997 | Assignment, ExpList | ||
| 998 | >, | ||
| 943 | Space, | 999 | Space, |
| 944 | opt< | 1000 | opt< |
| 945 | sor< | 1001 | sor< |
| @@ -969,401 +1025,643 @@ namespace moon | |||
| 969 | 1025 | ||
| 970 | struct Block : seq<Line, star<plus<Break>, Line>> {}; | 1026 | struct Block : seq<Line, star<plus<Break>, Line>> {}; |
| 971 | 1027 | ||
| 972 | struct BlockWithEnd : seq<Block, eolf> {}; | 1028 | struct BlockWithEnd : seq<Block, eof> {}; |
| 1029 | |||
| 1030 | template <class T> | ||
| 1031 | struct NodeBase : Node | ||
| 1032 | { | ||
| 1033 | static int id; | ||
| 1034 | }; | ||
| 1035 | |||
| 1036 | template <class T> | ||
| 1037 | int NodeBase<T>::id = MoonType<T>(); | ||
| 1038 | |||
| 1039 | struct ImportNameNode : Node | ||
| 1040 | { | ||
| 1041 | }; | ||
| 1042 | |||
| 1043 | struct ImportNameListNode : NodeBase<ImportNameListNode> | ||
| 1044 | { | ||
| 1045 | std::vector<std::shared_ptr<Node>> names; | ||
| 1046 | }; | ||
| 1047 | |||
| 1048 | struct ImportNode : NodeBase<ImportNode> | ||
| 1049 | { | ||
| 1050 | std::shared_ptr<Node> nameList; | ||
| 1051 | std::shared_ptr<Node> exp; | ||
| 1052 | }; | ||
| 973 | 1053 | ||
| 974 | template<typename Rule> | 1054 | template<typename Rule> |
| 975 | struct action : nothing<Rule> {}; | 1055 | struct action : nothing<Rule> {}; |
| 976 | 1056 | ||
| 977 | template<> | 1057 | template<> |
| 978 | struct action<Assignment> | 1058 | struct action<ImportName> |
| 979 | { | 1059 | { |
| 980 | template<typename Input> | 1060 | template<typename Input> |
| 981 | static void apply(const Input& in, State&) | 1061 | static void apply(const Input& in, State& st) |
| 982 | { | 1062 | { |
| 983 | std::cout << "Assignment: " << in.string() << '\n'; | 1063 | auto node = std::make_shared<ImportNameNode>(); |
| 1064 | node->token = slice::Slice(in.begin(), in.end() - in.begin()); | ||
| 1065 | node->token.trimSpace(); | ||
| 1066 | st.astStack.pop_back(); | ||
| 1067 | st.astStack.back().push_back(node); | ||
| 984 | } | 1068 | } |
| 985 | }; | 1069 | }; |
| 986 | 1070 | ||
| 987 | template<> | 1071 | template<> |
| 988 | struct action<Return> | 1072 | struct action<Exp> |
| 989 | { | 1073 | { |
| 990 | template<typename Input> | 1074 | template<typename Input> |
| 991 | static void apply(const Input& in, State&) | 1075 | static void apply(const Input& in, State& st) |
| 992 | { | 1076 | { |
| 993 | std::cout << "Return: " << in.string() << "\n\n"; | 1077 | auto node = std::make_shared<Node>(); |
| 1078 | node->token = slice::Slice(in.begin(), in.end() - in.begin()); | ||
| 1079 | node->token.trimSpace(); | ||
| 1080 | st.astStack.pop_back(); | ||
| 1081 | st.astStack.back().push_back(node); | ||
| 994 | } | 1082 | } |
| 995 | }; | 1083 | }; |
| 996 | } | ||
| 997 | 1084 | ||
| 998 | int main() | 1085 | template<> |
| 999 | { | 1086 | struct action<Import> |
| 1000 | analyze<moon::BlockWithEnd>(); | 1087 | { |
| 1001 | moon::State state; | 1088 | template<typename Input> |
| 1002 | string_input<> inName(R"xoxo( | 1089 | static void apply(const Input& in, State& st) |
| 1003 | debug_grammar = false | 1090 | { |
| 1004 | lpeg = require "lpeg" | 1091 | auto node = std::make_shared<ImportNode>(); |
| 1005 | 1092 | node->exp = st.astStack.back().back(); | |
| 1006 | lpeg.setmaxstack 10000 -- whoa | 1093 | st.astStack.back().pop_back(); |
| 1094 | node->nameList = st.astStack.back().back(); | ||
| 1095 | st.astStack.back().pop_back(); | ||
| 1096 | st.astStack.pop_back(); | ||
| 1097 | st.astStack.back().push_back(node); | ||
| 1098 | } | ||
| 1099 | }; | ||
| 1007 | 1100 | ||
| 1008 | err_msg = "Failed to parse:%s\n [%d] >> %s" | 1101 | template<> |
| 1102 | struct action<ImportNameListNode> | ||
| 1103 | { | ||
| 1104 | template<typename Input> | ||
| 1105 | static void apply(const Input& in, State& st) | ||
| 1106 | { | ||
| 1107 | auto node = std::make_shared<ImportNameListNode>(); | ||
| 1108 | node->names = std::move(st.astStack.back()); | ||
| 1109 | st.astStack.pop_back(); | ||
| 1110 | st.astStack.back().push_back(node); | ||
| 1111 | } | ||
| 1112 | }; | ||
| 1009 | 1113 | ||
| 1010 | import Stack from require "moonscript.data" | 1114 | template<typename Rule> |
| 1011 | import trim, pos_to_line, get_line from require "moonscript.util" | 1115 | struct control : normal<Rule> {}; |
| 1012 | import unpack from require "moonscript.util" | ||
| 1013 | import wrap_env from require "moonscript.parse.env" | ||
| 1014 | 1116 | ||
| 1015 | { | 1117 | template<> |
| 1016 | :R, :S, :V, :P, :C, :Ct, :Cmt, :Cg, :Cb, :Cc | 1118 | struct control<ImportNameListNode> : normal<ImportNameListNode> |
| 1017 | } = lpeg | 1119 | { |
| 1120 | template<typename Input> | ||
| 1121 | static void start(Input& in, State& st) | ||
| 1122 | { | ||
| 1123 | st.astStack.emplace_back(); | ||
| 1124 | } | ||
| 1018 | 1125 | ||
| 1019 | { | 1126 | template<typename Input> |
| 1020 | :White, :Break, :Stop, :Comment, :Space, :SomeSpace, :SpaceBreak, :EmptyLine, | 1127 | static void failure(Input& /*unused*/, State& st) |
| 1021 | :AlphaNum, :Num, :Shebang, :L | 1128 | { |
| 1022 | Name: _Name | 1129 | st.astStack.pop_back(); |
| 1023 | } = require "moonscript.parse.literals" | 1130 | } |
| 1024 | 1131 | ||
| 1025 | SpaceName = Space * _Name | 1132 | template<typename Input> |
| 1026 | Num = Space * (Num / (v) -> {"number", v}) | 1133 | static void success(Input& /*unused*/, State& st) |
| 1134 | { | ||
| 1135 | } | ||
| 1136 | }; | ||
| 1137 | } | ||
| 1027 | 1138 | ||
| 1139 | int main() | ||
| 1028 | { | 1140 | { |
| 1029 | :Indent, :Cut, :ensure, :extract_line, :mark, :pos, :flatten_or_mark, | 1141 | analyze<moon::BlockWithEnd>(); |
| 1030 | :is_assignable, :check_assignable, :format_assign, :format_single_assign, | 1142 | moon::State state; |
| 1031 | :sym, :symx, :simple_string, :wrap_func_arg, :join_chain, | 1143 | string_input<> inName(R"xoxox( |
| 1032 | :wrap_decorator, :check_lua_string, :self_assign, :got | 1144 | |
| 1033 | 1145 | Dorothy! | |
| 1034 | } = require "moonscript.parse.util" | 1146 | EditMenuView = require "View.Control.Operation.EditMenu" |
| 1035 | 1147 | MessageBox = require "Control.Basic.MessageBox" | |
| 1036 | 1148 | ||
| 1037 | build_grammar = wrap_env debug_grammar, (root) -> | 1149 | -- [no signals] |
| 1038 | _indent = Stack 0 | 1150 | -- [no params] |
| 1039 | _do_stack = Stack 0 | 1151 | Class EditMenuView, |
| 1040 | 1152 | __init:=> | |
| 1041 | state = { | 1153 | {:width} = CCDirector.winSize |
| 1042 | -- last pos we saw, used to report error location | 1154 | isHide = false |
| 1043 | last_pos: 0 | 1155 | |
| 1044 | } | 1156 | @itemArea\setupMenuScroll @itemMenu |
| 1045 | 1157 | @itemArea.viewSize = @itemMenu\alignItems! | |
| 1046 | check_indent = (str, pos, indent) -> | 1158 | |
| 1047 | state.last_pos = pos | 1159 | for child in *@itemMenu.children |
| 1048 | _indent\top! == indent | 1160 | child.positionX = -35 |
| 1049 | 1161 | child.visible = false | |
| 1050 | advance_indent = (str, pos, indent) -> | 1162 | child.displayed = false |
| 1051 | top = _indent\top! | 1163 | @showItemButtons {"graphic","physics","logic","data"},true,true |
| 1052 | if top != -1 and indent > top | 1164 | |
| 1053 | _indent\push indent | 1165 | buttonNames = { |
| 1054 | true | 1166 | "sprite","model","body" |
| 1055 | 1167 | "effect","layer","world" | |
| 1056 | push_indent = (str, pos, indent) -> | 1168 | } |
| 1057 | _indent\push indent | ||
| 1058 | true | ||
| 1059 | |||
| 1060 | pop_indent = -> | ||
| 1061 | assert _indent\pop!, "unexpected outdent" | ||
| 1062 | true | ||
| 1063 | |||
| 1064 | check_do = (str, pos, do_node) -> | ||
| 1065 | top = _do_stack\top! | ||
| 1066 | if top == nil or top | ||
| 1067 | return true, do_node | ||
| 1068 | false | ||
| 1069 | |||
| 1070 | disable_do = -> | ||
| 1071 | _do_stack\push false | ||
| 1072 | true | ||
| 1073 | |||
| 1074 | pop_do = -> | ||
| 1075 | assert _do_stack\pop! != nil, "unexpected do pop" | ||
| 1076 | true | ||
| 1077 | |||
| 1078 | DisableDo = Cmt "", disable_do | ||
| 1079 | PopDo = Cmt "", pop_do | ||
| 1080 | |||
| 1081 | keywords = {} | ||
| 1082 | key = (chars) -> | ||
| 1083 | keywords[chars] = true | ||
| 1084 | Space * chars * -AlphaNum | ||
| 1085 | |||
| 1086 | op = (chars) -> | ||
| 1087 | patt = Space * C chars | ||
| 1088 | -- it's a word, treat like keyword | ||
| 1089 | if chars\match "^%w*$" | ||
| 1090 | keywords[chars] = true | ||
| 1091 | patt *= -AlphaNum | ||
| 1092 | |||
| 1093 | patt | ||
| 1094 | |||
| 1095 | Name = Cmt(SpaceName, (str, pos, name) -> | ||
| 1096 | return false if keywords[name] | ||
| 1097 | true | ||
| 1098 | ) / trim | ||
| 1099 | |||
| 1100 | SelfName = Space * "@" * ( | ||
| 1101 | "@" * (_Name / mark"self_class" + Cc"self.__class") + | ||
| 1102 | _Name / mark"self" + | ||
| 1103 | Cc"self" -- @ by itself | ||
| 1104 | ) | ||
| 1105 | |||
| 1106 | KeyName = SelfName + Space * _Name / mark"key_literal" | ||
| 1107 | VarArg = Space * P"..." / trim | ||
| 1108 | |||
| 1109 | g = P { | ||
| 1110 | root or File | ||
| 1111 | File: Shebang^-1 * (Block + Ct"") | ||
| 1112 | Block: Ct(Line * (Break^1 * Line)^0) | ||
| 1113 | CheckIndent: Cmt(Indent, check_indent), -- validates line is in correct indent | ||
| 1114 | Line: (CheckIndent * Statement + Space * L(Stop)) | ||
| 1115 | |||
| 1116 | Statement: pos( | ||
| 1117 | Import + While + With + For + ForEach + Switch + Return + | ||
| 1118 | Local + Export + BreakLoop + | ||
| 1119 | Ct(ExpList) * (Update + Assign)^-1 / format_assign | ||
| 1120 | ) * Space * (( | ||
| 1121 | -- statement decorators | ||
| 1122 | key"if" * Exp * (key"else" * Exp)^-1 * Space / mark"if" + | ||
| 1123 | key"unless" * Exp / mark"unless" + | ||
| 1124 | CompInner / mark"comprehension" | ||
| 1125 | ) * Space)^-1 / wrap_decorator | ||
| 1126 | |||
| 1127 | Body: Space^-1 * Break * EmptyLine^0 * InBlock + Ct(Statement) -- either a statement, or an indented block | ||
| 1128 | |||
| 1129 | Advance: L Cmt(Indent, advance_indent) -- Advances the indent, gives back whitespace for CheckIndent | ||
| 1130 | PushIndent: Cmt(Indent, push_indent) | ||
| 1131 | PreventIndent: Cmt(Cc(-1), push_indent) | ||
| 1132 | PopIndent: Cmt("", pop_indent) | ||
| 1133 | InBlock: Advance * Block * PopIndent | ||
| 1134 | |||
| 1135 | Local: key"local" * ((op"*" + op"^") / mark"declare_glob" + Ct(NameList) / mark"declare_with_shadows") | ||
| 1136 | |||
| 1137 | Import: key"import" * Ct(ImportNameList) * SpaceBreak^0 * key"from" * Exp / mark"import" | ||
| 1138 | ImportName: (sym"\\" * Ct(Cc"colon" * Name) + Name) | ||
| 1139 | ImportNameList: SpaceBreak^0 * ImportName * ((SpaceBreak^1 + sym"," * SpaceBreak^0) * ImportName)^0 | ||
| 1140 | |||
| 1141 | BreakLoop: Ct(key"break"/trim) + Ct(key"continue"/trim) | ||
| 1142 | |||
| 1143 | Return: key"return" * (ExpListLow/mark"explist" + C"") / mark"return" | ||
| 1144 | |||
| 1145 | WithExp: Ct(ExpList) * Assign^-1 / format_assign | ||
| 1146 | With: key"with" * DisableDo * ensure(WithExp, PopDo) * key"do"^-1 * Body / mark"with" | ||
| 1147 | |||
| 1148 | Switch: key"switch" * DisableDo * ensure(Exp, PopDo) * key"do"^-1 * Space^-1 * Break * SwitchBlock / mark"switch" | ||
| 1149 | |||
| 1150 | SwitchBlock: EmptyLine^0 * Advance * Ct(SwitchCase * (Break^1 * SwitchCase)^0 * (Break^1 * SwitchElse)^-1) * PopIndent | ||
| 1151 | SwitchCase: key"when" * Ct(ExpList) * key"then"^-1 * Body / mark"case" | ||
| 1152 | SwitchElse: key"else" * Body / mark"else" | ||
| 1153 | |||
| 1154 | IfCond: Exp * Assign^-1 / format_single_assign | ||
| 1155 | |||
| 1156 | IfElse: (Break * EmptyLine^0 * CheckIndent)^-1 * key"else" * Body / mark"else" | ||
| 1157 | IfElseIf: (Break * EmptyLine^0 * CheckIndent)^-1 * key"elseif" * pos(IfCond) * key"then"^-1 * Body / mark"elseif" | ||
| 1158 | |||
| 1159 | If: key"if" * IfCond * key"then"^-1 * Body * IfElseIf^0 * IfElse^-1 / mark"if" | ||
| 1160 | Unless: key"unless" * IfCond * key"then"^-1 * Body * IfElseIf^0 * IfElse^-1 / mark"unless" | ||
| 1161 | |||
| 1162 | While: key"while" * DisableDo * ensure(Exp, PopDo) * key"do"^-1 * Body / mark"while" | ||
| 1163 | |||
| 1164 | For: key"for" * DisableDo * ensure(Name * sym"=" * Ct(Exp * sym"," * Exp * (sym"," * Exp)^-1), PopDo) * | ||
| 1165 | key"do"^-1 * Body / mark"for" | ||
| 1166 | |||
| 1167 | ForEach: key"for" * Ct(AssignableNameList) * key"in" * DisableDo * ensure(Ct(sym"*" * Exp / mark"unpack" + ExpList), PopDo) * key"do"^-1 * Body / mark"foreach" | ||
| 1168 | |||
| 1169 | Do: key"do" * Body / mark"do" | ||
| 1170 | |||
| 1171 | Comprehension: sym"[" * Exp * CompInner * sym"]" / mark"comprehension" | ||
| 1172 | |||
| 1173 | TblComprehension: sym"{" * Ct(Exp * (sym"," * Exp)^-1) * CompInner * sym"}" / mark"tblcomprehension" | ||
| 1174 | |||
| 1175 | CompInner: Ct((CompForEach + CompFor) * CompClause^0) | ||
| 1176 | CompForEach: key"for" * Ct(AssignableNameList) * key"in" * (sym"*" * Exp / mark"unpack" + Exp) / mark"foreach" | ||
| 1177 | CompFor: key "for" * Name * sym"=" * Ct(Exp * sym"," * Exp * (sym"," * Exp)^-1) / mark"for" | ||
| 1178 | CompClause: CompFor + CompForEach + key"when" * Exp / mark"when" | ||
| 1179 | |||
| 1180 | Assign: sym"=" * (Ct(With + If + Switch) + Ct(TableBlock + ExpListLow)) / mark"assign" | ||
| 1181 | Update: ((sym"..=" + sym"+=" + sym"-=" + sym"*=" + sym"/=" + sym"%=" + sym"or=" + sym"and=" + sym"&=" + sym"|=" + sym">>=" + sym"<<=") / trim) * Exp / mark"update" | ||
| 1182 | |||
| 1183 | CharOperators: Space * C(S"+-*/%^><|&") | ||
| 1184 | WordOperators: op"or" + op"and" + op"<=" + op">=" + op"~=" + op"!=" + op"==" + op".." + op"<<" + op">>" + op"//" | ||
| 1185 | BinaryOperator: (WordOperators + CharOperators) * SpaceBreak^0 | ||
| 1186 | |||
| 1187 | Assignable: Cmt(Chain, check_assignable) + Name + SelfName | ||
| 1188 | Exp: Ct(Value * (BinaryOperator * Value)^0) / flatten_or_mark"exp" | ||
| 1189 | |||
| 1190 | SimpleValue: | ||
| 1191 | If + Unless + | ||
| 1192 | Switch + | ||
| 1193 | With + | ||
| 1194 | ClassDecl + | ||
| 1195 | ForEach + For + While + | ||
| 1196 | Cmt(Do, check_do) + | ||
| 1197 | sym"-" * -SomeSpace * Exp / mark"minus" + | ||
| 1198 | sym"#" * Exp / mark"length" + | ||
| 1199 | sym"~" * Exp / mark"bitnot" + | ||
| 1200 | key"not" * Exp / mark"not" + | ||
| 1201 | TblComprehension + | ||
| 1202 | TableLit + | ||
| 1203 | Comprehension + | ||
| 1204 | FunLit + | ||
| 1205 | Num | ||
| 1206 | |||
| 1207 | -- a function call or an object access | ||
| 1208 | ChainValue: (Chain + Callable) * Ct(InvokeArgs^-1) / join_chain | ||
| 1209 | |||
| 1210 | Value: pos( | ||
| 1211 | SimpleValue + | ||
| 1212 | Ct(KeyValueList) / mark"table" + | ||
| 1213 | ChainValue + | ||
| 1214 | String) | ||
| 1215 | |||
| 1216 | SliceValue: Exp | ||
| 1217 | |||
| 1218 | String: Space * DoubleString + Space * SingleString + LuaString | ||
| 1219 | SingleString: simple_string("'") | ||
| 1220 | DoubleString: simple_string('"', true) | ||
| 1221 | |||
| 1222 | LuaString: Cg(LuaStringOpen, "string_open") * Cb"string_open" * Break^-1 * | ||
| 1223 | C((1 - Cmt(C(LuaStringClose) * Cb"string_open", check_lua_string))^0) * | ||
| 1224 | LuaStringClose / mark"string" | ||
| 1225 | |||
| 1226 | LuaStringOpen: sym"[" * P"="^0 * "[" / trim | ||
| 1227 | LuaStringClose: "]" * P"="^0 * "]" | ||
| 1228 | |||
| 1229 | Callable: pos(Name / mark"ref") + SelfName + VarArg + Parens / mark"parens" | ||
| 1230 | Parens: sym"(" * SpaceBreak^0 * Exp * SpaceBreak^0 * sym")" | ||
| 1231 | |||
| 1232 | FnArgs: symx"(" * SpaceBreak^0 * Ct(FnArgsExpList^-1) * SpaceBreak^0 * sym")" + sym"!" * -P"=" * Ct"" | ||
| 1233 | FnArgsExpList: Exp * ((Break + sym",") * White * Exp)^0 | ||
| 1234 | |||
| 1235 | Chain: (Callable + String + -S".\\") * ChainItems / mark"chain" + | ||
| 1236 | Space * (DotChainItem * ChainItems^-1 + ColonChain) / mark"chain" | ||
| 1237 | |||
| 1238 | ChainItems: ChainItem^1 * ColonChain^-1 + ColonChain | ||
| 1239 | |||
| 1240 | ChainItem: | ||
| 1241 | Invoke + | ||
| 1242 | DotChainItem + | ||
| 1243 | Slice + | ||
| 1244 | symx"[" * Exp/mark"index" * sym"]" | ||
| 1245 | |||
| 1246 | DotChainItem: symx"." * _Name/mark"dot" | ||
| 1247 | ColonChainItem: symx"\\" * _Name / mark"colon" | ||
| 1248 | ColonChain: ColonChainItem * (Invoke * ChainItems^-1)^-1 | ||
| 1249 | |||
| 1250 | Slice: symx"[" * (SliceValue + Cc(1)) * sym"," * (SliceValue + Cc"") * | ||
| 1251 | (sym"," * SliceValue)^-1 *sym"]" / mark"slice" | ||
| 1252 | |||
| 1253 | Invoke: FnArgs / mark"call" + | ||
| 1254 | SingleString / wrap_func_arg + | ||
| 1255 | DoubleString / wrap_func_arg + | ||
| 1256 | L(P"[") * LuaString / wrap_func_arg | ||
| 1257 | |||
| 1258 | TableValue: KeyValue + Ct(Exp) | ||
| 1259 | |||
| 1260 | TableLit: sym"{" * Ct( | ||
| 1261 | TableValueList^-1 * sym","^-1 * | ||
| 1262 | (SpaceBreak * TableLitLine * (sym","^-1 * SpaceBreak * TableLitLine)^0 * sym","^-1)^-1 | ||
| 1263 | ) * White * sym"}" / mark"table" | ||
| 1264 | |||
| 1265 | TableValueList: TableValue * (sym"," * TableValue)^0 | ||
| 1266 | TableLitLine: PushIndent * ((TableValueList * PopIndent) + (PopIndent * Cut)) + Space | ||
| 1267 | |||
| 1268 | -- the unbounded table | ||
| 1269 | TableBlockInner: Ct(KeyValueLine * (SpaceBreak^1 * KeyValueLine)^0) | ||
| 1270 | TableBlock: SpaceBreak^1 * Advance * ensure(TableBlockInner, PopIndent) / mark"table" | ||
| 1271 | |||
| 1272 | ClassDecl: key"class" * -P":" * (Assignable + Cc(nil)) * (key"extends" * PreventIndent * ensure(Exp, PopIndent) + C"")^-1 * (ClassBlock + Ct("")) / mark"class" | ||
| 1273 | |||
| 1274 | ClassBlock: SpaceBreak^1 * Advance * | ||
| 1275 | Ct(ClassLine * (SpaceBreak^1 * ClassLine)^0) * PopIndent | ||
| 1276 | ClassLine: CheckIndent * (( | ||
| 1277 | KeyValueList / mark"props" + | ||
| 1278 | Statement / mark"stm" + | ||
| 1279 | Exp / mark"stm" | ||
| 1280 | ) * sym","^-1) | ||
| 1281 | |||
| 1282 | Export: key"export" * ( | ||
| 1283 | Cc"class" * ClassDecl + | ||
| 1284 | op"*" + op"^" + | ||
| 1285 | Ct(NameList) * (sym"=" * Ct(ExpListLow))^-1) / mark"export" | ||
| 1286 | |||
| 1287 | KeyValue: (sym":" * -SomeSpace * Name * lpeg.Cp!) / self_assign + | ||
| 1288 | Ct( | ||
| 1289 | (KeyName + sym"[" * Exp * sym"]" +Space * DoubleString + Space * SingleString) * | ||
| 1290 | symx":" * | ||
| 1291 | (Exp + TableBlock + SpaceBreak^1 * Exp) | ||
| 1292 | ) | ||
| 1293 | |||
| 1294 | KeyValueList: KeyValue * (sym"," * KeyValue)^0 | ||
| 1295 | KeyValueLine: CheckIndent * KeyValueList * sym","^-1 | ||
| 1296 | |||
| 1297 | FnArgsDef: sym"(" * White * Ct(FnArgDefList^-1) * | ||
| 1298 | (key"using" * Ct(NameList + Space * "nil") + Ct"") * | ||
| 1299 | White * sym")" + Ct"" * Ct"" | ||
| 1300 | |||
| 1301 | FnArgDefList: FnArgDef * ((sym"," + Break) * White * FnArgDef)^0 * ((sym"," + Break) * White * Ct(VarArg))^0 + Ct(VarArg) | ||
| 1302 | FnArgDef: Ct((Name + SelfName) * (sym"=" * Exp)^-1) | ||
| 1303 | |||
| 1304 | FunLit: FnArgsDef * | ||
| 1305 | (sym"->" * Cc"slim" + sym"=>" * Cc"fat") * | ||
| 1306 | (Body + Ct"") / mark"fndef" | ||
| 1307 | |||
| 1308 | NameList: Name * (sym"," * Name)^0 | ||
| 1309 | NameOrDestructure: Name + TableLit | ||
| 1310 | AssignableNameList: NameOrDestructure * (sym"," * NameOrDestructure)^0 | ||
| 1311 | |||
| 1312 | ExpList: Exp * (sym"," * Exp)^0 | ||
| 1313 | ExpListLow: Exp * ((sym"," + sym";") * Exp)^0 | ||
| 1314 | |||
| 1315 | -- open args | ||
| 1316 | InvokeArgs: -P"-" * (ExpList * (sym"," * (TableBlock + SpaceBreak * Advance * ArgBlock * TableBlock^-1) + TableBlock)^-1 + TableBlock) | ||
| 1317 | ArgBlock: ArgLine * (sym"," * SpaceBreak * ArgLine)^0 * PopIndent | ||
| 1318 | ArgLine: CheckIndent * ExpList | ||
| 1319 | } | ||
| 1320 | |||
| 1321 | g, state | ||
| 1322 | |||
| 1323 | file_parser = -> | ||
| 1324 | g, state = build_grammar! | ||
| 1325 | file_grammar = White * g * White * -1 | ||
| 1326 | |||
| 1327 | { | ||
| 1328 | match: (str) => | ||
| 1329 | local tree | ||
| 1330 | _, err = xpcall (-> | ||
| 1331 | tree = file_grammar\match str | ||
| 1332 | ), (err) -> | ||
| 1333 | debug.traceback err, 2 | ||
| 1334 | |||
| 1335 | -- regular error, let it bubble up | ||
| 1336 | if type(err) == "string" | ||
| 1337 | return nil, err | ||
| 1338 | |||
| 1339 | unless tree | ||
| 1340 | local msg | ||
| 1341 | err_pos = state.last_pos | ||
| 1342 | |||
| 1343 | if err | ||
| 1344 | node, msg = unpack err | ||
| 1345 | msg = " " .. msg if msg | ||
| 1346 | err_pos = node[-1] | ||
| 1347 | |||
| 1348 | line_no = pos_to_line str, err_pos | ||
| 1349 | line_str = get_line(str, line_no) or "" | ||
| 1350 | return nil, err_msg\format msg or "", line_no, trim line_str | ||
| 1351 | |||
| 1352 | tree | ||
| 1353 | } | ||
| 1354 | 1169 | ||
| 1355 | { | 1170 | clearSelection = -> |
| 1356 | :extract_line | 1171 | for name in *buttonNames |
| 1357 | :build_grammar | 1172 | with @[name.."Btn"] |
| 1173 | if .selected | ||
| 1174 | .selected = false | ||
| 1175 | .color = ccColor3 0x00ffff | ||
| 1176 | .scaleX = 0 | ||
| 1177 | .scaleY = 0 | ||
| 1178 | \perform oScale 0.3,1,1,oEase.OutBack | ||
| 1179 | emit .event,nil | ||
| 1180 | |||
| 1181 | for name in *buttonNames | ||
| 1182 | with @[name.."Btn"] | ||
| 1183 | .selected = false | ||
| 1184 | upperName = name\sub(1,1)\upper!..name\sub(2,-1) | ||
| 1185 | .event = "Scene."..upperName.."Selected" | ||
| 1186 | @gslot .event,(item)-> | ||
| 1187 | if item | ||
| 1188 | .selected = true | ||
| 1189 | .color = ccColor3 0xff0088 | ||
| 1190 | .scaleX = 0 | ||
| 1191 | .scaleY = 0 | ||
| 1192 | \perform oScale 0.3,1,1,oEase.OutBack | ||
| 1193 | \slot "Tapped",-> | ||
| 1194 | if not .selected | ||
| 1195 | emit "Scene.View"..upperName | ||
| 1196 | clearSelection! | ||
| 1197 | else | ||
| 1198 | .selected = false | ||
| 1199 | .color = ccColor3 0x00ffff | ||
| 1200 | emit .event,nil | ||
| 1201 | |||
| 1202 | @triggerBtn\slot "Tapped",-> | ||
| 1203 | clearSelection! | ||
| 1204 | if @pickPanel.visible | ||
| 1205 | MessageBox text:"Pick An Item First",okOnly:true | ||
| 1206 | else | ||
| 1207 | emit "Scene.Trigger.Open" | ||
| 1208 | |||
| 1209 | @actionBtn\slot "Tapped",-> | ||
| 1210 | clearSelection! | ||
| 1211 | if @pickPanel.visible | ||
| 1212 | MessageBox text:"Pick An Item First",okOnly:true | ||
| 1213 | else | ||
| 1214 | emit "Scene.Action.Open" | ||
| 1215 | |||
| 1216 | @aiBtn\slot "Tapped",-> | ||
| 1217 | clearSelection! | ||
| 1218 | if @pickPanel.visible | ||
| 1219 | MessageBox text:"Pick An Item First",okOnly:true | ||
| 1220 | else | ||
| 1221 | emit "Scene.AITree.Open" | ||
| 1222 | |||
| 1223 | @unitBtn\slot "Tapped",-> | ||
| 1224 | clearSelection! | ||
| 1225 | if @pickPanel.visible | ||
| 1226 | MessageBox text:"Pick An Item First",okOnly:true | ||
| 1227 | else | ||
| 1228 | emit "Scene.Unit.Open" | ||
| 1229 | |||
| 1230 | @delBtn\slot "Tapped",-> | ||
| 1231 | clearSelection! | ||
| 1232 | emit "Scene.EditMenu.Delete" | ||
| 1233 | |||
| 1234 | mode = 0 | ||
| 1235 | @zoomBtn\slot "Tapped",-> | ||
| 1236 | scale = switch mode | ||
| 1237 | when 0 then 2 | ||
| 1238 | when 1 then 0.5 | ||
| 1239 | when 2 then 1 | ||
| 1240 | mode += 1 | ||
| 1241 | mode %= 3 | ||
| 1242 | @zoomBtn.text = string.format("%d%%",scale*100) | ||
| 1243 | emit "Scene.ViewArea.ScaleTo",scale | ||
| 1244 | |||
| 1245 | @originBtn\slot "Tapped",-> editor\moveTo oVec2.zero | ||
| 1246 | |||
| 1247 | @progressUp.visible = false | ||
| 1248 | @progressDown.visible = false | ||
| 1249 | |||
| 1250 | with @upBtn | ||
| 1251 | .visible = false | ||
| 1252 | .enabled = false | ||
| 1253 | \slot "TapBegan",-> | ||
| 1254 | clearSelection! | ||
| 1255 | \schedule once -> | ||
| 1256 | sleep 0.4 | ||
| 1257 | @progressUp.visible = true | ||
| 1258 | @progressUp\play! | ||
| 1259 | \slot "Tapped",-> | ||
| 1260 | if @progressUp.visible | ||
| 1261 | if @progressUp.done | ||
| 1262 | emit "Scene.EditMenu.Top" | ||
| 1263 | else | ||
| 1264 | emit "Scene.EditMenu.Up" | ||
| 1265 | \slot "TapEnded",-> | ||
| 1266 | \unschedule! | ||
| 1267 | if @progressUp.visible | ||
| 1268 | @progressUp.visible = false | ||
| 1269 | |||
| 1270 | with @downBtn | ||
| 1271 | .visible = false | ||
| 1272 | .enabled = false | ||
| 1273 | \slot "TapBegan",-> | ||
| 1274 | clearSelection! | ||
| 1275 | \schedule once -> | ||
| 1276 | sleep 0.4 | ||
| 1277 | @progressDown.visible = true | ||
| 1278 | @progressDown\play! | ||
| 1279 | \slot "Tapped",-> | ||
| 1280 | if @progressDown.visible | ||
| 1281 | if @progressDown.done | ||
| 1282 | emit "Scene.EditMenu.Bottom" | ||
| 1283 | else | ||
| 1284 | emit "Scene.EditMenu.Down" | ||
| 1285 | \slot "TapEnded",-> | ||
| 1286 | \unschedule! | ||
| 1287 | if @progressDown.visible | ||
| 1288 | @progressDown.visible = false | ||
| 1289 | |||
| 1290 | with @foldBtn | ||
| 1291 | .visible = false | ||
| 1292 | .enabled = false | ||
| 1293 | \slot "Tapped",-> | ||
| 1294 | clearSelection! | ||
| 1295 | emit "Scene.ViewPanel.Fold",editor.currentData | ||
| 1296 | |||
| 1297 | with @editBtn | ||
| 1298 | .visible = false | ||
| 1299 | .enabled = false | ||
| 1300 | \slot "Tapped",-> | ||
| 1301 | emit "Scene.SettingPanel.Edit",nil | ||
| 1302 | editor\editCurrentItemInPlace! | ||
| 1303 | |||
| 1304 | with @menuBtn | ||
| 1305 | .dirty = false | ||
| 1306 | \slot "Tapped",-> | ||
| 1307 | clearSelection! | ||
| 1308 | if .dirty | ||
| 1309 | editor\save! | ||
| 1310 | emit "Scene.Dirty",false | ||
| 1311 | else | ||
| 1312 | ScenePanel = require "Control.Item.ScenePanel" | ||
| 1313 | ScenePanel! | ||
| 1314 | emit "Scene.SettingPanel.Edit",nil | ||
| 1315 | |||
| 1316 | with @undoBtn | ||
| 1317 | .visible = false | ||
| 1318 | \slot "Tapped",-> | ||
| 1319 | clearSelection! | ||
| 1320 | editor.currentSceneFile = editor.currentSceneFile | ||
| 1321 | emit "Scene.Dirty",false | ||
| 1322 | |||
| 1323 | with @xFixBtn | ||
| 1324 | .visible = false | ||
| 1325 | \slot "Tapped",(button)-> | ||
| 1326 | editor.xFix = not editor.xFix | ||
| 1327 | if editor.yFix | ||
| 1328 | editor.yFix = false | ||
| 1329 | @yFixBtn.color = ccColor3 0x00ffff | ||
| 1330 | button.color = ccColor3 editor.xFix and 0xff0088 or 0x00ffff | ||
| 1331 | emit "Scene.FixChange" | ||
| 1332 | |||
| 1333 | with @yFixBtn | ||
| 1334 | .visible = false | ||
| 1335 | \slot "Tapped",(button)-> | ||
| 1336 | editor.yFix = not editor.yFix | ||
| 1337 | if editor.xFix | ||
| 1338 | editor.xFix = false | ||
| 1339 | @xFixBtn.color = ccColor3 0x00ffff | ||
| 1340 | button.color = ccColor3 editor.yFix and 0xff0088 or 0x00ffff | ||
| 1341 | emit "Scene.FixChange" | ||
| 1342 | |||
| 1343 | @iconCam.visible = false | ||
| 1344 | |||
| 1345 | currentSubCam = nil | ||
| 1346 | with @camBtn | ||
| 1347 | .visible = false | ||
| 1348 | .editing = false | ||
| 1349 | \gslot "Scene.Camera.Select",(subCam)-> | ||
| 1350 | currentSubCam = subCam | ||
| 1351 | \slot "Tapped",-> | ||
| 1352 | .editing = not .editing | ||
| 1353 | if .editing | ||
| 1354 | emit "Scene.Camera.Activate",currentSubCam | ||
| 1355 | else | ||
| 1356 | emit "Scene.Camera.Activate",nil | ||
| 1357 | |||
| 1358 | with @zoomEditBtn | ||
| 1359 | .visible = false | ||
| 1360 | .editing = false | ||
| 1361 | \slot "Tapped",-> | ||
| 1362 | .editing = not .editing | ||
| 1363 | if .editing and currentSubCam | ||
| 1364 | emit "Scene.Edit.ShowRuler", {currentSubCam.zoom,0.5,10,1,(value)-> | ||
| 1365 | emit "Scene.ViewArea.Scale",value | ||
| 1366 | } | ||
| 1367 | else | ||
| 1368 | emit "Scene.Edit.ShowRuler",nil | ||
| 1369 | |||
| 1370 | @playBtn\slot "Tapped",-> | ||
| 1371 | settings = editor\getSettings! | ||
| 1372 | sceneFile = if settings.StartupScene | ||
| 1373 | editor.sceneFullPath..settings.StartupScene..".scene" | ||
| 1374 | else | ||
| 1375 | nil | ||
| 1376 | if not sceneFile or not oContent\exist sceneFile | ||
| 1377 | MessageBox text:"Startup Scene\nIs Required!",okOnly:true | ||
| 1378 | return | ||
| 1379 | @menuBtn\emit "Tapped" if @menuBtn.dirty | ||
| 1380 | -- test codes below | ||
| 1381 | Game = require "Lib.Game.Game" | ||
| 1382 | game = Game editor.game,false | ||
| 1383 | editorData = editor\getEditorData! | ||
| 1384 | editorData.lastScene = editor.lastScene | ||
| 1385 | emit "Scene.EditorData",editorData | ||
| 1386 | editor\emit "Quit",game\loadScene! | ||
| 1387 | |||
| 1388 | setupItemButton = (button,groupLine,subItems)-> | ||
| 1389 | groupLine.data = button | ||
| 1390 | with button | ||
| 1391 | .showItem = false | ||
| 1392 | \slot "Tapped",-> | ||
| 1393 | return if .scheduled | ||
| 1394 | .showItem = not .showItem | ||
| 1395 | if .showItem | ||
| 1396 | groupLine.visible = true | ||
| 1397 | groupLine.opacity = 0 | ||
| 1398 | groupLine\perform oOpacity 0.3,1 | ||
| 1399 | groupLine.position = button.position-oVec2 25,25 | ||
| 1400 | else | ||
| 1401 | \schedule once -> | ||
| 1402 | groupLine\perform oOpacity 0.3,0 | ||
| 1403 | sleep 0.3 | ||
| 1404 | groupLine.visible = false | ||
| 1405 | @showItemButtons subItems,.showItem | ||
| 1406 | setupItemButton @graphicBtn,@graphicLine,{"sprite","model","effect","layer"} | ||
| 1407 | setupItemButton @physicsBtn,@physicsLine,{"body","world"} | ||
| 1408 | setupItemButton @logicBtn,@logicLine,{"trigger","action","ai"} | ||
| 1409 | setupItemButton @dataBtn,@dataLine,{"unit"} | ||
| 1410 | |||
| 1411 | @gslot "Scene.ShowFix",(value)-> | ||
| 1412 | editor.xFix = false | ||
| 1413 | editor.yFix = false | ||
| 1414 | emit "Scene.FixChange" | ||
| 1415 | if value | ||
| 1416 | with @xFixBtn | ||
| 1417 | .visible = true | ||
| 1418 | .color = ccColor3 0x00ffff | ||
| 1419 | .scaleX = 0 | ||
| 1420 | .scaleY = 0 | ||
| 1421 | \perform oScale 0.5,1,1,oEase.OutBack | ||
| 1422 | with @yFixBtn | ||
| 1423 | .visible = true | ||
| 1424 | .color = ccColor3 0x00ffff | ||
| 1425 | .scaleX = 0 | ||
| 1426 | .scaleY = 0 | ||
| 1427 | \perform oScale 0.5,1,1,oEase.OutBack | ||
| 1428 | else | ||
| 1429 | @xFixBtn.visible = false | ||
| 1430 | @yFixBtn.visible = false | ||
| 1431 | |||
| 1432 | @gslot "Scene.Dirty",(dirty)-> | ||
| 1433 | with @menuBtn | ||
| 1434 | if .dirty ~= dirty | ||
| 1435 | .dirty = dirty | ||
| 1436 | if dirty | ||
| 1437 | .text = "Save" | ||
| 1438 | with @undoBtn | ||
| 1439 | if not .visible | ||
| 1440 | .enabled = true | ||
| 1441 | .visible = true | ||
| 1442 | .scaleX = 0 | ||
| 1443 | .scaleY = 0 | ||
| 1444 | \perform oScale 0.3,1,1,oEase.OutBack | ||
| 1445 | else | ||
| 1446 | .color = ccColor3 0x00ffff | ||
| 1447 | .text = "Menu" | ||
| 1448 | with @undoBtn | ||
| 1449 | if .visible | ||
| 1450 | .enabled = false | ||
| 1451 | \perform CCSequence { | ||
| 1452 | oScale 0.3,0,0,oEase.InBack | ||
| 1453 | CCHide! | ||
| 1454 | } | ||
| 1455 | |||
| 1456 | itemChoosed = (itemData)-> | ||
| 1457 | return if isHide | ||
| 1458 | if @camBtn.visible or @iconCam.visible | ||
| 1459 | @iconCam.visible = false | ||
| 1460 | @camBtn.visible = false | ||
| 1461 | emit "Scene.Camera.Activate",nil | ||
| 1462 | emit "Scene.Camera.Select",nil | ||
| 1463 | emit "Scene.ViewPanel.FoldState",{ | ||
| 1464 | itemData:itemData | ||
| 1465 | handler:(state)-> | ||
| 1466 | if state ~= nil | ||
| 1467 | @setButtonVisible @foldBtn,true | ||
| 1468 | switch itemData.typeName | ||
| 1469 | when "Body","Model","Effect" | ||
| 1470 | @setButtonVisible @editBtn,true | ||
| 1471 | else | ||
| 1472 | @setButtonVisible @editBtn,false | ||
| 1473 | text = @foldBtn.text | ||
| 1474 | targetText = state and "Un\nFold" or "Fold" | ||
| 1475 | if text ~= targetText | ||
| 1476 | @foldBtn.text = targetText | ||
| 1477 | if @foldBtn.scale.done | ||
| 1478 | @setButtonVisible @foldBtn,true | ||
| 1479 | else | ||
| 1480 | @setButtonVisible @foldBtn,false | ||
| 1481 | @setButtonVisible @upBtn,false | ||
| 1482 | @setButtonVisible @downBtn,false | ||
| 1483 | @setButtonVisible @editBtn,false | ||
| 1484 | } | ||
| 1485 | return unless itemData | ||
| 1486 | switch itemData.typeName | ||
| 1487 | when "Camera","PlatformWorld","UILayer" | ||
| 1488 | @setButtonVisible @upBtn,false | ||
| 1489 | @setButtonVisible @downBtn,false | ||
| 1490 | {:x,:y} = @upBtn.position | ||
| 1491 | @foldBtn\runAction oPos 0.3,x,y,oEase.OutQuad | ||
| 1492 | if itemData.typeName == "Camera" | ||
| 1493 | clearSelection! | ||
| 1494 | with @iconCam | ||
| 1495 | .visible = true | ||
| 1496 | .scaleX = 0 | ||
| 1497 | .scaleY = 0 | ||
| 1498 | \perform oScale 0.3,0.5,0.5,oEase.OutBack | ||
| 1499 | else | ||
| 1500 | item = editor\getItem itemData | ||
| 1501 | hasChildren = false | ||
| 1502 | if itemData.typeName == "World" | ||
| 1503 | hasChildren = #item.parent.parent.children > 1 | ||
| 1504 | else | ||
| 1505 | hasChildren = #item.parent.children > 1 | ||
| 1506 | if item.parent.children and hasChildren | ||
| 1507 | @setButtonVisible @upBtn,true | ||
| 1508 | @setButtonVisible @downBtn,true | ||
| 1509 | {:x,:y} = @downBtn.position | ||
| 1510 | @foldBtn\runAction oPos 0.3,x,y-60,oEase.OutQuad | ||
| 1511 | @editBtn\runAction oPos 0.3,x,y-120,oEase.OutQuad | ||
| 1512 | else | ||
| 1513 | @setButtonVisible @upBtn,false | ||
| 1514 | @setButtonVisible @downBtn,false | ||
| 1515 | {:x,:y} = @upBtn.position | ||
| 1516 | @foldBtn\runAction oPos 0.3,x,y,oEase.OutQuad | ||
| 1517 | @editBtn\runAction oPos 0.3,x,y-60,oEase.OutQuad | ||
| 1518 | @gslot "Scene.ViewPanel.Pick",itemChoosed | ||
| 1519 | @gslot "Scene.ViewPanel.Select",itemChoosed | ||
| 1520 | |||
| 1521 | @gslot "Scene.ViewArea.Scale",(scale)-> | ||
| 1522 | mode = 2 if scale ~= 1 | ||
| 1523 | @zoomBtn.text = string.format("%d%%",scale*100) | ||
| 1524 | @gslot "Scene.ViewArea.ScaleReset",-> | ||
| 1525 | mode = 0 | ||
| 1526 | @zoomBtn.text = "100%" | ||
| 1527 | emit "Scene.ViewArea.ScaleTo",1 | ||
| 1528 | |||
| 1529 | @gslot "Scene.Camera.Select",(subCam)-> | ||
| 1530 | if subCam and not @camBtn.visible | ||
| 1531 | @iconCam.opacity = 0 | ||
| 1532 | with @camBtn | ||
| 1533 | .visible = true | ||
| 1534 | .scaleX = 0 | ||
| 1535 | .scaleY = 0 | ||
| 1536 | \perform oScale 0.3,1,1,oEase.OutBack | ||
| 1537 | else | ||
| 1538 | @camBtn.visible = false | ||
| 1539 | with @iconCam | ||
| 1540 | .opacity = 1 | ||
| 1541 | .scaleX = 0 | ||
| 1542 | .scaleY = 0 | ||
| 1543 | \perform oScale 0.3,0.5,0.5,oEase.OutBack | ||
| 1544 | |||
| 1545 | changeDisplay = (child)-> | ||
| 1546 | if child.positionX < width/2 | ||
| 1547 | child\perform oPos 0.5,-child.positionX,child.positionY,oEase.OutQuad | ||
| 1548 | else | ||
| 1549 | child\perform oPos 0.5,width*2-child.positionX,child.positionY,oEase.OutQuad | ||
| 1550 | |||
| 1551 | @gslot "Scene.HideEditor",(args)-> | ||
| 1552 | {hide,all} = args | ||
| 1553 | return if isHide == hide | ||
| 1554 | isHide = hide | ||
| 1555 | @enabled = @camBtn.editing or not hide | ||
| 1556 | for i = 1,#@children | ||
| 1557 | child = @children[i] | ||
| 1558 | switch child | ||
| 1559 | when @camBtn | ||
| 1560 | posX = @camBtn.editing and width-35 or width-345 | ||
| 1561 | child\perform oPos 0.5,posX,child.positionY,oEase.OutQuad | ||
| 1562 | when @menuBtn,@undoBtn,@zoomEditBtn,@iconCam | ||
| 1563 | if all | ||
| 1564 | changeDisplay child | ||
| 1565 | else | ||
| 1566 | continue | ||
| 1567 | else | ||
| 1568 | changeDisplay child | ||
| 1569 | |||
| 1570 | @gslot "Scene.Camera.Activate",(subCam)-> | ||
| 1571 | editor.isFixed = not @camBtn.editing | ||
| 1572 | if subCam | ||
| 1573 | with @zoomEditBtn | ||
| 1574 | .scaleX = 0 | ||
| 1575 | .scaleY = 0 | ||
| 1576 | .visible = true | ||
| 1577 | \perform CCSequence { | ||
| 1578 | CCDelay 0.5 | ||
| 1579 | oScale 0.3,1,1,oEase.OutBack | ||
| 1580 | } | ||
| 1581 | else | ||
| 1582 | @zoomEditBtn.visible = false | ||
| 1583 | @zoomEditBtn.editing = false | ||
| 1584 | emit "Scene.Edit.ShowRuler",nil | ||
| 1585 | |||
| 1586 | @gslot "Scene.EditMenu.ClearSelection",clearSelection | ||
| 1587 | |||
| 1588 | setButtonVisible:(button,visible)=> | ||
| 1589 | return if visible == button.enabled | ||
| 1590 | button.enabled = visible | ||
| 1591 | if visible | ||
| 1592 | if not button.visible | ||
| 1593 | button.visible = true | ||
| 1594 | button.scaleX = 0 | ||
| 1595 | button.scaleY = 0 | ||
| 1596 | button\perform oScale 0.3,1,1,oEase.OutBack | ||
| 1597 | else | ||
| 1598 | button\perform CCSequence { | ||
| 1599 | oScale 0.3,0,0,oEase.InBack | ||
| 1600 | CCHide! | ||
| 1601 | } | ||
| 1358 | 1602 | ||
| 1359 | -- parse a string as a file | 1603 | showItemButtons:(names,visible,instant=false)=> |
| 1360 | -- returns tree, or nil and error message | 1604 | buttonSet = {@["#{name}Btn"],true for name in *names} |
| 1361 | string: (str) -> file_parser!\match str | 1605 | posX = 35 |
| 1362 | } | 1606 | posY = @itemMenu.height-25 |
| 1363 | )xoxo", "abc"); | 1607 | if visible |
| 1608 | offset = @itemArea.offset | ||
| 1609 | firstItem = nil | ||
| 1610 | for child in *@itemMenu.children | ||
| 1611 | isTarget = buttonSet[child] | ||
| 1612 | firstItem = child if isTarget and not firstItem | ||
| 1613 | if child.displayed or isTarget | ||
| 1614 | offsetX = switch child | ||
| 1615 | when @graphicBtn,@physicsBtn,@logicBtn,@dataBtn then 0 | ||
| 1616 | else 20 | ||
| 1617 | child.position = offset+oVec2(posX+offsetX,posY) | ||
| 1618 | if isTarget | ||
| 1619 | child.displayed = true | ||
| 1620 | child.visible = true | ||
| 1621 | if not instant | ||
| 1622 | child.face.scaleY = 0 | ||
| 1623 | child.face\perform oScale 0.3,1,1,oEase.OutBack | ||
| 1624 | posY -= 60 | ||
| 1625 | elseif child.data -- data is parentButton | ||
| 1626 | child.position = child.data.position-oVec2(25,25) | ||
| 1627 | @itemArea.viewSize = CCSize 70,@itemArea.height-posY-35 | ||
| 1628 | @itemArea\scrollToPosY firstItem.positionY | ||
| 1629 | else | ||
| 1630 | @itemMenu\schedule once -> | ||
| 1631 | if not instant | ||
| 1632 | for child in *@itemMenu.children | ||
| 1633 | if buttonSet[child] | ||
| 1634 | child.face\perform oScale 0.3,1,0,oEase.OutQuad | ||
| 1635 | sleep 0.3 | ||
| 1636 | offset = @itemArea.offset | ||
| 1637 | lastPosY = nil | ||
| 1638 | for child in *@itemMenu.children | ||
| 1639 | if buttonSet[child] | ||
| 1640 | child.positionX = -35 | ||
| 1641 | child.displayed = false | ||
| 1642 | child.visible = false | ||
| 1643 | lastPosY = child.positionY | ||
| 1644 | elseif child.displayed | ||
| 1645 | if lastPosY and child.positionY < lastPosY | ||
| 1646 | child.face.scaleY = 0 | ||
| 1647 | child.face\perform oScale 0.3,1,1,oEase.OutBack | ||
| 1648 | offsetX = switch child | ||
| 1649 | when @graphicBtn,@physicsBtn,@logicBtn,@dataBtn then 0 | ||
| 1650 | else 20 | ||
| 1651 | child.position = offset+oVec2(posX+offsetX,posY) | ||
| 1652 | posY -= 60 | ||
| 1653 | elseif lastPosY and child.data and child.positionY < lastPosY | ||
| 1654 | child.opacity = 0 | ||
| 1655 | child\perform oOpacity 0.3,1 | ||
| 1656 | child.position = child.data.position-oVec2(25,25) | ||
| 1657 | @itemArea.viewSize = CCSize 70,@itemArea.height-posY-35 | ||
| 1658 | |||
| 1659 | )xoxox", "abc"); | ||
| 1660 | |||
| 1661 | string_input<> in(R"PIG(import Path, Struct from require "utils")PIG", "bcd"); | ||
| 1364 | try | 1662 | try |
| 1365 | { | 1663 | { |
| 1366 | if (parse<must<moon::BlockWithEnd>, moon::action>(inName, state)) | 1664 | if (parse<must<moon::Import, eof>, moon::action, moon::control>(in, state)) |
| 1367 | { | 1665 | { |
| 1368 | std::cout << "matched.\n"; | 1666 | std::cout << "matched.\n"; |
| 1369 | } | 1667 | } |
| @@ -1374,6 +1672,7 @@ file_parser = -> | |||
| 1374 | } | 1672 | } |
| 1375 | catch (parse_error e) | 1673 | catch (parse_error e) |
| 1376 | { | 1674 | { |
| 1675 | std::cout << "not matched.\n"; | ||
| 1377 | std::cout << e.what() << '\n'; | 1676 | std::cout << e.what() << '\n'; |
| 1378 | } | 1677 | } |
| 1379 | /* | 1678 | /* |
