Permalink
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Apr 25, 2020
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Dec 20, 2018
Dec 20, 2018
Jan 14, 2015
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Jan 14, 2015
Mar 19, 2018
Jan 14, 2015
Jan 14, 2015
Jan 14, 2015
Mar 19, 2018
Jan 14, 2015
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Jan 14, 2015
Mar 19, 2018
Jan 14, 2015
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Dec 18, 2019
Dec 18, 2019
Mar 19, 2018
Jan 14, 2015
Jan 14, 2015
Mar 19, 2018
Mar 19, 2018
Jan 14, 2015
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 27, 2019
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Apr 2, 2019
Mar 19, 2018
Aug 31, 2017
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Aug 31, 2017
Apr 16, 2019
Mar 19, 2018
Apr 16, 2019
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Nov 12, 2018
Nov 12, 2018
Nov 12, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Apr 2, 2019
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Aug 31, 2017
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Jan 6, 2016
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Aug 31, 2017
May 24, 2019
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Feb 27, 2020
Feb 27, 2020
Feb 27, 2020
Aug 31, 2017
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Nov 14, 2018
Jan 26, 2020
Mar 19, 2018
Mar 19, 2018
Nov 15, 2019
Jul 28, 2018
Oct 27, 2019
May 3, 2020
Nov 2, 2018
Oct 27, 2019
Nov 2, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Nov 12, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Jun 29, 2017
Jun 29, 2017
Jun 29, 2017
Oct 13, 2019
Jun 29, 2017
Jul 10, 2017
Jul 10, 2017
Mar 19, 2018
Mar 19, 2018
Oct 13, 2019
Dec 27, 2019
Oct 13, 2019
Apr 25, 2020
Newer
100644
2528 lines (2317 sloc)
80.1 KB
21
if($.start === null || $.start === _b_.None){$.start = 0}
22
else if($.start < 0){
23
$.start += $.self.length
24
$.start = Math.max(0, $.start)
25
}
26
if($.end === null || $.end === _b_.None){$.end = $.self.length}
27
else if($.end < 0){
28
$.end += $.self.length
29
$.end = Math.max(0, $.end)
30
}
32
if(! isinstance($.start, _b_.int) || ! isinstance($.end, _b_.int)){
33
throw _b_.TypeError.$factory("slice indices must be integers " +
34
"or None or have an __index__ method")
35
}
52
if(!(typeof other === "string")){
53
try{return getattr(other, "__radd__")(self)}
54
catch(err){
55
throw _b_.TypeError.$factory("Can't convert " +
63
throw _b_.TypeError.$factory("'in <string>' requires " +
64
"string as left operand, not " + item.__class__)
65
}
66
if(typeof item == "string"){
67
var nbcar = item.length
68
}else{
69
var nbcar = _b_.len(item)
70
}
71
if(nbcar == 0) {return true} // a string contains the empty string
72
if(self.length == 0){return nbcar == 0}
73
for(var i = 0, len = self.length; i < len; i++){
74
if(self.substr(i, nbcar) == item){return true}
83
// __dir__must be assigned explicitely because attribute resolution for
84
// builtin classes doesn't use __mro__
88
if(other === undefined){ // compare object "self" to class "str"
89
return self === str
99
if(fmt.type && fmt.type != "s"){
100
throw _b_.ValueError.$factory("Unknown format code '" + fmt.type +
108
if(fmt.sign !== undefined){
109
throw _b_.ValueError.$factory(
110
"Sign not allowed in string format specifier")
123
if(arg < 0) {pos += self.length}
124
if(pos >= 0 && pos < self.length){return self.charAt(pos)}
125
throw _b_.IndexError.$factory("string index out of range")
126
}
127
if(isinstance(arg, slice)) {
128
var s = _b_.slice.$conv_for_seq(arg, self.length),
129
start = s.start,
130
stop = s.stop,
131
step = s.step
132
var res = "",
134
if(step > 0){
135
if(stop <= start){return ""}
136
for(var i = start; i < stop; i += step){res += self.charAt(i)}
138
if(stop >= start){return ''}
139
for(var i = start; i > stop; i += step){res += self.charAt(i)}
147
var prefix = 2,
148
suffix = 3,
149
mask = (2 ** 32 - 1)
150
function fnv(p){
151
if(p.length == 0){
152
return 0
153
}
155
var x = prefix
156
x = (x ^ (p.charCodeAt(0) << 7)) & mask
157
for(var i = 0, len = p.length; i < len; i++){
158
x = ((1000003 * x) ^ p.charCodeAt(i)) & mask
159
}
160
x = (x ^ p.length) & mask
161
x = (x ^ suffix) & mask
221
// left adjusted
222
return s + get_char_array(padding - s.length, flags.pad_char)
223
}
224
}
225
233
if(val.__class__ === $B.long_int){
234
s = $B.long_int.to_base(val, 10)
235
}else{
236
s = val.toString()
238
if(s[0] === "-"){
239
return "-" + get_char_array(precision - s.length + 1, "0") + s.slice(1)
250
if(val === Infinity){
251
val = "inf"
252
}else if(val === -Infinity){
253
val = "-inf"
254
}else{
255
val = "nan"
277
var str_format = function(val, flags) {
278
// string format supports left and right padding
279
flags.pad_char = " " // even if 0 padding is defined, don't use it
285
if(val.__class__ === $B.long_int){
286
val = $B.long_int.to_base(val, 10)
287
}else{
288
val = parseInt(val)
306
var repr_format = function(val, flags) {
307
flags.pad_char = " " // even if 0 padding is defined, don't use it
308
return format_padding(repr(val), flags)
309
}
311
var ascii_format = function(val, flags) {
312
flags.pad_char = " " // even if 0 padding is defined, don't use it
313
return format_padding(ascii(val), flags)
314
}
326
flags.precision = parseInt(flags.precision, 10)
327
validate_precision(flags.precision)
328
}
329
return parseFloat(val)
330
}
333
var trailing_zeros = /(.*?)(0+)([eE].*)/,
334
leading_zeros = /\.(0*)/,
335
trailing_dot = /\.$/
337
var validate_precision = function(precision) {
338
// force precision to limits of javascript
343
var floating_point_format = function(val, upper, flags){
344
val = _float_helper(val, flags),
345
v = val.toString(),
346
v_len = v.length,
347
dot_idx = v.indexOf('.')
348
if(dot_idx < 0){dot_idx = v_len}
349
if(val < 1 && val > -1){
350
var zeros = leading_zeros.exec(v),
351
numzeros
352
if(zeros){
357
if(numzeros >= 4){
358
val = format_sign(val, flags) + format_float_precision(val, upper,
359
flags, _floating_g_exp_helper)
360
if(!flags.alternate){
373
return format_padding(format_sign(val, flags) +
374
format_float_precision(val, upper, flags,
375
function(val, precision) {
376
return val.toFixed(min(precision, v_len - dot_idx) +
377
numzeros)
378
}),
379
flags
380
)
381
}
382
383
if(dot_idx > flags.precision){
384
val = format_sign(val, flags) + format_float_precision(val, upper,
385
flags, _floating_g_exp_helper)
386
if(! flags.alternate){
398
return format_padding(format_sign(val, flags) +
399
format_float_precision(val, upper, flags,
400
function(val, precision) {
401
if(!flags.decimal_point){
402
precision = min(v_len - 1, 6)
403
}else if (precision > v_len){
404
if(! flags.alternate){
405
precision = v_len
406
}
408
if(precision < dot_idx){
409
precision = dot_idx
410
}
411
return val.toFixed(precision - dot_idx)
412
}),
413
flags
414
)
417
var _floating_g_exp_helper = function(val, precision, flags, upper){
418
if(precision){--precision}
421
var e_idx = val.lastIndexOf("e")
422
if(e_idx > val.length - 4){
423
val = val.substring(0, e_idx + 2) + "0" + val.substring(e_idx + 2)
426
return val
427
}
428
429
// fF
430
var floating_point_decimal_format = function(val, upper, flags) {
431
val = _float_helper(val, flags)
432
return format_padding(format_sign(val, flags) +
433
format_float_precision(val, upper, flags,
434
function(val, precision, flags) {
435
val = val.toFixed(precision)
436
if(precision === 0 && flags.alternate){
437
val += '.'
438
}
439
return val
440
}),
441
flags
442
)
443
}
444
445
var _floating_exp_helper = function(val, precision, flags, upper) {
446
val = val.toExponential(precision)
447
// pad exponent to two digits
460
return format_padding(format_sign(val, flags) +
461
format_float_precision(val, upper, flags, _floating_exp_helper), flags)
487
if(flags.alternate){
488
if(ret.charAt(0) === "-"){
489
if(upper){ret = "-0X" + ret.slice(1)}
490
else{ret = "-0x" + ret.slice(1)}
491
}else{
492
if(upper){ret = "0X" + ret}
493
else{ret = "0x" + ret}
503
if(val.__class__ === $B.long_int){
504
ret = $B.long_int.to_base(8)
505
}else{
506
ret = parseInt(val)
507
ret = ret.toString(8)
523
if(flags.alternate){
524
if(ret.charAt(0) === "-"){ret = "-0o" + ret.slice(1)}
525
else{ret = "0o" + ret}
530
function series_of_bytes(val, flags){
531
if(val.__class__ && val.__class__.$buffer_protocol){
532
var it = _b_.iter(val),
533
ints = []
534
while(true){
535
try{
536
ints.push(_b_.next(it))
537
}catch(err){
538
if(err.__class__ === _b_.StopIteration){
539
var b = _b_.bytes.$factory(ints)
540
return format_padding(_b_.bytes.decode(b, "ascii"), flags)
541
}
542
throw err
543
}
544
}
545
}else{
546
try{
547
bytes_obj = $B.$getattr(val, "__bytes__")
548
return format_padding(_b_.bytes.decode(bytes_obj), flags)
549
}catch(err){
550
if(err.__class__ === _b_.AttributeError){
551
throw _b_.TypeError.$factory("%b does not accept '" +
552
$B.class_name(val) + "'")
553
}
554
throw err
555
}
556
}
557
}
558
560
if(isinstance(val, str) && val.length == 1){
561
return val
562
}else if(isinstance(val, bytes) && val.source.length == 1){
563
val = val.source[0]
564
}else{
565
try{
566
val = _b_.int.$factory(val) // yes, floats are valid (they are cast to int)
567
}catch (err){
568
throw _b_.TypeError.$factory("%c requires int or char")
569
}
574
var num_flag = function(c, flags){
575
if(c === "0" && ! flags.padding && ! flags.decimal_point && ! flags.left){
576
flags.pad_char = "0"
582
flags.precision = (flags.precision || "") + c
583
}
584
}
585
586
var decimal_point_flag = function(val, flags) {
588
// can only have one decimal point
589
throw new UnsupportedChar()
590
}
591
flags.decimal_point = true
592
}
593
594
var neg_flag = function(val, flags){
595
flags.pad_char = " " // overrides '0' flag
613
"s": str_format,
614
"d": num_format,
615
"i": num_format,
616
"u": num_format,
617
"o": octal_format,
618
"r": repr_format,
619
"a": ascii_format,
620
"g": function(val, flags){
621
return floating_point_format(val, false, flags)
622
},
623
"G": function(val, flags){return floating_point_format(val, true, flags)},
624
"f": function(val, flags){
625
return floating_point_decimal_format(val, false, flags)
626
},
627
"F": function(val, flags){
628
return floating_point_decimal_format(val, true, flags)
629
},
630
"e": function(val, flags){
631
return floating_point_exponential_format(val, false, flags)
632
},
633
"E": function(val, flags){
634
return floating_point_exponential_format(val, true, flags)
635
},
636
"x": function(val, flags){return signed_hex_format(val, false, flags)},
637
"X": function(val, flags){return signed_hex_format(val, true, flags)},
638
"c": single_char_format,
639
"0": function(val, flags){return num_flag("0", flags)},
640
"1": function(val, flags){return num_flag("1", flags)},
641
"2": function(val, flags){return num_flag("2", flags)},
642
"3": function(val, flags){return num_flag("3", flags)},
643
"4": function(val, flags){return num_flag("4", flags)},
644
"5": function(val, flags){return num_flag("5", flags)},
645
"6": function(val, flags){return num_flag("6", flags)},
646
"7": function(val, flags){return num_flag("7", flags)},
647
"8": function(val, flags){return num_flag("8", flags)},
648
"9": function(val, flags){return num_flag("9", flags)},
649
"-": neg_flag,
650
" ": space_flag,
651
"+": sign_flag,
652
".": decimal_point_flag,
653
"#": alternate_flag
654
}
655
656
// exception thrown when an unsupported char is encountered in legacy format
703
if(self === undefined){
704
throw _b_.TypeError.$factory(
705
"not enough arguments for format string")
732
throw _b_.ValueError.$factory(
733
"unsupported format character '" + invalid_char +
734
"' (0x" + invalid_char.charCodeAt(0).toString(16) +
735
") at index " + newpos)
736
}else if(err.name === "NotANumber"){
737
var try_char = s[newpos],
738
cls = self.__class__
739
if(!cls){
740
if(typeof(self) === "string"){
741
cls = "str"
742
}else{
748
throw _b_.TypeError.$factory("%" + try_char +
749
" format: a number is required, not " + cls)
750
}else{
782
}while(pos < length)
783
784
if(argpos !== null){
785
if(args.length > argpos){
786
throw _b_.TypeError.$factory(
787
"not enough arguments for format string")
788
}else if(args.length < argpos){
789
throw _b_.TypeError.$factory(
790
"not all arguments converted during string formatting")
792
}else if(nbph == 0){
793
throw _b_.TypeError.$factory(
794
"not all arguments converted during string formatting")
802
var $ = $B.args("__mul__", 2, {self: null, other: null},
803
["self", "other"], arguments, {}, null, null)
804
if(! isinstance($.other, _b_.int)){throw _b_.TypeError.$factory(
805
"Can't multiply sequence by non-int of type '" +
817
res = self.replace(/\\/g, "\\\\")
818
// special cases
819
res = res.replace(new RegExp("\u0007", "g"), "\\x07").
820
replace(new RegExp("\b", "g"), "\\x08").
822
replace(new RegExp("\f", "g"), "\\x0c").
823
replace(new RegExp("\n", "g"), "\\n").
824
replace(new RegExp("\r", "g"), "\\r").
825
replace(new RegExp("\t", "g"), "\\t")
827
if(res.search('"') == -1 && res.search("'") == -1){
828
return "'" + res + "'"
829
}else if(self.search('"') == -1){
830
return '"' + res + '"'
831
}
832
var qesc = new RegExp("'", "g") // to escape single quote
833
res = "'" + res.replace(qesc, "\\'") + "'"
837
str.__setitem__ = function(self, attr, value){
838
throw _b_.TypeError.$factory(
839
"'str' object does not support item assignment")
841
var combining = []
842
for(var cp = 0x300; cp <= 0x36F; cp++){
843
combining.push(String.fromCharCode(cp))
844
}
845
var combining_re = new RegExp("(" + combining.join("|") + ")")
857
$comp_func += "" // source code
858
var $comps = {">": "gt", ">=": "ge", "<": "lt", "<=": "le"}
867
var $notimplemented = function(self, other){
868
throw NotImplementedError.$factory(
869
"OPERATOR not implemented for class str")
872
str.capitalize = function(self){
873
var $ = $B.args("capitalize", 1, {self}, ["self"],
874
arguments, {}, null, null)
875
if(self.length == 0){return ""}
876
return self.charAt(0).toUpperCase() + self.substr(1)
877
}
878
879
str.casefold = function(self){
880
var $ = $B.args("casefold", 1, {self}, ["self"],
881
arguments, {}, null, null),
882
res = "",
883
char,
884
cf
885
for(var i = 0, len = self.length; i < len; i++){
886
char = self.charCodeAt(i)
887
cf = $B.unicode_casefold[char]
888
if(cf){
889
cf.forEach(function(cp){
890
res += String.fromCharCode(cp)
891
})
892
}else{
893
res += self.charAt(i).toLowerCase()
894
}
895
}
896
return res
897
}
899
str.center = function(){
900
var $ = $B.args("center", 3, {self: null, width: null, fillchar: null},
901
["self", "width", "fillchar"],
902
arguments, {fillchar:" "}, null, null),
903
self = $.self
915
var $ = $B.args("count", 4, {self:null, sub:null, start:null, stop:null},
916
["self", "sub", "start", "stop"], arguments, {start:null, stop:null},
924
if($.stop !== null){_slice = _b_.slice.$factory($.start, $.stop)}
925
else{_slice = _b_.slice.$factory($.start, $.self.length)}
930
if($.sub.length == 0){
931
if($.start == $.self.length){return 1}
932
else if(substr.length == 0){return 0}
933
return substr.length + 1
935
var n = 0,
936
pos = 0
937
while(pos < substr.length){
938
pos = substr.indexOf($.sub, pos)
939
if(pos >= 0){n++; pos += $.sub.length}
940
else{break}
945
str.encode = function(){
946
var $ = $B.args("encode", 3, {self: null, encoding: null, errors: null},
947
["self", "encoding", "errors"], arguments,
948
{encoding: "utf-8", errors: "strict"}, null, null)
949
if($.encoding == "rot13" || $.encoding == "rot_13"){
954
if(("a" <= char && char <= "m") || ("A" <= char && char <= "M")){
955
res += String.fromCharCode(String.charCodeAt(char) + 13)
956
}else if(("m" < char && char <= "z") ||
957
("M" < char && char <= "Z")){
958
res += String.fromCharCode(String.charCodeAt(char) - 13)
967
// Return True if the string ends with the specified suffix, otherwise
968
// return False. suffix can also be a tuple of suffixes to look for.
969
// With optional start, test beginning at that position. With optional
973
["self", "suffix", "start", "end"],
974
arguments, {start: 0, end: null}, null, null)
981
var s = $.self.substring($.start, $.end)
982
for(var i = 0, len = suffixes.length; i < len; i++){
986
if(suffix.length <= s.length &&
987
s.substr(s.length - suffix.length) == suffix){return true}
993
var $ = $B.args("expandtabs", 2, {self: null, tabsize: null},
994
["self", "tabsize"], arguments, {tabsize: 8}, null, null)
995
var s = $B.$GetInt($.tabsize),
996
col = 0,
997
pos = 0,
998
res = ""
999
if(s == 1){return self.replace(/\t/g," ")}
1000
while(pos < self.length){
1008
res += car
1009
col = 0
1010
break
1011
default:
1012
res += car
1013
col++
1014
break
1015
}
1016
pos++
1017
}
1023
// Return the lowest index in the string where substring sub is found,
1024
// such that sub is contained in the slice s[start:end]. Optional
1025
// arguments start and end are interpreted as in slice notation.
1028
{self: null, sub: null, start: null, end: null},
1029
["self", "sub", "start", "end"],
1030
arguments, {start: 0, end: null}, null, null)
1034
if(!isinstance($.start, _b_.int)||!isinstance($.end, _b_.int)){
1035
throw _b_.TypeError.$factory("slice indices must be " +
1036
"integers or None or have an __index__ method")}
1037
// Can't use string.substring(start, end) because if end < start,
1038
// Javascript transforms it into substring(end, start)...
1039
var s = ""
1040
for(var i = $.start; i < $.end; i++){
1041
s += $.self.charAt(i)
1042
}
1044
if($.sub.length == 0 && $.start == $.self.length){return $.self.length}
1045
if(s.length + $.sub.length == 0){return -1}
1047
var last_search = s.length - $.sub.length
1048
for(var i = 0; i <= last_search; i++){
1049
if(s.substr(i, $.sub.length) == $.sub){return $.start + i}
1060
// a.x[z]!r:...
1061
// the object has attributes :
1062
// - name : "a"
1063
// - name_ext : [".x", "[z]"]
1064
// - conv : r
1065
// - spec : rest of string after :
1073
// No : in the string : it only contains a name
1074
name = fmt_string
1075
}else{
1076
// name is before the first ":"
1077
// spec (the format specification) is after
1078
name = elts[0]
1082
var elts = name.split("!")
1083
if(elts.length > 1){
1084
name = elts[0]
1085
conv = elts[1] // conversion flag
1089
// "name' may be a subscription or attribute
1090
// Put these "extensions" in the list "name_ext"
1091
function name_repl(match){
1092
name_ext.push(match)
1094
}
1095
var name_ext_re = /\.[_a-zA-Z][_a-zA-Z0-9]*|\[[_a-zA-Z][_a-zA-Z0-9]*\]|\[[0-9]+\]/g
1096
name = name.replace(name_ext_re, name_repl)
1097
}
1104
// Parse self to detect formatting instructions
1105
// Create a list "parts" made of sections of the string :
1106
// - elements of even rank are literal text
1107
// - elements of odd rank are "format objects", built from the
1108
// format strings in self (of the form {...})
1119
text += "{"
1120
pos += 2
1121
}else if(car == "}" && self.charAt(pos + 1) == "}"){
1128
// Store current literal text
1129
parts.push(text)
1130
1131
// Search the end of the format string, ie the } closing the
1132
// opening {. Since the string can contain other pairs {} for
1133
// nested formatting, an integer nb is incremented for each { and
1134
// decremented for each } ; the end of the format string is
1135
// reached when nb == 0
1136
var end = pos + 1,
1137
nb = 1
1138
while(end < _len){
1139
if(self.charAt(end) == "{"){nb++; end++}
1140
else if(self.charAt(end) == "}"){
1141
nb--; end++
1142
if(nb == 0){
1147
var fmt_obj = $B.parse_format(fmt_string)
1148
fmt_obj.raw_name = fmt_obj.name
1149
fmt_obj.raw_spec = fmt_obj.spec
1184
return parts
1185
}
1186
1187
str.format = function(self) {
1188
var $ = $B.args("format", 1, {self: null}, ["self"],
1189
arguments, {}, "$args", "$kw")
1190
1191
var parts = $B.split_format($.self)
1192
1203
1204
if(fmt.spec !== undefined){
1205
// "spec" may contain "nested replacement fields"
1206
// In this case, evaluate them using the positional
1207
// or keyword arguments passed to format()
1208
function replace_nested(name, key){
1209
if(/\d+/.exec(key)){
1210
// If key is numeric, search in positional
1211
// arguments
1212
return _b_.tuple.__getitem__($.$args,
1213
parseInt(key))
1214
}else{
1215
// Else try in keyword arguments
1216
return _b_.dict.__getitem__($.$kw, key)
1217
}
1218
}
1219
fmt.spec = fmt.spec.replace(/\{(.*?)\}/g,
1220
replace_nested)
1221
}
1223
// Numerical reference : use positional arguments
1224
var pos = parseInt(fmt.name),
1234
// Attribute
1235
value = _b_.getattr(value, ext.substr(1))
1236
}else{
1237
// Subscription
1240
if(key.charAt(0).search(/\d/) > -1){key = parseInt(key)}
1241
value = _b_.getattr(value, "__getitem__")(key)
1245
// If the conversion flag is set, first call a function to convert
1246
// the value
1247
if(fmt.conv == "a"){value = _b_.ascii(value)}
1248
else if(fmt.conv == "r"){value = _b_.repr(value)}
1249
else if(fmt.conv == "s"){value = _b_.str.$factory(value)}
1263
throw NotImplementedError.$factory(
1264
"function format_map not implemented yet")
1275
/* Return true if the string is empty or all characters in the string are
1276
ASCII, false otherwise. ASCII characters have code points in the range
1277
U+0000-U+007F. */
1278
for(var i = 0, len = self.length; i < len; i++){
1279
if(self.charCodeAt(i) > 127){return false}
1280
}
1281
return true
1282
}
1283
1284
str.isalnum = function(self){
1285
/* Return true if all characters in the string are alphanumeric and there
1286
is at least one character, false otherwise. A character c is alphanumeric
1287
if one of the following returns True: c.isalpha(), c.isdecimal(),
1288
c.isdigit(), or c.isnumeric(). */
1289
var $ = $B.args("isalnum", 1, {self: null}, ["self"],
1290
arguments, {}, null, null),
1291
char
1292
for(var i = 0, len = self.length; i < len; i++){
1293
char = self.charCodeAt(i)
1294
if(unicode_tables.Ll[char] ||
1295
unicode_tables.Lu[char] ||
1296
unicode_tables.Lm[char] ||
1297
unicode_tables.Lt[char] ||
1298
unicode_tables.Lo[char] ||
1299
unicode_tables.Nd[char] ||
1300
unicode_tables.digits[char] ||
1301
unicode_tables.numeric[char]){
1302
continue
1303
}
1304
return false
1305
}
1306
return true
1307
}
1308
1309
str.isalpha = function(self){
1310
/* Return true if all characters in the string are alphabetic and there is
1311
at least one character, false otherwise. Alphabetic characters are those
1312
characters defined in the Unicode character database as "Letter", i.e.,
1313
those with general category property being one of "Lm", "Lt", "Lu", "Ll",
1314
or "Lo". */
1315
var $ = $B.args("isalpha", 1, {self: null}, ["self"],
1316
arguments, {}, null, null),
1317
char
1318
for(var i = 0, len = self.length; i < len; i++){
1319
char = self.charCodeAt(i)
1320
if(unicode_tables.Ll[char] ||
1321
unicode_tables.Lu[char] ||
1322
unicode_tables.Lm[char] ||
1323
unicode_tables.Lt[char] ||
1324
unicode_tables.Lo[char]){
1325
continue
1326
}
1327
return false
1328
}
1329
return true
1330
}
1331
1332
str.isdecimal = function(self){
1333
/* Return true if all characters in the string are decimal characters and
1334
there is at least one character, false otherwise. Decimal characters are
1335
those that can be used to form numbers in base 10, e.g. U+0660,
1336
ARABIC-INDIC DIGIT ZERO. Formally a decimal character is a character in
1337
the Unicode General Category "Nd". */
1338
var $ = $B.args("isdecimal", 1, {self: null}, ["self"],
1339
arguments, {}, null, null),
1340
char
1341
for(var i = 0, len = self.length; i < len; i++){
1342
char = self.charCodeAt(i)
1343
if(! unicode_tables.Nd[char]){
1344
return false
1345
}
1346
}
1347
return self.length > 0
1348
}
1349
1350
str.isdigit = function(self){
1351
/* Return true if all characters in the string are digits and there is at
1352
least one character, false otherwise. */
1353
var $ = $B.args("isdigit", 1, {self: null}, ["self"],
1354
arguments, {}, null, null),
1355
char
1356
for(var i = 0, len = self.length; i < len; i++){
1357
char = self.charCodeAt(i)
1358
if(! unicode_tables.digits[char]){
1359
return false
1360
}
1361
}
1362
return self.length > 0
1363
}
1364
1365
str.isidentifier = function(self){
1366
/* Return true if the string is a valid identifier according to the
1367
language definition. */
1368
var $ = $B.args("isidentifier", 1, {self: null}, ["self"],
1369
arguments, {}, null, null),
1370
char
1371
if(self.length == 0){return false}
1372
else if(unicode_tables.XID_Start[self.charCodeAt(0)] === undefined){
1373
return false
1374
}else{
1375
for(var i = 1, len = self.length; i < len; i++){
1376
if(unicode_tables.XID_Continue[self.charCodeAt(i)] === undefined){
1377
return false
1378
}
1379
}
1380
}
1381
return true
1382
}
1383
1384
str.islower = function(self){
1385
/* Return true if all cased characters 4 in the string are lowercase and
1386
there is at least one cased character, false otherwise. */
1387
var $ = $B.args("islower", 1, {self: null}, ["self"],
1388
arguments, {}, null, null),
1389
has_cased = false,
1390
char
1391
1392
for(var i = 0, len = self.length; i < len; i++){
1393
char = self.charCodeAt(i)
1394
if(unicode_tables.Ll[char]){has_cased = true; continue}
1395
else if(unicode_tables.Lu[char] || unicode_tables.Lt[char]){
1396
return false
1397
}
1398
}
1399
return has_cased
1400
}
1401
1402
str.isnumeric = function(self){
1403
/* Return true if all characters in the string are numeric characters, and
1404
there is at least one character, false otherwise. Numeric characters
1405
include digit characters, and all characters that have the Unicode numeric
1406
value property, e.g. U+2155, VULGAR FRACTION ONE FIFTH. Formally, numeric
1407
characters are those with the property value Numeric_Type=Digit,
1408
Numeric_Type=Decimal or Numeric_Type=Numeric.*/
1409
var $ = $B.args("isnumeric", 1, {self: null}, ["self"],
1410
arguments, {}, null, null)
1411
for(var i = 0, len = self.length; i < len; i++){
1412
if(! unicode_tables.numeric[self.charCodeAt(i)]){
1413
return false
1414
}
1415
}
1416
return self.length > 0
1417
}
1418
1419
var printable,
1420
printable_gc = ['Cc', 'Cf', 'Co', 'Cs','Zl', 'Zp', 'Zs']
1421
1422
str.isprintable = function(self){
1423
/* Return true if all characters in the string are printable or the string
1424
is empty, false otherwise. Nonprintable characters are those characters
1425
defined in the Unicode character database as "Other" or "Separator",
1426
excepting the ASCII space (0x20) which is considered printable. */
1427
1428
// Set printable if not set yet
1429
if(printable === undefined){
1430
for(var i = 0; i < printable_gc.length; i++){
1431
var table = unicode_tables[printable_gc[i]]
1432
for(var cp in table){
1433
printable[cp] = true
1434
}
1435
}
1436
printable[32] = true
1437
}
1438
1439
var $ = $B.args("isprintable", 1, {self: null}, ["self"],
1440
arguments, {}, null, null),
1441
char,
1442
flag
1443
for(var i = 0, len = self.length; i < len; i++){
1444
char = self.charCodeAt(i)
1445
if(! printable[char]){
1446
return false
1447
}
1448
}
1449
return true
1450
}
1451
1452
str.isspace = function(self){
1453
/* Return true if there are only whitespace characters in the string and
1454
there is at least one character, false otherwise.
1455
1456
A character is whitespace if in the Unicode character database, either its
1457
general category is Zs ("Separator, space"), or its bidirectional class is
1458
one of WS, B, or S.*/
1459
var $ = $B.args("isspace", 1, {self: null}, ["self"],
1460
arguments, {}, null, null),
1461
char
1462
for(var i = 0, len = self.length; i < len; i++){
1463
char = self.charCodeAt(i)
1464
if(! unicode_tables.Zs[char] &&
1465
$B.unicode_bidi_whitespace.indexOf(char) == -1){
1466
return false
1467
}
1468
}
1469
return self.length > 0
1470
}
1471
1472
str.istitle = function(self){
1473
/* Return true if the string is a titlecased string and there is at least
1474
one character, for example uppercase characters may only follow uncased
1475
characters and lowercase characters only cased ones. Return false
1476
otherwise. */
1477
var $ = $B.args("istitle", 1, {self: null}, ["self"],
1478
arguments, {}, null, null)
1479
return self.length > 0 && str.title(self) == self
1480
}
1481
1482
str.isupper = function(self){
1483
/* Return true if all cased characters 4 in the string are lowercase and
1484
there is at least one cased character, false otherwise. */
1485
var $ = $B.args("islower", 1, {self: null}, ["self"],
1486
arguments, {}, null, null),
1487
has_cased = false,
1488
char
1489
1490
for(var i = 0, len = self.length; i < len; i++){
1491
char = self.charCodeAt(i)
1492
if(unicode_tables.Lu[char]){has_cased = true; continue}
1493
else if(unicode_tables.Ll[char] || unicode_tables.Lt[char]){
1511
if(! isinstance(obj2, str)){throw _b_.TypeError.$factory(
1512
"sequence item " + count + ": expected str instance, " +
1526
var $ = $B.args("ljust", 3, {self: null, width: null, fillchar:null},
1527
["self", "width", "fillchar"],
1528
arguments, {fillchar: " "}, null, null)
1534
str.lower = function(self){
1535
var $ = $B.args("lower", 1, {self: null}, ["self"],
1536
arguments, {}, null, null)
1537
return self.toLowerCase()
1538
}
1539
1541
var $ = $B.args("lstrip", 2, {self: null, chars: null}, ["self", "chars"],
1542
arguments, {chars:_b_.None}, null, null)
1543
if($.chars === _b_.None){return $.self.trimLeft()}
1544
for(var i = 0; i < $.self.length; i++){
1545
if($.chars.indexOf($.self.charAt(i)) === -1){
1546
return $.self.substring(i)
1554
var $ = $B.args("maketrans", 3, {x: null, y: null, z: null},
1555
["x", "y", "z"], arguments, {y: null, z: null}, null, null)
1560
// If there is only one argument, it must be a dictionary mapping
1561
// Unicode ordinals (integers) or characters (strings of length 1) to
1562
// Unicode ordinals, strings (of arbitrary lengths) or None. Character
1564
if(! _b_.isinstance($.x, _b_.dict)){
1565
throw _b_.TypeError.$factory(
1566
"maketrans only argument must be a dict")
1569
for(var i = 0, len = items.length; i < len; i++){
1570
var k = items[i][0],
1571
v = items[i][1]
1572
if(! _b_.isinstance(k, _b_.int)){
1573
if(_b_.isinstance(k, _b_.str) && k.length == 1){
1574
k = _b_.ord(k)
1575
}else{throw _b_.TypeError.$factory("dictionary key " + k +
1578
if(v !== _b_.None && ! _b_.isinstance(v, [_b_.int, _b_.str])){
1579
throw _b_.TypeError.$factory("dictionary value " + v +
1587
// and in the resulting dictionary, each character in x will be mapped
1588
// to the character at the same position in y
1591
}else if($.x.length !== $.y.length){
1592
throw _b_.TypeError.$factory(
1593
"maketrans arguments must be strings or same length")
1599
if(! _b_.isinstance($.z, _b_.str)){
1600
throw _b_.TypeError.$factory(
1601
"maketrans third argument must be a string")
1623
var $ = $B.args("partition", 2, {self: null, sep: null}, ["self", "sep"],
1624
arguments, {}, null, null)
1629
return _b_.tuple.$factory([$.self.substring(0, i), $.sep,
1630
$.self.substring(i + $.sep.length)])
1631
}
1632
1633
function $re_escape(str){
1634
var specials = "[.*+?|()$^"
1635
for(var i = 0, len = specials.length; i < len; i++){
1636
var re = new RegExp("\\"+specials.charAt(i), "g")
1637
str = str.replace(re, "\\"+specials.charAt(i))
1638
}
1639
return str
1646
var $ = $B.args("replace", 4,
1647
{self: null, old: null, $$new: null, count: null},
1648
["self", "old", "$$new", "count"],
1649
arguments, {count: -1}, null, null),
1650
count = $.count,
1651
self = $.self,
1652
old = $.old,
1653
_new = $.$$new
1660
"' object cannot be interpreted as an integer")
1661
}else if(isinstance(count, _b_.float)){
1662
throw _b_.TypeError.$factory("integer argument expected, got float")
1663
}
1664
if(count == 0){return self}
1665
if(count.__class__ == $B.long_int){count = parseInt(count.value)}
1666
if(old == ""){
1667
if(_new == ""){return self}
1668
if(self == ""){return _new}
1669
var elts = self.split("")
1670
if(count > -1 && elts.length >= count){
1671
var rest = elts.slice(count).join("")
1672
return _new + elts.slice(0, count).join(_new) + rest
1673
}else{return _new + elts.join(_new) + _new}
1688
if(count < 0){count = res.length}
1689
while(count > 0){
1690
pos = res.indexOf(old, pos)
1691
if(pos < 0){break}
1692
res = res.substr(0, pos) + _new + res.substr(pos + old.length)
1693
pos = pos + _new.length
1694
count--
1700
// Return the highest index in the string where substring sub is found,
1701
// such that sub is contained within s[start:end]. Optional arguments
1703
if(arguments.length == 2 && typeof substr == "string"){
1704
return self.lastIndexOf(substr)
1705
}
1707
{self: null, sub: null, start: null, end: null},
1708
["self", "sub", "start", "end"],
1709
arguments, {start: 0, end: null}, null, null)
1721
for(var i = $.end - sublen; i >= $.start; i--){
1722
if($.self.substr(i, sublen) == $.sub){return i}
1729
var res = str.rfind.apply(null, arguments)
1730
if(res == -1){throw _b_.ValueError.$factory("substring not found")}
1735
var $ = $B.args("rjust",3,
1736
{self: null, width: null, fillchar: null},
1737
["self", "width", "fillchar"],
1738
arguments, {fillchar: " "}, null, null)
1746
var $ = $B.args("rpartition", 2, {self: null, sep: null}, ["self", "sep"],
1747
arguments, {}, null, null)
1751
var items = str.partition(self, sep).reverse()
1752
for(var i = 0; i < items.length; i++){
1753
items[i] = items[i].split("").reverse().join("")
1759
var $ = $B.args("rsplit", 3, {self: null, sep: null, maxsplit: null},
1760
["self", "sep", "maxsplit"], arguments,
1761
{sep: _b_.None, maxsplit: -1}, null, null),
1762
sep = $.sep
1765
var rev_str = reverse($.self),
1766
rev_sep = sep === _b_.None ? sep : reverse($.sep),
1777
str.rstrip = function(self, x){
1778
var $ = $B.args("rstrip", 2, {self: null, chars: null}, ["self", "chars"],
1779
arguments, {chars: _b_.None}, null, null)
1780
if($.chars === _b_.None){return $.self.trimRight()}
1782
if($.chars.indexOf($.self.charAt(j)) == -1){
1783
return $.self.substring(0, j + 1)
1790
var $ = $B.args("split", 3, {self: null, sep: null, maxsplit: null},
1791
["self", "sep", "maxsplit"], arguments,
1792
{sep: _b_.None, maxsplit: -1}, null, null),
1793
sep = $.sep,
1794
maxsplit = $.maxsplit,
1795
self = $.self,
1796
pos = 0
1797
if(maxsplit.__class__ === $B.long_int){maxsplit = parseInt(maxsplit.value)}
1798
if(sep == ""){throw _b_.ValueError.$factory("empty separator")}
1799
if(sep === _b_.None){
1801
while(pos < self.length && self.charAt(pos).search(/\s/) > -1){pos++}
1802
if(pos === self.length - 1){return [self]}
1803
var name = ""
1805
if(self.charAt(pos).search(/\s/) == -1){
1806
if(name == ""){name = self.charAt(pos)}
1807
else{name += self.charAt(pos)}
1827
var res = [],
1828
s = "",
1829
seplen = sep.length
1830
if(maxsplit == 0){return [self]}
1831
while(pos < self.length){
1832
if(self.substr(pos, seplen) == sep){
1850
str.splitlines = function(self) {
1851
var $ = $B.args('splitlines', 2, {self: null, keepends: null},
1852
['self','keepends'], arguments, {keepends: false},
1853
null, null)
1854
if(!_b_.isinstance($.keepends,[_b_.bool, _b_.int])){
1855
throw _b_.TypeError('integer argument expected, got '+
1858
var keepends = _b_.int.$factory($.keepends),
1859
res = [],
1860
self = $.self,
1861
start = 0,
1862
pos = 0
1863
if(!self.length){
1866
while (pos < self.length) {
1867
if(self.substr(pos, 2) == '\r\n'){
1868
res.push(self.slice(start, keepends ? pos + 2 : pos))
1869
start = pos = pos+2
1870
}else if(self[pos] == '\r' || self[pos] == '\n'){
1871
res.push(self.slice(start, keepends ? pos+1 : pos))
1872
start = pos = pos+1
1873
}else{
1874
pos++
1875
}
1876
}
1877
if(start < self.length){
1878
res.push(self.slice(start))
1879
}
1880
return res
1884
// Return True if string starts with the prefix, otherwise return False.
1885
// prefix can also be a tuple of prefixes to look for. With optional
1886
// start, test string beginning at that position. With optional end,
1888
var $ = $B.args("startswith", 4,
1889
{self: null, prefix: null, start: null, end: null},
1890
["self", "prefix", "start", "end"],
1891
arguments, {start: 0, end: null}, null, null)
1898
var s = $.self.substring($.start, $.end)
1899
for(var i = 0, len = prefixes.length; i < len; i++){
1910
var $ = $B.args("strip", 2, {self: null, chars: null}, ["self", "chars"],
1911
arguments, {chars: _b_.None}, null, null)
1912
if($.chars === _b_.None){return $.self.trim()}
1913
for(var i = 0; i < $.self.length; i++){
1914
if($.chars.indexOf($.self.charAt(i)) == -1){
1915
break
1918
for(var j = $.self.length - 1; j >= i; j--){
1919
if($.chars.indexOf($.self.charAt(j)) == -1){
1920
break
1926
str.swapcase = function(self){
1927
var $ = $B.args("swapcase", 1, {self}, ["self"],
1928
arguments, {}, null, null),
1929
res = "",
1930
char
1931
1932
for(var i = 0, len = self.length; i < len; i++){
1933
char = self.charCodeAt(i)
1934
if(unicode_tables.Ll[char]){
1935
res += self.charAt(i).toUpperCase()
1936
}else if(unicode_tables.Lu[char]){
1937
res += self.charAt(i).toLowerCase()
1938
}else{
1939
res += self.charAt(i)
1940
}
1941
}
1942
return res
1943
}
1944
1945
str.title = function(self){
1946
var $ = $B.args("title", 1, {self}, ["self"],
1947
arguments, {}, null, null),
1948
state,
1949
char,
1950
res = ""
1951
for(var i = 0, len = self.length; i < len; i++){
1952
char = self.charCodeAt(i)
1953
if(unicode_tables.Ll[char]){
1954
if(! state){
1955
res += self.charAt(i).toUpperCase()
1956
state = "word"
1957
}else{
1958
res += self.charAt(i)
1959
}
1960
}else if(unicode_tables.Lu[char] || unicode_tables.Lt[char]){
1961
res += state ? self.charAt(i).toLowerCase() : self.charAt(i)
1962
state = "word"
1963
}else{
1964
state = null
1965
res += self.charAt(i)
1966
}
1967
}
1968
return res
1969
}
1970
1973
getitem = $B.$getattr(table, "__getitem__")
1974
for(var i = 0, len = self.length; i < len; i++){
1975
try{
1976
var repl = getitem(self.charCodeAt(i))
1977
if(repl !== _b_.None){
1978
if(typeof repl == "string"){
1979
res.push(repl)
1980
}else if(typeof repl == "number"){
1981
res.push(String.fromCharCode(repl))
1982
}
1991
str.upper = function(self){
1992
var $ = $B.args("upper", 1, {self: null}, ["self"],
1993
arguments, {}, null, null)
1994
return self.toUpperCase()
1995
}
1996
1999
["self", "width"], arguments, {}, null, null)
2000
if($.width <= self.length){return self}
2002
case "+":
2003
case "-":
2004
return self.charAt(0) +
2005
"0".repeat($.width - self.length) + self.substr(1)
2016
if(encoding !== undefined){
2017
// Arguments may be passed as keywords (cf. issue #1060)
2018
var $ = $B.args("str", 3, {arg: null, encoding: null, errors: null},
2019
["arg", "encoding", "errors"], arguments,
2020
{encoding: "utf-8", errors: "strict"}, null, null),
2021
encoding = $.encoding,
2022
errors = $.errors
2023
}
2034
// class or its subclasses, but the attribute __str__ of the
2035
// class metaclass (usually "type") or its subclasses (usually
2036
// "object")
2037
// The metaclass is the attribute __class__ of the class dictionary
2042
if(arg.__class__ && arg.__class__ === _b_.bytes &&
2043
encoding !== undefined){
2044
// str(bytes, encoding, errors) is equal to
2045
// bytes.decode(encoding, errors)
2048
// Implicit invocation of __str__ uses method __str__ on the class,
2049
// even if arg has an attribute __str__
2050
var klass = arg.__class__ || $B.get_class(arg)
2051
if(klass === undefined){
2052
return $B.JSObject.__str__($B.JSObject.$factory(arg))
2053
}
2056
// if not better than object.__str__, try __repr__
2057
(arg.__class__ && arg.__class__ !== _b_.object &&
2058
method.$infos && method.$infos.__func__ === _b_.object.__str__)){
2059
var method = $B.$getattr(klass, "__repr__")
2065
if($B.debug > 1){console.log(err)}
2066
console.log("Warning - no method __str__ or __repr__, " +
2067
"default to toString", arg)
2074
if(cls === undefined){
2075
throw _b_.TypeError.$factory("str.__new__(): not enough arguments")
2099
var args = [],
2100
pos = 0
2101
if(arguments.length > 0){
2102
var args = [arguments[0].valueOf()],
2103
pos = 1
2104
for(var i = 1, len = arguments.length; i < len; i++){
2105
args[pos++] = arguments[i]
2121
// Function to parse the 2nd argument of format()
2122
$B.parse_format_spec = function(spec){
2125
var pos = 0,
2126
aligns = "<>=^",
2127
digits = "0123456789",
2128
types = "bcdeEfFgGnosxX%",
2130
if(align_pos != -1){
2131
if(spec.charAt(1) && aligns.indexOf(spec.charAt(1)) != -1){
2132
// If the second char is also an alignment specifier, the
2133
// first char is the fill value
2134
this.fill = spec.charAt(0)
2135
this.align = spec.charAt(1)
2136
pos = 2
2137
}else{
2138
// The first character defines alignment : fill defaults to ' '
2153
if(car == "+" || car == "-" || car == " "){
2154
this.sign = car
2155
pos++
2156
car = spec.charAt(pos)
2158
if(car == "#"){this.alternate = true; pos++; car = spec.charAt(pos)}
2159
if(car == "0"){
2168
while(car && digits.indexOf(car) > -1){
2169
if(this.width === undefined){this.width = car}
2170
else{this.width += car}
2171
pos++
2172
car = spec.charAt(pos)
2175
if(this.width === undefined && car == "{"){
2176
// Width is determined by a parameter
2177
var end_param_pos = spec.substr(pos).search("}")
2178
this.width = spec.substring(pos, end_param_pos)
2179
console.log("width", "[" + this.width + "]")
2180
pos += end_param_pos + 1
2181
}
2182
if(car == ","){this.comma = true; pos++; car = spec.charAt(pos)}
2183
if(car == "."){
2184
if(digits.indexOf(spec.charAt(pos + 1)) == -1){
2185
throw _b_.ValueError.$factory(
2186
"Missing precision in format spec")
2188
this.precision = spec.charAt(pos + 1)
2189
pos += 2
2190
car = spec.charAt(pos)
2191
while(car && digits.indexOf(car) > -1){
2198
if(car && types.indexOf(car) > -1){
2199
this.type = car
2200
pos++
2201
car = spec.charAt(pos)
2202
}
2203
if(pos !== spec.length){
2209
return (this.fill === undefined ? "" : _b_.str.$factory(this.fill)) +
2210
(this.align || "") +
2211
(this.sign || "") +
2212
(this.alternate ? "#" : "") +
2213
(this.sign_aware ? "0" : "") +
2214
(this.width || "") +
2215
(this.comma ? "," : "") +
2216
(this.precision ? "." + this.precision : "") +
2217
(this.type || "")
2222
if(fmt.width && s.length < fmt.width){
2223
var fill = fmt.fill || " ",
2224
align = fmt.align || "<",
2225
missing = fmt.width - s.length
2227
case "<":
2228
return s + fill.repeat(missing)
2229
case ">":
2230
return fill.repeat(missing) + s
2231
case "=":
2232
if("+-".indexOf(s.charAt(0)) > -1){
2233
return s.charAt(0) + fill.repeat(missing) + s.substr(1)
2237
case "^":
2238
var left = parseInt(missing / 2)
2239
return fill.repeat(left) + s + fill.repeat(missing - left)
2252
$B.parse_fstring = function(string){
2253
// Parse a f-string
2254
var elts = [],
2255
pos = 0,
2279
}else{
2280
throw Error(" f-string: single '}' is not allowed")
2281
}
2282
}else{
2304
current += car
2305
i += 2
2306
}else{
2307
throw Error(" f-string: single '}' is not allowed")
2308
}
2309
}else{
2310
current += car
2311
i++
2312
}
2313
}
2315
}else if(ctype == "debug"){
2316
// after the equal sign, whitespace are ignored and the only
2317
// valid characters are } and :
2318
while(string.charAt(i) == " "){i++}
2319
if(string.charAt(i) == "}"){
2320
// end of debug expression
2321
elts.push(current)
2322
ctype = null
2323
current = ""
2324
pos = i + 1
2325
}
2326
}else{
2327
// End of expression is the } matching the opening {
2328
// There may be nested braces
2329
var i = pos,
2330
nb_braces = 1,
2352
// backslash is not allowed in expressions
2353
throw Error("f-string expression part cannot include a" +
2354
" backslash")
2361
throw Error("f-string: invalid conversion character:" +
2362
" expected 's', 'r', or 'a'")
2363
}else{
2377
if(string.substr(i, 3) == '"""'){
2378
var end = string.indexOf('"""', i + 3)
2379
if(end == -1){
2380
throw Error("f-string: unterminated string")
2381
}else{
2382
var trs = string.substring(i, end + 3)
2383
trs = trs.replace("\n", "\\n\\")
2388
var end = string.indexOf('"', i + 1)
2389
if(end == -1){
2390
throw Error("f-string: unterminated string")
2391
}else{
2392
current.expression += string.substring(i, end + 1)
2393
i = end + 1
2400
}else if(car == "="){
2401
// might be a "debug expression", eg f"{x=}"
2402
var ce = current.expression
2403
if(ce.length == 0 ||
2404
string.charAt(i + 1) == "=" ||
2405
"=!<>:".search(ce.charAt(ce.length - 1)) > -1){
2408
}else{
2409
// add debug string
2410
tail = car
2411
while(string.charAt(i + 1).match(/\s/)){
2412
tail += string.charAt(i + 1)
2413
i++
2414
}
2415
elts.push(current.expression + tail)
2416
// remove trailing whitespace from expression
2417
while(ce.match(/\s$/)){
2418
ce = ce.substr(0, ce.length - 1)
2419
}
2420
current.expression = ce
2421
ctype = "debug"
2422
i++
2423
}
2438
// Class for strings with surrogate pairs. We can't rely on Javascript
2439
// strings in this case because they don't count characters like Python
2440
2441
var surrogate = str.$surrogate = $B.make_class("surrogate_string", function(s){
2442
// create an instance of str subclass for strings with surrogate pairs
2443
var items = []
2444
for(var i = 0, len = s.length; i < len; i++){
2445
var code = s.charCodeAt(i)
2446
if(code >= 0xD800 && code <= 0xDBFF){
2447
i++
2448
var low = s.charCodeAt(i)
2449
code = ((code - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000
2450
}
2451
items.push(String.fromCodePoint(code))
2452
}
2453
return {
2454
__class__: str.$surrogate,
2455
items: items
2456
}
2457
})
2458
2459
surrogate.__mro__ = [str, object]
2460
2461
surrogate.__contains__ = function(self, other){
2462
return str.__contains__(self.items.join(''), other)
2463
}
2464
2465
surrogate.__getitem__ = function(self, arg){
2466
if(isinstance(arg, _b_.int)){
2467
var pos = arg
2468
if(arg < 0){
2469
pos += self.items.length
2470
}
2471
if(pos >= 0 && pos < self.items.length){
2472
if(self.items[pos].length == 2){
2473
return surrogate.$factory(self.items[pos])
2474
}
2475
return self.items[pos]
2476
}
2477
throw _b_.IndexError.$factory("string index out of range")
2478
}
2479
if(isinstance(arg, slice)) {
2480
var s = _b_.slice.$conv_for_seq(arg, self.items.length),
2481
start = s.start,
2482
stop = s.stop,
2483
step = s.step
2484
var res = "",
2485
i = null
2486
if(step > 0){
2487
if(stop <= start){return ""}
2488
for(var i = start; i < stop; i += step){
2489
res += self.items[i]
2490
}
2491
}else{
2492
if(stop >= start){return ''}
2493
for(var i = start; i > stop; i += step){
2494
res += self.items[i]
2495
}
2496
}
2497
return res
2498
}
2499
if(isinstance(arg, _b_.bool)){
2500
return surrogate.__getitem__(self, _b_.int.$factory(arg))
2501
}
2502
throw _b_.TypeError.$factory("string indices must be integers")
2503
}
2504
2505
surrogate.__hash__ = function(self){
2506
return str.__hash__(self.items.join(''))
2507
}
2508
2509
surrogate.__iter__ = function(self){
2510
return str_iterator.$factory(self.items)
2511
}
2512
2513
surrogate.__len__ = function(self){
2514
return self.items.length
2515
}
2516
2517
surrogate.__repr__ = function(self){
2518
return str.__repr__(self.items.join(''))
2519
}
2520
2521
surrogate.__str__ = function(self){
2522
return str.__str__(self.items.join(''))
2523
}
2524
2525
$B.set_func_names(surrogate, "builtins")
2526
2527