[comp.lang.icon] more code; bal like routine

goer@quads.uchicago.edu (Richard L. Goerwitz) (10/05/90)

I had to write this the other day, and it seemed to be something that
would be of general interest.

-Richard


############################################################################
#
#	Name:	 slashbal.icn
#
#	Title:	 Bal() with backslash escaping
#
#	Author:	 Richard L. Goerwitz
#
#	Version: 1.1
#
############################################################################
#
#  I am often frustrated at bal()'s inability to deal elegantly with
#  the common \backslash escaping convention (a way of telling Unix
#  Bourne and C shells, for instance, not to interpret a given
#  character as a "metacharacter").  I recognize that bal()'s generic
#  behavior is a must, and so I wrote slashbal() to fill the gap.
#
#  Slashbal behaves like bal, except that it ignores, for purposes of
#  balancing, any character which is preceded by a backslash.  Note
#  that we are talking about internal backslashes, and not necessarily
#  the backslashes used in Icon string literals.  If you have "\(" in
#  your source code, the string produced will have no backslash.  To
#  get this effect, you would need to write "\\(."
#
#  BUGS:  Note that, like bal() (v8), slashbal() cannot correctly
#  handle cases where c2 and c3 intersect.
#
############################################################################
#
#  Links: none
#
############################################################################

procedure slashbal(c1, c2, c3, s, i, j)

    local allcs, chr, count

    /c1 := &cset
    /c2 := '('
    /c3 := ')'
    allcs := c1 ++ c2 ++ c3 ++ '\\'

    /s := \&subject | stop("slashbal:  No string argument.")
    /i := \&pos | 1
    /j := *s + 1

    count := 0
    s ? {
	while tab(upto(allcs)) do {
	    chr := move(1)
	    if chr == "\\" then {
		chr := move(1) | fail
		if any(c1, chr) & count = 0 then
		    suspend .&pos - 1
	    }
	    else {
		if any(c1, chr) & count = 0 then
		    suspend .&pos - 1
		if any(c2, chr) then
		    count +:= 1
		else if any(c3, chr) then
		    count -:= 1
	    }
	}
    }

end