Mercurial > hg > octave-avbm
comparison src/symtab.cc @ 530:c3268005bf98
[project @ 1994-07-20 19:26:33 by jwe]
author | jwe |
---|---|
date | Wed, 20 Jul 1994 19:26:33 +0000 |
parents | 89ed09321d16 |
children | 94fd73d1a0bc |
comparison
equal
deleted
inserted
replaced
529:7ea224e713cd | 530:c3268005bf98 |
---|---|
1 // Symbol table classes. -*- C++ -*- | 1 // symtab.cc -*- C++ -*- |
2 /* | 2 /* |
3 | 3 |
4 Copyright (C) 1992, 1993, 1994 John W. Eaton | 4 Copyright (C) 1992, 1993, 1994 John W. Eaton |
5 | 5 |
6 This file is part of Octave. | 6 This file is part of Octave. |
51 init_state (); | 51 init_state (); |
52 definition = t; | 52 definition = t; |
53 type = USER_VARIABLE; | 53 type = USER_VARIABLE; |
54 } | 54 } |
55 | 55 |
56 symbol_def::symbol_def (tree_builtin *t) | 56 symbol_def::symbol_def (tree_builtin *t, unsigned fcn_type) |
57 { | 57 { |
58 init_state (); | 58 init_state (); |
59 definition = t; | 59 definition = t; |
60 type = BUILTIN_FUNCTION; | 60 type = BUILTIN_FUNCTION | fcn_type; |
61 } | 61 } |
62 | 62 |
63 symbol_def::symbol_def (tree_function *t) | 63 symbol_def::symbol_def (tree_function *t, unsigned fcn_type) |
64 { | 64 { |
65 init_state (); | 65 init_state (); |
66 definition = t; | 66 definition = t; |
67 type = USER_FUNCTION; | 67 type = USER_FUNCTION | fcn_type; |
68 } | 68 } |
69 | 69 |
70 void | 70 void |
71 symbol_def::init_state (void) | 71 symbol_def::init_state (void) |
72 { | 72 { |
73 type = UNKNOWN; | 73 type = UNKNOWN; |
74 eternal = 0; | 74 eternal = 0; |
75 read_only = 0; | 75 read_only = 0; |
76 | 76 |
77 help_string = (char *) NULL; | 77 help_string = 0; |
78 definition = (tree_fvc *) NULL; | 78 definition = 0; |
79 next_elem = (symbol_def *) NULL; | 79 next_elem = 0; |
80 count = 0; | 80 count = 0; |
81 } | 81 } |
82 | 82 |
83 symbol_def::~symbol_def (void) | 83 symbol_def::~symbol_def (void) |
84 { | 84 { |
87 } | 87 } |
88 | 88 |
89 int | 89 int |
90 symbol_def::is_variable (void) const | 90 symbol_def::is_variable (void) const |
91 { | 91 { |
92 return (type == USER_VARIABLE || type == BUILTIN_VARIABLE); | 92 return (type & USER_VARIABLE || type & BUILTIN_VARIABLE); |
93 } | 93 } |
94 | 94 |
95 int | 95 int |
96 symbol_def::is_function (void) const | 96 symbol_def::is_function (void) const |
97 { | 97 { |
98 return (type == USER_FUNCTION || type == BUILTIN_FUNCTION); | 98 return (type & USER_FUNCTION || type & BUILTIN_FUNCTION); |
99 } | 99 } |
100 | 100 |
101 int | 101 int |
102 symbol_def::is_user_variable (void) const | 102 symbol_def::is_user_variable (void) const |
103 { | 103 { |
104 return (type == USER_VARIABLE); | 104 return (type & USER_VARIABLE); |
105 } | |
106 | |
107 int | |
108 symbol_def::is_text_function (void) const | |
109 { | |
110 return (type & TEXT_FUNCTION); | |
111 } | |
112 | |
113 int | |
114 symbol_def::is_mapper_function (void) const | |
115 { | |
116 return (type & MAPPER_FUNCTION); | |
105 } | 117 } |
106 | 118 |
107 int | 119 int |
108 symbol_def::is_user_function (void) const | 120 symbol_def::is_user_function (void) const |
109 { | 121 { |
110 return (type == USER_FUNCTION); | 122 return (type & USER_FUNCTION); |
111 } | 123 } |
112 | 124 |
113 int | 125 int |
114 symbol_def::is_builtin_variable (void) const | 126 symbol_def::is_builtin_variable (void) const |
115 { | 127 { |
116 return (type == BUILTIN_VARIABLE); | 128 return (type & BUILTIN_VARIABLE); |
117 } | 129 } |
118 | 130 |
119 int | 131 int |
120 symbol_def::is_builtin_function (void) const | 132 symbol_def::is_builtin_function (void) const |
121 { | 133 { |
122 return (type == BUILTIN_FUNCTION); | 134 return (type & BUILTIN_FUNCTION); |
123 } | 135 } |
124 | 136 |
125 void | 137 void |
126 symbol_def::define (tree_constant *t) | 138 symbol_def::define (tree_constant *t) |
127 { | 139 { |
129 if (! is_builtin_variable ()) | 141 if (! is_builtin_variable ()) |
130 type = USER_VARIABLE; | 142 type = USER_VARIABLE; |
131 } | 143 } |
132 | 144 |
133 void | 145 void |
134 symbol_def::define (tree_builtin *t) | 146 symbol_def::define (tree_builtin *t, unsigned fcn_type) |
135 { | 147 { |
136 definition = t; | 148 definition = t; |
137 type = BUILTIN_FUNCTION; | 149 type = BUILTIN_FUNCTION | fcn_type; |
138 } | 150 } |
139 | 151 |
140 void | 152 void |
141 symbol_def::define (tree_function *t) | 153 symbol_def::define (tree_function *t, unsigned fcn_type) |
142 { | 154 { |
143 definition = t; | 155 definition = t; |
144 type = USER_FUNCTION; | 156 type = USER_FUNCTION | fcn_type; |
145 } | 157 } |
146 | 158 |
147 void | 159 void |
148 symbol_def::protect (void) | 160 symbol_def::protect (void) |
149 { | 161 { |
190 | 202 |
191 int | 203 int |
192 maybe_delete (symbol_def *def) | 204 maybe_delete (symbol_def *def) |
193 { | 205 { |
194 int count = 0; | 206 int count = 0; |
195 if (def != (symbol_def *) NULL) | 207 if (def && def->count > 0) |
196 { | 208 { |
197 if (def->count > 0) | 209 def->count--; |
198 { | 210 count = def->count; |
199 def->count--; | 211 if (def->count == 0) |
200 count = def->count; | 212 delete def; |
201 if (def->count == 0) | |
202 delete def; | |
203 } | |
204 } | 213 } |
205 return count; | 214 return count; |
206 } | 215 } |
207 | 216 |
208 /* | 217 /* |
211 symbol_record::symbol_record (void) | 220 symbol_record::symbol_record (void) |
212 { | 221 { |
213 init_state (); | 222 init_state (); |
214 } | 223 } |
215 | 224 |
216 symbol_record::symbol_record (const char *n, | 225 symbol_record::symbol_record (const char *n, symbol_record *nxt) |
217 symbol_record *nxt = (symbol_record *) NULL) | |
218 { | 226 { |
219 init_state (); | 227 init_state (); |
220 nm = strsave (n); | 228 nm = strsave (n); |
221 next_elem = nxt; | 229 next_elem = nxt; |
222 } | 230 } |
224 void | 232 void |
225 symbol_record::init_state (void) | 233 symbol_record::init_state (void) |
226 { | 234 { |
227 formal_param = 0; | 235 formal_param = 0; |
228 linked_to_global = 0; | 236 linked_to_global = 0; |
229 nm = (char *) NULL; | 237 nm = 0; |
230 sv_fcn = (sv_Function) NULL; | 238 sv_fcn = 0; |
231 definition = (symbol_def *) NULL; | 239 definition = 0; |
232 next_elem = (symbol_record *) NULL; | 240 next_elem = 0; |
233 } | 241 } |
234 | 242 |
235 symbol_record::~symbol_record (void) | 243 symbol_record::~symbol_record (void) |
236 { | 244 { |
237 delete [] nm; | 245 delete [] nm; |
244 } | 252 } |
245 | 253 |
246 char * | 254 char * |
247 symbol_record::help (void) const | 255 symbol_record::help (void) const |
248 { | 256 { |
249 if (definition != (symbol_def *) NULL) | 257 return definition ? definition->help () : 0; |
250 return definition->help (); | |
251 else | |
252 return (char *) NULL; | |
253 } | 258 } |
254 | 259 |
255 void | 260 void |
256 symbol_record::rename (const char *n) | 261 symbol_record::rename (const char *n) |
257 { | 262 { |
260 } | 265 } |
261 | 266 |
262 tree_fvc * | 267 tree_fvc * |
263 symbol_record::def (void) const | 268 symbol_record::def (void) const |
264 { | 269 { |
265 if (definition != (symbol_def *) NULL) | 270 return definition ? definition->def () : 0; |
266 return definition->def (); | |
267 else | |
268 return (tree_fvc *) NULL; | |
269 } | 271 } |
270 | 272 |
271 int | 273 int |
272 symbol_record::is_function (void) const | 274 symbol_record::is_function (void) const |
273 { | 275 { |
274 if (definition != (symbol_def *) NULL) | 276 return definition ? definition->is_function () : 0; |
275 return definition->is_function (); | 277 } |
276 else | 278 |
277 return 0; | 279 int |
280 symbol_record::is_text_function (void) const | |
281 { | |
282 return definition ? definition->is_text_function () : 0; | |
283 } | |
284 | |
285 int | |
286 symbol_record::is_mapper_function (void) const | |
287 { | |
288 return definition ? definition->is_mapper_function () : 0; | |
278 } | 289 } |
279 | 290 |
280 int | 291 int |
281 symbol_record::is_user_function (void) const | 292 symbol_record::is_user_function (void) const |
282 { | 293 { |
283 if (definition != (symbol_def *) NULL) | 294 return definition ? definition->is_user_function () : 0; |
284 return definition->is_user_function (); | |
285 else | |
286 return 0; | |
287 } | 295 } |
288 | 296 |
289 int | 297 int |
290 symbol_record::is_builtin_function (void) const | 298 symbol_record::is_builtin_function (void) const |
291 { | 299 { |
292 if (definition != (symbol_def *) NULL) | 300 return definition ? definition->is_builtin_function () : 0; |
293 return definition->is_builtin_function (); | |
294 else | |
295 return 0; | |
296 } | 301 } |
297 | 302 |
298 int | 303 int |
299 symbol_record::is_variable (void) const | 304 symbol_record::is_variable (void) const |
300 { | 305 { |
301 if (definition != (symbol_def *) NULL) | 306 return definition ? definition->is_variable () : 0; |
302 return definition->is_variable (); | |
303 else | |
304 return 0; | |
305 } | 307 } |
306 | 308 |
307 int | 309 int |
308 symbol_record::is_user_variable (void) const | 310 symbol_record::is_user_variable (void) const |
309 { | 311 { |
310 if (definition != (symbol_def *) NULL) | 312 return definition ? definition->is_user_variable () : 0; |
311 return definition->is_user_variable (); | |
312 else | |
313 return 0; | |
314 } | 313 } |
315 | 314 |
316 int | 315 int |
317 symbol_record::is_builtin_variable (void) const | 316 symbol_record::is_builtin_variable (void) const |
318 { | 317 { |
319 if (definition != (symbol_def *) NULL) | 318 return definition ? definition->is_builtin_variable () : 0; |
320 return definition->is_builtin_variable (); | |
321 else | |
322 return 0; | |
323 } | 319 } |
324 | 320 |
325 unsigned | 321 unsigned |
326 symbol_record::type (void) const | 322 symbol_record::type (void) const |
327 { | 323 { |
328 if (definition != (symbol_def *) NULL) | 324 return definition ? definition->type : 0; |
329 return definition->type; | |
330 else | |
331 return 0; | |
332 } | 325 } |
333 | 326 |
334 int | 327 int |
335 symbol_record::is_defined (void) const | 328 symbol_record::is_defined (void) const |
336 { | 329 { |
337 if (definition != (symbol_def *) NULL) | 330 return definition ? (definition->def () != 0) : 0; |
338 return (definition->def () != NULL_TREE); | |
339 else | |
340 return 0; | |
341 } | 331 } |
342 | 332 |
343 int | 333 int |
344 symbol_record::is_read_only (void) const | 334 symbol_record::is_read_only (void) const |
345 { | 335 { |
346 if (definition != (symbol_def *) NULL) | 336 return definition ? definition->read_only : 0; |
347 return definition->read_only; | |
348 else | |
349 return 0; | |
350 } | 337 } |
351 | 338 |
352 int | 339 int |
353 symbol_record::is_eternal (void) const | 340 symbol_record::is_eternal (void) const |
354 { | 341 { |
355 if (definition != (symbol_def *) NULL) | 342 return definition ? definition->eternal : 0; |
356 return definition->eternal; | |
357 else | |
358 return 0; | |
359 } | 343 } |
360 | 344 |
361 void | 345 void |
362 symbol_record::protect (void) | 346 symbol_record::protect (void) |
363 { | 347 { |
364 if (definition != (symbol_def *) NULL) | 348 if (definition) |
365 { | 349 { |
366 definition->protect (); | 350 definition->protect (); |
367 | 351 |
368 if (! is_defined ()) | 352 if (! is_defined ()) |
369 warning ("protecting undefined variable `%s'", nm); | 353 warning ("protecting undefined variable `%s'", nm); |
371 } | 355 } |
372 | 356 |
373 void | 357 void |
374 symbol_record::unprotect (void) | 358 symbol_record::unprotect (void) |
375 { | 359 { |
376 if (definition != (symbol_def *) NULL) | 360 if (definition) |
377 definition->unprotect (); | 361 definition->unprotect (); |
378 } | 362 } |
379 | 363 |
380 void | 364 void |
381 symbol_record::make_eternal (void) | 365 symbol_record::make_eternal (void) |
382 { | 366 { |
383 if (definition != (symbol_def *) NULL) | 367 if (definition) |
384 { | 368 { |
385 definition->make_eternal (); | 369 definition->make_eternal (); |
386 | 370 |
387 if (! is_defined ()) | 371 if (! is_defined ()) |
388 warning ("giving eternal life to undefined variable `%s'", nm); | 372 warning ("giving eternal life to undefined variable `%s'", nm); |
399 symbol_record::define (tree_constant *t) | 383 symbol_record::define (tree_constant *t) |
400 { | 384 { |
401 if (is_variable () && read_only_error ()) | 385 if (is_variable () && read_only_error ()) |
402 return 0; | 386 return 0; |
403 | 387 |
404 tree_fvc *saved_def = (tree_fvc *) NULL; | 388 tree_fvc *saved_def = 0; |
405 if (definition == (symbol_def *) NULL) | 389 if (! definition) |
406 { | 390 { |
407 definition = new symbol_def (); | 391 definition = new symbol_def (); |
408 definition->count = 1; | 392 definition->count = 1; |
409 } | 393 } |
410 else if (is_function ()) | 394 else if (is_function ()) |
418 saved_def = definition->def (); | 402 saved_def = definition->def (); |
419 } | 403 } |
420 | 404 |
421 definition->define (t); | 405 definition->define (t); |
422 | 406 |
423 if (sv_fcn != (sv_Function) NULL && sv_fcn () < 0) | 407 if (sv_fcn && sv_fcn () < 0) |
424 { | 408 { |
425 // Would be nice to be able to avoid this cast. XXX FIXME XXX | 409 // Would be nice to be able to avoid this cast. XXX FIXME XXX |
426 definition->define ((tree_constant *) saved_def); | 410 definition->define ((tree_constant *) saved_def); |
427 delete t; | 411 delete t; |
428 return 0; | 412 return 0; |
432 | 416 |
433 return 1; | 417 return 1; |
434 } | 418 } |
435 | 419 |
436 int | 420 int |
437 symbol_record::define (tree_builtin *t) | 421 symbol_record::define (tree_builtin *t, int text_fcn) |
438 { | 422 { |
439 if (read_only_error ()) | 423 if (read_only_error ()) |
440 return 0; | 424 return 0; |
441 | 425 |
442 if (is_variable ()) | 426 if (is_variable ()) |
449 { | 433 { |
450 symbol_def *old_def = pop_def (); | 434 symbol_def *old_def = pop_def (); |
451 maybe_delete (old_def); | 435 maybe_delete (old_def); |
452 } | 436 } |
453 | 437 |
454 symbol_def *new_def = new symbol_def (t); | 438 unsigned fcn_type = text_fcn ? symbol_def::TEXT_FUNCTION |
439 : ((t && t->is_mapper_function ()) ? symbol_def::MAPPER_FUNCTION | |
440 : symbol_def::UNKNOWN); | |
441 | |
442 symbol_def *new_def = new symbol_def (t, fcn_type); | |
455 push_def (new_def); | 443 push_def (new_def); |
456 definition->count = 1; | 444 definition->count = 1; |
457 | 445 |
458 return 1; | 446 return 1; |
459 } | 447 } |
460 | 448 |
461 int | 449 int |
462 symbol_record::define (tree_function *t) | 450 symbol_record::define (tree_function *t, int text_fcn) |
463 { | 451 { |
464 if (read_only_error ()) | 452 if (read_only_error ()) |
465 return 0; | 453 return 0; |
466 | 454 |
467 if (is_variable ()) | 455 if (is_variable ()) |
474 { | 462 { |
475 symbol_def *old_def = pop_def (); | 463 symbol_def *old_def = pop_def (); |
476 maybe_delete (old_def); | 464 maybe_delete (old_def); |
477 } | 465 } |
478 | 466 |
479 symbol_def *new_def = new symbol_def (t); | 467 unsigned fcn_type = text_fcn ? symbol_def::TEXT_FUNCTION |
468 : symbol_def::UNKNOWN; | |
469 | |
470 symbol_def *new_def = new symbol_def (t, fcn_type); | |
480 push_def (new_def); | 471 push_def (new_def); |
481 definition->count = 1; | 472 definition->count = 1; |
482 | 473 |
483 return 1; | 474 return 1; |
484 } | 475 } |
513 symbol_record::define_builtin_var (tree_constant *t) | 504 symbol_record::define_builtin_var (tree_constant *t) |
514 { | 505 { |
515 define (t); | 506 define (t); |
516 if (is_variable ()) | 507 if (is_variable ()) |
517 definition->type = symbol_def::BUILTIN_VARIABLE; | 508 definition->type = symbol_def::BUILTIN_VARIABLE; |
509 return 1; | |
518 } | 510 } |
519 | 511 |
520 void | 512 void |
521 symbol_record::document (const char *h) | 513 symbol_record::document (const char *h) |
522 { | 514 { |
523 if (definition != (symbol_def *) NULL) | 515 if (definition) |
524 { | 516 { |
525 definition->document (h); | 517 definition->document (h); |
526 | 518 |
527 if (! is_defined ()) | 519 if (! is_defined ()) |
528 warning ("documenting undefined variable `%s'", nm); | 520 warning ("documenting undefined variable `%s'", nm); |
529 } | 521 } |
530 } | 522 } |
531 | 523 |
532 int | 524 int |
533 symbol_record::save (ostream& os, int mark_as_global = 0, | 525 symbol_record::save (ostream& os, int mark_as_global, int precision) |
534 int precision = 17) | |
535 { | 526 { |
536 int status = -1; | 527 int status = -1; |
537 | 528 |
538 // This is a kludge, but hey, it doesn't make sense to save them | 529 // This is a kludge, but hey, it doesn't make sense to save them |
539 // anyway, does it? Even if it did, we would just have trouble trying | 530 // anyway, does it? Even if it did, we would just have trouble trying |
559 { | 550 { |
560 int count = 0; | 551 int count = 0; |
561 if (linked_to_global) | 552 if (linked_to_global) |
562 { | 553 { |
563 count = maybe_delete (definition); | 554 count = maybe_delete (definition); |
564 definition = (symbol_def *) NULL; | 555 definition = 0; |
565 linked_to_global = 0; | 556 linked_to_global = 0; |
566 } | 557 } |
567 else | 558 else |
568 { | 559 { |
569 symbol_def *old_def = pop_def (); | 560 symbol_def *old_def = pop_def (); |
571 } | 562 } |
572 return count; | 563 return count; |
573 } | 564 } |
574 | 565 |
575 void | 566 void |
576 symbol_record::alias (symbol_record *s, int force = 0) | 567 symbol_record::alias (symbol_record *s, int force) |
577 { | 568 { |
578 sv_fcn = s->sv_fcn; | 569 sv_fcn = s->sv_fcn; |
579 | 570 |
580 if (force && s->definition == (symbol_def *) NULL) | 571 if (force && ! s->definition) |
581 { | 572 { |
582 s->definition = new symbol_def (); | 573 s->definition = new symbol_def (); |
583 definition = s->definition; | 574 definition = s->definition; |
584 definition->count = 2; // Yes, this is correct. | 575 definition->count = 2; // Yes, this is correct. |
585 } | 576 } |
586 else if (s->definition != (symbol_def *) NULL) | 577 else if (s->definition) |
587 { | 578 { |
588 definition = s->definition; | 579 definition = s->definition; |
589 definition->count++; | 580 definition->count++; |
590 } | 581 } |
591 } | 582 } |
628 | 619 |
629 void | 620 void |
630 symbol_record::push_context (void) | 621 symbol_record::push_context (void) |
631 { | 622 { |
632 context.push (definition); | 623 context.push (definition); |
633 definition = (symbol_def *) NULL; | 624 definition = 0; |
634 | 625 |
635 global_link_context.push ((unsigned) linked_to_global); | 626 global_link_context.push ((unsigned) linked_to_global); |
636 linked_to_global = 0; | 627 linked_to_global = 0; |
637 } | 628 } |
638 | 629 |
677 } | 668 } |
678 | 669 |
679 void | 670 void |
680 symbol_record::push_def (symbol_def *sd) | 671 symbol_record::push_def (symbol_def *sd) |
681 { | 672 { |
682 if (sd == (symbol_def *) NULL) | 673 if (! sd) |
683 return; | 674 return; |
684 | 675 |
685 sd->next_elem = definition; | 676 sd->next_elem = definition; |
686 definition = sd; | 677 definition = sd; |
687 } | 678 } |
688 | 679 |
689 symbol_def * | 680 symbol_def * |
690 symbol_record::pop_def (void) | 681 symbol_record::pop_def (void) |
691 { | 682 { |
692 symbol_def *top = definition; | 683 symbol_def *top = definition; |
693 if (definition != (symbol_def *) NULL) | 684 if (definition) |
694 definition = definition->next_elem; | 685 definition = definition->next_elem; |
695 return top; | 686 return top; |
696 } | 687 } |
697 | 688 |
698 /* | 689 /* |
741 nr = tmp->rows (); | 732 nr = tmp->rows (); |
742 nc = tmp->columns (); | 733 nc = tmp->columns (); |
743 | 734 |
744 symbol_def *sr_def = sr.definition; | 735 symbol_def *sr_def = sr.definition; |
745 symbol_def *hidden_def = sr_def->next_elem; | 736 symbol_def *hidden_def = sr_def->next_elem; |
746 if (hidden_def != (symbol_def *) NULL) | 737 if (hidden_def) |
747 { | 738 { |
748 if (hidden_def->is_user_function ()) | 739 if (hidden_def->is_user_function ()) |
749 hides = SR_INFO_USER_FUNCTION; | 740 hides = SR_INFO_USER_FUNCTION; |
750 else if (hidden_def->is_builtin_function ()) | 741 else if (hidden_def->is_builtin_function ()) |
751 hides = SR_INFO_BUILTIN_FUNCTION; | 742 hides = SR_INFO_BUILTIN_FUNCTION; |
887 hides = SR_INFO_NONE; | 878 hides = SR_INFO_NONE; |
888 eternal = 0; | 879 eternal = 0; |
889 read_only = 0; | 880 read_only = 0; |
890 nr = -1; | 881 nr = -1; |
891 nc = -1; | 882 nc = -1; |
892 nm = (char *) NULL; | 883 nm = 0; |
893 } | 884 } |
894 | 885 |
895 /* | 886 /* |
896 * A symbol table. | 887 * A symbol table. |
897 */ | 888 */ |
899 symbol_table::symbol_table (void) | 890 symbol_table::symbol_table (void) |
900 { | 891 { |
901 } | 892 } |
902 | 893 |
903 symbol_record * | 894 symbol_record * |
904 symbol_table::lookup (const char *nm, int insert = 0, int warn = 0) | 895 symbol_table::lookup (const char *nm, int insert, int warn) |
905 { | 896 { |
906 int index = hash (nm) & HASH_MASK; | 897 int index = hash (nm) & HASH_MASK; |
907 | 898 |
908 symbol_record *ptr = table[index].next (); | 899 symbol_record *ptr = table[index].next (); |
909 | 900 |
910 while (ptr != (symbol_record *) NULL) | 901 while (ptr) |
911 { | 902 { |
912 if (strcmp (ptr->name (), nm) == 0) | 903 if (strcmp (ptr->name (), nm) == 0) |
913 return ptr; | 904 return ptr; |
914 ptr = ptr->next (); | 905 ptr = ptr->next (); |
915 } | 906 } |
922 return new_sym; | 913 return new_sym; |
923 } | 914 } |
924 else if (warn) | 915 else if (warn) |
925 warning ("lookup: symbol`%s' not found", nm); | 916 warning ("lookup: symbol`%s' not found", nm); |
926 | 917 |
927 return (symbol_record *) NULL; | 918 return 0; |
928 } | 919 } |
929 | 920 |
930 void | 921 void |
931 symbol_table::clear (int clear_user_functions = 1) | 922 symbol_table::clear (int clear_user_functions) |
932 { | 923 { |
933 for (int i = 0; i < HASH_TABLE_SIZE; i++) | 924 for (int i = 0; i < HASH_TABLE_SIZE; i++) |
934 { | 925 { |
935 symbol_record *ptr = table[i].next (); | 926 symbol_record *ptr = table[i].next (); |
936 | 927 |
937 while (ptr != (symbol_record *) NULL) | 928 while (ptr) |
938 { | 929 { |
939 if (ptr->is_user_variable () | 930 if (ptr->is_user_variable () |
940 || (clear_user_functions && ptr->is_user_function ())) | 931 || (clear_user_functions && ptr->is_user_function ())) |
941 { | 932 { |
942 ptr->clear (); | 933 ptr->clear (); |
946 } | 937 } |
947 } | 938 } |
948 } | 939 } |
949 | 940 |
950 int | 941 int |
951 symbol_table::clear (const char *nm, int clear_user_functions = 1) | 942 symbol_table::clear (const char *nm, int clear_user_functions) |
952 { | 943 { |
953 int index = hash (nm) & HASH_MASK; | 944 int index = hash (nm) & HASH_MASK; |
954 | 945 |
955 symbol_record *ptr = table[index].next (); | 946 symbol_record *ptr = table[index].next (); |
956 | 947 |
957 while (ptr != (symbol_record *) NULL) | 948 while (ptr) |
958 { | 949 { |
959 if (strcmp (ptr->name (), nm) == 0 | 950 if (strcmp (ptr->name (), nm) == 0 |
960 && (ptr->is_user_variable () | 951 && (ptr->is_user_variable () |
961 || (clear_user_functions && ptr->is_user_function ()))) | 952 || (clear_user_functions && ptr->is_user_function ()))) |
962 { | 953 { |
968 | 959 |
969 return 0; | 960 return 0; |
970 } | 961 } |
971 | 962 |
972 int | 963 int |
973 symbol_table::save (ostream& os, int mark_as_global = 0, | 964 symbol_table::save (ostream& os, int mark_as_global, int precision) |
974 int precision = 17) | |
975 { | 965 { |
976 int status = 0; | 966 int status = 0; |
977 int count; | 967 int count; |
978 char **names = list (count, 1, symbol_def::USER_VARIABLE); | 968 char **names = list (count, 1, symbol_def::USER_VARIABLE); |
979 char **ptr = names; | 969 char **ptr = names; |
980 if (ptr != (char **) NULL) | 970 if (ptr) |
981 { | 971 { |
982 while (*ptr != (char *) NULL) | 972 while (*ptr) |
983 { | 973 { |
984 if (save (os, *ptr, mark_as_global, precision)) | 974 if (save (os, *ptr, mark_as_global, precision)) |
985 status++; | 975 status++; |
986 delete [] *ptr++; | 976 delete [] *ptr++; |
987 } | 977 } |
989 } | 979 } |
990 return status; | 980 return status; |
991 } | 981 } |
992 | 982 |
993 int | 983 int |
994 symbol_table::save (ostream& os, const char *name, | 984 symbol_table::save (ostream& os, const char *name, int mark_as_global, |
995 int mark_as_global = 0, int precision = 17) | 985 int precision) |
996 { | 986 { |
997 int status = 0; | 987 int status = 0; |
998 symbol_record *sr = lookup (name, 0, 0); | 988 symbol_record *sr = lookup (name, 0, 0); |
999 if (sr != (symbol_record *) NULL) | 989 if (sr) |
1000 status = sr->save (os, mark_as_global, precision); | 990 status = sr->save (os, mark_as_global, precision); |
1001 return status; | 991 return status; |
1002 } | 992 } |
1003 | 993 |
1004 int | 994 int |
1006 { | 996 { |
1007 int count = 0; | 997 int count = 0; |
1008 for (int i = 0; i < HASH_TABLE_SIZE; i++) | 998 for (int i = 0; i < HASH_TABLE_SIZE; i++) |
1009 { | 999 { |
1010 symbol_record *ptr = table[i].next (); | 1000 symbol_record *ptr = table[i].next (); |
1011 while (ptr != (symbol_record *) NULL) | 1001 while (ptr) |
1012 { | 1002 { |
1013 count++; | 1003 count++; |
1014 ptr = ptr->next (); | 1004 ptr = ptr->next (); |
1015 } | 1005 } |
1016 } | 1006 } |
1031 | 1021 |
1032 // This function should probably share code with symbol_table::list. | 1022 // This function should probably share code with symbol_table::list. |
1033 // XXX FIXME XXX | 1023 // XXX FIXME XXX |
1034 | 1024 |
1035 symbol_record_info * | 1025 symbol_record_info * |
1036 symbol_table::long_list (int& count, int sort = 0, | 1026 symbol_table::long_list (int& count, int sort, unsigned type, |
1037 unsigned type = SYMTAB_ALL_TYPES, | 1027 unsigned scope) const |
1038 unsigned scope = SYMTAB_ALL_SCOPES) const | |
1039 { | 1028 { |
1040 count = 0; | 1029 count = 0; |
1041 int n = size (); | 1030 int n = size (); |
1042 if (n == 0) | 1031 if (n == 0) |
1043 return (symbol_record_info *) NULL; | 1032 return 0; |
1044 | 1033 |
1045 symbol_record_info *symbols = new symbol_record_info [n+1]; | 1034 symbol_record_info *symbols = new symbol_record_info [n+1]; |
1046 for (int i = 0; i < HASH_TABLE_SIZE; i++) | 1035 for (int i = 0; i < HASH_TABLE_SIZE; i++) |
1047 { | 1036 { |
1048 symbol_record *ptr = table[i].next (); | 1037 symbol_record *ptr = table[i].next (); |
1049 while (ptr != (symbol_record *) NULL) | 1038 while (ptr) |
1050 { | 1039 { |
1051 assert (count < n); | 1040 assert (count < n); |
1052 unsigned my_scope = ptr->is_linked_to_global () + 1; // Tricky... | 1041 unsigned my_scope = ptr->is_linked_to_global () + 1; // Tricky... |
1053 unsigned my_type = ptr->type (); | 1042 unsigned my_type = ptr->type (); |
1054 if ((type & my_type) && (scope & my_scope)) | 1043 if ((type & my_type) && (scope & my_scope)) |
1058 ptr = ptr->next (); | 1047 ptr = ptr->next (); |
1059 } | 1048 } |
1060 } | 1049 } |
1061 symbols[count] = symbol_record_info (); | 1050 symbols[count] = symbol_record_info (); |
1062 | 1051 |
1063 if (sort && symbols != (symbol_record_info *) NULL) | 1052 if (sort && symbols) |
1064 qsort ((void *) symbols, count, sizeof (symbol_record_info), | 1053 qsort ((void *) symbols, count, sizeof (symbol_record_info), |
1065 (int (*)(void*, void*)) symbol_record_info_cmp); | 1054 (int (*)(const void*, const void*)) symbol_record_info_cmp); |
1066 | 1055 |
1067 return symbols; | 1056 return symbols; |
1068 } | 1057 } |
1069 | 1058 |
1070 char ** | 1059 char ** |
1071 symbol_table::list (int& count, int sort = 0, | 1060 symbol_table::list (int& count, int sort, unsigned type, |
1072 unsigned type = SYMTAB_ALL_TYPES, | 1061 unsigned scope) const |
1073 unsigned scope = SYMTAB_ALL_SCOPES) const | |
1074 { | 1062 { |
1075 count = 0; | 1063 count = 0; |
1076 int n = size (); | 1064 int n = size (); |
1077 if (n == 0) | 1065 if (n == 0) |
1078 return (char **) NULL; | 1066 return 0; |
1079 | 1067 |
1080 char **symbols = new char * [n+1]; | 1068 char **symbols = new char * [n+1]; |
1081 for (int i = 0; i < HASH_TABLE_SIZE; i++) | 1069 for (int i = 0; i < HASH_TABLE_SIZE; i++) |
1082 { | 1070 { |
1083 symbol_record *ptr = table[i].next (); | 1071 symbol_record *ptr = table[i].next (); |
1084 while (ptr != (symbol_record *) NULL) | 1072 while (ptr) |
1085 { | 1073 { |
1086 assert (count < n); | 1074 assert (count < n); |
1087 unsigned my_scope = ptr->is_linked_to_global () + 1; // Tricky... | 1075 unsigned my_scope = ptr->is_linked_to_global () + 1; // Tricky... |
1088 unsigned my_type = ptr->type (); | 1076 unsigned my_type = ptr->type (); |
1089 if ((type & my_type) && (scope & my_scope)) | 1077 if ((type & my_type) && (scope & my_scope)) |
1090 symbols[count++] = strsave (ptr->name ()); | 1078 symbols[count++] = strsave (ptr->name ()); |
1091 ptr = ptr->next (); | 1079 ptr = ptr->next (); |
1092 } | 1080 } |
1093 } | 1081 } |
1094 symbols[count] = (char *) NULL; | 1082 symbols[count] = 0; |
1095 | 1083 |
1096 if (sort && symbols != (char **) NULL) | 1084 if (sort && symbols) |
1097 qsort ((void **) symbols, count, sizeof (char *), | 1085 qsort ((void **) symbols, count, sizeof (char *), |
1098 (int (*)(void*, void*)) pstrcmp); | 1086 (int (*)(const void*, const void*)) pstrcmp); |
1099 | 1087 |
1100 return symbols; | 1088 return symbols; |
1101 } | 1089 } |
1102 | 1090 |
1103 void | 1091 void |
1105 { | 1093 { |
1106 for (int i = 0; i < HASH_TABLE_SIZE; i++) | 1094 for (int i = 0; i < HASH_TABLE_SIZE; i++) |
1107 { | 1095 { |
1108 symbol_record *ptr = table[i].next (); | 1096 symbol_record *ptr = table[i].next (); |
1109 | 1097 |
1110 while (ptr != (symbol_record *) NULL) | 1098 while (ptr) |
1111 { | 1099 { |
1112 ptr->push_context (); | 1100 ptr->push_context (); |
1113 ptr = ptr->next (); | 1101 ptr = ptr->next (); |
1114 } | 1102 } |
1115 } | 1103 } |
1120 { | 1108 { |
1121 for (int i = 0; i < HASH_TABLE_SIZE; i++) | 1109 for (int i = 0; i < HASH_TABLE_SIZE; i++) |
1122 { | 1110 { |
1123 symbol_record *ptr = table[i].next (); | 1111 symbol_record *ptr = table[i].next (); |
1124 | 1112 |
1125 while (ptr != (symbol_record *) NULL) | 1113 while (ptr) |
1126 { | 1114 { |
1127 ptr->pop_context (); | 1115 ptr->pop_context (); |
1128 ptr = ptr->next (); | 1116 ptr = ptr->next (); |
1129 } | 1117 } |
1130 } | 1118 } |