Skip to content

Commit 88be8cd

Browse files
committed
wip: issue/88
1 parent 1aeb676 commit 88be8cd

File tree

1 file changed

+70
-18
lines changed

1 file changed

+70
-18
lines changed

crates/lean_compiler/src/b_compile_intermediate.rs

Lines changed: 70 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -126,13 +126,16 @@ fn compile_function(
126126
function: &SimpleFunction,
127127
compiler: &mut Compiler,
128128
) -> Result<Vec<IntermediateInstruction>, String> {
129-
let mut internal_vars = find_internal_vars(&function.instructions);
130-
131-
internal_vars.retain(|var| !function.arguments.contains(var));
129+
let internal_vars: InternalVars = find_internal_vars(
130+
&function.instructions,
131+
&|var: &Var| -> bool {
132+
function.arguments.contains(var)
133+
}
134+
);
132135

133136
// memory layout: pc, fp, args, return_vars, internal_vars
134137
let mut stack_pos = 2; // Reserve space for pc and fp
135-
let mut var_positions = BTreeMap::new();
138+
let mut var_positions: BTreeMap<Var, usize> = BTreeMap::new();
136139

137140
for (i, var) in function.arguments.iter().enumerate() {
138141
var_positions.insert(var.clone(), stack_pos + i);
@@ -141,10 +144,7 @@ fn compile_function(
141144

142145
stack_pos += function.n_returned_vars;
143146

144-
for (i, var) in internal_vars.iter().enumerate() {
145-
var_positions.insert(var.clone(), stack_pos + i);
146-
}
147-
stack_pos += internal_vars.len();
147+
stack_pos = layout_internal_vars(&internal_vars, &mut var_positions, stack_pos);
148148

149149
compiler.func_name = function.name.clone();
150150
compiler.var_positions = var_positions;
@@ -161,6 +161,37 @@ fn compile_function(
161161
)
162162
}
163163

164+
fn layout_internal_vars(
165+
internal_vars: &InternalVars,
166+
var_positions: &mut BTreeMap<Var, usize>,
167+
initial_stack_pos: usize
168+
) -> usize {
169+
let mut stack_pos = initial_stack_pos;
170+
match internal_vars {
171+
InternalVars::One(var) => {
172+
if !var_positions.contains_key(var) {
173+
var_positions.insert(var.clone(), stack_pos);
174+
stack_pos += 1;
175+
}
176+
},
177+
InternalVars::AllOf(children) => {
178+
for child in children {
179+
stack_pos = layout_internal_vars(child, var_positions, stack_pos);
180+
}
181+
},
182+
InternalVars::OneOf(children) => {
183+
// TODO: this is wrong b/c it can result in the same stack pos
184+
// being doubly assigned when a name is shared between branches?
185+
let mut new_stack_poss: Vec<usize> = Vec::new();
186+
for child in children {
187+
new_stack_poss.push(layout_internal_vars(child, var_positions, stack_pos));
188+
}
189+
stack_pos = *new_stack_poss.iter().max().unwrap_or(&stack_pos);
190+
},
191+
}
192+
stack_pos
193+
}
194+
164195
fn compile_lines(
165196
function_name: &Label,
166197
lines: &[SimpleLine],
@@ -795,18 +826,30 @@ fn compile_function_ret(
795826
});
796827
}
797828

798-
fn find_internal_vars(lines: &[SimpleLine]) -> BTreeSet<Var> {
799-
let mut internal_vars = BTreeSet::new();
829+
enum InternalVars {
830+
One(Var),
831+
AllOf(Vec<InternalVars>),
832+
OneOf(Vec<InternalVars>),
833+
}
834+
835+
fn find_internal_vars<F>(lines: &[SimpleLine], exclude: &F) -> InternalVars
836+
where F: Fn(&Var) -> bool
837+
{
838+
let mut internal_vars: Vec<InternalVars> = Vec::new();
800839
for line in lines {
801840
match line {
802841
SimpleLine::Match { arms, .. } => {
842+
let mut branch_vars: Vec<InternalVars> = Vec::new();
803843
for arm in arms {
804-
internal_vars.extend(find_internal_vars(arm));
844+
branch_vars.push(find_internal_vars(arm, exclude));
805845
}
846+
internal_vars.push(InternalVars::OneOf(branch_vars));
806847
}
807848
SimpleLine::Assignment { var, .. } => {
808849
if let VarOrConstMallocAccess::Var(var) = var {
809-
internal_vars.insert(var.clone());
850+
if !exclude(var) {
851+
internal_vars.push(InternalVars::One(var.clone()));
852+
}
810853
}
811854
}
812855
SimpleLine::TestZero { .. } => {}
@@ -815,23 +858,32 @@ fn find_internal_vars(lines: &[SimpleLine]) -> BTreeSet<Var> {
815858
| SimpleLine::DecomposeBits { var, .. }
816859
| SimpleLine::DecomposeCustom { var, .. }
817860
| SimpleLine::CounterHint { var } => {
818-
internal_vars.insert(var.clone());
861+
internal_vars.push(InternalVars::One(var.clone()));
819862
}
820863
SimpleLine::RawAccess { res, .. } => {
821864
if let SimpleExpr::Var(var) = res {
822-
internal_vars.insert(var.clone());
865+
if !exclude(var) {
866+
internal_vars.push(InternalVars::One(var.clone()));
867+
}
823868
}
824869
}
825870
SimpleLine::FunctionCall { return_data, .. } => {
826-
internal_vars.extend(return_data.iter().cloned());
871+
internal_vars.extend(return_data.iter().cloned()
872+
.filter(|var| !exclude(var))
873+
.map(InternalVars::One)
874+
);
827875
}
828876
SimpleLine::IfNotZero {
829877
then_branch,
830878
else_branch,
831879
..
832880
} => {
833-
internal_vars.extend(find_internal_vars(then_branch));
834-
internal_vars.extend(find_internal_vars(else_branch));
881+
internal_vars.push(InternalVars::OneOf(
882+
vec![
883+
find_internal_vars(then_branch, exclude),
884+
find_internal_vars(else_branch, exclude)
885+
]
886+
));
835887
}
836888
SimpleLine::Panic
837889
| SimpleLine::Print { .. }
@@ -840,5 +892,5 @@ fn find_internal_vars(lines: &[SimpleLine]) -> BTreeSet<Var> {
840892
| SimpleLine::LocationReport { .. } => {}
841893
}
842894
}
843-
internal_vars
895+
InternalVars::AllOf(internal_vars)
844896
}

0 commit comments

Comments
 (0)