Skip to content

Commit fff175c

Browse files
authored
builtin: Implement builtin_ascii (#66)
1 parent bd0985b commit fff175c

File tree

3 files changed

+77
-49
lines changed

3 files changed

+77
-49
lines changed

builtin/builtin.go

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ func init() {
2424
py.MustNewMethod("abs", builtin_abs, 0, abs_doc),
2525
py.MustNewMethod("all", builtin_all, 0, all_doc),
2626
py.MustNewMethod("any", builtin_any, 0, any_doc),
27-
// py.MustNewMethod("ascii", builtin_ascii, 0, ascii_doc),
27+
py.MustNewMethod("ascii", builtin_ascii, 0, ascii_doc),
2828
// py.MustNewMethod("bin", builtin_bin, 0, bin_doc),
2929
// py.MustNewMethod("callable", builtin_callable, 0, callable_doc),
3030
py.MustNewMethod("chr", builtin_chr, 0, chr_doc),
@@ -309,6 +309,19 @@ func builtin_any(self, seq py.Object) (py.Object, error) {
309309
return py.False, nil
310310
}
311311

312+
const ascii_doc = `
313+
`
314+
315+
func builtin_ascii(self, o py.Object) (py.Object, error) {
316+
reprObj, err := py.Repr(o)
317+
if err != nil {
318+
return nil, err
319+
}
320+
repr := reprObj.(py.String)
321+
out := py.StringEscape(repr, true)
322+
return py.String(out), err
323+
}
324+
312325
const round_doc = `round(number[, ndigits]) -> number
313326
314327
Round a number to a given precision in decimal digits (default 0 digits).

builtin/tests/builtin.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@
1919
assert any(["hello", "world"]) == True
2020
assert any([]) == False
2121

22+
doc="ascii"
23+
assert ascii('hello world') == "'hello world'"
24+
assert ascii('안녕 세상') == "'\\uc548\\ub155 \\uc138\\uc0c1'"
25+
assert ascii(chr(0x10001)) == "'\\U00010001'"
26+
assert ascii('안녕 gpython') == "'\\uc548\\ub155 gpython'"
27+
2228
doc="chr"
2329
assert chr(65) == "A"
2430
assert chr(163) == "£"

py/string.go

Lines changed: 57 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,61 @@ or repr(object).
3535
encoding defaults to sys.getdefaultencoding().
3636
errors defaults to 'strict'.`, StrNew, nil)
3737

38+
// Escape the py.String
39+
func StringEscape(a String, ascii bool) string {
40+
s := string(a)
41+
var out bytes.Buffer
42+
quote := '\''
43+
if strings.ContainsRune(s, '\'') && !strings.ContainsRune(s, '"') {
44+
quote = '"'
45+
}
46+
if !ascii {
47+
out.WriteRune(quote)
48+
}
49+
for _, c := range s {
50+
switch {
51+
case c < 0x20:
52+
switch c {
53+
case '\t':
54+
out.WriteString(`\t`)
55+
case '\n':
56+
out.WriteString(`\n`)
57+
case '\r':
58+
out.WriteString(`\r`)
59+
default:
60+
fmt.Fprintf(&out, `\x%02x`, c)
61+
}
62+
case !ascii && c < 0x7F:
63+
if c == '\\' || (quote == '\'' && c == '\'') || (quote == '"' && c == '"') {
64+
out.WriteRune('\\')
65+
}
66+
out.WriteRune(c)
67+
case c < 0x100:
68+
if ascii || strconv.IsPrint(c) {
69+
out.WriteRune(c)
70+
} else {
71+
fmt.Fprintf(&out, "\\x%02x", c)
72+
}
73+
case c < 0x10000:
74+
if !ascii && strconv.IsPrint(c) {
75+
out.WriteRune(c)
76+
} else {
77+
fmt.Fprintf(&out, "\\u%04x", c)
78+
}
79+
default:
80+
if !ascii && strconv.IsPrint(c) {
81+
out.WriteRune(c)
82+
} else {
83+
fmt.Fprintf(&out, "\\U%08x", c)
84+
}
85+
}
86+
}
87+
if !ascii {
88+
out.WriteRune(quote)
89+
}
90+
return out.String()
91+
}
92+
3893
// standard golang strings.Fields doesn't have a 'first N' argument
3994
func fieldsN(s string, n int) []string {
4095
out := []string{}
@@ -194,54 +249,8 @@ func (a String) M__str__() (Object, error) {
194249
}
195250

196251
func (a String) M__repr__() (Object, error) {
197-
// FIXME combine this with parser/stringescape.go into file in py?
198-
s := string(a)
199-
var out bytes.Buffer
200-
quote := '\''
201-
if strings.ContainsRune(s, '\'') && !strings.ContainsRune(s, '"') {
202-
quote = '"'
203-
}
204-
out.WriteRune(quote)
205-
for _, c := range s {
206-
switch {
207-
case c < 0x20:
208-
switch c {
209-
case '\t':
210-
out.WriteString(`\t`)
211-
case '\n':
212-
out.WriteString(`\n`)
213-
case '\r':
214-
out.WriteString(`\r`)
215-
default:
216-
fmt.Fprintf(&out, `\x%02x`, c)
217-
}
218-
case c < 0x7F:
219-
if c == '\\' || (quote == '\'' && c == '\'') || (quote == '"' && c == '"') {
220-
out.WriteRune('\\')
221-
}
222-
out.WriteRune(c)
223-
case c < 0x100:
224-
if strconv.IsPrint(c) {
225-
out.WriteRune(c)
226-
} else {
227-
fmt.Fprintf(&out, "\\x%02x", c)
228-
}
229-
case c < 0x10000:
230-
if strconv.IsPrint(c) {
231-
out.WriteRune(c)
232-
} else {
233-
fmt.Fprintf(&out, "\\u%04x", c)
234-
}
235-
default:
236-
if strconv.IsPrint(c) {
237-
out.WriteRune(c)
238-
} else {
239-
fmt.Fprintf(&out, "\\U%08x", c)
240-
}
241-
}
242-
}
243-
out.WriteRune(quote)
244-
return String(out.String()), nil
252+
out := StringEscape(a, false)
253+
return String(out), nil
245254
}
246255

247256
func (s String) M__bool__() (Object, error) {

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy