Go で書き直した Ikemen
Revisión | 246d29c0aa4ff5b59a839d75c941cca29d05c0e3 (tree) |
---|---|
Tiempo | 2016-12-18 00:00:41 |
Autor | SUEHIRO <supersuehiro@user...> |
Commiter | SUEHIRO |
煩雑になると思ったのでステートコントローラーの定数専用の処理をやめた
@@ -63,6 +63,7 @@ const ( | ||
63 | 63 | OC_int8 |
64 | 64 | OC_int |
65 | 65 | OC_float |
66 | + OC_pop | |
66 | 67 | OC_dup |
67 | 68 | OC_swap |
68 | 69 | OC_jmp8 |
@@ -187,7 +188,6 @@ const ( | ||
187 | 188 | OC_hitvel_y |
188 | 189 | OC_roundno |
189 | 190 | OC_roundsexisted |
190 | - OC_matchno | |
191 | 191 | OC_ishometeam |
192 | 192 | OC_parent |
193 | 193 | OC_root |
@@ -359,6 +359,7 @@ const ( | ||
359 | 359 | OC_ex_loseko |
360 | 360 | OC_ex_losetime |
361 | 361 | OC_ex_drawgame |
362 | + OC_ex_matchno | |
362 | 363 | OC_ex_tickspersecond |
363 | 364 | ) |
364 | 365 |
@@ -425,6 +426,15 @@ func (bv *BytecodeValue) SetB(b bool) { | ||
425 | 426 | func BytecodeSF() BytecodeValue { |
426 | 427 | return BytecodeValue{VT_SFalse, math.NaN()} |
427 | 428 | } |
429 | +func BytecodeFloat(f float32) BytecodeValue { | |
430 | + return BytecodeValue{VT_Float, float64(f)} | |
431 | +} | |
432 | +func BytecodeInt(i int32) BytecodeValue { | |
433 | + return BytecodeValue{VT_Int, float64(i)} | |
434 | +} | |
435 | +func BytecodeBool(b bool) BytecodeValue { | |
436 | + return BytecodeValue{VT_Bool, float64(Btoi(b))} | |
437 | +} | |
428 | 438 | |
429 | 439 | type BytecodeStack []BytecodeValue |
430 | 440 |
@@ -449,29 +459,19 @@ type BytecodeExp []OpCode | ||
449 | 459 | func (be *BytecodeExp) append(op ...OpCode) { |
450 | 460 | *be = append(*be, op...) |
451 | 461 | } |
452 | -func (be *BytecodeExp) appendFloat(f float32) { | |
453 | - be.append((*(*[4]OpCode)(unsafe.Pointer(&f)))[:]...) | |
454 | -} | |
455 | -func (be *BytecodeExp) appendInt(i int32) { | |
456 | - be.append((*(*[4]OpCode)(unsafe.Pointer(&i)))[:]...) | |
457 | -} | |
458 | -func (be BytecodeExp) toF() float32 { | |
459 | - return *(*float32)(unsafe.Pointer(&be[0])) | |
460 | -} | |
461 | -func (be BytecodeExp) toI() int32 { | |
462 | - return *(*int32)(unsafe.Pointer(&be[0])) | |
463 | -} | |
464 | 462 | func (be *BytecodeExp) appendValue(bv BytecodeValue) (ok bool) { |
465 | 463 | switch bv.t { |
466 | 464 | case VT_Float: |
467 | 465 | be.append(OC_float) |
468 | - be.appendFloat(float32(bv.v)) | |
466 | + f := float32(bv.v) | |
467 | + be.append((*(*[4]OpCode)(unsafe.Pointer(&f)))[:]...) | |
469 | 468 | case VT_Int: |
470 | 469 | if bv.v >= -128 || bv.v <= 127 { |
471 | 470 | be.append(OC_int8, OpCode(bv.v)) |
472 | 471 | } else { |
473 | 472 | be.append(OC_int) |
474 | - be.appendInt(int32(bv.v)) | |
473 | + i := int32(bv.v) | |
474 | + be.append((*(*[4]OpCode)(unsafe.Pointer(&i)))[:]...) | |
475 | 475 | } |
476 | 476 | case VT_Bool: |
477 | 477 | if bv.v != 0 { |
@@ -484,6 +484,10 @@ func (be *BytecodeExp) appendValue(bv BytecodeValue) (ok bool) { | ||
484 | 484 | } |
485 | 485 | return true |
486 | 486 | } |
487 | +func (be *BytecodeExp) appendJmp(op OpCode, addr int32) { | |
488 | + be.append(OC_int) | |
489 | + be.append((*(*[4]OpCode)(unsafe.Pointer(&addr)))[:]...) | |
490 | +} | |
487 | 491 | func (_ BytecodeExp) blnot(v *BytecodeValue) { |
488 | 492 | if v.ToB() { |
489 | 493 | v.v = 0 |
@@ -624,14 +628,36 @@ func (be BytecodeExp) run(c *Char, scpn int) BytecodeValue { | ||
624 | 628 | sys.bcStack.Clear() |
625 | 629 | for i := 1; i <= len(be); i++ { |
626 | 630 | switch be[i-1] { |
631 | + case OC_jz8, OC_jnz8: | |
632 | + if sys.bcStack.Top().ToB() == (be[i-1] == OC_jz8) { | |
633 | + i++ | |
634 | + break | |
635 | + } | |
636 | + fallthrough | |
637 | + case OC_jmp8: | |
638 | + if be[i] == 0 { | |
639 | + i = len(be) | |
640 | + } else { | |
641 | + i += int(uint8(be[i])) + 1 | |
642 | + } | |
643 | + case OC_jz, OC_jnz: | |
644 | + if sys.bcStack.Top().ToB() == (be[i-1] == OC_jz) { | |
645 | + i += 4 | |
646 | + break | |
647 | + } | |
648 | + fallthrough | |
649 | + case OC_jmp: | |
650 | + i += int(*(*int32)(unsafe.Pointer(&be[i]))) + 4 | |
627 | 651 | case OC_int8: |
628 | 652 | sys.bcStack.Push(BytecodeValue{VT_Int, float64(int8(be[i]))}) |
629 | 653 | i++ |
630 | 654 | case OC_int: |
631 | - sys.bcStack.Push(BytecodeValue{VT_Int, float64(be[i:].toI())}) | |
655 | + sys.bcStack.Push(BytecodeValue{VT_Int, | |
656 | + float64(*(*int32)(unsafe.Pointer(&be[i])))}) | |
632 | 657 | i += 4 |
633 | 658 | case OC_float: |
634 | - sys.bcStack.Push(BytecodeValue{VT_Float, float64(be[i:].toF())}) | |
659 | + sys.bcStack.Push(BytecodeValue{VT_Float, | |
660 | + float64(*(*float32)(unsafe.Pointer(&be[i])))}) | |
635 | 661 | i += 4 |
636 | 662 | case OC_blnot: |
637 | 663 | be.blnot(sys.bcStack.Top()) |
@@ -689,10 +715,14 @@ func (be BytecodeExp) run(c *Char, scpn int) BytecodeValue { | ||
689 | 715 | case OC_blor: |
690 | 716 | v2 := sys.bcStack.Pop() |
691 | 717 | be.blor(sys.bcStack.Top(), v2) |
718 | + case OC_pop: | |
719 | + sys.bcStack.Pop() | |
692 | 720 | case OC_dup: |
693 | 721 | sys.bcStack.Dup() |
694 | 722 | case OC_swap: |
695 | 723 | sys.bcStack.Swap() |
724 | + case OC_time: | |
725 | + sys.bcStack.Push(BytecodeInt(c.time())) | |
696 | 726 | default: |
697 | 727 | unimplemented() |
698 | 728 | } |
@@ -710,13 +740,10 @@ func (be BytecodeExp) evalB(c *Char, scpn int) bool { | ||
710 | 740 | } |
711 | 741 | |
712 | 742 | type StateController interface { |
713 | - Run(c *Char, scpn int) (changeState bool) | |
743 | + Run(c *Char, ps *int32) (changeState bool) | |
714 | 744 | } |
715 | 745 | |
716 | -const ( | |
717 | - SCID_trigger byte = 0 | |
718 | - SCID_const byte = 128 | |
719 | -) | |
746 | +const SCID_trigger byte = 255 | |
720 | 747 | |
721 | 748 | type StateControllerBase struct { |
722 | 749 | playerNo int |
@@ -728,21 +755,21 @@ type StateControllerBase struct { | ||
728 | 755 | func newStateControllerBase(pn int) *StateControllerBase { |
729 | 756 | return &StateControllerBase{playerNo: pn, persistent: 1} |
730 | 757 | } |
731 | -func (scb StateControllerBase) beToExp(be ...BytecodeExp) []BytecodeExp { | |
758 | +func (_ StateControllerBase) beToExp(be ...BytecodeExp) []BytecodeExp { | |
732 | 759 | return be |
733 | 760 | } |
734 | -func (scb StateControllerBase) fToExp(f ...float32) (exp []BytecodeExp) { | |
761 | +func (_ StateControllerBase) fToExp(f ...float32) (exp []BytecodeExp) { | |
735 | 762 | for _, v := range f { |
736 | 763 | var be BytecodeExp |
737 | - be.appendFloat(v) | |
764 | + be.appendValue(BytecodeFloat(v)) | |
738 | 765 | exp = append(exp, be) |
739 | 766 | } |
740 | 767 | return |
741 | 768 | } |
742 | -func (scb StateControllerBase) iToExp(i ...int32) (exp []BytecodeExp) { | |
769 | +func (_ StateControllerBase) iToExp(i ...int32) (exp []BytecodeExp) { | |
743 | 770 | for _, v := range i { |
744 | 771 | var be BytecodeExp |
745 | - be.appendInt(v) | |
772 | + be.appendValue(BytecodeInt(v)) | |
746 | 773 | exp = append(exp, be) |
747 | 774 | } |
748 | 775 | return |
@@ -755,7 +782,12 @@ func (scb *StateControllerBase) add(id byte, exp []BytecodeExp) { | ||
755 | 782 | scb.code = append(scb.code, (*(*[]byte)(unsafe.Pointer(&e)))...) |
756 | 783 | } |
757 | 784 | } |
758 | -func (scb StateControllerBase) run(f func(byte, []BytecodeExp) bool) bool { | |
785 | +func (scb StateControllerBase) run(c *Char, ps *int32, | |
786 | + f func(byte, []BytecodeExp)) bool { | |
787 | + (*ps)-- | |
788 | + if *ps > 0 { | |
789 | + return false | |
790 | + } | |
759 | 791 | for i := 0; i < len(scb.code); { |
760 | 792 | id := scb.code[i] |
761 | 793 | i++ |
@@ -768,17 +800,22 @@ func (scb StateControllerBase) run(f func(byte, []BytecodeExp) bool) bool { | ||
768 | 800 | exp[m] = (*(*BytecodeExp)(unsafe.Pointer(&scb.code)))[i : i+int(l)] |
769 | 801 | i += int(l) |
770 | 802 | } |
771 | - if !f(id, exp) { | |
772 | - return false | |
803 | + if id == SCID_trigger { | |
804 | + if !exp[0].evalB(c, scb.playerNo) { | |
805 | + return false | |
806 | + } | |
807 | + } else { | |
808 | + f(id, exp) | |
773 | 809 | } |
774 | 810 | } |
811 | + *ps = scb.persistent | |
775 | 812 | return true |
776 | 813 | } |
777 | 814 | |
778 | 815 | type stateDef StateControllerBase |
779 | 816 | |
780 | 817 | const ( |
781 | - stateDef_hitcountpersist byte = iota + 1 | |
818 | + stateDef_hitcountpersist byte = iota | |
782 | 819 | stateDef_movehitpersist |
783 | 820 | stateDef_hitdefpersist |
784 | 821 | stateDef_sprpriority |
@@ -788,72 +825,46 @@ const ( | ||
788 | 825 | stateDef_anim |
789 | 826 | stateDef_ctrl |
790 | 827 | stateDef_poweradd |
791 | - stateDef_hitcountpersist_c = stateDef_hitcountpersist + SCID_const | |
792 | - stateDef_movehitpersist_c = stateDef_movehitpersist + SCID_const | |
793 | - stateDef_hitdefpersist_c = stateDef_hitdefpersist + SCID_const | |
794 | - stateDef_sprpriority_c = stateDef_sprpriority + SCID_const | |
795 | - stateDef_facep2_c = stateDef_facep2 + SCID_const | |
796 | - stateDef_juggle_c = stateDef_juggle + SCID_const | |
797 | - stateDef_velset_c = stateDef_velset + SCID_const | |
798 | - stateDef_anim_c = stateDef_anim + SCID_const | |
799 | - stateDef_ctrl_c = stateDef_ctrl + SCID_const | |
800 | - stateDef_poweradd_c = stateDef_poweradd + SCID_const | |
801 | 828 | ) |
802 | 829 | |
803 | -func (sd stateDef) Run(c *Char, scpn int) bool { | |
804 | - StateControllerBase(sd).run(func(id byte, exp []BytecodeExp) bool { | |
830 | +func (sc stateDef) Run(c *Char, ps *int32) bool { | |
831 | + StateControllerBase(sc).run(c, ps, func(id byte, exp []BytecodeExp) { | |
805 | 832 | switch id { |
806 | - case stateDef_hitcountpersist, stateDef_hitcountpersist_c: | |
807 | - if id == stateDef_hitcountpersist_c || !exp[0].evalB(c, scpn) { | |
833 | + case stateDef_hitcountpersist: | |
834 | + if !exp[0].evalB(c, sc.playerNo) { | |
808 | 835 | c.clearHitCount() |
809 | 836 | } |
810 | - case stateDef_movehitpersist, stateDef_movehitpersist_c: | |
811 | - if id == stateDef_movehitpersist_c || !exp[0].evalB(c, scpn) { | |
837 | + case stateDef_movehitpersist: | |
838 | + if !exp[0].evalB(c, sc.playerNo) { | |
812 | 839 | c.clearMoveHit() |
813 | 840 | } |
814 | - case stateDef_hitdefpersist, stateDef_hitdefpersist_c: | |
815 | - if id == stateDef_hitdefpersist_c || !exp[0].evalB(c, scpn) { | |
841 | + case stateDef_hitdefpersist: | |
842 | + if !exp[0].evalB(c, sc.playerNo) { | |
816 | 843 | c.clearHitDef() |
817 | 844 | } |
818 | 845 | case stateDef_sprpriority: |
819 | - c.setSprPriority(exp[0].evalI(c, scpn)) | |
820 | - case stateDef_sprpriority_c: | |
821 | - c.setSprPriority(exp[0].toI()) | |
822 | - case stateDef_facep2, stateDef_facep2_c: | |
823 | - if id == stateDef_facep2_c || exp[0].evalB(c, scpn) { | |
846 | + c.setSprPriority(exp[0].evalI(c, sc.playerNo)) | |
847 | + case stateDef_facep2: | |
848 | + if exp[0].evalB(c, sc.playerNo) { | |
824 | 849 | c.faceP2() |
825 | 850 | } |
826 | 851 | case stateDef_juggle: |
827 | - c.setJuggle(exp[0].evalI(c, scpn)) | |
828 | - case stateDef_juggle_c: | |
829 | - c.setJuggle(exp[0].toI()) | |
852 | + c.setJuggle(exp[0].evalI(c, sc.playerNo)) | |
830 | 853 | case stateDef_velset: |
831 | - c.setXV(exp[0].evalF(c, scpn)) | |
854 | + c.setXV(exp[0].evalF(c, sc.playerNo)) | |
832 | 855 | if len(exp) > 1 { |
833 | - c.setYV(exp[1].evalF(c, scpn)) | |
856 | + c.setYV(exp[1].evalF(c, sc.playerNo)) | |
834 | 857 | if len(exp) > 2 { |
835 | - exp[2].run(c, scpn) | |
858 | + exp[2].run(c, sc.playerNo) | |
836 | 859 | } |
837 | 860 | } |
838 | - case stateDef_velset_c: | |
839 | - c.setXV(exp[0].toF()) | |
840 | - if len(exp) > 1 { | |
841 | - c.setYV(exp[1].toF()) | |
842 | - } | |
843 | 861 | case stateDef_anim: |
844 | - c.changeAnim(exp[0].evalI(c, scpn)) | |
845 | - case stateDef_anim_c: | |
846 | - c.changeAnim(exp[0].toI()) | |
862 | + c.changeAnim(exp[0].evalI(c, sc.playerNo)) | |
847 | 863 | case stateDef_ctrl: |
848 | - c.setCtrl(exp[0].evalB(c, scpn)) | |
849 | - case stateDef_ctrl_c: | |
850 | - c.setCtrl(exp[0].toI() != 0) | |
864 | + c.setCtrl(exp[0].evalB(c, sc.playerNo)) | |
851 | 865 | case stateDef_poweradd: |
852 | - c.addPower(exp[0].evalI(c, scpn)) | |
853 | - case stateDef_poweradd_c: | |
854 | - c.addPower(exp[0].toI()) | |
866 | + c.addPower(exp[0].evalI(c, sc.playerNo)) | |
855 | 867 | } |
856 | - return true | |
857 | 868 | }) |
858 | 869 | return false |
859 | 870 | } |
@@ -861,23 +872,49 @@ func (sd stateDef) Run(c *Char, scpn int) bool { | ||
861 | 872 | type hitBy StateControllerBase |
862 | 873 | |
863 | 874 | const ( |
864 | - _hitBy_value byte = iota | |
865 | - _hitBy_value2 | |
875 | + hitBy_value byte = iota | |
876 | + hitBy_value2 | |
866 | 877 | hitBy_time |
867 | - hitBy_value_c = _hitBy_value + SCID_const | |
868 | - hitBy_value2_c = _hitBy_value2 + SCID_const | |
869 | - hitBy_time_c = hitBy_time + SCID_const | |
870 | 878 | ) |
871 | 879 | |
872 | -func (nhb hitBy) Run(c *Char, scpn int) bool { | |
873 | - unimplemented() | |
880 | +func (sc hitBy) Run(c *Char, ps *int32) bool { | |
881 | + time := int32(1) | |
882 | + StateControllerBase(sc).run(c, ps, func(id byte, exp []BytecodeExp) { | |
883 | + switch id { | |
884 | + case hitBy_time: | |
885 | + time = exp[0].evalI(c, sc.playerNo) | |
886 | + case hitBy_value: | |
887 | + unimplemented() | |
888 | + case hitBy_value2: | |
889 | + unimplemented() | |
890 | + } | |
891 | + }) | |
874 | 892 | return false |
875 | 893 | } |
876 | 894 | |
877 | 895 | type notHitBy hitBy |
878 | 896 | |
879 | -func (nhb notHitBy) Run(c *Char, scpn int) bool { | |
880 | - unimplemented() | |
897 | +func (sc notHitBy) Run(c *Char, ps *int32) bool { | |
898 | + time := int32(1) | |
899 | + StateControllerBase(sc).run(c, ps, func(id byte, exp []BytecodeExp) { | |
900 | + switch id { | |
901 | + case hitBy_time: | |
902 | + time = exp[0].evalI(c, sc.playerNo) | |
903 | + case hitBy_value: | |
904 | + unimplemented() | |
905 | + case hitBy_value2: | |
906 | + unimplemented() | |
907 | + } | |
908 | + }) | |
909 | + return false | |
910 | +} | |
911 | + | |
912 | +type assertSpecial StateControllerBase | |
913 | + | |
914 | +func (sc assertSpecial) Run(c *Char, ps *int32) bool { | |
915 | + StateControllerBase(sc).run(c, ps, func(id byte, exp []BytecodeExp) { | |
916 | + unimplemented() | |
917 | + }) | |
881 | 918 | return false |
882 | 919 | } |
883 | 920 |
@@ -568,3 +568,7 @@ func (c *Char) setCtrl(ctrl bool) { | ||
568 | 568 | func (c *Char) addPower(power int32) { |
569 | 569 | unimplemented() |
570 | 570 | } |
571 | +func (c *Char) time() int32 { | |
572 | + unimplemented() | |
573 | + return 0 | |
574 | +} |
@@ -149,6 +149,14 @@ func Atof(str string) float64 { | ||
149 | 149 | } |
150 | 150 | return f |
151 | 151 | } |
152 | +func readDigit(d string) (int32, bool) { | |
153 | + for _, c := range d { | |
154 | + if c < '0' || c > '9' { | |
155 | + return 0, false | |
156 | + } | |
157 | + } | |
158 | + return int32(Atof(d)), true | |
159 | +} | |
152 | 160 | func Btoi(b bool) int32 { |
153 | 161 | if b { |
154 | 162 | return 1 |
@@ -324,7 +324,13 @@ func (c *Compiler) expValue(out *BytecodeExp, in *string) (BytecodeValue, | ||
324 | 324 | if !sys.ignoreMostErrors { |
325 | 325 | defer func() { c.usiroOp = false }() |
326 | 326 | } |
327 | - unimplemented() | |
327 | + switch c.token { | |
328 | + case "time": | |
329 | + out.append(OC_time) | |
330 | + default: | |
331 | + println(c.token) | |
332 | + unimplemented() | |
333 | + } | |
328 | 334 | c.token = c.tokenizer(in) |
329 | 335 | return bv, nil |
330 | 336 | } |
@@ -704,42 +710,47 @@ func (c *Compiler) expBoolOr(out *BytecodeExp, in *string) (BytecodeValue, | ||
704 | 710 | return c.expOneOp(out, in, c.expBoolXor, "||", out.blor, OC_blor) |
705 | 711 | } |
706 | 712 | func (c *Compiler) typedExp(ef ExpFunc, in *string, |
707 | - vt ValueType) (BytecodeExp, BytecodeValue, error) { | |
713 | + vt ValueType) (BytecodeExp, error) { | |
708 | 714 | c.token = c.tokenizer(in) |
709 | 715 | var be BytecodeExp |
710 | 716 | bv, err := ef(&be, in) |
711 | 717 | if err != nil { |
712 | - return nil, BytecodeSF(), err | |
718 | + return nil, err | |
713 | 719 | } |
714 | 720 | if !bv.IsSF() { |
715 | - if vt == VT_Bool { | |
721 | + switch vt { | |
722 | + case VT_Float: | |
723 | + bv.SetF(bv.ToF()) | |
724 | + case VT_Int: | |
725 | + bv.SetI(bv.ToI()) | |
726 | + case VT_Bool: | |
716 | 727 | bv.SetB(bv.ToB()) |
717 | 728 | } |
718 | - return nil, bv, nil | |
729 | + be.appendValue(bv) | |
719 | 730 | } |
720 | - return be, BytecodeSF(), nil | |
731 | + return be, nil | |
721 | 732 | } |
722 | -func (c *Compiler) argExpression(in *string, | |
723 | - vt ValueType) (BytecodeExp, BytecodeValue, error) { | |
724 | - be, v, err := c.typedExp(c.expBoolOr, in, vt) | |
733 | +func (c *Compiler) argExpression(in *string, vt ValueType) (BytecodeExp, | |
734 | + error) { | |
735 | + be, err := c.typedExp(c.expBoolOr, in, vt) | |
725 | 736 | if err != nil { |
726 | - return nil, BytecodeSF(), err | |
737 | + return nil, err | |
727 | 738 | } |
728 | 739 | if len(c.token) > 0 && c.token != "," { |
729 | - return nil, BytecodeSF(), Error(c.token + "が不正です") | |
740 | + return nil, Error(c.token + "が不正です") | |
730 | 741 | } |
731 | - return be, v, nil | |
742 | + return be, nil | |
732 | 743 | } |
733 | -func (c *Compiler) fullExpression(in *string, | |
734 | - vt ValueType) (BytecodeExp, BytecodeValue, error) { | |
735 | - be, v, err := c.typedExp(c.expBoolOr, in, vt) | |
744 | +func (c *Compiler) fullExpression(in *string, vt ValueType) (BytecodeExp, | |
745 | + error) { | |
746 | + be, err := c.typedExp(c.expBoolOr, in, vt) | |
736 | 747 | if err != nil { |
737 | - return nil, BytecodeSF(), err | |
748 | + return nil, err | |
738 | 749 | } |
739 | 750 | if len(c.token) > 0 { |
740 | - return nil, BytecodeSF(), Error(c.token + "が不正です") | |
751 | + return nil, Error(c.token + "が不正です") | |
741 | 752 | } |
742 | - return be, v, nil | |
753 | + return be, nil | |
743 | 754 | } |
744 | 755 | func (c *Compiler) parseSection(lines []string, i *int, |
745 | 756 | sctrl func(name, data string) error) (IniSection, error) { |
@@ -843,50 +854,24 @@ func (c *Compiler) stateParam(is IniSection, name string, | ||
843 | 854 | } |
844 | 855 | func (c *Compiler) scAdd(sc *StateControllerBase, id byte, |
845 | 856 | data string, vt ValueType, numArg int) error { |
846 | - bes, vs := []BytecodeExp{}, []BytecodeValue{} | |
857 | + bes := []BytecodeExp{} | |
847 | 858 | for n := 1; n <= numArg; n++ { |
848 | 859 | var be BytecodeExp |
849 | - var v BytecodeValue | |
850 | 860 | var err error |
851 | 861 | if n < numArg { |
852 | - be, v, err = c.argExpression(&data, vt) | |
862 | + be, err = c.argExpression(&data, vt) | |
853 | 863 | } else { |
854 | - be, v, err = c.fullExpression(&data, vt) | |
864 | + be, err = c.fullExpression(&data, vt) | |
855 | 865 | } |
856 | 866 | if err != nil { |
857 | 867 | return err |
858 | 868 | } |
859 | 869 | bes = append(bes, be) |
860 | - vs = append(vs, v) | |
861 | - if n < numArg && c.token != "," { | |
870 | + if c.token != "," { | |
862 | 871 | break |
863 | 872 | } |
864 | 873 | } |
865 | - cns := true | |
866 | - for i, v := range vs { | |
867 | - if v.IsSF() { | |
868 | - cns = false | |
869 | - } else { | |
870 | - bes[i].appendValue(v) | |
871 | - } | |
872 | - } | |
873 | - if cns { | |
874 | - if vt == VT_Float { | |
875 | - floats := make([]float32, len(vs)) | |
876 | - for i := range floats { | |
877 | - floats[i] = float32(vs[i].v) | |
878 | - } | |
879 | - sc.add(id+SCID_const, sc.fToExp(floats...)) | |
880 | - } else { | |
881 | - ints := make([]int32, len(vs)) | |
882 | - for i := range ints { | |
883 | - ints[i] = int32(vs[i].v) | |
884 | - } | |
885 | - sc.add(id+SCID_const, sc.iToExp(ints...)) | |
886 | - } | |
887 | - } else { | |
888 | - sc.add(id, bes) | |
889 | - } | |
874 | + sc.add(id, bes) | |
890 | 875 | return nil |
891 | 876 | } |
892 | 877 | func (c *Compiler) stateDef(is IniSection, sbc *StateBytecode) error { |
@@ -959,59 +944,32 @@ func (c *Compiler) stateDef(is IniSection, sbc *StateBytecode) error { | ||
959 | 944 | b := false |
960 | 945 | if err := c.stateParam(is, "hitcountpersist", func(data string) error { |
961 | 946 | b = true |
962 | - be, v, err := c.fullExpression(&data, VT_Bool) | |
963 | - if err != nil { | |
964 | - return err | |
965 | - } | |
966 | - if v.IsSF() { | |
967 | - sc.add(stateDef_hitcountpersist, sc.beToExp(be)) | |
968 | - } else if !v.ToB() { // falseのときだけクリアする | |
969 | - sc.add(stateDef_hitcountpersist_c, nil) | |
970 | - } | |
971 | - return nil | |
947 | + return c.scAdd(sc, stateDef_hitcountpersist, data, VT_Bool, 1) | |
972 | 948 | }); err != nil { |
973 | 949 | return err |
974 | 950 | } |
975 | 951 | if !b { |
976 | - sc.add(stateDef_hitcountpersist_c, nil) | |
952 | + sc.add(stateDef_hitcountpersist, sc.iToExp(0)) | |
977 | 953 | } |
978 | 954 | b = false |
979 | 955 | if err := c.stateParam(is, "movehitpersist", func(data string) error { |
980 | 956 | b = true |
981 | - be, v, err := c.fullExpression(&data, VT_Bool) | |
982 | - if err != nil { | |
983 | - return err | |
984 | - } | |
985 | - if v.IsSF() { | |
986 | - sc.add(stateDef_movehitpersist, sc.beToExp(be)) | |
987 | - } else if !v.ToB() { // falseのときだけクリアする | |
988 | - sc.add(stateDef_movehitpersist_c, nil) | |
989 | - } | |
990 | - return nil | |
957 | + return c.scAdd(sc, stateDef_movehitpersist, data, VT_Bool, 1) | |
991 | 958 | }); err != nil { |
992 | 959 | return err |
993 | 960 | } |
994 | 961 | if !b { |
995 | - sc.add(stateDef_movehitpersist_c, nil) | |
962 | + sc.add(stateDef_movehitpersist, sc.iToExp(0)) | |
996 | 963 | } |
997 | 964 | b = false |
998 | 965 | if err := c.stateParam(is, "hitdefpersist", func(data string) error { |
999 | 966 | b = true |
1000 | - be, v, err := c.fullExpression(&data, VT_Bool) | |
1001 | - if err != nil { | |
1002 | - return err | |
1003 | - } | |
1004 | - if v.IsSF() { | |
1005 | - sc.add(stateDef_hitdefpersist, sc.beToExp(be)) | |
1006 | - } else if !v.ToB() { // falseのときだけクリアする | |
1007 | - sc.add(stateDef_hitdefpersist_c, nil) | |
1008 | - } | |
1009 | - return nil | |
967 | + return c.scAdd(sc, stateDef_hitdefpersist, data, VT_Bool, 1) | |
1010 | 968 | }); err != nil { |
1011 | 969 | return err |
1012 | 970 | } |
1013 | 971 | if !b { |
1014 | - sc.add(stateDef_hitdefpersist_c, nil) | |
972 | + sc.add(stateDef_hitdefpersist, sc.iToExp(0)) | |
1015 | 973 | } |
1016 | 974 | if err := c.stateParam(is, "sprpriority", func(data string) error { |
1017 | 975 | return c.scAdd(sc, stateDef_sprpriority, data, VT_Int, 1) |
@@ -1019,16 +977,7 @@ func (c *Compiler) stateDef(is IniSection, sbc *StateBytecode) error { | ||
1019 | 977 | return err |
1020 | 978 | } |
1021 | 979 | if err := c.stateParam(is, "facep2", func(data string) error { |
1022 | - be, v, err := c.fullExpression(&data, VT_Bool) | |
1023 | - if err != nil { | |
1024 | - return err | |
1025 | - } | |
1026 | - if v.IsSF() { | |
1027 | - sc.add(stateDef_facep2, sc.beToExp(be)) | |
1028 | - } else if v.ToB() { | |
1029 | - sc.add(stateDef_facep2_c, nil) | |
1030 | - } | |
1031 | - return nil | |
980 | + return c.scAdd(sc, stateDef_facep2, data, VT_Bool, 1) | |
1032 | 981 | }); err != nil { |
1033 | 982 | return err |
1034 | 983 | } |
@@ -1040,7 +989,7 @@ func (c *Compiler) stateDef(is IniSection, sbc *StateBytecode) error { | ||
1040 | 989 | return err |
1041 | 990 | } |
1042 | 991 | if !b { |
1043 | - sc.add(stateDef_juggle_c, sc.iToExp(0)) | |
992 | + sc.add(stateDef_juggle, sc.iToExp(0)) | |
1044 | 993 | } |
1045 | 994 | if err := c.stateParam(is, "velset", func(data string) error { |
1046 | 995 | return c.scAdd(sc, stateDef_velset, data, VT_Float, 3) |
@@ -1066,14 +1015,14 @@ func (c *Compiler) stateDef(is IniSection, sbc *StateBytecode) error { | ||
1066 | 1015 | return nil |
1067 | 1016 | }) |
1068 | 1017 | } |
1069 | -func (c *Compiler) hitBySub(is IniSection) (attr int32, | |
1070 | - timebe BytecodeExp, timev BytecodeValue, two bool, err error) { | |
1071 | - attr = -1 | |
1018 | +func (c *Compiler) hitBySub(is IniSection, sc *StateControllerBase) error { | |
1019 | + attr, two := int32(-1), false | |
1020 | + var err error | |
1072 | 1021 | if err = c.stateParam(is, "value", func(data string) error { |
1073 | 1022 | attr, err = c.attr(data, false) |
1074 | 1023 | return err |
1075 | 1024 | }); err != nil { |
1076 | - return | |
1025 | + return err | |
1077 | 1026 | } |
1078 | 1027 | if attr == -1 { |
1079 | 1028 | if err = c.stateParam(is, "value2", func(data string) error { |
@@ -1081,43 +1030,39 @@ func (c *Compiler) hitBySub(is IniSection) (attr int32, | ||
1081 | 1030 | attr, err = c.attr(data, false) |
1082 | 1031 | return err |
1083 | 1032 | }); err != nil { |
1084 | - return | |
1033 | + return err | |
1085 | 1034 | } |
1086 | 1035 | } |
1087 | 1036 | if attr == -1 { |
1088 | - err = Error("valueが指定されていません") | |
1089 | - return | |
1037 | + return Error("valueが指定されていません") | |
1090 | 1038 | } |
1091 | - timev = BytecodeSF() | |
1092 | 1039 | if err = c.stateParam(is, "time", func(data string) error { |
1093 | - timebe, timev, err = c.fullExpression(&data, VT_Int) | |
1094 | - return err | |
1040 | + return c.scAdd(sc, hitBy_time, data, VT_Int, 1) | |
1095 | 1041 | }); err != nil { |
1096 | - return | |
1042 | + return err | |
1097 | 1043 | } |
1098 | - if len(timebe) == 0 && timev.IsSF() { | |
1099 | - timev.SetI(1) | |
1044 | + if two { | |
1045 | + sc.add(hitBy_value2, sc.iToExp(attr)) | |
1046 | + } else { | |
1047 | + sc.add(hitBy_value, sc.iToExp(attr)) | |
1100 | 1048 | } |
1101 | - return | |
1049 | + return nil | |
1102 | 1050 | } |
1103 | 1051 | func (c *Compiler) hitBy(is IniSection, sbc *StateBytecode, |
1104 | 1052 | sc *StateControllerBase) (StateController, error) { |
1105 | 1053 | return hitBy(*sc), c.stateSec(is, func() error { |
1106 | - attr, timebe, timev, two, err := c.hitBySub(is) | |
1107 | - if err != nil { | |
1108 | - return err | |
1109 | - } | |
1110 | - unimplemented() | |
1111 | - return nil | |
1054 | + return c.hitBySub(is, sc) | |
1112 | 1055 | }) |
1113 | 1056 | } |
1114 | 1057 | func (c *Compiler) notHitBy(is IniSection, sbc *StateBytecode, |
1115 | 1058 | sc *StateControllerBase) (StateController, error) { |
1116 | 1059 | return notHitBy(*sc), c.stateSec(is, func() error { |
1117 | - attr, timebe, timev, two, err := c.hitBySub(is) | |
1118 | - if err != nil { | |
1119 | - return err | |
1120 | - } | |
1060 | + return c.hitBySub(is, sc) | |
1061 | + }) | |
1062 | +} | |
1063 | +func (c *Compiler) assertSpecial(is IniSection, sbc *StateBytecode, | |
1064 | + sc *StateControllerBase) (StateController, error) { | |
1065 | + return assertSpecial(*sc), c.stateSec(is, func() error { | |
1121 | 1066 | unimplemented() |
1122 | 1067 | return nil |
1123 | 1068 | }) |
@@ -1171,6 +1116,10 @@ func (c *Compiler) stateCompile(bc *Bytecode, filename, def string) error { | ||
1171 | 1116 | sc := newStateControllerBase(c.playerNo) |
1172 | 1117 | var scf func(is IniSection, sbc *StateBytecode, |
1173 | 1118 | sc *StateControllerBase) (StateController, error) |
1119 | + var triggerall []BytecodeExp | |
1120 | + allUtikiri := false | |
1121 | + var trigger [][]BytecodeExp | |
1122 | + var trexist []int8 | |
1174 | 1123 | is, err := c.parseSection(lines, &i, func(name, data string) error { |
1175 | 1124 | switch name { |
1176 | 1125 | case "type": |
@@ -1179,6 +1128,8 @@ func (c *Compiler) stateCompile(bc *Bytecode, filename, def string) error { | ||
1179 | 1128 | scf = c.hitBy |
1180 | 1129 | case "nothitby": |
1181 | 1130 | scf = c.notHitBy |
1131 | + case "assertspecial": | |
1132 | + scf = c.assertSpecial | |
1182 | 1133 | default: |
1183 | 1134 | println(data) |
1184 | 1135 | unimplemented() |
@@ -1188,12 +1139,61 @@ func (c *Compiler) stateCompile(bc *Bytecode, filename, def string) error { | ||
1188 | 1139 | sc.persistent = Atoi(data) |
1189 | 1140 | if sc.persistent > 128 { |
1190 | 1141 | sc.persistent = 1 |
1142 | + } else if sc.persistent <= 0 { | |
1143 | + sc.persistent = math.MaxInt32 | |
1191 | 1144 | } |
1192 | 1145 | } |
1193 | 1146 | case "ignorehitpause": |
1194 | 1147 | sc.ignorehitpause = Atoi(data) != 0 |
1148 | + case "triggerall": | |
1149 | + be, err := c.fullExpression(&data, VT_Bool) | |
1150 | + if err != nil { | |
1151 | + return err | |
1152 | + } | |
1153 | + if len(be) == 2 && be[0] == OC_int8 { | |
1154 | + if be[1] == 0 { | |
1155 | + allUtikiri = true | |
1156 | + } | |
1157 | + } else if !allUtikiri { | |
1158 | + triggerall = append(triggerall, be) | |
1159 | + } | |
1195 | 1160 | default: |
1196 | - unimplemented() | |
1161 | + tn, ok := readDigit(name[7:]) | |
1162 | + if !ok || tn <= 0 || tn > 65536 { | |
1163 | + errmes(Error("トリガー名 (" + name + ") が不正です")) | |
1164 | + } | |
1165 | + if len(trigger) < int(tn) { | |
1166 | + trigger = append(trigger, make([][]BytecodeExp, | |
1167 | + int(tn)-len(trigger))...) | |
1168 | + trexist = append(trexist, make([]int8, int(tn)-len(trexist))...) | |
1169 | + } | |
1170 | + tn-- | |
1171 | + be, err := c.fullExpression(&data, VT_Bool) | |
1172 | + if err != nil { | |
1173 | + if sys.ignoreMostErrors { | |
1174 | + _break := false | |
1175 | + for i := 0; i < int(tn); i++ { | |
1176 | + if trexist[i] == 0 { | |
1177 | + _break = true | |
1178 | + break | |
1179 | + } | |
1180 | + } | |
1181 | + if _break { | |
1182 | + break | |
1183 | + } | |
1184 | + } | |
1185 | + return err | |
1186 | + } | |
1187 | + if len(be) == 2 && be[0] == OC_int8 { | |
1188 | + if be[1] == 0 { | |
1189 | + trexist[tn] = -1 | |
1190 | + } else if trexist[tn] == 0 { | |
1191 | + trexist[tn] = 1 | |
1192 | + } | |
1193 | + } else if !allUtikiri && trexist[tn] >= 0 { | |
1194 | + trigger[tn] = append(trigger[tn], be) | |
1195 | + trexist[tn] = 1 | |
1196 | + } | |
1197 | 1197 | } |
1198 | 1198 | return nil |
1199 | 1199 | }) |
@@ -1203,11 +1203,92 @@ func (c *Compiler) stateCompile(bc *Bytecode, filename, def string) error { | ||
1203 | 1203 | if scf == nil { |
1204 | 1204 | return errmes(Error("typeが指定されていません")) |
1205 | 1205 | } |
1206 | + if len(trexist) == 0 || trexist[0] == 0 { | |
1207 | + return errmes(Error("trigger1がありません")) | |
1208 | + } | |
1209 | + var texp BytecodeExp | |
1210 | + for i, e := range triggerall { | |
1211 | + if len(e) > 0 { | |
1212 | + texp.append(e...) | |
1213 | + if i < len(triggerall)-1 { | |
1214 | + texp.append(OC_jz8, 0) | |
1215 | + texp.append(OC_pop) | |
1216 | + } | |
1217 | + } | |
1218 | + } | |
1219 | + if allUtikiri { | |
1220 | + if len(texp) > 0 { | |
1221 | + texp.appendValue(BytecodeBool(false)) | |
1222 | + } | |
1223 | + } else { | |
1224 | + for i, tr := range trigger { | |
1225 | + if trexist[i] == 0 { | |
1226 | + break | |
1227 | + } | |
1228 | + var te BytecodeExp | |
1229 | + if trexist[i] < 0 { | |
1230 | + te.appendValue(BytecodeBool(false)) | |
1231 | + } | |
1232 | + oldlen := len(te) | |
1233 | + for j := len(tr) - 1; j >= 0; j-- { | |
1234 | + tmp := tr[j] | |
1235 | + if len(tmp) > 0 { | |
1236 | + if j < len(tr)-1 { | |
1237 | + if len(te) > int(math.MaxUint8-1) { | |
1238 | + tmp.appendJmp(OC_jz, int32(len(te)+1)) | |
1239 | + tmp.append(OC_pop) | |
1240 | + } else { | |
1241 | + tmp.append(OC_jz8, OpCode(len(te)+1)) | |
1242 | + tmp.append(OC_pop) | |
1243 | + } | |
1244 | + } | |
1245 | + te = append(tmp, te...) | |
1246 | + } | |
1247 | + } | |
1248 | + if len(te) == oldlen { | |
1249 | + te = nil | |
1250 | + } | |
1251 | + if len(te) == 0 { | |
1252 | + if trexist[i] > 0 { | |
1253 | + if len(texp) > 0 { | |
1254 | + texp.appendValue(BytecodeBool(true)) | |
1255 | + } | |
1256 | + break | |
1257 | + } | |
1258 | + } else { | |
1259 | + texp.append(te...) | |
1260 | + if i < len(trigger)-1 { | |
1261 | + texp.append(OC_jnz8, 0) | |
1262 | + texp.append(OC_pop) | |
1263 | + } | |
1264 | + } | |
1265 | + } | |
1266 | + } | |
1267 | + if len(texp) > 0 { | |
1268 | + sc.add(SCID_trigger, sc.beToExp(texp)) | |
1269 | + } | |
1206 | 1270 | sctrl, err := scf(is, sbc, sc) |
1207 | 1271 | if err != nil { |
1208 | 1272 | return errmes(err) |
1209 | 1273 | } |
1210 | - sbc.ctrls = append(sbc.ctrls, sctrl) | |
1274 | + appending := true | |
1275 | + if len(texp) > 0 { | |
1276 | + } else if allUtikiri { | |
1277 | + appending = false | |
1278 | + } else { | |
1279 | + appending = false | |
1280 | + for _, te := range trexist { | |
1281 | + if te >= 0 { | |
1282 | + if te > 0 { | |
1283 | + appending = true | |
1284 | + } | |
1285 | + break | |
1286 | + } | |
1287 | + } | |
1288 | + } | |
1289 | + if appending { | |
1290 | + sbc.ctrls = append(sbc.ctrls, sctrl) | |
1291 | + } | |
1211 | 1292 | } |
1212 | 1293 | _, ok := bc.states[n] |
1213 | 1294 | if !ok { |