Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1769 yogev_ezra 1
#include 
2
#include 
3
#include 
4
#include 
5
#include 
6
using namespace std;
7
 
8
char str[20000], *word[100];
9
int wordlen[sizeof(word) / sizeof(word[0])];
10
 
11
char words_ignore[100][100] = { "?debug",
12
								"if",
13
								"ifdef",
14
								"ifndef",
15
								"endif",
16
								"macro",
17
								"endm",
18
								"dgroup",
19
								"assume",
20
								"segment",
21
								"ends",
22
								"public",
23
								"proc",
24
								"endp",
25
								"extrn",
26
								"model",
27
								"label",
28
								"end",
29
								""};
30
 
31
#define WI_macro    (words_ignore[5])
32
#define WI_endm     (words_ignore[6])
33
#define WI_segment  (words_ignore[9])
34
#define WI_ends     (words_ignore[10])
35
#define WI_proc     (words_ignore[12])
36
#define WI_endp     (words_ignore[13])
37
#define WI_label    (words_ignore[16])
38
const char *WI_END = "END";
39
 
40
int nwords_ignore = -1;
41
char *words_ign_sort[sizeof(words_ignore) / sizeof(words_ignore[0])];
42
 
43
int strcmp1(const char *s0, int n0, const char *s1, int n1)
44
{
45
	while (n0 && n1)
46
	{
47
		n0--; n1--;
48
		int c = (int)tolower(*s0) - (int)tolower(*s1);
49
		if (c < 0) return -1;
50
		if (c > 0) return 1;
51
		if (!*(s0++) || !*(s1++)) return 0;
52
	}
53
	if (n0 && *s0) return 1;
54
	if (n1 && *s1) return -1;
55
	return 0;
56
}
57
 
58
int strlen1(const char *s, int n)
59
{
60
	int i = 0;
61
	while (i < n && s[i]) i++;
62
	return i;
63
}
64
 
65
char *strcpy1(char *r, const char *s, int n)
66
{
67
	char *r0 = r;
68
	while (n-- && *s) *(r++) = *(s++);
69
	*r = 0;
70
	return r0;
71
}
72
 
73
char *strchr1(char *s, int n, char c)
74
{
75
	while (n-- && *s)
76
	{
77
		if (*s == c) return s;
78
		s++;
79
	}
80
	return 0;
81
}
82
 
83
char *first_not_space(char *s)
84
{
85
	while (*s && isspace(*s)) s++;
86
	return s;
87
}
88
 
89
char get_word(char *s)
90
{
91
	int i = 0, k;
92
	for (k = 0; k < sizeof(word) / sizeof(word[0]); k++)
93
	{
94
		s = first_not_space(s + i);
95
		word[k] = s;
96
		i = 0;
97
		while (s[i] && !isspace(s[i]) && s[i] != ';' && s[i] != ',' && s[i] != ':')
98
		{
99
			i++;
100
		}
101
		if (i == 0)
102
		{
103
			if (s[i] != ',' && s[i] != ':') break;
104
			i = 1;
105
		}
106
		wordlen[k] = i;
107
	}
108
	for (; k < sizeof(word) / sizeof(word[0]); k++)
109
	{
110
		word[k] = s; wordlen[k] = 0;
111
	}
112
	return s[i];
113
}
114
 
115
void build_words_ignore()
116
{
117
	int i, j;
118
	nwords_ignore = 0;
119
	while (words_ignore[nwords_ignore][0])
120
	{
121
		words_ign_sort[nwords_ignore] = words_ignore[nwords_ignore];
122
		nwords_ignore++;
123
	}
124
	for (i = 0; i < nwords_ignore; i++) for (j = 0; j < i; j++)
125
	{
126
		if (strcmp1(words_ign_sort[j], -1, words_ign_sort[i], -1) > 0)
127
		{
128
			char *s = words_ign_sort[j];
129
			words_ign_sort[j] = words_ign_sort[i];
130
			words_ign_sort[i] = s;
131
		}
132
	}
133
	words_ign_sort[nwords_ignore] = words_ignore[nwords_ignore];
134
}
135
 
136
int find_word_ign_sort(const char *s, int n)
137
{
138
	int i0, i1, i;
139
	if (nwords_ignore < 0) build_words_ignore();
140
	i0 = -1; i1 = nwords_ignore;
141
	while (i1 > i0 + 1)
142
	{
143
		i = (i0 + i1) / 2;
144
		if (strcmp1(s, n, words_ign_sort[i], -1) > 0) i0 = i;
145
		else i1 = i;
146
	}
147
	return i1;
148
}
149
 
150
char *find_word_ignore(const char *s, int n)
151
{
152
	int i = find_word_ign_sort(s, n);
153
	return (strcmp1(s, n, words_ign_sort[i], -1) == 0) ? words_ign_sort[i] : 0;
154
}
155
 
156
char *add_word_ignore(const char *s, int n)
157
{
158
	int i = find_word_ign_sort(s, n), j;
159
	if (strcmp1(s, n, words_ign_sort[i], -1) != 0)
160
	{
161
		if (s[0] && strlen1(s, n) < sizeof(words_ignore[0]) &&
162
			words_ignore[nwords_ignore+1] < words_ignore[0] + sizeof(words_ignore))
163
		{
164
			strcpy1(words_ignore[nwords_ignore], s, n);
165
			words_ignore[nwords_ignore+1][0] = 0;
166
			for (j = nwords_ignore; j >= i; j--) words_ign_sort[j+1] = words_ign_sort[j];
167
			words_ign_sort[i] = words_ignore[nwords_ignore];
168
			nwords_ignore++;
169
			words_ign_sort[nwords_ignore] = words_ignore[nwords_ignore];
170
		}
171
		else return 0;
172
	}
173
	return words_ign_sort[i];
174
}
175
 
176
struct CSegment
177
{
178
	char name[100];
179
	int state;
180
	string text;
181
};
182
 
183
int nsegment = 0, cursegment = 0, stack_segment[50], nstack_segment = 0;
184
CSegment segment[100];
185
 
186
void push_stack_segment()
187
{
188
	if (nstack_segment < sizeof(stack_segment) / sizeof(stack_segment[0]))
189
	{
190
		stack_segment[nstack_segment] = cursegment;
191
	}
192
	nstack_segment++;
193
}
194
 
195
void pop_stack_segment()
196
{
197
	if (nstack_segment > 0) nstack_segment--;
198
	if (nstack_segment < sizeof(stack_segment) / sizeof(stack_segment[0]))
199
	{
200
		cursegment = stack_segment[nstack_segment];
201
	}
202
}
203
 
204
void newsegment()
205
{
206
	segment[nsegment].name[0] = 0;
207
	segment[nsegment].state = 0;
208
	segment[nsegment].text = "";
209
	cursegment = nsegment++;
210
}
211
 
212
void tosegment(char *name, int nameL)
213
{
214
	int i;
215
	cursegment = 0;
216
	if (strlen1(name, nameL) >= sizeof(segment[0].name)) return;
217
	for (i = 0; i < nsegment; i++)
218
	{
219
		if (strcmp1(name, nameL, segment[i].name, -1) == 0)
220
		{
221
			cursegment = i;
222
			return;
223
		}
224
	}
225
	if (nsegment >= sizeof(segment) / sizeof(segment[0])) return;
226
	newsegment();
227
	strcpy1(segment[cursegment].name, name, nameL);
228
}
229
 
230
void outsegment()
231
{
232
	if (segment[cursegment].state == 0) return;
233
	fputs("\nsegment", stdout);
234
	if (segment[cursegment].name[0])
235
	{
236
		fputc(' ', stdout);
237
		fputs(segment[cursegment].name, stdout);
238
	}
239
	fputc('\n', stdout);
240
	fputs(segment[cursegment].text.c_str(), stdout);
241
	fputs("endseg", stdout);
242
	if (segment[cursegment].name[0])
243
	{
244
		fputs("  ", stdout);
245
		fputs(segment[cursegment].name, stdout);
246
	}
247
	fputc('\n', stdout);
248
}
249
 
250
void transform_label(int in_define, bool label = false)
251
{
252
	if (in_define)
253
	{
254
		memmove(str + 8, word[0], wordlen[0]);
255
		memcpy(str, "nextdef ", 8);
256
		str[wordlen[0]+8] = '\n';
257
		str[wordlen[0]+9] = 0;
258
	}
259
	else if (label)
260
	{
261
		memmove(str, word[0], wordlen[0]);
262
		str[wordlen[0]] = ':';
263
		str[wordlen[0]+1] = '\n';
264
		str[wordlen[0]+2] = 0;
265
	}
266
	segment[cursegment].state |= 4;
267
}
268
 
269
int main()
270
{
271
	char *s;
272
	int in_macro = 0, in_define = 0, i;
273
	newsegment();
274
	for (;;)
275
	{
276
		i = sizeof(str) - 200;
277
		if (!fgets(str, i, stdin)) break;
278
		if ((s = strchr(str, '\n')) == NULL)
279
		{
280
			if (strlen(str) < i-1) strcat(str, "\n");
281
			else
282
			{
283
				while (fgets(str, sizeof(str), stdin))
284
				{
285
					if (strchr(str, '\n')) break;
286
				}
287
				continue;
288
			}
289
		}
290
		char* p;
291
		while (p=strstr(str,"st("))
292
		{
293
			p[2]=p[3];
294
			memmove(p+3,p+5,strlen(p+5)+1);
295
		}
296
		get_word(str);
297
		if (word[1][0] == ':') transform_label(in_define, false);
298
		else
299
		{
300
			if (word[0][0] == '.') continue;
301
			if (strcmp1(word[0], wordlen[0], WI_macro, -1) == 0 ||
302
				strcmp1(word[1], wordlen[1], WI_macro, -1) == 0)
303
			{
304
				add_word_ignore(word[0], wordlen[0]);
305
				in_macro++;
306
				continue;
307
			}
308
			if (strcmp1(word[0], wordlen[0], WI_endm, -1) == 0)
309
			{
310
				if (in_macro > 0) in_macro--;
311
				continue;
312
			}
313
			if (strcmp1(word[1], wordlen[1], WI_segment, -1) == 0)
314
			{
315
				push_stack_segment();
316
				add_word_ignore(word[0], wordlen[0]);
317
				tosegment(word[0], wordlen[0]);
318
				continue;
319
			}
320
			if (strcmp1(word[1], wordlen[1], WI_ends, -1) == 0)
321
			{
322
				pop_stack_segment();
323
				continue;
324
			}
325
			if (find_word_ignore(word[0], wordlen[0])) continue;
326
			if (wordlen[0] == 0 || strcmp1(word[0], wordlen[0], "align", -1) == 0)
327
			{
328
				if (word[0][0] == 0) {str[0] = '\n'; str[1] = 0;}
329
			}
330
			else if (strcmp1(word[1], wordlen[1], WI_endp, -1) == 0)
331
			{
332
				if (in_define > 0) strcpy(str, (--in_define) ? "newdef\n" : "enddef\n");
333
			}
334
			else if (strcmp1(word[1], wordlen[1], WI_proc, -1) == 0)
335
			{
336
				memmove(str + 8, word[0], wordlen[0]);
337
				memcpy(str, (in_define++) ? "newdef  " : "define  ", 8);
338
				str[wordlen[0]+8] = '\n';
339
				str[wordlen[0]+9] = 0;
340
				segment[cursegment].state |= 4;
341
			}
342
			else if (strcmp1(word[1], wordlen[1], WI_label, -1) == 0)
343
			{
344
				transform_label(in_define, true);
345
			}
346
			else
347
			{
348
				for (i = 0; i <= 1; i++)
349
				{
350
					if (strcmp1(word[i], wordlen[i], "db", -1) == 0 &&
351
						wordlen[i+2] >= 3 && strcmp1(word[i+2], 3, "dup", 3) == 0)
352
					{
353
						if (word[i][0] == 'd') word[i][0] = 'r';
354
						else if (word[i][0] == 'D') word[i][0] = 'R';
355
						word[i+1][wordlen[i+1]] = '\n';
356
						word[i+1][wordlen[i+1]+1] = 0;
357
						segment[cursegment].state |= 2;
358
						break;
359
					}
360
				}
361
				if (i > 1)
362
				{
363
					int word_shift = 0;
364
					for (i = 1; i < sizeof(word) / sizeof(word[0]); i++)
365
					{
366
						word[i] += word_shift;
367
						if (wordlen[i] >= 4 && word[i][0] != '[' &&
368
							word[i][wordlen[i]-1] == ']' &&
369
							(s = strchr1(word[i], wordlen[i], '[')) != 0)
370
						{
371
							*s = '+';
372
							memmove(word[i] + 1, word[i], strlen(word[i]) + 1);
373
							word[i][0] = '[';
374
							wordlen[i]++;
375
							word_shift++;
376
						}
377
						else if (wordlen[i] >= 1 && !strchr1(word[i], wordlen[i], '[') &&
378
								strcmp1(word[i-1], wordlen[i-1], "ptr", -1) == 0)
379
						{
380
							memmove(word[i] + wordlen[i] + 2, word[i] + wordlen[i],
381
									strlen(word[i] + wordlen[i]) + 1);
382
							memmove(word[i] + 1, word[i], wordlen[i]);
383
							word[i][0] = '['; word[i][wordlen[i] + 1] = ']';
384
							wordlen[i] += 2;
385
							word_shift += 2;
386
						}
387
						else if (wordlen[i] >= 5 && word[i][wordlen[i]-1] == ')' &&
388
									 strcmp1(word[i], wordlen[i], "st(", -1))
389
						{
390
							memmove(word[i] + 2, word[i] + 3, wordlen[i] - 4);
391
							memmove(word[i] + wordlen[i] - 2, word[i] + wordlen[i],
392
									strlen(word[i] + wordlen[i]) + 1);
393
							word_shift -= 2;
394
						}
395
					}
396
					segment[cursegment].state |= 1;
397
				}
398
			}
399
		}
400
		if (in_macro) continue;
401
		if ((s = strchr(str, ';')) != NULL)
402
		{
403
			s[0] = '\n'; s[1] = 0;
404
			if (!first_not_space(str)[0]) continue;
405
		}
406
		segment[cursegment].text += str;
407
	}
408
	for (cursegment = 0; cursegment < nsegment; cursegment++)
409
	{
410
		if ((segment[cursegment].state & 3) != 2) outsegment();
411
	}
412
	fputs("\nI_END:\n", stdout);
413
	for (cursegment = 0; cursegment < nsegment; cursegment++)
414
	{
415
		if ((segment[cursegment].state & 3) == 2) outsegment();
416
	}
417
	fputs("\nalign 0x10\nU_END:\n", stdout);
418
	return 0;
419
}
420