Skip to content

Commit

Permalink
Lookup binary operator from registry during parsing stage instead of …
Browse files Browse the repository at this point in the history
…during evaluation stage
  • Loading branch information
Muqsit committed Sep 25, 2022
1 parent b054f17 commit 346091f
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 28 deletions.
32 changes: 14 additions & 18 deletions src/muqsit/arithmexp/Parser.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,24 +65,20 @@ public function parse(string $expression) : Expression{
$this->transformUnaryOperatorTokens($tokens);
$this->groupBinaryOperations($expression, $tokens);
$this->convertTokenTreeToPostfixTokenTree($tokens);
return new Expression(
$this->binary_operator_registry,
$expression,
array_map(function(Token $token) : ExpressionToken{
if($token instanceof BinaryOperatorToken){
return new OperatorExpressionToken($token->getOperator());
}
if($token instanceof NumericLiteralToken){
return new NumericLiteralExpressionToken($token->getValue());
}
if($token instanceof VariableToken){
$label = $token->getLabel();
$constant_value = $this->constant_registry->registered[$label] ?? null;
return $constant_value !== null ? new NumericLiteralExpressionToken($constant_value) : new VariableExpressionToken($label);
}
throw new RuntimeException("Don't know how to convert {$token->getType()->getName()} token to " . ExpressionToken::class);
}, $tokens)
);
return new Expression($expression, array_map(function(Token $token) : ExpressionToken{
if($token instanceof BinaryOperatorToken){
return new OperatorExpressionToken($this->binary_operator_registry->get($token->getOperator()));
}
if($token instanceof NumericLiteralToken){
return new NumericLiteralExpressionToken($token->getValue());
}
if($token instanceof VariableToken){
$label = $token->getLabel();
$constant_value = $this->constant_registry->registered[$label] ?? null;
return $constant_value !== null ? new NumericLiteralExpressionToken($constant_value) : new VariableExpressionToken($label);
}
throw new RuntimeException("Don't know how to convert {$token->getType()->getName()} token to " . ExpressionToken::class);
}, $tokens));
}

/**
Expand Down
9 changes: 1 addition & 8 deletions src/muqsit/arithmexp/expression/Expression.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,28 +8,21 @@
use muqsit\arithmexp\expression\token\ExpressionToken;
use muqsit\arithmexp\expression\token\OperatorExpressionToken;
use muqsit\arithmexp\expression\token\VariableExpressionToken;
use muqsit\arithmexp\operator\BinaryOperatorRegistry;
use RuntimeException;
use function array_map;
use function implode;

final class Expression{

/**
* @param BinaryOperatorRegistry $binary_operator_registry
* @param string $expression
* @param ExpressionToken[] $postfix_expression_tokens
*/
public function __construct(
private BinaryOperatorRegistry $binary_operator_registry,
private string $expression,
private array $postfix_expression_tokens
){}

public function getBinaryOperatorRegistry() : BinaryOperatorRegistry{
return $this->binary_operator_registry;
}

public function getExpression() : string{
return $this->expression;
}
Expand Down Expand Up @@ -61,7 +54,7 @@ public function evaluate(array $variable_values = []) : int|float{
$ptr = -1;
foreach($this->postfix_expression_tokens as $token){
if($token instanceof OperatorExpressionToken){
$stack[$ptr - 1] = $this->binary_operator_registry->get($token->operator)->operate($stack[$ptr - 1], $stack[$ptr]);
$stack[$ptr - 1] = $token->operator->operate($stack[$ptr - 1], $stack[$ptr]);
--$ptr;
}else{
$stack[++$ptr] = $token->getValue($this, $variable_values);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,20 @@
namespace muqsit\arithmexp\expression\token;

use muqsit\arithmexp\expression\Expression;
use muqsit\arithmexp\operator\BinaryOperator;
use RuntimeException;

final class OperatorExpressionToken implements ExpressionToken{

public function __construct(
public string $operator
public BinaryOperator $operator
){}

public function getValue(Expression $expression, array $variables) : int|float{
throw new RuntimeException("Don't know how to get value of " . self::class);
}

public function __toString() : string{
return $this->operator;
return $this->operator->getSymbol();
}
}

0 comments on commit 346091f

Please sign in to comment.