|
44 | 44 | Pp: "had" |
45 | 45 | } |
46 | 46 | }, |
47 | | - irregular0 = { |
| 47 | + irregular2 = { |
48 | 48 | "bet": 1, "bid": 1, "broadcast": 1, "burst": 1, "cast": 1, "clad": 1, |
49 | 49 | "clearcut": 1, "cost": 1, "crosscut": 1, "cut": 1, "fit": 1, "handset": 1, |
50 | 50 | "hit": 1, "hurt": 1, "intercut": 1, "let": 1, "lipread": 1, "podcast": 1, |
|
53 | 53 | "split": 1, "spread": 1, "sublet": 1, "telecast": 1, "thrust": 1, |
54 | 54 | "typecast": 1, "typeset": 1, "webcast": 1, "wed": 1 |
55 | 55 | }, |
56 | | - irregular1 = { |
| 56 | + irregular3 = { |
57 | 57 | "babysit": "babysat", "bend": "bent", "beseech": "besought", |
58 | 58 | "besprenge": "besprent", "bind": "bound", "bleed": "bled", |
59 | 59 | "breastfeed": "breastfed", "breed": "bred", "bring": "brought", |
|
78 | 78 | "tell": "told", "think": "thought", "tread": "trod", "understand": "understood", |
79 | 79 | "waylay": "waylaid", "win": "won", "wind": "wound", "wring": "wrung" |
80 | 80 | }, |
81 | | - irregular2 = { |
| 81 | + irregular4 = { |
82 | 82 | "acknow": ["acknew", "1n"], "ake": ["oke", "1n"], "arise": ["arose", "1n"], |
83 | 83 | "awake": ["awoke", "2n"], "bear": ["bore", "born"], "beat": ["1", "1en"], |
84 | 84 | "bedo": ["bedid", "1ne"], "begin": ["began", "begun"], "bego": ["bewent", "1ne"], |
|
380 | 380 |
|
381 | 381 | let g; |
382 | 382 |
|
| 383 | + /** |
| 384 | + * An object to be a medium between different functions, |
| 385 | + * Its function is to optimize conjugation when the same verb is used |
| 386 | + * @type {Object} |
| 387 | + */ |
| 388 | + let verbInfo = { |
| 389 | + /** |
| 390 | + * The verb |
| 391 | + * @type {String} |
| 392 | + */ |
| 393 | + verb: "", |
| 394 | + /** |
| 395 | + * Is it irregular, values are: null (no value yet), 0 (regular) or 1 (irregular) |
| 396 | + * @type {Number} |
| 397 | + */ |
| 398 | + irregular: null, |
| 399 | + prefix: "", |
| 400 | + rverb: "" |
| 401 | + }; |
| 402 | + |
383 | 403 | //========================================== |
384 | 404 | // CLASS CONSTRUCTOR |
385 | 405 | //========================================== |
|
712 | 732 |
|
713 | 733 | let begin = "", end = ""; |
714 | 734 |
|
| 735 | + __verbTypes(verb); |
| 736 | + |
| 737 | + //the case of be and have |
| 738 | + let conjVerb = { |
| 739 | + v: verbInfo.rverb, //verb |
| 740 | + p: verbInfo.prefix, |
| 741 | + i: verbInfo.irregular, //irregular |
| 742 | + c: verbInfo.conj //conjugation table |
| 743 | + }; |
| 744 | + |
715 | 745 | if ((opts.voice) && (opts.voice === Voice.P)) { |
716 | | - if (beHave[verb]) end = " " + __beHaveConj(verb, "Pp", opts); |
717 | | - else if (__isIrregular(verb)) end = " " + __irregularConj(verb, 1); |
718 | | - else end = " " + this.conj(verb, {tense:Tense.Pa}); |
719 | | - verb = "be"; |
| 746 | + switch (conjVerb.i) { |
| 747 | + case 1: |
| 748 | + end = " " + __beHaveConj(conjVerb, "Pp", opts); |
| 749 | + break; |
| 750 | + case 2: |
| 751 | + case 3: |
| 752 | + case 4: |
| 753 | + end = " " + __irregularConj(conjVerb, 1); |
| 754 | + break; |
| 755 | + default: |
| 756 | + end = " " + this.conj(verb, {tense:Tense.Pa}); |
| 757 | + } |
| 758 | + conjVerb = { |
| 759 | + v: "be", |
| 760 | + p: "", |
| 761 | + i: 1, |
| 762 | + c: beHave["be"] |
| 763 | + }; |
720 | 764 | } |
721 | 765 |
|
722 | 766 | if (opts.aspect) { |
723 | 767 | if ([Aspect.C, Aspect.PC].includes(opts.aspect)) { |
724 | 768 | // http://www.eclecticenglish.com/grammar/PresentContinuous1G.html |
725 | | - let base = verb; |
| 769 | + let base = conjVerb.v; |
726 | 770 | if(["lie", "die"].includes(verb)) base = verb.slice(0,-2) + "y"; |
727 | 771 | else if (/^[^aeuio]*[aeuio][^aeuioy]$/g.test(verb)) base = verb + verb.slice(-1); |
728 | 772 | else if (/^.{2,}e$/g.test(verb)) base = verb.slice(0,-1); |
729 | 773 |
|
730 | 774 | end = " " + base + "ing" + end; |
731 | | - verb = "be"; |
| 775 | + conjVerb = { |
| 776 | + v: "be", |
| 777 | + p: "", |
| 778 | + i: 1, |
| 779 | + c: beHave["be"] |
| 780 | + }; |
732 | 781 | } |
733 | 782 |
|
734 | 783 | if ([Aspect.P, Aspect.PC].includes(opts.aspect)) { |
735 | | - if (beHave[verb]) end = " " + __beHaveConj(verb, "Pp", opts) + end; |
736 | | - else if (__isIrregular(verb)) end = " " + __irregularConj(verb, 1) + end; |
737 | | - else end = " " + this.conj(verb, {tense:Tense.Pa}) + end; |
738 | | - verb = "have"; |
739 | | - } |
| 784 | + switch (conjVerb.i) { |
| 785 | + case 1: |
| 786 | + end = " " + __beHaveConj(conjVerb, "Pp", opts) + end; |
| 787 | + break; |
| 788 | + case 2: |
| 789 | + case 3: |
| 790 | + case 4: |
| 791 | + end = " " + __irregularConj(conjVerb, 1) + end; |
| 792 | + break; |
| 793 | + default: |
| 794 | + end = " " + this.conj(verb, {tense:Tense.Pa}) + end; |
| 795 | + } |
| 796 | + conjVerb = { |
| 797 | + v: "have", |
| 798 | + p: "", |
| 799 | + i: 1, |
| 800 | + c: beHave["have"] |
| 801 | + }; |
| 802 | + } |
740 | 803 | } |
741 | 804 |
|
742 | 805 | if ((opts.negated) && (opts.tense !== Tense.Fu)) { |
743 | 806 | end = " not" + end; |
744 | 807 | if ((!opts.aspect) || opts.aspect === Aspect.S) { |
745 | 808 | if ((!opts.voice) || opts.voice === Voice.A) { |
746 | 809 | end += " " + verb; |
747 | | - verb = "do"; |
| 810 | + conjVerb = { |
| 811 | + v: "do", |
| 812 | + p: "", |
| 813 | + i: 4, |
| 814 | + c: irregular4["do"] |
| 815 | + }; |
748 | 816 | //console.log("negation active aspect"); |
749 | 817 | } |
750 | 818 | } |
751 | 819 | } |
752 | 820 |
|
| 821 | + let cverb = conjVerb.v; |
| 822 | + |
753 | 823 | switch (opts.tense) { |
754 | 824 |
|
755 | 825 | case Tense.Pr: |
756 | | - if (beHave[verb]) return begin + __beHaveConj(verb, "Pr", opts) + end; |
| 826 | + if (conjVerb.i == 1) return begin + __beHaveConj(conjVerb, "Pr", opts) + end; |
| 827 | + cverb = conjVerb.p + cverb; |
757 | 828 | if (opts.person == Person.T && opts.number === GNumber.S) { |
758 | 829 | //hurry, clarify |
759 | | - verb = verb.replace(/([^aeuio])y$/, "$1ie"); |
| 830 | + cverb = cverb.replace(/([^aeuio])y$/, "$1ie"); |
760 | 831 | //go, veto, do, wash, mix, fizz (add e ) |
761 | | - verb = verb.replace(/(s|z|sh|ch|[^aeui]o)$/, "$1e"); |
| 832 | + cverb = cverb.replace(/(s|z|sh|ch|[^aeui]o)$/, "$1e"); |
762 | 833 | end = "s" + end; |
763 | 834 | } |
764 | 835 | break; |
765 | 836 |
|
766 | 837 | case Tense.Pa: |
767 | 838 | //To be, To have |
768 | | - if (beHave[verb]) return begin + __beHaveConj(verb, "Pa", opts) + end; |
| 839 | + if (conjVerb.i == 1) return begin + __beHaveConj(conjVerb, "Pa", opts) + end; |
769 | 840 | //Irregular (the block is just for variables) |
770 | | - { |
771 | | - const pref = /(back|be|down|fore|for|in|mis|off|out|over|pre|re|sub|under|un|up|with)(.{3,})/gi; |
772 | | - let match = pref.exec(verb); |
773 | | - if (match) { |
774 | | - //verify if the verb is in Irregular list with the prefix |
775 | | - if (__isIrregular(verb)) return begin + __irregularConj(verb, 0) + end; |
776 | | - //Otherwise, delete the prefix and procede |
777 | | - begin = match[1]; |
778 | | - verb = match[2]; |
779 | | - } |
780 | | - } |
781 | 841 |
|
782 | | - if (__isIrregular(verb)) return begin + __irregularConj(verb, 0) + end; |
| 842 | + if (conjVerb.i > 1) return begin + __irregularConj(conjVerb, 0) + end; |
783 | 843 |
|
784 | | - verb = verb.replace(/([^aeuio])y$/, "$1i"); |
785 | | - verb = verb.replace(/c$/, "ck"); |
786 | | - verb = verb.replace(/^([^aeuio]*[aeuio])([^aeuiohwxy])$/, "$1$2$2"); |
787 | | - if (verb.endsWith("e")) end = "d" + end; |
| 844 | + cverb = cverb.replace(/([^aeuio])y$/, "$1i"); |
| 845 | + cverb = cverb.replace(/c$/, "ck"); |
| 846 | + cverb = cverb.replace(/^([^aeuio]*[aeuio])([^aeuiohwxy])$/, "$1$2$2"); |
| 847 | + if (cverb.endsWith("e")) end = "d" + end; |
788 | 848 | else end = "ed" + end; |
789 | 849 | break; |
790 | 850 |
|
|
795 | 855 |
|
796 | 856 | }//swich(tense) |
797 | 857 |
|
798 | | - return begin + verb + end; |
| 858 | + return begin + cverb + end; |
799 | 859 |
|
800 | 860 | }; |
801 | 861 |
|
802 | | - function __beHaveConj(verb, idx, opts) { |
803 | | - if (! (verb in beHave)) return verb; |
804 | | - if (! "Pr|Pa|Pp".includes(idx)) return verb; |
805 | | - if (idx === "Pp") return beHave[verb][idx]; |
| 862 | + function __beHaveConj(conjVerb, idx, opts) { |
| 863 | + if (conjVerb.i != 1) return conjVerb.v; |
| 864 | + if (! "Pr|Pa|Pp".includes(idx)) return conjVerb.v; |
| 865 | + if (idx === "Pp") return conjVerb.c[idx]; |
806 | 866 |
|
807 | 867 | if (opts.number === GNumber.S) { |
808 | | - if (opts.person == Person.F) return beHave[verb][idx][0]; |
809 | | - else if (opts.person == Person.T) return beHave[verb][idx][1]; |
810 | | - return beHave[verb][idx][2]; |
| 868 | + if (opts.person == Person.F) return conjVerb.c[idx][0]; |
| 869 | + else if (opts.person == Person.T) return conjVerb.c[idx][1]; |
| 870 | + return conjVerb.c[idx][2]; |
811 | 871 | } |
812 | 872 |
|
813 | | - return beHave[verb][idx][2]; |
814 | | - } |
815 | | - |
816 | | - |
817 | | - function __isIrregular(verb) { |
818 | | - if (irregular0[verb]) return 1; |
819 | | - if (irregular1[verb]) return 1; |
820 | | - if (irregular2[verb]) return 1; |
821 | | - return 0;//false |
| 873 | + return conjVerb.c[idx][2]; |
822 | 874 | } |
823 | 875 |
|
824 | 876 | /** |
|
828 | 880 | * @method __irregularConj |
829 | 881 | * @private |
830 | 882 | * @memberof EngMorpho |
831 | | - * @param {String} verb the irregular verb |
| 883 | + * @param {Object} verb the irregular verb |
832 | 884 | * @param {Number} idx 0 for past, 1 for past participle |
833 | 885 | * @return {String} the conjugation |
834 | 886 | */ |
835 | | - function __irregularConj(verb, idx) { |
836 | | - if (irregular0[verb]) return verb; |
837 | | - if (irregular1[verb])return irregular1[verb]; |
838 | | - //Here, we suppose it is irregular2[verb] |
839 | | - let res = irregular2[verb][idx]; |
840 | | - res = res.replace("1", verb); |
841 | | - if(idx === 1) { |
842 | | - res = res.replace("2", irregular2[verb][0]); |
843 | | - res = res.replace(/.-/,""); |
| 887 | + function __irregularConj(conjVerb, idx) { |
| 888 | + switch (conjVerb.i) { |
| 889 | + case 3: return conjVerb.p + conjVerb.c; |
| 890 | + case 4: |
| 891 | + let res = conjVerb.c[idx]; |
| 892 | + res = res.replace("1", conjVerb.v); |
| 893 | + if(idx === 1) { |
| 894 | + res = res.replace("2", conjVerb.c[0]); |
| 895 | + res = res.replace(/.-/,""); |
| 896 | + } |
| 897 | + return conjVerb.p + res; |
| 898 | + default: return conjVerb.p + conjVerb.v; |
| 899 | + } |
| 900 | + } |
| 901 | + |
| 902 | + //========================================== |
| 903 | + // CONJUGATION PREPROCESSOR FUNCTIONS |
| 904 | + //========================================== |
| 905 | + |
| 906 | + function __verbTypes(verb) { |
| 907 | + //delete spaces |
| 908 | + verb = verb.trim(); |
| 909 | + if (verb === verbInfo.verb) return; |
| 910 | + |
| 911 | + verbInfo.rverb = verb; |
| 912 | + verbInfo.prefix = ""; |
| 913 | + |
| 914 | + // conjugation table for the verb "be" or "have" |
| 915 | + let conjInfo = beHave[verb]; |
| 916 | + |
| 917 | + if (conjInfo) { |
| 918 | + verbInfo.irregular = 1; |
| 919 | + verbInfo.conj = conjInfo; |
| 920 | + return; |
| 921 | + } |
| 922 | + |
| 923 | + { |
| 924 | + const pref = /(back|be|down|fore|for|in|mis|off|out|over|pre|re|sub|under|un|up|with)(.{3,})/gi; |
| 925 | + let match = pref.exec(verb); |
| 926 | + if (match) { |
| 927 | + verbInfo.prefix = match[1]; |
| 928 | + verbInfo.rverb = match[2]; |
| 929 | + } |
| 930 | + } |
| 931 | + |
| 932 | + //These verbs do not need conjugation table |
| 933 | + // Past = past participle = verb |
| 934 | + if (irregular2[verbInfo.rverb]) { |
| 935 | + verbInfo.irregular = 2; |
| 936 | + verbInfo.conj = null; |
| 937 | + return; |
| 938 | + } |
| 939 | + |
| 940 | + //These verbs have irregularities in past participle and past |
| 941 | + // past = past participle |
| 942 | + conjInfo = irregular3[verbInfo.rverb]; |
| 943 | + if (conjInfo) { |
| 944 | + verbInfo.irregular = 3; |
| 945 | + verbInfo.conj = conjInfo; |
| 946 | + return; |
844 | 947 | } |
845 | | - return res; |
| 948 | + |
| 949 | + // These verbs have irregularities in te past: a table of conjugation |
| 950 | + conjInfo = irregular4[verbInfo.rverb]; |
| 951 | + if (conjInfo) { |
| 952 | + verbInfo.irregular = 4; |
| 953 | + verbInfo.conj = conjInfo; |
| 954 | + return; |
| 955 | + } |
| 956 | + |
| 957 | + verbInfo.irregular = 0; |
| 958 | + verbInfo.conj = null; |
| 959 | + |
846 | 960 | } |
847 | 961 |
|
848 | 962 | //========================================== |
|
0 commit comments