diff options
-rw-r--r-- | Sil/Compile.icl | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/Sil/Compile.icl b/Sil/Compile.icl index c64079e..baeb2fd 100644 --- a/Sil/Compile.icl +++ b/Sil/Compile.icl @@ -65,6 +65,12 @@ symbols cs = cs.symbols newReturn :: 'ABC'.Assembler CompileState -> CompileState newReturn ret cs = {cs & returns=[ret:cs.returns]} +addToReturn :: 'ABC'.Assembler CompileState -> CompileState +addToReturn ret cs=:{returns=[r:rs]} = {cs & returns=[ret ++ r:rs]} + +removeFromReturn :: Int CompileState -> CompileState +removeFromReturn i cs=:{returns=[r:rs]} = {cs & returns=[drop i r:rs]} + popReturn :: CompileState -> CompileState popReturn cs = {cs & returns=tl cs.returns} @@ -110,7 +116,7 @@ where tell [ 'ABC'.Annotation $ 'ABC'.OAnnot args [] , 'ABC'.Label f.f_name ] *> - foldM reserveVar (length f.f_code.cb_init) [a.arg_name \\ a <- reverse f.f_args] *> + foldM reserveVar locals [a.arg_name \\ a <- reverse f.f_args] *> modify (newReturn cleanup) *> gen f.f_code *> modify popReturn @@ -124,18 +130,21 @@ where , 'ABC'.Annotation $ 'ABC'.DAnnot 1 [] ] args = length f.f_args + locals = length f.f_code.cb_init instance gen CodeBlock where gen cb = foldM reserveVar 0 [i.init_name \\ i <- cb.cb_init] *> mapM_ gen cb.cb_init *> + modify (addToReturn cleanup`) *> mapM_ gen cb.cb_content *> - cleanup + cleanup *> + tell ['ABC'.Rtn] *> + modify (removeFromReturn $ length cleanup`) where - cleanup = case cb.cb_init of - [] -> tell [] - _ -> comment "Cleanup" *> tell - [ 'ABC'.Update_a 0 locals + cleanup` = case cb.cb_init of + [] -> [] + _ -> [ 'ABC'.Update_a 0 locals , 'ABC'.Pop_a locals ] locals = length cb.cb_init |