(Break.JaM.. ) .print

(/breakdepth) (Returns level of nesting inside break points) (
	(:breakdepth) .lvknown (:breakdepth) .cvx 0 .ifelse ) /xdef

(/breakexpr) (Returns current break expression if any) (
	(:breakexpr) .lvknown (:breakexpr) .cvx (()) .cvx .ifelse) /xdef

(/breakname) (Returns current break name if any) (
	(:breakname) .lvknown (:breakname) .cvx (()) .cvx .ifelse) /xdef

(/breakcoms) (Returns current break commands if any) (
	(:breakcoms) .lvknown (:breakcoms) .cvx (()) .cvx .ifelse) /xdef

(/breaktest) (Returns current break test if any) (
	(:breaktest) .lvknown (:breaktest) .cvx (()) .cvx .ifelse) /xdef

(/breakpoint) (Break routine that interacts with the user)
	(
	(:breakdepth) /breakdepth 1 .add .lv
	(:breakevaled) .false .lv
	(:breakexpr) .exch .lv
	(:breakcoms) .exch .lv
	(:breaktest) .exch .lv
	(:breakname) .exch .lv
	
	:breaktest .cvx .exec (
		:breakname (.interrupt) .eq
			(( interrupt) =) .cvx
			(( ) .print :breakname .print ( broken) =) .cvx
			.ifelse
		:breakcoms (
			.cvx .exec
			:breakdepth 1 .sub ((	) .print) .cvx .rept
			(>) .print .userline .dup .length 0 .eq (.pop .exit) .cvx .if) .cvx .loop )
		.cvx .if
		
	:breakevaled .not (/brkeval) .cvx .if) /xdef

(/brkgo) (.exit) .cvx .def

(/brkskip) ((:breakevaled) .true .lvstore .exit) .cvx .def

(/brkeval)
	((:breakevaled) .true .lvstore /breakexpr .cvx .exec) .cvx .def

(/!brkeval) (
	(:breakdef) :breakname .load .lv
	:breakname :breakexpr .store
	/brkeval
	:breakname :breakdef .store ) .cvx .def

(/!brkgo) (
	/!brkeval /brkgo) .cvx .def

(/brkwho) (/breakname) .cvx .def

(/unbreak) (
	(
	(:unbrkwho) .exch .cvlit .lv
	:unbrkwho /isbroken .not
		(:unbrkwho .print ( not broken) = .exit)
			.cvx .if
	:unbrkwho .load 3 .aget :unbrkwho .exch .store
	:unbrkwho .print ( unbroken) = .exit) .cvx .loop)
	.cvx .def

(/isbroken) (
	(.load .dup .type (.arraytype) .eq .not (.false .exit) .cvx .if
	.dup .length 5 .eq .not (.false .exit) .cvx .if
	.dup 4 .aget .type (.stringtype) .eq .not (.false .exit) .cvx .if
	.dup 4 .aget (/breakpoint) .eq .not (.false .exit) .cvx .if
	.true .exit) .cvx .loop .exch .pop ) .cvx .def

(/break) (Place a breakpoint.  Expects function name on operand stack, or
	array of name, test, and commands) (
	(.dup .type (.stringtype) .eq (.true ()) .cvx (.aload .pop) .cvx .ifelse
	(:brkcoms) .exch .cvlit .lv
	(:brktest) .exch .cvlit .lv
	(:brkname) .exch .cvlit .lv
	(:brkexpr) :brkname .load .cvlit .lv
	:brkname /isbroken
		(:brkname .print ( already broken) = .exit) .cvx .if
	:brkname [ :brkname :brktest :brkcoms :brkexpr (/breakpoint) .cvx ] .cvx .store
	:brkname .print ( broken) = .exit) .cvx .loop) /xdef

(.interrupt)
	[ (.interrupt) .true () () (/breakpoint) .cvx ] .cvx .def

(/bt) (Prints a back trace of the execution stack) (
	(:stack) .execstk .cvlit .lv
	(:loc) 0 .lv
	:stack .length (
		(:item) :stack :loc .aget .cvlit .lv
		(:typename) :item .type .cvlit .lv
		:typename (.stringtype) .eq
			:typename (.arraytype) .eq .or
			:typename (.inputtype) .eq .or
			(:item ==) .cvx .if
		(:loc) :loc 1 .add .lvstore
		) .cvx .rept ) /xdef

(Done
) .print