3v4l.org

run code in 300+ PHP versions simultaneously
<?php function parseRollCode($rollCode) { $cleanRollCode = preg_replace('/\s+/', '', strtolower($rollCode)); $intro = "<strong>Dice Roll:</strong> {$cleanRollCode}"; $error = "Invalid Roll Code"; $result = [ 'input' => $rollCode, 'total' => 0, 'detailText' => $intro ]; /* $out... [0] => roll tokens (optional leading sign) [1] => optional signs [2] => number&type die segments [3] => reroll threshold segments [4] => keep setting segments [5] => constant segments */ if (!preg_match_all('~\G(^-?|[+-])(?:(\d+d\d+)(r\d+)?([v^]\d+)?|(\d+))(?=[+-]|$)~x', $cleanRollCode, $out)) { $result['detailText'] .= "\n{$error}"; return $result; } foreach ($out[0] as $index => $segment) { $result['detailText'] .= "\n<strong>{$segment} Results:</strong>"; if (!empty($out[5][$index])) { $result['detailText'] .= ' (subtotal: ' . ((int)$segment) . ')'; $result['total'] += $segment; } else { // dice count & die type [$diceCount, $dieType] = explode('d', $out[2][$index], 2); // positive or negative arithmetic $signFactor = (!empty($out[1][$index][0]) && $out[1][$index][0] == '-' ? -1 : 1); // reroll threshold $rerollThreshold = (int)ltrim($out[3][$index] ?? 0, 'r'); if ($rerollThreshold >= $dieType) { return ['input' => $rollCode, 'total' => 0, 'detailText' => "{$intro}\n{$error}"]; } $rollResults = []; for ($r = 0; $r < $diceCount; ++$r) { $rollResults[] = rand($rerollThreshold + 1, $dieType); } // keep settings if (!empty($out[4][$index])) { $keepCount = ltrim($out[4][$index], '^v'); if ($keepCount > $diceCount) { return ['input' => $rollCode, 'total' => 0, 'detailText' => "{$intro}\n{$error}"]; } if ($out[4][$index][0] == '^') { arsort($rollResults); } else { asort($rollResults); } $keep = array_slice($rollResults, 0, $keepCount, true); $subtotal = array_sum($keep) * $signFactor; for ($i = 0, $len = count($rollResults); $i < $len; ++$i) { $result['detailText'] .= ' ' . ($keep[$i] ?? "<s>{$rollResults[$i]}</s>"); } $result['detailText'] .= " (subtotal: {$subtotal})"; $result['total'] += $subtotal; } else { $subtotal = array_sum($rollResults) * $signFactor; $result['detailText'] .= " " . implode(" ", $rollResults) . " (subtotal: {$subtotal})"; $result['total'] += $subtotal; } } } return $result; } $rolls = ["1 d2 0", "-1d20+5", "d20", "2d20^1", "4d6r1^3", "5d20^3", "5d8v2", "2d20v1", "5+3d4", "3d20^1", "3d6r1 + 1d4r2", "-1d20", "1d20+5", "1d20 + 5", "1d-20", "1d20+1d6", "5d20-3d6", "1d6r2", "5d6r-6", "3d20^1v1", "1d20r30", "1d20r20", "1d20r19", "1d20v2", "1d20v1", "1d20^2", "1d20+5d8r2^3-5-1d6+3d4+2-4+6-8"]; foreach ($rolls as $roll) { $rollResult = parseRollCode($roll); echo "{$rollResult['detailText']}\n<strong>Total:</strong> {$rollResult['total']}\n---\n"; }
Finding entry points
Branch analysis from position: 0
2 jumps found. (Code = 77) Position 1 = 2, Position 2 = 15
Branch analysis from position: 2
2 jumps found. (Code = 78) Position 1 = 3, Position 2 = 15
Branch analysis from position: 3
1 jumps found. (Code = 42) Position 1 = 2
Branch analysis from position: 2
Branch analysis from position: 15
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 15
filename:       /in/kI5eo
function name:  (null)
number of ops:  17
compiled vars:  !0 = $rolls, !1 = $roll, !2 = $rollResult
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   76     0  E >   ASSIGN                                                   !0, <array>
   79     1      > FE_RESET_R                                       $4      !0, ->15
          2    > > FE_FETCH_R                                               $4, !1, ->15
   80     3    >   INIT_FCALL                                               'parserollcode'
          4        SEND_VAR                                                 !1
          5        DO_FCALL                                      0  $5      
          6        ASSIGN                                                   !2, $5
   81     7        FETCH_DIM_R                                      ~7      !2, 'detailText'
          8        ROPE_INIT                                     4  ~10     ~7
          9        ROPE_ADD                                      1  ~10     ~10, '%0A%3Cstrong%3ETotal%3A%3C%2Fstrong%3E+'
         10        FETCH_DIM_R                                      ~8      !2, 'total'
         11        ROPE_ADD                                      2  ~10     ~10, ~8
         12        ROPE_END                                      3  ~9      ~10, '%0A---%0A'
         13        ECHO                                                     ~9
   79    14      > JMP                                                      ->2
         15    >   FE_FREE                                                  $4
   82    16      > RETURN                                                   1

Function parserollcode:
Finding entry points
Branch analysis from position: 0
2 jumps found. (Code = 43) Position 1 = 25, Position 2 = 30
Branch analysis from position: 25
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 30
2 jumps found. (Code = 77) Position 1 = 32, Position 2 = 200
Branch analysis from position: 32
2 jumps found. (Code = 78) Position 1 = 33, Position 2 = 200
Branch analysis from position: 33
2 jumps found. (Code = 43) Position 1 = 43, Position 2 = 51
Branch analysis from position: 43
1 jumps found. (Code = 42) Position 1 = 199
Branch analysis from position: 199
1 jumps found. (Code = 42) Position 1 = 32
Branch analysis from position: 32
Branch analysis from position: 51
2 jumps found. (Code = 46) Position 1 = 68, Position 2 = 73
Branch analysis from position: 68
2 jumps found. (Code = 43) Position 1 = 74, Position 2 = 76
Branch analysis from position: 74
1 jumps found. (Code = 42) Position 1 = 77
Branch analysis from position: 77
2 jumps found. (Code = 43) Position 1 = 90, Position 2 = 98
Branch analysis from position: 90
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 98
1 jumps found. (Code = 42) Position 1 = 109
Branch analysis from position: 109
2 jumps found. (Code = 44) Position 1 = 111, Position 2 = 101
Branch analysis from position: 111
2 jumps found. (Code = 43) Position 1 = 115, Position 2 = 181
Branch analysis from position: 115
2 jumps found. (Code = 43) Position 1 = 124, Position 2 = 132
Branch analysis from position: 124
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 132
2 jumps found. (Code = 43) Position 1 = 137, Position 2 = 141
Branch analysis from position: 137
1 jumps found. (Code = 42) Position 1 = 144
Branch analysis from position: 144
1 jumps found. (Code = 42) Position 1 = 171
Branch analysis from position: 171
2 jumps found. (Code = 44) Position 1 = 173, Position 2 = 160
Branch analysis from position: 173
1 jumps found. (Code = 42) Position 1 = 199
Branch analysis from position: 199
Branch analysis from position: 160
2 jumps found. (Code = 44) Position 1 = 173, Position 2 = 160
Branch analysis from position: 173
Branch analysis from position: 160
Branch analysis from position: 141
1 jumps found. (Code = 42) Position 1 = 171
Branch analysis from position: 171
Branch analysis from position: 181
1 jumps found. (Code = 42) Position 1 = 32
Branch analysis from position: 32
Branch analysis from position: 101
2 jumps found. (Code = 44) Position 1 = 111, Position 2 = 101
Branch analysis from position: 111
Branch analysis from position: 101
Branch analysis from position: 76
2 jumps found. (Code = 43) Position 1 = 90, Position 2 = 98
Branch analysis from position: 90
Branch analysis from position: 98
Branch analysis from position: 73
Branch analysis from position: 200
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 200
filename:       /in/kI5eo
function name:  parseRollCode
number of ops:  203
compiled vars:  !0 = $rollCode, !1 = $cleanRollCode, !2 = $intro, !3 = $error, !4 = $result, !5 = $out, !6 = $segment, !7 = $index, !8 = $diceCount, !9 = $dieType, !10 = $signFactor, !11 = $rerollThreshold, !12 = $rollResults, !13 = $r, !14 = $keepCount, !15 = $keep, !16 = $subtotal, !17 = $i, !18 = $len
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
    2     0  E >   RECV                                             !0      
    3     1        INIT_FCALL                                               'preg_replace'
          2        SEND_VAL                                                 '%2F%5Cs%2B%2F'
          3        SEND_VAL                                                 ''
          4        INIT_FCALL                                               'strtolower'
          5        SEND_VAR                                                 !0
          6        DO_ICALL                                         $19     
          7        SEND_VAR                                                 $19
          8        DO_ICALL                                         $20     
          9        ASSIGN                                                   !1, $20
    4    10        NOP                                                      
         11        FAST_CONCAT                                      ~22     '%3Cstrong%3EDice+Roll%3A%3C%2Fstrong%3E+', !1
         12        ASSIGN                                                   !2, ~22
    5    13        ASSIGN                                                   !3, 'Invalid+Roll+Code'
    7    14        INIT_ARRAY                                       ~25     !0, 'input'
    8    15        ADD_ARRAY_ELEMENT                                ~25     0, 'total'
    9    16        ADD_ARRAY_ELEMENT                                ~25     !2, 'detailText'
    6    17        ASSIGN                                                   !4, ~25
   22    18        INIT_FCALL                                               'preg_match_all'
         19        SEND_VAL                                                 '%7E%5CG%28%5E-%3F%7C%5B%2B-%5D%29%28%3F%3A%28%5Cd%2Bd%5Cd%2B%29%28r%5Cd%2B%29%3F%28%5Bv%5E%5D%5Cd%2B%29%3F%7C%28%5Cd%2B%29%29%28%3F%3D%5B%2B-%5D%7C%24%29%7Ex'
         20        SEND_VAR                                                 !1
         21        SEND_REF                                                 !5
         22        DO_ICALL                                         $27     
         23        BOOL_NOT                                         ~28     $27
         24      > JMPZ                                                     ~28, ->30
   23    25    >   NOP                                                      
         26        FAST_CONCAT                                      ~30     '%0A', !3
         27        ASSIGN_DIM_OP                .=               8          !4, 'detailText'
         28        OP_DATA                                                  ~30
   24    29      > RETURN                                                   !4
   26    30    >   FETCH_DIM_R                                      ~31     !5, 0
         31      > FE_RESET_R                                       $32     ~31, ->200
         32    > > FE_FETCH_R                                       ~33     $32, !6, ->200
         33    >   ASSIGN                                                   !7, ~33
   27    34        ROPE_INIT                                     3  ~37     '%0A%3Cstrong%3E'
         35        ROPE_ADD                                      1  ~37     ~37, !6
         36        ROPE_END                                      2  ~36     ~37, '+Results%3A%3C%2Fstrong%3E'
         37        ASSIGN_DIM_OP                .=               8          !4, 'detailText'
         38        OP_DATA                                                  ~36
   28    39        FETCH_DIM_IS                                     ~39     !5, 5
         40        ISSET_ISEMPTY_DIM_OBJ                         1  ~40     ~39, !7
         41        BOOL_NOT                                         ~41     ~40
         42      > JMPZ                                                     ~41, ->51
   29    43    >   CAST                                          4  ~43     !6
         44        CONCAT                                           ~44     '+%28subtotal%3A+', ~43
         45        CONCAT                                           ~45     ~44, '%29'
         46        ASSIGN_DIM_OP                .=               8          !4, 'detailText'
         47        OP_DATA                                                  ~45
   30    48        ASSIGN_DIM_OP                +=               1          !4, 'total'
         49        OP_DATA                                                  !6
   28    50      > JMP                                                      ->199
   33    51    >   INIT_FCALL                                               'explode'
         52        SEND_VAL                                                 'd'
         53        FETCH_DIM_R                                      ~47     !5, 2
         54        FETCH_DIM_R                                      ~48     ~47, !7
         55        SEND_VAL                                                 ~48
         56        SEND_VAL                                                 2
         57        DO_ICALL                                         $49     
         58        FETCH_LIST_R                                     $50     $49, 0
         59        ASSIGN                                                   !8, $50
         60        FETCH_LIST_R                                     $52     $49, 1
         61        ASSIGN                                                   !9, $52
         62        FREE                                                     $49
   36    63        FETCH_DIM_IS                                     ~54     !5, 1
         64        FETCH_DIM_IS                                     ~55     ~54, !7
         65        ISSET_ISEMPTY_DIM_OBJ                         1  ~56     ~55, 0
         66        BOOL_NOT                                         ~57     ~56
         67      > JMPZ_EX                                          ~57     ~57, ->73
         68    >   FETCH_DIM_R                                      ~58     !5, 1
         69        FETCH_DIM_R                                      ~59     ~58, !7
         70        FETCH_DIM_R                                      ~60     ~59, 0
         71        IS_EQUAL                                         ~61     ~60, '-'
         72        BOOL                                             ~57     ~61
         73    > > JMPZ                                                     ~57, ->76
         74    >   QM_ASSIGN                                        ~62     -1
         75      > JMP                                                      ->77
         76    >   QM_ASSIGN                                        ~62     1
         77    >   ASSIGN                                                   !10, ~62
   39    78        INIT_FCALL                                               'ltrim'
         79        FETCH_DIM_IS                                     ~64     !5, 3
         80        FETCH_DIM_IS                                     ~65     ~64, !7
         81        COALESCE                                         ~66     ~65
         82        QM_ASSIGN                                        ~66     0
         83        SEND_VAL                                                 ~66
         84        SEND_VAL                                                 'r'
         85        DO_ICALL                                         $67     
         86        CAST                                          4  ~68     $67
         87        ASSIGN                                                   !11, ~68
   40    88        IS_SMALLER_OR_EQUAL                                      !9, !11
         89      > JMPZ                                                     ~70, ->98
   41    90    >   INIT_ARRAY                                       ~71     !0, 'input'
         91        ADD_ARRAY_ELEMENT                                ~71     0, 'total'
         92        ROPE_INIT                                     3  ~73     !2
         93        ROPE_ADD                                      1  ~73     ~73, '%0A'
         94        ROPE_END                                      2  ~72     ~73, !3
         95        ADD_ARRAY_ELEMENT                                ~71     ~72, 'detailText'
         96        FE_FREE                                                  $32
         97      > RETURN                                                   ~71
   43    98    >   ASSIGN                                                   !12, <array>
   44    99        ASSIGN                                                   !13, 0
        100      > JMP                                                      ->109
   45   101    >   INIT_FCALL                                               'rand'
        102        ADD                                              ~78     !11, 1
        103        SEND_VAL                                                 ~78
        104        SEND_VAR                                                 !9
        105        DO_ICALL                                         $79     
        106        ASSIGN_DIM                                               !12
        107        OP_DATA                                                  $79
   44   108        PRE_INC                                                  !13
        109    >   IS_SMALLER                                               !13, !8
        110      > JMPNZ                                                    ~81, ->101
   49   111    >   FETCH_DIM_IS                                     ~82     !5, 4
        112        ISSET_ISEMPTY_DIM_OBJ                         1  ~83     ~82, !7
        113        BOOL_NOT                                         ~84     ~83
        114      > JMPZ                                                     ~84, ->181
   50   115    >   INIT_FCALL                                               'ltrim'
        116        FETCH_DIM_R                                      ~85     !5, 4
        117        FETCH_DIM_R                                      ~86     ~85, !7
        118        SEND_VAL                                                 ~86
        119        SEND_VAL                                                 '%5Ev'
        120        DO_ICALL                                         $87     
        121        ASSIGN                                                   !14, $87
   51   122        IS_SMALLER                                               !8, !14
        123      > JMPZ                                                     ~89, ->132
   52   124    >   INIT_ARRAY                                       ~90     !0, 'input'
        125        ADD_ARRAY_ELEMENT                                ~90     0, 'total'
        126        ROPE_INIT                                     3  ~92     !2
        127        ROPE_ADD                                      1  ~92     ~92, '%0A'
        128        ROPE_END                                      2  ~91     ~92, !3
        129        ADD_ARRAY_ELEMENT                                ~90     ~91, 'detailText'
        130        FE_FREE                                                  $32
        131      > RETURN                                                   ~90
   54   132    >   FETCH_DIM_R                                      ~94     !5, 4
        133        FETCH_DIM_R                                      ~95     ~94, !7
        134        FETCH_DIM_R                                      ~96     ~95, 0
        135        IS_EQUAL                                                 ~96, '%5E'
        136      > JMPZ                                                     ~97, ->141
   55   137    >   INIT_FCALL                                               'arsort'
        138        SEND_REF                                                 !12
        139        DO_ICALL                                                 
   54   140      > JMP                                                      ->144
   57   141    >   INIT_FCALL                                               'asort'
        142        SEND_REF                                                 !12
        143        DO_ICALL                                                 
   59   144    >   INIT_FCALL                                               'array_slice'
        145        SEND_VAR                                                 !12
        146        SEND_VAL                                                 0
        147        SEND_VAR                                                 !14
        148        SEND_VAL                                                 <true>
        149        DO_ICALL                                         $100    
        150        ASSIGN                                                   !15, $100
   60   151        INIT_FCALL                                               'array_sum'
        152        SEND_VAR                                                 !15
        153        DO_ICALL                                         $102    
        154        MUL                                              ~103    !10, $102
        155        ASSIGN                                                   !16, ~103
   61   156        ASSIGN                                                   !17, 0
        157        COUNT                                            ~106    !12
        158        ASSIGN                                                   !18, ~106
        159      > JMP                                                      ->171
   62   160    >   FETCH_DIM_IS                                     ~109    !15, !17
        161        COALESCE                                         ~110    ~109
        162        ROPE_INIT                                     3  ~113    '%3Cs%3E'
        163        FETCH_DIM_R                                      ~111    !12, !17
        164        ROPE_ADD                                      1  ~113    ~113, ~111
        165        ROPE_END                                      2  ~112    ~113, '%3C%2Fs%3E'
        166        QM_ASSIGN                                        ~110    ~112
        167        CONCAT                                           ~115    '+', ~110
        168        ASSIGN_DIM_OP                .=               8          !4, 'detailText'
        169        OP_DATA                                                  ~115
   61   170        PRE_INC                                                  !17
        171    >   IS_SMALLER                                               !17, !18
        172      > JMPNZ                                                    ~117, ->160
   64   173    >   ROPE_INIT                                     3  ~120    '+%28subtotal%3A+'
        174        ROPE_ADD                                      1  ~120    ~120, !16
        175        ROPE_END                                      2  ~119    ~120, '%29'
        176        ASSIGN_DIM_OP                .=               8          !4, 'detailText'
        177        OP_DATA                                                  ~119
   65   178        ASSIGN_DIM_OP                +=               1          !4, 'total'
        179        OP_DATA                                                  !16
   49   180      > JMP                                                      ->199
   67   181    >   INIT_FCALL                                               'array_sum'
        182        SEND_VAR                                                 !12
        183        DO_ICALL                                         $123    
        184        MUL                                              ~124    !10, $123
        185        ASSIGN                                                   !16, ~124
   68   186        INIT_FCALL                                               'implode'
        187        SEND_VAL                                                 '+'
        188        SEND_VAR                                                 !12
        189        DO_ICALL                                         $127    
        190        CONCAT                                           ~128    '+', $127
        191        ROPE_INIT                                     3  ~130    '+%28subtotal%3A+'
        192        ROPE_ADD                                      1  ~130    ~130, !16
        193        ROPE_END                                      2  ~129    ~130, '%29'
        194        CONCAT                                           ~132    ~128, ~129
        195        ASSIGN_DIM_OP                .=               8          !4, 'detailText'
        196        OP_DATA                                                  ~132
   69   197        ASSIGN_DIM_OP                +=               1          !4, 'total'
        198        OP_DATA                                                  !16
   26   199    > > JMP                                                      ->32
        200    >   FE_FREE                                                  $32
   73   201      > RETURN                                                   !4
   74   202*     > RETURN                                                   null

End of function parserollcode

Generated using Vulcan Logic Dumper, using php 8.0.0


preferences:
154.66 ms | 1034 KiB | 25 Q