############################################################################ # # File: models.icn # # Subject: Procedure to model Icon functions # # Author: Ralph E. Griswold # # Date: May 1, 1993 # ############################################################################ # # This file is in the public domain. # ############################################################################ # # These procedures model built-in Icon functions. Their purpose is # primarily pedagogical. # # See Icon Analyst 11, pp. 5-7. # ############################################################################ procedure tab(i) suspend .&subject[.&pos : &pos <- i] end procedure upto(c, s, i, j) local k if /s := &subject then { # handle defaults /i := &pos } else { s := string(s) | runerr(103, s) /i := 1 } i := integer(i) | runerr(101, i) i := cvpos(i, s) | fail if not(/j := *s + 1) then { j := integer(j) | runerr(101, j) j := cvpos(j, s) | fail if i > j then i :=: j } every k := i to j do if !c == s[k] then suspend k # perform the actual mapping # The following is faster, but not as clear. # # every k := i to j do # if any(c, s[k]) then suspend k fail end procedure map(s1, s2, s3) local i, result static last_s2, last_s3, map_array initial map_array := list(256) s1 := string(s1) | runerr(103, s1) # check types s2 := def_str(s2, string(&ucase)) | runerr(103, s2) # default null values s3 := def_str(s3, string(&lcase)) | runerr(103, s3) if *s2 ~= *s3 then runerr(208) # See if mapping array needs to be rebuilt if (s2 ~=== last_s2) | (s3 ~=== last_s3) then { last_s2 := s2 last_s3 := s3 every i := 1 to 256 do map_array[i] := char(i - 1) every i := 1 to *s2 do map_array[ord(s2[i]) + 1] := s3[i] } result := "" # every result ||:= map_array[ord(!s1) + 1] # do actual mapping every i := 1 to *s1 do # do actual mapping result ||:= map_array[ord(s1[i]) + 1] return result end # Support procedures # Produce the positive equivalent of i with respect to s. procedure cvpos(i, s) if i <= 0 then i +:= *s + 1 if i <= i <= *s + 1 then return i else fail end # Default the null value to a specified string. procedure def_str(s1, s2) if /s1 then return s2 else return string(s1) # may fail end