diff options
-rw-r--r-- | debug.c | 222 | ||||
-rw-r--r-- | debug.h | 86 | ||||
-rw-r--r-- | eval.c | 28 | ||||
-rw-r--r-- | lisplib.c | 4 | ||||
-rw-r--r-- | match.c | 52 | ||||
-rw-r--r-- | parser.y | 5 | ||||
-rw-r--r-- | protsym.c | 6 | ||||
-rw-r--r-- | signal.h | 17 | ||||
-rw-r--r-- | txr.1 | 329 | ||||
-rw-r--r-- | unwind.c | 17 | ||||
-rw-r--r-- | unwind.h | 18 |
11 files changed, 40 insertions, 744 deletions
@@ -43,230 +43,12 @@ #include "debug.h" int opt_debugger; -int debug_depth; -static int step_mode; -static int next_depth = -1; -static val breakpoints; -static val last_command; -static int cols = 80; +int debug_state; -val debug_quit_s; - -/* C99 inline instantiations. */ #if __STDC_VERSION__ >= 199901L -val debug_check(val form, val bindings, val data, val line, - val pos, val base); -void debug_init(void); +int debug_set_state(int state); #endif -static void help(val stream) -{ - put_string(lit("commands:\n" - "? - help q - quit c - continue s - step into form\n" - "h - help f - finish form n - step over form\n" - "v - show variable binding environment o - show current form\n" - "b - set breakpoint by line number i - show current data\n" - "d - delete breakpoint w - backtrace\n" - "l - list breakpoints g - set loglevel\n"), - stream); -} - -static void show_bindings(val env, val stream) -{ - val level = zero; - put_string(lit("bindings:\n"), stream); - - for (;; level = plus(level, one)) { - if (nilp(env)) - break; - else if (consp(env)) { - format(stream, lit("~d: ~s\n"), level, env, nao); - break; - } else if (type(env) == ENV) { - format(stream, lit("~d: ~s\n"), level, env->e.vbindings, nao); - env = env->e.up_env; - } else { - format(stream, lit("invalid environment object: ~s\n"), env, nao); - break; - } - } -} - -val debug(val ctx, val bindings, val data, val line, val pos, val base) -{ - uses_or2; - val form = ctx_form(ctx); - val rl = source_loc(form); - cons_bind (lineno, file, rl); - - if (consp(data)) - data = car(data); - else if (data == t) - data = nil; - - if (!step_mode && !memqual(rl, breakpoints) - && (debug_depth > next_depth)) - { - return nil; - } else { - val print_form = t; - val print_data = t; - - for (;;) { - val input, command; - - if (print_form) { - format(std_debug, lit("stopped at line ~d of ~a\n"), - lineno, file, nao); - format(std_debug, lit("form: ~s\n"), form, nao); - format(std_debug, lit("depth: ~s\n"), num(debug_depth), nao); - print_form = nil; - } - - if (print_data) { - int lim = cols * 8; - - if (data && pos) { - val half = num((lim - 8) / 2); - val full = num((lim - 8)); - val prefix, suffix; - - if (lt(pos, half)) { - prefix = sub_str(data, zero, pos); - suffix = sub_str(data, pos, full); - } else { - prefix = sub_str(data, minus(pos, half), pos); - suffix = sub_str(data, pos, plus(pos, half)); - } - - format(std_debug, lit("data (~d:~d):\n~s . ~s\n"), - line, plus(pos, base), prefix, suffix, nao); - } else if (data && length_str_ge(data, num(lim - 2))) { - format(std_debug, lit("data (~d):\n~s...~s\n"), line, - sub_str(data, zero, num(lim/2 - 4)), - sub_str(data, num(-(lim/2 - 3)), t), nao); - } else { - format(std_debug, lit("data (~d):\n~s\n"), line, data, nao); - } - print_data = nil; - } - - format(std_debug, lit("txr> "), nao); - flush_stream(std_debug); - - input = split_str_set(or2(get_line(std_input), lit("q")), lit("\t ")); - command = if3(equal(first(input), null_string), - or2(last_command, lit("")), first(input)); - last_command = command; - - if (equal(command, lit("?")) || equal(command, lit("h"))) { - help(std_debug); - continue; - } else if (equal(command, null_string)) { - continue; - } else if (equal(command, lit("c"))) { - step_mode = 0; - next_depth = -1; - return nil; - } else if (equal(command, lit("s"))) { - step_mode = 1; - return nil; - } else if (equal(command, lit("n"))) { - step_mode = 0; - next_depth = debug_depth; - return nil; - } else if (equal(command, lit("f"))) { - step_mode = 0; - next_depth = debug_depth - 1; - return nil; - } else if (equal(command, lit("v"))) { - show_bindings(bindings, std_debug); - } else if (equal(command, lit("o"))) { - print_form = t; - } else if (equal(command, lit("i"))) { - print_data = t; - } else if (equal(command, lit("b")) || equal(command, lit("d")) || - equal(command, lit("g"))) - { - if (!rest(input)) { - format(std_debug, lit("~s needs arguments\n"), command, nao); - continue; - } else { - val n = int_str(second(input), num(10)); - val l = cons(n, or2(third(input), file)); - - if (!n) { - format(std_debug, lit("~s needs <line> [ <file> ]\n"), - command, nao); - continue; - } - - if (equal(command, lit("b"))) { - breakpoints = remqual(l, breakpoints, nil); - push(l, &breakpoints); - } else if (equal(command, lit("d"))) { - val breakpoints_old = breakpoints; - breakpoints = remqual(l, breakpoints, nil); - if (breakpoints == breakpoints_old) - format(std_debug, lit("no such breakpoint\n"), nao); - } else { - opt_loglevel = c_num(n); - } - } - } else if (equal(command, lit("l"))) { - format(std_debug, lit("breakpoints: ~s\n"), breakpoints, nao); - } else if (equal(command, lit("w"))) { - format(std_debug, lit("backtrace:\n"), nao); - { - uw_frame_t *iter; - - for (iter = uw_current_frame(); iter != 0; iter = iter->uw.up) { - if (iter->uw.type == UW_DBG) { - if (iter->db.ub_p_a_pairs) - format(std_debug, lit("(~s ~s ~s)\n"), iter->db.func, - args_copy_to_list(iter->db.args), - iter->db.ub_p_a_pairs, nao); - else - format(std_debug, lit("(~s ~s)\n"), iter->db.func, - args_copy_to_list(iter->db.args), nao); - } - } - } - } else if (equal(command, lit("q"))) { - uw_throwf(debug_quit_s, lit("terminated via debugger"), nao); - } else { - format(std_debug, lit("unrecognized command: ~a\n"), command, nao); - } - } - - return nil; - } -} - -debug_state_t debug_set_state(int depth, int step) -{ - debug_state_t old = { next_depth, step_mode }; - next_depth = depth; - step_mode = step; - return old; -} - -void debug_restore_state(debug_state_t state) -{ - next_depth = state.next_depth; - step_mode = state.step_mode; -} - void debug_init(void) { - step_mode = 1; - protect(&breakpoints, &last_command, convert(val *, 0)); - debug_quit_s = intern(lit("debug-quit"), user_package); - { - char *columns = getenv("COLUMNS"); - if (columns) - cols = atoi(columns); - if (cols < 40) - cols = 40; - } } @@ -26,93 +26,23 @@ */ extern int opt_debugger; -extern int debug_depth; -val debug(val form, val bindings, val data, val line, val pos, val base); +int debug_state; #if CONFIG_DEBUG_SUPPORT -typedef struct { - int next_depth; - int step_mode; -} debug_state_t; - -#define debug_enter \ - { \ - int debug_depth_save = debug_depth++; \ - val debug_result = nil; \ - (void) 0 - -#define debug_leave \ - debug_return_out: \ - debug_depth = debug_depth_save; \ - return debug_result; \ - } - -#define debug_return(VAL) \ - do { \ - debug_result = VAL; \ - goto debug_return_out; \ - } while (0) - -INLINE val debug_check(val ctx, val bindings, val data, val line, - val pos, val base) -{ - return (opt_debugger) ? debug(ctx, bindings, data, line, pos, base) : nil; -} - -debug_state_t debug_set_state(int depth, int step); -void debug_restore_state(debug_state_t); void debug_init(void); -#define debug_frame(FUNC, ARGS, UBP, \ - BINDINGS, DATA, \ - LINE, CHR) \ - do { \ - uw_frame_t db_env; \ - if (opt_debugger) { \ - uw_push_debug(&db_env, FUNC, ARGS,\ - UBP, BINDINGS, DATA,\ - LINE, CHR); \ - } \ - (void) 0 - -#define debug_end \ - if (opt_debugger) { \ - uw_pop_frame(&db_env); \ - } \ - } while (0) - -#else - -typedef int debug_state_t; - -#define debug_enter { - -#define debug_leave } - -#define debug_return(VAL) return VAL - -INLINE val debug_check(val form, val bindings, val data, val line, - val pos, val base) +INLINE int debug_set_state(int state) { - return nil; + int ret = debug_state; + debug_state = state; + return ret; } -#define debug_frame(FUNC, ARGS, UBP, \ - BINDINGS, DATA, \ - LINE, CHR) \ - do { \ - (void) 0 - -#define debug_end \ - } while (0) - -#define debug_set_state(D, S) (0) -#define debug_restore_state(S) ((void) 0) +#else -INLINE void debug_init(void) -{ -} +#define debug_init() ((void) 0) +#define debug_set_state(S) 0 #endif @@ -1486,20 +1486,17 @@ val eval_intrinsic_noerr(val form, val env, val *error_p) static val do_eval(val form, val env, val ctx, val (*lookup)(val env, val sym)) { - debug_enter; - - debug_check(consp(form) ? form : ctx, env, nil, nil, nil, nil); sig_check_fast(); if (nilp(form)) { - debug_return (nil); + return nil; } else if (symbolp(form)) { if (!bindable(form)) { - debug_return (form); + return form; } else { val binding = lookup(env, form); if (binding) - debug_return (cdr(binding)); + return cdr(binding); eval_error(ctx, lit("unbound variable ~s"), form, nao); abort(); } @@ -1513,7 +1510,7 @@ static val do_eval(val form, val env, val ctx, last_form_evaled = form; ret = fp(form, env); last_form_evaled = lfe_save; - debug_return (ret); + return ret; } else { val fbinding = lookup_fun(env, oper); @@ -1534,20 +1531,16 @@ static val do_eval(val form, val env, val ctx, last_form_evaled = form; do_eval_args(rest(form), env, form, &lookup_var, args); - debug_frame(oper, args, nil, env, nil, nil, nil); ret = generic_funcall(cdr(fbinding), args); - debug_end; last_form_evaled = lfe_save; - debug_return (ret); + return ret; } } } else { - debug_return (form); + return form; } - - debug_leave; } val eval(val form, val env, val ctx) @@ -2020,8 +2013,6 @@ static val op_defun(val form, val env) static val me_interp_macro(val expander, val form, val menv) { - debug_enter; - val name = car(form); val arglist = rest(form); val env = car(expander); val params = cadr(expander); @@ -2029,15 +2020,10 @@ static val me_interp_macro(val expander, val form, val menv) val saved_de = set_dyn_env(make_env(nil, nil, dyn_env)); val exp_env = bind_macro_params(env, menv, params, arglist, nil, form); val result; - args_decl_list(args, ARGS_MIN, arglist); - - debug_frame(name, args, nil, env, nil, nil, nil); result = eval_progn(body, exp_env, body); - debug_end; set_dyn_env(saved_de); set_origin(result, form); - debug_return(result); - debug_leave; + return result; } static val op_defmacro(val form, val env) @@ -833,14 +833,14 @@ val lisplib_try_load(val sym) val fun = gethash(dl_table, sym); if (fun) { - debug_state_t ds = debug_set_state(opt_dbg_autoload ? 0 : -1, opt_dbg_autoload); + int ds = debug_set_state(opt_dbg_autoload); val saved_dyn_env = dyn_env; dyn_env = make_env(nil, nil, dyn_env); env_vbind(dyn_env, package_s, system_package); env_vbind(dyn_env, package_alist_s, packages); funcall(fun); dyn_env = saved_dyn_env; - debug_restore_state(ds); + debug_set_state(ds); return t; } return nil; @@ -1405,8 +1405,6 @@ static val h_fun(match_line_ctx *c) args_decl_list(args, ARGS_MIN, bindings_cp); uw_block_begin(nil, result); uw_match_env_begin; - debug_frame(sym, args, ub_p_a_pairs, c->bindings, c->dataline, c->data_lineno, c->pos); - uw_simple_catch_begin; result = match_line(ml_bindings_specline(*c, bindings_cp, body)); @@ -1417,7 +1415,6 @@ static val h_fun(match_line_ctx *c) uw_catch_end; - debug_end; uw_match_env_end; uw_block_end; @@ -1525,8 +1522,6 @@ static val do_match_line(match_line_ctx *c) { val lfe_save = set_last_form_evaled(nil); - debug_enter; - while (c->specline) { val elem = first(c->specline); @@ -1537,9 +1532,6 @@ static val do_match_line(match_line_ctx *c) consume_prefix(c); - debug_check(c->specline, c->bindings, c->dataline, c->data_lineno, - c->pos, c->base); - switch (type(elem)) { case CONS: /* directive */ { @@ -1551,7 +1543,7 @@ static val do_match_line(match_line_ctx *c) if (!len) { LOG_MISMATCH("string tree"); - debug_return (nil); + return nil; } newpos = plus(c->pos, len); @@ -1568,7 +1560,7 @@ static val do_match_line(match_line_ctx *c) } else if (result == repeat_spec_k) { continue; } else { - debug_return (result); + return result; } } else { val result = h_fun(c); @@ -1597,10 +1589,10 @@ static val do_match_line(match_line_ctx *c) sem_error(elem, lit("no such function or directive: ~a"), directive, nao); } else { - debug_return (vresult); + return vresult; } } else { - debug_return (result); + return result; } } } @@ -1613,7 +1605,7 @@ static val do_match_line(match_line_ctx *c) val newpos; if (!match_str(c->dataline, elem, c->pos)) { LOG_MISMATCH("string"); - debug_return (nil); + return nil; } newpos = plus(c->pos, length_str(elem)); LOG_MATCH("string", newpos); @@ -1625,7 +1617,7 @@ static val do_match_line(match_line_ctx *c) val past = match_regex(c->dataline, elem, c->pos); if (nilp(past)) { LOG_MISMATCH("regex"); - debug_return (nil); + return nil; } LOG_MATCH("regex", past); c->pos = past; @@ -1639,8 +1631,7 @@ static val do_match_line(match_line_ctx *c) c->specline = cdr(c->specline); } - debug_return (cons(c->bindings, plus(c->pos, c->base))); - debug_leave; + return cons(c->bindings, plus(c->pos, c->base)); set_last_form_evaled(lfe_save); } @@ -4182,8 +4173,6 @@ static val v_fun(match_files_ctx *c) args_decl_list(args, ARGS_MIN, bindings_cp); uw_block_begin(nil, result); uw_match_env_begin; - debug_frame(sym, args, ub_p_a_pairs, c->bindings, if2(consp(c->data), car(c->data)), - c->data_lineno, nil); uw_simple_catch_begin; @@ -4195,7 +4184,6 @@ static val v_fun(match_files_ctx *c) uw_catch_end; - debug_end; uw_match_env_end; uw_block_end; @@ -4599,8 +4587,6 @@ static void open_data_source(match_files_ctx *c) static val match_files(match_files_ctx c) { - debug_enter; - gc_hint(c.data); for (; c.spec; c.spec = rest(c.spec), @@ -4612,8 +4598,6 @@ repeat_spec_same_data: open_data_source(&c); - debug_check(specline, c.bindings, c.data, c.data_lineno, nil, nil); - /* Line with nothing but a single directive or call: vertical mode. */ if (consp(first_spec) && !rest(specline)) { val lfe_save = set_last_form_evaled(first_spec); @@ -4635,7 +4619,7 @@ repeat_spec_same_data: } else if (result == decline_k) { /* Vertical directive declined; go to horizontal processing */ } else { - debug_return (result); + return result; } } else if (gethash(h_directive_table,sym)) { /* Lone horizontal-only directive: go to horizontal processing */ @@ -4653,7 +4637,7 @@ repeat_spec_same_data: since rest(specline) is nil, this is not horizontal fallback. */ sem_error(specline, lit("function ~s not found"), sym, nao); } else { - debug_return (result); + return result; } } } @@ -4670,20 +4654,18 @@ repeat_spec_same_data: c.data, c.data_lineno, c.curfile))); if (!success) - debug_return (nil); + return nil; c.bindings = new_bindings; } else if (consp(c.data) || nilp(c.data)) { debuglf(specline, lit("spec ran out of data"), nao); - debug_return (nil); + return nil; } else { internal_error("bug in data stream opening logic"); } } - debug_return (cons(c.bindings, if3(c.data, cons(c.data, c.data_lineno), t))); - - debug_leave; + return cons(c.bindings, if3(c.data, cons(c.data, c.data_lineno), t)); } val match_filter(val name, val arg, val other_args) @@ -4737,21 +4719,15 @@ val match_fun(val name, val args, val input_in, val files_in) match_files_ctx c = mf_all(spec, files, in_bindings, data, curfile); val ret; - debug_enter; - - debug_check(call, c.bindings, c.data, c.data_lineno, nil, nil); - ret = v_fun(&c); if (ret == nil) - debug_return (nil); + return nil; if (ret == decline_k) sem_error(nil, lit("match-fun: function ~s not found"), name, nao); - debug_return (cons(c.bindings, if3(c.data, cons(c.data, c.data_lineno), t))); - - debug_leave; + return cons(c.bindings, if3(c.data, cons(c.data, c.data_lineno), t)); } val include(val specline) @@ -1851,8 +1851,7 @@ int parse_once(val stream, val name, parser_t *parser) { int res = 0; #if CONFIG_DEBUG_SUPPORT - debug_state_t ds = debug_set_state(opt_dbg_expansion ? 0 : -1, - opt_dbg_expansion); + int ds = debug_set_state(opt_dbg_expansion); #endif parser_common_init(parser); @@ -1875,7 +1874,7 @@ int parse_once(val stream, val name, parser_t *parser) uw_unwind { parser_cleanup(parser); #if CONFIG_DEBUG_SUPPORT - debug_restore_state(ds); + debug_set_state(ds); #endif } @@ -143,9 +143,6 @@ extern val while_star_s, whole_k, width_s, wild_s, word_char_k; extern val wrap_k, wstr_d_s, wstr_s, year_s, zap_s; extern val zarray_s, zerop_s, zeroplus_s, zone_s; -#if CONFIG_DEBUG_SUPPORT -extern val debug_quit_s; -#endif #if HAVE_DLOPEN extern val dlhandle_s, dlsym_s; #endif @@ -285,9 +282,6 @@ val *protected_sym[] = { &wrap_k, &wstr_d_s, &wstr_s, &year_s, &zap_s, &zarray_s, &zerop_s, &zeroplus_s, &zone_s, -#if CONFIG_DEBUG_SUPPORT - &debug_quit_s, -#endif #if HAVE_DLOPEN &dlhandle_s, &dlsym_s, #endif @@ -26,20 +26,9 @@ */ -#if CONFIG_DEBUG_SUPPORT -extern int debug_depth; -#define EJ_DBG_MEMB volatile int dbg_depth; -#define EJ_DBG_SAVE(EJB) (EJB).dbg_depth = debug_depth, -#define EJ_DBG_REST(EJB) debug_depth = (EJB).dbg_depth, -#else -#define EJ_DBG_MEMB -#define EJ_DBG_SAVE(EJB) -#define EJ_DBG_REST(EJB) -#endif - -#define EJ_OPT_MEMB EJ_DBG_MEMB -#define EJ_OPT_SAVE(EJB) EJ_DBG_SAVE(EJB) -#define EJ_OPT_REST(EJB) EJ_DBG_REST(EJB) +#define EJ_OPT_MEMB +#define EJ_OPT_SAVE(EJB) +#define EJ_OPT_REST(EJB) #if __i386__ @@ -67155,335 +67155,8 @@ that is located in the same directory. .brev .SH* DEBUGGER -\*(TX has a simple, crude, built-in debugger. The debugger is invoked by adding -the -.code -d -command line option to an invocation of \*(TX. -In this debugger it is possible to step through code, set breakpoints, -and examine the variable binding environment. - -Prior to executing any code, the debugger waits at the -.code txr> -prompt, allowing for the opportunity to set breakpoints. - -Help can be obtained with the -.code h -or -.code ? -command. - -Whenever the program stops at the debugger, it prints the Lisp-ified -piece of syntax tree that is about to be interpreted. -It also shows the context of the input being matched. - -The s command can be used to step into a form; n to step over. -Sometimes the behavior seems counter-intuitive. For instance stepping -over a -.code @(next) -directive actually means skipping everything which follows -it. This is because the query material after a -.code @(next) -is actually child -nodes in the abstract syntax tree node of the -.code next -directive, whereas the surface syntax appears flat. - -The following is an example of the debugger being applied to a web scraping program -which connects to a US NAVY clock server to retrieve a dynamically-generated -web page, from which the current time is extracted, in various time zones. -The handling of the web request is done by the wget command; the -\*(TX query opens a wget command as and scans the body of the HTTP response -containing -HTML. This is the code, saved in a file called navytime.txr: - -.verb - @(bind url "http://tycho.usno.navy.mil/cgi-bin/timer.pl") - @(next (open-command `wget -c @url -O - 2> /dev/null`)) - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final"//EN> - <html> - <body> - <TITLE>What time is it?</TITLE> - <H2> US Naval Observatory Master Clock Time</H2> <H3><PRE> - @(collect :vars (MO DD HH MM SS (PM " ") TZ TZNAME)) - <BR>@MO. @DD, @HH:@MM:@SS @(maybe)@{PM /PM/} @(end)@TZ@/\t+/@TZNAME - @ (until) - </PRE>@/.*/ - @(end) - </PRE></H3><P><A HREF="http://@(skip)"> US Naval Observatory</A> - - </body></html> - @(output) - @ (repeat) - @MO-@DD @HH:@MM:@SS @PM @TZ - @ (end) - @(end) -.brev - -This is the debug session: - -.verb - $ txr -d navytime.txr - stopped at line 1 of navytime.txr - form: ((bind url "http://tycho.usno.navy.mil/cgi-bin/timer.pl")) - depth: 1 - data (1): - nil - txr> s -.brev - -Control stops on the first line of the script. The -.code form: -line output by the debugger shows the internal syntax. -The user issues the -.code s -command to step: - -.verb - stopped at line 2 of navytime.txr - form: ((next (open-command `wget -c @url -O - 2> /dev/null`))) - depth: 1 - data (1): - nil -.brev - -The user types -.code s -to step into the -.code "(next ...)" -form. - -.verb - txr> s - stopped at line 2 of navytime.txr - form: (open-command `wget -c @url -O - 2> /dev/null`) - depth: 2 - data (nil): - nil -.brev - -The current form now is the \*(TL -.code open-command -form which will create an input stream from the given -.code wget -command. The user types -.code s -again to step in: - -.verb - txr> s - stopped at line 2 of navytime.txr - form: `wget -c @url -O - 2> /dev/null` - depth: 3 - data (nil): - nil -.brev - -Now, the argument expression of the -.code open-command -form is about to be evaluated. -.verb - txr> s - stopped at line 3 of navytime.txr - form: ((sys:text "<!DOCTYPE" #/ +/ "HTML" #/ +/ "PUBLIC" - #/ +/ "\e"-//W3C//DTD" #/ +/ "HTML" #/ +/ "3.2" - #/ +/ "Final\e"//EN>")) - depth: 2 - data (1): - "<!DOCTYPE HTML PUBLIC \e"-//W3C//DTD HTML 3.2 Final\e"//EN>" -.brev - -Now, the input stream has been opened, and control has stopped at line 3 -of the query. The -.code "((sys:text ...) ...)" -syntax is the internal representation of this line. The pattern matching -is in vertical mode, and so the current line of input is shown without -an indication of the character position. - -.verb - txr> s - stopped at line 3 of navytime.txr - form: ((sys:text "<!DOCTYPE" #/ +/ "HTML" #/ +/ "PUBLIC" - #/ +/ "\e"-//W3C//DTD" #/ +/ "HTML" #/ +/ "3.2" - #/ +/ "Final\e"//EN>")) - depth: 3 - data (1:0): - "" . "<!DOCTYPE HTML PUBLIC \e"-//W3C//DTD HTML 3.2 Final\e"//EN>" -.brev - -Now, the form about to be processed is the first item of the -.codn "(sys:text ...)" , -the string -.strn <!DOCTYPE . - -The input is shown broken into two quoted strings with a dot in between. -The dot indicates the current position. The left string is empty, meaning -that this is the leftmost position. The programmer steps: - -.verb -txr> s - stopped at line 3 of navytime.txr - form: ("<!DOCTYPE" #/ +/ "HTML" #/ +/ "PUBLIC" #/ +/ "\e"-//W3C//DTD" - #/ +/ "HTML" #/ +/ "3.2" #/ +/ "Final\e"//EN>") - depth: 4 - data (1:0): - "" . "<!DOCTYPE HTML PUBLIC \e"-//W3C//DTD HTML 3.2 Final\e"//EN>" -.brev - -The literal text -.str "<!DOCTYPE" -is about to be matched. - -.verb - txr> s - stopped at line 3 of navytime.txr - form: (#/ +/ "HTML" #/ +/ "PUBLIC" #/ +/ "\e"-//W3C//DTD" #/ +/ "HTML" - #/ +/ "3.2" #/ +/ "Final\e"//EN>") - depth: 4 - data (1:9): - "<!DOCTYPE" . " HTML PUBLIC \e"-//W3C//DTD HTML 3.2 Final\e"//EN>" -.brev - -The -.str "<!DOCTYPE" -text matches and so the current position advances in the input. -Control has now passed to the second element of the -.codn "(sys:text ...)" , -the regular expression -.code "#/ +/" -which matches one or more spaces. This regular expression is -produced by a single space in the source code, according to the language rules. - -.verb - txr> s - stopped at line 3 of navytime.txr - form: ("HTML" #/ +/ "PUBLIC" #/ +/ "\e"-//W3C//DTD" #/ +/ "HTML" #/ +/ - "3.2" #/ +/ "Final\e"//EN>") - depth: 4 - data (1:10): - "<!DOCTYPE " . "HTML PUBLIC \e"-//W3C//DTD HTML 3.2 Final\e"//EN>" -.brev - -Now, the regular expression has matched and moved the position past -the space; the facing input is now -.strn "HTML ..." . - -The programmer then repeats the -.code s -command by hitting Enter. - -.verb - txr> - stopped at line 3 of navytime.txr - form: (#/ +/ "PUBLIC" #/ +/ "\e"-//W3C//DTD" #/ +/ "HTML" #/ +/ "3.2" - #/ +/ "Final\e"//EN>") - depth: 4 - data (1:14): - "<!DOCTYPE HTML" . " PUBLIC \e"-//W3C//DTD HTML 3.2 Final\e"//EN>" - txr> - stopped at line 3 of navytime.txr - form: ("PUBLIC" #/ +/ "\e"-//W3C//DTD" #/ +/ "HTML" #/ +/ "3.2" #/ +/ - "Final\e"//EN>") - depth: 4 - data (1:15): - "<!DOCTYPE HTML " . "PUBLIC \e"-//W3C//DTD HTML 3.2 Final\e"//EN>" - txr> - stopped at line 3 of navytime.txr - form: (#/ +/ "\e"-//W3C//DTD" #/ +/ "HTML" #/ +/ "3.2" #/ +/ - "Final\e"//EN>") - depth: 4 - data (1:21): - "<!DOCTYPE HTML PUBLIC" . " \e"-//W3C//DTD HTML 3.2 Final\e"//EN>" - txr> - stopped at line 3 of navytime.txr - form: ("\e"-//W3C//DTD" #/ +/ "HTML" #/ +/ "3.2" #/ +/ "Final\e"//EN>") - depth: 4 - data (1:22): - "<!DOCTYPE HTML PUBLIC " . "\e"-//W3C//DTD HTML 3.2 Final\e"//EN>" - txr> - stopped at line 3 of navytime.txr - form: (#/ +/ "HTML" #/ +/ "3.2" #/ +/ "Final\e"//EN>") - depth: 4 - data (1:34): - "<!DOCTYPE HTML PUBLIC \e"-//W3C//DTD" . " HTML 3.2 Final\e"//EN>" -.brev - -It is not evident from the session transcript, but during interactive use, -the input context appears to be animated. Whenever the programmer hits -Enter, the new context is printed and the dot appears to advance. - -Eventually the programmer becomes bored and place a breakpoint on line 16, -where the -.code @(output) -block begins, and invokes the -.code c -command to continue the execution: - -.verb - txr> b 16 - txr> c - stopped at line 16 of navytime.txr - form: ((output (((repeat () ((@MO "-" @DD - " " @HH ":" - @MM ":" @SS - " " @PM " " - @TZ)) - () () () () - () ()))))) - depth: 2 - data (16): - "" -.brev - -The programmer issues a -.code v -command to take a look at the variable bindings, -which indicate that the -.code @(collect) -has produced some lists: - -.verb - txr> v - bindings: - 0: ((PM " " " " " " " " " " "PM" "PM") - (TZNAME "Universal Time" "Eastern Time" - "Central Time" "Mountain Time" "Pacific Time" - "Alaska Time" "Hawaii-Aleutian Time") - (TZ "UTC" "AM EDT" "AM CDT" - "AM MDT" "AM PDT" "AKDT" "HAST") - (SS "03" "03" "03" "03" "03" "03" "03") - (MM "09" "09" "09" "09" "09" "09" "09") - (HH "07" "03" "02" "01" "12" "11" "09") - (DD "07" "07" "07" "07" "07" "06" "06") - (MO "Apr" "Apr" "Apr" "Apr" "Apr" "Apr" "Apr")) -.brev - -Then the continue command -.code c -is isued twice, which finishes the program, whose output appears: - -.verb - txr> c - stopped at line 16 of navytime.txr - form: ((output (((repeat () ((@MO "-" @DD - " " @HH ":" - @MM ":" @SS - " " @PM " " - @TZ)) - () () () () - () ()))))) - depth: 3 - data (nil): - nil - txr> c - Apr-07 07:09:03 UTC - Apr-07 03:09:03 AM EDT - Apr-07 02:09:03 AM CDT - Apr-07 01:09:03 AM MDT - Apr-07 12:09:03 AM PDT - Apr-06 11:09:03 PM AKDT - Apr-06 09:09:03 PM HAST -.brev +\*(TX had a simple, crude, built-in debugger, which was removed. .SH* COMPATIBILITY @@ -256,23 +256,6 @@ void uw_push_guard(uw_frame_t *fr, int uw_ok) uw_stack = fr; } -void uw_push_debug(uw_frame_t *fr, val func, struct args *args, - val ub_p_a_pairs, val env, val data, - val line, val chr) -{ - memset(fr, 0, sizeof *fr); - fr->db.type = UW_DBG; - fr->db.func = func; - fr->db.args = args; - fr->db.ub_p_a_pairs = ub_p_a_pairs; - fr->db.env = env; - fr->db.data = data; - fr->db.line = line; - fr->db.chr = chr; - fr->db.up = uw_stack; - uw_stack = fr; -} - void uw_pop_frame(uw_frame_t *fr) { assert (fr == uw_stack); @@ -28,7 +28,7 @@ typedef union uw_frame uw_frame_t; typedef enum uw_frtype { UW_BLOCK, UW_CAPTURED_BLOCK, UW_MENV, UW_CATCH, UW_HANDLE, - UW_CONT_COPY, UW_GUARD, UW_DBG + UW_CONT_COPY, UW_GUARD } uw_frtype_t; struct uw_common { @@ -87,18 +87,6 @@ struct uw_guard { int uw_ok; }; -struct uw_debug { - uw_frame_t *up; - uw_frtype_t type; - val func; - struct args *args; - val ub_p_a_pairs; - val env; - val data; - val line; - val chr; -}; - #if __aarch64__ #define UW_FRAME_ALIGN __attribute__ ((aligned (16))) #else @@ -113,7 +101,6 @@ union uw_frame { struct uw_handler ha; struct uw_cont_copy cp; struct uw_guard gu; - struct uw_debug db; } UW_FRAME_ALIGN; void uw_push_block(uw_frame_t *, val tag); @@ -147,9 +134,6 @@ val uw_register_subtype(val sub, val super); val uw_exception_subtype_p(val sub, val sup); void uw_continue(uw_frame_t *target); void uw_push_guard(uw_frame_t *, int uw_ok); -void uw_push_debug(uw_frame_t *, val func, struct args *, - val ub_p_a_pairs, val env, val data, - val line, val chr); void uw_pop_frame(uw_frame_t *); void uw_pop_block(uw_frame_t *, val *pret); void uw_pop_until(uw_frame_t *); |