Re: suggestion sequence section

new topic     » goto parent     » topic index » view thread      » older message » newer message

Carl W. wrote:

> gertie at visionsix.com wrote:
>
> > s = "abcdefgh"
> > x = "1..2"
> > ? s[x]
>
> That's equivalent to ? s[{49,46,46,50}] which other people have
> requested return a sequence containing the 49th, 46th, 46th again and
> 50th elements of s[].
>
> Which interpretation is better? Discuss. :)

I know I'm replying to myself here, but a third interpretation occurred to
me after reading Lucius' response:

String parse (Kat):
       s["1..2"]        --> s[1..2]

Element selection (Lucius):
       s[{49,46,46,50}] --> s[49] & s[46] & s[46] & s[50]

Multidimensional access:
       s[{49,46,46,50}] --> s[49][46][46][50]

_Now_ which is the better interpretation? Aargh!! :)

Here's an (untested) code snippet that tries to roll all three into one:

include get.e -- needed for value()

type intseq(object o) -- sequence of integers
    if atom(o) then return 0 end if -- atom != sequence
    for x = 1 to length(o) do -- this loop is skipped if length is zero
        if not integer o[x] then return 0 end if
    end for
    return 1
end type

type intseqinseq(object o) if sequence(o) and
    length(o) = 1 and
    intseq(o[1])
then return 1 end if return 0 end if end type

function rerange(object i, integer len)
    -- Used to avoid errors with badly ranged subscripts
    if sequence(i)  then return 1
    elsif i < 0     then return len + i + 1
    elsif i = 0     then return 1
    elsif i > len   then return len
    end if               return i
endf if

function si(sequence s, object i)
    -- Usage: si(s, atom)   -- returns s[atom]
    --        si(s, "1..2") -- returns s[1..2]
    --        si(s, {integer, integer...}) where there are no consecutive
46's
                            -- returns s[integer1] & s[integer2] & etc.
    --        si(s, { {integer, integer...} }) -- returns
s[integer1][integer2]...
    object i1, i2
    integer len, ddot

    len = length(s)
    if not len then return {} end if -- can't index nothing!

    if atom(i) then
        return s[rerange(i,len)]
    elsif intseq(i) then
        ddot = match("..", i) -- Kat's "x..y"
        if ddot then
            i1 = value(i[1..ddot-1])   i1 = rerange(i1[1],len)
            i2 = value(i[ddot+2..len]) i2 = rerange(i2[1],len)
            -- swap if bad slice NB: s[n..n-1] is valid so is left alone
            if i2+1 < i1 then ddot = i1 i1 = i2 i2 = ddot end if
            return s[i1..i2]
        end if
        i1 = {} -- Lucius' element selection
        for x = 1 to len do
           i1 = append(i1, s[rerange(i[x],len)])
        end for
        return i1
    elsif intseqinseq(i) then -- Dimension stepping...
        i1 = s
        for x = 1 to len do
           if sequence(i1) then
               i1 = i1[rerange(i[x],length(i1))]
           else
               -- Not enough dimensions!
               return {}
           end if
        end for
        return i1
    else
        -- 'i' is badly formatted!
        return {}
    end if
end function

Carl

--
[ Carl R White == aka () = The Domain of Cyrek = ]
[ Cyrek the Illogical /\ www.cyreksoft.yorks.com ]

new topic     » goto parent     » topic index » view thread      » older message » newer message

Search



Quick Links

User menu

Not signed in.

Misc Menu