aboutsummaryrefslogtreecommitdiff
path: root/Sil
diff options
context:
space:
mode:
Diffstat (limited to 'Sil')
-rw-r--r--Sil/Compile.icl21
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