openrat-cms

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

DslFunctionCall.class.php (2518B)


      1 <?php
      2 
      3 namespace dsl\ast;
      4 
      5 use dsl\DslRuntimeException;
      6 use dsl\DslToken;
      7 use dsl\executor\DslInterpreter;
      8 use dsl\standard\Number;
      9 use dsl\standard\StandardArray;
     10 use dsl\standard\StandardString;
     11 
     12 class DslFunctionCall implements DslStatement
     13 {
     14 	public $name;
     15 	private $parameters;
     16 
     17 	/**
     18 	 * DslFunctionCall constructor.
     19 	 * @param $name
     20 	 * @param $parameters DslToken[][]
     21 	 */
     22 	public function __construct($name, $parameters)
     23 	{
     24 		$this->name       = $name;
     25 		$this->parameters = $parameters;
     26 	}
     27 
     28 
     29 	/**
     30 	 * @throws DslRuntimeException
     31 	 */
     32 	public function execute(& $context ) {
     33 
     34 		$function = $this->name->execute( $context );
     35 
     36 		if   ( $this->parameters == null )
     37 			$parameterValues = []; // parameterless functions.
     38 		else
     39 			$parameterValues = $this->parameters->execute( $context );
     40 
     41 		// if there is only 1 parameter it must be converted to an array.
     42 		// if there are more than 1 parameter, it is already a sequence
     43 		if   ( ! is_array($parameterValues)) $parameterValues = array($parameterValues);
     44 
     45 
     46 		if   ( $function instanceof DslFunction ) {
     47 			// inscript custom function
     48 			$parameters = $function->parameters;
     49 
     50 			if   ( sizeof($parameters) > sizeof($parameterValues) )
     51 				throw new DslRuntimeException('function call has '.sizeof($parameterValues).' parameters but the function has '.sizeof($parameters).' parameters');
     52 
     53 			// Put all function parameters to the function context.
     54 			$parameterContext = array_combine( $parameters, array_slice($parameterValues,0,sizeof($parameters)) );
     55 			$subContext = array_merge( $context,$parameterContext );
     56 
     57 			return $function->execute( $subContext );
     58 
     59 		}
     60 		elseif   ( is_callable($function) ) {
     61 
     62 			return DslExpression::convertValueToStandardObject( call_user_func_array( $function, $this->toPrimitiveValues($parameterValues)) );
     63 		}
     64 		else
     65 			throw new DslRuntimeException('function is not callable'.var_export($function));
     66 	}
     67 
     68 	public function parse($tokens)
     69 	{
     70 		$this->statements[] = $tokens;
     71 	}
     72 
     73 
     74 	/**
     75 	 * Converts variables to its primitives, because external objects in applications will not be able to handle things like "StandardString".
     76 	 * @param $parameterValues
     77 	 * @return array
     78 	 */
     79 	private function toPrimitiveValues( $parameterValues )
     80 	{
     81 		return array_map( function( $val ) {
     82 			if   ( $val instanceof StandardArray )
     83 				return $val->getInternalValue();
     84 			if   ( $val instanceof Number )
     85 				return $val->toNumber();
     86 			if   ( $val instanceof StandardString )
     87 				return (string)$val;
     88 
     89 			return $val;
     90 
     91 		},$parameterValues );
     92 	}
     93 }