aboutsummaryrefslogtreecommitdiff
path: root/portToNewSyntax/merge.icl
blob: a0d97e9a442f2b9cce8a124fde8d2f9a12c18953 (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
181
182
183
184
185
186
implementation module merge

import StdEnv, RWSDebug, StdArrayExtensions

from syntax import Optional, Yes, No
import utilities, portToNewSyntax

mergeFiles ::  !*File !*File !*File -> (!.File,!.File,!.File)
mergeFiles old inferred new
	# (lines_within_comment, old)
			= lines_in_comment old
	= merge_files lines_within_comment 0 old inferred new

merge_files ::  ![Int] !Int !*File !*File !*File -> (!.File,!.File,!.File)
merge_files lines_within_comment line_nr old inferred new
	# (end, old) = fend old
	| end
		# (inferred, new)
				= copy_rest inferred new
		= (old, inferred, new)
	# (line, old) = my_freadline old
	  line_l = [ ch \\ ch<-:line ]
	| not (begins_with_from line_l) || isMember line_nr lines_within_comment
		= merge_files lines_within_comment (line_nr+1) old inferred (fwrites line new)
	# new = fwrites ("//1.3\n"+++(complete_line line)) new
	  (new_line_nr, module_names, old, new)
	  		= copy_original_from_statements line_nr line_l [] old new
  // insert inferred part
  	  new = fwrites ("//3.1\n/*2.0\n") new
	  (inferred, new)
	  		= foldSt insert_inferred_from_stmnt module_names (inferred, new)
	= merge_files lines_within_comment new_line_nr old inferred (fwrites "0.2*/\n" new)

copy_original_from_statements line_nr line_l mod_names_accu old new
	# (left_space, module_name) = get_ls_and_mn line_l
	  (line_nr, opt_next_from_statement, old, new) = layout_skip line_nr left_space old new
	= case opt_next_from_statement of
		No
			-> (line_nr, reverse [module_name:mod_names_accu], old, new)
		Yes line_l`
			-> copy_original_from_statements line_nr line_l` [module_name:mod_names_accu]
					old new

insert_inferred_from_stmnt module_name (inferred, new)
	# (first_line_of_import, inferred) = my_freadline inferred
	  new = foldSt fwrites ["from ", module_name, " ", first_line_of_import] new
  	= copy_rest_of_import inferred new
	
begins_with_from line_l
	# without_spaces = dropWhile isSpace line_l
	= case without_spaces of
		['from'] -> True
		['from',ch:_] -> not (isAlphanum ch || isMember ch ['`_']) 
		_ -> False

get_ls_and_mn line_l
	# (spaces, rest1) = span isSpace line_l
	  without_from = drop 4 rest1
	  (_, rest2) = span isSpace without_from
	  module_name = takeWhile (not o isSpace) rest2
	= (space_count spaces 0, toString module_name)

space_count [] _
	= 0
space_count [' ':spaces] modTabWidth
	= 1+(space_count spaces ((modTabWidth+1) mod modTabWidth))
space_count ['\t':spaces] modTabWidth
	= (cTabWidth-modTabWidth)+(space_count spaces 0)
space_count ['\n':_] _
	= 0

layout_skip :: !Int !Int !*File !*File -> (!Int, !Optional [Char], !.File, !.File)
layout_skip line_nr left_space old new
	# (end, old) = fend old
	| end
		= (line_nr, No, old, new)
	# (cur_pos, old) = fposition old
	  (line, old) = my_freadline old
	  line_l = [ ch \\ ch<-:line ]
	  spaces = takeWhile isSpace line_l
	| space_count spaces 0<=left_space
		| begins_with_from line_l
			= (line_nr+1, Yes line_l, old, fwrites (complete_line line) new) 
		= (line_nr+1, No, snd (fseek old cur_pos FSeekSet), new)
	= layout_skip (line_nr+1) left_space old (fwrites (complete_line line) new)

copy_rest_of_import :: !*File !*File -> (!.File, !.File)
copy_rest_of_import inferred new
	# (end, inferred) = fend inferred
	| end
		= (inferred ,new)
	# (cur_pos, inferred) = fposition inferred
	  (line, inferred) = my_freadline inferred
	| line % (0,5)=="import"
		= (snd (fseek inferred cur_pos FSeekSet), new)
	= copy_rest_of_import inferred (fwrites line new)

complete_line line
	| line.[size line-1]<>'\n'
		= line+++"\n"
	= line	

copy_rest inferred new
	# (end, inferred) = fend inferred
	| end
		= (inferred, new)
	# (line, inferred)
			= my_freadline inferred
	= copy_rest inferred (fwrites line new)

lines_in_comment file
	# (cur_pos, file)
			= fposition file
	  (rev_lines_within_comment, file)
	  		= get_lic 0 [] file
	= (reverse rev_lines_within_comment, snd (fseek file cur_pos FSeekSet))
  where
	get_lic :: !Int ![Int] !*File -> (![Int], !*File)
	get_lic line_nr line_nr_accu file
		# (end, file)
				= fend file
		| end
			= (line_nr_accu, file)
		# (line, file)
				= my_freadline file
		  line_l
		  		= [ch \\ ch<-:line]
		# (bwc, rest)
				= begins_with_comment line_l
		| bwc
			= consider_comment 1 rest line_nr line_nr_accu file
		= get_lic (line_nr+1) line_nr_accu file

	begins_with_comment ['//1.3':rest]
		= (True, rest)
	begins_with_comment line_l
	  	 # without_spaces
	  	  		= dropWhile isSpace line_l
		= case without_spaces of
			['/*':rest]
				-> (True, rest)
			_
				-> (False, [])

	consider_comment nesting_level ['*/':rest] line_nr line_nr_accu file
		| nesting_level==1
			= get_lic line_nr line_nr_accu file
		= consider_comment (nesting_level-1) rest line_nr line_nr_accu file
	consider_comment nesting_level ['/*':rest] line_nr line_nr_accu file
		= consider_comment (nesting_level+1) rest line_nr line_nr_accu file
	consider_comment nesting_level [_:rest] line_nr line_nr_accu file
		= consider_comment nesting_level rest line_nr line_nr_accu file
	consider_comment nesting_level [] line_nr line_nr_accu file
		# (end, file)
				= fend file
		| end
			= ([], file)
		# (line, file)
				= my_freadline file
		  line_l
		  		= [ch \\ ch<-:line]
		= case line_l of
			['//3.1':rest]
				| nesting_level==1
					-> get_lic (line_nr+1) [line_nr+1:line_nr_accu] file
				-> consider_comment (nesting_level-1) rest (line_nr+1) [line_nr+1:line_nr_accu] file
			_
				-> consider_comment nesting_level line_l (line_nr+1) [line_nr+1:line_nr_accu] file

my_freadline :: !*File -> (!String, !*File)
my_freadline file
	#! (line, file) = freadline file
	   last_char_ix = size line - 1
	   last_printable_char_ix = findrArrElt isntNewlineOnAnyPlatform line last_char_ix
	| last_printable_char_ix==(-1)
		= ("\n", file)
	| last_printable_char_ix==last_char_ix
		= (line, file)
	| last_printable_char_ix==last_char_ix-1 && line.[last_char_ix]=='\n'
		= (line, file)
	= ({line & [last_printable_char_ix+1] = '\n' } %(0, last_printable_char_ix+1), file)

isntNewlineOnAnyPlatform '\xA' = False
isntNewlineOnAnyPlatform '\xD' = False
isntNewlineOnAnyPlatform _ = True