Go で書き直した Ikemen
Révision | 4218929c8ba477ebfe9da2ca8b595f33cd84e3ca (tree) |
---|---|
l'heure | 2016-12-23 11:28:24 |
Auteur | SUEHIRO <supersuehiro@user...> |
Commiter | SUEHIRO |
リダイレクトがちゃんとできていなかった
@@ -67,6 +67,7 @@ const ( | ||
67 | 67 | OC_dup |
68 | 68 | OC_swap |
69 | 69 | OC_run |
70 | + OC_ocrun | |
70 | 71 | OC_jsf8 |
71 | 72 | OC_jmp8 |
72 | 73 | OC_jz8 |
@@ -188,7 +189,6 @@ const ( | ||
188 | 189 | OC_hitfall |
189 | 190 | OC_hitvel_x |
190 | 191 | OC_hitvel_y |
191 | - OC_roundsexisted | |
192 | 192 | OC_parent |
193 | 193 | OC_root |
194 | 194 | OC_helper |
@@ -362,6 +362,7 @@ const ( | ||
362 | 362 | OC_ex_matchover |
363 | 363 | OC_ex_matchno |
364 | 364 | OC_ex_roundno |
365 | + OC_ex_roundsexisted | |
365 | 366 | OC_ex_ishometeam |
366 | 367 | OC_ex_tickspersecond |
367 | 368 | OC_ex_timemod |
@@ -375,7 +376,7 @@ type StringPool struct { | ||
375 | 376 | func NewStringPool() *StringPool { |
376 | 377 | return &StringPool{Map: make(map[string]int)} |
377 | 378 | } |
378 | -func (sp *StringPool) Clear(s string) { | |
379 | +func (sp *StringPool) Clear() { | |
379 | 380 | sp.List, sp.Map = nil, make(map[string]int) |
380 | 381 | } |
381 | 382 | func (sp *StringPool) Add(s string) int { |
@@ -634,7 +635,7 @@ func (_ BytecodeExp) blor(v1 *BytecodeValue, v2 BytecodeValue) { | ||
634 | 635 | v1.SetB(v1.ToB() || v2.ToB()) |
635 | 636 | } |
636 | 637 | func (be BytecodeExp) run(c *Char, scpn int) BytecodeValue { |
637 | - orgc := c | |
638 | + oc := c | |
638 | 639 | for i := 1; i <= len(be); i++ { |
639 | 640 | switch be[i-1] { |
640 | 641 | case OC_jsf8: |
@@ -730,6 +731,15 @@ func (be BytecodeExp) run(c *Char, scpn int) BytecodeValue { | ||
730 | 731 | } |
731 | 732 | sys.bcStack.Push(BytecodeSF()) |
732 | 733 | i += int(*(*int32)(unsafe.Pointer(&be[i]))) + 4 |
734 | + case OC_run: | |
735 | + l := int(*(*int32)(unsafe.Pointer(&be[i]))) | |
736 | + sys.bcStack.Push(be[i+4:i+4+l].run(c, scpn)) | |
737 | + i += 4 + l | |
738 | + case OC_ocrun: | |
739 | + l := int(*(*int32)(unsafe.Pointer(&be[i]))) | |
740 | + sys.bcStack.Push(be[i+4:i+4+l].run(oc, scpn)) | |
741 | + i += 4 + l | |
742 | + continue | |
733 | 743 | case OC_int8: |
734 | 744 | sys.bcStack.Push(BytecodeInt(int32(int8(be[i])))) |
735 | 745 | i++ |
@@ -813,10 +823,6 @@ func (be BytecodeExp) run(c *Char, scpn int) BytecodeValue { | ||
813 | 823 | sys.bcStack.Dup() |
814 | 824 | case OC_swap: |
815 | 825 | sys.bcStack.Swap() |
816 | - case OC_run: | |
817 | - l := int(*(*int32)(unsafe.Pointer(&be[i]))) | |
818 | - sys.bcStack.Push(be[i+4:i+4+l].run(c, scpn)) | |
819 | - i += 4 + l | |
820 | 826 | case OC_time: |
821 | 827 | sys.bcStack.Push(BytecodeInt(c.time())) |
822 | 828 | case OC_alive: |
@@ -839,7 +845,7 @@ func (be BytecodeExp) run(c *Char, scpn int) BytecodeValue { | ||
839 | 845 | println(be[i-1]) |
840 | 846 | unimplemented() |
841 | 847 | } |
842 | - c = orgc | |
848 | + c = oc | |
843 | 849 | } |
844 | 850 | return sys.bcStack.Pop() |
845 | 851 | } |
@@ -490,8 +490,32 @@ func (c *Compiler) kyuushikiSuperDX(out *BytecodeExp, in *string, | ||
490 | 490 | c.usiroOp = true |
491 | 491 | return nil |
492 | 492 | } |
493 | -func (c *Compiler) expValue(out *BytecodeExp, in *string) (BytecodeValue, | |
494 | - error) { | |
493 | +func (c *Compiler) oneArg(fun string, out *BytecodeExp, in *string, | |
494 | + rd, appendVal bool) (BytecodeValue, error) { | |
495 | + if c.tokenizer(in) != "(" { | |
496 | + return BytecodeSF(), Error(fun + "の次に'('がありません") | |
497 | + } | |
498 | + c.token = c.tokenizer(in) | |
499 | + var be BytecodeExp | |
500 | + bv, err := c.expBoolOr(&be, in) | |
501 | + if err != nil { | |
502 | + return BytecodeSF(), err | |
503 | + } | |
504 | + if err := c.kakkotojiru(in); err != nil { | |
505 | + return BytecodeSF(), err | |
506 | + } | |
507 | + if appendVal { | |
508 | + be.appendValue(bv) | |
509 | + bv = BytecodeSF() | |
510 | + } | |
511 | + if rd && len(be) > 0 { | |
512 | + out.appendJmp(OC_ocrun, int32(len(be))) | |
513 | + } | |
514 | + out.append(be...) | |
515 | + return bv, nil | |
516 | +} | |
517 | +func (c *Compiler) expValue(out *BytecodeExp, in *string, | |
518 | + rd bool) (BytecodeValue, error) { | |
495 | 519 | c.usiroOp, c.norange = true, false |
496 | 520 | bv := c.number(c.token) |
497 | 521 | if !bv.IsSF() { |
@@ -535,42 +559,52 @@ func (c *Compiler) expValue(out *BytecodeExp, in *string) (BytecodeValue, | ||
535 | 559 | c.token = c.tokenizer(in) |
536 | 560 | if c.token == "(" { |
537 | 561 | c.token = c.tokenizer(in) |
538 | - if bv1, err = c.expBoolOr(out, in); err != nil { | |
562 | + if bv1, err = c.expBoolOr(&be1, in); err != nil { | |
539 | 563 | return BytecodeSF(), err |
540 | 564 | } |
541 | 565 | if err := c.kakkotojiru(in); err != nil { |
542 | 566 | return BytecodeSF(), err |
543 | 567 | } |
544 | 568 | c.token = c.tokenizer(in) |
545 | - out.appendValue(bv1) | |
569 | + be1.appendValue(bv1) | |
546 | 570 | } else { |
547 | 571 | switch opc { |
548 | 572 | case OC_helper, OC_target: |
549 | - out.appendValue(BytecodeInt(-1)) | |
573 | + be1.appendValue(BytecodeInt(-1)) | |
550 | 574 | case OC_partner, OC_enemy, OC_enemynear: |
551 | - out.appendValue(BytecodeInt(0)) | |
575 | + be1.appendValue(BytecodeInt(0)) | |
552 | 576 | case OC_playerid: |
553 | 577 | return BytecodeSF(), Error("playeridの次に'('がありません") |
554 | 578 | } |
555 | 579 | } |
556 | 580 | } |
581 | + if rd { | |
582 | + out.appendJmp(OC_ocrun, int32(len(be1))) | |
583 | + } | |
584 | + out.append(be1...) | |
557 | 585 | if c.token != "," { |
558 | 586 | return BytecodeSF(), Error(",がありません") |
559 | 587 | } |
560 | 588 | c.token = c.tokenizer(in) |
561 | - bv1, err = c.expValue(&be1, in) | |
589 | + bv2, err = c.expValue(&be2, in, true) | |
562 | 590 | if err != nil { |
563 | 591 | return BytecodeSF(), err |
564 | 592 | } |
565 | - be1.appendValue(bv1) | |
566 | - out.appendJmp(opc, int32(len(be1))) | |
567 | - out.append(be1...) | |
593 | + be2.appendValue(bv2) | |
594 | + out.appendJmp(opc, int32(len(be2))) | |
595 | + out.append(be2...) | |
568 | 596 | return BytecodeSF(), nil |
569 | 597 | case "(": |
570 | 598 | c.token = c.tokenizer(in) |
571 | 599 | if bv, err = c.expBoolOr(&be1, in); err != nil { |
572 | 600 | return BytecodeSF(), err |
573 | 601 | } |
602 | + if bv.IsSF() { | |
603 | + if rd { | |
604 | + out.appendJmp(OC_jmp, int32(0)) // NOPでリダイレクトをもどす | |
605 | + } | |
606 | + out.append(be1...) | |
607 | + } | |
574 | 608 | if err := c.kakkotojiru(in); err != nil { |
575 | 609 | return BytecodeSF(), err |
576 | 610 | } |
@@ -583,8 +617,12 @@ func (c *Compiler) expValue(out *BytecodeExp, in *string) (BytecodeValue, | ||
583 | 617 | } |
584 | 618 | } else { |
585 | 619 | c.token = c.tokenizer(in) |
586 | - bv, err = c.expValue(out, in) | |
620 | + bv, err = c.expValue(&be1, in, false) | |
587 | 621 | if bv.IsSF() { |
622 | + if rd { | |
623 | + out.appendJmp(OC_jmp, int32(0)) // NOPでリダイレクトをもどす | |
624 | + } | |
625 | + out.append(be1...) | |
588 | 626 | out.append(OC_neg) |
589 | 627 | } else { |
590 | 628 | out.neg(&bv) |
@@ -592,25 +630,30 @@ func (c *Compiler) expValue(out *BytecodeExp, in *string) (BytecodeValue, | ||
592 | 630 | } |
593 | 631 | case "~": |
594 | 632 | c.token = c.tokenizer(in) |
595 | - bv, err = c.expValue(out, in) | |
633 | + bv, err = c.expValue(&be1, in, false) | |
596 | 634 | if bv.IsSF() { |
635 | + if rd { | |
636 | + out.appendJmp(OC_jmp, int32(0)) // NOPでリダイレクトをもどす | |
637 | + } | |
638 | + out.append(be1...) | |
597 | 639 | out.append(OC_not) |
598 | 640 | } else { |
599 | 641 | out.not(&bv) |
600 | 642 | } |
601 | 643 | case "!": |
602 | 644 | c.token = c.tokenizer(in) |
603 | - bv, err = c.expValue(out, in) | |
645 | + bv, err = c.expValue(&be1, in, false) | |
604 | 646 | if bv.IsSF() { |
647 | + if rd { | |
648 | + out.appendJmp(OC_jmp, int32(0)) // NOPでリダイレクトをもどす | |
649 | + } | |
650 | + out.append(be1...) | |
605 | 651 | out.append(OC_blnot) |
606 | 652 | } else { |
607 | 653 | out.blnot(&bv) |
608 | 654 | } |
609 | - case "time": | |
610 | - out.append(OC_time) | |
611 | - case "alive": | |
612 | - out.append(OC_alive) | |
613 | - case "ifelse": | |
655 | + case "ifelse", "cond": | |
656 | + cond := c.token == "cond" | |
614 | 657 | if c.tokenizer(in) != "(" { |
615 | 658 | return BytecodeSF(), Error(c.token + "の次に'('がありません") |
616 | 659 | } |
@@ -636,13 +679,40 @@ func (c *Compiler) expValue(out *BytecodeExp, in *string) (BytecodeValue, | ||
636 | 679 | return BytecodeSF(), err |
637 | 680 | } |
638 | 681 | if bv1.IsSF() || bv2.IsSF() || bv3.IsSF() { |
639 | - out.append(be1...) | |
640 | - out.appendValue(bv1) | |
641 | - out.append(be2...) | |
642 | - out.appendValue(bv2) | |
643 | - out.append(be3...) | |
644 | - out.appendValue(bv3) | |
645 | - out.append(OC_ifelse) | |
682 | + if cond { | |
683 | + be3.appendValue(bv3) | |
684 | + be2.appendValue(bv2) | |
685 | + if len(be3) > int(math.MaxUint8-1) { | |
686 | + be2.appendJmp(OC_jmp, int32(len(be3)+1)) | |
687 | + } else { | |
688 | + be2.append(OC_jmp8, OpCode(len(be3)+1)) | |
689 | + } | |
690 | + be1.appendValue(bv1) | |
691 | + if len(be2) > int(math.MaxUint8-1) { | |
692 | + be1.appendJmp(OC_jz, int32(len(be2)+1)) | |
693 | + } else { | |
694 | + be1.append(OC_jz8, OpCode(len(be2)+1)) | |
695 | + } | |
696 | + be1.append(OC_pop) | |
697 | + be1.append(be2...) | |
698 | + be1.append(OC_pop) | |
699 | + be1.append(be3...) | |
700 | + if rd { | |
701 | + out.appendJmp(OC_run, int32(len(be1))) // NOPでリダイレクトをもどす | |
702 | + } | |
703 | + out.append(be1...) | |
704 | + } else { | |
705 | + if rd { | |
706 | + out.appendJmp(OC_jmp, int32(0)) // NOPでリダイレクトをもどす | |
707 | + } | |
708 | + out.append(be1...) | |
709 | + out.appendValue(bv1) | |
710 | + out.append(be2...) | |
711 | + out.appendValue(bv2) | |
712 | + out.append(be3...) | |
713 | + out.appendValue(bv3) | |
714 | + out.append(OC_ifelse) | |
715 | + } | |
646 | 716 | } else { |
647 | 717 | if bv1.ToB() { |
648 | 718 | bv = bv2 |
@@ -650,6 +720,10 @@ func (c *Compiler) expValue(out *BytecodeExp, in *string) (BytecodeValue, | ||
650 | 720 | bv = bv3 |
651 | 721 | } |
652 | 722 | } |
723 | + case "time": | |
724 | + out.append(OC_time) | |
725 | + case "alive": | |
726 | + out.append(OC_alive) | |
653 | 727 | case "random": |
654 | 728 | out.append(OC_random) |
655 | 729 | case "roundstate": |
@@ -673,7 +747,11 @@ func (c *Compiler) expValue(out *BytecodeExp, in *string) (BytecodeValue, | ||
673 | 747 | if n <= 0 { |
674 | 748 | return BytecodeSF(), Error("animelemのは0より大きくなければいけません") |
675 | 749 | } |
676 | - out.appendValue(BytecodeInt(n)) | |
750 | + be1.appendValue(BytecodeInt(n)) | |
751 | + if rd { | |
752 | + out.appendJmp(OC_ocrun, int32(len(be1))) | |
753 | + } | |
754 | + out.append(be1...) | |
677 | 755 | out.append(OC_animelemtime) |
678 | 756 | if err = c.kyuushikiSuperDX(&be, in, false); err != nil { |
679 | 757 | return BytecodeSF(), err |
@@ -681,17 +759,9 @@ func (c *Compiler) expValue(out *BytecodeExp, in *string) (BytecodeValue, | ||
681 | 759 | out.append(OC_jsf8, OpCode(len(be))) |
682 | 760 | out.append(be...) |
683 | 761 | case "animelemtime": |
684 | - if c.tokenizer(in) != "(" { | |
685 | - return BytecodeSF(), Error(c.token + "の次に'('がありません") | |
686 | - } | |
687 | - c.token = c.tokenizer(in) | |
688 | - if bv1, err = c.expBoolOr(out, in); err != nil { | |
689 | - return BytecodeSF(), err | |
690 | - } | |
691 | - if err := c.kakkotojiru(in); err != nil { | |
762 | + if _, err := c.oneArg(c.token, out, in, rd, true); err != nil { | |
692 | 763 | return BytecodeSF(), err |
693 | 764 | } |
694 | - out.appendValue(bv1) | |
695 | 765 | out.append(OC_animelemtime) |
696 | 766 | case "stateno": |
697 | 767 | out.append(OC_stateno) |
@@ -719,7 +789,7 @@ func (c *Compiler) renzokuEnzansihaError(in *string) error { | ||
719 | 789 | } |
720 | 790 | func (c *Compiler) expPostNot(out *BytecodeExp, in *string) (BytecodeValue, |
721 | 791 | error) { |
722 | - bv, err := c.expValue(out, in) | |
792 | + bv, err := c.expValue(out, in, false) | |
723 | 793 | if err != nil { |
724 | 794 | return BytecodeSF(), err |
725 | 795 | } |
@@ -740,7 +810,7 @@ func (c *Compiler) expPostNot(out *BytecodeExp, in *string) (BytecodeValue, | ||
740 | 810 | } |
741 | 811 | oldtoken, oldin := c.token, *in |
742 | 812 | var dummyout BytecodeExp |
743 | - if _, err := c.expValue(&dummyout, in); err != nil { | |
813 | + if _, err := c.expValue(&dummyout, in, false); err != nil { | |
744 | 814 | return BytecodeSF(), err |
745 | 815 | } |
746 | 816 | if c.isOperator(c.token) <= 0 { |
@@ -2324,11 +2394,10 @@ func (c *Compiler) stateCompile(bc *Bytecode, filename, def string) error { | ||
2324 | 2394 | if j < len(tr)-1 { |
2325 | 2395 | if len(te) > int(math.MaxUint8-1) { |
2326 | 2396 | tmp.appendJmp(OC_jz, int32(len(te)+1)) |
2327 | - tmp.append(OC_pop) | |
2328 | 2397 | } else { |
2329 | 2398 | tmp.append(OC_jz8, OpCode(len(te)+1)) |
2330 | - tmp.append(OC_pop) | |
2331 | 2399 | } |
2400 | + tmp.append(OC_pop) | |
2332 | 2401 | } |
2333 | 2402 | te = append(tmp, te...) |
2334 | 2403 | } |
@@ -2495,6 +2564,7 @@ func (c *Compiler) Compile(n int, def string) (*Bytecode, error) { | ||
2495 | 2564 | } |
2496 | 2565 | c.cmdl.Add(*cm) |
2497 | 2566 | } |
2567 | + sys.stringPool[n].Clear() | |
2498 | 2568 | for _, s := range st { |
2499 | 2569 | if len(s) > 0 { |
2500 | 2570 | if err := c.stateCompile(bc, s, def); err != nil { |