aboutsummaryrefslogtreecommitdiff
path: root/backend/backendpreprocess.icl
blob: 85aba8cc472b3631c7368698a5710a740e65dd6d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
/*
	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