Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
P
Pyston
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Boxiang Sun
Pyston
Commits
934d8f6f
Commit
934d8f6f
authored
Jul 29, 2014
by
Kevin Modzelewski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implement set literals
parent
58eb408a
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
120 additions
and
1 deletion
+120
-1
src/analysis/type_analysis.cpp
src/analysis/type_analysis.cpp
+2
-0
src/codegen/irgen/irgenerator.cpp
src/codegen/irgen/irgenerator.cpp
+29
-0
src/codegen/parser.cpp
src/codegen/parser.cpp
+12
-0
src/codegen/runtime_hooks.cpp
src/codegen/runtime_hooks.cpp
+2
-0
src/codegen/runtime_hooks.h
src/codegen/runtime_hooks.h
+1
-1
src/core/ast.cpp
src/core/ast.cpp
+33
-0
src/core/ast.h
src/core/ast.h
+16
-0
src/core/cfg.cpp
src/core/cfg.cpp
+15
-0
src/runtime/inline/link_forcer.cpp
src/runtime/inline/link_forcer.cpp
+2
-0
src/runtime/set.cpp
src/runtime/set.cpp
+4
-0
src/runtime/set.h
src/runtime/set.h
+2
-0
test/tests/set.py
test/tests/set.py
+2
-0
No files found.
src/analysis/type_analysis.cpp
View file @
934d8f6f
...
@@ -415,6 +415,8 @@ private:
...
@@ -415,6 +415,8 @@ private:
virtual
void
*
visit_repr
(
AST_Repr
*
node
)
{
return
STR
;
}
virtual
void
*
visit_repr
(
AST_Repr
*
node
)
{
return
STR
;
}
virtual
void
*
visit_set
(
AST_Set
*
node
)
{
return
SET
;
}
virtual
void
*
visit_slice
(
AST_Slice
*
node
)
{
return
SLICE
;
}
virtual
void
*
visit_slice
(
AST_Slice
*
node
)
{
return
SLICE
;
}
virtual
void
*
visit_str
(
AST_Str
*
node
)
{
return
STR
;
}
virtual
void
*
visit_str
(
AST_Str
*
node
)
{
return
STR
;
}
...
...
src/codegen/irgen/irgenerator.cpp
View file @
934d8f6f
...
@@ -754,6 +754,32 @@ private:
...
@@ -754,6 +754,32 @@ private:
return
new
ConcreteCompilerVariable
(
STR
,
rtn
,
true
);
return
new
ConcreteCompilerVariable
(
STR
,
rtn
,
true
);
}
}
CompilerVariable
*
evalSet
(
AST_Set
*
node
,
ExcInfo
exc_info
)
{
assert
(
state
!=
PARTIAL
);
std
::
vector
<
CompilerVariable
*>
elts
;
for
(
int
i
=
0
;
i
<
node
->
elts
.
size
();
i
++
)
{
CompilerVariable
*
value
=
evalExpr
(
node
->
elts
[
i
],
exc_info
);
elts
.
push_back
(
value
);
}
llvm
::
Value
*
v
=
emitter
.
getBuilder
()
->
CreateCall
(
g
.
funcs
.
createSet
);
ConcreteCompilerVariable
*
rtn
=
new
ConcreteCompilerVariable
(
SET
,
v
,
true
);
static
std
::
string
add_str
(
"add"
);
for
(
int
i
=
0
;
i
<
node
->
elts
.
size
();
i
++
)
{
CompilerVariable
*
elt
=
elts
[
i
];
CompilerVariable
*
r
=
rtn
->
callattr
(
emitter
,
getOpInfoForNode
(
node
,
exc_info
),
&
add_str
,
true
,
ArgPassSpec
(
1
),
{
elt
},
NULL
);
r
->
decvref
(
emitter
);
elt
->
decvref
(
emitter
);
}
return
rtn
;
}
CompilerVariable
*
evalSlice
(
AST_Slice
*
node
,
ExcInfo
exc_info
)
{
CompilerVariable
*
evalSlice
(
AST_Slice
*
node
,
ExcInfo
exc_info
)
{
assert
(
state
!=
PARTIAL
);
assert
(
state
!=
PARTIAL
);
...
@@ -930,6 +956,9 @@ private:
...
@@ -930,6 +956,9 @@ private:
case
AST_TYPE
:
:
Repr
:
case
AST_TYPE
:
:
Repr
:
rtn
=
evalRepr
(
ast_cast
<
AST_Repr
>
(
node
),
exc_info
);
rtn
=
evalRepr
(
ast_cast
<
AST_Repr
>
(
node
),
exc_info
);
break
;
break
;
case
AST_TYPE
:
:
Set
:
rtn
=
evalSet
(
ast_cast
<
AST_Set
>
(
node
),
exc_info
);
break
;
case
AST_TYPE
:
:
Slice
:
case
AST_TYPE
:
:
Slice
:
rtn
=
evalSlice
(
ast_cast
<
AST_Slice
>
(
node
),
exc_info
);
rtn
=
evalSlice
(
ast_cast
<
AST_Slice
>
(
node
),
exc_info
);
break
;
break
;
...
...
src/codegen/parser.cpp
View file @
934d8f6f
...
@@ -578,6 +578,16 @@ AST_Return* read_return(BufferedReader* reader) {
...
@@ -578,6 +578,16 @@ AST_Return* read_return(BufferedReader* reader) {
return
rtn
;
return
rtn
;
}
}
AST_Set
*
read_set
(
BufferedReader
*
reader
)
{
AST_Set
*
rtn
=
new
AST_Set
();
rtn
->
col_offset
=
readColOffset
(
reader
);
readExprVector
(
rtn
->
elts
,
reader
);
rtn
->
lineno
=
reader
->
readULL
();
return
rtn
;
}
AST_Slice
*
read_slice
(
BufferedReader
*
reader
)
{
AST_Slice
*
read_slice
(
BufferedReader
*
reader
)
{
AST_Slice
*
rtn
=
new
AST_Slice
();
AST_Slice
*
rtn
=
new
AST_Slice
();
...
@@ -742,6 +752,8 @@ AST_expr* readASTExpr(BufferedReader* reader) {
...
@@ -742,6 +752,8 @@ AST_expr* readASTExpr(BufferedReader* reader) {
return
read_num
(
reader
);
return
read_num
(
reader
);
case
AST_TYPE
:
:
Repr
:
case
AST_TYPE
:
:
Repr
:
return
read_repr
(
reader
);
return
read_repr
(
reader
);
case
AST_TYPE
:
:
Set
:
return
read_set
(
reader
);
case
AST_TYPE
:
:
Slice
:
case
AST_TYPE
:
:
Slice
:
return
read_slice
(
reader
);
return
read_slice
(
reader
);
case
AST_TYPE
:
:
Str
:
case
AST_TYPE
:
:
Str
:
...
...
src/codegen/runtime_hooks.cpp
View file @
934d8f6f
...
@@ -39,6 +39,7 @@
...
@@ -39,6 +39,7 @@
#include "runtime/int.h"
#include "runtime/int.h"
#include "runtime/long.h"
#include "runtime/long.h"
#include "runtime/objmodel.h"
#include "runtime/objmodel.h"
#include "runtime/set.h"
#include "runtime/types.h"
#include "runtime/types.h"
extern
"C"
void
*
__cxa_begin_catch
(
void
*
);
extern
"C"
void
*
__cxa_begin_catch
(
void
*
);
...
@@ -173,6 +174,7 @@ void initGlobalFuncs(GlobalState& g) {
...
@@ -173,6 +174,7 @@ void initGlobalFuncs(GlobalState& g) {
GET
(
createClosure
);
GET
(
createClosure
);
GET
(
createGenerator
);
GET
(
createGenerator
);
GET
(
createLong
);
GET
(
createLong
);
GET
(
createSet
);
GET
(
getattr
);
GET
(
getattr
);
GET
(
setattr
);
GET
(
setattr
);
...
...
src/codegen/runtime_hooks.h
View file @
934d8f6f
...
@@ -32,7 +32,7 @@ struct GlobalFuncs {
...
@@ -32,7 +32,7 @@ struct GlobalFuncs {
llvm
::
Value
*
boxInt
,
*
unboxInt
,
*
boxFloat
,
*
unboxFloat
,
*
boxStringPtr
,
*
boxCLFunction
,
*
unboxCLFunction
,
llvm
::
Value
*
boxInt
,
*
unboxInt
,
*
boxFloat
,
*
unboxFloat
,
*
boxStringPtr
,
*
boxCLFunction
,
*
unboxCLFunction
,
*
boxInstanceMethod
,
*
boxBool
,
*
unboxBool
,
*
createTuple
,
*
createDict
,
*
createList
,
*
createSlice
,
*
boxInstanceMethod
,
*
boxBool
,
*
unboxBool
,
*
createTuple
,
*
createDict
,
*
createList
,
*
createSlice
,
*
createUserClass
,
*
createClosure
,
*
createGenerator
,
*
createLong
;
*
createUserClass
,
*
createClosure
,
*
createGenerator
,
*
createLong
,
*
createSet
;
llvm
::
Value
*
getattr
,
*
setattr
,
*
delattr
,
*
delitem
,
*
delGlobal
,
*
print
,
*
nonzero
,
*
binop
,
*
compare
,
*
augbinop
,
llvm
::
Value
*
getattr
,
*
setattr
,
*
delattr
,
*
delitem
,
*
delGlobal
,
*
print
,
*
nonzero
,
*
binop
,
*
compare
,
*
augbinop
,
*
unboxedLen
,
*
getitem
,
*
getclsattr
,
*
getGlobal
,
*
setitem
,
*
unaryop
,
*
import
,
*
importFrom
,
*
importStar
,
*
repr
,
*
unboxedLen
,
*
getitem
,
*
getclsattr
,
*
getGlobal
,
*
setitem
,
*
unaryop
,
*
import
,
*
importFrom
,
*
importStar
,
*
repr
,
*
isinstance
,
*
yield
;
*
isinstance
,
*
yield
;
...
...
src/core/ast.cpp
View file @
934d8f6f
...
@@ -706,6 +706,18 @@ void AST_Return::accept_stmt(StmtVisitor* v) {
...
@@ -706,6 +706,18 @@ void AST_Return::accept_stmt(StmtVisitor* v) {
v
->
visit_return
(
this
);
v
->
visit_return
(
this
);
}
}
void
AST_Set
::
accept
(
ASTVisitor
*
v
)
{
bool
skip
=
v
->
visit_set
(
this
);
if
(
skip
)
return
;
visitVector
(
elts
,
v
);
}
void
*
AST_Set
::
accept_expr
(
ExprVisitor
*
v
)
{
return
v
->
visit_set
(
this
);
}
void
AST_Slice
::
accept
(
ASTVisitor
*
v
)
{
void
AST_Slice
::
accept
(
ASTVisitor
*
v
)
{
bool
skip
=
v
->
visit_slice
(
this
);
bool
skip
=
v
->
visit_slice
(
this
);
if
(
skip
)
if
(
skip
)
...
@@ -1443,6 +1455,23 @@ bool PrintVisitor::visit_return(AST_Return* node) {
...
@@ -1443,6 +1455,23 @@ bool PrintVisitor::visit_return(AST_Return* node) {
return
false
;
return
false
;
}
}
bool
PrintVisitor
::
visit_set
(
AST_Set
*
node
)
{
assert
(
node
->
elts
.
size
());
printf
(
"{"
);
bool
first
=
true
;
for
(
auto
e
:
node
->
elts
)
{
if
(
!
first
)
printf
(
", "
);
first
=
false
;
e
->
accept
(
this
);
}
printf
(
"}"
);
return
true
;
}
bool
PrintVisitor
::
visit_slice
(
AST_Slice
*
node
)
{
bool
PrintVisitor
::
visit_slice
(
AST_Slice
*
node
)
{
printf
(
"<slice>("
);
printf
(
"<slice>("
);
if
(
node
->
lower
)
if
(
node
->
lower
)
...
@@ -1825,6 +1854,10 @@ public:
...
@@ -1825,6 +1854,10 @@ public:
output
->
push_back
(
node
);
output
->
push_back
(
node
);
return
false
;
return
false
;
}
}
virtual
bool
visit_set
(
AST_Set
*
node
)
{
output
->
push_back
(
node
);
return
false
;
}
virtual
bool
visit_slice
(
AST_Slice
*
node
)
{
virtual
bool
visit_slice
(
AST_Slice
*
node
)
{
output
->
push_back
(
node
);
output
->
push_back
(
node
);
return
false
;
return
false
;
...
...
src/core/ast.h
View file @
934d8f6f
...
@@ -683,6 +683,18 @@ public:
...
@@ -683,6 +683,18 @@ public:
static
const
AST_TYPE
::
AST_TYPE
TYPE
=
AST_TYPE
::
Return
;
static
const
AST_TYPE
::
AST_TYPE
TYPE
=
AST_TYPE
::
Return
;
};
};
class
AST_Set
:
public
AST_expr
{
public:
std
::
vector
<
AST_expr
*>
elts
;
virtual
void
accept
(
ASTVisitor
*
v
);
virtual
void
*
accept_expr
(
ExprVisitor
*
v
);
AST_Set
()
:
AST_expr
(
AST_TYPE
::
Set
)
{}
static
const
AST_TYPE
::
AST_TYPE
TYPE
=
AST_TYPE
::
Set
;
};
class
AST_Slice
:
public
AST_expr
{
class
AST_Slice
:
public
AST_expr
{
public:
public:
AST_expr
*
lower
,
*
upper
,
*
step
;
AST_expr
*
lower
,
*
upper
,
*
step
;
...
@@ -963,6 +975,7 @@ public:
...
@@ -963,6 +975,7 @@ public:
virtual
bool
visit_raise
(
AST_Raise
*
node
)
{
RELEASE_ASSERT
(
0
,
""
);
}
virtual
bool
visit_raise
(
AST_Raise
*
node
)
{
RELEASE_ASSERT
(
0
,
""
);
}
virtual
bool
visit_repr
(
AST_Repr
*
node
)
{
RELEASE_ASSERT
(
0
,
""
);
}
virtual
bool
visit_repr
(
AST_Repr
*
node
)
{
RELEASE_ASSERT
(
0
,
""
);
}
virtual
bool
visit_return
(
AST_Return
*
node
)
{
RELEASE_ASSERT
(
0
,
""
);
}
virtual
bool
visit_return
(
AST_Return
*
node
)
{
RELEASE_ASSERT
(
0
,
""
);
}
virtual
bool
visit_set
(
AST_Set
*
node
)
{
RELEASE_ASSERT
(
0
,
""
);
}
virtual
bool
visit_slice
(
AST_Slice
*
node
)
{
RELEASE_ASSERT
(
0
,
""
);
}
virtual
bool
visit_slice
(
AST_Slice
*
node
)
{
RELEASE_ASSERT
(
0
,
""
);
}
virtual
bool
visit_str
(
AST_Str
*
node
)
{
RELEASE_ASSERT
(
0
,
""
);
}
virtual
bool
visit_str
(
AST_Str
*
node
)
{
RELEASE_ASSERT
(
0
,
""
);
}
virtual
bool
visit_subscript
(
AST_Subscript
*
node
)
{
RELEASE_ASSERT
(
0
,
""
);
}
virtual
bool
visit_subscript
(
AST_Subscript
*
node
)
{
RELEASE_ASSERT
(
0
,
""
);
}
...
@@ -1027,6 +1040,7 @@ public:
...
@@ -1027,6 +1040,7 @@ public:
virtual
bool
visit_raise
(
AST_Raise
*
node
)
{
return
false
;
}
virtual
bool
visit_raise
(
AST_Raise
*
node
)
{
return
false
;
}
virtual
bool
visit_repr
(
AST_Repr
*
node
)
{
return
false
;
}
virtual
bool
visit_repr
(
AST_Repr
*
node
)
{
return
false
;
}
virtual
bool
visit_return
(
AST_Return
*
node
)
{
return
false
;
}
virtual
bool
visit_return
(
AST_Return
*
node
)
{
return
false
;
}
virtual
bool
visit_set
(
AST_Set
*
node
)
{
return
false
;
}
virtual
bool
visit_slice
(
AST_Slice
*
node
)
{
return
false
;
}
virtual
bool
visit_slice
(
AST_Slice
*
node
)
{
return
false
;
}
virtual
bool
visit_str
(
AST_Str
*
node
)
{
return
false
;
}
virtual
bool
visit_str
(
AST_Str
*
node
)
{
return
false
;
}
virtual
bool
visit_subscript
(
AST_Subscript
*
node
)
{
return
false
;
}
virtual
bool
visit_subscript
(
AST_Subscript
*
node
)
{
return
false
;
}
...
@@ -1066,6 +1080,7 @@ public:
...
@@ -1066,6 +1080,7 @@ public:
virtual
void
*
visit_name
(
AST_Name
*
node
)
{
RELEASE_ASSERT
(
0
,
""
);
}
virtual
void
*
visit_name
(
AST_Name
*
node
)
{
RELEASE_ASSERT
(
0
,
""
);
}
virtual
void
*
visit_num
(
AST_Num
*
node
)
{
RELEASE_ASSERT
(
0
,
""
);
}
virtual
void
*
visit_num
(
AST_Num
*
node
)
{
RELEASE_ASSERT
(
0
,
""
);
}
virtual
void
*
visit_repr
(
AST_Repr
*
node
)
{
RELEASE_ASSERT
(
0
,
""
);
}
virtual
void
*
visit_repr
(
AST_Repr
*
node
)
{
RELEASE_ASSERT
(
0
,
""
);
}
virtual
void
*
visit_set
(
AST_Set
*
node
)
{
RELEASE_ASSERT
(
0
,
""
);
}
virtual
void
*
visit_slice
(
AST_Slice
*
node
)
{
RELEASE_ASSERT
(
0
,
""
);
}
virtual
void
*
visit_slice
(
AST_Slice
*
node
)
{
RELEASE_ASSERT
(
0
,
""
);
}
virtual
void
*
visit_str
(
AST_Str
*
node
)
{
RELEASE_ASSERT
(
0
,
""
);
}
virtual
void
*
visit_str
(
AST_Str
*
node
)
{
RELEASE_ASSERT
(
0
,
""
);
}
virtual
void
*
visit_subscript
(
AST_Subscript
*
node
)
{
RELEASE_ASSERT
(
0
,
""
);
}
virtual
void
*
visit_subscript
(
AST_Subscript
*
node
)
{
RELEASE_ASSERT
(
0
,
""
);
}
...
@@ -1161,6 +1176,7 @@ public:
...
@@ -1161,6 +1176,7 @@ public:
virtual
bool
visit_raise
(
AST_Raise
*
node
);
virtual
bool
visit_raise
(
AST_Raise
*
node
);
virtual
bool
visit_repr
(
AST_Repr
*
node
);
virtual
bool
visit_repr
(
AST_Repr
*
node
);
virtual
bool
visit_return
(
AST_Return
*
node
);
virtual
bool
visit_return
(
AST_Return
*
node
);
virtual
bool
visit_set
(
AST_Set
*
node
);
virtual
bool
visit_slice
(
AST_Slice
*
node
);
virtual
bool
visit_slice
(
AST_Slice
*
node
);
virtual
bool
visit_str
(
AST_Str
*
node
);
virtual
bool
visit_str
(
AST_Str
*
node
);
virtual
bool
visit_subscript
(
AST_Subscript
*
node
);
virtual
bool
visit_subscript
(
AST_Subscript
*
node
);
...
...
src/core/cfg.cpp
View file @
934d8f6f
...
@@ -669,6 +669,18 @@ private:
...
@@ -669,6 +669,18 @@ private:
return
rtn
;
return
rtn
;
}
}
AST_expr
*
remapSet
(
AST_Set
*
node
)
{
AST_Set
*
rtn
=
new
AST_Set
();
rtn
->
lineno
=
node
->
lineno
;
rtn
->
col_offset
=
node
->
col_offset
;
for
(
auto
e
:
node
->
elts
)
{
rtn
->
elts
.
push_back
(
remapExpr
(
e
));
}
return
rtn
;
}
AST_expr
*
remapSlice
(
AST_Slice
*
node
)
{
AST_expr
*
remapSlice
(
AST_Slice
*
node
)
{
AST_Slice
*
rtn
=
new
AST_Slice
();
AST_Slice
*
rtn
=
new
AST_Slice
();
rtn
->
lineno
=
node
->
lineno
;
rtn
->
lineno
=
node
->
lineno
;
...
@@ -778,6 +790,9 @@ private:
...
@@ -778,6 +790,9 @@ private:
case
AST_TYPE
:
:
Repr
:
case
AST_TYPE
:
:
Repr
:
rtn
=
remapRepr
(
ast_cast
<
AST_Repr
>
(
node
));
rtn
=
remapRepr
(
ast_cast
<
AST_Repr
>
(
node
));
break
;
break
;
case
AST_TYPE
:
:
Set
:
rtn
=
remapSet
(
ast_cast
<
AST_Set
>
(
node
));
break
;
case
AST_TYPE
:
:
Slice
:
case
AST_TYPE
:
:
Slice
:
rtn
=
remapSlice
(
ast_cast
<
AST_Slice
>
(
node
));
rtn
=
remapSlice
(
ast_cast
<
AST_Slice
>
(
node
));
break
;
break
;
...
...
src/runtime/inline/link_forcer.cpp
View file @
934d8f6f
...
@@ -25,6 +25,7 @@
...
@@ -25,6 +25,7 @@
#include "runtime/list.h"
#include "runtime/list.h"
#include "runtime/long.h"
#include "runtime/long.h"
#include "runtime/objmodel.h"
#include "runtime/objmodel.h"
#include "runtime/set.h"
#include "runtime/types.h"
#include "runtime/types.h"
namespace
pyston
{
namespace
pyston
{
...
@@ -62,6 +63,7 @@ void force() {
...
@@ -62,6 +63,7 @@ void force() {
FORCE
(
createClosure
);
FORCE
(
createClosure
);
FORCE
(
createGenerator
);
FORCE
(
createGenerator
);
FORCE
(
createLong
);
FORCE
(
createLong
);
FORCE
(
createSet
);
FORCE
(
getattr
);
FORCE
(
getattr
);
FORCE
(
setattr
);
FORCE
(
setattr
);
...
...
src/runtime/set.cpp
View file @
934d8f6f
...
@@ -31,6 +31,10 @@ extern "C" void setIteratorGCHandler(GCVisitor* v, void* p);
...
@@ -31,6 +31,10 @@ extern "C" void setIteratorGCHandler(GCVisitor* v, void* p);
const
ObjectFlavor
set_flavor
(
&
setGCHandler
,
NULL
);
const
ObjectFlavor
set_flavor
(
&
setGCHandler
,
NULL
);
const
ObjectFlavor
set_iterator_flavor
(
&
setIteratorGCHandler
,
NULL
);
const
ObjectFlavor
set_iterator_flavor
(
&
setIteratorGCHandler
,
NULL
);
extern
"C"
Box
*
createSet
()
{
return
new
BoxedSet
(
set_cls
);
}
namespace
set
{
namespace
set
{
class
BoxedSetIterator
:
public
Box
{
class
BoxedSetIterator
:
public
Box
{
...
...
src/runtime/set.h
View file @
934d8f6f
...
@@ -28,6 +28,8 @@ void teardownSet();
...
@@ -28,6 +28,8 @@ void teardownSet();
extern
BoxedClass
*
set_cls
,
*
frozenset_cls
;
extern
BoxedClass
*
set_cls
,
*
frozenset_cls
;
extern
const
ObjectFlavor
set_flavor
,
frozenset_flavor
;
extern
const
ObjectFlavor
set_flavor
,
frozenset_flavor
;
extern
"C"
Box
*
createSet
();
class
BoxedSet
:
public
Box
{
class
BoxedSet
:
public
Box
{
public:
public:
std
::
unordered_set
<
Box
*
,
PyHasher
,
PyEq
,
StlCompatAllocator
<
Box
*>
>
s
;
std
::
unordered_set
<
Box
*
,
PyHasher
,
PyEq
,
StlCompatAllocator
<
Box
*>
>
s
;
...
...
test/tests/set.py
View file @
934d8f6f
s1
=
{
1
}
def
sorted
(
s
):
def
sorted
(
s
):
l
=
list
(
s
)
l
=
list
(
s
)
l
.
sort
()
l
.
sort
()
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment