CPythonに後置インクリメントを加えてみた　全変更点一覧

# リンクリスト
全三回プラス番外編になっています。
[CPythonに後置インクリメントを加えてみた　概要とまとめ](http://qiita.com/DOSS_INCREMENT/items/36629e1f4044de4742a1)
[CPythonに後置インクリメントを加えてみた　実装編](http://qiita.com/DOSS_INCREMENT/items/8b050847145f635211e2)
[CPythonに後置インクリメントを加えてみた　全変更点一覧](http://qiita.com/DOSS_INCREMENT/items/8371b7a1711c8c680a1a)
[CPythonに後置インクリメントを加えてみた　番外編](http://qiita.com/DOSS_INCREMENT/items/c8719c3a78502f097c76)


# 変更点一覧
以下に示すのはソースコードに加えられた全変更である。それぞれのファイルの場所と、大まかな行数をわかりやすくするため`grep "def DOSS" . -r -I -n -B 3`の結果をまず貼る。その後各ソースコードにおける変更を詳述する。

```bash:bash
./Modules/parsermodule.c-1000-#define validate_star(ch)       validate_terminal(ch,       STAR, "*")
./Modules/parsermodule.c-1001-#define validate_vbar(ch)       validate_terminal(ch,       VBAR, "|")
./Modules/parsermodule.c-1002-#define validate_doublestar(ch) validate_terminal(ch, DOUBLESTAR, "**")
./Modules/parsermodule.c:1003:#ifdef DOSS_INCREMENT
--
./Modules/parsermodule.c-1017-VALIDATER(vfpdef);
./Modules/parsermodule.c-1018-VALIDATER(stmt);                VALIDATER(simple_stmt);
./Modules/parsermodule.c-1019-VALIDATER(expr_stmt);
./Modules/parsermodule.c:1020:#ifdef DOSS_INCREMENT
--
./Modules/parsermodule.c-2433- *
./Modules/parsermodule.c-2434- *  factor: ('+'|'-'|'~') factor | power
./Modules/parsermodule.c-2435- */
./Modules/parsermodule.c:2436:#ifdef DOSS_INCREMENT
--
./Modules/parsermodule.c-2493- *
./Modules/parsermodule.c-2494- *  power: atom_expr trailer* ['**' factor]
./Modules/parsermodule.c-2495- */
./Modules/parsermodule.c:2496:#ifndef DOSS_INCREMENT
--
./Modules/parsermodule.c-3386-          case factor:
./Modules/parsermodule.c-3387-            res = validate_factor(tree);
./Modules/parsermodule.c-3388-            break;
./Modules/parsermodule.c:3389:            #ifndef DOSS_INCREMENT
--
./Grammar/Grammar-103-arith_expr: term (('+'|'-') term)*
./Grammar/Grammar-104-term: factor (('*'|'@'|'/'|'%'|'//') factor)*
./Grammar/Grammar-105-#######################################
./Grammar/Grammar:106:# #ifdef DOSS_INCREMENT
--
./Include/token.h-69-#define ERRORTOKEN    56
./Include/token.h-70-#define N_TOKENS    57
./Include/token.h-71-
./Include/token.h:72:#ifdef DOSS_INCREMENT
--
./Python/ceval.c-809-    PyThreadState *tstate = PyThreadState_GET();
./Python/ceval.c-810-    PyCodeObject *co;
./Python/ceval.c-811-
./Python/ceval.c:812:    #ifdef DOSS_INCREMENT
--
./Python/ceval.c-1476-                goto error;
./Python/ceval.c-1477-            }
./Python/ceval.c-1478-
./Python/ceval.c:1479:    #ifdef DOSS_INCREMENT
--
./Python/ceval.c-2341-                PyObject *name = GETITEM(names, oparg);
./Python/ceval.c-2342-                PyObject *locals = f->f_locals;
./Python/ceval.c-2343-                PyObject *v;
./Python/ceval.c:2344:    #ifdef DOSS_INCREMENT
--
./Python/compile.c-873-    case UNARY_NEGATIVE:
./Python/compile.c-874-    case UNARY_NOT:
./Python/compile.c-875-    case UNARY_INVERT:
./Python/compile.c:876:#ifdef DOSS_INCREMENT
--
./Python/compile.c-2751-        return UNARY_POSITIVE;
./Python/compile.c-2752-    case USub:
./Python/compile.c-2753-        return UNARY_NEGATIVE;
./Python/compile.c:2754:#ifdef DOSS_INCREMENT
--
./Python/compile.c-3817-    case UnaryOp_kind:
./Python/compile.c-3818-        VISIT(c, expr, e->v.UnaryOp.operand);
./Python/compile.c-3819-        ADDOP(c, unaryop(e->v.UnaryOp.op));
./Python/compile.c:3820:    #ifdef DOSS_INCREMENT
--
./Python/ast.c-2337-static expr_ty
./Python/ast.c-2338-ast_for_factor(struct compiling *c, const node *n)
./Python/ast.c-2339-{
./Python/ast.c:2340:#ifdef DOSS_INCREMENT
--
./Python/ast.c-2453-        return e;
./Python/ast.c-2454-    }
./Python/ast.c-2455-}
./Python/ast.c:2456:#ifndef DOSS_INCREMENT
--
./Python/ast.c-2476-}
./Python/ast.c-2477-#endif
./Python/ast.c-2478-
./Python/ast.c:2479:#ifdef DOSS_INCREMENT
--
./Python/ast.c-2666-            return Yield(exp, LINENO(n), n->n_col_offset, c->c_arena);
./Python/ast.c-2667-        }
./Python/ast.c-2668-        case factor:
./Python/ast.c:2669:#ifndef DOSS_INCREMENT
--
./Python/ast.c-2673-            }
./Python/ast.c-2674-#endif
./Python/ast.c-2675-            return ast_for_factor(c, n);
./Python/ast.c:2676:#ifndef DOSS_INCREMENT
./Python/ast.c-2677-        case power:
./Python/ast.c-2678-            return ast_for_power(c, n);
./Python/ast.c-2679-#endif
./Python/ast.c:2680:#ifdef DOSS_INCREMENT
--
./Parser/tokenizer.c-107-    "ASYNC",
./Parser/tokenizer.c-108-    "<ERRORTOKEN>",
./Parser/tokenizer.c-109-    "<N_TOKENS>"
./Parser/tokenizer.c:110:    #ifdef DOSS_INCREMENT
--
./Parser/tokenizer.c-1179-    case '+':
./Parser/tokenizer.c-1180-        switch (c2) {
./Parser/tokenizer.c-1181-        case '=':               return PLUSEQUAL;
./Parser/tokenizer.c:1182:        #ifdef DOSS_INCREMENT
--
./Parser/Python.asdl-97-    operator = Add | Sub | Mult | MatMult | Div | Mod | Pow | LShift
./Parser/Python.asdl-98-                 | RShift | BitOr | BitXor | BitAnd | FloorDiv
./Parser/Python.asdl-99-
./Parser/Python.asdl:100:    -- #ifdef DOSS_INCREMENT
--
./Lib/opcode.py-67-def_op('UNARY_POSITIVE', 10)
./Lib/opcode.py-68-def_op('UNARY_NEGATIVE', 11)
./Lib/opcode.py-69-def_op('UNARY_NOT', 12)
./Lib/opcode.py:70:#ifdef DOSS_INCREMENT
```

詳細な変更点は以下。
### ./Modules/parsermodule.c:1003:#ifdef DOSS_INCREMENT

```c
#ifdef DOSS_INCREMENT
#define validate_increment(ch) validate_terminal(ch, INCREMENT, "++")
#endif
```

### ./Modules/parsermodule.c:1020:#ifdef DOSS_INCREMENT

```c
#ifdef DOSS_INCREMENT
VALIDATER(inc);
#else
VALIDATER(power);
#endif
```

### ./Modules/parsermodule.c:2436:#ifdef DOSS_INCREMENT

```c
#ifdef DOSS_INCREMENT
static int
validate_factor(node *tree)
{
        int nch = NCH(tree);
        int res = (validate_ntype(tree, factor)
                   && (((nch == 1)
                        && validate_inc(CHILD(tree, 0)))
                       ||((nch == 2)
                          && ((TYPE(CHILD(tree, 0)) == PLUS)
                              || (TYPE(CHILD(tree, 0)) == MINUS)
                              || (TYPE(CHILD(tree, 0)) == TILDE))
                          && validate_inc(CHILD(tree, 1)))
                       ||((nch == 3)
                          && validate_inc(CHILD(tree, 0))
                          && validate_doublestar(CHILD(tree,1))
                          && validate_factor(CHILD(tree,2)))
                       || ((nch == 4)
                           && ((TYPE(CHILD(tree, 0)) == PLUS)
                               || (TYPE(CHILD(tree, 0)) == MINUS)
                               || (TYPE(CHILD(tree, 0)) == TILDE))
                           && validate_inc(CHILD(tree, 1))
                           && validate_doublestar(CHILD(tree,2))
                           && validate_factor(CHILD(tree,3)))));
        return (res);
}

static int
validate_inc(node *tree)
{
    int nch = NCH(tree);
    int res = (validate_ntype(tree, factor)
               && (((nch == 2)
                    && validate_atom_expr(CHILD(tree, 0))
                    && validate_increment(CHILD(tree, 1)))
                   || ((nch == 1)
                       && validate_atom_expr(CHILD(tree, 0)))));
    return (res);
}
#else
static int
validate_factor(node *tree)
{
    int nch = NCH(tree);
    int res = (validate_ntype(tree, factor)
               && (((nch == 2)
                    && ((TYPE(CHILD(tree, 0)) == PLUS)
                        || (TYPE(CHILD(tree, 0)) == MINUS)
                        || (TYPE(CHILD(tree, 0)) == TILDE))
                    && validate_factor(CHILD(tree, 1)))
                   || ((nch == 1)
                       && validate_power(CHILD(tree, 0)))));
    return (res);
}
#endif
```

### ./Modules/parsermodule.c:2496:#ifndef DOSS_INCREMENT

```c
#ifndef DOSS_INCREMENT
static int
validate_power(node *tree)
{
    int nch = NCH(tree);
    int res = (validate_ntype(tree, power) && (nch >= 1)
               && validate_atom_expr(CHILD(tree, 0)));

    if (nch > 1) {
        if (nch != 3) {
            err_string("illegal number of nodes for 'power'");
            return (0);
        }
        res = (validate_doublestar(CHILD(tree, 1))
               && validate_factor(CHILD(tree, 2)));
    }

    return (res);
}
#endif
```

### ./Modules/parsermodule.c:3389:            #ifndef DOSS_INCREMENT

```c
#ifndef DOSS_INCREMENT
case power:
res = validate_power(tree);
break;
#endif
```

### ./Grammar/Grammar:106:# #ifdef DOSS_INCREMENT

```
#######################################
# #ifdef DOSS_INCREMENT
# Tips: We should not use Japanese here!!
#######################################
#factor: ('+'|'-'|'~') factor | power
#power: atom_expr ['**' factor]
# factor: power
factor: ['+'|'-'|'~'] inc ['**' factor]
inc: atom_expr ['++']
#######################################
```

### ./Include/token.h:72:#ifdef DOSS_INCREMENT

```c
#ifdef DOSS_INCREMENT
#define INCREMENT 58
#endif
```

### ./Python/ceval.c:812:    #ifdef DOSS_INCREMENT

```c
#ifdef DOSS_INCREMENT
static PyObject *name_for_increment;
#endif
```

### ./Python/ceval.c:1479:    #ifdef DOSS_INCREMENT

```c
#ifdef DOSS_INCREMENT
    TARGET(UNARY_INCREMENT) {
      PyObject *left = TOP();
      PyObject *inv, *sum;
      // note that -(~x) == x+1 for all x
      inv = PyNumber_Invert(left);
      //Py_DECREF(left);
      if (inv == NULL)
        goto error;
      sum = PyNumber_Negative(inv);
      Py_DECREF(inv);
      if (sum == NULL)
        goto error;

      PUSH(sum);
      //Py_DECREF(sum);

      // //for STORE
      // name = name_for_increment;
      // v = sum;
      // Py_DECREF(sum);
      // ns = f->f_locals;
      // if (ns == NULL) {
      //     PyErr_Format(PyExc_SystemError,
      //                  "no locals found when storing %R", name);
      //     Py_DECREF(v);
      //     goto error;
      // }
      // if (PyDict_CheckExact(ns))
      //     err = PyDict_SetItem(ns, name, v);
      // else
      //     err = PyObject_SetItem(ns, name, v);
      // Py_DECREF(v);
      // if (err != 0)
      //     goto error;
      //

      DISPATCH();
    }
#endif
```

### ./Python/ceval.c:2344:    #ifdef DOSS_INCREMENT

```c
#ifdef DOSS_INCREMENT
      name_for_increment = name;
#endif
```

### ./Python/compile.c:876:#ifdef DOSS_INCREMENT

```c
#ifdef DOSS_INCREMENT
    case UNARY_INCREMENT:
#endif
```

### ./Python/compile.c:2754:#ifdef DOSS_INCREMENT

```c
#ifdef DOSS_INCREMENT
    case UInc:
        return UNARY_INCREMENT;
#endif
```

### ./Python/compile.c:3820:    #ifdef DOSS_INCREMENT

```c
#ifdef DOSS_INCREMENT
  // set variables
  if( e->v.UnaryOp.op == UInc ) {
    expr_ty auge;
    e=e->v.UnaryOp.operand;
    switch (e->kind) {
    case Attribute_kind:
      //fprintf(stderr,"Attribute_kind\n");
      auge = Attribute(e->v.Attribute.value, e->v.Attribute.attr,
                       AugLoad, e->lineno, e->col_offset, c->c_arena);
      if (auge == NULL)
        return 0;
      auge->v.Attribute.ctx = Store;
      VISIT(c, expr, auge);
      break;
    case Subscript_kind:
      //fprintf(stderr,"Subscript_kind\n");
      auge = Subscript(e->v.Subscript.value, e->v.Subscript.slice,
                       Load, e->lineno, e->col_offset, c->c_arena);
      if (auge == NULL)
        return 0;
      auge->v.Subscript.ctx = Store;
      VISIT(c, expr, auge);
      break;
    case Name_kind:
      //fprintf(stderr,"Name_kind\n");
      compiler_nameop(c, e->v.Name.id, Store);
      break;
    default:
      PyErr_Format(PyExc_SystemError,
                   "invalid node type (%d) for augmented assignment",
                   e->kind);
      return 0;
    }
  }
#endif
```

### ./Python/ast.c:2340:#ifdef DOSS_INCREMENT

```c
#ifdef DOSS_INCREMENT
    expr_ty expression, f;

    // expression = ast_for_expr(c, CHILD(n, 1));
    switch (NCH(n)){
        case 1:
            return ast_for_expr(c, CHILD(n, 0));
        case 2: //  ['+' | '-' | '~'] inc
            expression = ast_for_expr(c, CHILD(n, 1));
            switch (TYPE(CHILD(n, 0))){
                case PLUS:
                    return UnaryOp(UAdd, expression, LINENO(n), n->n_col_offset,
                            c->c_arena);
                case MINUS:
                    return UnaryOp(USub, expression, LINENO(n), n->n_col_offset,
                            c->c_arena);
                case TILDE:
                    return UnaryOp(Invert, expression, LINENO(n),
                            n->n_col_offset, c->c_arena);
            }
            PyErr_Format(PyExc_SystemError, "cant reach here: %d",
                    TYPE(CHILD(n, 0)));
        case 3: //  inc ['**' factor]
            expression = ast_for_expr(c, CHILD(n, 0));
            f = ast_for_expr(c, CHILD(n, 2));
            return BinOp(expression, Pow, f, LINENO(n), n->n_col_offset, c->c_arena);

        case 4: //  ['+' | '-' | '~'] inc ['**' factor]
            expression = ast_for_expr(c, CHILD(n, 1));
            switch (TYPE(CHILD(n, 0))){
                case PLUS:
                    expression = UnaryOp(UAdd, expression, LINENO(n), n->n_col_offset,
                            c->c_arena);
                case MINUS:
                    expression = UnaryOp(USub, expression, LINENO(n), n->n_col_offset,
                            c->c_arena);
                case TILDE:
                    expression = UnaryOp(Invert, expression, LINENO(n),
                            n->n_col_offset, c->c_arena);
            }
            f = ast_for_expr(c, CHILD(n, 3));
            return BinOp(expression, Pow, f, LINENO(n), n->n_col_offset, c->c_arena);

        default:
            PyErr_Format(PyExc_SystemError, "unhandled factor: %d",
                    TYPE(CHILD(n, 0)));

    }
    return NULL;
#else
    expr_ty expression;

    expression = ast_for_expr(c, CHILD(n, 1));
    if (!expression)
        return NULL;

    switch (TYPE(CHILD(n, 0))) {
        case PLUS:
            return UnaryOp(UAdd, expression, LINENO(n), n->n_col_offset,
                           c->c_arena);
        case MINUS:
            return UnaryOp(USub, expression, LINENO(n), n->n_col_offset,
                           c->c_arena);
        case TILDE:
            return UnaryOp(Invert, expression, LINENO(n),
                           n->n_col_offset, c->c_arena);
    }
    PyErr_Format(PyExc_SystemError, "unhandled factor: %d",
                 TYPE(CHILD(n, 0)));
    return NULL;
#endif
```

### ./Python/ast.c:2456:#ifndef DOSS_INCREMENT

```c
#ifndef DOSS_INCREMENT
static expr_ty
ast_for_power(struct compiling *c, const node *n)
{
    /* power: atom trailer* ('**' factor)*
     */
    expr_ty e;
    REQ(n, power);
    e = ast_for_atom_expr(c, CHILD(n, 0));
    if (!e)
        return NULL;
    if (NCH(n) == 1)
        return e;
    if (TYPE(CHILD(n, NCH(n) - 1)) == factor) {
        expr_ty f = ast_for_expr(c, CHILD(n, NCH(n) - 1));
        if (!f)
            return NULL;
        e = BinOp(e, Pow, f, LINENO(n), n->n_col_offset, c->c_arena);
    }
    return e;
}
#endif
```

### ./Python/ast.c:2479:#ifdef DOSS_INCREMENT

```c
#ifdef DOSS_INCREMENT
static expr_ty
ast_for_inc(struct compiling *c, const node *n)
{
    expr_ty expression;

    expression = ast_for_atom_expr(c, CHILD(n, 0));
    if (!expression)
        return NULL;

    if (NCH(n) == 1)
        return expression;
    else if (TYPE(CHILD(n, NCH(n) - 1)) == INCREMENT) {
      return UnaryOp(UInc, expression, LINENO(n), n->n_col_offset, c->c_arena);
    }
    PyErr_Format(PyExc_SystemError, "unhandled increment: %d",
                 TYPE(CHILD(n, 0)));
    return NULL;
}
#endif
```

### ./Python/ast.c:2669:#ifndef DOSS_INCREMENT

```c
#ifndef DOSS_INCREMENT
            if (NCH(n) == 1) {
                n = CHILD(n, 0);
                goto loop;
            }
#endif
```

### ./Python/ast.c:2676:#ifndef DOSS_INCREMENT

```c
#ifndef DOSS_INCREMENT
        case power:
            return ast_for_power(c, n);
#endif
```

### ./Python/ast.c:2680:#ifdef DOSS_INCREMENT

```c
#ifdef DOSS_INCREMENT
        case inc:
            return ast_for_inc(c, n);
#endif
```

### ./Parser/tokenizer.c:110:    #ifdef DOSS_INCREMENT

```c
#ifdef DOSS_INCREMENT
,"INCREMENT"
#endif
```

### ./Parser/tokenizer.c:1182:        #ifdef DOSS_INCREMENT

```c
#ifdef DOSS_INCREMENT
case '+':               return INCREMENT;
#endif
```

### ./Parser/Python.asdl: 100:    -- #ifdef DOSS_INCREMENT

```
-- #ifdef DOSS_INCREMENT
-- unaryop = Invert | Not | UAdd | USub
unaryop = Invert | Not | UAdd | USub | UInc
-- #endif
```

### ./Lib/opcode.py:70:#ifdef DOSS_INCREMENT

```py3
#ifdef DOSS_INCREMENT
def_op('UNARY_INCREMENT',13)
#endif
```

以上である。