aboutsummaryrefslogtreecommitdiff
path: root/Sil/Compile.icl
diff options
context:
space:
mode:
authorCamil Staps2017-07-27 13:05:23 +0200
committerCamil Staps2017-07-27 13:05:39 +0200
commitea4794ccdc9d0d8709ba22e43494e392b48be768 (patch)
tree26cdfda5d554beeecb08983f3d4d38219a779f6c /Sil/Compile.icl
parentAdd test file for #10 (lazy logical operators) (diff)
Resolve #4: mandatory initial values for basic locals
Diffstat (limited to 'Sil/Compile.icl')
-rw-r--r--Sil/Compile.icl44
1 files changed, 26 insertions, 18 deletions
diff --git a/Sil/Compile.icl b/Sil/Compile.icl
index 9bfd4f5..254cc67 100644
--- a/Sil/Compile.icl
+++ b/Sil/Compile.icl
@@ -28,13 +28,14 @@ import Sil.Util.Printer
instance toString CompileError
where
- toString (UndefinedName n) = "Undefined name '" <+ n <+ "'."
- toString VariableLabel = "Variable stored at label."
- toString FunctionOnStack = "Function stored on the stack."
- toString (TypeError err e) = "Type error in '" <+ e <+ "': " <+ err
- toString (CouldNotDeduceType e) = "Could not deduce type of '" <+ e <+ "'."
- toString (TypeMisMatch t e) = "Type mismatch: expected " <+ t <+ " for '" <+ e <+ "'."
- toString UnknownError = "Unknown error."
+ toString (UndefinedName n) = "Undefined name '" <+ n <+ "'."
+ toString VariableLabel = "Variable stored at label."
+ toString FunctionOnStack = "Function stored on the stack."
+ toString (TypeError err e) = "Type error in '" <+ e <+ "': " <+ err
+ toString (CouldNotDeduceType e) = "Could not deduce type of '" <+ e <+ "'."
+ toString (TypeMisMatch t e) = "Type mismatch: expected " <+ t <+ " for '" <+ e <+ "'."
+ toString (BasicInitWithoutValue n) = "Basic value '" <+ n <+ "' must have an initial value."
+ toString UnknownError = "Unknown error."
error :: CompileError -> RWST r w s (MaybeError CompileError) a
error e = RWST \_ _ -> Error e
@@ -164,8 +165,8 @@ getTypeResolver = gets typeresolvers >>= \trs -> pure $ \n ->
[t:_] -> Just t
[] -> Nothing
-reserveVar :: Bool (Name, Type) -> Gen Address
-reserveVar canBeOnBStack (n,t) = gets stackoffsets >>= put
+reserveVar :: (Name, Type) -> Gen Address
+reserveVar (n,t) = gets stackoffsets >>= put
where
put :: (Int, Int) -> Gen Address
put (aso, bso) =
@@ -173,10 +174,9 @@ where
comment ("Reserved " <+ addr <+ " for " <+ n) $>
addr
where
- (so`, addr) = case (canBeOnBStack, typeSize t) of
- (False, _) -> ((aso+1, bso), AAddr $ aso+1)
- (True, {bsize=0}) -> ((aso+1, bso), AAddr $ aso+1)
- (True, {btypes}) -> ((aso, bso + length btypes), BAddr $ bso+1)
+ (so`, addr) = case typeSize t of
+ {asize,bsize=0} -> ((aso + asize, bso), AAddr $ aso + asize)
+ {asize=0,bsize} -> ((aso, bso + bsize), BAddr $ bso + bsize)
findVar :: Name -> Gen Address
findVar n = gets stackoffsets >>= \(aso, bso) ->
@@ -253,7 +253,7 @@ where
, 'ABC'.Label $ toLabel f.f_name
] *>
tell (repeatn retSize.asize 'ABC'.Create) *> growStack {retSize & bsize=0} *>
- mapM_ (reserveVar True) [(a.arg_name, a.arg_type) \\ a <- f.f_args] *>
+ mapM_ reserveVar [(a.arg_name, a.arg_type) \\ a <- f.f_args] *>
newReturn cleanup` *>
pushTypeResolver typeresolver *>
setReturnType f.f_type *>
@@ -303,7 +303,7 @@ where
gen cb =
storeStackOffsets *>
gets stackoffsets >>= \so ->
- mapM_ (reserveVar False) [(i.init_name, i.init_type) \\ i <- cb.cb_init] *>
+ mapM_ reserveVar [(i.init_name, i.init_type) \\ i <- cb.cb_init] *>
mapM_ gen cb.cb_init *>
addToReturn cleanup` *>
pushTypeResolver typeresolver *>
@@ -315,13 +315,21 @@ where
where
cleanup` = case cb.cb_init of
[] -> []
- _ -> [ 'ABC'.Pop_a locals ]
- locals = length cb.cb_init
+ _ -> [ 'ABC'.Pop_a locals.asize
+ , 'ABC'.Pop_b locals.bsize
+ ]
+ locals = foldr (+~) zero [typeSize i.init_type \\ i <- cb.cb_init]
typeresolver :: Name -> Maybe (MaybeError TypeError Type)
typeresolver n = listToMaybe [Ok i.init_type \\ i <- cb.cb_init | i.init_name == n]
-instance gen Initialisation where gen init = tell ['ABC'.Create]
+instance gen Initialisation
+where
+ gen init = case typeSize init.init_type of
+ s=:{bsize=0} -> tell $ repeatn s.asize 'ABC'.Create
+ s=:{asize=0} -> case init.init_value of
+ Nothing -> error $ BasicInitWithoutValue init.init_name
+ Just v -> gen v *> shrinkStack s
instance gen Statement
where