Example #1
0
 public function testWithersReturnNewModifiedInstance()
 {
     $value = 'bob';
     $newValue = 'alice';
     $type = new TokenType(TokenType::DYNAMIC_ARRAY_TYPE);
     $token = new Token($value, $type);
     $newToken = $token->withValue($newValue);
     $this->assertEquals($value, $token->getValue());
     $this->assertEquals($type->getValue(), $token->getType());
     $this->assertInstanceOf(Token::class, $newToken);
     $this->assertEquals($newValue, $newToken->getValue());
     $this->assertEquals($type->getValue(), $newToken->getType());
 }
Example #2
0
 public function __toString()
 {
     return sprintf('(%s) %s', $this->type->getValue(), $this->value);
 }
Example #3
0
 /**
  * @dataProvider provideAcceptableTypes
  */
 public function testCanCreateType(string $typeConstant)
 {
     $type = new TokenType($typeConstant);
     $this->assertEquals($type->getValue(), constant(sprintf('%s::%s', TokenType::class, $typeConstant)));
 }
Example #4
0
File: Parser.php Project: g4z/poop
 /**
  * Evaluate the next expression
  * @param string &$buffer The expression result value is written here
  * @param Token $token An optional start from token
  * @return int The Type ID of the expression result
  */
 protected function evalExp(&$buffer, $token = NULL)
 {
     static $depth = -1;
     $depth++;
     $this->debug(__METHOD__, __LINE__, 'evalExp depth: ' . $depth);
     $buffer = '';
     // write to arg by reference
     if (!$token) {
         $token = $this->getToken();
     }
     if (!$token) {
         throw new SyntaxException($this->getLine(), $this->getColumn(), 'Failed evaluating expression', __FILE__, __LINE__);
     }
     switch ($token->getType()) {
         case TokenType::IDENTIFIER:
             $this->debug(__METHOD__, __LINE__, "Evaluating IDENTIFIER token");
             $varname = $token->getValue();
             // If identifier not found in memory
             if (!$this->memory->hasVar($varname)) {
                 throw new SyntaxException($token->getLine(), $token->getColumn(), "Undefined identifier: '{$varname}'", __FILE__, __LINE__);
             }
             $variable = $this->memory->getVar($varname);
             $leftside = $variable->getValue();
             $vartype = $variable->getType();
             break;
         case TokenType::MINVOKE:
             $this->debug(__METHOD__, __LINE__, "Evaluating MINVOKE token");
             $result = $this->procMethodInvoke($token);
             $leftside = $result->getValue();
             $vartype = $result->getType();
             unset($result);
             break;
         case TokenType::INTEGER:
             $this->debug(__METHOD__, __LINE__, "Evaluating INTEGER token");
             $vartype = TokenType::INTEGER;
             $leftside = $token->getValue();
             break;
         case TokenType::FLOAT:
             $this->debug(__METHOD__, __LINE__, "Evaluating FLOAT token");
             $vartype = TokenType::FLOAT;
             $leftside = $token->getValue();
             break;
         case TokenType::STRING:
             $this->debug(__METHOD__, __LINE__, "Evaluating STRING token");
             $vartype = TokenType::STRING;
             $leftside = $token->getValue();
             break;
         case TokenType::SYMBOL:
             $this->debug(__METHOD__, __LINE__, "Evaluating SYMBOL token");
             list($leftside, $vartype) = $this->procSymbol($token);
             // $vartype = TokenType::SYMBOL;
             if (!$leftside) {
                 die("O");
                 return;
             }
             break;
         case TokenType::KEYWORD:
         default:
             throw new SyntaxException($token->getLine(), $token->getColumn(), 'Invalid expression: ' . $token->getValue(), __FILE__, __LINE__);
             break;
     }
     $buffer = $leftside;
     // assign it incase we exit ;)
     $this->debug(__METHOD__, __LINE__, "Leftside_Value: {$buffer}");
     // $this->debug(__METHOD__, __LINE__, "Leftside_Type: $vartype");
     $this->debug(__METHOD__, __LINE__, "Leftside_TypeName: " . TokenType::map($vartype));
     // Get the operator part of the expression
     $token = $this->getToken();
     switch ($token->getType()) {
         case TokenType::SYMBOL:
             switch ($token->getValue()) {
                 case ')':
                     $depth--;
                     $this->ungetCharacter();
                     return $vartype;
                     // hello
                 // hello
                 case ';':
                     $depth--;
                     // $this->ungetCharacter();
                     return $vartype;
                     // hello
                     break;
                 case ',':
                     return $vartype;
                     break;
                 case '+':
                     // also for string concat
                 // also for string concat
                 case '-':
                 case '*':
                 case '/':
                 case '%':
                     // math operators
                     break;
                 case '==':
                 case '!=':
                 case '<':
                 case '>':
                 case '>=':
                 case '<=':
                     // comparison operators
                     break;
                 case '&&':
                 case '||':
                     // logical
                     break;
                 case '&':
                 case '|':
                     // bitwise
                     break;
                 default:
                     throw new SyntaxException($token->getLine(), $token->getColumn(), 'Invalid operator: ' . $token->getValue(), __FILE__, __LINE__);
                     break;
             }
             break;
         default:
             throw new SyntaxException($token->getLine(), $token->getColumn(), 'Invalid symbol: ' . $token->getValue(), __FILE__, __LINE__);
             break;
     }
     $operator = $token->getValue();
     $this->debug(__METHOD__, __LINE__, 'Operator_Value: ' . $operator);
     // $this->debug(__METHOD__, __LINE__, 'Operator_Type: ' . $token->getType());
     $this->debug(__METHOD__, __LINE__, "Operator_TypeName: " . TokenType::map($token->getType()));
     // Recursive call to evaluate the expression further
     $rightside = '';
     $vartype2 = $this->evalExp($rightside);
     $this->debug(__METHOD__, __LINE__, 'Rightside_Value: ' . $rightside);
     // $this->debug(__METHOD__, __LINE__, "Rightside_Type: $vartype2");
     $this->debug(__METHOD__, __LINE__, "Rightside_TypeName: " . TokenType::map($vartype2));
     switch ($vartype) {
         case TokenType::FLOAT:
             $n1 = floatval($leftside);
             $n2 = floatval($rightside);
             if ($operator == '+') {
                 $n3 = $n1 + $n2;
             } elseif ($operator == '-') {
                 $n3 = $n1 - $n2;
             } elseif ($operator == '*') {
                 $n3 = $n1 * $n2;
             } elseif ($operator == '/') {
                 $n3 = $n1 / $n2;
             } elseif ($operator == '==') {
                 $n3 = $n1 == $n2;
             } elseif ($operator == '<') {
                 $n3 = $n1 < $n2;
             } elseif ($operator == '>') {
                 $n3 = $n1 > $n2;
             } elseif ($operator == '<=') {
                 $n3 = $n1 <= $n2;
             } elseif ($operator == '>=') {
                 $n3 = $n1 >= $n2;
             } elseif ($operator == '!=') {
                 $n3 = $n1 != $n2;
             } else {
                 throw new SyntaxException($token->getLine(), $token->getColumn(), 'Illegal float operator: ' . $operator, __FILE__, __LINE__);
             }
             // set the output buffer
             $buffer = floatval($n3);
             break;
         case TokenType::INTEGER:
             $n1 = intval($leftside);
             $n2 = intval($rightside);
             if ($operator == '+') {
                 $n3 = $n1 + $n2;
             } elseif ($operator == '-') {
                 $n3 = $n1 - $n2;
             } elseif ($operator == '*') {
                 $n3 = $n1 * $n2;
             } elseif ($operator == '/') {
                 $n3 = $n1 / $n2;
             } elseif ($operator == '%') {
                 $n3 = $n1 % $n2;
             } elseif ($operator == '==') {
                 $n3 = $n1 == $n2;
             } elseif ($operator == '<') {
                 $n3 = $n1 < $n2;
             } elseif ($operator == '>') {
                 $n3 = $n1 > $n2;
             } elseif ($operator == '<=') {
                 $n3 = $n1 <= $n2;
             } elseif ($operator == '>=') {
                 $n3 = $n1 >= $n2;
             } elseif ($operator == '!=') {
                 $n3 = $n1 != $n2;
             } elseif ($operator == '&&') {
                 $n3 = (int) ($n1 && $n2);
             } elseif ($operator == '||') {
                 $n3 = (int) ($n1 || $n2);
             } elseif ($operator == '&') {
                 $n3 = $n1 & $n2;
             } elseif ($operator == '|') {
                 $n3 = $n1 | $n2;
             } else {
                 throw new SyntaxException($token->getLine(), $token->getColumn(), 'Illegal numerical operator: ' . $operator, __FILE__, __LINE__);
             }
             // set the output buffer
             $buffer = intval($n3);
             break;
         case TokenType::STRING:
             $tmp = $rightside;
             if ($operator == '+') {
                 $buffer .= $rightside;
             } elseif ($operator == '==') {
                 $buffer = $buffer == $tmp ? '1' : '0';
             } elseif ($operator == '<') {
                 $buffer = $buffer < $tmp ? '1' : '0';
             } elseif ($operator == '>') {
                 $buffer = $buffer > $tmp ? '1' : '0';
             } elseif ($operator == '!=') {
                 $buffer = $buffer != $tmp ? '1' : '0';
             } elseif ($operator == '<=') {
                 $buffer = $buffer <= $tmp ? '1' : '0';
             } elseif ($operator == '>=') {
                 $buffer = $buffer >= $tmp ? '1' : '0';
             } elseif ($operator == '&&') {
                 $buffer = $buffer && $tmp ? '1' : '0';
             } elseif ($operator == '||') {
                 $buffer = $buffer || $tmp ? '1' : '0';
             } elseif ($operator == '&') {
                 $buffer = $buffer & $tmp ? '1' : '0';
             } elseif ($operator == '|') {
                 $buffer = $buffer | $tmp ? '1' : '0';
             } else {
                 throw new SyntaxException($token->getLine(), $token->getColumn(), 'Illegal string operator: ' . $operator, __FILE__, __LINE__);
             }
             break;
         default:
             throw new SyntaxException($token->getLine(), $token->getColumn(), 'Unexpected variable type: ' . TokenType::map($vartype), __FILE__, __LINE__);
             break;
     }
     $this->debug(__METHOD__, __LINE__, "Expression: {$leftside} {$operator} {$rightside}");
     $this->debug(__METHOD__, __LINE__, 'Result: ' . $buffer);
     $this->debug(__METHOD__, __LINE__, 'Type: ' . TokenType::map($vartype));
     $depth--;
     return $vartype;
 }