@@ -11,36 +11,37 @@ pub fn optimize_syntax_tree_expression(
1111 context : & CompilerContext ,
1212) -> Option < Vec < WriteInst > > {
1313 let lhs_context = context. lhs_context ( ) ;
14- optimize_expr ( term1, ops, state. sym_table ( ) , & lhs_context)
14+ optimize_expr ( term1, ops, & mut Some ( state. sym_table ( ) ) , & lhs_context)
1515}
1616
1717fn optimize_expr_int_inner (
1818 term1 : & Term ,
1919 ops : & [ ( Op , Term ) ] ,
20- sym_table : & mut SymbolTable ,
20+ sym_table : & mut Option < & mut SymbolTable > ,
2121 lhs_context : & LhsContext ,
2222) -> Option < i16 > {
2323 // dbg!(term1, ops);
24- let mut term1_value = eval_term ( term1, sym_table, lhs_context) ;
24+ let term1_value = eval_term ( term1, sym_table) ;
25+ let mut full_expr_int_value = term1_value;
2526 for ( Op ( op) , term2) in ops {
2627 if !is_simple_arith_op ( op. as_str ( ) ) {
2728 return None ;
2829 }
29- let term2_value = eval_term ( term2, sym_table, lhs_context ) ;
30- if let ( Some ( a) , Some ( b) ) = ( term1_value , term2_value) {
31- term1_value = eval_binop ( op, a, b) ;
30+ let term2_value = eval_term ( term2, sym_table) ;
31+ if let ( Some ( a) , Some ( b) ) = ( full_expr_int_value , term2_value) {
32+ full_expr_int_value = eval_binop ( op, a, b) ;
3233 } else {
3334 return None ;
3435 }
3536 }
3637
37- if let ( Some ( term_value) , Some ( LhsContextInner :: ClassStatic ( class_static) ) ) =
38- ( term1_value , lhs_context)
38+ if let ( Some ( term_value) , Some ( sym_table ) , Some ( LhsContextInner :: ClassStatic ( class_static) ) ) =
39+ ( full_expr_int_value , sym_table , lhs_context)
3940 {
4041 sym_table. add_constant_value_for_static ( class_static. name ( ) , term_value) ;
4142 }
4243
43- term1_value
44+ full_expr_int_value
4445}
4546
4647fn is_simple_arith_op ( op : & str ) -> bool {
@@ -50,7 +51,7 @@ fn is_simple_arith_op(op: &str) -> bool {
5051fn optimize_expr (
5152 term1 : & Term ,
5253 ops : & [ ( Op , Term ) ] ,
53- sym_table : & mut SymbolTable ,
54+ sym_table : & mut Option < & mut SymbolTable > ,
5455 lhs_context : & LhsContext ,
5556) -> Option < Vec < WriteInst > > {
5657 // dbg!(term1, ops);
@@ -88,27 +89,31 @@ fn eval_unop(op: &str, a: i16) -> Option<i16> {
8889 }
8990}
9091
91- fn eval_term ( term : & Term , sym_table : & mut SymbolTable , lhs_context : & LhsContext ) -> Option < i16 > {
92+ fn eval_term ( term : & Term , sym_table : & mut Option < & mut SymbolTable > ) -> Option < i16 > {
9293 // dbg!(term);
9394 match term {
9495 Term :: IntegerConstant ( value) => {
9596 // dbg!(value);
9697 Some ( ( * value) . try_into ( ) . unwrap ( ) )
9798 }
98- Term :: UnaryOp ( Op ( op) , term) => match eval_term ( term, sym_table, lhs_context ) {
99+ Term :: UnaryOp ( Op ( op) , term) => match eval_term ( term, sym_table) {
99100 Some ( term_value) => eval_unop ( op, term_value) ,
100101 None => None ,
101102 } ,
102103 Term :: ParenExpr ( expr) => {
103104 let Expr ( termp1, ops) = & * * expr;
104- optimize_expr_int_inner ( termp1, ops, sym_table, lhs_context)
105+ optimize_expr_int_inner (
106+ termp1, ops, sym_table,
107+ // add_constant_value_for_static only for top level expression
108+ & None ,
109+ )
105110 }
106111 Term :: KeywordConstant ( Keyword :: Null ) => Some ( 0 ) ,
107112 Term :: KeywordConstant ( Keyword :: True ) => Some ( -1 ) ,
108113 Term :: KeywordConstant ( Keyword :: False ) => Some ( 0 ) ,
109114 #[ allow( clippy:: let_and_return) ]
110115 Term :: VarName ( ident) => {
111- let entry = sym_table. lookup ( ident) ?;
116+ let entry = sym_table. as_ref ( ) . and_then ( |e| e . lookup ( ident) ) ?;
112117 if entry. typ != type_as_string ( & GrammarItemType :: Int ) {
113118 return None ;
114119 }
0 commit comments