Re: seq[a,b,c] as a syntax variant for seq[a][b][c]

new topic     » goto parent     » topic index » view thread      » older message » newer message
ChrisB said...

Thats great. How about an example of how to do it?

I was able to accomplish this with relatively little code by using Regular Expressions. You should be able to turn this into a pre-processor by following the example provided in The User Defined Pre-Processor. Basically, we're looking for anything that looks like a sequence index, splitting it on comma, and then reassembling it back into the normal bracket syntax. This code will process multiple instances of comma-based indexing on a single line (which my first attempt didn't do, and is what requires the start/stop integers). This code makes no attempt to ignore the contents of strings or comments. I'm sure it could be extended to do that if necessary.

include std/regex.e 
include std/sequence.e 
include std/text.e 
 
-- not sure what to call this, just use "syntax" for now 
constant re_syntax = regex:new( `(\[[\w,\s*]+\])` ) 
 
function process_syntax( sequence line ) 
     
    sequence text = "" 
    integer start = 1 
    integer stop  = 0 
     
    -- look for matches on this line (and get 
    -- the string offsets while we're at it) 
    object matches = regex:matches( re_syntax, line, start, STRING_OFFSETS ) 
     
    while sequence( matches ) do 
         
        -- get the matching parts 
        text  = matches[2][1] -- e.g. "[1,2,3]" 
        start = matches[2][2] -- e.g. 13 
        stop  = matches[2][3] -- e.g. 19 
         
        -- trim the brackets and split the indices 
        sequence parts = stdseq:split( text[2..$-1], ',' ) 
         
        -- trim extra spaces off the parts 
        for i = 1 to length( parts ) do 
            parts[i] = text:trim( parts[i] ) 
        end for 
         
        -- assemble the new index and put back the outer brackets 
        sequence temp = '[' & stdseq:join( parts, "][" ) & ']' 
         
        -- put the proper index back into this line 
        line = replace( line, temp, start, stop ) 
         
        -- keep track of the last start index 
        start += length(temp) + 1 
        stop  = 0 
         
        -- look for more matches on this line 
        matches = regex:matches( re_syntax, line, start, STRING_OFFSETS ) 
         
    end while 
     
    return line 
end function 
 

Here is some example code that I used to test.

constant ONE   = 1 
constant TWO   = 2 
constant THREE = 3 
 
sequence seq = { 
    {"ABC","DEF","GHI"}, 
    {"JKL","MNO","PQR"}, 
    {"STU","VWZ","YZ "} 
} 
 
printf( 1, "seq[ 1, 2 ] = \"%s\"\n", {seq[1,2]} ) -- outputs "DEF" 
printf( 1, "seq[ 3, 1 ] = \"%s\"\n", {seq[3,1]} ) -- outputs "STU" 
printf( 1, "seq[3,2,1] = '%s'\n", {seq[3,2,1]} ) -- outputs 'V' 
printf( 1, "seq[ONE,TWO,THREE] = '%s'\n", {seq[ONE,TWO,THREE]} ) -- outputs 'F' 

Hope this helps,

-Greg

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

Search



Quick Links

User menu

Not signed in.

Misc Menu