Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 0d6615f

Browse files
committed
PEP 342 implementation. Per Guido's comments, the generator throw()
method still needs to support string exceptions, and allow None for the third argument. Documentation updates are needed, too.
1 parent d794666 commit 0d6615f

16 files changed

Lines changed: 785 additions & 165 deletions

File tree

Grammar/Grammar

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ fplist: fpdef (',' fpdef)* [',']
3939
stmt: simple_stmt | compound_stmt
4040
simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
4141
small_stmt: expr_stmt | print_stmt | del_stmt | pass_stmt | flow_stmt | import_stmt | global_stmt | exec_stmt | assert_stmt
42-
expr_stmt: testlist (augassign testlist | ('=' testlist)*)
42+
expr_stmt: testlist (augassign (yield_expr|testlist) | ('=' (yield_expr|testlist))*)
4343
augassign: '+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^=' | '<<=' | '>>=' | '**=' | '//='
4444
# For normal assignments, additional restrictions enforced by the interpreter
4545
print_stmt: 'print' ( [ test (',' test)* [','] ] | '>>' test [ (',' test)+ [','] ] )
@@ -49,7 +49,7 @@ flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | yield_stmt
4949
break_stmt: 'break'
5050
continue_stmt: 'continue'
5151
return_stmt: 'return' [testlist]
52-
yield_stmt: 'yield' testlist
52+
yield_stmt: yield_expr
5353
raise_stmt: 'raise' [test [',' test [',' test]]]
5454
import_stmt: import_name | import_from
5555
import_name: 'import' dotted_as_names
@@ -86,7 +86,7 @@ arith_expr: term (('+'|'-') term)*
8686
term: factor (('*'|'/'|'%'|'//') factor)*
8787
factor: ('+'|'-'|'~') factor | power
8888
power: atom trailer* ['**' factor]
89-
atom: '(' [testlist_gexp] ')' | '[' [listmaker] ']' | '{' [dictmaker] '}' | '`' testlist1 '`' | NAME | NUMBER | STRING+
89+
atom: '(' [yield_expr|testlist_gexp] ')' | '[' [listmaker] ']' | '{' [dictmaker] '}' | '`' testlist1 '`' | NAME | NUMBER | STRING+
9090
listmaker: test ( list_for | (',' test)* [','] )
9191
testlist_gexp: test ( gen_for | (',' test)* [','] )
9292
lambdef: 'lambda' [varargslist] ':' test
@@ -116,3 +116,6 @@ testlist1: test (',' test)*
116116

117117
# not used in grammar, but may appear in "node" passed from Parser to Compiler
118118
encoding_decl: NAME
119+
120+
yield_expr: 'yield' [testlist]
121+

Include/ceval.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ PyAPI_FUNC(char *) PyEval_GetFuncDesc(PyObject *);
6565

6666
PyAPI_FUNC(PyObject *) PyEval_GetCallStats(PyObject *);
6767
PyAPI_FUNC(PyObject *) PyEval_EvalFrame(struct _frame *);
68+
PyAPI_FUNC(PyObject *) PyEval_EvalFrameEx(struct _frame *f, int exc);
6869

6970
/* this used to be handled on a per-thread basis - now just two globals */
7071
PyAPI_DATA(volatile int) _Py_Ticker;

Include/graminit.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,3 +76,4 @@
7676
#define gen_if 331
7777
#define testlist1 332
7878
#define encoding_decl 333
79+
#define yield_expr 334

Include/pyerrors.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ PyAPI_FUNC(void) PyErr_NormalizeException(PyObject**, PyObject**, PyObject**);
2525

2626
PyAPI_DATA(PyObject *) PyExc_Exception;
2727
PyAPI_DATA(PyObject *) PyExc_StopIteration;
28+
PyAPI_DATA(PyObject *) PyExc_GeneratorExit;
2829
PyAPI_DATA(PyObject *) PyExc_StandardError;
2930
PyAPI_DATA(PyObject *) PyExc_ArithmeticError;
3031
PyAPI_DATA(PyObject *) PyExc_LookupError;

Lib/compiler/transformer.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -403,7 +403,15 @@ def return_stmt(self, nodelist):
403403
return Return(self.com_node(nodelist[1]), lineno=nodelist[0][2])
404404

405405
def yield_stmt(self, nodelist):
406-
return Yield(self.com_node(nodelist[1]), lineno=nodelist[0][2])
406+
expr = self.com_node(nodelist[0])
407+
return Discard(expr, lineno=expr.lineno)
408+
409+
def yield_expr(self, nodelist):
410+
if len(nodelist)>1:
411+
value = nodelist[1]
412+
else:
413+
value = Const(None)
414+
return Yield(self.com_node(value), lineno=nodelist[0][2])
407415

408416
def raise_stmt(self, nodelist):
409417
# raise: [test [',' test [',' test]]]
@@ -1402,6 +1410,8 @@ def get_docstring(self, node, n=None):
14021410

14031411
if hasattr(symbol, 'yield_stmt'):
14041412
_legal_node_types.append(symbol.yield_stmt)
1413+
if hasattr(symbol, 'yield_expr'):
1414+
_legal_node_types.append(symbol.yield_expr)
14051415

14061416
_assign_types = [
14071417
symbol.test,

Lib/symbol.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@
8888
gen_if = 331
8989
testlist1 = 332
9090
encoding_decl = 333
91+
yield_expr = 334
9192
#--end constants--
9293

9394
sym_name = {}

0 commit comments

Comments
 (0)