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"