annotate gcc/d/dmd/lexer.c @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
145
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2 /* Compiler implementation of the D programming language
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3 * Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
4 * written by Walter Bright
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
5 * http://www.digitalmars.com
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
6 * Distributed under the Boost Software License, Version 1.0.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
7 * http://www.boost.org/LICENSE_1_0.txt
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
8 * https://github.com/D-Programming-Language/dmd/blob/master/src/lexer.c
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
9 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
10
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
11 /* Lexical Analyzer */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
12
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
13 #include "root/dsystem.h" // for time() and ctime()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
14 #include "root/rmem.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
15
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
16 #include "mars.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
17 #include "lexer.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
18 #include "utf.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
19 #include "identifier.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
20 #include "id.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
21
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
22 extern int HtmlNamedEntity(const utf8_t *p, size_t length);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
23
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
24 #define LS 0x2028 // UTF line separator
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
25 #define PS 0x2029 // UTF paragraph separator
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
26
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
27 /********************************************
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
28 * Do our own char maps
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
29 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
30
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
31 static unsigned char cmtable[256];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
32
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
33 const int CMoctal = 0x1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
34 const int CMhex = 0x2;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
35 const int CMidchar = 0x4;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
36
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
37 inline bool isoctal (utf8_t c) { return (cmtable[c] & CMoctal) != 0; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
38 inline bool ishex (utf8_t c) { return (cmtable[c] & CMhex) != 0; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
39 inline bool isidchar(utf8_t c) { return (cmtable[c] & CMidchar) != 0; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
40
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
41 struct CMTableInitializer
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
42 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
43 CMTableInitializer();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
44 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
45
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
46 static CMTableInitializer cmtableinitializer;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
47
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
48 CMTableInitializer::CMTableInitializer()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
49 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
50 for (unsigned c = 0; c < 256; c++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
51 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
52 if ('0' <= c && c <= '7')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
53 cmtable[c] |= CMoctal;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
54 if (isxdigit(c))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
55 cmtable[c] |= CMhex;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
56 if (isalnum(c) || c == '_')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
57 cmtable[c] |= CMidchar;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
58 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
59 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
60
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
61 /*************************** Lexer ********************************************/
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
62
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
63 OutBuffer Lexer::stringbuffer;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
64
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
65 Lexer::Lexer(const char *filename,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
66 const utf8_t *base, size_t begoffset, size_t endoffset,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
67 bool doDocComment, bool commentToken)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
68 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
69 scanloc = Loc(filename, 1, 1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
70 //printf("Lexer::Lexer(%p,%d)\n",base,length);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
71 //printf("lexer.filename = %s\n", filename);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
72 this->token = Token();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
73 this->token.ptr = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
74 this->token.value = TOKreserved;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
75 this->token.blockComment = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
76 this->token.lineComment = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
77 this->base = base;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
78 this->end = base + endoffset;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
79 p = base + begoffset;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
80 line = p;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
81 this->doDocComment = doDocComment;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
82 this->anyToken = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
83 this->commentToken = commentToken;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
84 this->errors = false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
85 //initKeywords();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
86
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
87 /* If first line starts with '#!', ignore the line
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
88 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
89
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
90 if (p[0] == '#' && p[1] =='!')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
91 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
92 p += 2;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
93 while (1)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
94 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
95 utf8_t c = *p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
96 switch (c)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
97 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
98 case 0:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
99 case 0x1A:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
100 p--;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
101 /* fall through */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
102
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
103 case '\n':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
104 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
105
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
106 default:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
107 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
108 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
109 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
110 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
111 endOfLine();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
112 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
113 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
114
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
115
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
116 void Lexer::endOfLine()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
117 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
118 scanloc.linnum++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
119 line = p;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
120 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
121
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
122
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
123 void Lexer::error(const char *format, ...)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
124 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
125 va_list ap;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
126 va_start(ap, format);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
127 ::verror(token.loc, format, ap);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
128 va_end(ap);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
129 errors = true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
130 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
131
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
132 void Lexer::error(Loc loc, const char *format, ...)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
133 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
134 va_list ap;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
135 va_start(ap, format);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
136 ::verror(loc, format, ap);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
137 va_end(ap);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
138 errors = true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
139 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
140
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
141 void Lexer::deprecation(const char *format, ...)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
142 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
143 va_list ap;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
144 va_start(ap, format);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
145 ::vdeprecation(token.loc, format, ap);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
146 va_end(ap);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
147 if (global.params.useDeprecated == DIAGNOSTICerror)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
148 errors = true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
149 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
150
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
151 TOK Lexer::nextToken()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
152 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
153 if (token.next)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
154 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
155 Token *t = token.next;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
156 memcpy(&token,t,sizeof(Token));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
157 t->free();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
158 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
159 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
160 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
161 scan(&token);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
162 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
163 //token.print();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
164 return token.value;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
165 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
166
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
167 Token *Lexer::peek(Token *ct)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
168 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
169 Token *t;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
170 if (ct->next)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
171 t = ct->next;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
172 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
173 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
174 t = Token::alloc();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
175 scan(t);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
176 ct->next = t;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
177 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
178 return t;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
179 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
180
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
181 /***********************
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
182 * Look ahead at next token's value.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
183 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
184
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
185 TOK Lexer::peekNext()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
186 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
187 return peek(&token)->value;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
188 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
189
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
190 /***********************
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
191 * Look 2 tokens ahead at value.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
192 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
193
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
194 TOK Lexer::peekNext2()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
195 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
196 Token *t = peek(&token);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
197 return peek(t)->value;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
198 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
199
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
200 /*********************************
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
201 * tk is on the opening (.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
202 * Look ahead and return token that is past the closing ).
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
203 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
204
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
205 Token *Lexer::peekPastParen(Token *tk)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
206 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
207 //printf("peekPastParen()\n");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
208 int parens = 1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
209 int curlynest = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
210 while (1)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
211 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
212 tk = peek(tk);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
213 //tk->print();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
214 switch (tk->value)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
215 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
216 case TOKlparen:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
217 parens++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
218 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
219
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
220 case TOKrparen:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
221 --parens;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
222 if (parens)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
223 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
224 tk = peek(tk);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
225 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
226
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
227 case TOKlcurly:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
228 curlynest++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
229 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
230
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
231 case TOKrcurly:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
232 if (--curlynest >= 0)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
233 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
234 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
235
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
236 case TOKsemicolon:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
237 if (curlynest)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
238 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
239 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
240
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
241 case TOKeof:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
242 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
243
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
244 default:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
245 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
246 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
247 return tk;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
248 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
249 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
250
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
251 /****************************
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
252 * Turn next token in buffer into a token.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
253 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
254
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
255 void Lexer::scan(Token *t)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
256 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
257 unsigned lastLine = scanloc.linnum;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
258 Loc startLoc;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
259
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
260 t->blockComment = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
261 t->lineComment = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
262 while (1)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
263 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
264 t->ptr = p;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
265 //printf("p = %p, *p = '%c'\n",p,*p);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
266 t->loc = loc();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
267 switch (*p)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
268 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
269 case 0:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
270 case 0x1A:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
271 t->value = TOKeof; // end of file
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
272 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
273
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
274 case ' ':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
275 case '\t':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
276 case '\v':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
277 case '\f':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
278 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
279 continue; // skip white space
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
280
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
281 case '\r':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
282 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
283 if (*p != '\n') // if CR stands by itself
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
284 endOfLine();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
285 continue; // skip white space
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
286
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
287 case '\n':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
288 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
289 endOfLine();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
290 continue; // skip white space
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
291
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
292 case '0': case '1': case '2': case '3': case '4':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
293 case '5': case '6': case '7': case '8': case '9':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
294 t->value = number(t);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
295 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
296
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
297 case '\'':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
298 t->value = charConstant(t);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
299 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
300
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
301 case 'r':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
302 if (p[1] != '"')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
303 goto case_ident;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
304 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
305 /* fall through */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
306 case '`':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
307 t->value = wysiwygStringConstant(t, *p);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
308 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
309
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
310 case 'x':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
311 if (p[1] != '"')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
312 goto case_ident;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
313 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
314 t->value = hexStringConstant(t);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
315 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
316
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
317 case 'q':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
318 if (p[1] == '"')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
319 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
320 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
321 t->value = delimitedStringConstant(t);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
322 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
323 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
324 else if (p[1] == '{')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
325 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
326 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
327 t->value = tokenStringConstant(t);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
328 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
329 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
330 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
331 goto case_ident;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
332
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
333 case '"':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
334 t->value = escapeStringConstant(t);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
335 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
336
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
337 case 'a': case 'b': case 'c': case 'd': case 'e':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
338 case 'f': case 'g': case 'h': case 'i': case 'j':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
339 case 'k': case 'l': case 'm': case 'n': case 'o':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
340 case 'p': /*case 'q': case 'r':*/ case 's': case 't':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
341 case 'u': case 'v': case 'w': /*case 'x':*/ case 'y':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
342 case 'z':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
343 case 'A': case 'B': case 'C': case 'D': case 'E':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
344 case 'F': case 'G': case 'H': case 'I': case 'J':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
345 case 'K': case 'L': case 'M': case 'N': case 'O':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
346 case 'P': case 'Q': case 'R': case 'S': case 'T':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
347 case 'U': case 'V': case 'W': case 'X': case 'Y':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
348 case 'Z':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
349 case '_':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
350 case_ident:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
351 { utf8_t c;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
352
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
353 while (1)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
354 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
355 c = *++p;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
356 if (isidchar(c))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
357 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
358 else if (c & 0x80)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
359 { const utf8_t *s = p;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
360 unsigned u = decodeUTF();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
361 if (isUniAlpha(u))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
362 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
363 error("char 0x%04x not allowed in identifier", u);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
364 p = s;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
365 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
366 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
367 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
368
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
369 Identifier *id = Identifier::idPool((const char *)t->ptr, p - t->ptr);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
370 t->ident = id;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
371 t->value = (TOK) id->getValue();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
372 anyToken = 1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
373 if (*t->ptr == '_') // if special identifier token
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
374 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
375 static bool initdone = false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
376 static char date[11+1];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
377 static char time[8+1];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
378 static char timestamp[24+1];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
379
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
380 if (!initdone) // lazy evaluation
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
381 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
382 initdone = true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
383 time_t ct;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
384 ::time(&ct);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
385 char *p = ctime(&ct);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
386 assert(p);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
387 sprintf(&date[0], "%.6s %.4s", p + 4, p + 20);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
388 sprintf(&time[0], "%.8s", p + 11);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
389 sprintf(&timestamp[0], "%.24s", p);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
390 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
391
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
392 if (id == Id::DATE)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
393 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
394 t->ustring = (utf8_t *)date;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
395 goto Lstr;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
396 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
397 else if (id == Id::TIME)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
398 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
399 t->ustring = (utf8_t *)time;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
400 goto Lstr;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
401 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
402 else if (id == Id::VENDOR)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
403 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
404 t->ustring = (utf8_t *)const_cast<char *>(global.vendor);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
405 goto Lstr;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
406 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
407 else if (id == Id::TIMESTAMP)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
408 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
409 t->ustring = (utf8_t *)timestamp;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
410 Lstr:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
411 t->value = TOKstring;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
412 t->postfix = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
413 t->len = (unsigned)strlen((char *)t->ustring);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
414 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
415 else if (id == Id::VERSIONX)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
416 { unsigned major = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
417 unsigned minor = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
418 bool point = false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
419
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
420 for (const char *p = global.version + 1; 1; p++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
421 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
422 c = *p;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
423 if (isdigit((utf8_t)c))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
424 minor = minor * 10 + c - '0';
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
425 else if (c == '.')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
426 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
427 if (point)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
428 break; // ignore everything after second '.'
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
429 point = true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
430 major = minor;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
431 minor = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
432 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
433 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
434 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
435 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
436 t->value = TOKint64v;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
437 t->uns64value = major * 1000 + minor;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
438 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
439 else if (id == Id::EOFX)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
440 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
441 t->value = TOKeof;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
442 // Advance scanner to end of file
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
443 while (!(*p == 0 || *p == 0x1A))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
444 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
445 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
446 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
447 //printf("t->value = %d\n",t->value);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
448 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
449 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
450
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
451 case '/':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
452 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
453 switch (*p)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
454 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
455 case '=':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
456 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
457 t->value = TOKdivass;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
458 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
459
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
460 case '*':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
461 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
462 startLoc = loc();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
463 while (1)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
464 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
465 while (1)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
466 { utf8_t c = *p;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
467 switch (c)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
468 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
469 case '/':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
470 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
471
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
472 case '\n':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
473 endOfLine();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
474 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
475 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
476
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
477 case '\r':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
478 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
479 if (*p != '\n')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
480 endOfLine();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
481 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
482
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
483 case 0:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
484 case 0x1A:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
485 error("unterminated /* */ comment");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
486 p = end;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
487 t->loc = loc();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
488 t->value = TOKeof;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
489 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
490
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
491 default:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
492 if (c & 0x80)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
493 { unsigned u = decodeUTF();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
494 if (u == PS || u == LS)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
495 endOfLine();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
496 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
497 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
498 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
499 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
500 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
501 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
502 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
503 if (p[-2] == '*' && p - 3 != t->ptr)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
504 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
505 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
506 if (commentToken)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
507 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
508 t->loc = startLoc;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
509 t->value = TOKcomment;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
510 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
511 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
512 else if (doDocComment && t->ptr[2] == '*' && p - 4 != t->ptr)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
513 { // if /** but not /**/
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
514 getDocComment(t, lastLine == startLoc.linnum);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
515 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
516 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
517
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
518 case '/': // do // style comments
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
519 startLoc = loc();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
520 while (1)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
521 { utf8_t c = *++p;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
522 switch (c)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
523 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
524 case '\n':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
525 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
526
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
527 case '\r':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
528 if (p[1] == '\n')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
529 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
530 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
531
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
532 case 0:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
533 case 0x1A:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
534 if (commentToken)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
535 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
536 p = end;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
537 t->loc = startLoc;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
538 t->value = TOKcomment;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
539 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
540 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
541 if (doDocComment && t->ptr[2] == '/')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
542 getDocComment(t, lastLine == startLoc.linnum);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
543 p = end;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
544 t->loc = loc();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
545 t->value = TOKeof;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
546 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
547
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
548 default:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
549 if (c & 0x80)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
550 { unsigned u = decodeUTF();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
551 if (u == PS || u == LS)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
552 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
553 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
554 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
555 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
556 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
557 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
558
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
559 if (commentToken)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
560 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
561 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
562 endOfLine();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
563 t->loc = startLoc;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
564 t->value = TOKcomment;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
565 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
566 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
567 if (doDocComment && t->ptr[2] == '/')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
568 getDocComment(t, lastLine == startLoc.linnum);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
569
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
570 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
571 endOfLine();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
572 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
573
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
574 case '+':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
575 { int nest;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
576
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
577 startLoc = loc();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
578 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
579 nest = 1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
580 while (1)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
581 { utf8_t c = *p;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
582 switch (c)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
583 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
584 case '/':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
585 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
586 if (*p == '+')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
587 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
588 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
589 nest++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
590 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
591 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
592
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
593 case '+':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
594 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
595 if (*p == '/')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
596 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
597 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
598 if (--nest == 0)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
599 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
600 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
601 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
602
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
603 case '\r':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
604 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
605 if (*p != '\n')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
606 endOfLine();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
607 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
608
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
609 case '\n':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
610 endOfLine();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
611 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
612 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
613
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
614 case 0:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
615 case 0x1A:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
616 error("unterminated /+ +/ comment");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
617 p = end;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
618 t->loc = loc();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
619 t->value = TOKeof;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
620 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
621
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
622 default:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
623 if (c & 0x80)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
624 { unsigned u = decodeUTF();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
625 if (u == PS || u == LS)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
626 endOfLine();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
627 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
628 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
629 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
630 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
631 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
632 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
633 if (commentToken)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
634 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
635 t->loc = startLoc;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
636 t->value = TOKcomment;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
637 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
638 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
639 if (doDocComment && t->ptr[2] == '+' && p - 4 != t->ptr)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
640 { // if /++ but not /++/
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
641 getDocComment(t, lastLine == startLoc.linnum);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
642 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
643 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
644 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
645 default:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
646 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
647 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
648 t->value = TOKdiv;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
649 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
650
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
651 case '.':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
652 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
653 if (isdigit(*p))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
654 { /* Note that we don't allow ._1 and ._ as being
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
655 * valid floating point numbers.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
656 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
657 p--;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
658 t->value = inreal(t);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
659 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
660 else if (p[0] == '.')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
661 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
662 if (p[1] == '.')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
663 { p += 2;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
664 t->value = TOKdotdotdot;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
665 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
666 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
667 { p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
668 t->value = TOKslice;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
669 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
670 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
671 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
672 t->value = TOKdot;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
673 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
674
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
675 case '&':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
676 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
677 if (*p == '=')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
678 { p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
679 t->value = TOKandass;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
680 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
681 else if (*p == '&')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
682 { p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
683 t->value = TOKandand;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
684 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
685 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
686 t->value = TOKand;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
687 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
688
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
689 case '|':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
690 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
691 if (*p == '=')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
692 { p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
693 t->value = TOKorass;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
694 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
695 else if (*p == '|')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
696 { p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
697 t->value = TOKoror;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
698 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
699 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
700 t->value = TOKor;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
701 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
702
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
703 case '-':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
704 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
705 if (*p == '=')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
706 { p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
707 t->value = TOKminass;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
708 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
709 else if (*p == '-')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
710 { p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
711 t->value = TOKminusminus;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
712 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
713 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
714 t->value = TOKmin;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
715 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
716
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
717 case '+':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
718 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
719 if (*p == '=')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
720 { p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
721 t->value = TOKaddass;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
722 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
723 else if (*p == '+')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
724 { p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
725 t->value = TOKplusplus;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
726 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
727 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
728 t->value = TOKadd;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
729 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
730
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
731 case '<':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
732 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
733 if (*p == '=')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
734 { p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
735 t->value = TOKle; // <=
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
736 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
737 else if (*p == '<')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
738 { p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
739 if (*p == '=')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
740 { p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
741 t->value = TOKshlass; // <<=
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
742 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
743 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
744 t->value = TOKshl; // <<
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
745 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
746 else if (*p == '>')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
747 { p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
748 if (*p == '=')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
749 { p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
750 t->value = TOKleg; // <>=
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
751 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
752 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
753 t->value = TOKlg; // <>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
754 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
755 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
756 t->value = TOKlt; // <
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
757 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
758
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
759 case '>':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
760 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
761 if (*p == '=')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
762 { p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
763 t->value = TOKge; // >=
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
764 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
765 else if (*p == '>')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
766 { p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
767 if (*p == '=')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
768 { p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
769 t->value = TOKshrass; // >>=
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
770 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
771 else if (*p == '>')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
772 { p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
773 if (*p == '=')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
774 { p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
775 t->value = TOKushrass; // >>>=
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
776 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
777 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
778 t->value = TOKushr; // >>>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
779 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
780 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
781 t->value = TOKshr; // >>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
782 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
783 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
784 t->value = TOKgt; // >
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
785 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
786
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
787 case '!':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
788 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
789 if (*p == '=')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
790 { p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
791 t->value = TOKnotequal; // !=
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
792 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
793 else if (*p == '<')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
794 { p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
795 if (*p == '>')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
796 { p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
797 if (*p == '=')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
798 { p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
799 t->value = TOKunord; // !<>=
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
800 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
801 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
802 t->value = TOKue; // !<>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
803 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
804 else if (*p == '=')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
805 { p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
806 t->value = TOKug; // !<=
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
807 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
808 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
809 t->value = TOKuge; // !<
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
810 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
811 else if (*p == '>')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
812 { p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
813 if (*p == '=')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
814 { p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
815 t->value = TOKul; // !>=
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
816 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
817 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
818 t->value = TOKule; // !>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
819 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
820 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
821 t->value = TOKnot; // !
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
822 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
823
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
824 case '=':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
825 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
826 if (*p == '=')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
827 { p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
828 t->value = TOKequal; // ==
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
829 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
830 else if (*p == '>')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
831 { p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
832 t->value = TOKgoesto; // =>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
833 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
834 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
835 t->value = TOKassign; // =
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
836 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
837
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
838 case '~':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
839 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
840 if (*p == '=')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
841 { p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
842 t->value = TOKcatass; // ~=
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
843 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
844 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
845 t->value = TOKtilde; // ~
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
846 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
847
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
848 case '^':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
849 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
850 if (*p == '^')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
851 { p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
852 if (*p == '=')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
853 { p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
854 t->value = TOKpowass; // ^^=
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
855 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
856 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
857 t->value = TOKpow; // ^^
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
858 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
859 else if (*p == '=')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
860 { p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
861 t->value = TOKxorass; // ^=
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
862 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
863 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
864 t->value = TOKxor; // ^
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
865 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
866
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
867 case '(': p++; t->value = TOKlparen; return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
868 case ')': p++; t->value = TOKrparen; return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
869 case '[': p++; t->value = TOKlbracket; return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
870 case ']': p++; t->value = TOKrbracket; return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
871 case '{': p++; t->value = TOKlcurly; return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
872 case '}': p++; t->value = TOKrcurly; return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
873 case '?': p++; t->value = TOKquestion; return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
874 case ',': p++; t->value = TOKcomma; return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
875 case ';': p++; t->value = TOKsemicolon; return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
876 case ':': p++; t->value = TOKcolon; return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
877 case '$': p++; t->value = TOKdollar; return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
878 case '@': p++; t->value = TOKat; return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
879
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
880 case '*':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
881 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
882 if (*p == '=')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
883 { p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
884 t->value = TOKmulass;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
885 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
886 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
887 t->value = TOKmul;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
888 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
889 case '%':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
890 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
891 if (*p == '=')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
892 { p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
893 t->value = TOKmodass;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
894 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
895 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
896 t->value = TOKmod;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
897 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
898
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
899 case '#':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
900 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
901 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
902 Token n;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
903 scan(&n);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
904 if (n.value == TOKidentifier)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
905 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
906 if (n.ident == Id::line)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
907 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
908 poundLine();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
909 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
910 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
911 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
912 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
913 const Loc locx = loc();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
914 warning(locx, "C preprocessor directive `#%s` is not supported", n.ident->toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
915 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
916 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
917 else if (n.value == TOKif)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
918 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
919 error("C preprocessor directive `#if` is not supported, use `version` or `static if`");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
920 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
921 t->value = TOKpound;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
922 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
923 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
924
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
925 default:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
926 { unsigned c = *p;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
927
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
928 if (c & 0x80)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
929 { c = decodeUTF();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
930
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
931 // Check for start of unicode identifier
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
932 if (isUniAlpha(c))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
933 goto case_ident;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
934
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
935 if (c == PS || c == LS)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
936 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
937 endOfLine();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
938 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
939 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
940 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
941 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
942 if (c < 0x80 && isprint(c))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
943 error("character '%c' is not a valid token", c);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
944 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
945 error("character 0x%02x is not a valid token", c);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
946 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
947 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
948 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
949 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
950 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
951 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
952
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
953 /*******************************************
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
954 * Parse escape sequence.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
955 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
956
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
957 unsigned Lexer::escapeSequence()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
958 { unsigned c = *p;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
959
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
960 int n;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
961 int ndigits;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
962
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
963 switch (c)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
964 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
965 case '\'':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
966 case '"':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
967 case '?':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
968 case '\\':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
969 Lconsume:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
970 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
971 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
972
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
973 case 'a': c = 7; goto Lconsume;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
974 case 'b': c = 8; goto Lconsume;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
975 case 'f': c = 12; goto Lconsume;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
976 case 'n': c = 10; goto Lconsume;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
977 case 'r': c = 13; goto Lconsume;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
978 case 't': c = 9; goto Lconsume;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
979 case 'v': c = 11; goto Lconsume;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
980
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
981 case 'u':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
982 ndigits = 4;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
983 goto Lhex;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
984 case 'U':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
985 ndigits = 8;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
986 goto Lhex;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
987 case 'x':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
988 ndigits = 2;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
989 Lhex:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
990 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
991 c = *p;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
992 if (ishex((utf8_t)c))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
993 { unsigned v;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
994
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
995 n = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
996 v = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
997 while (1)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
998 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
999 if (isdigit((utf8_t)c))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1000 c -= '0';
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1001 else if (islower(c))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1002 c -= 'a' - 10;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1003 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1004 c -= 'A' - 10;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1005 v = v * 16 + c;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1006 c = *++p;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1007 if (++n == ndigits)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1008 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1009 if (!ishex((utf8_t)c))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1010 { error("escape hex sequence has %d hex digits instead of %d", n, ndigits);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1011 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1012 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1013 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1014 if (ndigits != 2 && !utf_isValidDchar(v))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1015 { error("invalid UTF character \\U%08x", v);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1016 v = '?'; // recover with valid UTF character
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1017 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1018 c = v;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1019 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1020 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1021 error("undefined escape hex sequence \\%c",c);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1022 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1023
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1024 case '&': // named character entity
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1025 for (const utf8_t *idstart = ++p; 1; p++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1026 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1027 switch (*p)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1028 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1029 case ';':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1030 c = HtmlNamedEntity(idstart, p - idstart);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1031 if (c == ~0U)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1032 { error("unnamed character entity &%.*s;", (int)(p - idstart), idstart);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1033 c = ' ';
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1034 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1035 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1036 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1037
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1038 default:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1039 if (isalpha(*p) ||
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1040 (p != idstart && isdigit(*p)))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1041 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1042 error("unterminated named entity &%.*s;", (int)(p - idstart + 1), idstart);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1043 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1044 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1045 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1046 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1047 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1048
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1049 case 0:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1050 case 0x1A: // end of file
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1051 c = '\\';
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1052 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1053
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1054 default:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1055 if (isoctal((utf8_t)c))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1056 { unsigned v;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1057
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1058 n = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1059 v = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1060 do
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1061 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1062 v = v * 8 + (c - '0');
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1063 c = *++p;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1064 } while (++n < 3 && isoctal((utf8_t)c));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1065 c = v;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1066 if (c > 0xFF)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1067 error("escape octal sequence \\%03o is larger than \\377", c);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1068 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1069 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1070 error("undefined escape sequence \\%c",c);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1071 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1072 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1073 return c;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1074 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1075
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1076 /**************************************
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1077 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1078
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1079 TOK Lexer::wysiwygStringConstant(Token *t, int tc)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1080 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1081 int c;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1082 Loc start = loc();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1083
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1084 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1085 stringbuffer.reset();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1086 while (1)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1087 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1088 c = *p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1089 switch (c)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1090 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1091 case '\n':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1092 endOfLine();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1093 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1094
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1095 case '\r':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1096 if (*p == '\n')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1097 continue; // ignore
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1098 c = '\n'; // treat EndOfLine as \n character
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1099 endOfLine();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1100 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1101
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1102 case 0:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1103 case 0x1A:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1104 error("unterminated string constant starting at %s", start.toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1105 t->ustring = (utf8_t *)const_cast<char *>("");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1106 t->len = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1107 t->postfix = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1108 return TOKstring;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1109
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1110 case '"':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1111 case '`':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1112 if (c == tc)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1113 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1114 t->len = (unsigned)stringbuffer.offset;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1115 stringbuffer.writeByte(0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1116 t->ustring = (utf8_t *)mem.xmalloc(stringbuffer.offset);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1117 memcpy(t->ustring, stringbuffer.data, stringbuffer.offset);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1118 stringPostfix(t);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1119 return TOKstring;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1120 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1121 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1122
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1123 default:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1124 if (c & 0x80)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1125 { p--;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1126 unsigned u = decodeUTF();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1127 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1128 if (u == PS || u == LS)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1129 endOfLine();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1130 stringbuffer.writeUTF8(u);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1131 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1132 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1133 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1134 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1135 stringbuffer.writeByte(c);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1136 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1137 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1138
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1139 /**************************************
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1140 * Lex hex strings:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1141 * x"0A ae 34FE BD"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1142 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1143
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1144 TOK Lexer::hexStringConstant(Token *t)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1145 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1146 unsigned c;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1147 Loc start = loc();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1148 unsigned n = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1149 unsigned v = ~0; // dead assignment, needed to suppress warning
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1150
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1151 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1152 stringbuffer.reset();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1153 while (1)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1154 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1155 c = *p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1156 switch (c)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1157 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1158 case ' ':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1159 case '\t':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1160 case '\v':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1161 case '\f':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1162 continue; // skip white space
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1163
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1164 case '\r':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1165 if (*p == '\n')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1166 continue; // ignore
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1167 // Treat isolated '\r' as if it were a '\n'
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1168 /* fall through */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1169 case '\n':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1170 endOfLine();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1171 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1172
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1173 case 0:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1174 case 0x1A:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1175 error("unterminated string constant starting at %s", start.toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1176 t->ustring = (utf8_t *)const_cast<char *>("");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1177 t->len = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1178 t->postfix = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1179 return TOKxstring;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1180
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1181 case '"':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1182 if (n & 1)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1183 { error("odd number (%d) of hex characters in hex string", n);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1184 stringbuffer.writeByte(v);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1185 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1186 t->len = (unsigned)stringbuffer.offset;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1187 stringbuffer.writeByte(0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1188 t->ustring = (utf8_t *)mem.xmalloc(stringbuffer.offset);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1189 memcpy(t->ustring, stringbuffer.data, stringbuffer.offset);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1190 stringPostfix(t);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1191 return TOKxstring;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1192
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1193 default:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1194 if (c >= '0' && c <= '9')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1195 c -= '0';
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1196 else if (c >= 'a' && c <= 'f')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1197 c -= 'a' - 10;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1198 else if (c >= 'A' && c <= 'F')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1199 c -= 'A' - 10;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1200 else if (c & 0x80)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1201 { p--;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1202 unsigned u = decodeUTF();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1203 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1204 if (u == PS || u == LS)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1205 endOfLine();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1206 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1207 error("non-hex character \\u%04x in hex string", u);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1208 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1209 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1210 error("non-hex character '%c' in hex string", c);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1211 if (n & 1)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1212 { v = (v << 4) | c;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1213 stringbuffer.writeByte(v);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1214 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1215 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1216 v = c;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1217 n++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1218 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1219 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1220 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1221 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1222
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1223
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1224 /**************************************
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1225 * Lex delimited strings:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1226 * q"(foo(xxx))" // "foo(xxx)"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1227 * q"[foo(]" // "foo("
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1228 * q"/foo]/" // "foo]"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1229 * q"HERE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1230 * foo
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1231 * HERE" // "foo\n"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1232 * Input:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1233 * p is on the "
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1234 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1235
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1236 TOK Lexer::delimitedStringConstant(Token *t)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1237 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1238 unsigned c;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1239 Loc start = loc();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1240 unsigned delimleft = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1241 unsigned delimright = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1242 unsigned nest = 1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1243 unsigned nestcount = ~0; // dead assignment, needed to suppress warning
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1244 Identifier *hereid = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1245 unsigned blankrol = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1246 unsigned startline = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1247
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1248 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1249 stringbuffer.reset();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1250 while (1)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1251 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1252 c = *p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1253 //printf("c = '%c'\n", c);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1254 switch (c)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1255 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1256 case '\n':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1257 Lnextline:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1258 endOfLine();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1259 startline = 1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1260 if (blankrol)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1261 { blankrol = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1262 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1263 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1264 if (hereid)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1265 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1266 stringbuffer.writeUTF8(c);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1267 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1268 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1269 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1270
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1271 case '\r':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1272 if (*p == '\n')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1273 continue; // ignore
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1274 c = '\n'; // treat EndOfLine as \n character
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1275 goto Lnextline;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1276
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1277 case 0:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1278 case 0x1A:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1279 error("unterminated delimited string constant starting at %s", start.toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1280 t->ustring = (utf8_t *)const_cast<char *>("");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1281 t->len = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1282 t->postfix = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1283 return TOKstring;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1284
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1285 default:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1286 if (c & 0x80)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1287 { p--;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1288 c = decodeUTF();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1289 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1290 if (c == PS || c == LS)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1291 goto Lnextline;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1292 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1293 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1294 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1295 if (delimleft == 0)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1296 { delimleft = c;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1297 nest = 1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1298 nestcount = 1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1299 if (c == '(')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1300 delimright = ')';
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1301 else if (c == '{')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1302 delimright = '}';
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1303 else if (c == '[')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1304 delimright = ']';
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1305 else if (c == '<')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1306 delimright = '>';
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1307 else if (isalpha(c) || c == '_' || (c >= 0x80 && isUniAlpha(c)))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1308 { // Start of identifier; must be a heredoc
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1309 Token tok;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1310 p--;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1311 scan(&tok); // read in heredoc identifier
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1312 if (tok.value != TOKidentifier)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1313 { error("identifier expected for heredoc, not %s", tok.toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1314 delimright = c;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1315 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1316 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1317 { hereid = tok.ident;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1318 //printf("hereid = '%s'\n", hereid->toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1319 blankrol = 1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1320 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1321 nest = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1322 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1323 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1324 { delimright = c;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1325 nest = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1326 if (isspace(c))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1327 error("delimiter cannot be whitespace");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1328 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1329 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1330 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1331 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1332 if (blankrol)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1333 { error("heredoc rest of line should be blank");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1334 blankrol = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1335 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1336 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1337 if (nest == 1)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1338 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1339 if (c == delimleft)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1340 nestcount++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1341 else if (c == delimright)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1342 { nestcount--;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1343 if (nestcount == 0)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1344 goto Ldone;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1345 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1346 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1347 else if (c == delimright)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1348 goto Ldone;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1349 if (startline && isalpha(c) && hereid)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1350 { Token tok;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1351 const utf8_t *psave = p;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1352 p--;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1353 scan(&tok); // read in possible heredoc identifier
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1354 //printf("endid = '%s'\n", tok.ident->toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1355 if (tok.value == TOKidentifier && tok.ident->equals(hereid))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1356 { /* should check that rest of line is blank
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1357 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1358 goto Ldone;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1359 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1360 p = psave;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1361 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1362 stringbuffer.writeUTF8(c);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1363 startline = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1364 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1365 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1366
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1367 Ldone:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1368 if (*p == '"')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1369 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1370 else if (hereid)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1371 error("delimited string must end in %s\"", hereid->toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1372 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1373 error("delimited string must end in %c\"", delimright);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1374 t->len = (unsigned)stringbuffer.offset;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1375 stringbuffer.writeByte(0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1376 t->ustring = (utf8_t *)mem.xmalloc(stringbuffer.offset);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1377 memcpy(t->ustring, stringbuffer.data, stringbuffer.offset);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1378 stringPostfix(t);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1379 return TOKstring;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1380 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1381
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1382 /**************************************
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1383 * Lex delimited strings:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1384 * q{ foo(xxx) } // " foo(xxx) "
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1385 * q{foo(} // "foo("
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1386 * q{{foo}"}"} // "{foo}"}""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1387 * Input:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1388 * p is on the q
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1389 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1390
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1391 TOK Lexer::tokenStringConstant(Token *t)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1392 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1393 unsigned nest = 1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1394 Loc start = loc();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1395 const utf8_t *pstart = ++p;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1396
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1397 while (1)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1398 { Token tok;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1399
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1400 scan(&tok);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1401 switch (tok.value)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1402 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1403 case TOKlcurly:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1404 nest++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1405 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1406
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1407 case TOKrcurly:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1408 if (--nest == 0)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1409 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1410 t->len = (unsigned)(p - 1 - pstart);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1411 t->ustring = (utf8_t *)mem.xmalloc(t->len + 1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1412 memcpy(t->ustring, pstart, t->len);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1413 t->ustring[t->len] = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1414 stringPostfix(t);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1415 return TOKstring;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1416 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1417 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1418
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1419 case TOKeof:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1420 error("unterminated token string constant starting at %s", start.toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1421 t->ustring = (utf8_t *)const_cast<char *>("");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1422 t->len = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1423 t->postfix = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1424 return TOKstring;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1425
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1426 default:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1427 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1428 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1429 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1430 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1431
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1432
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1433
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1434 /**************************************
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1435 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1436
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1437 TOK Lexer::escapeStringConstant(Token *t)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1438 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1439 unsigned c;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1440 Loc start = loc();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1441
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1442 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1443 stringbuffer.reset();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1444 while (1)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1445 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1446 c = *p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1447 switch (c)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1448 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1449 case '\\':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1450 switch (*p)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1451 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1452 case 'u':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1453 case 'U':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1454 case '&':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1455 c = escapeSequence();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1456 stringbuffer.writeUTF8(c);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1457 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1458
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1459 default:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1460 c = escapeSequence();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1461 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1462 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1463 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1464 case '\n':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1465 endOfLine();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1466 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1467
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1468 case '\r':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1469 if (*p == '\n')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1470 continue; // ignore
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1471 c = '\n'; // treat EndOfLine as \n character
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1472 endOfLine();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1473 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1474
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1475 case '"':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1476 t->len = (unsigned)stringbuffer.offset;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1477 stringbuffer.writeByte(0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1478 t->ustring = (utf8_t *)mem.xmalloc(stringbuffer.offset);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1479 memcpy(t->ustring, stringbuffer.data, stringbuffer.offset);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1480 stringPostfix(t);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1481 return TOKstring;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1482
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1483 case 0:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1484 case 0x1A:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1485 p--;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1486 error("unterminated string constant starting at %s", start.toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1487 t->ustring = (utf8_t *)const_cast<char *>("");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1488 t->len = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1489 t->postfix = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1490 return TOKstring;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1491
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1492 default:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1493 if (c & 0x80)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1494 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1495 p--;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1496 c = decodeUTF();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1497 if (c == LS || c == PS)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1498 { c = '\n';
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1499 endOfLine();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1500 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1501 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1502 stringbuffer.writeUTF8(c);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1503 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1504 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1505 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1506 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1507 stringbuffer.writeByte(c);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1508 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1509 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1510
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1511 /**************************************
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1512 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1513
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1514 TOK Lexer::charConstant(Token *t)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1515 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1516 unsigned c;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1517 TOK tk = TOKcharv;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1518
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1519 //printf("Lexer::charConstant\n");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1520 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1521 c = *p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1522 switch (c)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1523 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1524 case '\\':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1525 switch (*p)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1526 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1527 case 'u':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1528 t->uns64value = escapeSequence();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1529 tk = TOKwcharv;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1530 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1531
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1532 case 'U':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1533 case '&':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1534 t->uns64value = escapeSequence();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1535 tk = TOKdcharv;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1536 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1537
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1538 default:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1539 t->uns64value = escapeSequence();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1540 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1541 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1542 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1543 case '\n':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1544 L1:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1545 endOfLine();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1546 /* fall through */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1547 case '\r':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1548 case 0:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1549 case 0x1A:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1550 case '\'':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1551 error("unterminated character constant");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1552 t->uns64value = '?';
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1553 return tk;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1554
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1555 default:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1556 if (c & 0x80)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1557 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1558 p--;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1559 c = decodeUTF();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1560 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1561 if (c == LS || c == PS)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1562 goto L1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1563 if (c < 0xD800 || (c >= 0xE000 && c < 0xFFFE))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1564 tk = TOKwcharv;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1565 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1566 tk = TOKdcharv;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1567 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1568 t->uns64value = c;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1569 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1570 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1571
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1572 if (*p != '\'')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1573 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1574 error("unterminated character constant");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1575 t->uns64value = '?';
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1576 return tk;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1577 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1578 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1579 return tk;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1580 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1581
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1582 /***************************************
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1583 * Get postfix of string literal.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1584 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1585
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1586 void Lexer::stringPostfix(Token *t)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1587 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1588 switch (*p)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1589 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1590 case 'c':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1591 case 'w':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1592 case 'd':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1593 t->postfix = *p;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1594 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1595 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1596
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1597 default:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1598 t->postfix = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1599 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1600 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1601 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1602
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1603 /**************************************
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1604 * Read in a number.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1605 * If it's an integer, store it in tok.TKutok.Vlong.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1606 * integers can be decimal, octal or hex
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1607 * Handle the suffixes U, UL, LU, L, etc.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1608 * If it's double, store it in tok.TKutok.Vdouble.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1609 * Returns:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1610 * TKnum
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1611 * TKdouble,...
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1612 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1613
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1614 TOK Lexer::number(Token *t)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1615 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1616 int base = 10;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1617 const utf8_t *start = p;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1618 unsigned c;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1619 uinteger_t n = 0; // unsigned >=64 bit integer type
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1620 int d;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1621 bool err = false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1622 bool overflow = false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1623
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1624 c = *p;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1625 if (c == '0')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1626 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1627 ++p;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1628 c = *p;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1629 switch (c)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1630 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1631 case '0': case '1': case '2': case '3':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1632 case '4': case '5': case '6': case '7':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1633 n = c - '0';
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1634 ++p;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1635 base = 8;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1636 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1637
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1638 case 'x':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1639 case 'X':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1640 ++p;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1641 base = 16;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1642 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1643
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1644 case 'b':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1645 case 'B':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1646 ++p;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1647 base = 2;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1648 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1649
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1650 case '.':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1651 if (p[1] == '.')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1652 goto Ldone; // if ".."
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1653 if (isalpha(p[1]) || p[1] == '_' || p[1] & 0x80)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1654 goto Ldone; // if ".identifier" or ".unicode"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1655 goto Lreal; // '.' is part of current token
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1656
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1657 case 'i':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1658 case 'f':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1659 case 'F':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1660 goto Lreal;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1661
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1662 case '_':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1663 ++p;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1664 base = 8;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1665 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1666
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1667 case 'L':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1668 if (p[1] == 'i')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1669 goto Lreal;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1670 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1671
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1672 default:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1673 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1674 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1675 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1676
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1677 while (1)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1678 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1679 c = *p;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1680 switch (c)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1681 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1682 case '0': case '1':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1683 ++p;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1684 d = c - '0';
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1685 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1686
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1687 case '2': case '3':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1688 case '4': case '5': case '6': case '7':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1689 if (base == 2 && !err)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1690 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1691 error("binary digit expected");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1692 err = true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1693 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1694 ++p;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1695 d = c - '0';
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1696 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1697
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1698 case '8': case '9':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1699 ++p;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1700 if (base < 10 && !err)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1701 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1702 error("radix %d digit expected, not '%c'", base, c);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1703 err = true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1704 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1705 d = c - '0';
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1706 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1707
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1708 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1709 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1710 ++p;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1711 if (base != 16)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1712 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1713 if (c == 'e' || c == 'E' || c == 'f' || c == 'F')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1714 goto Lreal;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1715 if (!err)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1716 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1717 error("radix %d digit expected, not '%c'", base, c);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1718 err = true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1719 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1720 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1721 if (c >= 'a')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1722 d = c + 10 - 'a';
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1723 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1724 d = c + 10 - 'A';
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1725 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1726
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1727 case 'L':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1728 if (p[1] == 'i')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1729 goto Lreal;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1730 goto Ldone;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1731
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1732 case '.':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1733 if (p[1] == '.')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1734 goto Ldone; // if ".."
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1735 if (base == 10 && (isalpha(p[1]) || p[1] == '_' || p[1] & 0x80))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1736 goto Ldone; // if ".identifier" or ".unicode"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1737 goto Lreal; // otherwise as part of a floating point literal
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1738
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1739 case 'p':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1740 case 'P':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1741 case 'i':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1742 Lreal:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1743 p = start;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1744 return inreal(t);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1745
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1746 case '_':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1747 ++p;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1748 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1749
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1750 default:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1751 goto Ldone;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1752 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1753
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1754 uinteger_t n2 = n * base;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1755 if ((n2 / base != n || n2 + d < n))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1756 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1757 overflow = true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1758 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1759 n = n2 + d;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1760
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1761 // if n needs more than 64 bits
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1762 if (sizeof(n) > 8 &&
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1763 n > 0xFFFFFFFFFFFFFFFFULL)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1764 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1765 overflow = true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1766 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1767 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1768
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1769 Ldone:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1770
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1771 if (overflow && !err)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1772 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1773 error("integer overflow");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1774 err = true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1775 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1776
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1777 enum FLAGS
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1778 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1779 FLAGS_none = 0,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1780 FLAGS_decimal = 1, // decimal
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1781 FLAGS_unsigned = 2, // u or U suffix
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1782 FLAGS_long = 4, // L suffix
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1783 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1784
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1785 unsigned flags = (base == 10) ? FLAGS_decimal : FLAGS_none;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1786
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1787 // Parse trailing 'u', 'U', 'l' or 'L' in any combination
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1788 const utf8_t *psuffix = p;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1789 while (1)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1790 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1791 utf8_t f;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1792 switch (*p)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1793 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1794 case 'U':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1795 case 'u':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1796 f = FLAGS_unsigned;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1797 goto L1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1798
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1799 case 'l':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1800 f = FLAGS_long;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1801 error("lower case integer suffix 'l' is not allowed. Please use 'L' instead");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1802 goto L1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1803
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1804 case 'L':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1805 f = FLAGS_long;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1806 L1:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1807 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1808 if ((flags & f) && !err)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1809 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1810 error("unrecognized token");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1811 err = true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1812 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1813 flags = (FLAGS) (flags | f);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1814 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1815 default:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1816 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1817 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1818 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1819 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1820
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1821 if (base == 8 && n >= 8)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1822 error("octal literals 0%llo%.*s are no longer supported, use std.conv.octal!%llo%.*s instead",
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1823 n, p - psuffix, psuffix, n, p - psuffix, psuffix);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1824
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1825 TOK result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1826 switch (flags)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1827 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1828 case FLAGS_none:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1829 /* Octal or Hexadecimal constant.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1830 * First that fits: int, uint, long, ulong
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1831 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1832 if (n & 0x8000000000000000LL)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1833 result = TOKuns64v;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1834 else if (n & 0xFFFFFFFF00000000LL)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1835 result = TOKint64v;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1836 else if (n & 0x80000000)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1837 result = TOKuns32v;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1838 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1839 result = TOKint32v;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1840 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1841
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1842 case FLAGS_decimal:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1843 /* First that fits: int, long, long long
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1844 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1845 if (n & 0x8000000000000000LL)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1846 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1847 if (!err)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1848 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1849 error("signed integer overflow");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1850 err = true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1851 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1852 result = TOKuns64v;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1853 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1854 else if (n & 0xFFFFFFFF80000000LL)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1855 result = TOKint64v;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1856 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1857 result = TOKint32v;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1858 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1859
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1860 case FLAGS_unsigned:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1861 case FLAGS_decimal | FLAGS_unsigned:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1862 /* First that fits: uint, ulong
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1863 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1864 if (n & 0xFFFFFFFF00000000LL)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1865 result = TOKuns64v;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1866 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1867 result = TOKuns32v;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1868 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1869
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1870 case FLAGS_decimal | FLAGS_long:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1871 if (n & 0x8000000000000000LL)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1872 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1873 if (!err)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1874 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1875 error("signed integer overflow");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1876 err = true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1877 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1878 result = TOKuns64v;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1879 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1880 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1881 result = TOKint64v;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1882 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1883
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1884 case FLAGS_long:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1885 if (n & 0x8000000000000000LL)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1886 result = TOKuns64v;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1887 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1888 result = TOKint64v;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1889 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1890
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1891 case FLAGS_unsigned | FLAGS_long:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1892 case FLAGS_decimal | FLAGS_unsigned | FLAGS_long:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1893 result = TOKuns64v;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1894 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1895
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1896 default:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1897 assert(0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1898 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1899 t->uns64value = n;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1900 return result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1901 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1902
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1903 /**************************************
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1904 * Read in characters, converting them to real.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1905 * Bugs:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1906 * Exponent overflow not detected.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1907 * Too much requested precision is not detected.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1908 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1909
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1910 TOK Lexer::inreal(Token *t)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1911 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1912 //printf("Lexer::inreal()\n");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1913 bool isWellformedString = true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1914 stringbuffer.reset();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1915 const utf8_t *pstart = p;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1916 char hex = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1917 unsigned c = *p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1918
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1919 // Leading '0x'
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1920 if (c == '0')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1921 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1922 c = *p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1923 if (c == 'x' || c == 'X')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1924 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1925 hex = true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1926 c = *p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1927 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1928 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1929
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1930 // Digits to left of '.'
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1931 while (1)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1932 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1933 if (c == '.')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1934 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1935 c = *p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1936 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1937 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1938 if (isdigit(c) || (hex && isxdigit(c)) || c == '_')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1939 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1940 c = *p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1941 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1942 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1943 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1944 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1945
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1946 // Digits to right of '.'
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1947 while (1)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1948 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1949 if (isdigit(c) || (hex && isxdigit(c)) || c == '_')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1950 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1951 c = *p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1952 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1953 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1954 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1955 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1956
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1957 if (c == 'e' || c == 'E' || (hex && (c == 'p' || c == 'P')))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1958 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1959 c = *p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1960 if (c == '-' || c == '+')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1961 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1962 c = *p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1963 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1964 bool anyexp = false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1965 while (1)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1966 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1967 if (isdigit(c))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1968 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1969 anyexp = true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1970 c = *p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1971 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1972 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1973 if (c == '_')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1974 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1975 c = *p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1976 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1977 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1978 if (!anyexp)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1979 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1980 error("missing exponent");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1981 isWellformedString = false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1982 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1983 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1984 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1985 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1986 else if (hex)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1987 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1988 error("exponent required for hex float");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1989 isWellformedString = false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1990 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1991 --p;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1992 while (pstart < p)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1993 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1994 if (*pstart != '_')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1995 stringbuffer.writeByte(*pstart);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1996 ++pstart;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1997 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1998
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1999 stringbuffer.writeByte(0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2000 const char *sbufptr = (char *)stringbuffer.data;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2001 TOK result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2002 bool isOutOfRange = false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2003 t->floatvalue = (isWellformedString ? CTFloat::parse(sbufptr, &isOutOfRange) : CTFloat::zero);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2004 errno = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2005 switch (*p)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2006 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2007 case 'F':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2008 case 'f':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2009 if (isWellformedString && !isOutOfRange)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2010 isOutOfRange = Port::isFloat32LiteralOutOfRange(sbufptr);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2011 result = TOKfloat32v;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2012 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2013 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2014
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2015 default:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2016 if (isWellformedString && !isOutOfRange)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2017 isOutOfRange = Port::isFloat64LiteralOutOfRange(sbufptr);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2018 result = TOKfloat64v;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2019 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2020
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2021 case 'l':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2022 error("use 'L' suffix instead of 'l'");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2023 /* fall through */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2024 case 'L':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2025 result = TOKfloat80v;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2026 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2027 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2028 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2029 if (*p == 'i' || *p == 'I')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2030 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2031 if (*p == 'I')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2032 error("use 'i' suffix instead of 'I'");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2033 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2034 switch (result)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2035 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2036 case TOKfloat32v:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2037 result = TOKimaginary32v;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2038 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2039 case TOKfloat64v:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2040 result = TOKimaginary64v;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2041 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2042 case TOKfloat80v:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2043 result = TOKimaginary80v;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2044 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2045 default: break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2046 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2047 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2048 const bool isLong = (result == TOKfloat80v || result == TOKimaginary80v);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2049 if (isOutOfRange && !isLong)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2050 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2051 const char *suffix = (result == TOKfloat32v || result == TOKimaginary32v) ? "f" : "";
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2052 error(scanloc, "number '%s%s' is not representable", (char *)stringbuffer.data, suffix);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2053 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2054 return result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2055 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2056
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2057 /*********************************************
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2058 * parse:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2059 * #line linnum [filespec]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2060 * also allow __LINE__ for linnum, and __FILE__ for filespec
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2061 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2062
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2063 void Lexer::poundLine()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2064 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2065 Token tok;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2066 int linnum = this->scanloc.linnum;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2067 char *filespec = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2068 Loc loc = this->loc();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2069
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2070 scan(&tok);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2071 if (tok.value == TOKint32v || tok.value == TOKint64v)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2072 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2073 int lin = (int)(tok.uns64value - 1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2074 if ((unsigned)lin != tok.uns64value - 1)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2075 error("line number %lld out of range", (unsigned long long)tok.uns64value);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2076 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2077 linnum = lin;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2078 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2079 else if (tok.value == TOKline)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2080 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2081 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2082 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2083 goto Lerr;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2084
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2085 while (1)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2086 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2087 switch (*p)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2088 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2089 case 0:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2090 case 0x1A:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2091 case '\n':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2092 Lnewline:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2093 this->scanloc.linnum = linnum;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2094 if (filespec)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2095 this->scanloc.filename = filespec;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2096 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2097
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2098 case '\r':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2099 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2100 if (*p != '\n')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2101 { p--;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2102 goto Lnewline;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2103 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2104 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2105
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2106 case ' ':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2107 case '\t':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2108 case '\v':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2109 case '\f':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2110 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2111 continue; // skip white space
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2112
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2113 case '_':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2114 if (memcmp(p, "__FILE__", 8) == 0)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2115 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2116 p += 8;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2117 filespec = mem.xstrdup(scanloc.filename);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2118 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2119 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2120 goto Lerr;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2121
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2122 case '"':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2123 if (filespec)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2124 goto Lerr;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2125 stringbuffer.reset();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2126 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2127 while (1)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2128 { unsigned c;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2129
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2130 c = *p;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2131 switch (c)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2132 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2133 case '\n':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2134 case '\r':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2135 case 0:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2136 case 0x1A:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2137 goto Lerr;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2138
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2139 case '"':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2140 stringbuffer.writeByte(0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2141 filespec = mem.xstrdup((char *)stringbuffer.data);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2142 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2143 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2144
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2145 default:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2146 if (c & 0x80)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2147 { unsigned u = decodeUTF();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2148 if (u == PS || u == LS)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2149 goto Lerr;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2150 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2151 stringbuffer.writeByte(c);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2152 p++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2153 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2154 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2155 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2156 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2157 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2158
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2159 default:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2160 if (*p & 0x80)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2161 { unsigned u = decodeUTF();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2162 if (u == PS || u == LS)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2163 goto Lnewline;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2164 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2165 goto Lerr;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2166 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2167 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2168
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2169 Lerr:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2170 error(loc, "#line integer [\"filespec\"]\\n expected");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2171 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2172
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2173
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2174 /********************************************
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2175 * Decode UTF character.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2176 * Issue error messages for invalid sequences.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2177 * Return decoded character, advance p to last character in UTF sequence.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2178 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2179
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2180 unsigned Lexer::decodeUTF()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2181 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2182 dchar_t u;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2183 utf8_t c;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2184 const utf8_t *s = p;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2185 size_t len;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2186 size_t idx;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2187 const char *msg;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2188
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2189 c = *s;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2190 assert(c & 0x80);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2191
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2192 // Check length of remaining string up to 6 UTF-8 characters
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2193 for (len = 1; len < 6 && s[len]; len++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2194 ;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2195
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2196 idx = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2197 msg = utf_decodeChar(s, len, &idx, &u);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2198 p += idx - 1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2199 if (msg)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2200 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2201 error("%s", msg);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2202 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2203 return u;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2204 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2205
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2206
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2207 /***************************************************
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2208 * Parse doc comment embedded between t->ptr and p.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2209 * Remove trailing blanks and tabs from lines.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2210 * Replace all newlines with \n.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2211 * Remove leading comment character from each line.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2212 * Decide if it's a lineComment or a blockComment.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2213 * Append to previous one for this token.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2214 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2215
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2216 void Lexer::getDocComment(Token *t, unsigned lineComment)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2217 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2218 /* ct tells us which kind of comment it is: '/', '*', or '+'
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2219 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2220 utf8_t ct = t->ptr[2];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2221
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2222 /* Start of comment text skips over / * *, / + +, or / / /
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2223 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2224 const utf8_t *q = t->ptr + 3; // start of comment text
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2225
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2226 const utf8_t *qend = p;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2227 if (ct == '*' || ct == '+')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2228 qend -= 2;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2229
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2230 /* Scan over initial row of ****'s or ++++'s or ////'s
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2231 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2232 for (; q < qend; q++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2233 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2234 if (*q != ct)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2235 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2236 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2237
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2238 /* Remove leading spaces until start of the comment
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2239 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2240 int linestart = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2241 if (ct == '/')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2242 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2243 while (q < qend && (*q == ' ' || *q == '\t'))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2244 ++q;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2245 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2246 else if (q < qend)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2247 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2248 if (*q == '\r')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2249 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2250 ++q;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2251 if (q < qend && *q == '\n')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2252 ++q;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2253 linestart = 1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2254 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2255 else if (*q == '\n')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2256 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2257 ++q;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2258 linestart = 1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2259 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2260 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2261
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2262 /* Remove trailing row of ****'s or ++++'s
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2263 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2264 if (ct != '/')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2265 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2266 for (; q < qend; qend--)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2267 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2268 if (qend[-1] != ct)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2269 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2270 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2271 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2272
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2273 /* Comment is now [q .. qend].
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2274 * Canonicalize it into buf[].
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2275 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2276 OutBuffer buf;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2277
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2278 for (; q < qend; q++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2279 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2280 utf8_t c = *q;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2281
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2282 switch (c)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2283 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2284 case '*':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2285 case '+':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2286 if (linestart && c == ct)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2287 { linestart = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2288 /* Trim preceding whitespace up to preceding \n
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2289 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2290 while (buf.offset && (buf.data[buf.offset - 1] == ' ' || buf.data[buf.offset - 1] == '\t'))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2291 buf.offset--;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2292 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2293 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2294 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2295
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2296 case ' ':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2297 case '\t':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2298 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2299
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2300 case '\r':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2301 if (q[1] == '\n')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2302 continue; // skip the \r
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2303 goto Lnewline;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2304
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2305 default:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2306 if (c == 226)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2307 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2308 // If LS or PS
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2309 if (q[1] == 128 &&
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2310 (q[2] == 168 || q[2] == 169))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2311 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2312 q += 2;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2313 goto Lnewline;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2314 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2315 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2316 linestart = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2317 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2318
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2319 Lnewline:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2320 c = '\n'; // replace all newlines with \n
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2321 /* fall through */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2322 case '\n':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2323 linestart = 1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2324
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2325 /* Trim trailing whitespace
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2326 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2327 while (buf.offset && (buf.data[buf.offset - 1] == ' ' || buf.data[buf.offset - 1] == '\t'))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2328 buf.offset--;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2329
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2330 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2331 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2332 buf.writeByte(c);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2333 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2334
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2335 /* Trim trailing whitespace (if the last line does not have newline)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2336 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2337 if (buf.offset && (buf.data[buf.offset - 1] == ' ' || buf.data[buf.offset - 1] == '\t'))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2338 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2339 while (buf.offset && (buf.data[buf.offset - 1] == ' ' || buf.data[buf.offset - 1] == '\t'))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2340 buf.offset--;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2341 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2342
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2343 // Always end with a newline
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2344 if (!buf.offset || buf.data[buf.offset - 1] != '\n')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2345 buf.writeByte('\n');
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2346
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2347 buf.writeByte(0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2348
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2349 // It's a line comment if the start of the doc comment comes
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2350 // after other non-whitespace on the same line.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2351 const utf8_t** dc = (lineComment && anyToken)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2352 ? &t->lineComment
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2353 : &t->blockComment;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2354
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2355 // Combine with previous doc comment, if any
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2356 if (*dc)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2357 *dc = combineComments(*dc, (utf8_t *)buf.data);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2358 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2359 *dc = (utf8_t *)buf.extractData();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2360 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2361
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2362 /********************************************
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2363 * Combine two document comments into one,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2364 * separated by a newline.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2365 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2366
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2367 const utf8_t *Lexer::combineComments(const utf8_t *c1, const utf8_t *c2)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2368 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2369 //printf("Lexer::combineComments('%s', '%s')\n", c1, c2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2370
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2371 const utf8_t *c = c2;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2372
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2373 if (c1)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2374 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2375 c = c1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2376 if (c2)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2377 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2378 size_t len1 = strlen((const char *)c1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2379 size_t len2 = strlen((const char *)c2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2380
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2381 int insertNewLine = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2382 if (len1 && c1[len1 - 1] != '\n')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2383 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2384 ++len1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2385 insertNewLine = 1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2386 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2387
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2388 utf8_t *p = (utf8_t *)mem.xmalloc(len1 + 1 + len2 + 1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2389 memcpy(p, c1, len1 - insertNewLine);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2390 if (insertNewLine)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2391 p[len1 - 1] = '\n';
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2392
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2393 p[len1] = '\n';
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2394
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2395 memcpy(p + len1 + 1, c2, len2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2396 p[len1 + 1 + len2] = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2397 c = p;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2398 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2399 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2400 return c;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2401 }