1 module zua.vm.std..string; 2 import zua.vm.engine; 3 import zua.vm.reflection; 4 import std.algorithm.mutation; 5 import std.typecons; 6 import std.variant; 7 import std.conv; 8 9 private ubyte[] lstring_byte(string s, Nullable!long ni, Nullable!long nj) { 10 long i = ni.isNull ? 1 : ni.get; 11 long j = nj.isNull ? i : nj.get; 12 13 if (i < 0) i += s.length; else i--; 14 if (j < 0) j += s.length; else j--; 15 16 if (i > j) return []; 17 18 if (i < 0) i = 0; 19 if (j > s.length) j = s.length - 1; 20 21 return cast(ubyte[]) s[i .. j + 1]; 22 } 23 24 private string lstring_char(long[] args...) { 25 string str; 26 27 foreach (i; 0 .. args.length) { 28 long v = args[i]; 29 if (v < 0 || v > 255) { 30 throw new Exception("bad argument #" ~ (i + 1).to!string ~ " to 'char' (invalid value)"); 31 } 32 str ~= cast(char) v; 33 } 34 35 return str; 36 } 37 38 private size_t lstring_len(string s) { 39 return s.length; 40 } 41 42 private string lstring_lower(string s) { 43 string res; 44 res.reserve(s.length); 45 foreach (c; s) { 46 if (c >= 'A' && c <= 'Z') res ~= c + ('a' - 'A'); 47 else res ~= c; 48 } 49 return res; 50 } 51 52 private string lstring_rep(string s, long n) { 53 if (n < 1) return ""; 54 string res; 55 res.reserve(s.length * n); 56 foreach (i; 0 .. n) { 57 res ~= s; 58 } 59 return res; 60 } 61 62 private string lstring_reverse(string s) { 63 string res; 64 res.reserve(s.length); 65 foreach_reverse (c; s) { 66 res ~= c; 67 } 68 return res; 69 } 70 71 private string lstring_sub(string s, Nullable!long ni, Nullable!long nj) { 72 long i = ni.isNull ? 1 : ni.get; 73 long j = nj.isNull ? i : nj.get; 74 75 if (i < 0) i += s.length; else i--; 76 if (j < 0) j += s.length; else j--; 77 78 if (i > j) return []; 79 80 if (i < 0) i = 0; 81 if (j > s.length) j = s.length - 1; 82 83 return s[i .. j + 1]; 84 } 85 86 private string lstring_upper(string s) { 87 string res; 88 res.reserve(s.length); 89 foreach (c; s) { 90 if (c >= 'a' && c <= 'z') res ~= c - ('a' - 'A'); 91 else res ~= c; 92 } 93 return res; 94 } 95 96 /** Get string library */ 97 Value stringlib() { 98 TableValue res = new TableValue; 99 res.set(Value("byte"), exposeFunction!(lstring_byte, "byte")); 100 res.set(Value("char"), exposeFunction!(lstring_char, "char")); 101 res.set(Value("len"), exposeFunction!(lstring_len, "len")); 102 res.set(Value("lower"), exposeFunction!(lstring_lower, "lower")); 103 res.set(Value("rep"), exposeFunction!(lstring_rep, "rep")); 104 res.set(Value("reverse"), exposeFunction!(lstring_reverse, "reverse")); 105 res.set(Value("sub"), exposeFunction!(lstring_sub, "sub")); 106 res.set(Value("upper"), exposeFunction!(lstring_upper, "upper")); 107 return Value(res); 108 }