diff options
Diffstat (limited to 'Sil/Compile.icl')
-rw-r--r-- | Sil/Compile.icl | 37 |
1 files changed, 28 insertions, 9 deletions
diff --git a/Sil/Compile.icl b/Sil/Compile.icl index 9404b1c..0d5a3f2 100644 --- a/Sil/Compile.icl +++ b/Sil/Compile.icl @@ -98,6 +98,7 @@ where , returns :: ['ABC'.Assembler] , returnType :: Type , stackoffsets :: (Int, Int) // A and B stack + , globalsize :: (Int, Int) , storedoffsets :: [(Int, Int)] , typeresolvers :: [TypeResolver] } @@ -111,6 +112,7 @@ where , returns = [] , returnType = TVoid , stackoffsets = (0, 0) + , globalsize = (0, 0) , storedoffsets = [] , typeresolvers = [] } @@ -133,6 +135,9 @@ returnType cs = cs.returnType stackoffsets :: CompileState -> (Int, Int) stackoffsets cs = cs.stackoffsets +globalsize :: CompileState -> (Int, Int) +globalsize cs = cs.globalsize + typeresolvers :: CompileState -> [TypeResolver] typeresolvers cs = cs.typeresolvers @@ -259,14 +264,21 @@ instance gen Program where gen p = tell [ 'ABC'.Annotation $ 'ABC'.RawAnnot ["comp", "920", "01011101001"] - , 'ABC'.Annotation $ 'ABC'.RawAnnot ["start", "__sil_boot"] + , 'ABC'.Annotation $ 'ABC'.RawAnnot ["start", "_sil_boot"] , 'ABC'.Annotation $ 'ABC'.RawAnnot ["endinfo"] , 'ABC'.Annotation $ 'ABC'.RawAnnot ["module", "m_sil_compiled", "\"sil_compiled\""] - , 'ABC'.Label "__sil_boot" + , 'ABC'.Label "_sil_boot" , 'ABC'.Create - , 'ABC'.Fill "_" 0 (toLabel "main") 0 + , 'ABC'.Fill "_" 0 "_sil_boot2" 0 , 'ABC'.Jmp "_driver" - ] *> + , 'ABC'.Annotation $ 'ABC'.OAnnot 0 [] + , 'ABC'.Label "_sil_boot2" ] *> + let gsize = foldr (+~) zero [typeSize i.init_type \\ i <- p.p_globals] in + modify (\cs -> {cs & globalsize=(gsize.asize, gsize.bsize)}) *> + shrinkStack gsize *> + mapM_ reserveVar [(i.init_name, i.init_type) \\ i <- p.p_globals] *> + mapM_ gen p.p_globals *> + tell [ 'ABC'.Jmp (toLabel "main") ] *> pushTypeResolver typeresolver *> mapM_ addFunction p.p_funs *> mapM_ gen p.p_funs *> @@ -274,13 +286,18 @@ where where typeresolver :: Name -> Maybe (MaybeError Error Type) typeresolver n = case [f \\ f <- p.p_funs | f.f_name == n] of - [] -> Nothing - [f:_] -> type zero f + [f:_] -> type typeresolver f + [] -> case [g.init_type \\ g <- p.p_globals | g.init_name == n] of + [t:_] -> Just $ Ok t + [] -> Nothing instance gen Function where gen f = - tell [ 'ABC'.Annotation $ toOAnnot` [typeSize a.arg_type \\ a <- f.f_args] + gets globalsize >>= \(gas,gbs) -> + tell [ 'ABC'.Annotation $ toOAnnot` + [if (f.f_name == "main") {zero & asize=gas,bsize=gbs} zero + :[typeSize a.arg_type \\ a <- f.f_args]] , 'ABC'.Label $ toLabel f.f_name ] *> tell (repeatn retSize.asize 'ABC'.Create) *> @@ -371,10 +388,12 @@ where instance gen Initialisation where gen init = case typeSize init.init_type of - s=:{bsize=0} -> tell $ repeatn s.asize 'ABC'.Create + s=:{bsize=0} -> case init.init_value of + Nothing -> tell $ repeatn s.asize 'ABC'.Create + Just v -> shrinkStack s *> gen v s=:{asize=0} -> case init.init_value of Nothing -> error $ C_BasicInitWithoutValue init.init_name - Just v -> checkType init.init_type v *> gen v *> shrinkStack s + Just v -> checkType init.init_type v *> shrinkStack s *> gen v instance gen Statement where |