*** empty log message ***
[bpt/guile.git] / libguile / debug.c
CommitLineData
63c51b9a 1 /* Debugging extensions for Guile
78a0461a 2 * Copyright (C) 1995, 1996, 1997, 1998, 1999 Free Software Foundation
ee340120
MD
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2, or (at your option)
7 * any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this software; see the file COPYING. If not, write to
82892bed
JB
16 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
17 * Boston, MA 02111-1307 USA
ee340120
MD
18 *
19 * As a special exception, the Free Software Foundation gives permission
20 * for additional uses of the text contained in its release of GUILE.
21 *
22 * The exception is that, if you link the GUILE library with other files
23 * to produce an executable, this does not by itself cause the
24 * resulting executable to be covered by the GNU General Public License.
25 * Your use of that executable is in no way restricted on account of
26 * linking the GUILE library code into it.
27 *
28 * This exception does not however invalidate any other reasons why
29 * the executable file might be covered by the GNU General Public License.
30 *
31 * This exception applies only to the code released by the
32 * Free Software Foundation under the name GUILE. If you copy
33 * code from other Free Software Foundation releases into a copy of
34 * GUILE, as the General Public License permits, the exception does
35 * not apply to the code that you add in this way. To avoid misleading
36 * anyone as to the status of such modified files, you must delete
37 * this exception notice from them.
38 *
39 * If you write modifications of your own for GUILE, it is your choice
40 * whether to permit this exception to apply to your modifications.
41 * If you do not wish that, delete this exception notice.
42 *
43 * The author can be reached at djurfeldt@nada.kth.se
82892bed 44 * Mikael Djurfeldt, SANS/NADA KTH, 10044 STOCKHOLM, SWEDEN */
f0e9217a
MD
45
46#include <stdio.h>
47#include "_scm.h"
20e6290e 48#include "eval.h"
a6e350dd 49#include "stackchk.h"
20e6290e
JB
50#include "throw.h"
51#include "genio.h"
41d3b325 52#include "macros.h"
20e6290e
JB
53#include "smob.h"
54#include "procprop.h"
55#include "srcprop.h"
56#include "alist.h"
57#include "continuations.h"
58#include "strports.h"
59#include "read.h"
60#include "feature.h"
260b1416 61#include "dynwind.h"
650de6d7 62#include "modules.h"
f0e9217a 63
20e6290e 64#include "debug.h"
f0e9217a
MD
65\f
66
67/* {Run time control of the debugging evaluator}
68 */
69
5e8d7fd4 70SCM_PROC (s_debug_options, "debug-options-interface", 0, 1, 0, scm_debug_options);
1cc91f1b 71
f0e9217a 72SCM
5e8d7fd4
MD
73scm_debug_options (setting)
74 SCM setting;
f0e9217a
MD
75{
76 SCM ans;
77 SCM_DEFER_INTS;
5e8d7fd4
MD
78 ans = scm_options (setting,
79 scm_debug_opts,
80 SCM_N_DEBUG_OPTIONS,
81 s_debug_options);
f0e9217a 82#ifndef SCM_RECKLESS
5e8d7fd4 83 if (!(1 <= SCM_N_FRAMES && SCM_N_FRAMES <= SCM_MAX_FRAME_SIZE))
f0e9217a 84 {
5e8d7fd4 85 scm_options (ans, scm_debug_opts, SCM_N_DEBUG_OPTIONS, s_debug_options);
52859adf 86 scm_out_of_range (s_debug_options, setting);
f0e9217a
MD
87 }
88#endif
5e8d7fd4 89 SCM_RESET_DEBUG_MODE;
a6e350dd 90 scm_stack_checking_enabled_p = SCM_STACK_CHECKING_P;
5e8d7fd4 91 scm_debug_eframe_size = 2 * SCM_N_FRAMES;
bfc69694 92 SCM_ALLOW_INTS;
f0e9217a
MD
93 return ans;
94}
95
260b1416
MD
96SCM_PROC (s_with_traps, "with-traps", 1, 0, 0, scm_with_traps);
97
98static void
99with_traps_before (void *data)
100{
101 int *trap_flag = data;
102 *trap_flag = SCM_TRAPS_P;
103 SCM_TRAPS_P = 1;
104}
105
106static void
107with_traps_after (void *data)
108{
109 int *trap_flag = data;
110 SCM_TRAPS_P = *trap_flag;
111}
112
113static SCM
114with_traps_inner (void *data)
115{
116 SCM thunk = (SCM) data;
117 return scm_apply (thunk, SCM_EOL, SCM_EOL);
118}
1cc91f1b 119
f0e9217a 120SCM
260b1416 121scm_with_traps (SCM thunk)
f0e9217a 122{
260b1416
MD
123 int trap_flag;
124 SCM_ASSERT (SCM_NFALSEP (scm_thunk_p (thunk)),
125 thunk,
126 SCM_ARG1,
127 s_with_traps);
128 return scm_internal_dynamic_wind (with_traps_before,
129 with_traps_inner,
130 with_traps_after,
131 (void *) thunk,
132 &trap_flag);
f0e9217a
MD
133}
134
135\f
63c51b9a
MD
136static SCM scm_sym_source, scm_sym_dots;
137static SCM scm_sym_procname;
f0e9217a
MD
138
139/* {Memoized Source}
140 */
141
142long scm_tc16_memoized;
143
1cc91f1b
JB
144
145static int prinmemoized SCM_P ((SCM obj, SCM port, scm_print_state *pstate));
146
f0e9217a 147static int
9882ea19 148prinmemoized (obj, port, pstate)
f0e9217a
MD
149 SCM obj;
150 SCM port;
9882ea19 151 scm_print_state *pstate;
f0e9217a 152{
9882ea19 153 int writingp = SCM_WRITINGP (pstate);
b7f3516f 154 scm_puts ("#<memoized ", port);
9882ea19 155 SCM_SET_WRITINGP (pstate, 1);
33b97402
MD
156#ifdef GUILE_DEBUG
157 scm_iprin1 (SCM_MEMOIZED_EXP (obj), port, pstate);
158#else
9882ea19 159 scm_iprin1 (scm_unmemoize (obj), port, pstate);
33b97402 160#endif
9882ea19 161 SCM_SET_WRITINGP (pstate, writingp);
b7f3516f 162 scm_putc ('>', port);
f0e9217a
MD
163 return 1;
164}
165
f0e9217a 166SCM_PROC (s_memoized_p, "memoized?", 1, 0, 0, scm_memoized_p);
1cc91f1b 167
f0e9217a
MD
168SCM
169scm_memoized_p (obj)
170 SCM obj;
f0e9217a
MD
171{
172 return SCM_NIMP (obj) && SCM_MEMOIZEDP (obj) ? SCM_BOOL_T : SCM_BOOL_F;
173}
174
f0e9217a 175SCM
bba4bfdb 176scm_make_memoized (exp, env)
1cc91f1b
JB
177 SCM exp;
178 SCM env;
f0e9217a 179{
6c179711 180 /* *fixme* Check that env is a valid environment. */
f0e9217a 181 register SCM z, ans;
f83e2737 182 SCM_ENTER_A_SECTION;
23a62151
MD
183 SCM_NEWSMOB (z, exp, env);
184 SCM_NEWSMOB (ans, scm_tc16_memoized, z);
f83e2737 185 SCM_EXIT_A_SECTION;
f0e9217a
MD
186 return ans;
187}
188
33b97402
MD
189#ifdef GUILE_DEBUG
190/*
191 * Some primitives for construction of memoized code
192 *
193 * - procedure: memcons CAR CDR [ENV]
194 *
195 * Construct a pair, encapsulated in a memoized object.
196 *
197 * The CAR and CDR can be either normal or memoized. If ENV isn't
198 * specified, the top-level environment of the current module will
199 * be assumed. All environments must match.
200 *
201 * - procedure: make-gloc VARIABLE [ENV]
202 *
203 * Return a gloc, encapsulated in a memoized object.
204 *
205 * (Glocs can't exist in normal list structures, since they will
206 * be mistaken for structs.)
207 *
208 * - procedure: gloc? OBJECT
209 *
210 * Return #t if OBJECT is a memoized gloc.
211 *
212 * - procedure: make-iloc FRAME BINDING CDRP
213 *
214 * Return an iloc referring to frame no. FRAME, binding
215 * no. BINDING. If CDRP is non-#f, the iloc is referring to a
216 * frame consisting of a single pair, with the value stored in the
217 * CDR.
218 *
219 * - procedure: iloc? OBJECT
220 *
221 * Return #t if OBJECT is an iloc.
222 *
223 * - procedure: mem->proc MEMOIZED
224 *
225 * Construct a closure from the memoized lambda expression MEMOIZED
226 *
227 * WARNING! The code is not copied!
228 *
229 * - procedure: proc->mem CLOSURE
230 *
231 * Turn the closure CLOSURE into a memoized object.
232 *
233 * WARNING! The code is not copied!
234 *
235 * - constant: SCM_IM_AND
236 * - constant: SCM_IM_BEGIN
237 * - constant: SCM_IM_CASE
238 * - constant: SCM_IM_COND
239 * - constant: SCM_IM_DO
240 * - constant: SCM_IM_IF
241 * - constant: SCM_IM_LAMBDA
242 * - constant: SCM_IM_LET
243 * - constant: SCM_IM_LETSTAR
244 * - constant: SCM_IM_LETREC
245 * - constant: SCM_IM_OR
246 * - constant: SCM_IM_QUOTE
247 * - constant: SCM_IM_SET
248 * - constant: SCM_IM_DEFINE
249 * - constant: SCM_IM_APPLY
250 * - constant: SCM_IM_CONT
bbab09f6 251 * - constant: SCM_IM_DISPATCH
33b97402
MD
252 */
253
254#include "variable.h"
255#include "procs.h"
256
257SCM_PROC (s_make_gloc, "make-gloc", 1, 1, 0, scm_make_gloc);
258
259SCM
260scm_make_gloc (var, env)
261 SCM var;
262 SCM env;
263{
264#if 1 /* Unsafe */
265 if (SCM_NIMP (var) && SCM_CONSP (var))
266 var = scm_cons (SCM_BOOL_F, var);
267 else
268#endif
269 SCM_ASSERT (SCM_NIMP (var) && SCM_VARIABLEP (var),
270 var,
271 SCM_ARG1,
272 s_make_gloc);
273 if (SCM_UNBNDP (env))
274 env = scm_top_level_env (SCM_CDR (scm_top_level_lookup_closure_var));
275 else
276 SCM_ASSERT (SCM_NULLP (env) || (SCM_NIMP (env) && SCM_CONSP (env)),
277 env,
278 SCM_ARG2,
279 s_make_gloc);
280 return scm_make_memoized (SCM_VARVCELL (var) + 1, env);
281}
282
283SCM_PROC (s_gloc_p, "gloc?", 1, 0, 0, scm_gloc_p);
284
285SCM
286scm_gloc_p (obj)
287 SCM obj;
288{
289 return ((SCM_NIMP (obj)
290 && SCM_MEMOIZEDP (obj)
291 && (SCM_MEMOIZED_EXP (obj) & 7) == 1)
292 ? SCM_BOOL_T
293 : SCM_BOOL_F);
294}
295
296SCM_PROC (s_make_iloc, "make-iloc", 3, 0, 0, scm_make_iloc);
297
298SCM
299scm_make_iloc (frame, binding, cdrp)
300 SCM frame;
301 SCM binding;
302 SCM cdrp;
303{
304 SCM_ASSERT (SCM_INUMP (frame), frame, SCM_ARG1, s_make_iloc);
305 SCM_ASSERT (SCM_INUMP (binding), binding, SCM_ARG2, s_make_iloc);
306 return (SCM_ILOC00
307 + SCM_IFRINC * SCM_INUM (frame)
308 + (SCM_NFALSEP (cdrp) ? SCM_ICDR : 0)
309 + SCM_IDINC * SCM_INUM (binding));
310}
311
312SCM_PROC (s_iloc_p, "iloc?", 1, 0, 0, scm_iloc_p);
313
314SCM
315scm_iloc_p (obj)
316 SCM obj;
317{
318 return SCM_ILOCP (obj) ? SCM_BOOL_T : SCM_BOOL_F;
319}
320
321SCM_PROC (s_memcons, "memcons", 2, 1, 0, scm_memcons);
322
323SCM
324scm_memcons (car, cdr, env)
325 SCM car;
326 SCM cdr;
327 SCM env;
328{
329 if (SCM_NIMP (car) && SCM_MEMOIZEDP (car))
330 {
331 /*fixme* environments may be two different but equal top-level envs */
332 if (!SCM_UNBNDP (env) && SCM_MEMOIZED_ENV (car) != env)
333 scm_misc_error (s_memcons,
334 "environment mismatch arg1 <-> arg3",
335 scm_cons2 (car, env, SCM_EOL));
336 else
337 env = SCM_MEMOIZED_ENV (car);
338 car = SCM_MEMOIZED_EXP (car);
339 }
340 if (SCM_NIMP (cdr) && SCM_MEMOIZEDP (cdr))
341 {
342 if (!SCM_UNBNDP (env) && SCM_MEMOIZED_ENV (cdr) != env)
343 scm_misc_error (s_memcons,
344 "environment mismatch arg2 <-> arg3",
345 scm_cons2 (cdr, env, SCM_EOL));
346 else
347 env = SCM_MEMOIZED_ENV (cdr);
348 cdr = SCM_MEMOIZED_EXP (cdr);
349 }
350 if (SCM_UNBNDP (env))
351 env = scm_top_level_env (SCM_CDR (scm_top_level_lookup_closure_var));
352 else
353 SCM_ASSERT (SCM_NULLP (env) || (SCM_NIMP (env) && SCM_CONSP (env)),
354 env,
355 SCM_ARG3,
356 s_make_iloc);
357 return scm_make_memoized (scm_cons (car, cdr), env);
358}
359
360SCM_PROC (s_mem_to_proc, "mem->proc", 1, 0, 0, scm_mem_to_proc);
361
362SCM
363scm_mem_to_proc (obj)
364 SCM obj;
365{
366 SCM env;
367 SCM_ASSERT (SCM_NIMP (obj) && SCM_MEMOIZEDP (obj),
368 obj,
369 SCM_ARG1,
370 s_mem_to_proc);
371 env = SCM_MEMOIZED_ENV (obj);
372 obj = SCM_MEMOIZED_EXP (obj);
373 if (!(SCM_NIMP (obj) && SCM_CAR (obj) == SCM_IM_LAMBDA))
374 scm_misc_error (s_mem_to_proc,
375 "expected lambda expression",
376 scm_cons (obj, SCM_EOL));
377 return scm_closure (SCM_CDR (obj), env);
378}
379
380SCM_PROC (s_proc_to_mem, "proc->mem", 1, 0, 0, scm_proc_to_mem);
381
382SCM
383scm_proc_to_mem (obj)
384 SCM obj;
385{
386 SCM_ASSERT (SCM_NIMP (obj) && SCM_CLOSUREP (obj),
387 obj,
388 SCM_ARG1,
389 s_proc_to_mem);
390 return scm_make_memoized (scm_cons (SCM_IM_LAMBDA, SCM_CODE (obj)),
391 SCM_ENV (obj));
392}
393
394#endif /* GUILE_DEBUG */
395
f0e9217a 396SCM_PROC (s_unmemoize, "unmemoize", 1, 0, 0, scm_unmemoize);
1cc91f1b 397
f0e9217a
MD
398SCM
399scm_unmemoize (m)
400 SCM m;
f0e9217a 401{
6c179711 402 SCM_ASSERT (SCM_NIMP (m) && SCM_MEMOIZEDP (m), m, SCM_ARG1, s_unmemoize);
bfe3154c 403 return scm_unmemocopy (SCM_MEMOIZED_EXP (m), SCM_MEMOIZED_ENV (m));
f0e9217a
MD
404}
405
406SCM_PROC (s_memoized_environment, "memoized-environment", 1, 0, 0, scm_memoized_environment);
1cc91f1b 407
f0e9217a
MD
408SCM
409scm_memoized_environment (m)
410 SCM m;
f0e9217a 411{
6c179711 412 SCM_ASSERT (SCM_NIMP (m) && SCM_MEMOIZEDP (m), m, SCM_ARG1, s_unmemoize);
bfe3154c 413 return SCM_MEMOIZED_ENV (m);
f0e9217a
MD
414}
415
416SCM_PROC (s_procedure_name, "procedure-name", 1, 0, 0, scm_procedure_name);
1cc91f1b 417
f0e9217a
MD
418SCM
419scm_procedure_name (proc)
420 SCM proc;
f0e9217a
MD
421{
422 SCM_ASSERT(scm_procedure_p (proc) == SCM_BOOL_T,
423 proc,
424 SCM_ARG1,
425 s_procedure_name);
426 switch (SCM_TYP7 (proc)) {
a726dd9d
MD
427 case scm_tcs_subrs:
428 return SCM_SNAME (proc);
429 default:
f0e9217a 430 {
63c51b9a 431 SCM name = scm_procedure_property (proc, scm_sym_name);
f0e9217a 432#if 0
63c51b9a
MD
433 /* Source property scm_sym_procname not implemented yet... */
434 SCM name = scm_source_property (SCM_CAR (SCM_CDR (SCM_CODE (proc))), scm_sym_procname);
f0e9217a 435 if (SCM_FALSEP (name))
63c51b9a 436 name = scm_procedure_property (proc, scm_sym_name);
f0e9217a 437#endif
c75512d6
MD
438 if (SCM_FALSEP (name) && SCM_CLOSUREP (proc))
439 name = scm_reverse_lookup (SCM_ENV (proc), proc);
f0e9217a
MD
440 return name;
441 }
f0e9217a
MD
442 }
443}
444
445SCM_PROC (s_procedure_source, "procedure-source", 1, 0, 0, scm_procedure_source);
1cc91f1b 446
f0e9217a
MD
447SCM
448scm_procedure_source (proc)
449 SCM proc;
f0e9217a
MD
450{
451 SCM_ASSERT(SCM_NIMP (proc), proc, SCM_ARG1, s_procedure_source);
452 switch (SCM_TYP7 (proc)) {
453 case scm_tcs_closures:
454 {
455 SCM src;
63c51b9a 456 src = scm_source_property (SCM_CDR (SCM_CODE (proc)), scm_sym_copy);
f0e9217a 457 if (src != SCM_BOOL_F)
63c51b9a 458 return scm_cons2 (scm_sym_lambda, SCM_CAR (SCM_CODE (proc)), src);
f0e9217a 459 src = SCM_CODE (proc);
63c51b9a 460 return scm_cons (scm_sym_lambda,
f0e9217a 461 scm_unmemocopy (src,
e2806c10 462 SCM_EXTEND_ENV (SCM_CAR (src),
f0e9217a
MD
463 SCM_EOL,
464 SCM_ENV (proc))));
465 }
466 case scm_tc7_contin:
467 case scm_tcs_subrs:
468#ifdef CCLO
469 case scm_tc7_cclo:
470#endif
471 /* It would indeed be a nice thing if we supplied source even for
472 built in procedures! */
63c51b9a 473 return scm_procedure_property (proc, scm_sym_source);
f0e9217a
MD
474 default:
475 scm_wta (proc, (char *) SCM_ARG1, s_procedure_source);
476 return 0;
477 }
478}
479
480SCM_PROC (s_procedure_environment, "procedure-environment", 1, 0, 0, scm_procedure_environment);
1cc91f1b 481
f0e9217a
MD
482SCM
483scm_procedure_environment (proc)
484 SCM proc;
f0e9217a
MD
485{
486 SCM_ASSERT (SCM_NIMP (proc), proc, SCM_ARG1, s_procedure_environment);
487 switch (SCM_TYP7 (proc)) {
488 case scm_tcs_closures:
489 return SCM_ENV (proc);
490 case scm_tc7_contin:
491 case scm_tcs_subrs:
492#ifdef CCLO
493 case scm_tc7_cclo:
494#endif
495 return SCM_EOL;
496 default:
497 scm_wta (proc, (char *) SCM_ARG1, s_procedure_environment);
498 return 0;
499 }
500}
501
bfe3154c 502\f
f0e9217a
MD
503
504/* Eval in a local environment. We would like to have the ability to
e38ecb05
MD
505 * evaluate in a specified local environment, but due to the
506 * memoization this isn't normally possible. We solve it by copying
507 * the code before evaluating. One solution would be to have eval.c
508 * generate yet another evaluator. They are not very big actually.
f0e9217a 509 */
6c179711 510SCM_PROC (s_local_eval, "local-eval", 1, 1, 0, scm_local_eval);
1cc91f1b 511
f0e9217a
MD
512SCM
513scm_local_eval (exp, env)
514 SCM exp;
515 SCM env;
f0e9217a 516{
6c179711
MD
517 if (SCM_UNBNDP (env))
518 {
b210cb73 519 SCM_ASSERT (SCM_NIMP (exp) && SCM_MEMOIZEDP (exp), exp, SCM_ARG1, s_local_eval);
6c179711
MD
520 return scm_eval_3 (SCM_MEMOIZED_EXP (exp), 0, SCM_MEMOIZED_ENV (exp));
521 }
f0e9217a
MD
522 return scm_eval_3 (exp, 1, env);
523}
524
c75512d6
MD
525#if 0
526SCM_PROC (s_reverse_lookup, "reverse-lookup", 2, 0, 0, scm_reverse_lookup);
527#endif
528
529SCM
530scm_reverse_lookup (SCM env, SCM data)
531{
532 SCM names, values;
533 while (SCM_NIMP (env) && SCM_CONSP (SCM_CAR (env)))
534 {
535 names = SCM_CAAR (env);
536 values = SCM_CDAR (env);
537 while (SCM_NIMP (names) && SCM_CONSP (names))
538 {
539 if (SCM_CAR (values) == data)
540 return SCM_CAR (names);
541 names = SCM_CDR (names);
542 values = SCM_CDR (values);
543 }
544 if (names != SCM_EOL && values == data)
545 return names;
546 env = SCM_CDR (env);
547 }
548 return SCM_BOOL_F;
549}
550
bfe3154c 551SCM
9fa2c7b1
MD
552scm_start_stack (id, exp, env)
553 SCM id;
bfe3154c
MD
554 SCM exp;
555 SCM env;
556{
557 SCM answer;
c6b8a41a 558 scm_debug_frame vframe;
c0ab1b8d 559 scm_debug_info vframe_vect_body;
9fa2c7b1
MD
560 vframe.prev = scm_last_debug_frame;
561 vframe.status = SCM_VOIDFRAME;
562 vframe.vect = &vframe_vect_body;
563 vframe.vect[0].id = id;
564 scm_last_debug_frame = &vframe;
cb412265 565 answer = scm_eval_3 (exp, 1, env);
9fa2c7b1
MD
566 scm_last_debug_frame = vframe.prev;
567 return answer;
568}
569
b8229a3b
MS
570SCM_SYNTAX(s_start_stack, "start-stack", scm_makacro, scm_m_start_stack);
571
8a04c1a2 572static SCM
9fa2c7b1
MD
573scm_m_start_stack (exp, env)
574 SCM exp;
575 SCM env;
576{
bfe3154c 577 exp = SCM_CDR (exp);
c6b8a41a 578 SCM_ASSERT (SCM_NIMP (exp)
e38ecb05 579 && SCM_ECONSP (exp)
c6b8a41a 580 && SCM_NIMP (SCM_CDR (exp))
e38ecb05 581 && SCM_ECONSP (SCM_CDR (exp))
c6b8a41a 582 && SCM_NULLP (SCM_CDDR (exp)),
bfe3154c
MD
583 exp,
584 SCM_WNA,
585 s_start_stack);
9fa2c7b1 586 return scm_start_stack (scm_eval_car (exp, env), SCM_CADR (exp), env);
bfe3154c 587}
f0e9217a
MD
588
589/* {Debug Objects}
590 *
591 * The debugging evaluator throws these on frame traps.
592 */
593
594long scm_tc16_debugobj;
595
1cc91f1b
JB
596static int prindebugobj SCM_P ((SCM obj, SCM port, scm_print_state *pstate));
597
f0e9217a 598static int
1cc91f1b 599prindebugobj (obj, port, pstate)
9882ea19
MD
600 SCM obj;
601 SCM port;
602 scm_print_state *pstate;
f0e9217a 603{
b7f3516f 604 scm_puts ("#<debug-object ", port);
bfe3154c 605 scm_intprint (SCM_DEBUGOBJ_FRAME (obj), 16, port);
b7f3516f 606 scm_putc ('>', port);
f0e9217a
MD
607 return 1;
608}
609
f0e9217a 610SCM_PROC (s_debug_object_p, "debug-object?", 1, 0, 0, scm_debug_object_p);
1cc91f1b 611
f0e9217a
MD
612SCM
613scm_debug_object_p (obj)
614 SCM obj;
f0e9217a 615{
bfe3154c 616 return SCM_NIMP (obj) && SCM_DEBUGOBJP (obj) ? SCM_BOOL_T : SCM_BOOL_F;
f0e9217a
MD
617}
618
1cc91f1b 619
f0e9217a
MD
620SCM
621scm_make_debugobj (frame)
622 scm_debug_frame *frame;
f0e9217a
MD
623{
624 register SCM z;
f0e9217a 625 SCM_NEWCELL (z);
f83e2737 626 SCM_ENTER_A_SECTION;
a6c64c3c 627 SCM_SET_DEBUGOBJ_FRAME (z, (SCM) frame);
f83e2737
MD
628 SCM_SETCAR (z, scm_tc16_debugobj);
629 SCM_EXIT_A_SECTION;
f0e9217a
MD
630 return z;
631}
632
f0e9217a
MD
633\f
634
fe57f652
MD
635/* Undocumented debugging procedure */
636#ifdef GUILE_DEBUG
e38ecb05
MD
637SCM_PROC (s_debug_hang, "debug-hang", 0, 1, 0, scm_debug_hang);
638
639SCM
640scm_debug_hang (obj)
641 SCM obj;
642{
643 int go = 0;
644 while (!go) ;
645 return SCM_UNSPECIFIED;
646}
fe57f652 647#endif
e38ecb05
MD
648
649\f
650
f0e9217a
MD
651void
652scm_init_debug ()
653{
5e8d7fd4 654 scm_init_opts (scm_debug_options, scm_debug_opts, SCM_N_DEBUG_OPTIONS);
ee340120 655
23a62151
MD
656 scm_tc16_memoized = scm_make_smob_type_mfpe ("memoized", 0,
657 scm_markcdr, NULL, prinmemoized, NULL);
658
659 scm_tc16_debugobj = scm_make_smob_type_mfpe ("debug-object", 0,
660 NULL, NULL, prindebugobj, NULL);
f0e9217a 661
63c51b9a
MD
662 scm_sym_procname = SCM_CAR (scm_sysintern ("procname", SCM_UNDEFINED));
663 scm_sym_dots = SCM_CAR (scm_sysintern ("...", SCM_UNDEFINED));
664 scm_sym_source = SCM_CAR (scm_sysintern ("source", SCM_UNDEFINED));
f0e9217a 665
33b97402
MD
666#ifdef GUILE_DEBUG
667 scm_sysintern ("SCM_IM_AND", SCM_IM_AND);
668 scm_sysintern ("SCM_IM_BEGIN", SCM_IM_BEGIN);
669 scm_sysintern ("SCM_IM_CASE", SCM_IM_CASE);
670 scm_sysintern ("SCM_IM_COND", SCM_IM_COND);
671 scm_sysintern ("SCM_IM_DO", SCM_IM_DO);
672 scm_sysintern ("SCM_IM_IF", SCM_IM_IF);
673 scm_sysintern ("SCM_IM_LAMBDA", SCM_IM_LAMBDA);
674 scm_sysintern ("SCM_IM_LET", SCM_IM_LET);
675 scm_sysintern ("SCM_IM_LETSTAR", SCM_IM_LETSTAR);
676 scm_sysintern ("SCM_IM_LETREC", SCM_IM_LETREC);
677 scm_sysintern ("SCM_IM_OR", SCM_IM_OR);
678 scm_sysintern ("SCM_IM_QUOTE", SCM_IM_QUOTE);
bbab09f6 679 scm_sysintern ("SCM_IM_SET_X", SCM_IM_SET_X);
33b97402
MD
680 scm_sysintern ("SCM_IM_DEFINE", SCM_IM_DEFINE);
681 scm_sysintern ("SCM_IM_APPLY", SCM_IM_APPLY);
682 scm_sysintern ("SCM_IM_CONT", SCM_IM_CONT);
bbab09f6 683 scm_sysintern ("SCM_IM_DISPATCH", SCM_IM_DISPATCH);
33b97402 684#endif
f0e9217a
MD
685 scm_add_feature ("debug-extensions");
686
687#include "debug.x"
688}