aboutsummaryrefslogtreecommitdiff
path: root/backend/backendpreprocess.icl
blob: 31f81a2462541536d2306203638a6a2e338fd8a6 (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
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

//1.3
instance preprocess {#a} | preprocess a & ArrayElem a where
//3.1
/*2.0
instance preprocess {#a} | preprocess a & Array {#} a where
0.2*/
	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
		&	ss_varHeap = writePtr varInfoPtr (VI_SequenceNumber sequenceState.ss_sequenceNumber) sequenceState.ss_varHeap
		,	ss_sequenceNumber = sequenceState.ss_sequenceNumber + 1
		}

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 (BackendBody backEndBodies)
		=	sequence backEndBodies
	sequence body
		=	abort "preprocess (FunctionBody): unknown body" <<- body

instance sequence BackendBody where
	sequence body
		=	sequence body.bb_args
		o`	sequence body.bb_rhs

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_then, if_else})
		=	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 _
		=	identity

instance sequence Selection where
	sequence (RecordSelection _ _)
		=	identity
	sequence (ArraySelection _ _ index)
		=	sequence index
	sequence (DictionarySelection dictionaryVar dictionarySelections _ index)
		=	sequence index

instance sequence (Bind Expression FreeVar) where
	sequence {bind_src=App app , bind_dst}
		= sequence` app bind_dst
	  where
	  	sequence` {app_symb, app_args} bind_dst sequenceState=:{ss_aliasDummyId}
			| app_symb.symb_name==ss_aliasDummyId
				// the compiled source was a strict alias like "#! x = y"
				= case hd app_args of
					Var bound_var=:{var_info_ptr}
						# (vi, ss_varHeap) = readPtr var_info_ptr sequenceState.ss_varHeap
						  non_alias_bound_var = case vi of
													VI_SequenceNumber _		-> bound_var
													VI_Alias alias_bound_var-> alias_bound_var
						  ss_varHeap = writePtr bind_dst.fv_info_ptr (VI_Alias non_alias_bound_var) ss_varHeap
						-> { sequenceState & ss_varHeap = ss_varHeap }
					_
						-> sequence bind_dst sequenceState
		= sequence bind_dst sequenceState
	sequence bind
		=	sequence bind.bind_dst

instance sequence FunctionPattern where
	sequence (FP_Algebraic _ subpatterns optionalVar)
		=	sequence subpatterns
		o`	sequence optionalVar
	sequence (FP_Variable freeVar)
		=	sequence freeVar
	sequence (FP_Basic _ optionalVar)
		=	sequence optionalVar
	sequence FP_Empty
		=	identity

instance sequence (Ptr VarInfo) where
	sequence varInfoPtr
		=	assignSequenceNumber varInfoPtr