/**
 * Module with rules to handle the special construct for the
 * constant propogation.
 */
module php/strategy/const-prop/analysis/special

strategies
/***********************************************************************\
                 Start FunctionCall Handling
\***********************************************************************/
/**
 * These function-calls are special, they encode library functions that 
 * are needed for the proper working of constant-propogation.
 * Other function calls are handeld by the strategy for FunctionCall in
 * Expression. 
 */
strategies
  /**
   * FunctionCall-construct
   */
  special-const-prop(main|)  =
      FunctionCall(id,map(main))
    ; ?FunctionCall(name,params)
    ; where( value := <php-handle-function-call> (name,params))
    ; add-php-simple-value(|value)

 /**
  * Handles a function call within PHP. It currently has support for the following 
  * internal functions:
  *  - ini_set (some parameters)
  *  - chdir
  */
  php-handle-function-call =
     ?(name,params)
   ; name'   := <php-get-function-name;upper-case> name
   ; params' := <map(php-get-param-value)> params
   ; <php-handle-library-function> (name',params')

  /**
   * Retrieves the functionname. It first tries to get the simple-string value.
   * If this fails it will match a FunctionName-node
   *
   * @type FunctionName(name) OR Expr -> String
   */
  php-get-function-name =
      get-simple-raw-string-value
   <+ ( ?FunctionName(name)
      ; !name
      )

  /**
   * Retrieves the actual value of a parameter. This means that it matches a
   * Param(expr) and retrieves the simple value of this expression.
   *
   * @type Param(Expr) -> PHPValue
   */
  php-get-param-value =
    ?Param(expr)
   ; <get-php-simple-value> expr

  /**
   * Handles the library function chdir
   */
  php-handle-library-function =
      ("CHDIR", ?[PHPString(new-dir)])
    ; set-php-working-directory(|new-dir)
    ; !PHPBoolean(True())  //returns True if succeeds

  /**
   * Handles the library function ini-set on the include_path
   */
  php-handle-library-function =
      ("INI_SET", ?[ inc-path | tail ])
    ; <get-php-raw-value;upper-case> inc-path => "INCLUDE_PATH"
    ; <?[PHPString(new-path)]> tail
    ; <set-php-include-path> new-path
    ; !PHPBoolean(True()) //returns True if succeeds

  /**
   * Handles the library function define
   */
  php-handle-library-function =
       ("DEFINE", ?params)
     ; <?[ php-name | tail    ]> params
     ; <?[ value    | optional]> tail
     ; name := <get-php-raw-value> php-name
     ;(( <php-constant-get-value> name
       ; !PHPBoolean(False())                     // Constant already defined
       )
       <+ 
       ( if <?[PHPBoolean(True())]> optional
         then // add rules for all casings
               names := <all-casings> name
             ; <map (\ ciname -> <add-php-constant-rule> (ciname,value) \)>  names
         else // just normal rule
              <add-php-constant-rule> (name,value)
         end
        ;!PHPBoolean(True())
       )
      )

/***********************************************************************\
                 End FunctionCall Handling
\***********************************************************************/