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