Copyright updates for 2007.
[deliverable/binutils-gdb.git] / gdb / scm-exp.c
CommitLineData
c906108c 1/* Scheme/Guile language support routines for GDB, the GNU debugger.
69517000 2
6aba47ca
DJ
3 Copyright (C) 1995, 1996, 2000, 2003, 2005, 2007
4 Free Software Foundation, Inc.
c906108c 5
c5aa993b 6 This file is part of GDB.
c906108c 7
c5aa993b
JM
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
c906108c 12
c5aa993b
JM
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
c906108c 17
c5aa993b
JM
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
197e01b6
EZ
20 Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA. */
c906108c
SS
22
23#include "defs.h"
24#include "symtab.h"
25#include "gdbtypes.h"
26#include "expression.h"
27#include "parser-defs.h"
28#include "language.h"
29#include "value.h"
30#include "c-lang.h"
31#include "scm-lang.h"
32#include "scm-tags.h"
33
34#define USE_EXPRSTRING 0
35
a14ed312
KB
36static void scm_lreadparen (int);
37static int scm_skip_ws (void);
38static void scm_read_token (int, int);
39static LONGEST scm_istring2number (char *, int, int);
40static LONGEST scm_istr2int (char *, int, int);
41static void scm_lreadr (int);
c906108c
SS
42
43static LONGEST
fba45db2 44scm_istr2int (char *str, int len, int radix)
c906108c
SS
45{
46 int i = 0;
47 LONGEST inum = 0;
48 int c;
49 int sign = 0;
50
c5aa993b
JM
51 if (0 >= len)
52 return SCM_BOOL_F; /* zero scm_length */
c906108c 53 switch (str[0])
c5aa993b 54 { /* leading sign */
c906108c
SS
55 case '-':
56 case '+':
57 sign = str[0];
c5aa993b
JM
58 if (++i == len)
59 return SCM_BOOL_F; /* bad if lone `+' or `-' */
c906108c 60 }
c5aa993b
JM
61 do
62 {
63 switch (c = str[i++])
64 {
65 case '0':
66 case '1':
67 case '2':
68 case '3':
69 case '4':
70 case '5':
71 case '6':
72 case '7':
73 case '8':
74 case '9':
75 c = c - '0';
76 goto accumulate;
77 case 'A':
78 case 'B':
79 case 'C':
80 case 'D':
81 case 'E':
82 case 'F':
83 c = c - 'A' + 10;
84 goto accumulate;
85 case 'a':
86 case 'b':
87 case 'c':
88 case 'd':
89 case 'e':
90 case 'f':
91 c = c - 'a' + 10;
92 accumulate:
93 if (c >= radix)
94 return SCM_BOOL_F; /* bad digit for radix */
95 inum *= radix;
96 inum += c;
97 break;
98 default:
99 return SCM_BOOL_F; /* not a digit */
100 }
c906108c 101 }
c5aa993b 102 while (i < len);
c906108c
SS
103 if (sign == '-')
104 inum = -inum;
105 return SCM_MAKINUM (inum);
106}
107
108static LONGEST
fba45db2 109scm_istring2number (char *str, int len, int radix)
c906108c
SS
110{
111 int i = 0;
112 char ex = 0;
113 char ex_p = 0, rx_p = 0; /* Only allow 1 exactness and 1 radix prefix */
114#if 0
115 SCM res;
116#endif
c5aa993b
JM
117 if (len == 1)
118 if (*str == '+' || *str == '-') /* Catches lone `+' and `-' for speed */
c906108c
SS
119 return SCM_BOOL_F;
120
c5aa993b
JM
121 while ((len - i) >= 2 && str[i] == '#' && ++i)
122 switch (str[i++])
123 {
124 case 'b':
125 case 'B':
126 if (rx_p++)
127 return SCM_BOOL_F;
128 radix = 2;
129 break;
130 case 'o':
131 case 'O':
132 if (rx_p++)
133 return SCM_BOOL_F;
134 radix = 8;
135 break;
136 case 'd':
137 case 'D':
138 if (rx_p++)
139 return SCM_BOOL_F;
140 radix = 10;
141 break;
142 case 'x':
143 case 'X':
144 if (rx_p++)
145 return SCM_BOOL_F;
146 radix = 16;
147 break;
148 case 'i':
149 case 'I':
150 if (ex_p++)
151 return SCM_BOOL_F;
152 ex = 2;
153 break;
154 case 'e':
155 case 'E':
156 if (ex_p++)
157 return SCM_BOOL_F;
158 ex = 1;
159 break;
160 default:
161 return SCM_BOOL_F;
162 }
c906108c 163
c5aa993b
JM
164 switch (ex)
165 {
166 case 1:
167 return scm_istr2int (&str[i], len - i, radix);
168 case 0:
169 return scm_istr2int (&str[i], len - i, radix);
c906108c 170#if 0
c5aa993b
JM
171 if NFALSEP
172 (res) return res;
c906108c 173#ifdef FLOATS
c5aa993b
JM
174 case 2:
175 return scm_istr2flo (&str[i], len - i, radix);
c906108c
SS
176#endif
177#endif
c5aa993b 178 }
c906108c
SS
179 return SCM_BOOL_F;
180}
181
182static void
fba45db2 183scm_read_token (int c, int weird)
c906108c
SS
184{
185 while (1)
186 {
187 c = *lexptr++;
188 switch (c)
189 {
190 case '[':
191 case ']':
192 case '(':
193 case ')':
194 case '\"':
195 case ';':
c5aa993b
JM
196 case ' ':
197 case '\t':
198 case '\r':
199 case '\f':
c906108c
SS
200 case '\n':
201 if (weird)
202 goto default_case;
c5aa993b 203 case '\0': /* End of line */
c906108c
SS
204 eof_case:
205 --lexptr;
206 return;
207 case '\\':
208 if (!weird)
209 goto default_case;
210 else
211 {
212 c = *lexptr++;
213 if (c == '\0')
214 goto eof_case;
215 else
216 goto default_case;
217 }
218 case '}':
219 if (!weird)
220 goto default_case;
221
222 c = *lexptr++;
223 if (c == '#')
224 return;
225 else
226 {
227 --lexptr;
228 c = '}';
229 goto default_case;
230 }
231
232 default:
233 default_case:
234 ;
235 }
236 }
237}
238
c5aa993b 239static int
fba45db2 240scm_skip_ws (void)
c906108c 241{
52f0bd74 242 int c;
c906108c
SS
243 while (1)
244 switch ((c = *lexptr++))
245 {
246 case '\0':
247 goteof:
248 return c;
249 case ';':
250 lp:
251 switch ((c = *lexptr++))
252 {
253 case '\0':
254 goto goteof;
255 default:
256 goto lp;
257 case '\n':
258 break;
259 }
c5aa993b
JM
260 case ' ':
261 case '\t':
262 case '\r':
263 case '\f':
264 case '\n':
c906108c
SS
265 break;
266 default:
267 return c;
268 }
269}
270
271static void
fba45db2 272scm_lreadparen (int skipping)
c906108c
SS
273{
274 for (;;)
275 {
276 int c = scm_skip_ws ();
277 if (')' == c || ']' == c)
278 return;
279 --lexptr;
280 if (c == '\0')
281 error ("missing close paren");
282 scm_lreadr (skipping);
283 }
284}
285
286static void
fba45db2 287scm_lreadr (int skipping)
c906108c
SS
288{
289 int c, j;
290 struct stoken str;
291 LONGEST svalue = 0;
c5aa993b 292tryagain:
c906108c
SS
293 c = *lexptr++;
294 switch (c)
295 {
296 case '\0':
297 lexptr--;
298 return;
299 case '[':
300 case '(':
301 scm_lreadparen (skipping);
302 return;
303 case ']':
304 case ')':
305 error ("unexpected #\\%c", c);
306 goto tryagain;
307 case '\'':
308 case '`':
309 str.ptr = lexptr - 1;
310 scm_lreadr (skipping);
311 if (!skipping)
312 {
6943961c 313 struct value *val = scm_evaluate_string (str.ptr, lexptr - str.ptr);
df407dfe 314 if (!is_scmvalue_type (value_type (val)))
c906108c 315 error ("quoted scm form yields non-SCM value");
0fd88904 316 svalue = extract_signed_integer (value_contents (val),
df407dfe 317 TYPE_LENGTH (value_type (val)));
c906108c
SS
318 goto handle_immediate;
319 }
320 return;
321 case ',':
322 c = *lexptr++;
323 if ('@' != c)
324 lexptr--;
325 scm_lreadr (skipping);
326 return;
327 case '#':
328 c = *lexptr++;
329 switch (c)
330 {
331 case '[':
332 case '(':
333 scm_lreadparen (skipping);
334 return;
c5aa993b
JM
335 case 't':
336 case 'T':
c906108c
SS
337 svalue = SCM_BOOL_T;
338 goto handle_immediate;
c5aa993b
JM
339 case 'f':
340 case 'F':
c906108c
SS
341 svalue = SCM_BOOL_F;
342 goto handle_immediate;
c5aa993b
JM
343 case 'b':
344 case 'B':
345 case 'o':
346 case 'O':
347 case 'd':
348 case 'D':
349 case 'x':
350 case 'X':
351 case 'i':
352 case 'I':
353 case 'e':
354 case 'E':
c906108c
SS
355 lexptr--;
356 c = '#';
357 goto num;
c5aa993b 358 case '*': /* bitvector */
c906108c
SS
359 scm_read_token (c, 0);
360 return;
361 case '{':
362 scm_read_token (c, 1);
363 return;
c5aa993b 364 case '\\': /* character */
c906108c
SS
365 c = *lexptr++;
366 scm_read_token (c, 0);
367 return;
368 case '|':
369 j = 1; /* here j is the comment nesting depth */
370 lp:
371 c = *lexptr++;
372 lpc:
373 switch (c)
374 {
375 case '\0':
376 error ("unbalanced comment");
377 default:
378 goto lp;
379 case '|':
380 if ('#' != (c = *lexptr++))
381 goto lpc;
382 if (--j)
383 goto lp;
384 break;
385 case '#':
386 if ('|' != (c = *lexptr++))
387 goto lpc;
388 ++j;
389 goto lp;
390 }
391 goto tryagain;
392 case '.':
393 default:
394#if 0
395 callshrp:
396#endif
397 scm_lreadr (skipping);
398 return;
399 }
400 case '\"':
401 while ('\"' != (c = *lexptr++))
402 {
403 if (c == '\\')
404 switch (c = *lexptr++)
405 {
406 case '\0':
407 error ("non-terminated string literal");
408 case '\n':
409 continue;
410 case '0':
411 case 'f':
412 case 'n':
413 case 'r':
414 case 't':
415 case 'a':
416 case 'v':
417 break;
418 }
419 }
420 return;
c5aa993b
JM
421 case '0':
422 case '1':
423 case '2':
424 case '3':
425 case '4':
426 case '5':
427 case '6':
428 case '7':
429 case '8':
430 case '9':
c906108c
SS
431 case '.':
432 case '-':
433 case '+':
434 num:
435 {
c5aa993b 436 str.ptr = lexptr - 1;
c906108c
SS
437 scm_read_token (c, 0);
438 if (!skipping)
439 {
440 svalue = scm_istring2number (str.ptr, lexptr - str.ptr, 10);
441 if (svalue != SCM_BOOL_F)
442 goto handle_immediate;
443 goto tok;
444 }
445 }
446 return;
447 case ':':
448 scm_read_token ('-', 0);
449 return;
450#if 0
451 do_symbol:
452#endif
453 default:
c5aa993b 454 str.ptr = lexptr - 1;
c906108c
SS
455 scm_read_token (c, 0);
456 tok:
457 if (!skipping)
458 {
459 str.length = lexptr - str.ptr;
460 if (str.ptr[0] == '$')
461 {
462 write_dollar_variable (str);
463 return;
464 }
465 write_exp_elt_opcode (OP_NAME);
466 write_exp_string (str);
467 write_exp_elt_opcode (OP_NAME);
468 }
469 return;
470 }
c5aa993b 471handle_immediate:
c906108c
SS
472 if (!skipping)
473 {
474 write_exp_elt_opcode (OP_LONG);
475 write_exp_elt_type (builtin_type_scm);
476 write_exp_elt_longcst (svalue);
477 write_exp_elt_opcode (OP_LONG);
478 }
479}
480
481int
fba45db2 482scm_parse (void)
c906108c 483{
c5aa993b 484 char *start;
c906108c
SS
485 while (*lexptr == ' ')
486 lexptr++;
487 start = lexptr;
488 scm_lreadr (USE_EXPRSTRING);
489#if USE_EXPRSTRING
490 str.length = lexptr - start;
491 str.ptr = start;
492 write_exp_elt_opcode (OP_EXPRSTRING);
493 write_exp_string (str);
494 write_exp_elt_opcode (OP_EXPRSTRING);
495#endif
496 return 0;
497}
This page took 0.619172 seconds and 4 git commands to generate.