Skip to content

Commit 4c39f56

Browse files
committed
compiler: add constant value only for top let exprs
1 parent 2b4f727 commit 4c39f56

File tree

2 files changed

+25
-14
lines changed

2 files changed

+25
-14
lines changed

src/compiler/src/optimizer/optimize_syntax_tree.rs

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -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

1717
fn 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

4647
fn is_simple_arith_op(op: &str) -> bool {
@@ -50,7 +51,7 @@ fn is_simple_arith_op(op: &str) -> bool {
5051
fn 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
}

src/compiler/src/symbol_table.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,12 @@ impl EntryClass {
3838
}
3939

4040
fn set_constant_value(&mut self, term_value: i16) {
41+
assert!(
42+
matches!(self.constant_value, None),
43+
"Must be written only once. Entry: {:?}\nValue:{}",
44+
self,
45+
term_value
46+
);
4147
self.constant_value = Some(term_value);
4248
}
4349
}

0 commit comments

Comments
 (0)