diff --git a/.gitignore b/.gitignore index fa9845f..8521912 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ .idea/* -__pycache__ \ No newline at end of file +__pycache__ +/venv/ +mathterpreter.egg-info diff --git a/mathterpreter/_parser.py b/mathterpreter/_parser.py index 2450677..80670b6 100644 --- a/mathterpreter/_parser.py +++ b/mathterpreter/_parser.py @@ -1,5 +1,5 @@ from mathterpreter.nodes import * -from mathterpreter.tokens import TokenType, Token +from mathterpreter.tokens import TokenType, Token, FORMATS from mathterpreter.exceptions import MathSyntaxError from typing import List @@ -11,6 +11,7 @@ def __init__(self, tokens: List[Token]): self._token = None self._index = -1 self._iterate_token() + print(tokens) def _iterate_token(self): try: @@ -31,20 +32,20 @@ def _addition_subtraction_base(self): if self._token is None: output = ''.join([z.__str__() for z in self.token_list]) raise MathSyntaxError("Expression expected", f"{output}\n{'^^^'.rjust(len(output) + 3)}") - result = self._multiplication_division() + result = self._multiplication_division_modulo() while self._token is not None: if self._token.type == TokenType.ADDITION_OPERATOR: self._iterate_token() - result = AdditionNode(result, self._multiplication_division()) + result = AdditionNode(result, self._multiplication_division_modulo()) elif self._token.type == TokenType.SUBTRACTION_OPERATOR: self._iterate_token() - result = SubtractionNode(result, self._multiplication_division()) + result = SubtractionNode(result, self._multiplication_division_modulo()) else: break return result - def _multiplication_division(self): + def _multiplication_division_modulo(self): result = self._exponentiation_root() while self._token is not None: @@ -54,6 +55,9 @@ def _multiplication_division(self): elif self._token.type == TokenType.DIVISION_OPERATOR: self._iterate_token() result = DivisionNode(result, self._exponentiation_root()) + elif self._token.type == TokenType.MODULO_OPERATOR: + self._iterate_token() + result = ModuloNode(result, self._exponentiation_root()) elif self._token.type == TokenType.OPENING_BRACKET: result = MultiplicationNode(result, self._literal_polarity()) else: diff --git a/mathterpreter/lexer.py b/mathterpreter/lexer.py index 23f2fc9..3189bbf 100644 --- a/mathterpreter/lexer.py +++ b/mathterpreter/lexer.py @@ -26,6 +26,8 @@ def expand(compact_dict): "^": lambda: TokenType.POWER_OPERATOR, "(": lambda: TokenType.OPENING_BRACKET, ")": lambda: TokenType.CLOSING_BRACKET, + "!": lambda: TokenType.FACTORIAL_OPERATOR, + "%": lambda: TokenType.MODULO_OPERATOR, } CONSTANTS = { ("pi", "π"): lambda: math.pi, diff --git a/mathterpreter/nodes.py b/mathterpreter/nodes.py index 93d86fe..45b2497 100644 --- a/mathterpreter/nodes.py +++ b/mathterpreter/nodes.py @@ -105,3 +105,14 @@ def __repr__(self): def evaluate(self) -> float: return self.first_operand.evaluate() ** self.second_operand.evaluate() + +@dataclass +class ModuloNode(OperationNode): + def __repr__(self): + return f"({self.first_operand}%{self.second_operand})" + + def evaluate(self) -> float: + return self.first_operand.evaluate() % self.second_operand.evaluate() + + + diff --git a/mathterpreter/tokens.py b/mathterpreter/tokens.py index 516f05c..72a2d02 100644 --- a/mathterpreter/tokens.py +++ b/mathterpreter/tokens.py @@ -14,6 +14,7 @@ class TokenType: POWER_OPERATOR = 7 OPENING_BRACKET = 8 CLOSING_BRACKET = 9 + MODULO_OPERATOR = 10 FORMATS = { @@ -27,7 +28,8 @@ class TokenType: TokenType.SQRT_OPERATOR: "√", TokenType.POWER_OPERATOR: "^", TokenType.OPENING_BRACKET: "(", - TokenType.CLOSING_BRACKET: ")" + TokenType.CLOSING_BRACKET: ")", + TokenType.MODULO_OPERATOR: "%", }