Changeset 162
- Timestamp:
- 04/29/07 12:59:13 (2 years ago)
- Files:
-
- trunk/benchmark/binarytrees.md (modified) (3 diffs)
- trunk/benchmark/chameneos.md (modified) (2 diffs)
- trunk/benchmark/cheapconcurrency.md (modified) (1 diff)
- trunk/benchmark/fannkuch.md (modified) (1 diff)
- trunk/benchmark/nsieve.md (modified) (2 diffs)
- trunk/benchmark/nsievebits.md (modified) (3 diffs)
- trunk/benchmark/partialsums.md (modified) (3 diffs)
- trunk/benchmark/pidigits.md (modified) (4 diffs)
- trunk/benchmark/recursive.md (modified) (4 diffs)
- trunk/compile.bat (modified) (2 diffs)
- trunk/imports/test.md (modified) (1 diff)
- trunk/imports/test/fork.md (modified) (1 diff)
- trunk/lzw.md (added)
- trunk/mdcl.d (modified) (2 diffs)
- trunk/mdcl.zip (modified) (previous)
- trunk/minid/arraylib.d (modified) (2 diffs)
- trunk/minid/baselib.d (modified) (12 diffs)
- trunk/minid/compiler.d (modified) (43 diffs)
- trunk/minid/iolib.d (modified) (5 diffs)
- trunk/minid/mathlib.d (modified) (6 diffs)
- trunk/minid/opcodes.d (modified) (3 diffs)
- trunk/minid/oslib.d (modified) (2 diffs)
- trunk/minid/types.d (modified) (10 diffs)
- trunk/minid/utils.d (modified) (1 diff)
- trunk/minid2.txt (modified) (2 diffs)
- trunk/samples/simple.md (modified) (9 diffs)
- trunk/test.d (modified) (1 diff)
- trunk/test.opt (modified) (previous)
- trunk/unlzw.md (added)
- trunk/wc.md (added)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/benchmark/binarytrees.md
r161 r162 3 3 // n = 16, 94.764 sec 4 4 5 localfunction BottomUpTree(item, depth)5 function BottomUpTree(item, depth) 6 6 { 7 7 if(depth > 0) … … 19 19 } 20 20 21 localfunction ItemCheck(tree)21 function ItemCheck(tree) 22 22 { 23 23 if(#tree == 3) … … 53 53 local longlivedtree = BottomUpTree(0, maxdepth); 54 54 55 for( local depth = mindepth; depth <= maxdepth; depth +=2)55 for(depth : mindepth .. maxdepth + 1, 2) 56 56 { 57 57 local iterations = 1 << (maxdepth - depth + mindepth); 58 58 local check = 0; 59 60 for( local i = 1; i <= iterations; ++i)59 60 for(i : 0 .. iterations) 61 61 check += ItemCheck(BottomUpTree(1, depth)) + ItemCheck(BottomUpTree(-1, depth)); 62 62 trunk/benchmark/chameneos.md
r161 r162 61 61 local me = color; 62 62 63 for( local met = 0; met <= 1_000_000_000; met++)63 for(met : 0 .. 1_000_000_001) 64 64 { 65 65 local other = meet(me); … … 103 103 while(true) 104 104 { 105 for( local i = 0; i < numThreads; i++)105 for(i : 0 .. numThreads) 106 106 { 107 107 local thr = threads[i]; trunk/benchmark/cheapconcurrency.md
r161 r162 37 37 local count = 0; 38 38 39 for( local i = 1; i <= n; i++)39 for(i : 0 .. n) 40 40 count += cofunc(); 41 41 trunk/benchmark/fannkuch.md
r117 r162 4 4 // n = 11, 975 sec 5 5 6 localfunction fannkuch(n)6 function fannkuch(n) 7 7 { 8 8 local perm = array.new(n, 0); trunk/benchmark/nsieve.md
r118 r162 1 1 module benchmark.nsieve; 2 2 3 // n = 9, 1 4.772sec3 // n = 9, 13.79 sec 4 4 5 localfunction nsieve(m)5 function nsieve(m) 6 6 { 7 7 local isPrime = array.new(m, true); 8 8 local count = 0; 9 9 10 for( local i = 2; i < m; ++i)10 for(i : 2 .. m) 11 11 { 12 12 if(isPrime[i]) 13 13 { 14 for( local k = i + i; k < m; k +=i)14 for(k : i + i .. m, i) 15 15 isPrime[k] = false; 16 16 … … 34 34 local time = os.microTime(); 35 35 36 for( local i = 0; i < 3; ++i)36 for(i : 0 .. 3) 37 37 { 38 38 local m = 10000 << (n - i); trunk/benchmark/nsievebits.md
r119 r162 1 1 module benchmark.nsievebits; 2 2 3 // n = 11, 1 67.86 sec (crappy)3 // n = 11, 155 sec 4 4 5 5 local BPC = 32; 6 6 7 localfunction primes(n)7 function primes(n) 8 8 { 9 9 local count = 0; 10 local prime = 0;11 10 local size = 10000 << n; 12 11 13 12 local flags = array.new(size / BPC + 1, -1); 14 13 15 for(prime = 2; prime <= size; ++prime)14 for(prime : 2 .. size + 1) 16 15 { 17 16 local offset = prime / BPC; … … 22 21 ++count; 23 22 24 for( local i = prime + prime; i <= size; i +=prime)23 for(i : prime + prime .. size + 1, prime) 25 24 { 26 25 offset = i / BPC; … … 48 47 local time = os.microTime(); 49 48 50 for( local i = 0; i < 3; ++i)49 for(i : 0 .. 3) 51 50 primes(n - i); 52 51 trunk/benchmark/partialsums.md
r120 r162 1 1 module benchmark.partialsums; 2 2 3 // n = 2,500,000, 18.96 sec (no double precision, so results are not correct)3 // n = 2,500,000, 21.74 sec 4 4 5 5 local args = [vararg]; … … 30 30 local pow = math.pow; 31 31 32 for(local k = 1 ; k <= n; ++k)32 for(local k = 1.0; k <= n; k += 1.0) 33 33 { 34 34 local k2 = k * k; … … 36 36 local ck = cos(k); 37 37 local k3 = k2 * k; 38 38 39 39 a1 += pow(2.0 / 3.0, k); 40 40 a2 += 1.0 / sqrt(k); 41 41 a3 += 1.0 / (k2 + k); 42 43 // Flint Hills 42 44 a4 += 1.0 / (k3 * sk * sk); 45 46 // Cookson Hills 43 47 a5 += 1.0 / (k3 * ck * ck); 48 49 // Harmonic 44 50 a6 += 1.0 / k; 51 52 // Riemann zeta 45 53 a7 += 1.0 / k2; 54 55 // Alternating harmonic 46 56 a8 += alt / k; 57 58 // Gregory 47 59 a9 += alt / (k + k - 1); 60 48 61 alt = -alt; 49 62 } trunk/benchmark/pidigits.md
r121 r162 3 3 // Broken, need a bigInt representation 4 4 5 localfunction Next(z)5 function Next(z) 6 6 { 7 return (3 * z[0] + z[1]) / (3 * z[2] + z[3]);7 return (3zz * z[0] + z[1]) / (3 * z[2] + z[3]); 8 8 } 9 9 10 localfunction Safe(z, n)10 function Safe(z, n) 11 11 { 12 12 return n == ((4 * z[0] + z[1]) / (4 * z[2] + z[3])); 13 13 } 14 14 15 localfunction Comp(a, b)15 function Comp(a, b) 16 16 { 17 17 return [a[0] * b[0] + a[1] * b[2], … … 21 21 } 22 22 23 localfunction Prod(z, n)23 function Prod(z, n) 24 24 { 25 25 return Comp([10, -10 * n, 0, 1], z); 26 26 } 27 27 28 localfunction Cons(z, k)28 function Cons(z, k) 29 29 { 30 30 return Comp(z, [k, 4 * k + 2, 0, 2 * k + 1]); 31 31 } 32 32 33 localfunction Digit(k, z, n, Row, Col)33 function Digit(k, z, n, Row, Col) 34 34 { 35 35 if(n > 0) … … 62 62 } 63 63 64 localfunction Digits(n)64 function Digits(n) 65 65 { 66 66 return Digit(1, [1, 0, 0, 1], n, 0, 0); … … 79 79 local time = os.microTime(); 80 80 81 Digits(n);81 Digits(n); 82 82 83 83 time = os.microTime() - time; trunk/benchmark/recursive.md
r122 r162 1 1 module benchmark.recursive; 2 2 3 // n = 11, 345.122 sec (Fib(38.0) output is off by 2, don't have double precision)3 // n = 11, 345.122 sec 4 4 5 localfunction ack(m, n)5 function ack(m, n) 6 6 { 7 7 if(m == 0) … … 14 14 } 15 15 16 localfunction fib(n)16 function fib(n) 17 17 { 18 18 if(n < 2) … … 22 22 } 23 23 24 localfunction tak(x, y, z)24 function tak(x, y, z) 25 25 { 26 26 if(y >= x) … … 42 42 local time = os.microTime(); 43 43 44 writefln("Ack(3, %d): %d", n, ack(3, n));44 //writefln("Ack(3, %d): %d", n, ack(3, n)); 45 45 writefln("Fib(%.1f): %.1f", n + 27.0, fib(n + 27.0)); 46 46 47 47 --n; 48 writefln("Tak(%d, %d, %d): %d", 3 * n, 2 * n, n, tak(3 * n, 2 * n, n));49 writefln("Fib(3): %d", fib(3));50 writefln("Tak(3.0, 2.0, 1.0): %.1f", tak(3.0, 2.0, 1.0));48 //writefln("Tak(%d, %d, %d): %d", 3 * n, 2 * n, n, tak(3 * n, 2 * n, n)); 49 //writefln("Fib(3): %d", fib(3)); 50 //writefln("Tak(3.0, 2.0, 1.0): %.1f", tak(3.0, 2.0, 1.0)); 51 51 52 52 time = os.microTime() - time; trunk/compile.bat
r104 r162 1 1 @echo off 2 3 set BASEFILES=minid\arraylib.d4 set BASEFILES=%BASEFILES% minid\baselib.d5 set BASEFILES=%BASEFILES% minid\charlib.d6 set BASEFILES=%BASEFILES% minid\compiler.d7 set BASEFILES=%BASEFILES% minid\iolib.d8 set BASEFILES=%BASEFILES% minid\mathlib.d9 set BASEFILES=%BASEFILES% minid\minid.d10 set BASEFILES=%BASEFILES% minid\opcodes.d11 set BASEFILES=%BASEFILES% minid\oslib.d12 set BASEFILES=%BASEFILES% minid\regexplib.d13 set BASEFILES=%BASEFILES% minid\stringlib.d14 set BASEFILES=%BASEFILES% minid\tablelib.d15 set BASEFILES=%BASEFILES% minid\types.d16 set BASEFILES=%BASEFILES% minid\utils.d17 2 18 3 rem goto makemdcl … … 20 5 21 6 :maketest 22 set DFLAGS=-debug -g -oftest.exe 23 set DPROG=test 24 set DFILES=%DPROG%.d %BASEFILES% 25 set DLIBS= 26 27 call \dmd\proj\maincompile.bat 7 build @test 28 8 goto end 29 9 30 10 :makemdcl 31 set DFLAGS=-release -ofmdcl.exe 32 set DPROG=mdcl 33 set DFILES=%DPROG%.d %BASEFILES% 34 set DLIBS= 35 36 call \dmd\proj\maincompile.bat 11 build @mdcl 37 12 goto end 38 13 39 14 :makeminidc 40 set DFLAGS=-release -ofminidc.exe 41 set DPROG=minidc 42 set DFILES=%DPROG%.d %BASEFILES% 43 set DLIBS= 44 45 call \dmd\proj\maincompile.bat 15 build @minidc 46 16 goto end 47 17 trunk/imports/test.md
r129 r162 1 1 module test; 2 2 3 global x = 5; 4 5 global function foo() 3 global class A 6 4 { 7 return "foo"; 5 this() 6 { 7 writefln("A ctor"); 8 } 8 9 } 9 10 local function bar()11 {12 return "bar";13 }14 15 global function opCall()16 {17 writefln("BRRING BRRING I HAVE AN IMPORTANT CALL");18 }trunk/imports/test/fork.md
r131 r162 2 2 3 3 global y = 10; 4 5 writefln("FORK!");trunk/mdcl.d
r113 r162 135 135 state.push(arg); 136 136 137 state.call(funcReg, scriptArgs.length + 1, 0); 137 try 138 state.call(funcReg, scriptArgs.length + 1, 0); 139 catch(MDException e) 140 { 141 writefln("Error: ", e); 142 writefln(MDState.getTracebackString()); 143 } 138 144 } 139 145 … … 188 194 catch(MDException e) 189 195 { 190 writefln(e); 196 writefln("Error: ", e); 197 writefln(MDState.getTracebackString()); 191 198 writefln(); 192 199 } trunk/minid/arraylib.d
r146 r162 50 50 "filter"d, new MDClosure(namespace, &filter, "array.filter"), 51 51 "find"d, new MDClosure(namespace, &find, "array.find"), 52 "bsearch"d, new MDClosure(namespace, &bsearch, "array.bsearch") 52 "bsearch"d, new MDClosure(namespace, &bsearch, "array.bsearch"), 53 "pop"d, new MDClosure(namespace, &pop, "array.pop") 53 54 ); 54 55 … … 414 415 return 1; 415 416 } 417 418 int pop(MDState s, uint numParams) 419 { 420 MDArray array = s.getContext!(MDArray); 421 int index = -1; 422 423 if(array.length == 0) 424 s.throwRuntimeException("Array is empty"); 425 426 if(numParams > 0) 427 index = s.getParam!(int)(0); 428 429 if(index < 0) 430 index += array.length; 431 432 if(index < 0 || index >= array.length) 433 s.throwRuntimeException("Invalid array index: ", index); 434 435 s.push(array[index]); 436 437 for(int i = index; i < array.length - 1; i++) 438 array[i] = *array[i + 1]; 439 440 array.length = array.length - 1; 441 442 return 1; 443 } 416 444 } 417 445 trunk/minid/baselib.d
r159 r162 117 117 118 118 case 'e', 'E', 'f', 'F', 'g', 'G', 'a', 'A': 119 float f;119 mdfloat f; 120 120 input.readf(fmt, &f); 121 121 val = f; 122 122 break; 123 123 124 case ' s':124 case 'r', 's': 125 125 char[] v; 126 126 input.readf(fmt, &v); … … 184 184 } 185 185 186 float getFloatParam(int index)186 mdfloat getFloatParam(int index) 187 187 { 188 188 if(index >= params.length) … … 192 192 s.throwRuntimeException("Expected 'float' but got '%s' for parameter ", params[index].typeString(), formatStrIndex); 193 193 194 return params[index].as!( float);194 return params[index].as!(mdfloat); 195 195 } 196 196 … … 326 326 327 327 case 'e', 'E', 'f', 'F', 'g', 'G', 'a', 'A': 328 float val;328 mdfloat val; 329 329 330 330 if(s.isParam!("int")(paramIndex)) … … 340 340 specialFormat(&outputChar, formatting[0 .. formattingLength], val.mData); 341 341 break; 342 343 case 'r': 344 formatting[formattingLength - 1] = 's'; 345 char[] val = getParam(paramIndex).toString(); 346 specialFormat(&outputChar, formatting[0 .. formattingLength], val); 347 break; 342 348 343 349 case 'c': … … 348 354 default: 349 355 // unsupported: %p 350 s.throwRuntimeException("Unsupported format specifier '% c' in parameter ", c, formatStrIndex);356 s.throwRuntimeException("Unsupported format specifier '%s' in parameter ", c, formatStrIndex); 351 357 } 352 358 } … … 433 439 return 1; 434 440 } 441 442 int rawToString(MDState s, uint numParams) 443 { 444 s.push(s.getParam(0u).toString()); 445 return 1; 446 } 435 447 436 448 int getTraceback(MDState s, uint numParams) … … 476 488 477 489 case MDValue.Type.Float: 478 s.push(cast(int)val.as!( float));490 s.push(cast(int)val.as!(mdfloat)); 479 491 break; 480 492 … … 501 513 { 502 514 case MDValue.Type.Bool: 503 s.push(cast( float)val.as!(bool));515 s.push(cast(mdfloat)val.as!(bool)); 504 516 break; 505 517 506 518 case MDValue.Type.Int: 507 s.push(cast( float)val.as!(int));519 s.push(cast(mdfloat)val.as!(int)); 508 520 break; 509 521 510 522 case MDValue.Type.Float: 511 s.push(val.as!( float));523 s.push(val.as!(mdfloat)); 512 524 break; 513 525 514 526 case MDValue.Type.Char: 515 s.push(cast( float)val.as!(dchar));527 s.push(cast(mdfloat)val.as!(dchar)); 516 528 break; 517 529 … … 696 708 return 1; 697 709 } 710 711 MDStringBufferClass stringBufferClass; 712 713 static class MDStringBufferClass : MDClass 714 { 715 public this() 716 { 717 super("StringBuffer", null); 718 719 iteratorClosure = new MDClosure(mMethods, &iterator, "StringBuffer.iterator"); 720 iteratorReverseClosure = new MDClosure(mMethods, &iteratorReverse, "StringBuffer.iteratorReverse"); 721 auto catEq = new MDClosure(mMethods, &opCatAssign, "StringBuffer.opCatAssign"); 722 723 mMethods.addList 724 ( 725 "constructor"d, new MDClosure(mMethods, &constructor, "StringBuffer.constructor"), 726 "append"d, catEq, 727 "opCatAssign"d, catEq, 728 "insert"d, new MDClosure(mMethods, &insert, "StringBuffer.insert"), 729 "remove"d, new MDClosure(mMethods, &remove, "StringBuffer.remove"), 730 "toString"d, new MDClosure(mMethods, &toString, "StringBuffer.toString"), 731 "length"d, new MDClosure(mMethods, &length, "StringBuffer.length"), 732 "opLength"d, new MDClosure(mMethods, &opLength, "StringBuffer.opLength"), 733 "opIndex"d, new MDClosure(mMethods, &opIndex, "StringBuffer.opIndex"), 734 "opIndexAssign"d, new MDClosure(mMethods, &opIndexAssign, "StringBuffer.opIndexAssign"), 735 "opApply"d, new MDClosure(mMethods, &opApply, "StringBuffer.opApply"), 736 "opSlice"d, new MDClosure(mMethods, &opSlice, "StringBuffer.opSlice"), 737 "opSliceAssign"d, new MDClosure(mMethods, &opSliceAssign, "StringBuffer.opSliceAssign"), 738 "reserve"d, new MDClosure(mMethods, &reserve, "StringBuffer.reserve") 739 ); 740 } 741 742 public MDStringBuffer newInstance() 743 { 744 return new MDStringBuffer(this); 745 } 746 747 public int constructor(MDState s, uint numParams) 748 { 749 MDStringBuffer i = s.getContext!(MDStringBuffer); 750 751 if(numParams > 0) 752 { 753 if(s.isParam!("int")(0)) 754 i.constructor(s.getParam!(uint)(0)); 755 else if(s.isParam!("string")(0)) 756 i.constructor(s.getParam!(dchar[])(0)); 757 else 758 s.throwRuntimeException("'int' or 'string' expected for constructor, not '%s'", s.getParam(0u).typeString()); 759 } 760 else 761 i.constructor(); 762 763 return 0; 764 } 765 766 public int opCatAssign(MDState s, uint numParams) 767 { 768 MDStringBuffer i = s.getContext!(MDStringBuffer); 769 770 for(uint j = 0; j < numParams; j++) 771 { 772 MDValue param = s.getParam(j); 773 774 if(param.isObj) 775 { 776 if(param.isInstance) 777 { 778 MDStringBuffer other = cast(MDStringBuffer)param.as!(MDInstance); 779 780 if(other) 781 { 782 i.append(other); 783 return 0; 784 } 785 } 786 787 i.append(s.valueToString(param)); 788 } 789 else 790 i.append(param.toString()); 791 } 792 793 return 0; 794 } 795 796 public int insert(MDState s, uint numparams) 797 { 798 MDStringBuffer i = s.getContext!(MDStringBuffer); 799 MDValue param = s.getParam(1u); 800 801 if(param.isObj) 802 { 803 if(param.isInstance) 804 { 805 MDStringBuffer other = cast(MDStringBuffer)param.as!(MDInstance); 806 807 if(other) 808 { 809 i.insert(s.getParam!(int)(0), other); 810 return 0; 811 } 812 } 813 814 i.insert(s.getParam!(int)(0), s.valueToString(param)); 815 } 816 else 817 i.insert(s.getParam!(int)(0), param.toString()); 818 819 return 0; 820 } 821 822 public int remove(MDState s, uint numParams) 823 { 824 MDStringBuffer i = s.getContext!(MDStringBuffer); 825 uint start = s.getParam!(uint)(0); 826 uint end = start + 1; 827 828 if(numParams > 1) 829 end = s.getParam!(uint)(1); 830 831 i.remove(start, end); 832 return 0; 833 } 834 835 public int toString(MDState s, uint numParams) 836 { 837 s.push(s.getContext!(MDStringBuffer).toMDString()); 838 return 1; 839 } 840 841 public int length(MDState s, uint numParams) 842 { 843 s.getContext!(MDStringBuffer).length = s.getParam!(uint)(0); 844 return 0; 845 } 846 847 public int opLength(MDState s, uint numParams) 848 { 849 s.push(s.getContext!(MDStringBuffer).length); 850 return 1; 851 } 852 853 public int opIndex(MDState s, uint numParams) 854 { 855 s.push(s.getContext!(MDStringBuffer)()[s.getParam!(int)(0)]); 856 return 1; 857 } 858 859 public int opIndexAssign(MDState s, uint numParams) 860 { 861 s.getContext!(MDStringBuffer)()[s.getParam!(int)(0)] = s.getParam!(dchar)(1); 862 return 0; 863 } 864 865 MDClosure iteratorClosure; 866 MDClosure iteratorReverseClosure; 867 868 public int iterator(MDState s, uint numParams) 869 { 870 MDStringBuffer i = s.getContext!(MDStringBuffer); 871 int index = s.getParam!(int)(0); 872 873 index++; 874 875 if(index >= i.length) 876 return 0; 877 878 s.push(index); 879 s.push(i[index]); 880 881 return 2; 882 } 883 884 public int iteratorReverse(MDState s, uint numParams) 885 { 886 MDStringBuffer i = s.getContext!(MDStringBuffer); 887 int index = s.getParam!(int)(0); 888 889 index--; 890 891 if(index < 0) 892 return 0; 893 894 s.push(index); 895 s.push(i[index]); 896 897 return 2; 898 } 899 900 public int opApply(MDState s, uint numParams) 901 { 902 MDStringBuffer i = s.getContext!(MDStringBuffer); 903 904 if(s.isParam!("string")(0) && s.getParam!(MDString)(0) == "reverse"d) 905 { 906 s.push(iteratorReverseClosure); 907 s.push(i); 908 s.push(cast(int)i.length); 909 } 910 else 911 { 912 s.push(iteratorClosure); 913 s.push(i); 914 s.push(-1); 915 } 916 917 return 3; 918 } 919 920 public int opSlice(MDState s, uint numParams) 921 { 922 s.push(s.getContext!(MDStringBuffer)()[s.getParam!(int)(0) .. s.getParam!(int)(1)]); 923 return 1; 924 } 925 926 public int opSliceAssign(MDState s, uint numParams) 927 { 928 s.getContext!(MDStringBuffer)()[s.getParam!(int)(0) .. s.getParam!(int)(1)] = s.getParam!(dchar[])(2); 929 return 0; 930 } 931 932 public int reserve(MDState s, uint numParams) 933 { 934 s.getContext!(MDStringBuffer).reserve(s.getParam!(uint)(0)); 935 return 0; 936 } 937 } 938 939 static class MDStringBuffer : MDInstance 940 { 941 protected dchar[] mBuffer; 942 protected uint mLength = 0; 943 944 public this(MDClass owner) 945 { 946 super(owner); 947 } 948 949 public void constructor() 950 { 951 mBuffer = new dchar[32]; 952 } 953 954 public void constructor(int size) 955 { 956 mBuffer = new dchar[size]; 957 } 958 959 public void constructor(dchar[] data) 960 { 961 mBuffer = data; 962 mLength = mBuffer.length; 963 } 964 965 public void append(MDStringBuffer other) 966 { 967 resize(other.mLength); 968 mBuffer[mLength .. mLength + other.mLength] = other.mBuffer[0 .. other.mLength]; 969 mLength += other.mLength; 970 } 971 972 public void append(MDString str) 973 { 974 resize(str.mData.length); 975 mBuffer[mLength .. mLength + str.mData.length] = str.mData[]; 976 mLength += str.mData.length; 977 } 978 979 public void append(char[] s) 980 { 981 dchar[] str = utf.toUTF32(s); 982 resize(str.length); 983 mBuffer[mLength .. mLength + str.length] = str[]; 984 mLength += str.length; 985 } 986 987 public void insert(int offset, MDStringBuffer other) 988 { 989 if(offset > mLength) 990 throw new MDException("Offset out of bounds: ", offset); 991 992 resize(other.mLength); 993 994 for(int i = mLength + other.mLength - 1, j = mLength - 1; j >= offset; i--, j--) 995 mBuffer[i] = mBuffer[j]; 996 997 mBuffer[offset .. offset + other.mLength] = other.mBuffer[0 .. other.mLength]; 998 mLength += other.mLength; 999 } 1000 1001 public void insert(int offset, MDString str) 1002 { 1003 if(offset > mLength) 1004 throw new MDException("Offset out of bounds: ", offset); 1005 1006 resize(str.mData.length); 1007 1008 for(int i = mLength + str.mData.length - 1, j = mLength - 1; j >= offset; i--, j--) 1009 mBuffer[i] = mBuffer[j]; 1010 1011 mBuffer[offset .. offset + str.mData.length] = str.mData[]; 1012 mLength += str.mData.length; 1013 } 1014 1015 public void insert(int offset, char[] s) 1016 { 1017 if(offset > mLength) 1018 throw new MDException("Offset out of bounds: ", offset); 1019 1020 dchar[] str = utf.toUTF32(s); 1021 resize(str.length); 1022 1023 for(int i = mLength + str.length - 1, j = mLength - 1; j >= offset; i--, j--) 1024 mBuffer[i] = mBuffer[j]; 1025 1026 mBuffer[offset .. offset + str.length] = str[]; 1027 mLength += str.length; 1028 } 1029 1030 public void remove(uint start, uint end) 1031 { 1032 if(end > mLength) 1033 end = mLength; 1034 1035 if(start > mLength || start > end) 1036 throw new MDException("Invalid indices: %d .. %d", start, end); 1037 1038 for(int i = start, j = end; j < mLength; i++, j++) 1039 mBuffer[i] = mBuffer[j]; 1040 1041 mLength -= (end - start); 1042 } 1043 1044 public MDString toMDString() 1045 { 1046 return new MDString(mBuffer[0 .. mLength]); 1047 } 1048 1049 public void length(uint len) 1050 { 1051 uint oldLength = mLength; 1052 mLength = len; 1053 1054 if(mLength > mBuffer.length) 1055 mBuffer.length = mLength; 1056 1057 if(mLength > oldLength) 1058 mBuffer[oldLength .. mLength] = dchar.init; 1059 } 1060 1061 public uint length() 1062 { 1063 return mLength; 1064 } 1065 1066 public dchar opIndex(int index) 1067 { 1068 if(index < 0) 1069 index += mLength; 1070 1071 if(index < 0 || index >= mLength) 1072 throw new MDException("Invalid index: ", index); 1073 1074 return mBuffer[index]; 1075 } 1076 1077 public void opIndexAssign(dchar c, int index) 1078 { 1079 if(index < 0) 1080 index += mLength; 1081 1082 if(index >= mLength) 1083 throw new MDException("Invalid index: ", index); 1084 1085 mBuffer[index] = c; 1086 &nbs
