forked from pixie-lang/pixie
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathstring.py
More file actions
127 lines (108 loc) · 3.87 KB
/
string.py
File metadata and controls
127 lines (108 loc) · 3.87 KB
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
import pixie.vm.rt as rt
from pixie.vm.string import String
from pixie.vm.code import as_var, extend, intern_var, wrap_fn, MultiArityFn
from pixie.vm.object import affirm, runtime_error, Object, Type
import pixie.vm.stdlib as proto
from pixie.vm.keyword import keyword
from pixie.vm.numbers import Integer
from rpython.rlib.clibffi import get_libc_name
from rpython.rlib.unicodedata import unicodedb_6_2_0 as unicodedb
import rpython.rlib.rstring as rstring
import os
import pixie.vm.rt as rt
@as_var("pixie.string.internal", "starts-with")
def startswith(a, b):
return rt.wrap(rt.name(a).startswith(rt.name(b)))
@as_var("pixie.string.internal", "ends-with")
def endswith(a, b):
return rt.wrap(rt.name(a).endswith(rt.name(b)))
@as_var("pixie.string.internal", "split")
def split(a, b):
affirm(rt.count(b) > 0, u"separator can't be empty")
v = rt.vector()
for s in rstring.split(rt.name(a), rt.name(b)):
v = rt.conj(v, rt.wrap(s))
return v
def index_of2(a, sep):
return rt.wrap(rt.name(a).find(rt.name(sep)))
def index_of3(a, sep, start):
affirm(isinstance(start, Integer), u"Third argument must be an integer")
start = start.int_val()
if start >= 0:
return rt.wrap(rt.name(a).find(rt.name(sep), start))
else:
runtime_error(u"Third argument must be a non-negative integer")
def index_of4(a, sep, start, end):
affirm(isinstance(start, Integer) and isinstance(end, Integer), u"Third and fourth argument must be integers")
start = start.int_val()
end = end.int_val()
if start >= 0 and end >= 0:
return rt.wrap(rt.name(a).find(rt.name(sep), start, end))
else:
runtime_error(u"Third and fourth argument must be non-negative integers")
index_of = intern_var(u"pixie.string.internal", u"index-of")
index_of.set_root(MultiArityFn({2: wrap_fn(index_of2), 3: wrap_fn(index_of3), 4: wrap_fn(index_of4)},
required_arity = 2))
def substring2(a, start):
return substring3(a, start, rt._count(a))
def substring3(a, start, end):
affirm(isinstance(a, String), u"First argument must be a string")
affirm(isinstance(start, Integer) and isinstance(end, Integer), u"Second and third argument must be integers")
start = start.int_val()
end = end.int_val()
if start >= 0 and end >= 0:
return rt.wrap(rt.name(a)[start:end])
else:
runtime_error(u"Second and third argument must be non-negative integers")
substring = intern_var(u"pixie.string.internal", u"substring")
substring.set_root(MultiArityFn({2: wrap_fn(substring2), 3: wrap_fn(substring3)},
required_arity = 2))
@as_var("pixie.string.internal", "upper-case")
def upper_case(a):
a = rt.name(a)
res = ""
for ch in a:
res += chr(unicodedb.toupper(ord(ch)))
return rt.wrap(res)
@as_var("pixie.string.internal", "lower-case")
def lower_case(a):
a = rt.name(a)
res = ""
for ch in a:
res += chr(unicodedb.tolower(ord(ch)))
return rt.wrap(res)
@as_var("pixie.string.internal", "capitalize")
def capitalize(a):
a = rt.name(a)
res = u""
res += unichr(unicodedb.toupper(ord(a[0])))
res += a[1:]
return rt.wrap(res)
@as_var("pixie.string.internal", "trim")
def trim(a):
a = rt.name(a)
i = 0
while i < len(a) and unicodedb.isspace(ord(a[i])):
i += 1
j = len(a)
while j > 0 and unicodedb.isspace(ord(a[j - 1])):
j -= 1
if j <= i:
return rt.wrap(u"")
return rt.wrap(a[i:j])
@as_var("pixie.string.internal", "triml")
def triml(a):
a = rt.name(a)
i = 0
while i < len(a) and unicodedb.isspace(ord(a[i])):
i += 1
return rt.wrap(a[i:len(a)])
@as_var("pixie.string.internal", "trimr")
def trimr(a):
a = rt.name(a)
j = len(a)
while j > 0 and unicodedb.isspace(ord(a[j - 1])):
j -= 1
if j <= 0:
return rt.wrap(u"")
return rt.wrap(a[0:j])