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 | /* |