debug.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669
  1. /* Debugging extensions for Guile
  2. * Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2003 Free Software Foundation
  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
  16. * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  17. * Boston, MA 02110-1301 USA
  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
  44. * Mikael Djurfeldt, SANS/NADA KTH, 10044 STOCKHOLM, SWEDEN */
  45. #include "libguile/_scm.h"
  46. #include "libguile/eval.h"
  47. #include "libguile/stackchk.h"
  48. #include "libguile/throw.h"
  49. #include "libguile/macros.h"
  50. #include "libguile/smob.h"
  51. #include "libguile/procprop.h"
  52. #include "libguile/srcprop.h"
  53. #include "libguile/alist.h"
  54. #include "libguile/continuations.h"
  55. #include "libguile/strports.h"
  56. #include "libguile/read.h"
  57. #include "libguile/feature.h"
  58. #include "libguile/dynwind.h"
  59. #include "libguile/modules.h"
  60. #include "libguile/ports.h"
  61. #include "libguile/root.h"
  62. #include "libguile/fluids.h"
  63. #include "libguile/objects.h"
  64. #include "libguile/validate.h"
  65. #include "libguile/debug.h"
  66. /* {Run time control of the debugging evaluator}
  67. */
  68. SCM_DEFINE (scm_debug_options, "debug-options-interface", 0, 1, 0,
  69. (SCM setting),
  70. "Option interface for the debug options. Instead of using\n"
  71. "this procedure directly, use the procedures @code{debug-enable},\n"
  72. "@code{debug-disable}, @code{debug-set!} and @code{debug-options}.")
  73. #define FUNC_NAME s_scm_debug_options
  74. {
  75. SCM ans;
  76. SCM_DEFER_INTS;
  77. ans = scm_options (setting,
  78. scm_debug_opts,
  79. SCM_N_DEBUG_OPTIONS,
  80. FUNC_NAME);
  81. #ifndef SCM_RECKLESS
  82. if (!(1 <= SCM_N_FRAMES && SCM_N_FRAMES <= SCM_MAX_FRAME_SIZE))
  83. {
  84. scm_options (ans, scm_debug_opts, SCM_N_DEBUG_OPTIONS, FUNC_NAME);
  85. SCM_OUT_OF_RANGE (1, setting);
  86. }
  87. #endif
  88. SCM_RESET_DEBUG_MODE;
  89. scm_stack_checking_enabled_p = SCM_STACK_CHECKING_P;
  90. scm_debug_eframe_size = 2 * SCM_N_FRAMES;
  91. SCM_ALLOW_INTS;
  92. return ans;
  93. }
  94. #undef FUNC_NAME
  95. static void
  96. with_traps_before (void *data)
  97. {
  98. int *trap_flag = data;
  99. *trap_flag = SCM_TRAPS_P;
  100. SCM_TRAPS_P = 1;
  101. }
  102. static void
  103. with_traps_after (void *data)
  104. {
  105. int *trap_flag = data;
  106. SCM_TRAPS_P = *trap_flag;
  107. }
  108. static SCM
  109. with_traps_inner (void *data)
  110. {
  111. SCM thunk = SCM_PACK (data);
  112. return scm_call_0 (thunk);
  113. }
  114. SCM_DEFINE (scm_with_traps, "with-traps", 1, 0, 0,
  115. (SCM thunk),
  116. "Call @var{thunk} with traps enabled.")
  117. #define FUNC_NAME s_scm_with_traps
  118. {
  119. int trap_flag;
  120. SCM_VALIDATE_THUNK (1,thunk);
  121. return scm_internal_dynamic_wind (with_traps_before,
  122. with_traps_inner,
  123. with_traps_after,
  124. (void *) SCM_UNPACK (thunk),
  125. &trap_flag);
  126. }
  127. #undef FUNC_NAME
  128. SCM_SYMBOL (scm_sym_procname, "procname");
  129. SCM_SYMBOL (scm_sym_dots, "...");
  130. SCM_SYMBOL (scm_sym_source, "source");
  131. /* {Memoized Source}
  132. */
  133. scm_t_bits scm_tc16_memoized;
  134. static int
  135. memoized_print (SCM obj, SCM port, scm_print_state *pstate)
  136. {
  137. int writingp = SCM_WRITINGP (pstate);
  138. scm_puts ("#<memoized ", port);
  139. SCM_SET_WRITINGP (pstate, 1);
  140. #ifdef GUILE_DEBUG
  141. scm_iprin1 (SCM_MEMOIZED_EXP (obj), port, pstate);
  142. #else
  143. scm_iprin1 (scm_unmemoize (obj), port, pstate);
  144. #endif
  145. SCM_SET_WRITINGP (pstate, writingp);
  146. scm_putc ('>', port);
  147. return 1;
  148. }
  149. SCM_DEFINE (scm_memoized_p, "memoized?", 1, 0, 0,
  150. (SCM obj),
  151. "Return @code{#t} if @var{obj} is memoized.")
  152. #define FUNC_NAME s_scm_memoized_p
  153. {
  154. return SCM_BOOL(SCM_MEMOIZEDP (obj));
  155. }
  156. #undef FUNC_NAME
  157. SCM
  158. scm_make_memoized (SCM exp, SCM env)
  159. {
  160. /* *fixme* Check that env is a valid environment. */
  161. register SCM z, ans;
  162. SCM_ENTER_A_SECTION;
  163. SCM_NEWSMOB (z, SCM_UNPACK (exp), SCM_UNPACK (env));
  164. SCM_NEWSMOB (ans, scm_tc16_memoized, SCM_UNPACK (z));
  165. SCM_EXIT_A_SECTION;
  166. return ans;
  167. }
  168. #ifdef GUILE_DEBUG
  169. /*
  170. * Some primitives for construction of memoized code
  171. *
  172. * - procedure: memcons CAR CDR [ENV]
  173. *
  174. * Construct a pair, encapsulated in a memoized object.
  175. *
  176. * The CAR and CDR can be either normal or memoized. If ENV isn't
  177. * specified, the top-level environment of the current module will
  178. * be assumed. All environments must match.
  179. *
  180. * - procedure: make-gloc VARIABLE [ENV]
  181. *
  182. * Return a gloc, encapsulated in a memoized object.
  183. *
  184. * (Glocs can't exist in normal list structures, since they will
  185. * be mistaken for structs.)
  186. *
  187. * - procedure: gloc? OBJECT
  188. *
  189. * Return #t if OBJECT is a memoized gloc.
  190. *
  191. * - procedure: make-iloc FRAME BINDING CDRP
  192. *
  193. * Return an iloc referring to frame no. FRAME, binding
  194. * no. BINDING. If CDRP is non-#f, the iloc is referring to a
  195. * frame consisting of a single pair, with the value stored in the
  196. * CDR.
  197. *
  198. * - procedure: iloc? OBJECT
  199. *
  200. * Return #t if OBJECT is an iloc.
  201. *
  202. * - procedure: mem->proc MEMOIZED
  203. *
  204. * Construct a closure from the memoized lambda expression MEMOIZED
  205. *
  206. * WARNING! The code is not copied!
  207. *
  208. * - procedure: proc->mem CLOSURE
  209. *
  210. * Turn the closure CLOSURE into a memoized object.
  211. *
  212. * WARNING! The code is not copied!
  213. *
  214. * - constant: SCM_IM_AND
  215. * - constant: SCM_IM_BEGIN
  216. * - constant: SCM_IM_CASE
  217. * - constant: SCM_IM_COND
  218. * - constant: SCM_IM_DO
  219. * - constant: SCM_IM_IF
  220. * - constant: SCM_IM_LAMBDA
  221. * - constant: SCM_IM_LET
  222. * - constant: SCM_IM_LETSTAR
  223. * - constant: SCM_IM_LETREC
  224. * - constant: SCM_IM_OR
  225. * - constant: SCM_IM_QUOTE
  226. * - constant: SCM_IM_SET
  227. * - constant: SCM_IM_DEFINE
  228. * - constant: SCM_IM_APPLY
  229. * - constant: SCM_IM_CONT
  230. * - constant: SCM_IM_DISPATCH
  231. */
  232. #include "libguile/variable.h"
  233. #include "libguile/procs.h"
  234. SCM_DEFINE (scm_make_gloc, "make-gloc", 1, 1, 0,
  235. (SCM var, SCM env),
  236. "Create a gloc for variable @var{var} in the environment\n"
  237. "@var{env}.")
  238. #define FUNC_NAME s_scm_make_gloc
  239. {
  240. SCM_VALIDATE_VARIABLE (1,var);
  241. if (SCM_UNBNDP (env))
  242. env = scm_top_level_env (SCM_TOP_LEVEL_LOOKUP_CLOSURE);
  243. else
  244. SCM_VALIDATE_NULLORCONS (2,env);
  245. return scm_make_memoized (SCM_PACK (SCM_UNPACK (var) + scm_tc3_cons_gloc), env);
  246. }
  247. #undef FUNC_NAME
  248. SCM_DEFINE (scm_gloc_p, "gloc?", 1, 0, 0,
  249. (SCM obj),
  250. "Return @code{#t} if @var{obj} is a gloc.")
  251. #define FUNC_NAME s_scm_gloc_p
  252. {
  253. return
  254. SCM_BOOL (SCM_MEMOIZEDP (obj)
  255. && ((SCM_UNPACK(SCM_MEMOIZED_EXP(obj))&7) == scm_tc3_cons_gloc));
  256. }
  257. #undef FUNC_NAME
  258. SCM_DEFINE (scm_make_iloc, "make-iloc", 3, 0, 0,
  259. (SCM frame, SCM binding, SCM cdrp),
  260. "Return a new iloc with frame offset @var{frame}, binding\n"
  261. "offset @var{binding} and the cdr flag @var{cdrp}.")
  262. #define FUNC_NAME s_scm_make_iloc
  263. {
  264. SCM_VALIDATE_INUM (1,frame);
  265. SCM_VALIDATE_INUM (2,binding);
  266. return SCM_PACK (SCM_UNPACK (SCM_ILOC00)
  267. + SCM_IFRINC * SCM_INUM (frame)
  268. + (SCM_NFALSEP (cdrp) ? SCM_ICDR : 0)
  269. + SCM_IDINC * SCM_INUM (binding));
  270. }
  271. #undef FUNC_NAME
  272. SCM_DEFINE (scm_iloc_p, "iloc?", 1, 0, 0,
  273. (SCM obj),
  274. "Return @code{#t} if @var{obj} is an iloc.")
  275. #define FUNC_NAME s_scm_iloc_p
  276. {
  277. return SCM_BOOL(SCM_ILOCP (obj));
  278. }
  279. #undef FUNC_NAME
  280. SCM_DEFINE (scm_memcons, "memcons", 2, 1, 0,
  281. (SCM car, SCM cdr, SCM env),
  282. "Return a new memoized cons cell with @var{car} and @var{cdr}\n"
  283. "as members and @var{env} as the environment.")
  284. #define FUNC_NAME s_scm_memcons
  285. {
  286. if (SCM_MEMOIZEDP (car))
  287. {
  288. /*fixme* environments may be two different but equal top-level envs */
  289. if (!SCM_UNBNDP (env) && SCM_MEMOIZED_ENV (car) != env)
  290. SCM_MISC_ERROR ("environment mismatch arg1 <-> arg3",
  291. scm_cons2 (car, env, SCM_EOL));
  292. else
  293. env = SCM_MEMOIZED_ENV (car);
  294. car = SCM_MEMOIZED_EXP (car);
  295. }
  296. if (SCM_MEMOIZEDP (cdr))
  297. {
  298. if (!SCM_UNBNDP (env) && SCM_MEMOIZED_ENV (cdr) != env)
  299. SCM_MISC_ERROR ("environment mismatch arg2 <-> arg3",
  300. scm_cons2 (cdr, env, SCM_EOL));
  301. else
  302. env = SCM_MEMOIZED_ENV (cdr);
  303. cdr = SCM_MEMOIZED_EXP (cdr);
  304. }
  305. if (SCM_UNBNDP (env))
  306. env = scm_top_level_env (SCM_TOP_LEVEL_LOOKUP_CLOSURE);
  307. else
  308. SCM_VALIDATE_NULLORCONS (3,env);
  309. return scm_make_memoized (scm_cons (car, cdr), env);
  310. }
  311. #undef FUNC_NAME
  312. SCM_DEFINE (scm_mem_to_proc, "mem->proc", 1, 0, 0,
  313. (SCM obj),
  314. "Convert a memoized object (which must be a lambda expression)\n"
  315. "to a procedure.")
  316. #define FUNC_NAME s_scm_mem_to_proc
  317. {
  318. SCM env;
  319. SCM_VALIDATE_MEMOIZED (1,obj);
  320. env = SCM_MEMOIZED_ENV (obj);
  321. obj = SCM_MEMOIZED_EXP (obj);
  322. if (!(SCM_NIMP (obj) && SCM_CAR (obj) == SCM_IM_LAMBDA))
  323. SCM_MISC_ERROR ("expected lambda expression",
  324. scm_cons (obj, SCM_EOL));
  325. return scm_closure (SCM_CDR (obj), env);
  326. }
  327. #undef FUNC_NAME
  328. SCM_DEFINE (scm_proc_to_mem, "proc->mem", 1, 0, 0,
  329. (SCM obj),
  330. "Convert a procedure to a memoized object.")
  331. #define FUNC_NAME s_scm_proc_to_mem
  332. {
  333. SCM_VALIDATE_CLOSURE (1, obj);
  334. return scm_make_memoized (scm_cons (SCM_IM_LAMBDA, SCM_CODE (obj)),
  335. SCM_ENV (obj));
  336. }
  337. #undef FUNC_NAME
  338. #endif /* GUILE_DEBUG */
  339. SCM_DEFINE (scm_unmemoize, "unmemoize", 1, 0, 0,
  340. (SCM m),
  341. "Unmemoize the memoized expression @var{m},")
  342. #define FUNC_NAME s_scm_unmemoize
  343. {
  344. SCM_VALIDATE_MEMOIZED (1,m);
  345. return scm_unmemocopy (SCM_MEMOIZED_EXP (m), SCM_MEMOIZED_ENV (m));
  346. }
  347. #undef FUNC_NAME
  348. SCM_DEFINE (scm_memoized_environment, "memoized-environment", 1, 0, 0,
  349. (SCM m),
  350. "Return the environment of the memoized expression @var{m}.")
  351. #define FUNC_NAME s_scm_memoized_environment
  352. {
  353. SCM_VALIDATE_MEMOIZED (1,m);
  354. return SCM_MEMOIZED_ENV (m);
  355. }
  356. #undef FUNC_NAME
  357. SCM_DEFINE (scm_procedure_name, "procedure-name", 1, 0, 0,
  358. (SCM proc),
  359. "Return the name of the procedure @var{proc}")
  360. #define FUNC_NAME s_scm_procedure_name
  361. {
  362. SCM_VALIDATE_PROC (1,proc);
  363. switch (SCM_TYP7 (proc)) {
  364. case scm_tcs_subrs:
  365. return SCM_SNAME (proc);
  366. default:
  367. {
  368. SCM name = scm_procedure_property (proc, scm_sym_name);
  369. #if 0
  370. /* Source property scm_sym_procname not implemented yet... */
  371. SCM name = scm_source_property (SCM_CAR (SCM_CDR (SCM_CODE (proc))), scm_sym_procname);
  372. if (SCM_FALSEP (name))
  373. name = scm_procedure_property (proc, scm_sym_name);
  374. #endif
  375. if (SCM_FALSEP (name) && SCM_CLOSUREP (proc))
  376. name = scm_reverse_lookup (SCM_ENV (proc), proc);
  377. return name;
  378. }
  379. }
  380. }
  381. #undef FUNC_NAME
  382. #define scm_tcs_struct scm_tcs_cons_gloc
  383. SCM_DEFINE (scm_procedure_source, "procedure-source", 1, 0, 0,
  384. (SCM proc),
  385. "Return the source of the procedure @var{proc}.")
  386. #define FUNC_NAME s_scm_procedure_source
  387. {
  388. SCM_VALIDATE_NIM (1,proc);
  389. again:
  390. switch (SCM_TYP7 (proc)) {
  391. case scm_tcs_closures:
  392. {
  393. SCM formals = SCM_CLOSURE_FORMALS (proc);
  394. SCM src = scm_source_property (SCM_CDR (SCM_CODE (proc)), scm_sym_copy);
  395. if (!SCM_FALSEP (src))
  396. return scm_cons2 (scm_sym_lambda, formals, src);
  397. return scm_cons (scm_sym_lambda,
  398. scm_unmemocopy (SCM_CODE (proc),
  399. SCM_EXTEND_ENV (formals,
  400. SCM_EOL,
  401. SCM_ENV (proc))));
  402. }
  403. case scm_tcs_struct:
  404. if (!SCM_I_OPERATORP (proc))
  405. break;
  406. goto procprop;
  407. case scm_tc7_smob:
  408. if (!SCM_SMOB_DESCRIPTOR (proc).apply)
  409. break;
  410. case scm_tcs_subrs:
  411. #ifdef CCLO
  412. case scm_tc7_cclo:
  413. #endif
  414. procprop:
  415. /* It would indeed be a nice thing if we supplied source even for
  416. built in procedures! */
  417. return scm_procedure_property (proc, scm_sym_source);
  418. case scm_tc7_pws:
  419. {
  420. SCM src = scm_procedure_property (proc, scm_sym_source);
  421. if (!SCM_FALSEP (src))
  422. return src;
  423. proc = SCM_PROCEDURE (proc);
  424. goto again;
  425. }
  426. default:
  427. ;
  428. }
  429. SCM_WRONG_TYPE_ARG (1, proc);
  430. return SCM_BOOL_F; /* not reached */
  431. }
  432. #undef FUNC_NAME
  433. SCM_DEFINE (scm_procedure_environment, "procedure-environment", 1, 0, 0,
  434. (SCM proc),
  435. "Return the environment of the procedure @var{proc}.")
  436. #define FUNC_NAME s_scm_procedure_environment
  437. {
  438. SCM_VALIDATE_NIM (1,proc);
  439. switch (SCM_TYP7 (proc)) {
  440. case scm_tcs_closures:
  441. return SCM_ENV (proc);
  442. case scm_tcs_subrs:
  443. #ifdef CCLO
  444. case scm_tc7_cclo:
  445. #endif
  446. return SCM_EOL;
  447. default:
  448. SCM_WRONG_TYPE_ARG (1, proc);
  449. /* not reached */
  450. }
  451. }
  452. #undef FUNC_NAME
  453. /* Eval in a local environment. We would like to have the ability to
  454. * evaluate in a specified local environment, but due to the
  455. * memoization this isn't normally possible. We solve it by copying
  456. * the code before evaluating. One solution would be to have eval.c
  457. * generate yet another evaluator. They are not very big actually.
  458. */
  459. SCM_DEFINE (scm_local_eval, "local-eval", 1, 1, 0,
  460. (SCM exp, SCM env),
  461. "Evaluate @var{exp} in its environment. If @var{env} is supplied,\n"
  462. "it is the environment in which to evaluate @var{exp}. Otherwise,\n"
  463. "@var{exp} must be a memoized code object (in which case, its environment\n"
  464. "is implicit).")
  465. #define FUNC_NAME s_scm_local_eval
  466. {
  467. if (SCM_UNBNDP (env))
  468. {
  469. SCM_VALIDATE_MEMOIZED (1, exp);
  470. return scm_i_eval_x (SCM_MEMOIZED_EXP (exp), SCM_MEMOIZED_ENV (exp));
  471. }
  472. return scm_i_eval (exp, env);
  473. }
  474. #undef FUNC_NAME
  475. #if 0
  476. SCM_REGISTER_PROC (s_reverse_lookup, "reverse-lookup", 2, 0, 0, scm_reverse_lookup);
  477. #endif
  478. SCM
  479. scm_reverse_lookup (SCM env, SCM data)
  480. {
  481. while (SCM_CONSP (env) && SCM_CONSP (SCM_CAR (env)))
  482. {
  483. SCM names = SCM_CAAR (env);
  484. SCM values = SCM_CDAR (env);
  485. while (SCM_CONSP (names))
  486. {
  487. if (SCM_EQ_P (SCM_CAR (values), data))
  488. return SCM_CAR (names);
  489. names = SCM_CDR (names);
  490. values = SCM_CDR (values);
  491. }
  492. if (!SCM_NULLP (names) && SCM_EQ_P (values, data))
  493. return names;
  494. env = SCM_CDR (env);
  495. }
  496. return SCM_BOOL_F;
  497. }
  498. SCM
  499. scm_start_stack (SCM id, SCM exp, SCM env)
  500. {
  501. SCM answer;
  502. scm_t_debug_frame vframe;
  503. scm_t_debug_info vframe_vect_body;
  504. vframe.prev = scm_last_debug_frame;
  505. vframe.status = SCM_VOIDFRAME;
  506. vframe.vect = &vframe_vect_body;
  507. vframe.vect[0].id = id;
  508. scm_last_debug_frame = &vframe;
  509. answer = scm_i_eval (exp, env);
  510. scm_last_debug_frame = vframe.prev;
  511. return answer;
  512. }
  513. SCM_SYNTAX(s_start_stack, "start-stack", scm_makacro, scm_m_start_stack);
  514. static SCM
  515. scm_m_start_stack (SCM exp, SCM env)
  516. #define FUNC_NAME s_start_stack
  517. {
  518. exp = SCM_CDR (exp);
  519. if (!SCM_ECONSP (exp)
  520. || !SCM_ECONSP (SCM_CDR (exp))
  521. || !SCM_NULLP (SCM_CDDR (exp)))
  522. SCM_WRONG_NUM_ARGS ();
  523. return scm_start_stack (scm_eval_car (exp, env), SCM_CADR (exp), env);
  524. }
  525. #undef FUNC_NAME
  526. /* {Debug Objects}
  527. *
  528. * The debugging evaluator throws these on frame traps.
  529. */
  530. scm_t_bits scm_tc16_debugobj;
  531. static int
  532. debugobj_print (SCM obj, SCM port, scm_print_state *pstate SCM_UNUSED)
  533. {
  534. scm_puts ("#<debug-object ", port);
  535. scm_intprint ((long) SCM_DEBUGOBJ_FRAME (obj), 16, port);
  536. scm_putc ('>', port);
  537. return 1;
  538. }
  539. SCM_DEFINE (scm_debug_object_p, "debug-object?", 1, 0, 0,
  540. (SCM obj),
  541. "Return @code{#t} if @var{obj} is a debug object.")
  542. #define FUNC_NAME s_scm_debug_object_p
  543. {
  544. return SCM_BOOL(SCM_DEBUGOBJP (obj));
  545. }
  546. #undef FUNC_NAME
  547. SCM
  548. scm_make_debugobj (scm_t_debug_frame *frame)
  549. {
  550. register SCM z;
  551. SCM_NEWCELL (z);
  552. SCM_ENTER_A_SECTION;
  553. SCM_SET_DEBUGOBJ_FRAME (z, frame);
  554. SCM_SET_CELL_TYPE (z, scm_tc16_debugobj);
  555. SCM_EXIT_A_SECTION;
  556. return z;
  557. }
  558. /* Undocumented debugging procedure */
  559. #ifdef GUILE_DEBUG
  560. SCM_DEFINE (scm_debug_hang, "debug-hang", 0, 1, 0,
  561. (SCM obj),
  562. "Go into an endless loop, which can be only terminated with\n"
  563. "a debugger.")
  564. #define FUNC_NAME s_scm_debug_hang
  565. {
  566. int go = 0;
  567. while (!go) ;
  568. return SCM_UNSPECIFIED;
  569. }
  570. #undef FUNC_NAME
  571. #endif
  572. void
  573. scm_init_debug ()
  574. {
  575. scm_init_opts (scm_debug_options, scm_debug_opts, SCM_N_DEBUG_OPTIONS);
  576. scm_tc16_memoized = scm_make_smob_type ("memoized", 0);
  577. scm_set_smob_mark (scm_tc16_memoized, scm_markcdr);
  578. scm_set_smob_print (scm_tc16_memoized, memoized_print);
  579. scm_tc16_debugobj = scm_make_smob_type ("debug-object", 0);
  580. scm_set_smob_print (scm_tc16_debugobj, debugobj_print);
  581. #ifdef GUILE_DEBUG
  582. scm_c_define ("SCM_IM_AND", SCM_IM_AND);
  583. scm_c_define ("SCM_IM_BEGIN", SCM_IM_BEGIN);
  584. scm_c_define ("SCM_IM_CASE", SCM_IM_CASE);
  585. scm_c_define ("SCM_IM_COND", SCM_IM_COND);
  586. scm_c_define ("SCM_IM_DO", SCM_IM_DO);
  587. scm_c_define ("SCM_IM_IF", SCM_IM_IF);
  588. scm_c_define ("SCM_IM_LAMBDA", SCM_IM_LAMBDA);
  589. scm_c_define ("SCM_IM_LET", SCM_IM_LET);
  590. scm_c_define ("SCM_IM_LETSTAR", SCM_IM_LETSTAR);
  591. scm_c_define ("SCM_IM_LETREC", SCM_IM_LETREC);
  592. scm_c_define ("SCM_IM_OR", SCM_IM_OR);
  593. scm_c_define ("SCM_IM_QUOTE", SCM_IM_QUOTE);
  594. scm_c_define ("SCM_IM_SET_X", SCM_IM_SET_X);
  595. scm_c_define ("SCM_IM_DEFINE", SCM_IM_DEFINE);
  596. scm_c_define ("SCM_IM_APPLY", SCM_IM_APPLY);
  597. scm_c_define ("SCM_IM_CONT", SCM_IM_CONT);
  598. scm_c_define ("SCM_IM_DISPATCH", SCM_IM_DISPATCH);
  599. #endif
  600. scm_add_feature ("debug-extensions");
  601. #include "libguile/debug.x"
  602. }
  603. /*
  604. Local Variables:
  605. c-file-style: "gnu"
  606. End:
  607. */