I've written a library of sorts which contains useful routines such as:

_absi - absolute value of I0
_absn - absolute value of I0
_chomp - chomp a string (S0) with a trailing newline
_chr - create a string (S0) with the ascii value of I0
_exit - terminate with a return code of I0
_hex - return in I0 the decimal value of the hex string in S0
_index - return the index (in I0) of S1 in S0 starting with I0
_lc - lowercase S0
_lcfirst - lowercase the first character in S0
_ord - return (in I0) the ascii value of the first character in S0
_reverse - reverse the string in S0
_rindex - do a reverse index of S1 in S0, returing the value in I0
_tr - transliterate S0 with S1 as the source and S2 as the dest
_uc - uppercase S0
_ucfirst - uppercase the first char in S0

Here's an example which would uppercase only the last character of a
string:

        set     S0,"Hello world"
        bsr     _lc
        bsr     _reverse
        bsr     _ucfirst
        bsr     _reverse
        print   "This should have only the 'd' uppercase: "
        print   S0
        print   "\n"


Do you think this library (called "utils.pasm") should be included in
the examples directory?

Brian
#
# utils.pasm
#
# Copyright (C) 2001 Yet Another Society. All rights reserved.
# This program is free software. It is subject to the same
# license as The Parrot Interpreter.
#
# $Id$
#
# This contains a bunch of routines which can be used in other programs by
# adding a line like this:
#
#  include "utils.pasm"
#
# Unfortunately, since we don't have real libraries, you get the whole thing
# whether you want it or not, but its a start.
#
#
# The calling convention is register based, and starts with I0 for the first
# integer argument, S0 for the first string argument, etc.  Return value(s)
# are placed in register 0 of whatever type is being returned.

# _absi - the absolute value of I0
_absi:  gt      I0,0,$done
        mul     I0,I0,-1
$done:  ret

        
# _absn - the absolute value of N0
_absn:  gt      N0,0,$done
        mul     N0,N0,-1.0
$done:  ret


# _chomp - remove the last character of S0, if it is a newline
_chomp: clones
        pushi
        length  I0,S0
        dec     I0
        substr  S1,S0,I0,1
        ne      S1,"\n",$done   
        substr  S0,S0,0,I0
$done:  save    S0
        popi
        pops
        restore S0
        ret


# _chr - return the character S0 for the argument I0
_chr:   clonei
        pushs
        set     S0,""
        set     
S1,"\x0\x1\x2\x3\x4\x5\x6\x7\x8\x9\xA\xB\xC\xD\xE\xF\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xD\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF"
        substr  S0,S1,I0,1
        save    S0
        pops
        popi
        restore S0
        ret


# _exit - exit the program, indicating the status of I0
_exit:
        print   "Program terminated with result code "
        print   I0
        print   "\n"
        end


# _hex - return the decimal value of the hex argument S0
_hex:   clones
        pushi
        bsr     _reverse
        bsr     _uc
        length  I28,S0
        set     S2,S0
        set     I29,0
        set     I30,0
        set     I31,1
        set     S0,"0123456789ABCDEF"
        set     S1,""
$loop:  substr  S1,S2,I30,1
        bsr     _index
        mul     I0,I0,I31
        add     I29,I29,I0
        inc     I30
        mul     I31,I31,16
        lt      I30,I28,$loop
        save    I29
        popi
        pops
        restore I0
        ret

# _index - return the index of the substring S1 in the string S0, starting
#          with position I0.  -1 is returned if it is not found
_index: clones
        clonei
        set     S2,""
        length  I31,S1
        length  I30,S0
$loop:  substr  S2,S0,I0,I31
        eq      S2,S1,$done
        inc     I0
        lt      I0,I30,$loop
        set     I0,-1
$done:  save    I0
        popi
        pops
        restore I0
        ret


# _lc - lowercase the string S0
_lc:    clones
        set     S2,"abcdefghijklmnopqrstuvwxyz"
        set     S1,"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        bsr     _tr
        save    S0
        pops
        restore S0
        ret


# _lcfirst - lowercase the first character of S0
_lcfirst:
        clones
        pushi
        set     S30,S0
        length  I0,S30  
        dec     I0
        substr  S1,S30,1,I0
        substr  S0,S30,0,1
        bsr     _lc
        concat  S0,S1
        save    S0
        popi
        pops
        restore S0
        ret


# _ord - return the numeric value of the first character of string S0
_ord:   clones
        pushi
        set     S1,""
        substr  S1,S0,0,1
        set     
S0,"\x0\x1\x2\x3\x4\x5\x6\x7\x8\x9\xA\xB\xC\xD\xE\xF\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xD\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF"
        bsr     _index
        save    I0
        popi
        pops
        restore I0
        ret

# _reverse - reverse the string in S0
_reverse:
        clones
        pushi
        set     S1,""
        set     S2,""
        length  I0,S0
        dec     I0
$loop:  substr  S2,S0,I0,1
        concat  S1,S2
        dec     I0
        ge      I0,0,$loop
        save    S1
        popi
        pops
        restore S0
        ret


# _rindex - return the index of the substring S1 in the string S0, from the
#           end of the string.  -1 is returned if it is not found
_rindex:
        clones
        pushi
        length  I20,S0
        length  I21,S1
        sub     I20,I20,I21
        dec     I20
$loop:  substr  S2,S0,I20,I21
        eq      S2,S1,$done     
        dec     I20
        ge      I20,0,$loop
        set     I20,-1
$done:  save    I20
        popi
        pops
        restore I0
        ret

# _tr - transliterate the string S0 using S1 as the source and S2 as the dest
_tr:    clones
        pushi
        set     S20,S0
        length  I20,S0
        set     S21,S1
        set     S22,S2
        set     S3,""
        set     I1,0
$loop:  substr  S1,S20,I1,1
        set     S0,S21
        set     I0,0
        bsr     _index
        eq      I0,-1,$nope
        substr  S1,S22,I0,1
$nope:  concat  S3,S1
        inc     I1
        lt      I1,I20,$loop
        save    S3
        popi
        pops
        restore S0
        ret


# _uc - uppercase the string S0
_uc:    clones
        set     S1,"abcdefghijklmnopqrstuvwxyz"
        set     S2,"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        bsr     _tr
        save    S0
        pops
        restore S0
        ret


# _ucfirst - uppercase the first character of S0
_ucfirst:
        clones
        pushi
        set     S30,S0
        length  I0,S30  
        dec     I0
        substr  S1,S30,1,I0
        substr  S0,S30,0,1
        bsr     _uc
        concat  S0,S1
        save    S0
        popi
        pops
        restore S0
        ret


# an example program which runs through the utils.pasm library functions.

        set     I0,-1
        bsr     _absi
        print   "I0="
        print   I0
        print   "\n"

        set     N0,-1.0
        bsr     _absn
        print   "N0="
        print   N0
        print   "\n"

        set     S0,"Hello world"
        set     S1,"ll"
        set     I0,0
        bsr     _index
        print   "I0="
        print   I0
        print   "\n"

        set     S0,"Hello World"
        bsr     _reverse
        print   "S0="
        print   S0
        print   "\n"


        set     S0,"Hello World"
        bsr     _uc
        print   "S0="
        print   S0
        print   "\n"


        set     S0,"hello world"
        bsr     _ucfirst
        print   "S0="
        print   S0
        print   "\n"

        set     S0,"hello world"
        bsr     _chomp
        print   "S0="
        print   S0
        print   "\n"

        set     S0,"hello world\n"
        bsr     _chomp
        print   "S0="
        print   S0
        print   "\n"


        set     S0,"fe"
        bsr     _hex
        print   "I0="
        print   I0
        print   "\n"


        set     I0,65
        bsr     _chr
        print   "S0="
        print   S0
        print   "\n"


        set     S0,"A"
        bsr     _ord
        print   "I0="
        print   I0
        print   "\n"


        set     S0,"Hello hello hello!"
        set     S1,"hello"
        bsr     _rindex
        print   "I0="
        print   I0
        print   "\n"

        set     I0,0
        bsr     _exit


include "utils.pasm"

Reply via email to