|
|
/*
module owner: Ronny Wichers Schreur
*/
implementation module backendpreprocess
// assign sequence numbers to all variables in the syntax tree
import checksupport
import Heap
import backendsupport
// import RWSDebug
backEndPreprocess :: !Ident ![Index] !IclModule !*VarHeap -> *VarHeap
backEndPreprocess aliasDummyId functionIndices iclModule varHeap
= preprocess aliasDummyId
[iclModule.icl_functions.[i] \\ i <- functionIndices] varHeap
class preprocess a :: !Ident a -> Preprocessor
:: Preprocessor
:== *PreprocessState -> *PreprocessState
:: PreprocessState
:== VarHeap
instance preprocess {#a} | preprocess a & Array {#} a where
preprocess aliasDummyId array
= foldStateA (preprocess aliasDummyId) array
instance preprocess [a] | preprocess a where
preprocess aliasDummyId list
= foldState (preprocess aliasDummyId) list
// +++ this assigns sequence numbers per function, should be per alternative and move to backendconvert
instance preprocess FunDef where
preprocess aliasDummyId funDef
= fromSequencerToPreprocessor aliasDummyId (sequence funDef.fun_body)
class sequence a :: a -> Sequencer
:: Sequencer
:== *SequenceState -> *SequenceState
:: SequenceState
= {ss_sequenceNumber :: !Int, ss_varHeap :: .VarHeap, ss_aliasDummyId :: !Ident}
toSequenceState aliasDummyId varHeap
:== {ss_sequenceNumber = 0, ss_varHeap = varHeap, ss_aliasDummyId = aliasDummyId}
fromSequenceState sequenceState
:== sequenceState.ss_varHeap
fromSequencerToPreprocessor aliasDummyId sequencer
:== toSequenceState aliasDummyId
o` sequencer
o` fromSequenceState
assignSequenceNumber :: VarInfoPtr *SequenceState -> *SequenceState
assignSequenceNumber varInfoPtr sequenceState
# (varInfo, ss_varHeap) = readPtr varInfoPtr sequenceState.ss_varHeap
| alreadySequenced varInfo
= sequenceState
// otherwise
= { sequenceState
& ss_varHeap = writePtr varInfoPtr (VI_SequenceNumber sequenceState.ss_sequenceNumber) sequenceState.ss_varHeap
, ss_sequenceNumber = sequenceState.ss_sequenceNumber + 1
}
where
alreadySequenced :: VarInfo -> Bool
alreadySequenced (VI_SequenceNumber _)
= True
alreadySequenced (VI_AliasSequenceNumber _)
= True
alreadySequenced _
= False
instance sequence [a] | sequence a where
sequence list
= foldState sequence list
instance sequence (Optional a) | sequence a where
sequence (Yes x)
= sequence x
sequence No
= identity
// +++ this assigns sequence numbers per function, should be per alternative and moved to backendconvert
instance sequence FunctionBody where
sequence (TransformedBody transformedBody)
= sequence transformedBody
sequence body
= abort "preprocess (FunctionBody): unknown body"// <<- body
// case test ...
instance sequence TransformedBody where
sequence body
= sequence body.tb_args
o` sequence body.tb_rhs
// ... case test
instance sequence FreeVar where
sequence freeVar
= sequence freeVar.fv_info_ptr
instance sequence Expression where
sequence (Let {let_strict_binds, let_lazy_binds, let_expr})
= sequence let_strict_binds
o` sequence let_lazy_binds
o` sequence let_expr
sequence (Conditional {if_cond, if_then, if_else})
= sequence if_cond
o` sequence if_then
o` sequence if_else
sequence (App {app_args})
= sequence app_args
sequence (f @ arg)
= sequence f
o` sequence arg
sequence (Selection _ exp selections)
= sequence exp
o` sequence selections
sequence (AnyCodeExpr _ outParams _)
= foldState (\{bind_dst}->sequence bind_dst) outParams
sequence (Case caseExpr)
= sequence caseExpr
sequence _
= identity
instance sequence Case where
sequence {case_expr, case_guards, case_default}
= sequence case_expr
o` sequence case_guards
o` sequence case_default
instance sequence CasePatterns where
sequence (AlgebraicPatterns _ patterns)
= sequence patterns
sequence (BasicPatterns _ patterns)
= sequence patterns
sequence (OverloadedListPatterns _ decons_expr patterns)
= sequence patterns
instance sequence AlgebraicPattern where
sequence {ap_vars, ap_expr}
= sequence ap_vars
o` sequence ap_expr
instance sequence BasicPattern where
sequence {bp_expr}
= sequence bp_expr
instance sequence Selection where
sequence (RecordSelection _ _)
= identity
sequence (ArraySelection _ _ index)
= sequence index
sequence (DictionarySelection dictionaryVar dictionarySelections _ index)
= sequence index
instance sequence LetBind where
sequence {lb_src=App app , lb_dst}
= sequence` app lb_dst
where
sequence` {app_symb, app_args} lb_dst sequenceState=:{ss_aliasDummyId}
| not (isNilPtr app_symb.symb_ident.id_info) // nilPtr's are generated for Case's with case_ident=No in convertcases
&& app_symb.symb_ident==ss_aliasDummyId
// the compiled source was a strict alias like "#! x = y"
= case hd app_args of
Var bound_var=:{var_info_ptr}
# sequenceState = assignSequenceNumber var_info_ptr sequenceState
(vi, ss_varHeap) = readPtr var_info_ptr sequenceState.ss_varHeap
non_alias_bound_var = case vi of
VI_SequenceNumber _ -> bound_var
VI_AliasSequenceNumber alias_bound_var-> alias_bound_var
ss_varHeap = writePtr lb_dst.fv_info_ptr (VI_AliasSequenceNumber non_alias_bound_var) ss_varHeap
-> { sequenceState & ss_varHeap = ss_varHeap }
_
-> sequence lb_dst sequenceState
= sequence lb_dst sequenceState
sequence bind
= sequence bind.lb_dst
instance sequence (Ptr VarInfo) where
sequence varInfoPtr
= assignSequenceNumber varInfoPtr
|