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"