scriptbox

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

DslStatementList.class.php (4207B)


      1 <?php
      2 
      3 namespace dsl\ast;
      4 
      5 use dsl\DslParserException;
      6 use dsl\DslToken;
      7 
      8 class DslStatementList extends DslElement implements DslStatement
      9 {
     10 	private $statements = [];
     11 
     12 	private $functions = [];
     13 
     14 	public function __construct($tokenList)
     15 	{
     16 		$this->parse($tokenList);
     17 	}
     18 
     19 	/**
     20 	 * @param $tokens DslToken[]
     21 	 * @throws DslParserException
     22 	 */
     23 	public function parse($tokens)
     24 	{
     25 		$this->parseTokens($tokens);
     26 	}
     27 
     28 	public function execute( & $context)
     29 	{
     30 		// Auto hoisting for functions: Add functions to context.
     31 		$context = array_merge( $context, $this->functions );
     32 
     33 		foreach ($this->statements as $statement) {
     34 
     35 			$value = $statement->execute($context);
     36 
     37 			if ($statement instanceof DslReturn)
     38 				return $value; // Return to the caller
     39 		}
     40 
     41 		return null;
     42 	}
     43 
     44 
     45 
     46 	/**
     47 	 * @param $tokens DslToken[]
     48 	 * @throws DslParserException
     49 	 */
     50 	public function parseTokens($tokens)
     51 	{
     52 		while (true) {
     53 			$token = array_shift($tokens);
     54 
     55 			if   ( ! $token )
     56 				return;
     57 
     58 			switch ($token->type) {
     59 
     60 				case DslToken::T_STATEMENT_END:
     61 					// maybe an empty statement?
     62 					break;
     63 
     64 				case DslToken::T_OPERATOR:
     65 					throw new DslParserException('Unexpected operator', $token->lineNumber);
     66 				case DslToken::T_BRACKET_CLOSE:
     67 					throw new DslParserException('Unexpected closing group', $token->lineNumber);
     68 				case DslToken::T_BLOCK_END:
     69 					throw new DslParserException('Unexpected ending of an block', $token->lineNumber);
     70 				case DslToken::T_NEGATION:
     71 					throw new DslParserException('Unexpected negation', $token->lineNumber);
     72 				case DslToken::T_DOT:
     73 					throw new DslParserException('Unexpected dot', $token->lineNumber);
     74 
     75 				case DslToken::T_FUNCTION:
     76 
     77 					$nameToken = array_shift( $tokens );
     78 					if ($nameToken->type != DslToken::T_STRING)
     79 						throw new DslParserException('function must have a name', $token->lineNumber);
     80 					$name = $nameToken->value;
     81 
     82 					$functionCallOp    = array_shift($tokens);
     83 					if   ( $functionCallOp->type != DslToken::T_OPERATOR || $functionCallOp->value != '$' )
     84 						throw new DslParserException('function \''.$name.'\' must have a function signature');
     85 
     86 					$functionParameter = $this->getGroup($tokens);
     87 					$functionBlock     = $this->getBlock($tokens);
     88 
     89 					$this->functions[ $name ] = new DslFunction( $functionParameter, $functionBlock );
     90 
     91 					break;
     92 
     93 				case DslToken::T_IF:
     94 					$condition = $this->getGroup($tokens);
     95 					$positiveBlock = $this->getStatementOrBlock($tokens);
     96 					$nextToken = array_shift($tokens);
     97 					if ($nextToken && $nextToken->type == DslToken::T_ELSE) {
     98 						$negativeBlock = $this->getStatementOrBlock($tokens);
     99 					} else {
    100 						$negativeBlock = [];
    101 						array_unshift($tokens, $nextToken);
    102 					}
    103 					$this->statements[] = new DslIf($condition, $positiveBlock, $negativeBlock);
    104 					break;
    105 
    106 				case DslToken::T_LET:
    107 					break;
    108 
    109 				case DslToken::T_FOR:
    110 					$forGroup = $this->getGroup( $tokens );
    111 					$forBlock = $this->getStatementOrBlock( $tokens );
    112 
    113 					//echo "<h5>Forgroup:</h5><pre>"; var_export( $forGroup); echo "</pre>";
    114 
    115 					$varName = array_shift( $forGroup );
    116 					if   ( $varName == null || $varName->type != DslToken::T_STRING )
    117 						throw new DslParserException('for loop variable missing');
    118 					$ofName = array_shift( $forGroup );
    119 					if   ( $ofName == null || $ofName->type != DslToken::T_STRING || strtolower($ofName->value) != 'of' )
    120 						throw new DslParserException('missing \'of\' in for loop');
    121 
    122 					$this->statements[] = new DslFor( $varName->value, $forGroup, $forBlock );
    123 					break;
    124 
    125 				case DslToken::T_RETURN:
    126 					$returnTokens = $this->getSingleStatement( $tokens );
    127 					$this->statements[] = new DslReturn( $returnTokens );
    128 					break;
    129 
    130 				case DslToken::T_THROW:
    131 					$returnTokens = $this->getSingleStatement($tokens );
    132 					$this->statements[] = new DslThrow( $returnTokens );
    133 					break;
    134 
    135 				case DslToken::T_TEXT:
    136 				case DslToken::T_STRING:
    137 					array_unshift( $tokens, $token );
    138 					$statementTokens = $this->getSingleStatement( $tokens );
    139 
    140 					$this->statements[] = new DslExpression( $statementTokens );
    141 					break;
    142 
    143 				default:
    144 					throw new DslParserException('Unknown token of type '.$token->type,$token->lineNumber );
    145 			}
    146 
    147 		}
    148 
    149 	}
    150 
    151 
    152 }