transform.icl 133 KB
Newer Older
Ronny Wichers Schreur's avatar
Ronny Wichers Schreur committed
1
2
implementation module transform

3
import syntax, utilities, mergecases
Ronny Wichers Schreur's avatar
Ronny Wichers Schreur committed
4
5
6

::	LiftState =
	{	ls_var_heap		:: !.VarHeap
Sjaak Smetsers's avatar
Sjaak Smetsers committed
7
	,	ls_x 			:: !.LiftStateX
Ronny Wichers Schreur's avatar
Ronny Wichers Schreur committed
8
9
	,	ls_expr_heap	:: !.ExpressionHeap
	}
10

11
12
::	LiftStateX = {
		x_fun_defs :: !.{#FunDef},
13
		x_macro_defs :: !.{#.{#FunDef}},
14
15
16
		x_main_dcl_module_n :: !Int
	}

Ronny Wichers Schreur's avatar
Ronny Wichers Schreur committed
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class lift a :: !a !*LiftState -> (!a, !*LiftState)

instance lift [a] | lift a
where
	lift l ls = mapSt lift l ls

instance lift (a,b) | lift a & lift b
where
	lift t ls = app2St (lift,lift) t ls

instance lift (Optional a) | lift a
where
	lift (Yes x) ls
		# (x, ls) = lift x ls
		= (Yes x, ls)
	lift no ls
		= (no, ls)
	
35
36
37
38
39
40
instance lift CheckedAlternative
where
	lift ca=:{ca_rhs} ls
		# (ca_rhs, ls) = lift ca_rhs ls
		= ({ ca & ca_rhs = ca_rhs }, ls)
	
Ronny Wichers Schreur's avatar
Ronny Wichers Schreur committed
41
42
instance lift Expression
where
43
	lift (FreeVar {fv_ident,fv_info_ptr}) ls=:{ls_var_heap}
Sjaak Smetsers's avatar
Sjaak Smetsers committed
44
45
		# (var_info, ls_var_heap) = readPtr fv_info_ptr ls_var_heap
		  ls = { ls & ls_var_heap = ls_var_heap }
Ronny Wichers Schreur's avatar
Ronny Wichers Schreur committed
46
47
48
		= case var_info of
			 VI_LiftedVariable var_info_ptr
			 	# (var_expr_ptr, ls_expr_heap) = newPtr EI_Empty ls.ls_expr_heap
49
			 	-> (Var { var_ident = fv_ident, var_info_ptr = var_info_ptr, var_expr_ptr = var_expr_ptr }, { ls & ls_expr_heap = ls_expr_heap})
Ronny Wichers Schreur's avatar
Ronny Wichers Schreur committed
50
51
			 _
			 	# (var_expr_ptr, ls_expr_heap) = newPtr EI_Empty ls.ls_expr_heap
52
			 	-> (Var { var_ident = fv_ident, var_info_ptr = fv_info_ptr, var_expr_ptr = var_expr_ptr }, { ls & ls_expr_heap = ls_expr_heap})
Ronny Wichers Schreur's avatar
Ronny Wichers Schreur committed
53
54
55
56
57
58
	lift (App app) ls
		# (app, ls) = lift app ls
		= (App app, ls)
	lift (expr @ exprs) ls
		# ((expr,exprs), ls) = lift (expr,exprs) ls
		= (expr @ exprs, ls)
Sjaak Smetsers's avatar
Sjaak Smetsers committed
59
60
61
62
63
	lift (Let lad=:{let_strict_binds, let_lazy_binds, let_expr}) ls
		# (let_strict_binds, ls) = lift let_strict_binds ls
		  (let_lazy_binds, ls) = lift let_lazy_binds ls
		  (let_expr, ls) = lift let_expr ls
		= (Let {lad & let_strict_binds = let_strict_binds, let_lazy_binds = let_lazy_binds, let_expr = let_expr}, ls)
Ronny Wichers Schreur's avatar
Ronny Wichers Schreur committed
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
	lift (Case case_expr) ls
		# (case_expr, ls) = lift case_expr ls
		= (Case case_expr, ls)
	lift (Selection is_unique expr selectors) ls
		# (selectors, ls) = lift selectors ls
		  (expr, ls) = lift expr ls
		= (Selection is_unique expr selectors, ls)
	lift (Update expr1 selectors expr2) ls
		# (selectors, ls) = lift selectors ls
		  (expr1, ls) = lift expr1 ls
		  (expr2, ls) = lift expr2 ls
		= (Update expr1 selectors expr2, ls)
	lift (RecordUpdate cons_symbol expression expressions) ls
		# (expression, ls) = lift expression ls
		  (expressions, ls) = lift expressions ls
		= (RecordUpdate cons_symbol expression expressions, ls)
	lift (TupleSelect symbol argn_nr expr) ls
		# (expr, ls) = lift expr ls
		= (TupleSelect symbol argn_nr expr, ls)
83
	lift (MatchExpr cons_ident expr) ls
Ronny Wichers Schreur's avatar
Ronny Wichers Schreur committed
84
		# (expr, ls) = lift expr ls
85
		= (MatchExpr cons_ident expr, ls)
86
87
88
	lift (DynamicExpr expr) ls
		# (expr, ls) = lift expr ls
		= (DynamicExpr expr, ls)
89
90
91
	lift (IsConstructor expr cons_symbol cons_arity global_type_index case_ident position) ls
		# (expr, ls) = lift expr ls
		= (IsConstructor expr cons_symbol cons_arity global_type_index case_ident position, ls)
92
93
94
	lift (TypeSignature type_function expr) ls
		# (expr, ls) = lift expr ls
		= (TypeSignature type_function expr, ls)
Ronny Wichers Schreur's avatar
Ronny Wichers Schreur committed
95
96
97
98
99
100
101
102
103
104
105
106
107
	lift expr ls
		= (expr, ls)

instance lift Selection
where
	lift (ArraySelection array_select expr_ptr index_expr) ls
		# (index_expr, ls) = lift index_expr ls
		= (ArraySelection array_select expr_ptr index_expr, ls)
	lift record_selection ls
		= (record_selection, ls)

instance lift App
where
108
	lift app=:{app_symb = app_symbol=:{symb_kind = SK_Function {glob_object,glob_module}}, app_args} ls
109
		| glob_module == ls.ls_x.LiftStateX.x_main_dcl_module_n
110
			# (fun_def,ls) = ls!ls_x.x_fun_defs.[glob_object]
111
112
			= lift_function_app app fun_def.fun_info.fi_free_vars ls
			# (app_args, ls) = lift app_args ls
113
			= ({ app & app_args = app_args }, ls)
114
	lift app=:{app_symb = {symb_kind = SK_LocalMacroFunction glob_object},app_args} ls
115
		# (fun_def,ls) = ls!ls_x.x_fun_defs.[glob_object]
116
117
		= lift_function_app app fun_def.fun_info.fi_free_vars ls
	lift app=:{app_symb = {symb_kind = SK_LocalDclMacroFunction {glob_object,glob_module}}} ls
118
		# (fun_def,ls) = ls!ls_x.x_macro_defs.[glob_module,glob_object]
119
		= lift_function_app app fun_def.fun_info.fi_free_vars ls
Ronny Wichers Schreur's avatar
Ronny Wichers Schreur committed
120
121
122
123
	lift app=:{app_args} ls
		# (app_args, ls) = lift app_args ls
		= ({ app & app_args = app_args }, ls)

124
lift_function_app app=:{app_symb=app_symbol,app_args} [] ls
125
126
	# (app_args, ls) = lift app_args ls
	= ({ app & app_args = app_args }, ls)
127
lift_function_app app=:{app_args} fi_free_vars ls
128
129
	# (app_args, ls) = lift app_args ls
	# (app_args, ls_var_heap, ls_expr_heap) = add_free_variables_in_app fi_free_vars app_args ls.ls_var_heap ls.ls_expr_heap
130
	# app = { app & app_args = app_args }
131
132
133
134
135
	= (app,	{ ls & ls_var_heap = ls_var_heap, ls_expr_heap = ls_expr_heap })
where
	add_free_variables_in_app :: ![FreeVar] ![Expression] !*VarHeap !*ExpressionHeap -> (![Expression],!*VarHeap,!*ExpressionHeap)
	add_free_variables_in_app [] app_args var_heap expr_heap
		= (app_args, var_heap, expr_heap)
136
	add_free_variables_in_app [{fv_ident, fv_info_ptr} : free_vars] app_args var_heap expr_heap
137
		# (var_info,var_heap) = readPtr fv_info_ptr var_heap
138
139
140
		= case var_info of
			VI_LiftedVariable var_info_ptr
			 	# (var_expr_ptr, expr_heap) = newPtr EI_Empty expr_heap
141
				-> add_free_variables_in_app free_vars [Var { var_ident = fv_ident, var_info_ptr = var_info_ptr, var_expr_ptr = var_expr_ptr } : app_args]
142
143
144
						var_heap expr_heap
			_
			 	# (var_expr_ptr, expr_heap) = newPtr EI_Empty expr_heap
145
				-> add_free_variables_in_app free_vars [Var { var_ident = fv_ident, var_info_ptr = fv_info_ptr, var_expr_ptr = var_expr_ptr } : app_args]
146
						var_heap expr_heap
147

148
149
150
151
152
153
instance lift LetBind
where
	lift bind=:{lb_src} ls
		# (lb_src, ls) = lift lb_src ls
		= ({ bind & lb_src = lb_src }, ls)

Ronny Wichers Schreur's avatar
Ronny Wichers Schreur committed
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
instance lift (Bind a b) | lift a
where
	lift bind=:{bind_src} ls
		# (bind_src, ls) = lift bind_src ls
		= ({ bind & bind_src = bind_src }, ls)

instance lift Case
where
	lift kees=:{ case_expr,case_guards,case_default } ls
		# ((case_expr,(case_guards,case_default)), ls) = lift (case_expr,(case_guards,case_default)) ls
		= ({ kees & case_expr = case_expr,case_guards = case_guards, case_default = case_default }, ls)

instance lift CasePatterns
where
	lift (AlgebraicPatterns type patterns) ls
		# (patterns, ls) = lift patterns ls
		= (AlgebraicPatterns type patterns, ls)
	lift (BasicPatterns type patterns) ls
		# (patterns, ls) = lift patterns ls
		= (BasicPatterns type patterns, ls)
174
175
176
177
	lift (OverloadedListPatterns type decons_expr patterns) ls
		# (patterns, ls) = lift patterns ls
		# (decons_expr, ls) = lift decons_expr ls
		= (OverloadedListPatterns type decons_expr patterns, ls)
John van Groningen's avatar
John van Groningen committed
178
179
180
	lift (NewTypePatterns type patterns) ls
		# (patterns, ls) = lift patterns ls
		= (NewTypePatterns type patterns, ls)
Ronny Wichers Schreur's avatar
Ronny Wichers Schreur committed
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
	lift (DynamicPatterns patterns) ls
		# (patterns, ls) = lift patterns ls
		= (DynamicPatterns patterns, ls)

instance lift AlgebraicPattern
where
	lift pattern=:{ap_expr} ls
		# (ap_expr, ls) = lift ap_expr ls
		= ({ pattern & ap_expr = ap_expr }, ls)

instance lift BasicPattern
where
	lift pattern=:{bp_expr} ls
		# (bp_expr, ls) = lift bp_expr ls
		= ({ pattern & bp_expr = bp_expr }, ls)

instance lift DynamicPattern
where
	lift pattern=:{dp_rhs} ls
		# (dp_rhs, ls) = lift dp_rhs ls
		= ({ pattern & dp_rhs = dp_rhs }, ls)

203
204
205
206
207
208
instance lift DynamicExpr
where
	lift dyn=:{dyn_expr} ls
		# (dyn_expr, ls) = lift dyn_expr ls
		= ({ dyn & dyn_expr = dyn_expr}, ls)

209
liftFunctions :: [FunctionOrMacroIndex] Int Int *{#FunDef} *{#*{#FunDef}} *VarHeap *ExpressionHeap -> .LiftState;
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
liftFunctions group group_index main_dcl_module_n fun_defs macro_defs var_heap expr_heap
	# (contains_free_vars, lifted_function_called, fun_defs,macro_defs)
			= foldSt (add_free_vars_of_non_recursive_calls_to_function group_index) group (False, False, fun_defs,macro_defs)
	| contains_free_vars
		# (fun_defs,macro_defs) = iterateSt (add_free_vars_of_recursive_calls_to_functions group_index group) (fun_defs,macro_defs)
		= lift_functions group {ls_x={x_fun_defs=fun_defs,x_macro_defs=macro_defs,x_main_dcl_module_n=main_dcl_module_n},ls_var_heap=var_heap,ls_expr_heap=expr_heap}
	| lifted_function_called
		= lift_functions group {ls_x={x_fun_defs=fun_defs,x_macro_defs=macro_defs,x_main_dcl_module_n=main_dcl_module_n},ls_var_heap=var_heap,ls_expr_heap=expr_heap}
		= {ls_x={x_fun_defs=fun_defs,x_macro_defs=macro_defs,x_main_dcl_module_n=main_dcl_module_n},ls_var_heap=var_heap, ls_expr_heap=expr_heap}
where
	add_free_vars_of_non_recursive_calls_to_function group_index (FunctionOrIclMacroIndex fun) (contains_free_vars, lifted_function_called, fun_defs,macro_defs)
		# (fun_def=:{fun_info}, fun_defs) = fun_defs![fun]
		  { fi_free_vars,fi_def_level,fi_calls } = fun_info
		  (lifted_function_called, fi_free_vars, fun_defs,macro_defs)
				= add_free_vars_of_non_recursive_calls fi_def_level group_index fi_calls lifted_function_called fi_free_vars fun_defs macro_defs
		= (contains_free_vars || not (isEmpty fi_free_vars), lifted_function_called, 
			{ fun_defs & [fun] = { fun_def & fun_info = { fun_info & fi_free_vars = fi_free_vars }}},macro_defs)
	add_free_vars_of_non_recursive_calls_to_function group_index (DclMacroIndex macro_module_index macro_index) (contains_free_vars, lifted_function_called, fun_defs,macro_defs)
		# (fun_def=:{fun_info}, macro_defs) = macro_defs![macro_module_index,macro_index]
		  { fi_free_vars,fi_def_level,fi_calls } = fun_info
		  (lifted_function_called, fi_free_vars, fun_defs,macro_defs)
		  		= add_free_vars_of_non_recursive_calls fi_def_level group_index fi_calls lifted_function_called fi_free_vars fun_defs macro_defs
		= (contains_free_vars || not (isEmpty fi_free_vars), lifted_function_called, 
			fun_defs,{ macro_defs & [macro_module_index,macro_index] = { fun_def & fun_info = { fun_info & fi_free_vars = fi_free_vars }}})

	add_free_vars_of_non_recursive_calls fi_def_level group_index fi_calls lifted_function_called fi_free_vars fun_defs macro_defs
		= foldSt (add_free_vars_of_non_recursive_call fi_def_level group_index) fi_calls (lifted_function_called, fi_free_vars, fun_defs,macro_defs)
	where
		add_free_vars_of_non_recursive_call fun_def_level group_index (FunCall fc_index _) (lifted_function_called, free_vars, fun_defs,macro_defs)
			# ({fun_info = {fi_free_vars,fi_group_index}}, fun_defs) = fun_defs![fc_index]
			| (if (fi_group_index>=NoIndex) (fi_group_index==group_index) (-2-fi_group_index==group_index)) || (isEmpty fi_free_vars)
				= (lifted_function_called, free_vars, fun_defs,macro_defs)
				# (free_vars_added, free_vars) = add_free_variables fun_def_level fi_free_vars (False, free_vars)
				= (True, free_vars, fun_defs,macro_defs)
		add_free_vars_of_non_recursive_call fun_def_level group_index (MacroCall macro_module_index fc_index _) (lifted_function_called, free_vars, fun_defs,macro_defs)
			# ({fun_info = {fi_free_vars,fi_group_index}}, macro_defs) = macro_defs![macro_module_index,fc_index]
			| (if (fi_group_index>=NoIndex) (fi_group_index==group_index) (-2-fi_group_index==group_index)) || (isEmpty fi_free_vars)
				= (lifted_function_called, free_vars, fun_defs,macro_defs)
				# (free_vars_added, free_vars) = add_free_variables fun_def_level fi_free_vars (False, free_vars)
				= (True, free_vars, fun_defs,macro_defs)
250
251
		add_free_vars_of_non_recursive_call fun_def_level group_index (DclFunCall _ _) (lifted_function_called, free_vars, fun_defs,macro_defs)
			= (lifted_function_called, free_vars, fun_defs,macro_defs)
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282

	add_free_vars_of_recursive_calls_to_functions group_index group (fun_defs,macro_defs)
		= foldSt (add_free_vars_of_recursive_calls_to_function group_index) group (False, (fun_defs,macro_defs))

	add_free_vars_of_recursive_calls_to_function group_index (FunctionOrIclMacroIndex fun) (free_vars_added, (fun_defs,macro_defs))
		# (fun_def=:{fun_info}, fun_defs) = fun_defs![fun]
		  { fi_free_vars,fi_def_level,fi_calls } = fun_info
		  (free_vars_added, fi_free_vars, fun_defs,macro_defs)
				= foldSt (add_free_vars_of_recursive_call fi_def_level group_index) fi_calls (free_vars_added, fi_free_vars, fun_defs,macro_defs)
		  fun_defs = { fun_defs & [fun] = { fun_def & fun_info = { fun_info & fi_free_vars = fi_free_vars }}}
		= (free_vars_added, (fun_defs,macro_defs))
	add_free_vars_of_recursive_calls_to_function group_index (DclMacroIndex module_index fun) (free_vars_added, (fun_defs,macro_defs))
		# (fun_def=:{fun_info}, macro_defs) = macro_defs![module_index,fun]
		  { fi_free_vars,fi_def_level,fi_calls } = fun_info
		  (free_vars_added, fi_free_vars, fun_defs,macro_defs)
				= foldSt (add_free_vars_of_recursive_call fi_def_level group_index) fi_calls (free_vars_added, fi_free_vars, fun_defs,macro_defs)
		  macro_defs = { macro_defs & [module_index,fun] = { fun_def & fun_info = { fun_info & fi_free_vars = fi_free_vars }}}
		= (free_vars_added, (fun_defs,macro_defs))

	add_free_vars_of_recursive_call fun_def_level group_index (FunCall fc_index _) (free_vars_added, free_vars, fun_defs,macro_defs)
		# ({fun_info = {fi_free_vars,fi_group_index}}, fun_defs) = fun_defs![fc_index]
		| if (fi_group_index>=NoIndex) (fi_group_index==group_index) (-2-fi_group_index==group_index)
			# (free_vars_added, free_vars) = add_free_variables fun_def_level fi_free_vars (free_vars_added, free_vars)
			= (free_vars_added, free_vars, fun_defs,macro_defs)
			= (free_vars_added, free_vars, fun_defs,macro_defs)
	add_free_vars_of_recursive_call fun_def_level group_index (MacroCall module_index fc_index _) (free_vars_added, free_vars, fun_defs,macro_defs)
		# ({fun_info = {fi_free_vars,fi_group_index}}, macro_defs) = macro_defs![module_index,fc_index]
		| if (fi_group_index>=NoIndex) (fi_group_index==group_index) (-2-fi_group_index==group_index)
			# (free_vars_added, free_vars) = add_free_variables fun_def_level fi_free_vars (free_vars_added, free_vars)
			= (free_vars_added, free_vars, fun_defs,macro_defs)
			= (free_vars_added, free_vars, fun_defs,macro_defs)
283
284
	add_free_vars_of_recursive_call fun_def_level group_index (DclFunCall _ _) (free_vars_added, free_vars, fun_defs,macro_defs)
		= (free_vars_added, free_vars, fun_defs,macro_defs)
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328

	add_free_variables fun_level new_vars (free_vars_added, free_vars)
		= add_free_global_variables (skip_local_variables fun_level new_vars) (free_vars_added, free_vars)
	where
		skip_local_variables level vars=:[{fv_def_level}:rest_vars]
			| fv_def_level > level
				= skip_local_variables level rest_vars
				= vars
		skip_local_variables _ []
			= []

		add_free_global_variables []  (free_vars_added, free_vars)
			= (free_vars_added, free_vars)
		add_free_global_variables free_vars (free_vars_added, [])
			= (True, free_vars)
		add_free_global_variables [var:vars] (free_vars_added, free_vars)
			# (free_var_added, free_vars) = newFreeVariable var free_vars
			= add_free_global_variables vars (free_var_added || free_vars_added, free_vars)

	lift_functions group lift_state
		= foldSt lift_function group lift_state
	where
		lift_function (FunctionOrIclMacroIndex fun) {ls_x=ls_x=:{x_fun_defs=fun_defs=:{[fun] = fun_def}}, ls_var_heap=var_heap, ls_expr_heap=expr_heap}
			# {fi_free_vars} = fun_def.fun_info
			  fun_lifted = length fi_free_vars
			  (PartitioningFunction {cb_args,cb_rhs} fun_number) = fun_def.fun_body
			  (cb_args, var_heap) = add_lifted_args fi_free_vars cb_args var_heap
			  (cb_rhs, {ls_x,ls_var_heap,ls_expr_heap}) = lift cb_rhs { ls_x={ls_x & x_fun_defs = fun_defs}, ls_var_heap = var_heap, ls_expr_heap = expr_heap }
			  ls_var_heap = remove_lifted_args fi_free_vars ls_var_heap
			  fun_defs = ls_x.x_fun_defs
			  fun_defs = { fun_defs & [fun] = { fun_def & fun_lifted = fun_lifted, fun_body = PartitioningFunction {cb_args = cb_args, cb_rhs = cb_rhs} fun_number}}
			= {ls_x={ls_x & x_fun_defs=fun_defs}, ls_var_heap=ls_var_heap, ls_expr_heap= ls_expr_heap}
		lift_function (DclMacroIndex module_index fun) {ls_x=ls_x=:{x_macro_defs=macro_defs=:{[module_index,fun] = fun_def}}, ls_var_heap=var_heap, ls_expr_heap=expr_heap}
			# {fi_free_vars} = fun_def.fun_info
			  fun_lifted = length fi_free_vars
			  (PartitioningFunction {cb_args,cb_rhs} fun_number) = fun_def.fun_body
			  (cb_args, var_heap) = add_lifted_args fi_free_vars cb_args var_heap
			  (cb_rhs, {ls_x,ls_var_heap,ls_expr_heap}) = lift cb_rhs { ls_x={ls_x & x_macro_defs = macro_defs}, ls_var_heap = var_heap, ls_expr_heap = expr_heap }
			  ls_var_heap = remove_lifted_args fi_free_vars ls_var_heap
			  macro_defs = ls_x.x_macro_defs
			  macro_defs = { macro_defs & [module_index].[fun] = { fun_def & fun_lifted = fun_lifted, fun_body = PartitioningFunction {cb_args = cb_args, cb_rhs = cb_rhs} fun_number}}
			= {ls_x={ls_x & x_macro_defs=macro_defs}, ls_var_heap=ls_var_heap, ls_expr_heap= ls_expr_heap}

		remove_lifted_args vars var_heap
329
			= foldl (\var_heap {fv_ident,fv_info_ptr} -> writePtr fv_info_ptr VI_Empty var_heap) var_heap vars
330
	
331
		add_lifted_args [lifted_arg=:{fv_ident,fv_info_ptr} : lifted_args] args var_heap
332
333
334
335
336
337
			# (new_info_ptr, var_heap) = newPtr VI_Empty var_heap
			  args = [{ lifted_arg & fv_info_ptr = new_info_ptr } : args ]
			= add_lifted_args lifted_args args (writePtr fv_info_ptr (VI_LiftedVariable new_info_ptr) var_heap)
		add_lifted_args [] args var_heap
			= (args, var_heap)

338
339
unfoldVariable :: !BoundVar !*UnfoldState -> (!Expression, !*UnfoldState)
unfoldVariable var=:{var_info_ptr} us
Sjaak Smetsers's avatar
Sjaak Smetsers committed
340
	# (var_info, us) = readVarInfo var_info_ptr us
341
	= case var_info of
Ronny Wichers Schreur's avatar
Ronny Wichers Schreur committed
342
343
		VI_Expression expr
			-> (expr, us)
344
		VI_Variable var_ident var_info_ptr
345
		 	# (var_expr_ptr, us_symbol_heap) = newPtr EI_Empty us.us_symbol_heap
346
			-> (Var {var_ident = var_ident, var_info_ptr = var_info_ptr, var_expr_ptr = var_expr_ptr}, { us & us_symbol_heap = us_symbol_heap})
Ronny Wichers Schreur's avatar
Ronny Wichers Schreur committed
347
348
		_
			-> (Var var, us)
349
350

readVarInfo var_info_ptr us
Sjaak Smetsers's avatar
Sjaak Smetsers committed
351
352
	# (var_info, us_var_heap) = readPtr var_info_ptr us.us_var_heap
	  us = { us & us_var_heap = us_var_heap }
353
354
355
356
	= case var_info of
		VI_Extended _ original	-> (original, us)
		_						-> (var_info, us)

357
::	CopiedLocalFunction = { old_function_n :: !FunctionOrMacroIndex, new_function_n :: !Int }
358
359
360
361
362
363
364
365
366
367
368

::	CopiedLocalFunctions = {
		copied_local_functions :: [CopiedLocalFunction],
		used_copied_local_functions :: [CopiedLocalFunction],
		new_copied_local_functions :: [CopiedLocalFunction],
		next_local_function_n :: !Int
	}

::	UnfoldState =
	{	us_var_heap				:: !.VarHeap
	,	us_symbol_heap			:: !.ExpressionHeap
369
	,	us_local_macro_functions :: !Optional CopiedLocalFunctions
370
371
	}

372
class unfold a :: !a !*UnfoldState -> (!a, !*UnfoldState)
373

Ronny Wichers Schreur's avatar
Ronny Wichers Schreur committed
374
375
instance unfold Expression
where
376
377
378
379
	unfold (Var var) us
		= unfoldVariable var us
	unfold (App app) us
		# (app, us) = unfold app us
Ronny Wichers Schreur's avatar
Ronny Wichers Schreur committed
380
		= (App app, us)
381
382
	unfold (expr @ exprs) us
		# ((expr,exprs), us) = unfold (expr,exprs) us
Ronny Wichers Schreur's avatar
Ronny Wichers Schreur committed
383
		= (expr @ exprs, us)
384
385
	unfold (Let lad) us
		# (lad, us) = unfold lad us
Ronny Wichers Schreur's avatar
Ronny Wichers Schreur committed
386
		= (Let lad, us)
387
388
	unfold (Case case_expr) us
		# (case_expr, us) = unfold case_expr us
Ronny Wichers Schreur's avatar
Ronny Wichers Schreur committed
389
		= (Case case_expr, us)
390
	unfold (Selection selector_kind expr selectors) us
391
		# ((expr, selectors), us) = unfold (expr, selectors) us
392
		= (Selection selector_kind expr selectors, us)
393
394
	unfold (Update expr1 selectors expr2) us
		# (((expr1, expr2), selectors), us) = unfold ((expr1, expr2), selectors) us
Ronny Wichers Schreur's avatar
Ronny Wichers Schreur committed
395
		= (Update expr1 selectors expr2, us)
396
397
	unfold (RecordUpdate cons_symbol expression expressions) us
		# ((expression, expressions), us) = unfold (expression, expressions) us
Ronny Wichers Schreur's avatar
Ronny Wichers Schreur committed
398
		= (RecordUpdate cons_symbol expression expressions, us)
399
400
	unfold (TupleSelect symbol argn_nr expr) us
		# (expr, us) = unfold expr us
Ronny Wichers Schreur's avatar
Ronny Wichers Schreur committed
401
		= (TupleSelect symbol argn_nr expr, us)
402
403
	unfold (MatchExpr cons_ident expr) us
		# (expr, us) = unfold expr us
404
		= (MatchExpr cons_ident expr, us)
405
406
407
	unfold (IsConstructor expr cons_symbol cons_arity global_type_index case_ident position) us
		# (expr, us) = unfold expr us
		= (IsConstructor expr cons_symbol cons_arity global_type_index case_ident position, us)
408
409
	unfold (DynamicExpr expr) us
		# (expr, us) = unfold expr us
Martin Wierich's avatar
Martin Wierich committed
410
		= (DynamicExpr expr, us)
411
412
	unfold (TypeSignature type_function expr) us
		# (expr, us) = unfold expr us
413
		= (TypeSignature type_function expr, us)
414
	unfold expr us
Ronny Wichers Schreur's avatar
Ronny Wichers Schreur committed
415
416
		= (expr, us)

Martin Wierich's avatar
Martin Wierich committed
417
418
instance unfold DynamicExpr
where
419
	unfold expr=:{dyn_expr, dyn_info_ptr} us=:{us_symbol_heap}
420
421
		# (dyn_info, us_symbol_heap) = readPtr dyn_info_ptr us_symbol_heap
		# (new_dyn_info_ptr, us_symbol_heap) = newPtr dyn_info us_symbol_heap
422
		# (dyn_expr, us) = unfold dyn_expr {us & us_symbol_heap=us_symbol_heap}
423
		= ({ expr & dyn_expr = dyn_expr, dyn_info_ptr = new_dyn_info_ptr }, us)
Martin Wierich's avatar
Martin Wierich committed
424

Ronny Wichers Schreur's avatar
Ronny Wichers Schreur committed
425
426
instance unfold Selection
where
427
	unfold (ArraySelection array_select expr_ptr index_expr) us=:{us_symbol_heap}
Sjaak Smetsers's avatar
Sjaak Smetsers committed
428
		# (new_ptr, us_symbol_heap) = newPtr EI_Empty us_symbol_heap
429
		  (index_expr, us) = unfold index_expr { us & us_symbol_heap = us_symbol_heap}
Sjaak Smetsers's avatar
Sjaak Smetsers committed
430
		= (ArraySelection array_select new_ptr index_expr, us)
431
	unfold (DictionarySelection var selectors expr_ptr index_expr) us=:{us_symbol_heap}
Sjaak Smetsers's avatar
Sjaak Smetsers committed
432
		# (new_ptr, us_symbol_heap) = newPtr EI_Empty us_symbol_heap
433
434
		  (index_expr, us) = unfold index_expr { us & us_symbol_heap = us_symbol_heap}
		  (var_expr, us) = unfoldVariable var us
Ronny Wichers Schreur's avatar
Ronny Wichers Schreur committed
435
436
437
		= case var_expr of 
			App {app_symb={symb_kind= SK_Constructor _ }, app_args}
				# [RecordSelection _ field_index:_] = selectors
438
439
				  (App { app_symb = {symb_ident, symb_kind = SK_Function array_select}}) =  app_args !! field_index
				-> (ArraySelection { array_select & glob_object = { ds_ident = symb_ident, ds_arity = 2, ds_index = array_select.glob_object}}
Sjaak Smetsers's avatar
Sjaak Smetsers committed
440
							new_ptr index_expr, us)
Ronny Wichers Schreur's avatar
Ronny Wichers Schreur committed
441
			Var var
Sjaak Smetsers's avatar
Sjaak Smetsers committed
442
				-> (DictionarySelection var selectors new_ptr index_expr, us)
443
	unfold record_selection us
444
		= (record_selection, us)
Ronny Wichers Schreur's avatar
Ronny Wichers Schreur committed
445
446
447

instance unfold FreeVar
where
448
	unfold fv=:{fv_info_ptr,fv_ident} us=:{us_var_heap}
Ronny Wichers Schreur's avatar
Ronny Wichers Schreur committed
449
		# (new_info_ptr, us_var_heap) = newPtr VI_Empty us_var_heap
450
		= ({ fv & fv_info_ptr = new_info_ptr }, { us & us_var_heap = writePtr fv_info_ptr (VI_Variable fv_ident new_info_ptr) us_var_heap })
451

Ronny Wichers Schreur's avatar
Ronny Wichers Schreur committed
452
453
instance unfold App
where
454
	unfold app=:{app_symb={symb_kind}, app_args, app_info_ptr} us
455
		= case symb_kind of
456
			SK_Function {glob_module,glob_object}
457
				-> unfold_function_app app us
458
			SK_IclMacro macro_index
459
				-> unfold_function_app app us
460
			SK_DclMacro {glob_module,glob_object}
461
				-> unfold_function_app app us
462
			SK_OverloadedFunction {glob_module,glob_object}
463
				-> unfold_function_app app us
Artem Alimarine's avatar
Artem Alimarine committed
464
			SK_Generic {glob_module,glob_object} kind
465
				-> unfold_function_app app us
466
			SK_LocalMacroFunction local_macro_function_n
467
468
469
				-> unfold_local_macro_function (FunctionOrIclMacroIndex local_macro_function_n)
			SK_LocalDclMacroFunction {glob_module,glob_object}
				-> unfold_local_macro_function (DclMacroIndex glob_module glob_object)
470
471
472
			SK_Constructor _
				| not (isNilPtr app_info_ptr)
					# (app_info, us_symbol_heap) = readPtr app_info_ptr us.us_symbol_heap
473
					  new_app_info = app_info
474
					  (new_info_ptr, us_symbol_heap) = newPtr new_app_info us_symbol_heap
475
476
					  us={ us & us_symbol_heap = us_symbol_heap }
					  (app_args, us) = unfold app_args us
477
					-> ({ app & app_args = app_args, app_info_ptr = new_info_ptr}, us) 
478
					# (app_args, us) = unfold app_args us
479
480
					-> ({ app & app_args = app_args}, us)
			_
481
				# (app_args, us) = unfold app_args us
482
				-> ({ app & app_args = app_args, app_info_ptr = nilPtr}, us) 
Ronny Wichers Schreur's avatar
Ronny Wichers Schreur committed
483
	where
484
		unfold_function_app app=:{app_args, app_info_ptr} us
485
486
			# (new_info_ptr, us_symbol_heap) = newPtr EI_Empty us.us_symbol_heap
			# us={ us & us_symbol_heap = us_symbol_heap }
487
			# (app_args, us) = unfold app_args us
488
			= ({ app & app_args = app_args, app_info_ptr = new_info_ptr}, us) 
Sjaak Smetsers's avatar
Sjaak Smetsers committed
489

490
491
492
493
		unfold_local_macro_function local_macro_function_n
			# (us_local_macro_functions,us) = us!us_local_macro_functions
			= case us_local_macro_functions of
				No
494
					-> unfold_function_app app us
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
				uslocal_macro_functions=:(Yes local_macro_functions)
					# (new_local_macro_function_n,us_local_macro_functions) = determine_new_local_macro_function_n local_macro_function_n local_macro_functions
						with
							determine_new_local_macro_function_n local_macro_function_n local_macro_functions=:{copied_local_functions,used_copied_local_functions,new_copied_local_functions,next_local_function_n}
								# new_local_macro_function_n = search_new_local_macro_function_n used_copied_local_functions
								| new_local_macro_function_n>=0
									= (new_local_macro_function_n,us_local_macro_functions)
								# (new_local_macro_function_n,used_copied_local_functions) = search_new_local_macro_function_n_and_add_to_used_functions copied_local_functions used_copied_local_functions
								| new_local_macro_function_n>=0
									= (new_local_macro_function_n,Yes {local_macro_functions & used_copied_local_functions=used_copied_local_functions})
								# (new_local_macro_function_n,used_copied_local_functions) = search_new_local_macro_function_n_and_add_to_used_functions new_copied_local_functions used_copied_local_functions
								| new_local_macro_function_n>=0
									= (new_local_macro_function_n,Yes {local_macro_functions & used_copied_local_functions=used_copied_local_functions})
									# new_local_function = {old_function_n=local_macro_function_n,new_function_n=next_local_function_n}
									# new_copied_local_functions=new_copied_local_functions++[new_local_function]
									# us_local_macro_functions=Yes {copied_local_functions=copied_local_functions,
																	new_copied_local_functions=new_copied_local_functions,
																	used_copied_local_functions=[new_local_function:used_copied_local_functions],
																	next_local_function_n=next_local_function_n+1}
									= (next_local_function_n,us_local_macro_functions)
								where
									search_new_local_macro_function_n [{old_function_n,new_function_n}:local_functions]
										| local_macro_function_n==old_function_n
											= new_function_n
										 	= search_new_local_macro_function_n local_functions
									search_new_local_macro_function_n []
										= -1

									search_new_local_macro_function_n_and_add_to_used_functions [copied_local_function=:{old_function_n,new_function_n}:local_functions] used_copied_local_functions
										| local_macro_function_n==old_function_n
											= (new_function_n,[copied_local_function:used_copied_local_functions])
										 	= search_new_local_macro_function_n_and_add_to_used_functions local_functions used_copied_local_functions
									search_new_local_macro_function_n_and_add_to_used_functions [] used_copied_local_functions
										= (-1,used_copied_local_functions)
					# us={us & us_local_macro_functions=us_local_macro_functions}
					# app={app & app_symb.symb_kind=SK_LocalMacroFunction new_local_macro_function_n}
531
					-> unfold_function_app app us
Ronny Wichers Schreur's avatar
Ronny Wichers Schreur committed
532

533
534
instance unfold LetBind
where
535
536
	unfold bind=:{lb_src} us
		# (lb_src, us) = unfold lb_src us
537
538
		= ({ bind & lb_src = lb_src }, us)

Ronny Wichers Schreur's avatar
Ronny Wichers Schreur committed
539
540
instance unfold (Bind a b) | unfold a
where
541
542
	unfold bind=:{bind_src} us
		# (bind_src, us) = unfold bind_src us
Ronny Wichers Schreur's avatar
Ronny Wichers Schreur committed
543
544
545
546
		= ({ bind & bind_src = bind_src }, us)

instance unfold Case
where
547
	unfold kees=:{case_expr,case_guards,case_default,case_info_ptr} us
548
		# (old_case_info, us_symbol_heap) = readPtr case_info_ptr us.us_symbol_heap
549
		  new_case_info = old_case_info
550
		  (new_info_ptr, us_symbol_heap) = newPtr new_case_info us_symbol_heap
551
552
553
		  us = { us & us_symbol_heap = us_symbol_heap }
		  ((case_guards,case_default), us) = unfold (case_guards,case_default) us
		  (case_expr, us) = unfold case_expr us
554
555
		= ({ kees & case_expr = case_expr,case_guards = case_guards, case_default = case_default, case_info_ptr =  new_info_ptr}, us)

Ronny Wichers Schreur's avatar
Ronny Wichers Schreur committed
556
557
instance unfold Let
where
558
	unfold lad=:{let_strict_binds, let_lazy_binds, let_expr, let_info_ptr} us
Sjaak Smetsers's avatar
Sjaak Smetsers committed
559
560
		# (let_strict_binds, us) = copy_bound_vars let_strict_binds us
		# (let_lazy_binds, us) = copy_bound_vars let_lazy_binds us
561
562
563
		# (let_strict_binds, us) = unfold let_strict_binds us
		# (let_lazy_binds, us) = unfold let_lazy_binds us
		# (let_expr, us) = unfold let_expr us
Ronny Wichers Schreur's avatar
Ronny Wichers Schreur committed
564
		  (old_let_info, us_symbol_heap) = readPtr let_info_ptr us.us_symbol_heap
565
		  new_let_info = old_let_info
566
		  (new_info_ptr, us_symbol_heap) = newPtr new_let_info us_symbol_heap
Sjaak Smetsers's avatar
Sjaak Smetsers committed
567
		= ({lad & let_strict_binds = let_strict_binds, let_lazy_binds = let_lazy_binds, let_expr = let_expr, let_info_ptr = new_info_ptr},
568
			{ us & us_symbol_heap = us_symbol_heap })
Ronny Wichers Schreur's avatar
Ronny Wichers Schreur committed
569
		where
570
			copy_bound_vars [bind=:{lb_dst} : binds] us
571
				# (lb_dst, us) = unfold lb_dst us
Ronny Wichers Schreur's avatar
Ronny Wichers Schreur committed
572
				  (binds, us) = copy_bound_vars binds us
573
				= ([ {bind & lb_dst = lb_dst} : binds ], us)
Ronny Wichers Schreur's avatar
Ronny Wichers Schreur committed
574
575
576
577
578
			copy_bound_vars [] us
				= ([], us)

instance unfold CasePatterns
where
579
580
	unfold (AlgebraicPatterns type patterns) us
		# (patterns, us) = unfold patterns us
Ronny Wichers Schreur's avatar
Ronny Wichers Schreur committed
581
		= (AlgebraicPatterns type patterns, us)
582
583
	unfold (BasicPatterns type patterns) us
		# (patterns, us) = unfold patterns us
Ronny Wichers Schreur's avatar
Ronny Wichers Schreur committed
584
		= (BasicPatterns type patterns, us)
585
586
587
	unfold (OverloadedListPatterns type decons_expr patterns) us
		# (patterns, us) = unfold patterns us
		# (decons_expr, us) = unfold decons_expr us
588
		= (OverloadedListPatterns type decons_expr patterns, us)
589
590
	unfold (NewTypePatterns type patterns) us
		# (patterns, us) = unfold patterns us
John van Groningen's avatar
John van Groningen committed
591
		= (NewTypePatterns type patterns, us)
592
593
	unfold (DynamicPatterns patterns) us
		# (patterns, us) = unfold patterns us
Ronny Wichers Schreur's avatar
Ronny Wichers Schreur committed
594
595
596
597
		= (DynamicPatterns patterns, us)

instance unfold AlgebraicPattern
where
598
599
600
	unfold guard=:{ap_vars,ap_expr} us
		# (ap_vars, us) = unfold ap_vars us
		  (ap_expr, us) = unfold ap_expr us
Ronny Wichers Schreur's avatar
Ronny Wichers Schreur committed
601
602
		= ({ guard & ap_vars = ap_vars, ap_expr = ap_expr }, us)

603
604
instance unfold BasicPattern
where
605
606
	unfold guard=:{bp_expr} us
		# (bp_expr, us) = unfold bp_expr us
607
608
		= ({ guard & bp_expr = bp_expr }, us)

Ronny Wichers Schreur's avatar
Ronny Wichers Schreur committed
609
610
instance unfold DynamicPattern
where
611
612
613
	unfold guard=:{dp_var,dp_rhs} us
		# (dp_var, us) = unfold dp_var us
		  (dp_rhs, us) = unfold dp_rhs us
Ronny Wichers Schreur's avatar
Ronny Wichers Schreur committed
614
615
		= ({ guard & dp_var = dp_var, dp_rhs = dp_rhs }, us)

616
617
instance unfold [a] | unfold a
where
618
	unfold l us
619
620
621
		= map_st l us
		where
			map_st [x : xs] s
622
			 	# (x, s) = unfold x s
623
624
625
626
627
628
629
630
				  (xs, s) = map_st xs s
				#! s = s
				= ([x : xs], s)
			map_st [] s
			 	= ([], s)

instance unfold (a,b) | unfold a & unfold b
where
631
632
633
	unfold (a,b) us
		# (a,us) = unfold a us
		# (b,us) = unfold b us
634
635
636
637
		= ((a,b),us)

instance unfold (Optional a) | unfold a
where
638
639
	unfold (Yes x) us
		# (x, us) = unfold x us
640
		= (Yes x, us)
641
	unfold no us
642
643
		= (no, us)

Ronny Wichers Schreur's avatar
Ronny Wichers Schreur committed
644
645
646
647
648
updateFunctionCalls :: ![FunCall] ![FunCall] !*{# FunDef} !*SymbolTable
	-> (![FunCall], !*{# FunDef}, !*SymbolTable)
updateFunctionCalls calls collected_calls fun_defs symbol_table
	= foldSt add_function_call calls (collected_calls, fun_defs, symbol_table)
where
649
	add_function_call fc=:(FunCall fc_index _) (collected_calls, fun_defs, symbol_table)
650
//		# fc_index = trace_n ("add_function_call: "+++toString fc_index+++" ") fc_index
651
652
		# ({fun_ident}, fun_defs) = fun_defs![fc_index]
		  (collected_calls, symbol_table) = examineFunctionCall fun_ident fc (collected_calls, symbol_table) 
Ronny Wichers Schreur's avatar
Ronny Wichers Schreur committed
653
654
		= (collected_calls, fun_defs, symbol_table)

655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
examineFunctionCall {id_info} fc=:(FunCall fc_index _) (calls, symbol_table)
	# (entry, symbol_table) = readPtr id_info symbol_table
	= case entry.ste_kind of
		STE_Called indexes
			| is_member fc_index indexes
				-> (calls, symbol_table)
				-> ([ fc : calls ], symbol_table <:= (id_info, { entry & ste_kind = STE_Called [ FunctionOrIclMacroIndex fc_index : indexes ]}))
		_
			-> ( [ fc : calls ], symbol_table <:=
					(id_info, { ste_kind = STE_Called [FunctionOrIclMacroIndex fc_index], ste_index = NoIndex, ste_def_level = NotALevel, ste_previous = entry }))
	where
		is_member fc_index [FunctionOrIclMacroIndex index:indexes]
			| fc_index==index
				= True
				= is_member fc_index indexes
		is_member fc_index [_:indexes]
			= is_member fc_index indexes
		is_member _ []
			= False
examineFunctionCall {id_info} fc=:(MacroCall macro_module_index fc_index _) (calls, symbol_table)
675
	# (entry, symbol_table) = readPtr id_info symbol_table
Ronny Wichers Schreur's avatar
Ronny Wichers Schreur committed
676
677
	= case entry.ste_kind of
		STE_Called indexes
678
			| is_member macro_module_index fc_index indexes
Ronny Wichers Schreur's avatar
Ronny Wichers Schreur committed
679
				-> (calls, symbol_table)
680
				-> ([ fc : calls ], symbol_table <:= (id_info, { entry & ste_kind = STE_Called [ DclMacroIndex macro_module_index fc_index : indexes ]}))
Ronny Wichers Schreur's avatar
Ronny Wichers Schreur committed
681
682
		_
			-> ( [ fc : calls ], symbol_table <:=
683
684
685
686
687
688
689
690
691
692
					(id_info, { ste_kind = STE_Called [DclMacroIndex macro_module_index fc_index], ste_index = NoIndex, ste_def_level = NotALevel, ste_previous = entry }))
	where
		is_member macro_module_index fc_index [DclMacroIndex module_index index:indexes]
			| fc_index==index && module_index==macro_module_index
				= True
				= is_member macro_module_index fc_index indexes
		is_member macro_module_index fc_index [_:indexes]
			= is_member macro_module_index fc_index indexes
		is_member _ _ []
			= False
693

694
695
696
697
698
699
700
::	ExpandState = {
		es_symbol_table		:: !.SymbolTable,
		es_var_heap			:: !.VarHeap,
		es_expression_heap 	:: !.ExpressionHeap,
		es_error 			:: !.ErrorAdmin,
		es_fun_defs			:: !.{#FunDef},
		es_macro_defs		:: !.{#.{#FunDef}},
701
702
		es_new_fun_def_numbers :: ![Int]
	}
Ronny Wichers Schreur's avatar
Ronny Wichers Schreur committed
703

704
705
706
707
708
709
710
711
712
713
714
715
716
copy_macro_and_local_functions ::		!FunDef !Int !*{#FunDef} !*{#*{#FunDef}} !*VarHeap !*ExpressionHeap
	-> (!FunDef,![(CopiedLocalFunction,FunDef)],!Int,!*{#FunDef},!*{#*{#FunDef}},!*VarHeap,!*ExpressionHeap)
copy_macro_and_local_functions macro new_function_index fun_defs macro_defs var_heap expr_heap
	# local_macro_functions = Yes {copied_local_functions=[],used_copied_local_functions=[],new_copied_local_functions=[],next_local_function_n=new_function_index+1}
	  (macro,local_macro_functions,var_heap,expr_heap)
		= copy_macro_or_local_macro_function macro local_macro_functions var_heap expr_heap
	  (new_functions,Yes {next_local_function_n},fun_defs,macro_defs,var_heap,expr_heap)
		= copy_local_functions_of_macro local_macro_functions [] fun_defs macro_defs var_heap expr_heap
	= (macro,new_functions,next_local_function_n,fun_defs,macro_defs,var_heap,expr_heap)

copy_local_functions_of_macro :: (Optional CopiedLocalFunctions) [CopiedLocalFunction] !*{#FunDef} !*{#*{#FunDef}} !*VarHeap !*ExpressionHeap
					-> (![(CopiedLocalFunction,FunDef)],!Optional CopiedLocalFunctions,!*{#FunDef},!*{#*{#FunDef}},!*VarHeap,!*ExpressionHeap)
copy_local_functions_of_macro local_macro_functions local_functions_to_be_copied fun_defs macro_defs var_heap expr_heap
717
718
719
720
721
722
723
724
725
726
	# (local_functions_to_be_copied,local_macro_functions) = add_new_local_functions_to_be_copied local_functions_to_be_copied local_macro_functions
		with
			add_new_local_functions_to_be_copied local_functions_to_be_copied local_macro_functions=:(Yes copied_local_macro_functions=:{new_copied_local_functions=[]})
				= (local_functions_to_be_copied,Yes {copied_local_macro_functions & used_copied_local_functions=[]})
			add_new_local_functions_to_be_copied local_functions_to_be_copied (Yes {copied_local_functions,new_copied_local_functions,next_local_function_n})
				# local_macro_functions=Yes {copied_local_functions=copied_local_functions++new_copied_local_functions,
											new_copied_local_functions=[],used_copied_local_functions=[],next_local_function_n=next_local_function_n}
				= (local_functions_to_be_copied++new_copied_local_functions,local_macro_functions)
	= case local_functions_to_be_copied of
		[]
727
			-> ([],local_macro_functions,fun_defs,macro_defs,var_heap,expr_heap)
728
		[(old_and_new_function_n=:{old_function_n,new_function_n}):local_functions_to_be_copied]
729
			# (function,fun_defs,macro_defs)
730
731
				= case old_function_n of
					FunctionOrIclMacroIndex old_function_index
732
						# (function,fun_defs)=fun_defs![old_function_index]			
733
						#! function_group_index=function.fun_info.fi_group_index
734
						# fun_defs & [old_function_index].fun_info.fi_group_index= if (function_group_index>NoIndex) (-2-function_group_index) function_group_index
735
						# function = {function & fun_info.fi_group_index=if (function_group_index<NoIndex) (-2-function_group_index) function_group_index}
736
						-> (function,fun_defs,macro_defs)
737
					DclMacroIndex old_function_module_index old_function_index
738
						# (function,macro_defs)=macro_defs![old_function_module_index,old_function_index]			
739
						#! function_group_index=function.fun_info.fi_group_index
740
						# macro_defs & [old_function_module_index].[old_function_index].fun_info.fi_group_index= if (function_group_index>NoIndex) (-2-function_group_index) function_group_index
741
						# function = {function & fun_info.fi_group_index=if (function_group_index<NoIndex) (-2-function_group_index) function_group_index}
742
743
744
745
746
						-> (function,fun_defs,macro_defs)
			# (function,local_macro_functions,var_heap,expr_heap) = copy_macro_or_local_macro_function function local_macro_functions var_heap expr_heap
			# (new_functions,local_macro_functions,fun_defs,macro_defs,var_heap,expr_heap)
				= copy_local_functions_of_macro local_macro_functions local_functions_to_be_copied fun_defs macro_defs var_heap expr_heap
			-> ([(old_and_new_function_n,function):new_functions],local_macro_functions,fun_defs,macro_defs,var_heap,expr_heap)
747
748
749
750
751
752
753
754
755

update_calls calls No
	= calls
update_calls calls (Yes {used_copied_local_functions=[]})
	= calls
update_calls calls (Yes {used_copied_local_functions})
	# calls = remove_old_calls calls
	= add_new_calls used_copied_local_functions calls
where
756
	remove_old_calls [call=:(FunCall fc_index _):calls]
757
758
759
760
761
762
		| contains_old_function_n used_copied_local_functions
//			# calls = trace ("remove_old_calls1: "+++toString fc_index) calls
			= remove_old_calls calls
//			# calls = trace ("remove_old_calls2: "+++toString fc_index) calls
			= [call:remove_old_calls calls]
	where
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
		contains_old_function_n [{old_function_n=FunctionOrIclMacroIndex old_function_index }:local_functions]
			= fc_index==old_function_index || contains_old_function_n local_functions
		contains_old_function_n [_:local_functions]
			= contains_old_function_n local_functions
		contains_old_function_n []
			= False
	remove_old_calls [call=:(MacroCall macro_module_index fc_index _):calls]
		| contains_old_function_n used_copied_local_functions
			= remove_old_calls calls
			= [call:remove_old_calls calls]
	where
		contains_old_function_n [{old_function_n=DclMacroIndex old_macro_module_index old_function_index }:local_functions]
			= fc_index==old_function_index && macro_module_index==old_macro_module_index || contains_old_function_n local_functions
		contains_old_function_n [_:local_functions]
			= contains_old_function_n local_functions
778
779
		contains_old_function_n []
			= False
780
781
	remove_old_calls [call=:(DclFunCall _ _):calls]
			= [call:remove_old_calls calls]
782
783
784
785
786
	remove_old_calls []
		= []
	
	add_new_calls [{new_function_n}:local_functions] calls
//		# local_functions = trace ("add_new_calls: "+++toString new_function_n) local_functions
787
		= add_new_calls local_functions [FunCall new_function_n NotALevel:calls]
788
789
790
	add_new_calls [] calls
		= calls

791
792
793
copy_macro_or_local_macro_function :: !FunDef !(Optional CopiedLocalFunctions) !*VarHeap !*ExpressionHeap -> (!FunDef,!Optional CopiedLocalFunctions,!*VarHeap,!*ExpressionHeap);
copy_macro_or_local_macro_function macro=:{fun_body = TransformedBody {tb_args,tb_rhs},fun_kind,fun_info={fi_local_vars,fi_calls}} local_macro_functions var_heap expr_heap
	# (tb_args,var_heap) = create_new_arguments tb_args var_heap
794
		with
795
			create_new_arguments [var=:{fv_ident,fv_info_ptr} : vars] var_heap
796
797
				# (new_vars,var_heap) = create_new_arguments vars var_heap
				# (new_info, var_heap) = newPtr VI_Empty var_heap
798
799
				# new_var = { fv_ident = fv_ident, fv_def_level = NotALevel, fv_info_ptr = new_info, fv_count = 0 }
				= ([new_var : new_vars], writePtr fv_info_ptr (VI_Variable fv_ident new_info) var_heap)
800
801
			create_new_arguments [] var_heap
				= ([],var_heap)
802
	# us = { us_symbol_heap = expr_heap, us_var_heap = var_heap, us_local_macro_functions = local_macro_functions }
803
	# (result_expr,{us_local_macro_functions,us_symbol_heap,us_var_heap}) = unfold tb_rhs us
804
805
	# (fi_local_vars,us_var_heap) = update_local_vars fi_local_vars us_var_heap
		with
806
			update_local_vars :: ![FreeVar] !*VarHeap -> (![FreeVar],!*VarHeap);
807
808
809
810
811
812
813
814
815
816
817
			update_local_vars [fv=:{fv_info_ptr}:fvs] var_heap
				# (fvs,var_heap)=update_local_vars fvs var_heap
				# (fv_info,var_heap) = readPtr fv_info_ptr var_heap
				# fv = {fv & fv_info_ptr=case fv_info of 
											(VI_Variable _ info_ptr) -> info_ptr
						}
				= ([fv:fvs],var_heap)
			update_local_vars [] var_heap
				= ([],var_heap)
	# fi_calls = update_calls fi_calls us_local_macro_functions
	= ({macro & fun_body = TransformedBody {tb_args=tb_args,tb_rhs=result_expr},fun_info.fi_local_vars=fi_local_vars,fun_info.fi_calls=fi_calls},us_local_macro_functions,
818
	   us_var_heap, us_symbol_heap)
819

820
unfoldMacro :: !FunDef ![Expression] !*ExpandInfo -> (!Expression, !*ExpandInfo)
821
unfoldMacro {fun_body =fun_body=: TransformedBody {tb_args,tb_rhs}, fun_info = {fi_calls},fun_kind,fun_ident} args (calls, es=:{es_var_heap,es_expression_heap,es_fun_defs})
Ronny Wichers Schreur's avatar
Ronny Wichers Schreur committed
822
	# (let_binds, var_heap) = bind_expressions tb_args args [] es_var_heap
823
824
	#! size_fun_defs = size es_fun_defs
	# copied_local_functions = Yes { copied_local_functions=[],used_copied_local_functions=[],new_copied_local_functions=[],next_local_function_n=size_fun_defs}
825
	# us = { us_symbol_heap = es_expression_heap, us_var_heap = var_heap, us_local_macro_functions = copied_local_functions }
826
	# (result_expr,{us_local_macro_functions,us_symbol_heap,us_var_heap}) = unfold tb_rhs us
827
	# es = {es & es_var_heap = us_var_heap, es_expression_heap = us_symbol_heap}
828
	# fi_calls = update_calls fi_calls us_local_macro_functions
829
830
831
	# {es_fun_defs,es_macro_defs,es_var_heap,es_expression_heap,es_symbol_table,es_new_fun_def_numbers} = es
	  (new_functions,us_local_macro_functions,es_fun_defs,es_macro_defs,es_var_heap,es_expression_heap)
		= copy_local_functions_of_macro us_local_macro_functions [] es_fun_defs es_macro_defs es_var_heap es_expression_heap
832
833
834
835
836
837
838
839
840
	# (es_fun_defs,es_new_fun_def_numbers) = case new_functions of
		[]
			-> (es_fun_defs,es_new_fun_def_numbers)
		_
			# last_function_index = case us_local_macro_functions of (Yes {next_local_function_n}) -> next_local_function_n-1
			# new_fun_defs = new_fun_defs
				with
					new_fun_defs :: *{!FunDef}
					new_fun_defs => {fun_def \\ (_,fun_def)<-new_functions}
841
842
843
844
845
//			-> ({if (i<size_fun_defs) es_fun_defs.[i] new_fun_defs.[i-size_fun_defs] \\ i<-[0..last_function_index]} // inefficient
//				,[size_fun_defs:es_new_fun_def_numbers])
//			#! new_fun_defs = arrayConcat es_fun_defs new_fun_defs	// leads to backend crash!
			# new_fun_defs = arrayConcat es_fun_defs new_fun_defs
			-> (new_fun_defs, [size_fun_defs:es_new_fun_def_numbers])
846
	# (calls, fun_defs, es_symbol_table) = updateFunctionCalls fi_calls calls es_fun_defs es_symbol_table
Ronny Wichers Schreur's avatar
Ronny Wichers Schreur committed
847
	| isEmpty let_binds
848
849
		# es & es_macro_defs=es_macro_defs, es_var_heap=es_var_heap, es_symbol_table = es_symbol_table, es_expression_heap=es_expression_heap, es_fun_defs=fun_defs, es_new_fun_def_numbers=es_new_fun_def_numbers
		= (result_expr, (calls, es))
850
		# (new_info_ptr, es_expression_heap) = newPtr EI_Empty es_expression_heap
851
		# es & es_macro_defs=es_macro_defs, es_var_heap=es_var_heap, es_symbol_table = es_symbol_table, es_expression_heap=es_expression_heap, es_fun_defs=fun_defs, es_new_fun_def_numbers=es_new_fun_def_numbers
852
		# result_expr=Let { let_strict_binds = [], let_lazy_binds = let_binds, let_expr = result_expr, let_info_ptr = new_info_ptr, let_expr_position = NoPos }
853
		= (result_expr, (calls, es))
Ronny Wichers Schreur's avatar
Ronny Wichers Schreur committed
854
855
856
857
858
859
860
where
	bind_expressions [var : vars] [expr : exprs] binds var_heap
		# (binds, var_heap) = bind_expressions vars exprs binds var_heap
		= bind_expression var expr binds var_heap
	bind_expressions _ _ binds var_heap
		= (binds, var_heap)

861
	bind_expression :: FreeVar Expression [LetBind] *VarHeap -> (![LetBind],!*VarHeap);
Ronny Wichers Schreur's avatar
Ronny Wichers Schreur committed
862
863
864
	bind_expression {fv_count} expr binds var_heap
		| fv_count == 0
			= (binds, var_heap)
865
866
867
	bind_expression {fv_info_ptr} (Var {var_ident,var_info_ptr}) binds var_heap
		= (binds, writePtr fv_info_ptr (VI_Variable var_ident var_info_ptr) var_heap)
	bind_expression {fv_ident,fv_info_ptr,fv_count} expr binds var_heap
Ronny Wichers Schreur's avatar
Ronny Wichers Schreur committed
868
869
870
		| fv_count == 1
			= (binds, writePtr fv_info_ptr (VI_Expression expr) var_heap)
		# (new_info, var_heap) = newPtr VI_Empty var_heap
871
872
		  new_var = { fv_ident = fv_ident, fv_def_level = NotALevel, fv_info_ptr = new_info, fv_count = 0 }
		= ([{ lb_src = expr, lb_dst = new_var, lb_position = NoPos} : binds], writePtr fv_info_ptr (VI_Variable fv_ident new_info) var_heap)
Ronny Wichers Schreur's avatar
Ronny Wichers Schreur committed
873

874
875
:: UnexpandedDclMacros:==[(Int,Int,FunDef)]

876
::	PartitioningState =
877
878
879
880
881
882
883
884
885
886
	{	ps_symbol_table	:: !.SymbolTable
	,	ps_var_heap		:: !.VarHeap
	,	ps_symbol_heap	:: !.ExpressionHeap
	,	ps_error		:: !.ErrorAdmin
	,	ps_fun_defs		:: !.{#FunDef}
	,	ps_macro_defs	:: !.{#.{#FunDef}}
	,	ps_next_num		:: !Int
	,	ps_next_group	:: !Int
	,	ps_groups		:: ![[FunctionOrMacroIndex]]
	,	ps_deps			:: ![FunctionOrMacroIndex]
887
	,	ps_unexpanded_dcl_macros :: !UnexpandedDclMacros
Ronny Wichers Schreur's avatar
Ronny Wichers Schreur committed
888
889
	}

890
891
:: PartitioningInfo = ! {
	pi_predef_symbols_for_transform :: !PredefSymbolsForTransform,
892
893
	pi_main_dcl_module_n :: !Int,
	pi_reset_body_of_rhs_macros :: !Bool
894
895
   }

Ronny Wichers Schreur's avatar
Ronny Wichers Schreur committed
896
897
NotChecked :== -1	

John van Groningen's avatar
John van Groningen committed
898
899
:: PredefSymbolsForTransform = { predef_alias_dummy :: !PredefinedSymbol, predef_and :: !PredefinedSymbol, predef_or :: !PredefinedSymbol };

900
901
reset_body_of_rhs_macros ps_deps fun_defs macro_defs
	= foldSt reset_body_of_rhs_macro ps_deps (fun_defs,macro_defs)
Ronny Wichers Schreur's avatar
Ronny Wichers Schreur committed
902
	where
903
904
905