This is the Python RPN Utility Functions program.
It contains all the required subroutines for running
programs generated by the Python to RPN converter.
Normally you do not need this program because any required utility subroutines are automatically embedded into your RPN. However you can save memory by keeping your generated RPN small, and having it call the subroutines in this program instead. To do so, uncheck the Auto include checkbox on the main Converter page.
Warning: New subroutines are added regularly, so make sure you delete this "PyLIB" program and paste the latest version into your calculator/Free42 regularly.
01 LBL "PyLIB" // PyRPN Support Library of 02 "-Utility Funcs-" 03 RTN // --------------------------- 04 LBL "PErNkey" // Dictionary key not found error. () -> display error & stop. 05 "Dictionary key " 06 ARCL ST X 07 ├" not found" 08 PROMPT 09 RTN 10 LBL "p0Bool" // Util used by comparison ops. (a,b) -> (boolean) - whether flag 00 is set, plus RDNs 11 RDN 12 RDN // params dropped 13 FS? 00 14 1 15 FC? 00 16 0 17 RTN 18 LBL "p1MxIJ" // Set IJ for List. (index) -> () & sets IJ for list access 19 X≥0? 20 GTO 51 21 XEQ "pMxLen" 22 + // add the negative index to length to get the wanted index 23 LBL 51 24 1 25 + // adjust row from 0 based (python) to 1 based (RPN matrix) 26 1 // col (always, in lists) 27 STOIJ 28 RDN 29 RDN 30 RTN 31 LBL "p2Bool" // Convert to booleans. (a,b) -> (bool, bool) 32 XEQ "pBool" 33 X<>Y 34 XEQ "pBool" 35 X<>Y 36 RTN 37 LBL "p2MxIJ" // Set IJ for Dict. (key) -> () - finds key's value and sets IJ accordingly. 38 XEQ "pStoStk" // If flag 02 then auto creates new row. 39 1 // 'from' (search from row 1) 40 XEQ "pMxLen" // 'to' (get num rows in matrix) 41 1 42 + // add 1 cos want 'to' to include last row 43 1 // 'step' 44 XEQ "pISG" 45 STO "pISGvar" 46 RDN 47 1 48 1 49 STOIJ 50 RDN 51 RDN 52 CF 99 // found = False 53 LBL 56 54 ISG "pISGvar" 55 GTO 53 // ok, compare next element 56 GTO 51 // finished ISG search through the matrix row 'keys' (in col 1) 57 LBL 53 58 RCLEL 59 X=Y? // see if element matches 60 GTO 52 // found 61 RDN // else 62 I+ // increment row - could also use ↓ move down one element in the indexed matrix. 63 GTO 56 // keep looking 64 LBL 52 // have found 65 SF 99 66 LBL 51 // finished search 67 FS? 99 // was it found? 68 GTO 51 // perfectly found, nice 69 FC? 02 // if not auto create new row 70 GTO "PErNkey" // error key not found, auto create is off 71 0 // temp value 72 X<>Y // key (y:temp value, x:key) 73 XEQ "LIST+" // this will incidentally set IJ nicely to the 'value' element 74 GTO 52 // done 75 LBL 51 // ok found, nice 76 RCL "pISGvar" 77 IP // index where found y:(row / I) 78 2 // position of value x:(col / J) 79 STOIJ // all set to store or recall something 80 LBL 52 // done 81 XEQ "pRclStk" // recall stack 82 RDN // drop key we were looking for 83 RTN 84 LBL "p2Param" // Reverse params. (a,b) -> (b,a) 85 X<>Y 86 RTN 87 LBL "p3Param" // Reverse params. (a,b,c) -> (c,b,a) 88 X<>Y 89 RDN 90 RDN 91 X<>Y 92 RDN 93 RTN 94 LBL "p4Param" // Reverse params. (a,b,c,d) -> (d,c,b,a) 95 X<>Y 96 RDN 97 RDN 98 X<>Y 99 RTN 100 LBL "pAssert" // Assert. (bool) -> if true, keep going, else stop & display error 101 X≠0? 102 RTN 103 "Assertion Err " 104 ARCL ST X 105 ├" is not True" 106 PROMPT 107 RTN 108 LBL "pBIT" // Test the xth bit of y. (y,x) -> boolean 109 CF 00 110 BIT? 111 SF 00 112 RDN 113 RDN 114 FS? 00 115 1 116 FC? 00 117 0 118 RTN 119 LBL "pBool" // Convert to boolean. (a) -> (bool) 120 CF 00 121 X≠0? 122 SF 00 // is non zero, thus true 123 RDN // drop parameter 124 FS? 00 125 1 126 FC? 00 127 0 128 RTN 129 LBL "pCPX" // Is a complex number? (n) -> boolean 130 CF 00 131 CPX? 132 SF 00 133 RDN 134 FS? 00 135 1 136 FC? 00 137 0 138 RTN 139 LBL "pEQ" // == (y:a, x:b) -> boolean of a == b 140 CF 00 141 X=Y? 142 SF 00 143 XEQ "p0Bool" 144 RTN 145 LBL "pErOutR" // Out of Range error. (to,999) -> display error & stop. 146 RDN 147 "range() limited" 148 ├" to 999: got " 149 ARCL ST X 150 AVIEW 151 STOP 152 RTN 153 LBL "pFS" // Is Flag clear? (flag) -> boolean of flag 154 CF 00 155 FC? IND X 156 SF 00 157 RDN 158 FS? 00 159 1 160 FC? 00 161 0 162 RTN 163 LBL "pFS" // Is Flag set? (flag) -> boolean of flag 164 CF 00 165 FS? IND X 166 SF 00 167 RDN 168 FS? 00 169 1 170 FC? 00 171 0 172 RTN 173 LBL "pGT" // > (y:a, x:b) -> (boolean) of a > b 174 CF 00 175 X<Y? 176 SF 00 // true 177 XEQ "p0Bool" // get bool of flag 00 178 RTN 179 LBL "pGTE" // >= (y:a, x:b) -> (boolean) of a >= b 180 CF 00 181 X≤Y? 182 SF 00 183 XEQ "p0Bool" 184 RTN 185 LBL "pISG" // Prepare ISG (z:from, y:to, x:step) -> (ccccccc.fffii) 186 RCL T 187 STO "pSaveT" 188 RDN 189 CF 99 // neg_case = False 190 CF 98 // have_step = False (other than 1) 191 IP // ensure step is an int 192 1 193 X=Y? 194 SF 98 // have_step = True 195 RDN 196 RCL ST Z 197 IP // ensure from is an int 198 RCL ST Z // stack now: z:step y:from x:to 199 IP // ensure to is an int 200 1 201 - 202 999 // check don't exceed max 'to' value of 999 (ISG ccccccc.fffii) 203 X<Y? 204 XEQ "pErOutR" 205 RDN 206 X<>Y // stack now: z:step y:to-1 x:from 207 RCL ST Z // step 208 - // stack now: z:step y:to-1 x:from-step 209 X>=0? // if from > 0 210 GTO 51 // easy (non negative) 211 ABS // else from = abs(from) 212 SF 99 // neg_case = True 213 LBL 51 214 X<>Y // stack now: z:step y:from x:to 215 1000 216 / 217 + // stack now: y:step x:a.bbb 218 FS?C 98 // if not have_step 219 GTO 52 // skip ahead 220 RCL ST Z // else calculate step for ISG 221 100000 // step = step / 100,000 222 / 223 + // stack now: a.bbbnn 224 LBL 52 225 FS?C 99 // if neg_case 226 +/- 227 RCL "pSaveT" 228 X<>Y 229 RTN // returns ISG number in form a.bbbnn 230 LBL "pLT" // < (y:a, x:b) -> (boolean) of a < b 231 CF 00 232 X>Y? 233 SF 00 234 XEQ "p0Bool" 235 RTN 236 LBL "pLT" // <= (y:a, x:b) -> (boolean) of a <= b 237 CF 00 238 X≥Y? 239 SF 00 240 XEQ "p0Bool" 241 RTN 242 LBL "LIST" // 1D and 2D List Operations. p 176. HP42S programming manual 243 CLMENU 244 "LIST+" 245 KEY 1 XEQ "LIST+" 246 "LIST-" 247 KEY 2 XEQ "LIST-" 248 "CLIST" 249 KEY 6 XEQ "CLIST" 250 MENU 251 STOP 252 GTO "LIST" 253 LBL "LIST+" // LIST+ (x:val) when 1D, (y:val, x:key) when 2D 254 SF 25 // try: (ignore error) 255 XEQ 53 256 FC?C 25 // if was error (flag cleared) 257 GTO 51 // init list then push 258 GROW // else 259 J- // appends row via grow, j-, j+ trick 260 J+ 261 WRAP 262 LBL 54 // push (x[,y]) -> (x[,y]) 263 STOEL // zlist[j] = x 264 FS? 01 // if list 265 GTO 55 // finished 266 J+ // else 267 X<>Y // zlist[j+1] = y 268 STOEL 269 X<>Y 270 LBL 55 // finished (), view zlist 271 VIEW "ZLIST" 272 RTN 273 LBL 51 // Init list 274 1 275 FS? 01 276 1 277 FC? 01 278 2 // stack is (y:1,x:1) if flag 1 279 DIM "ZLIST" // else stack is (y:1,x:2) 280 XEQ 53 // prepare list for access 281 RDN 282 RDN // drop rubbish off the stack 283 GTO 54 // push() 284 LBL "LIST-" // LIST- pop () -> () 285 SF 25 286 XEQ 53 287 FC? 25 288 RTN 289 J- 290 RCLEL 291 FS? 01 292 GTO 52 293 J- 294 RCLEL 295 LBL 52 296 DELR 297 FS?C 25 298 GTO 55 299 LBL "CLIST" // CLIST () -> () 300 CLV "ZLIST" // clear ZLIST from memory 301 RTN 302 LBL 53 // prepare list "ZLIST" for access 303 INDEX "ZLIST" 304 RTN 305 LBL "pMAT" // Is matrix? (n) -> boolean 306 CF 00 307 MAT? 308 SF 00 309 RDN 310 FS? 00 311 1 312 FC? 00 313 0 314 RTN 315 LBL "pMxLen" // Get matrix row length. () -> length of ZLIST 316 SF 25 // try: (ignore error) 317 INDEX "ZLIST" 318 FC?C 25 // if was error (flag cleared) 319 GTO 51 // error, list is empty 320 1 321 1 322 STOIJ 323 RDN 324 RDN 325 I- 326 RCLIJ 327 RDN 328 RTN 329 LBL 51 // list is empty 330 0 331 RTN 332 LBL "pMxPrep" // Prepare Matrix. (matrix) -> () 333 MAT? // if is a matrix 334 GTO 51 // yes 335 XEQ "CLIST" // else empty matrix 336 RDN 337 RTN 338 LBL 51 // yes is a matrix 339 STO "ZLIST" 340 RDN 341 INDEX "ZLIST" 342 RTN 343 LBL "pMxSubm" // Matrix Sub-slice (t:row_from, z:col_from, y:row_to, x:col_to) -> (y:row_size, x:col_size) 344 RDN 345 RDN 346 STO- ST Z 347 RDN 348 STO- ST Z 349 RDN 350 1 351 STO+ ST Y 352 STO+ ST Z 353 RDN 354 RTN 355 LBL "pNEQ" // != (y:a, x:b) -> boolean of a != b 356 CF 00 357 X≠Y? 358 SF 00 359 XEQ "p0Bool" 360 RTN 361 LBL "pNot" // not (a) -> boolean of not a 362 X≠0? 363 SF 00 // is a true value 364 RDN 365 FS? 00 366 0 // False 367 FC? 00 368 1 // True 369 RTN 370 LBL "pREAL" // Is real number? (n) -> boolean 371 CF 00 372 REAL? 373 SF 00 374 RDN 375 FS? 00 376 1 377 FC? 00 378 0 379 RTN 380 LBL "pRclStk" // Recalls the stack. (?,?,?,?) -> (t,z,y,x) & recalls from regs pT, pZ, pY, pX 381 RCL "pT" 382 RCL "pZ" 383 RCL "pY" 384 RCL "pX" 385 RTN 386 LBL "pSTR" // Is string? (n) -> boolean 387 CF 00 388 STR? 389 SF 00 390 RDN 391 FS? 00 392 1 393 FC? 00 394 0 395 RTN 396 LBL "pStoStk" // Saves the stack. (t,z,y,x) -> (t,z,y,x) & saves to regs pT, pZ, pY, pX 397 STO "pX" 398 RDN 399 STO "pY" 400 RDN 401 STO "pZ" 402 RDN 403 STO "pT" 404 RDN 405 RTN
Interested in a modern thermal printer for the Free42 calculator emulator?
Introducing Print42 for Mac and Windows, which echoes your Free42 calculator virtual tape to a fast, modern thermal printer.