<p>Given a string <code>s</code> which represents an expression, <em>evaluate this expression and return its value</em>.&nbsp;</p>

<p>The integer division should truncate toward zero.</p>

<p>You may assume that the given expression is always valid. All intermediate results will be in the range of <code>[-2<sup>31</sup>, 2<sup>31</sup> - 1]</code>.</p>

<p><strong>Note:</strong> You are not allowed to use any built-in function which evaluates strings as mathematical expressions, such as <code>eval()</code>.</p>

<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>
<pre><strong>Input:</strong> s = "3+2*2"
<strong>Output:</strong> 7
</pre><p><strong class="example">Example 2:</strong></p>
<pre><strong>Input:</strong> s = " 3/2 "
<strong>Output:</strong> 1
</pre><p><strong class="example">Example 3:</strong></p>
<pre><strong>Input:</strong> s = " 3+5 / 2 "
<strong>Output:</strong> 5
</pre>
<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>

<ul>
	<li><code>1 &lt;= s.length &lt;= 3 * 10<sup>5</sup></code></li>
	<li><code>s</code> consists of integers and operators <code>(&#39;+&#39;, &#39;-&#39;, &#39;*&#39;, &#39;/&#39;)</code> separated by some number of spaces.</li>
	<li><code>s</code> represents <strong>a valid expression</strong>.</li>
	<li>All the integers in the expression are non-negative integers in the range <code>[0, 2<sup>31</sup> - 1]</code>.</li>
	<li>The answer is <strong>guaranteed</strong> to fit in a <strong>32-bit integer</strong>.</li>
</ul>

class Solution:
    def calculate(self, s: str) -> int:

        res = 0
        prev_digit = 0
        op = "+"
        is_neg = False

        def perform_op(op, num1, num2):
            print(f'eq: {num1} {op} {num2}')
            if op == "*":
                return num1 * num2
            if op == "/":
                val = abs(num1) // abs(num2)
                if (num1 < 0 or num2 < 0) and not (num1 < 0 and num2 < 0):
                    val = -val
                return val


        char_idx = 0
        while char_idx < len(s):

            char = s[char_idx]

            if char.isdigit():
                
                # form num
                digit_str = char
                # lookahead
                while char_idx + 1 < len(s):
                    lookahead_idx = char_idx + 1
                    lookahead_char = s[lookahead_idx]
                    if not lookahead_char.isdigit():
                        break # ran out of digits
                    digit_str += lookahead_char # add digit to form number
                    print(f"new digit {digit_str}")
                    char_idx += 1 # increment char_idx to keep track of where we are
                
                digit = int(digit_str)
                # negate if needed
                if is_neg:
                    digit = -digit
                    is_neg = False # reset

                print(digit)

                # for mult and div
                if op == "*" or op == "/": 
                    res -= prev_digit # remove the prev number first
                    digit = perform_op(op, prev_digit, digit) # perform mult/div on prev num to get the new digit

                # add the new digit into the current sum
                res += digit
                prev_digit = digit
            
            elif char != " ":
                if char == "-":
                    op = "+"
                    is_neg = True
                else:
                    op = char

            # check the next idx
            char_idx += 1 

        return res

        # stack = []
        # num_str = ""
        # for char in s:
            
        #     if char.isdigit():
        #         # do number
        #         num_str += char
    
        #     elif char != " ": # skip whitespace
        #         # do symbol
        #         stack.append(int(num_str))
        #         num_str = "" # reset
        #         stack.append(char)
        
        # stack.append(int(num_str))

        # def perform_operation(op, num1, num2):
        #     if op == "/":
        #         return num1 // num2
        #     if op == '*':
        #         return num1 * num2
        #     if op == "+":
        #         return num1 + num2
        #     if op == "-":
        #         return num1 - num2


            
        # # Do the * and / ops first
        # has_muldiv = True
        # while has_muldiv:

        #     # assume false
        #     has_muldiv = False
        #     new_stack = []

        #     # cehck for mul/div
        #     for i in range(len(stack)):
                    
        #         inp = stack[i]
        #         if inp == "*" or inp == "/":
        #             res = perform_operation(inp, stack[i-1], stack[i+1])
        #             new_stack.append(res)
        #             new_stack.extend(stack[i+2:])
        #             has_muldiv = True
        #             break

        #     stack = new_stack


        # # Do the rest of the + or - ops in order
        # res = 0
        # stack.insert(0, "+")
        # curr_op = ""
        # for inp in stack:
        #     if inp != "+" or inp != "-": # number
        #         perform_operation(curr_op, res, inp)
        #     else: # operator
        #         curr_op = inp

        # return res


                


19300