All three times plus extra edition. Overview and summary of adding post-increment to CPython Implementation of CPython with post-increment List of all changes when adding post-increment to CPython Extra edition of adding post-increment to CPython
Originally, increment was a task for practicing changing list comprehensions. However, it was more difficult to implement than expected, partly because the increment did not fit the design concept. Regardless of the concept, changing the list comprehension will be completed in about five minutes if you have the knowledge so far.
First, we use DOSS_HASKELL instead of DOSS_INCREMENT to make the changes independent. Therefore, configure is as follows.
CFLAGS="-O0 -g -DDOSS_INCREMENT=1 -DDOSS_HASKELL=1" ./configure --prefix="/home/denjo/piyothon_install"
The current Python list comprehension notation is as follows.
lst = [x for x in range(10) if x >= 5]
Haskell, on the other hand, is:
lst = [x | x <- [0..9], x >= 5]
The modified Python can be expressed as follows.
lst = [x $ x <- range(10), x >= 5]
In addition, here|
not$
Is used|
Because it has an operation as a logical sum, it will be recognized as that.
There are only three changes:
Grammar
comp_iter: comp_for | comp_if
#ifdef DOSS_HASKELL
comp_for: ('for' | '$') exprlist ('in' | '<-') or_test [comp_iter]
#endif
comp_if: ('if' | ',') test_nocond [comp_iter]
token.h
#ifdef DOSS_INCREMENT
#define INCREMENT 58
#define PRE_INCREMENT 61
#endif
#ifdef DOSS_HASKELL
#define LARROW 59
#define DOLLAR 60
#endif
toknizer.c
case '<':
switch (c2) {
case '>': return NOTEQUAL;
case '=': return LESSEQUAL;
case '<': return LEFTSHIFT;
#ifdef DOSS_HASKELL
case '-': return LARROW;
#endif
}
break;
In the end, all I did was rewrite the Grammar to allow $, <-, ”,” instead of for, in, if, and register the token.
By the way, with this alone, you can also write unpleasantly such as [x ** 2 $ x in range (10), x% 2 == 0]
. Also, it's cute that the conditional expressions after ,
must be connected by ʻandinstead of separating them by
,`.
Q. Why does it work even though I haven't defined the meaning for for and in? Is it an alias for for or in?
A. In the first place, the meaning is not defined for for and in. For for, the token that comes after for is a variable that is used repeatedly, and the token that comes after that is ..., and the grammar is not defined. for is just a delimiter, and what kind of operation is performed on the token that comes after it is defined not for for but in what comes after for in Grammar.
Grammar
comp_iter: comp_for | comp_if
comp_for: 'for' exprlist 'in' or_test [comp_iter]
comp_if: 'if' test_nocond [comp_iter]
The above is the Grammar part that corresponds to the list comprehension before rewriting. Looking at comp_for
, it is defined that the word after'for''
is called as ʻexprlist. Also, after
’in’, ʻor_test
is to be called. So what definitions (how the syntax tree is created and what bytecodes are executed) are fixed for ʻexprlist, ʻor_test
, and comp_for
rather than for and in. It can be said that it is.
If you create a new opcode UNARY_PRE_INCREMENT and pay attention to the stacking order in ceval.c, you can create it in 30 minutes.
Recommended Posts