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) {