Les trois fois plus une édition supplémentaire. Présentation et résumé de l'ajout de post-incrémentation à CPython [J'ai essayé d'ajouter un post-incrément à CPython Implémentation Liste de toutes les modifications lors de l'ajout de post-incrémentation à CPython Édition supplémentaire de l'ajout de post-incrémentation à CPython
À l'origine, l'incrémentation était une tâche pour s'entraîner à changer la notation d'inclusion de liste. Cependant, il a été plus difficile à mettre en œuvre que prévu, en partie parce que l'incrément ne correspondait pas au concept de conception. Quel que soit le concept, la modification de la notation d'inclusion de liste peut être effectuée en environ cinq minutes si vous avez les connaissances à ce jour.
Tout d'abord, nous utilisons DOSS_HASKELL au lieu de DOSS_INCREMENT pour rendre les modifications indépendantes. Par conséquent, la configuration est la suivante.
CFLAGS="-O0 -g -DDOSS_INCREMENT=1 -DDOSS_HASKELL=1" ./configure --prefix="/home/denjo/piyothon_install"
La notation d'inclusion de liste actuelle de Python est la suivante.
lst = [x for x in range(10) if x >= 5]
D'autre part, Haskell est comme suit.
lst = [x | x <- [0..9], x >= 5]
Le Python modifié peut être exprimé comme suit.
lst = [x $ x <- range(10), x >= 5]
De plus, ici|
ne pas$
Est utilisé|
Puisqu'il a une opération comme somme logique, il sera reconnu comme cela.
Il n'y a que trois changements:
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;
En fin de compte, tout ce que j'ai fait a été de réécrire la grammaire pour autoriser $, <-, ”,” au lieu de for, in, if, et d'enregistrer le jeton.
En passant, avec cela seul, vous pouvez également écrire de manière désagréable comme [x ** 2 $ x in range (10), x% 2 == 0]
. Aussi, c'est mignon que les expressions conditionnelles après ,
doivent être connectées par ʻetau lieu d'être séparées par
,`.
Q. Pourquoi cela fonctionne-t-il même si je n'ai pas défini la signification de pour et dans? Est-ce un alias pour for ou in?
A. En premier lieu, le sens n'est pas défini pour et dans. Pour for, le jeton qui vient après for est une variable qui est utilisée à plusieurs reprises, et le jeton qui vient après cela est ..., et la grammaire n'est pas définie. car est juste un délimiteur, et ce qu'il faut faire avec les jetons qui le suivent est défini dans Grammaire comme ce qui vient après pour, pas pour pour.
Grammar
comp_iter: comp_for | comp_if
comp_for: 'for' exprlist 'in' or_test [comp_iter]
comp_if: 'if' test_nocond [comp_iter]
Ce qui précède est la partie Grammaire qui correspond à la notation d'inclusion de liste avant la réécriture. En regardant comp_for
, il est défini que le mot suivant'for'
est appelé comme ʻexprlist. De plus, après «in», «or_test» doit être appelé. Par conséquent, quelles définitions (comment l'arborescence de syntaxe est créée et quel code d'octet est exécuté) sont fixées pour ʻexprlist
, ʻor_test et
comp_for` plutôt que pour et in. On peut dire que
Si vous créez un nouveau code d'opération UNARY_PRE_INCREMENT et faites attention à l'ordre d'empilement dans ceval.c, vous pouvez le créer en 30 minutes.
Recommended Posts