private function createMatches(array $expression, CompilationContext $context)
    {
        if (isset($expression['parameters'][2])) {
            $type = $expression['parameters'][2]['parameter']['type'];

            if ('variable' !== $type) {
                throw new CompilerException('Only variables can be passed by reference', $expression);
            }

            $name = $expression['parameters'][2]['parameter']['value'];

            if (!$variable = $context->symbolTable->getVariable($name)) {
                throw new CompilerException(
                    sprintf("Cannot mutate variable '%s' because it wasn't defined", $name),
                    $expression
                );
            }

            if (!\in_array($variable->getType(), ['variable', 'array'], true)) {
                throw new CompilerException(
                    sprintf(
                        "The '%s' variable must be either a variable or an array, got %s",
                        $name,
                        $variable->getType()
                    ),
                    $expression
                );
            }

            if (false == $variable->isInitialized()) {
                $variable->initVariant($context);
                $variable->setIsInitialized(true, $context);
            }
        } else {
            $variable = $context->symbolTable->addTemp('variable', $context);
            $variable->initVariant($context);
        }

        $variable->setDynamicTypes('array');

        return $variable;
    }