-
Notifications
You must be signed in to change notification settings - Fork 2
/
str.cpp
150 lines (126 loc) · 3.93 KB
/
str.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#include <algorithm>
#include "str.h"
#include "int.h"
#include "bool.h"
#include "assert.h"
value make$str(const char *v) {
value ret;
ret.type = value::STR;
ret.strval = new str_t(v);
return ret;
}
value __getitem__$str$(value self, value k) {
assert(self.type == value::STR);
switch (k.type) {
case value::INT:
return __getitem__$str$int_(self, k);
case value::SLICE:
return __getitem__$str$slice(self, k);
}
throw std::runtime_error("Illegal argument type for str::__getitem__");
}
value __getitem__$str$int_(value self, value k) {
value val;
val.type = value::STR;
val.strval = new str_t(1, self.strval->at(k.intval));
return val;
}
value __getitem__$str$slice(value self, value k) {
long start = k.sliceval->start;
long stop = k.sliceval->stop;
long step = k.sliceval->step;
if (start < 0)
start = (long)self.strval->size() + start;
if (stop < 0)
stop = (long)self.strval->size() + stop;
str_t *ret = new str_t();
if (step > 0) {
start = std::max(0L, start);
stop = std::min((long)self.strval->size(), stop);
for (long i = start; i < stop; i += step) {
ret->push_back(self.strval->at(i));
}
} else {
start = std::min((long)self.strval->size() - 1L, start);
stop = std::max(-1L, stop);
for (long i = start; i > stop; i += step) {
ret->push_back(self.strval->at(i));
}
}
value val;
val.type = value::STR;
val.strval = ret;
return val;
}
value __len__$str(value self) {
assert(self.type == value::STR);
return make$int_(self.strval->size());
}
value __add__$str$str(value x, value y) {
assert(x.type == value::STR && y.type == value::STR);
str_t *merged = new str_t();
merged->reserve(x.strval->size() + y.strval->size());
merged->insert(merged->end(), x.strval->begin(), x.strval->end());
merged->insert(merged->end(), y.strval->begin(), y.strval->end());
value ret;
ret.type = value::STR;
ret.strval = merged;
return ret;
}
value __mul__$str$bool_(value self, value n) {
assert(self.type == value::STR && n.type == value::BOOL);
return __mul__$str$int_(self, __int__$bool_(n));
}
value __mul__$bool_$str(value n, value self) {
assert(self.type == value::STR && n.type == value::BOOL);
return __mul__$int_$str(__int__$bool_(n), self);
}
value __mul__$int_$str(value n, value self) {
assert(self.type == value::STR && n.type == value::INT);
return __mul__$str$int_(self, n);
}
value __mul__$str$int_(value self, value n) {
assert(self.type == value::STR && n.type == value::INT);
str_t *duped = new str_t();
if (n.intval > 0) {
duped->reserve(self.strval->size() * n.intval);
for (long i = 0; i < n.intval; i++)
duped->insert(duped->end(), self.strval->begin(), self.strval->end());
}
value ret;
ret.type = value::STR;
ret.strval = duped;
return ret;
}
value __eq__$str$str(value x, value y) {
assert(x.type == value::STR && y.type == value::STR);
return make$bool_(*x.strval == *y.strval);
}
value __ne__$str$str(value x, value y) {
assert(x.type == value::STR && y.type == value::STR);
return make$bool_(*x.strval != *y.strval);
}
value __lt__$str$str(value x, value y) {
assert(x.type == value::STR && y.type == value::STR);
return make$bool_(*x.strval < *y.strval);
}
value __le__$str$str(value x, value y) {
assert(x.type == value::STR && y.type == value::STR);
return make$bool_(*x.strval <= *y.strval);
}
value __ge__$str$str(value x, value y) {
assert(x.type == value::STR && y.type == value::STR);
return make$bool_(*x.strval >= *y.strval);
}
value __gt__$str$str(value x, value y) {
assert(x.type == value::STR && y.type == value::STR);
return make$bool_(*x.strval > *y.strval);
}
value __contains__$str$str(value self, value sub) {
assert(self.type == value::STR && sub.type == value::STR);
return make$bool_(self.strval->find(*sub.strval) != std::string::npos);
}
value __bool__$str(value self) {
assert(self.type == value::STR);
return make$bool_(!self.strval->empty());
}