@@ -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,7 +159,7 @@ fn compile_lines(
156159
157160 for ( i, line) in lines. iter ( ) . enumerate ( ) {
158161 match line {
159- SimpleLine :: ForwardDeclaration => {
162+ SimpleLine :: ForwardDeclaration { .. } => {
160163 todo ! ( ) ; // amend stack frame layout
161164 }
162165
@@ -600,7 +603,8 @@ fn handle_const_malloc(
600603 offset : compiler. get_offset ( & var. clone ( ) . into ( ) ) ,
601604 } ,
602605 } ) ;
603- compiler. const_mallocs . insert ( * label, compiler. stack_size ) ;
606+ let current_scope = compiler. stack_frame_layout . scopes . last_mut ( ) . unwrap ( ) ;
607+ current_scope. const_mallocs . insert ( * label, compiler. stack_size ) ;
604608 compiler. stack_size += size;
605609}
606610
@@ -693,6 +697,9 @@ fn find_internal_vars(lines: &[SimpleLine]) -> BTreeSet<Var> {
693697 let mut internal_vars = BTreeSet :: new ( ) ;
694698 for line in lines {
695699 match line {
700+ SimpleLine :: ForwardDeclaration { var } => {
701+ internal_vars. insert ( var. clone ( ) ) ;
702+ }
696703 SimpleLine :: Match { arms, .. } => {
697704 for arm in arms {
698705 internal_vars. extend ( find_internal_vars ( arm) ) ;
0 commit comments