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 }