vipsi - example scripts
Author: kio@little-bat.de
Keywords: vipsi shell script interpreter programming

# vipsi - shell and script language

## example scripts

### count words

the following example shows a script which will count the words in a file which you pass as command line argument and print a list sorted by number of occurance.

it's an example for using the `@` operator, which takes a text as argument and converts it into a name.

    #!/usr/bin/vipsi

    var argc  = count globals -1
    var zeile = ""

    if argc==1
        zeile = file(globals[1])          // globals[1] is our first command line argument
        if count zeile==0                 // loading file failed
            convert globals[1] to quoted
            log "file ", globals[1], " not found", nl
        then
    then

    if count zeile==0                     // no command line argument given
        log "use: count_words <filename>",nl
        log "try again.",nl
        end
    then

    var word_db  = {}
    var word,a,e = 0

    do
        a = e+1
        do
            while a<=count zeile
            while lowerstr(zeile[a]) == upperstr(zeile[a]) // is_letter()
            a++
        loop

        until a>count zeile

        e = a+1
        do
            while e<=count zeile
            while lowerstr(zeile[e]) != upperstr(zeile[e])
            e++
        loop

        word  = zeile[a to e-1]

        if exists word_db.@word
            word_db.@word += 1
        else
            word_db #= 1
            rename word_db[count word_db] = word
        then
    loop

    log "words total: ", count word_db, nl

    rsort word_db

    var i=0
    do
        while ++i<=count word_db
        put word_db[i], tab, name(word_db[i]), nl
    loop

    end

now, let's walk through the code while i explain it:

    // start the file with a 'hashbang' and tag it as executable,
    // so that you can start it from the command line as any other program:
    #!/usr/bin/vipsi

    // get number of command line arguments which are passed in the list variable globals
    // which stores all global variables. because the definition of variable argc is made before
    // count is evaluated, argc is included in the count and we must subtract it:
    var argc  = count globals -1

    // variable zeile will keep the whole file contents:
    var zeile = ""

    // if exactly 1 argument is passed, we expect it to be the file name.
    // the first variable in globals has index 1.
    // so, let's read the file into variable zeile:
    if argc==1
        zeile = file(globals[1])
        if count zeile==0
            convert globals[1] to quoted
            log "file ", globals[1], " not found", nl
        then
    then

    // wrong number of arguments passed or reading the file failed:
    if count zeile==0
        log "use: count_words <filename>",nl
        log "try again.",nl
        end
    then

    // the list word_db will collect the words.
    // each item will be named with a word and contain the occurance count of the word:
    var word_db  = {}

    // a and e are used to index into the word_db:
    var word,a,e = 0

    // ---- loop over all characters in zeile: ----
    do
        // search start of word:
        a = e+1
        do
            while a<=count zeile
            while lowerstr(zeile[a]) == upperstr(zeile[a])
            a++
        loop

        // reached end of the text?  =>  exit loop
        until a>count zeile

        // search end of word:
        e = a+1
        do
            while e<=count zeile
            while lowerstr(zeile[e]) != upperstr(zeile[e])
            e++
        loop

        // extract word:
        word  = zeile[a to e-1]

        // test, whether there is already an item named word in word_db:
        // operator @ is used to convert the text variable word into a name.
        // e.g. if word=="foo" then word_db.@word is effectively word_db.foo.
        if exists word_db.@word
            // if it already exists then increment count
            word_db.@word += 1
        else
            // else append a new item with initial value 1 (the count)
            word_db #= 1
            // and set it's name to the current word:
            rename word_db[count word_db] = word
        then
    loop

    log "words total: ", count word_db, nl

    // sort the list. i like the most frequent words first, so i use the reverse sort function:
    rsort word_db

    // and print the list, showing word and frequency in pairs:
    var i=0
    do
        while ++i<=count word_db
        put word_db[i], tab, name(word_db[i]), nl
    loop

    end