File size: 2,119 Bytes
753d525
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
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