1 #include "lib9.h" 2 #include "isa.h" 3 #include "interp.h" 4 #include "raise.h" 5 #include "pool.h" 6 7 #define OP(fn) void fn(void) 8 #define B(r) *((BYTE*)(R.r)) 9 #define W(r) *((WORD*)(R.r)) 10 #define F(r) *((REAL*)(R.r)) 11 #define V(r) *((LONG*)(R.r)) 12 #define S(r) *((String**)(R.r)) 13 #define A(r) *((Array**)(R.r)) 14 #define L(r) *((List**)(R.r)) 15 #define P(r) *((WORD**)(R.r)) 16 #define C(r) *((Channel**)(R.r)) 17 #define T(r) *((void**)(R.r)) 18 19 OP(indc) 20 { 21 int l; 22 ulong v; 23 String *ss; 24 25 v = W(m); 26 ss = S(s); 27 28 if(ss == H) 29 error(exNilref); 30 31 l = ss->len; 32 if(l < 0) { 33 if(v >= -l) 34 e: error(exBounds); 35 l = ss->Srune[v]; 36 } 37 else { 38 if(v >= l) 39 goto e; 40 l = ss->Sascii[v]; 41 } 42 W(d) = l; 43 } 44 45 OP(insc) 46 { 47 ulong v; 48 int l, r, expand; 49 String *ss, *ns, **sp; 50 51 r = W(s); 52 v = W(m); 53 ss = S(d); 54 55 expand = r >= Runeself; 56 57 if(ss == H) { 58 ss = newstring(0); 59 if(expand) { 60 l = 0; 61 ss->max /= sizeof(Rune); 62 goto r; 63 } 64 } 65 else 66 if(D2H(ss)->ref > 1 || (expand && ss->len > 0)) 67 ss = splitc(R.d, expand); 68 69 l = ss->len; 70 if(l < 0 || expand) { 71 l = -l; 72 r: 73 if(v < l) 74 ss->Srune[v] = r; 75 else 76 if(v == l && v < ss->max) { 77 ss->len = -(v+1); 78 ss->Srune[v] = r; 79 } 80 else { 81 if(v != l) 82 error(exBounds); 83 ns = newstring((v + 1 + v/4)*sizeof(Rune)); 84 memmove(ns->Srune, ss->Srune, -ss->len*sizeof(Rune)); 85 ns->Srune[v] = r; 86 ns->len = -(v+1); 87 ns->max /= sizeof(Rune); 88 ss = ns; 89 } 90 } 91 else { 92 if(v < l) 93 ss->Sascii[v] = r; 94 else 95 if(v == l && v < ss->max) { 96 ss->len = v+1; 97 ss->Sascii[v] = r; 98 } 99 else { 100 if(v != l) 101 error(exBounds); 102 ns = newstring(v + 1 + v/4); 103 memmove(ns->Sascii, ss->Sascii, l); 104 ns->Sascii[v] = r; 105 ns->len = v+1; 106 ss = ns; 107 } 108 } 109 if(ss != S(d)) { 110 sp = R.d; 111 destroy(*sp); 112 *sp = ss; 113 } 114 } 115 116 String* 117 slicer(ulong start, ulong v, String *ds) 118 { 119 String *ns; 120 int l, nc; 121 122 if(ds == H) { 123 if(start == 0 && v == 0) 124 return H; 125 126 error(exBounds); 127 } 128 129 nc = v - start; 130 if(ds->len < 0) { 131 l = -ds->len; 132 if(v < start || v > l) 133 error(exBounds); 134 ns = newrunes(nc); 135 memmove(ns->Srune, &ds->Srune[start], nc*sizeof(Rune)); 136 } 137 else { 138 l = ds->len; 139 if(v < start || v > l) 140 error(exBounds); 141 ns = newstring(nc); 142 memmove(ns->Sascii, &ds->Sascii[start], nc); 143 } 144 145 return ns; 146 } 147 148 OP(slicec) 149 { 150 String *ns, **sp; 151 152 ns = slicer(W(s), W(m), S(d)); 153 sp = R.d; 154 destroy(*sp); 155 *sp = ns; 156 } 157 158 void 159 cvtup(Rune *r, String *s) 160 { 161 uchar *bp, *ep; 162 163 bp = (uchar*)s->Sascii; 164 ep = bp + s->len; 165 while(bp < ep) 166 *r++ = *bp++; 167 } 168 169 String* 170 addstring(String *s1, String *s2, int append) 171 { 172 Rune *r; 173 String *ns; 174 int l, l1, l2; 175 176 if(s1 == H) { 177 if(s2 == H) 178 return H; 179 return stringdup(s2); 180 } 181 if(D2H(s1)->ref > 1) 182 append = 0; 183 if(s2 == H) { 184 if(append) 185 return s1; 186 return stringdup(s1); 187 } 188 189 if(s1->len < 0) { 190 l1 = -s1->len; 191 if(s2->len < 0) 192 l = l1 - s2->len; 193 else 194 l = l1 + s2->len; 195 if(append && l <= s1->max) 196 ns = s1; 197 else { 198 ns = newrunes(append? (l+l/4): l); 199 memmove(ns->Srune, s1->Srune, l1*sizeof(Rune)); 200 } 201 ns->len = -l; 202 r = &ns->Srune[l1]; 203 if(s2->len < 0) 204 memmove(r, s2->Srune, -s2->len*sizeof(Rune)); 205 else 206 cvtup(r, s2); 207 208 return ns; 209 } 210 211 if(s2->len < 0) { 212 l2 = -s2->len; 213 l = s1->len + l2; 214 ns = newrunes(append? (l+l/4): l); 215 ns->len = -l; 216 cvtup(ns->Srune, s1); 217 memmove(&ns->Srune[s1->len], s2->Srune, l2*sizeof(Rune)); 218 return ns; 219 } 220 221 l1 = s1->len; 222 l = l1 + s2->len; 223 if(append && l <= s1->max) 224 ns = s1; 225 else { 226 ns = newstring(append? (l+l/4): l); 227 memmove(ns->Sascii, s1->Sascii, l1); 228 } 229 ns->len = l; 230 memmove(ns->Sascii+l1, s2->Sascii, s2->len); 231 232 return ns; 233 } 234 235 OP(addc) 236 { 237 String *ns, **sp; 238 239 ns = addstring(S(m), S(s), R.m == R.d); 240 241 sp = R.d; 242 if(ns != *sp) { 243 destroy(*sp); 244 *sp = ns; 245 } 246 } 247 248 OP(cvtca) 249 { 250 int l; 251 Rune *r; 252 char *p; 253 String *ss; 254 Array *a, **ap; 255 256 ss = S(s); 257 if(ss == H) { 258 a = mem2array(nil, 0); 259 goto r; 260 } 261 if(ss->len < 0) { 262 l = -ss->len; 263 a = mem2array(nil, runenlen(ss->Srune, l)); 264 p = (char*)a->data; 265 r = ss->Srune; 266 while(l--) 267 p += runetochar(p, r++); 268 goto r; 269 } 270 a = mem2array(ss->Sascii, ss->len); 271 272 r: ap = R.d; 273 destroy(*ap); 274 *ap = a; 275 } 276 277 OP(cvtac) 278 { 279 Array *a; 280 String *ds, **dp; 281 282 ds = H; 283 a = A(s); 284 if(a != H) 285 ds = c2string((char*)a->data, a->len); 286 287 dp = R.d; 288 destroy(*dp); 289 *dp = ds; 290 } 291 292 OP(lenc) 293 { 294 int l; 295 String *ss; 296 297 l = 0; 298 ss = S(s); 299 if(ss != H) { 300 l = ss->len; 301 if(l < 0) 302 l = -l; 303 } 304 W(d) = l; 305 } 306 307 OP(cvtcw) 308 { 309 String *s; 310 311 s = S(s); 312 if(s == H) 313 W(d) = 0; 314 else 315 if(s->len < 0) 316 W(d) = strtol(string2c(s), nil, 10); 317 else { 318 s->Sascii[s->len] = '\0'; 319 W(d) = strtol(s->Sascii, nil, 10); 320 } 321 } 322 323 OP(cvtcf) 324 { 325 String *s; 326 327 s = S(s); 328 if(s == H) 329 F(d) = 0.0; 330 else 331 if(s->len < 0) 332 F(d) = strtod(string2c(s), nil); 333 else { 334 s->Sascii[s->len] = '\0'; 335 F(d) = strtod(s->Sascii, nil); 336 } 337 } 338 339 OP(cvtwc) 340 { 341 String *ds, **dp; 342 343 ds = newstring(16); 344 ds->len = sprint(ds->Sascii, "%d", W(s)); 345 346 dp = R.d; 347 destroy(*dp); 348 *dp = ds; 349 } 350 351 OP(cvtlc) 352 { 353 String *ds, **dp; 354 355 ds = newstring(16); 356 ds->len = sprint(ds->Sascii, "%lld", V(s)); 357 358 dp = R.d; 359 destroy(*dp); 360 *dp = ds; 361 } 362 363 OP(cvtfc) 364 { 365 String *ds, **dp; 366 367 ds = newstring(32); 368 ds->len = sprint(ds->Sascii, "%g", F(s)); 369 dp = R.d; 370 destroy(*dp); 371 *dp = ds; 372 } 373 374 char* 375 string2c(String *s) 376 { 377 char *p; 378 int c, l, nc; 379 Rune *r, *er; 380 381 if(s == H) 382 return ""; 383 384 if(s->len >= 0) { 385 s->Sascii[s->len] = '\0'; 386 return s->Sascii; 387 } 388 389 nc = -s->len; 390 l = (nc * UTFmax) + UTFmax; 391 if(s->tmp == nil || msize(s->tmp) < l) { 392 free(s->tmp); 393 s->tmp = malloc(l); 394 if(s->tmp == nil) 395 error(exNomem); 396 } 397 398 p = s->tmp; 399 r = s->Srune; 400 er = r + nc; 401 while(r < er) { 402 c = *r++; 403 if(c < Runeself) 404 *p++ = c; 405 else 406 p += runetochar(p, r-1); 407 } 408 409 *p = 0; 410 411 return s->tmp; 412 } 413 414 String* 415 c2string(char *cs, int len) 416 { 417 uchar *p; 418 char *ecs; 419 String *s; 420 Rune *r, junk; 421 int c, nc, isrune; 422 423 isrune = 0; 424 ecs = cs+len; 425 p = (uchar*)cs; 426 while(len--) { 427 c = *p++; 428 if(c >= Runeself) { 429 isrune = 1; 430 break; 431 } 432 } 433 434 if(isrune == 0) { 435 nc = ecs - cs; 436 s = newstring(nc); 437 memmove(s->Sascii, cs, nc); 438 return s; 439 } 440 441 p--; 442 nc = p - (uchar*)cs; 443 while(p < (uchar*)ecs) { 444 c = *p; 445 if(c < Runeself) 446 p++; 447 else if(p+UTFmax<=(uchar*)ecs || fullrune((char*)p, (uchar*)ecs-p)) 448 p += chartorune(&junk, (char*)p); 449 else 450 break; 451 nc++; 452 } 453 s = newrunes(nc); 454 r = s->Srune; 455 while(nc--) 456 cs += chartorune(r++, cs); 457 458 return s; 459 } 460 461 String* 462 newstring(int nb) 463 { 464 Heap *h; 465 String *s; 466 467 h = nheap(sizeof(String)+nb); 468 h->t = &Tstring; 469 Tstring.ref++; 470 s = H2D(String*, h); 471 s->tmp = nil; 472 s->len = nb; 473 s->max = hmsize(h) - (sizeof(String)+sizeof(Heap)); 474 return s; 475 } 476 477 String* 478 newrunes(int nr) 479 { 480 Heap *h; 481 String *s; 482 483 if(nr == 0) 484 return newstring(nr); 485 if(nr < 0) 486 nr = -nr; 487 h = nheap(sizeof(String)+nr*sizeof(Rune)); 488 h->t = &Tstring; 489 Tstring.ref++; 490 s = H2D(String*, h); 491 s->tmp = nil; 492 s->len = -nr; 493 s->max = (hmsize(h) - (sizeof(String)+sizeof(Heap)))/sizeof(Rune); 494 return s; 495 } 496 497 String* 498 stringdup(String *s) 499 { 500 String *ns; 501 502 if(s == H) 503 return H; 504 505 if(s->len >= 0) { 506 ns = newstring(s->len); 507 memmove(ns->Sascii, s->Sascii, s->len); 508 return ns; 509 } 510 511 ns = newrunes(-s->len); 512 memmove(ns->Srune, s->Srune,-s->len*sizeof(Rune)); 513 514 return ns; 515 } 516 517 int 518 stringcmp(String *s1, String *s2) 519 { 520 Rune *r1, *r2; 521 char *a1, *a2; 522 int v, n, n1, n2, c1, c2; 523 static String snil = { 0, 0, nil }; 524 525 if(s1 == H) 526 s1 = &snil; 527 if(s2 == H) 528 s2 = &snil; 529 530 if(s1 == s2) 531 return 0; 532 533 v = 0; 534 n1 = s1->len; 535 if(n1 < 0) { 536 n1 = -n1; 537 v |= 1; 538 } 539 n2 = s2->len; 540 if(n2 < 0) { 541 n2 = -n2; 542 v |= 2; 543 } 544 545 n = n1; 546 if(n2 < n) 547 n = n2; 548 549 switch(v) { 550 case 0: /* Ascii Ascii */ 551 n = memcmp(s1->Sascii, s2->Sascii, n); 552 if(n == 0) 553 n = n1 - n2; 554 return n; 555 case 1: /* Rune Ascii */ 556 r1 = s1->Srune; 557 a2 = s2->Sascii; 558 while(n > 0) { 559 c1 = *r1++; 560 c2 = *a2++; 561 if(c1 != c2) 562 goto ne; 563 n--; 564 } 565 break; 566 case 2: /* Ascii Rune */ 567 a1 = s1->Sascii; 568 r2 = s2->Srune; 569 while(n > 0) { 570 c1 = *a1++; 571 c2 = *r2++; 572 if(c1 != c2) 573 goto ne; 574 n--; 575 } 576 break; 577 case 3: /* Rune Rune */ 578 r1 = s1->Srune; 579 r2 = s2->Srune; 580 while(n > 0) { 581 c1 = *r1++; 582 c2 = *r2++; 583 if(c1 != c2) 584 goto ne; 585 n--; 586 } 587 break; 588 } 589 return n1 - n2; 590 591 ne: if(c1 < c2) 592 return -1; 593 return 1; 594 } 595 596 String* 597 splitc(String **s, int expand) 598 { 599 String *ss, *ns; 600 601 ss = *s; 602 if(expand && ss->len > 0) { 603 ns = newrunes(ss->len); 604 cvtup(ns->Srune, ss); 605 } 606 else 607 ns = stringdup(ss); 608 609 destroy(ss); 610 *s = ns; 611 return ns; 612 } 613