Mercurial > projects > ddmd
comparison dmd/Lexer.d @ 157:b7b61140701d
* added all missing default cases in switch statements
+ Lexer.getDocComment
+ Lexer.combineComments
author | trass3r |
---|---|
date | Thu, 16 Sep 2010 01:34:10 +0200 |
parents | af1bebfd96a4 |
children | 438eaa11eed4 |
comparison
equal
deleted
inserted
replaced
156:0c8cc2a10f99 | 157:b7b61140701d |
---|---|
955 { | 955 { |
956 p = end; | 956 p = end; |
957 t.value = TOK.TOKcomment; | 957 t.value = TOK.TOKcomment; |
958 return; | 958 return; |
959 } | 959 } |
960 if (doDocComment && t.ptr[2] == '/') | 960 if (doDocComment && t.ptr[2] == '/' || t.ptr[2] == '!') // '///' or '//!' |
961 getDocComment(t, lastLine == linnum); | 961 getDocComment(t, lastLine == linnum); |
962 p = end; | 962 p = end; |
963 t.value = TOK.TOKeof; | 963 t.value = TOK.TOKeof; |
964 return; | 964 return; |
965 | 965 |
979 p++; | 979 p++; |
980 loc.linnum++; | 980 loc.linnum++; |
981 t.value = TOK.TOKcomment; | 981 t.value = TOK.TOKcomment; |
982 return; | 982 return; |
983 } | 983 } |
984 if (doDocComment && t.ptr[2] == '/') | 984 if (doDocComment && t.ptr[2] == '/' || t.ptr[2] == '!') // '///' or '//!' |
985 getDocComment(t, lastLine == linnum); | 985 getDocComment(t, lastLine == linnum); |
986 | 986 |
987 p++; | 987 p++; |
988 loc.linnum++; | 988 loc.linnum++; |
989 continue; | 989 continue; |
2709 result = TOKimaginary64v; | 2709 result = TOKimaginary64v; |
2710 break; | 2710 break; |
2711 case TOKfloat80v: | 2711 case TOKfloat80v: |
2712 result = TOKimaginary80v; | 2712 result = TOKimaginary80v; |
2713 break; | 2713 break; |
2714 default: | |
2714 } | 2715 } |
2715 } | 2716 } |
2716 | 2717 |
2717 version (Windows) { ///&& __DMC__ | 2718 version (Windows) { ///&& __DMC__ |
2718 __locale_decpoint = save; | 2719 __locale_decpoint = save; |
2780 error("%s", msg); | 2781 error("%s", msg); |
2781 } | 2782 } |
2782 return u; | 2783 return u; |
2783 } | 2784 } |
2784 | 2785 |
2785 void getDocComment(Token* t, uint lineComment) | 2786 /*************************************************** |
2786 { | 2787 * Parse doc comment embedded between t.ptr and p. |
2787 assert(false); | 2788 * Remove trailing blanks and tabs from lines. |
2789 * Replace all newlines with \n. | |
2790 * Remove leading comment character from each line. | |
2791 * Decide if it's a lineComment or a blockComment. | |
2792 * Append to previous one for this token. | |
2793 */ | |
2794 void getDocComment(Token* t, uint lineComment) | |
2795 { | |
2796 /* ct tells us which kind of comment it is: '!', '/', '*', or '+' | |
2797 */ | |
2798 ubyte ct = t.ptr[2]; | |
2799 | |
2800 /* Start of comment text skips over / * *, / + +, or / / / | |
2801 */ | |
2802 ubyte* q = t.ptr + 3; // start of comment text | |
2803 | |
2804 ubyte* qend = p; | |
2805 if (ct == '*' || ct == '+') | |
2806 qend -= 2; | |
2807 | |
2808 /* Scan over initial row of ****'s or ++++'s or ////'s | |
2809 */ | |
2810 for (; q < qend; q++) | |
2811 { | |
2812 if (*q != ct) | |
2813 break; | |
2814 } | |
2815 | |
2816 /* Remove trailing row of ****'s or ++++'s | |
2817 */ | |
2818 if (ct != '/' && ct != '!') | |
2819 { | |
2820 for (; q < qend; qend--) | |
2821 { | |
2822 if (qend[-1] != ct) | |
2823 break; | |
2824 } | |
2825 } | |
2826 | |
2827 /* Comment is now [q .. qend]. | |
2828 * Canonicalize it into buf[]. | |
2829 */ | |
2830 OutBuffer buf = new OutBuffer; | |
2831 int linestart = 0; | |
2832 | |
2833 for (; q < qend; q++) | |
2834 { | |
2835 ubyte c = *q; | |
2836 | |
2837 switch (c) | |
2838 { | |
2839 case '*': | |
2840 case '+': | |
2841 if (linestart && c == ct) | |
2842 { linestart = 0; | |
2843 /* Trim preceding whitespace up to preceding \n | |
2844 */ | |
2845 while (buf.offset && (buf.data[buf.offset - 1] == ' ' || buf.data[buf.offset - 1] == '\t')) | |
2846 buf.offset--; | |
2847 continue; | |
2848 } | |
2849 break; | |
2850 | |
2851 case ' ': | |
2852 case '\t': | |
2853 break; | |
2854 | |
2855 case '\r': | |
2856 if (q[1] == '\n') | |
2857 continue; // skip the \r | |
2858 goto Lnewline; | |
2859 | |
2860 default: | |
2861 if (c == 226) | |
2862 { | |
2863 // If LS or PS | |
2864 if (q[1] == 128 && | |
2865 (q[2] == 168 || q[2] == 169)) | |
2866 { | |
2867 q += 2; | |
2868 goto Lnewline; | |
2869 } | |
2870 } | |
2871 linestart = 0; | |
2872 break; | |
2873 | |
2874 Lnewline: | |
2875 c = '\n'; // replace all newlines with \n | |
2876 case '\n': | |
2877 linestart = 1; | |
2878 | |
2879 /* Trim trailing whitespace | |
2880 */ | |
2881 while (buf.offset && (buf.data[buf.offset - 1] == ' ' || buf.data[buf.offset - 1] == '\t')) | |
2882 buf.offset--; | |
2883 | |
2884 break; | |
2885 } | |
2886 buf.writeByte(c); | |
2887 } | |
2888 | |
2889 // Always end with a newline | |
2890 if (!buf.offset || buf.data[buf.offset - 1] != '\n') | |
2891 buf.writeByte('\n'); | |
2892 | |
2893 buf.writeByte(0); | |
2894 | |
2895 // It's a line comment if the start of the doc comment comes | |
2896 // after other non-whitespace on the same line. | |
2897 string* dc = (lineComment && anyToken) | |
2898 ? &t.lineComment | |
2899 : &t.blockComment; | |
2900 | |
2901 // Combine with previous doc comment, if any | |
2902 if (*dc) | |
2903 *dc = combineComments(*dc, cast(string) buf.data[0 .. buf.size]); // TODO: utf decode etc? | |
2904 else | |
2905 { | |
2906 auto bufsize = buf.size; | |
2907 *dc = cast(string) buf.extractData()[0..bufsize]; | |
2908 } | |
2909 } | |
2910 | |
2911 /******************************************** | |
2912 * Combine two document comments into one, | |
2913 * separated by a newline. | |
2914 */ | |
2915 static string combineComments(string c1, string c2) | |
2916 { | |
2917 //printf("Lexer::combineComments('%s', '%s')\n", c1, c2); | |
2918 | |
2919 string c = c2; | |
2920 | |
2921 if (c1) | |
2922 { | |
2923 c = c1; | |
2924 if (c2) | |
2925 { | |
2926 size_t len1 = c1.length; | |
2927 size_t len2 = c2.length; | |
2928 | |
2929 c = c1.idup; | |
2930 if (len1 && c1[$-1] != '\n') | |
2931 c ~= '\n'; | |
2932 c ~= c2; | |
2933 } | |
2934 } | |
2935 return c; | |
2788 } | 2936 } |
2789 | 2937 |
2790 static bool isValidIdentifier(string p) | 2938 static bool isValidIdentifier(string p) |
2791 { | 2939 { |
2792 if (p.length == 0) { | 2940 if (p.length == 0) { |