@@ -19,6 +19,7 @@ struct Compiler {
1919 stack_size : usize ,
2020}
2121
22+ #[ derive( Default ) ]
2223struct 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
@@ -156,8 +159,10 @@ fn compile_lines(
156159
157160 for ( i, line) in lines. iter ( ) . enumerate ( ) {
158161 match line {
159- SimpleLine :: ForwardDeclaration => {
160- todo ! ( ) ; // amend stack frame layout
162+ SimpleLine :: ForwardDeclaration { var } => {
163+ let mut current_scope_layout = compiler. stack_frame_layout . scopes . last_mut ( ) . unwrap ( ) ;
164+ current_scope_layout. var_positions . insert ( var. clone ( ) , compiler. stack_size ) ;
165+ compiler. stack_size += 1 ;
161166 }
162167
163168 SimpleLine :: Assignment {
@@ -166,7 +171,6 @@ fn compile_lines(
166171 arg0,
167172 arg1,
168173 } => {
169- todo ! ( ) ; // amend stack frame layout
170174 instructions. push ( IntermediateInstruction :: computation (
171175 * operation,
172176 IntermediateValue :: from_simple_expr ( arg0, compiler) ,
@@ -177,6 +181,9 @@ fn compile_lines(
177181 mark_vars_as_declared ( & [ arg0, arg1] , declared_vars) ;
178182 if let VarOrConstMallocAccess :: Var ( var) = var {
179183 declared_vars. insert ( var. clone ( ) ) ;
184+ let mut current_scope_layout = compiler. stack_frame_layout . scopes . last_mut ( ) . unwrap ( ) ;
185+ current_scope_layout. var_positions . insert ( var. clone ( ) , compiler. stack_size ) ;
186+ compiler. stack_size += 1 ;
180187 }
181188 }
182189
@@ -192,7 +199,9 @@ fn compile_lines(
192199 }
193200
194201 SimpleLine :: Match { value, arms } => {
195- todo ! ( ) ; // amend stack frame layout
202+ let saved_stack_size = compiler. stack_size ;
203+ compiler. stack_frame_layout . scopes . push ( ScopeLayout :: default ( ) ) ;
204+
196205 let match_index = compiler. match_blocks . len ( ) ;
197206 let end_label = Label :: match_end ( match_index) ;
198207
@@ -254,6 +263,9 @@ fn compile_lines(
254263 let remaining = compile_lines ( function_name, & lines[ i + 1 ..] , compiler, final_jump, declared_vars) ?;
255264 compiler. bytecode . insert ( end_label, remaining) ;
256265
266+ compiler. stack_frame_layout . scopes . pop ( ) ;
267+ compiler. stack_size = saved_stack_size;
268+
257269 return Ok ( instructions) ;
258270 }
259271
@@ -263,7 +275,9 @@ fn compile_lines(
263275 else_branch,
264276 line_number,
265277 } => {
266- todo ! ( ) ; // amend stack frame layout
278+ let saved_stack_size = compiler. stack_size ;
279+ compiler. stack_frame_layout . scopes . push ( ScopeLayout :: default ( ) ) ;
280+
267281 validate_vars_declared ( & [ condition] , declared_vars) ?;
268282
269283 let if_id = compiler. if_counter ;
@@ -368,6 +382,9 @@ fn compile_lines(
368382 let remaining = compile_lines ( function_name, & lines[ i + 1 ..] , compiler, final_jump, declared_vars) ?;
369383 compiler. bytecode . insert ( end_label, remaining) ;
370384
385+ compiler. stack_frame_layout . scopes . pop ( ) ;
386+ compiler. stack_size = saved_stack_size;
387+
371388 return Ok ( instructions) ;
372389 }
373390
@@ -393,7 +410,6 @@ fn compile_lines(
393410 return_data,
394411 line_number,
395412 } => {
396- todo ! ( ) ; // amend stack frame layout
397413 let call_id = compiler. call_counter ;
398414 compiler. call_counter += 1 ;
399415 let return_label = Label :: return_from_call ( call_id, * line_number) ;
@@ -411,6 +427,11 @@ fn compile_lines(
411427
412428 validate_vars_declared ( args, declared_vars) ?;
413429 declared_vars. extend ( return_data. iter ( ) . cloned ( ) ) ;
430+ for var in return_data. iter ( ) {
431+ let mut current_scope_layout = compiler. stack_frame_layout . scopes . last_mut ( ) . unwrap ( ) ;
432+ current_scope_layout. var_positions . insert ( var. clone ( ) , compiler. stack_size ) ;
433+ compiler. stack_size += 1 ;
434+ }
414435
415436 let after_call = {
416437 let mut instructions = Vec :: new ( ) ;
@@ -443,7 +464,6 @@ fn compile_lines(
443464 }
444465
445466 SimpleLine :: Precompile { table, args, .. } => {
446- todo ! ( ) ; // amend stack frame layout?
447467 if * table == Table :: poseidon24 ( ) {
448468 assert_eq ! ( args. len( ) , 3 ) ;
449469 } else {
@@ -486,7 +506,9 @@ fn compile_lines(
486506 vectorized,
487507 vectorized_len,
488508 } => {
489- todo ! ( ) ; // amend stack frame layout
509+ let mut current_scope_layout = compiler. stack_frame_layout . scopes . last_mut ( ) . unwrap ( ) ;
510+ current_scope_layout. var_positions . insert ( var. clone ( ) , compiler. stack_size ) ;
511+ compiler. stack_size += 1 ;
490512 declared_vars. insert ( var. clone ( ) ) ;
491513 instructions. push ( IntermediateInstruction :: RequestMemory {
492514 offset : compiler. get_offset ( & var. clone ( ) . into ( ) ) ,
@@ -496,7 +518,6 @@ fn compile_lines(
496518 } ) ;
497519 }
498520 SimpleLine :: ConstMalloc { var, size, label } => {
499- todo ! ( ) ; // amend stack frame layout
500521 let size = size. naive_eval ( ) . unwrap ( ) . to_usize ( ) ; // TODO not very good;
501522 handle_const_malloc ( declared_vars, & mut instructions, compiler, var, size, label) ;
502523 }
@@ -505,7 +526,6 @@ fn compile_lines(
505526 to_decompose,
506527 label,
507528 } => {
508- todo ! ( ) ; // amend stack frame layout
509529 instructions. push ( IntermediateInstruction :: DecomposeBits {
510530 res_offset : compiler. stack_size ,
511531 to_decompose : to_decompose
@@ -528,7 +548,6 @@ fn compile_lines(
528548 to_decompose,
529549 label,
530550 } => {
531- todo ! ( ) ; // amend stack frame layout
532551 instructions. push ( IntermediateInstruction :: DecomposeCustom {
533552 res_offset : compiler. stack_size ,
534553 to_decompose : to_decompose
@@ -547,7 +566,9 @@ fn compile_lines(
547566 ) ;
548567 }
549568 SimpleLine :: CounterHint { var } => {
550- todo ! ( ) ; // amend stack frame layout
569+ let mut current_scope_layout = compiler. stack_frame_layout . scopes . last_mut ( ) . unwrap ( ) ;
570+ current_scope_layout. var_positions . insert ( var. clone ( ) , compiler. stack_size ) ;
571+ compiler. stack_size += 1 ;
551572 declared_vars. insert ( var. clone ( ) ) ;
552573 instructions. push ( IntermediateInstruction :: CounterHint {
553574 res_offset : compiler
@@ -590,7 +611,6 @@ fn handle_const_malloc(
590611 size : usize ,
591612 label : & ConstMallocLabel ,
592613) {
593- todo ! ( ) ; // amend stack frame layout
594614 declared_vars. insert ( var. clone ( ) ) ;
595615 instructions. push ( IntermediateInstruction :: Computation {
596616 operation : Operation :: Add ,
@@ -600,7 +620,8 @@ fn handle_const_malloc(
600620 offset : compiler. get_offset ( & var. clone ( ) . into ( ) ) ,
601621 } ,
602622 } ) ;
603- compiler. const_mallocs . insert ( * label, compiler. stack_size ) ;
623+ let current_scope = compiler. stack_frame_layout . scopes . last_mut ( ) . unwrap ( ) ;
624+ current_scope. const_mallocs . insert ( * label, compiler. stack_size ) ;
604625 compiler. stack_size += size;
605626}
606627
@@ -693,6 +714,9 @@ 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) ) ;
0 commit comments