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