Skip to content

Commit f3942d2

Browse files
committed
wip: issue/88
1 parent 597f86f commit f3942d2

File tree

4 files changed

+70
-61
lines changed

4 files changed

+70
-61
lines changed

crates/lean_compiler/src/a_simplify_lang.rs

Lines changed: 10 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,6 @@ struct ArrayManager {
371371
pub struct ConstMalloc {
372372
counter: usize,
373373
map: BTreeMap<Var, ConstMallocLabel>,
374-
forbidden_vars: BTreeSet<Var>, // vars shared between branches of an if/else
375374
}
376375

377376
impl ArrayManager {
@@ -397,8 +396,8 @@ fn simplify_lines(
397396
let mut res = Vec::new();
398397
for line in lines {
399398
match line {
400-
Line::ForwardDeclaration { var: _ } => {
401-
todo!();
399+
Line::ForwardDeclaration { var } => {
400+
res.push(SimpleLine::ForwardDeclaration { var: var.clone() });
402401
},
403402
Line::Match { value, arms } => {
404403
let simple_value = simplify_expr(value, &mut res, counters, array_manager, const_malloc);
@@ -555,17 +554,6 @@ fn simplify_lines(
555554
}
556555
};
557556

558-
let forbidden_vars_before = const_malloc.forbidden_vars.clone();
559-
560-
let then_internal_vars = find_variable_usage(then_branch).0;
561-
let else_internal_vars = find_variable_usage(else_branch).0;
562-
let new_forbidden_vars = then_internal_vars
563-
.intersection(&else_internal_vars)
564-
.cloned()
565-
.collect::<BTreeSet<_>>();
566-
567-
const_malloc.forbidden_vars.extend(new_forbidden_vars);
568-
569557
let mut array_manager_then = array_manager.clone();
570558
let then_branch_simplified = simplify_lines(
571559
then_branch,
@@ -587,8 +575,6 @@ fn simplify_lines(
587575
const_malloc,
588576
);
589577

590-
const_malloc.forbidden_vars = forbidden_vars_before;
591-
592578
*array_manager = array_manager_else.clone();
593579
// keep the intersection both branches
594580
array_manager.valid = array_manager
@@ -650,6 +636,8 @@ fn simplify_lines(
650636
counter: const_malloc.counter,
651637
..ConstMalloc::default()
652638
};
639+
// TODO: what is array manager, and does it need to be updated
640+
// to make block-level scoping work?
653641
let valid_aux_vars_in_array_manager_before = array_manager.valid.clone();
654642
array_manager.valid.clear();
655643
let simplified_body = simplify_lines(
@@ -781,12 +769,8 @@ fn simplify_lines(
781769
let simplified_size = simplify_expr(size, &mut res, counters, array_manager, const_malloc);
782770
let simplified_vectorized_len =
783771
simplify_expr(vectorized_len, &mut res, counters, array_manager, const_malloc);
784-
if simplified_size.is_constant() && !*vectorized && const_malloc.forbidden_vars.contains(var) {
785-
println!("TODO: Optimization missed: Requires to align const malloc in if/else branches");
786-
}
787772
match simplified_size {
788-
SimpleExpr::Constant(const_size) if !*vectorized && !const_malloc.forbidden_vars.contains(var) => {
789-
// TODO do this optimization even if we are in an if/else branch
773+
SimpleExpr::Constant(const_size) if !*vectorized => {
790774
let label = const_malloc.counter;
791775
const_malloc.counter += 1;
792776
const_malloc.map.insert(var.clone(), label);
@@ -807,7 +791,6 @@ fn simplify_lines(
807791
}
808792
}
809793
Line::DecomposeBits { var, to_decompose } => {
810-
assert!(!const_malloc.forbidden_vars.contains(var), "TODO");
811794
let simplified_to_decompose = to_decompose
812795
.iter()
813796
.map(|expr| simplify_expr(expr, &mut res, counters, array_manager, const_malloc))
@@ -822,7 +805,6 @@ fn simplify_lines(
822805
});
823806
}
824807
Line::DecomposeCustom { var, to_decompose } => {
825-
assert!(!const_malloc.forbidden_vars.contains(var), "TODO");
826808
let simplified_to_decompose = to_decompose
827809
.iter()
828810
.map(|expr| simplify_expr(expr, &mut res, counters, array_manager, const_malloc))
@@ -949,9 +931,8 @@ pub fn find_variable_usage(lines: &[Line]) -> (BTreeSet<Var>, BTreeSet<Var>) {
949931

950932
for line in lines {
951933
match line {
952-
Line::ForwardDeclaration { var: _ } => {
953-
todo!();
954-
// internal_vars.push(var.clone()); // if declaring is using; otherwise do nothing
934+
Line::ForwardDeclaration { var } => {
935+
internal_vars.insert(var.clone());
955936
},
956937
Line::Match { value, arms } => {
957938
on_new_expr(value, &internal_vars, &mut external_vars);
@@ -1997,6 +1978,9 @@ impl SimpleLine {
19971978
fn to_string_with_indent(&self, indent: usize) -> String {
19981979
let spaces = " ".repeat(indent);
19991980
let line_str = match self {
1981+
Self::ForwardDeclaration { var } => {
1982+
format!("var {var}")
1983+
}
20001984
Self::Match { value, arms } => {
20011985
let arms_str = arms
20021986
.iter()

crates/lean_compiler/src/b_compile_intermediate.rs

Lines changed: 57 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ struct Compiler {
1919
stack_size: usize,
2020
}
2121

22+
#[derive(Default)]
2223
struct StackFrameLayout {
2324
// Innermost lexical scope last
2425
scopes: Vec<ScopeLayout>,
@@ -36,7 +37,7 @@ impl Compiler {
3637
VarOrConstMallocAccess::Var(var) => {
3738
for scope in self.stack_frame_layout.scopes.iter().rev() {
3839
if let Some(offset) = scope.var_positions.get(var) {
39-
return offset.into();
40+
return (*offset).into();
4041
}
4142
}
4243
panic!("Variable {var} not in scope");
@@ -45,9 +46,9 @@ impl Compiler {
4546
for scope in self.stack_frame_layout.scopes.iter().rev() {
4647
if let Some(base) = scope.const_mallocs.get(malloc_label) {
4748
return ConstExpression::Binary {
48-
left: Box::new(base.into()),
49+
left: Box::new((*base).into()),
4950
operation: HighLevelOperation::Add,
50-
right: Box::new(offset.clone()),
51+
right: Box::new((*offset).clone()),
5152
};
5253
}
5354
}
@@ -82,7 +83,10 @@ impl IntermediateValue {
8283
},
8384
SimpleExpr::Constant(c) => Self::Constant(c.clone()),
8485
SimpleExpr::ConstMallocAccess { malloc_label, offset } => Self::MemoryAfterFp {
85-
offset: compiler.get_offset(SimpleExpr::ConstMallocAccess { malloc_label, offset }),
86+
offset: compiler.get_offset(&VarOrConstMallocAccess::ConstMallocAccess {
87+
malloc_label: *malloc_label,
88+
offset: offset.clone()
89+
}),
8690
},
8791
}
8892
}
@@ -115,15 +119,14 @@ fn compile_function(
115119
) -> Result<Vec<IntermediateInstruction>, String> {
116120
// memory layout: pc, fp, args, return_vars, internal_vars
117121
let mut stack_pos = 2; // Reserve space for pc and fp
118-
let mut var_positions = BTreeMap::new();
119-
let mut function_scope = Scope::default();
122+
let mut function_scope_layout = ScopeLayout::default();
120123
compiler.stack_frame_layout = StackFrameLayout {
121-
scopes: vec![function_scope],
124+
scopes: vec![function_scope_layout],
122125
};
123-
let function_scope = &mut compiler.stack_frame_layout.scopes[0];
126+
let function_scope_layout = &mut compiler.stack_frame_layout.scopes[0];
124127

125128
for (i, var) in function.arguments.iter().enumerate() {
126-
function_scope.var_positions.insert(var.clone(), stack_pos + i);
129+
function_scope_layout.var_positions.insert(var.clone(), stack_pos + i);
127130
}
128131
stack_pos += function.arguments.len();
129132

@@ -150,14 +153,14 @@ fn compile_lines(
150153
final_jump: Option<Label>,
151154
declared_vars: &mut BTreeSet<Var>,
152155
) -> Result<Vec<IntermediateInstruction>, String> {
153-
// TODO: amend stack frame layout with internal variables.
154-
155156
let mut instructions = Vec::new();
156157

157158
for (i, line) in lines.iter().enumerate() {
158159
match line {
159-
SimpleLine::ForwardDeclaration => {
160-
todo!(); // amend stack frame layout
160+
SimpleLine::ForwardDeclaration { var } => {
161+
let mut current_scope_layout = compiler.stack_frame_layout.scopes.last_mut().unwrap();
162+
current_scope_layout.var_positions.insert(var.clone(), compiler.stack_size);
163+
compiler.stack_size += 1;
161164
}
162165

163166
SimpleLine::Assignment {
@@ -166,18 +169,23 @@ fn compile_lines(
166169
arg0,
167170
arg1,
168171
} => {
169-
todo!(); // amend stack frame layout
170-
instructions.push(IntermediateInstruction::computation(
171-
*operation,
172-
IntermediateValue::from_simple_expr(arg0, compiler),
173-
IntermediateValue::from_simple_expr(arg1, compiler),
174-
IntermediateValue::from_var_or_const_malloc_access(var, compiler),
175-
));
176-
177172
mark_vars_as_declared(&[arg0, arg1], declared_vars);
173+
let arg0 = IntermediateValue::from_simple_expr(arg0, compiler);
174+
let arg1 = IntermediateValue::from_simple_expr(arg1, compiler);
175+
178176
if let VarOrConstMallocAccess::Var(var) = var {
179177
declared_vars.insert(var.clone());
178+
let mut current_scope_layout = compiler.stack_frame_layout.scopes.last_mut().unwrap();
179+
current_scope_layout.var_positions.insert(var.clone(), compiler.stack_size);
180+
compiler.stack_size += 1;
180181
}
182+
183+
instructions.push(IntermediateInstruction::computation(
184+
*operation,
185+
arg0,
186+
arg1,
187+
IntermediateValue::from_var_or_const_malloc_access(var, compiler),
188+
));
181189
}
182190

183191
SimpleLine::TestZero { operation, arg0, arg1 } => {
@@ -192,7 +200,9 @@ fn compile_lines(
192200
}
193201

194202
SimpleLine::Match { value, arms } => {
195-
todo!(); // amend stack frame layout
203+
let saved_stack_size = compiler.stack_size;
204+
compiler.stack_frame_layout.scopes.push(ScopeLayout::default());
205+
196206
let match_index = compiler.match_blocks.len();
197207
let end_label = Label::match_end(match_index);
198208

@@ -254,6 +264,9 @@ fn compile_lines(
254264
let remaining = compile_lines(function_name, &lines[i + 1..], compiler, final_jump, declared_vars)?;
255265
compiler.bytecode.insert(end_label, remaining);
256266

267+
compiler.stack_frame_layout.scopes.pop();
268+
compiler.stack_size = saved_stack_size;
269+
257270
return Ok(instructions);
258271
}
259272

@@ -263,7 +276,9 @@ fn compile_lines(
263276
else_branch,
264277
line_number,
265278
} => {
266-
todo!(); // amend stack frame layout
279+
let saved_stack_size = compiler.stack_size;
280+
compiler.stack_frame_layout.scopes.push(ScopeLayout::default());
281+
267282
validate_vars_declared(&[condition], declared_vars)?;
268283

269284
let if_id = compiler.if_counter;
@@ -368,6 +383,9 @@ fn compile_lines(
368383
let remaining = compile_lines(function_name, &lines[i + 1..], compiler, final_jump, declared_vars)?;
369384
compiler.bytecode.insert(end_label, remaining);
370385

386+
compiler.stack_frame_layout.scopes.pop();
387+
compiler.stack_size = saved_stack_size;
388+
371389
return Ok(instructions);
372390
}
373391

@@ -393,7 +411,6 @@ fn compile_lines(
393411
return_data,
394412
line_number,
395413
} => {
396-
todo!(); // amend stack frame layout
397414
let call_id = compiler.call_counter;
398415
compiler.call_counter += 1;
399416
let return_label = Label::return_from_call(call_id, *line_number);
@@ -411,6 +428,11 @@ fn compile_lines(
411428

412429
validate_vars_declared(args, declared_vars)?;
413430
declared_vars.extend(return_data.iter().cloned());
431+
for var in return_data.iter() {
432+
let mut current_scope_layout = compiler.stack_frame_layout.scopes.last_mut().unwrap();
433+
current_scope_layout.var_positions.insert(var.clone(), compiler.stack_size);
434+
compiler.stack_size += 1;
435+
}
414436

415437
let after_call = {
416438
let mut instructions = Vec::new();
@@ -443,7 +465,6 @@ fn compile_lines(
443465
}
444466

445467
SimpleLine::Precompile { table, args, .. } => {
446-
todo!(); // amend stack frame layout?
447468
if *table == Table::poseidon24() {
448469
assert_eq!(args.len(), 3);
449470
} else {
@@ -486,7 +507,9 @@ fn compile_lines(
486507
vectorized,
487508
vectorized_len,
488509
} => {
489-
todo!(); // amend stack frame layout
510+
let mut current_scope_layout = compiler.stack_frame_layout.scopes.last_mut().unwrap();
511+
current_scope_layout.var_positions.insert(var.clone(), compiler.stack_size);
512+
compiler.stack_size += 1;
490513
declared_vars.insert(var.clone());
491514
instructions.push(IntermediateInstruction::RequestMemory {
492515
offset: compiler.get_offset(&var.clone().into()),
@@ -496,7 +519,6 @@ fn compile_lines(
496519
});
497520
}
498521
SimpleLine::ConstMalloc { var, size, label } => {
499-
todo!(); // amend stack frame layout
500522
let size = size.naive_eval().unwrap().to_usize(); // TODO not very good;
501523
handle_const_malloc(declared_vars, &mut instructions, compiler, var, size, label);
502524
}
@@ -505,7 +527,6 @@ fn compile_lines(
505527
to_decompose,
506528
label,
507529
} => {
508-
todo!(); // amend stack frame layout
509530
instructions.push(IntermediateInstruction::DecomposeBits {
510531
res_offset: compiler.stack_size,
511532
to_decompose: to_decompose
@@ -528,7 +549,6 @@ fn compile_lines(
528549
to_decompose,
529550
label,
530551
} => {
531-
todo!(); // amend stack frame layout
532552
instructions.push(IntermediateInstruction::DecomposeCustom {
533553
res_offset: compiler.stack_size,
534554
to_decompose: to_decompose
@@ -547,7 +567,9 @@ fn compile_lines(
547567
);
548568
}
549569
SimpleLine::CounterHint { var } => {
550-
todo!(); // amend stack frame layout
570+
let mut current_scope_layout = compiler.stack_frame_layout.scopes.last_mut().unwrap();
571+
current_scope_layout.var_positions.insert(var.clone(), compiler.stack_size);
572+
compiler.stack_size += 1;
551573
declared_vars.insert(var.clone());
552574
instructions.push(IntermediateInstruction::CounterHint {
553575
res_offset: compiler
@@ -590,7 +612,6 @@ fn handle_const_malloc(
590612
size: usize,
591613
label: &ConstMallocLabel,
592614
) {
593-
todo!(); // amend stack frame layout
594615
declared_vars.insert(var.clone());
595616
instructions.push(IntermediateInstruction::Computation {
596617
operation: Operation::Add,
@@ -600,7 +621,8 @@ fn handle_const_malloc(
600621
offset: compiler.get_offset(&var.clone().into()),
601622
},
602623
});
603-
compiler.const_mallocs.insert(*label, compiler.stack_size);
624+
let current_scope = compiler.stack_frame_layout.scopes.last_mut().unwrap();
625+
current_scope.const_mallocs.insert(*label, compiler.stack_size);
604626
compiler.stack_size += size;
605627
}
606628

@@ -688,11 +710,13 @@ fn compile_function_ret(
688710
});
689711
}
690712

691-
// TODO: delete this?
692713
fn find_internal_vars(lines: &[SimpleLine]) -> BTreeSet<Var> {
693714
let mut internal_vars = BTreeSet::new();
694715
for line in lines {
695716
match line {
717+
SimpleLine::ForwardDeclaration { var } => {
718+
internal_vars.insert(var.clone());
719+
}
696720
SimpleLine::Match { arms, .. } => {
697721
for arm in arms {
698722
internal_vars.extend(find_internal_vars(arm));

crates/lean_compiler/src/lang.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,7 @@ impl Context {
398398
}
399399
}
400400

401+
#[derive(Default)]
401402
pub struct Scope {
402403
/// A set of declared variables.
403404
pub vars: BTreeSet<Var>,

crates/lean_compiler/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ pub fn compile_program(program: String) -> Bytecode {
1616
let (parsed_program, function_locations) = parse_program(&program).unwrap();
1717
// println!("Parsed program: {}", parsed_program.to_string());
1818
let simple_program = simplify_program(parsed_program);
19-
// println!("Simplified program: {}", simple_program.to_string());
19+
println!("Simplified program: {}", simple_program.to_string());
2020
let intermediate_bytecode = compile_to_intermediate_bytecode(simple_program).unwrap();
21-
// println!("Intermediate Bytecode:\n\n{}", intermediate_bytecode.to_string());
21+
println!("Intermediate Bytecode:\n\n{}", intermediate_bytecode.to_string());
2222

2323
// println!("Function Locations: \n");
2424
// for (loc, name) in function_locations.iter() {

0 commit comments

Comments
 (0)