Spaces:
Runtime error
Runtime error
| class Optimizer: | |
| def fold_constants(self, expr): | |
| # --- PRESERVED: Your original base case fallback logic --- | |
| if not isinstance(expr, tuple) or expr[0] != 'BINOP': | |
| try: | |
| if isinstance(expr, str) and expr.isdigit(): | |
| return int(expr) | |
| return expr | |
| except: | |
| return expr | |
| op = expr[1] | |
| left = self.fold_constants(expr[2]) | |
| right = self.fold_constants(expr[3]) | |
| # --- ENHANCEMENT: Handle actual numeric objects from the lexer --- | |
| if isinstance(left, (int, float)) and isinstance(right, (int, float)): | |
| if op == '+': return left + right | |
| if op == '-': return left - right | |
| if op == '*': return left * right | |
| if op == '/': return left // right if right != 0 else 0 | |
| # --- HIGH-FI ADDITION: Algebraic Simplifications --- | |
| if op == '+': | |
| if left == 0: return right | |
| if right == 0: return left | |
| elif op == '-': | |
| if right == 0: return left | |
| if left == right: return 0 | |
| elif op == '*': | |
| if left == 0 or right == 0: return 0 | |
| if left == 1: return right | |
| if right == 1: return left | |
| return ('BINOP', op, left, right) | |
| def optimize(self, ast): | |
| optimized_ast = [] | |
| for node in ast: | |
| node_type = node[0] | |
| if node_type == 'ASSIGN': | |
| optimized_ast.append(('ASSIGN', node[1], self.fold_constants(node[2]))) | |
| elif node_type == 'DECL_ASSIGN': | |
| optimized_ast.append(('DECL_ASSIGN', node[1], self.fold_constants(node[2]))) | |
| elif node_type == 'PRINT': | |
| optimized_ast.append(('PRINT', self.fold_constants(node[1]))) | |
| elif node_type == 'BLOCK': | |
| optimized_ast.append(('BLOCK', self.optimize(node[1]))) | |
| else: | |
| optimized_ast.append(node) | |
| return optimized_ast |