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