Skip to content

Language: Pre/post increment and decrement (++/--) #137

@PurHur

Description

@PurHur

Problem

PreInc, PostInc, PreDec, PostDec are parsed by php-cfg but lib/Compiler.php::compileExpr() throws Unsupported expression (or similar). Loop counters (for ($i = 0; $i < n; $i++)), pagination, and stack depth checks in routers need pre/post semantics.

#300 tracks lint registry mapping until this lands.

Goal

Correct Zend-compatible pre vs post increment/decrement in VM (v1); JIT numeric int paths (v2); AOT follows JIT.

Implementation hints

php-cfg kinds

Probe with bin/print.php -r '++$i; $i++;' — expect Expr_PreInc, Expr_PostInc, etc.

Compiler (lib/Compiler.php)

  1. In compileExpr(), branch on increment/decrement nodes.
  2. Pre-inc: read old value, add 1, store, value of expression = new value.
  3. Post-inc: read old value, add 1, store, value of expression = old value.
  4. Lower to existing TYPE_PLUS / assign opcodes or dedicated TYPE_PRE_INC if cleaner for VM.

VM (lib/VM.php)

  • If using generic assign+plus, ensure expression result register matches pre/post rules.
  • Strings: defer or match Zend coercion policy (document if subset is int-only).

JIT (lib/JIT.php)

  • Fast path when operand is typed int in inferred types.
  • Fall back to VM call or skip with lint until ready.

Lint

Tests

  • test/compliance/cases/language/pre_post_inc.phpt
  • test/compliance/cases/language/pre_post_dec.phpt

Acceptance criteria

docker run --rm -v "$(pwd):/compiler" -w /compiler php-compiler:22.04-dev \
  php bin/vm.php -r '$i=0; echo ++$i, $i, $i++;'

Prints 112 (Zend: pre-inc returns new, post-inc returns old).

Verification (local / Docker only)

./script/ci-local.sh --filter pre_post_inc

Dependencies

Files

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions