Clean up RCS ids
[projects/cmucl/cmucl.git] / src / lisp / parse.c
CommitLineData
eeab7066
RT
1/*
2
3 This code was written as part of the CMU Common Lisp project at
4 Carnegie Mellon University, and has been placed in the public domain.
5
6*/
7
62957726 8#include <stdio.h>
9#include <ctype.h>
10#include <signal.h>
0ac2c885 11#include <string.h>
824dfde0 12#include <strings.h>
0ac2c885 13#include <stdlib.h>
62957726 14
15#include "lisp.h"
16#include "internals.h"
17#include "globals.h"
18#include "vars.h"
19#include "parse.h"
3861a7bf 20#include "os.h"
62957726 21#include "interrupt.h"
22#include "lispregs.h"
23#include "monitor.h"
24#include "arch.h"
62957726 25#include "search.h"
26
2df7ff23 27/*
28 * What platforms DON'T have strcasecmp nowadays? Enable this if you
29 * don't have it.
30 */
31#if 0
62957726 32
9a8c1c2f 33static int
34strcasecmp(s1, s2)
35 char *s1, *s2;
62957726 36{
37 int c1, c2;
38
9a8c1c2f 39 do {
40 c1 = (*s1++);
41 if (isupper(c1))
42 c1 = tolower(c1);
62957726 43
9a8c1c2f 44 c2 = (*s2++);
45 if (isupper(c2))
46 c2 = tolower(c2);
47 } while (c1 == c2 && c1 != 0);
62957726 48
9a8c1c2f 49 return c1 - c2;
62957726 50}
51
52#endif
53
9a8c1c2f 54static void
55skip_ws(char **ptr)
62957726 56{
57 while (**ptr <= ' ' && **ptr != '\0')
9a8c1c2f 58 (*ptr)++;
62957726 59}
60
9a8c1c2f 61static boolean
62string_to_long(char *token, long *value)
62957726 63{
64 int base, digit;
65 long num;
66 char *ptr;
67
68 if (token == 0)
9a8c1c2f 69 return FALSE;
62957726 70
71 if (token[0] == '0')
9a8c1c2f 72 if (token[1] == 'x') {
73 base = 16;
74 token += 2;
75 } else {
76 base = 8;
77 token++;
78 } else if (token[0] == '#') {
79 switch (token[1]) {
80 case 'x':
81 case 'X':
82 base = 16;
83 token += 2;
84 break;
85 case 'o':
86 case 'O':
87 base = 8;
88 token += 2;
89 break;
90 default:
91 return FALSE;
92 }
93 } else
94 base = 10;
62957726 95
96 num = 0;
97 ptr = token;
98 while (*ptr != '\0') {
9a8c1c2f 99 if (*ptr >= 'a' && *ptr <= 'f')
100 digit = *ptr + 10 - 'a';
101 else if (*ptr >= 'A' && *ptr <= 'F')
102 digit = *ptr + 10 - 'A';
103 else if (*ptr >= '0' && *ptr <= '9')
104 digit = *ptr - '0';
105 else
106 return FALSE;
107 if (digit < 0 || digit >= base)
108 return FALSE;
109
110 ptr++;
111 num = num * base + digit;
62957726 112 }
113
114 *value = num;
115 return TRUE;
116}
117
9a8c1c2f 118static boolean
119lookup_variable(char *name, lispobj * result)
62957726 120{
121 struct var *var = lookup_by_name(name);
122
123 if (var == NULL)
9a8c1c2f 124 return FALSE;
62957726 125 else {
9a8c1c2f 126 *result = var_value(var);
127 return TRUE;
62957726 128 }
129}
130
131
9a8c1c2f 132boolean
b8d0dfaf 133more_p(char **ptr)
62957726 134{
135 skip_ws(ptr);
136
137 if (**ptr == '\0')
9a8c1c2f 138 return FALSE;
62957726 139 else
9a8c1c2f 140 return TRUE;
62957726 141}
142
9a8c1c2f 143char *
b8d0dfaf 144parse_token(char **ptr)
62957726 145{
146 char *token;
147
148 skip_ws(ptr);
9a8c1c2f 149
62957726 150 if (**ptr == '\0')
9a8c1c2f 151 return NULL;
62957726 152
153 token = *ptr;
154
155 while (**ptr > ' ')
9a8c1c2f 156 (*ptr)++;
62957726 157
158 if (**ptr != '\0') {
9a8c1c2f 159 **ptr = '\0';
160 (*ptr)++;
62957726 161 }
162
163 return token;
164}
165
166#if 0
9a8c1c2f 167static boolean
168number_p(token)
169 char *token;
62957726 170{
171 char *okay;
172
173 if (token == NULL)
9a8c1c2f 174 return FALSE;
62957726 175
176 okay = "abcdefABCDEF987654321d0";
177
178 if (token[0] == '0')
9a8c1c2f 179 if (token[1] == 'x' || token[1] == 'X')
180 token += 2;
181 else {
182 token++;
183 okay += 14;
184 } else if (token[0] == '#') {
185 switch (token[1]) {
186 case 'x':
187 case 'X':
188 break;
189 case 'o':
190 case 'O':
191 okay += 14;
192 break;
193 default:
194 return FALSE;
195 }
196 } else
197 okay += 12;
62957726 198
199 while (*token != '\0')
9a8c1c2f 200 if (index(okay, *token++) == NULL)
201 return FALSE;
62957726 202 return TRUE;
203}
204#endif
205
9a8c1c2f 206long
b8d0dfaf 207parse_number(char **ptr)
62957726 208{
209 char *token = parse_token(ptr);
210 long result;
211
212 if (token == NULL) {
9a8c1c2f 213 printf("Expected a number.\n");
214 throw_to_monitor();
215 } else if (string_to_long(token, &result))
216 return result;
62957726 217 else {
9a8c1c2f 218 printf("Invalid number: ``%s''\n", token);
219 throw_to_monitor();
62957726 220 }
221 return 0;
222}
223
9a8c1c2f 224char *
b8d0dfaf 225parse_addr(char **ptr)
62957726 226{
227 char *token = parse_token(ptr);
228 long result;
229
230 if (token == NULL) {
9a8c1c2f 231 printf("Expected an address.\n");
232 throw_to_monitor();
233 } else if (token[0] == '$') {
234 if (!lookup_variable(token + 1, (lispobj *) & result)) {
235 printf("Unknown variable: ``%s''\n", token);
236 throw_to_monitor();
237 }
238 result &= ~7;
239 } else {
240 if (!string_to_long(token, &result)) {
241 printf("Invalid number: ``%s''\n", token);
242 throw_to_monitor();
243 }
244 result &= ~3;
62957726 245 }
246
9a8c1c2f 247 if (!valid_addr((os_vm_address_t) result)) {
248 printf("Invalid address: 0x%lx\n", result);
249 throw_to_monitor();
62957726 250 }
251
9a8c1c2f 252 return (char *) result;
62957726 253}
254
9a8c1c2f 255static boolean
256lookup_symbol(char *name, lispobj * result)
62957726 257{
258 int count;
259 lispobj *headerptr;
260
261 /* Search static space */
262 headerptr = static_space;
9a8c1c2f 263 count = ((lispobj *) SymbolValue(STATIC_SPACE_FREE_POINTER) - static_space);
62957726 264 if (search_for_symbol(name, &headerptr, &count)) {
9a8c1c2f 265 *result = (lispobj) headerptr | type_OtherPointer;
266 return TRUE;
62957726 267 }
268
269 /* Search dynamic space */
270 headerptr = current_dynamic_space;
97c1178e 271#if !defined(ibmrt) && !defined(i386) && !defined(__x86_64)
62957726 272 count = current_dynamic_space_free_pointer - current_dynamic_space;
273#else
9a8c1c2f 274 count = (lispobj *) SymbolValue(ALLOCATION_POINTER) - current_dynamic_space;
62957726 275#endif
276 if (search_for_symbol(name, &headerptr, &count)) {
9a8c1c2f 277 *result = (lispobj) headerptr | type_OtherPointer;
278 return TRUE;
62957726 279 }
280
281 return FALSE;
282}
283
284static int
285parse_regnum(char *s)
286{
9a8c1c2f 287 if ((s[1] == 'R') || (s[1] == 'r')) {
288 int regnum;
289
290 if (s[2] == '\0')
291 return -1;
292
293 /* skip the $R part and call atoi on the number */
294 regnum = atoi(s + 2);
295 if ((regnum >= 0) && (regnum < NREGS))
296 return regnum;
297 else
298 return -1;
299 } else {
300 int i;
301
302 for (i = 0; i < NREGS; i++)
303 if (strcasecmp(s + 1, lisp_register_names[i]) == 0)
cfe94c2e 304#ifdef i386
9a8c1c2f 305 return i * 2;
cfe94c2e 306#else
9a8c1c2f 307 return i;
cfe94c2e 308#endif
9a8c1c2f 309
310 return -1;
311 }
62957726 312}
313
9a8c1c2f 314lispobj
b8d0dfaf 315parse_lispobj(char **ptr)
62957726 316{
317 char *token = parse_token(ptr);
318 long pointer;
319 lispobj result;
320
321 if (token == NULL) {
9a8c1c2f 322 printf("Expected an object.\n");
323 throw_to_monitor();
62957726 324 } else if (token[0] == '$') {
325 if (isalpha(token[1])) {
9a8c1c2f 326 int free;
327 int regnum;
328 os_context_t *context;
329
330 free = SymbolValue(FREE_INTERRUPT_CONTEXT_INDEX) >> 2;
331
332 if (free == 0) {
333 printf
334 ("Variable ``%s'' is not valid -- there is no current interrupt context.\n",
335 token);
336 throw_to_monitor();
337 }
338
339 context = lisp_interrupt_contexts[free - 1];
340
341 regnum = parse_regnum(token);
342 if (regnum < 0) {
343 printf("Bogus register: ``%s''\n", token);
344 throw_to_monitor();
345 }
346
347 result = SC_REG(context, regnum);
348 } else if (!lookup_variable(token + 1, &result)) {
349 printf("Unknown variable: ``%s''\n", token);
350 throw_to_monitor();
351 }
62957726 352 } else if (token[0] == '@') {
9a8c1c2f 353 if (string_to_long(token + 1, &pointer)) {
354 pointer &= ~3;
355 if (valid_addr((os_vm_address_t) pointer))
356 result = *(lispobj *) pointer;
357 else {
358 printf("Invalid address: ``%s''\n", token + 1);
359 throw_to_monitor();
360 }
361 } else {
362 printf("Invalid address: ``%s''\n", token + 1);
363 throw_to_monitor();
364 }
365 } else if (string_to_long(token, (long *) &result));
366 else if (lookup_symbol(token, &result));
62957726 367 else {
9a8c1c2f 368 printf("Invalid lisp object: ``%s''\n", token);
369 throw_to_monitor();
62957726 370 }
371
372 return result;
373}