Browse code

Basic implementation of structs

neauoire authored on 23/02/2021 19:10:49
Showing 2 changed files
... ...
@@ -22,14 +22,15 @@ typedef struct {
22 22
 } Program;
23 23
 
24 24
 typedef struct {
25
-	char name[64], keys[16][64];
26
-	Uint8 len, lens[16];
25
+	char name[64], params[16][64];
26
+	Uint8 len, length[16], size;
27 27
 } Macro;
28 28
 
29 29
 typedef struct {
30
-	Uint8 len;
30
+	Uint8 len, offset;
31 31
 	Uint16 addr;
32 32
 	char name[64];
33
+	Macro *macro;
33 34
 } Label;
34 35
 
35 36
 int macroslen;
... ...
@@ -49,10 +50,11 @@ char ops[][4] = {
49 50
 	"ADD", "SUB", "MUL", "DIV", "EQU", "NEQ", "GTH", "LTH"
50 51
 };
51 52
 
52
-int scmp(char *a, char *b) { int i = 0; while(a[i] == b[i]) if(!a[i++]) return 1; return 0; } /* string compare */
53
-int slen(char *s) { int i = 0; while(s[i] && s[++i]) ; return i; } /* string length */
54
-int sihx(char *s) { int i = 0; char c; while((c = s[i++])) if(!(c >= '0' && c <= '9') && !(c >= 'a' && c <= 'f') && !(c >= 'A' && c <= 'F')) return 0; return 1; } /* string is hexadecimal */
55
-int shex(char *s) { int n = 0, i = 0; char c; while((c = s[i++])) if(c >= '0' && c <= '9') n = n * 16 + (c - '0'); else if(c >= 'A' && c <= 'F') n = n * 16 + 10 + (c - 'A'); else if(c >= 'a' && c <= 'f') n = n * 16 + 10 + (c - 'a'); return n; } /* string to num */
53
+int   scin(char *s, char c) { int i = 0; while(s[i]) if(s[i++] == c) return i - 1; return -1; } /* string char index */
54
+int   scmp(char *a, char *b, int len) { int i = 0; while(a[i] == b[i] && i < len) if(!a[i++]) return 1; return 0; } /* string compare */
55
+int   slen(char *s) { int i = 0; while(s[i] && s[++i]) ; return i; } /* string length */
56
+int   sihx(char *s) { int i = 0; char c; while((c = s[i++])) if(!(c >= '0' && c <= '9') && !(c >= 'a' && c <= 'f') && !(c >= 'A' && c <= 'F')) return 0; return 1; } /* string is hexadecimal */
57
+int   shex(char *s) { int n = 0, i = 0; char c; while((c = s[i++])) if(c >= '0' && c <= '9') n = n * 16 + (c - '0'); else if(c >= 'A' && c <= 'F') n = n * 16 + 10 + (c - 'A'); else if(c >= 'a' && c <= 'f') n = n * 16 + 10 + (c - 'a'); return n; } /* string to num */
56 58
 char *scpy(char *src, char *dst, int len) { int i = 0; while((dst[i] = src[i]) && i < len - 2) i++; dst[i + 1] = '\0'; return dst; } /* string copy */
57 59
 
58 60
 #pragma mark - Helpers
... ...
@@ -83,21 +85,53 @@ findmacro(char *s)
83 85
 {
84 86
 	int i;
85 87
 	for(i = 0; i < macroslen; ++i)
86
-		if(scmp(macros[i].name, s))
88
+		if(scmp(macros[i].name, s, 64))
87 89
 			return &macros[i];
88 90
 	return NULL;
89 91
 }
90 92
 
91 93
 Label *
92
-findlabel(char *s)
94
+findlabelplain(char *s)
93 95
 {
94 96
 	int i;
95 97
 	for(i = 0; i < labelslen; ++i)
96
-		if(scmp(labels[i].name, s))
98
+		if(scmp(labels[i].name, s, 64))
97 99
 			return &labels[i];
98 100
 	return NULL;
99 101
 }
100 102
 
103
+Label *
104
+findlabelmacro(char *s)
105
+{
106
+	int i, o = 0, pti = scin(s, '.');
107
+	char name[64], param[64];
108
+	Label *l;
109
+	if(pti > 0) {
110
+		scpy(s, name, pti + 1);
111
+		scpy(s + pti + 1, param, 64);
112
+	} else
113
+		scpy(s, name, 64);
114
+	if(!(l = findlabelplain(name)) || !l->macro)
115
+		return NULL;
116
+	/* find macro offset */
117
+	for(i = 0; i < l->macro->len; ++i) {
118
+		if(scmp(l->macro->params[i], param, 64)) {
119
+			l->offset = o;
120
+			break;
121
+		}
122
+		o += l->macro->length[i];
123
+	}
124
+	return l;
125
+}
126
+
127
+Label *
128
+findlabel(char *s)
129
+{
130
+	if(scin(s, '.') > 0)
131
+		return findlabelmacro(s);
132
+	return findlabelplain(s);
133
+}
134
+
101 135
 Uint8
102 136
 findopcode(char *s)
103 137
 {
... ...
@@ -140,25 +174,27 @@ makemacro(char *name, FILE *f)
140 174
 	if(findopcode(name))
141 175
 		return error("Macro name is invalid", name);
142 176
 	m = &macros[macroslen++];
177
+	scpy(name, m->name, 64);
143 178
 	while(fscanf(f, "%s", wv)) {
144 179
 		if(wv[0] == '{')
145 180
 			continue;
146 181
 		if(wv[0] == '}')
147 182
 			break;
148 183
 		if(mode == 0)
149
-			scpy(wv, m->keys[m->len], 64);
184
+			scpy(wv, m->params[m->len], 64);
150 185
 		else {
151
-			m->lens[m->len] = shex(wv);
186
+			m->length[m->len] = shex(wv);
187
+			m->size += m->length[m->len];
152 188
 			m->len++;
153 189
 		}
154 190
 		mode = !mode;
155 191
 	}
156
-	printf("New macro: %s[%d items]\n", name, m->len);
192
+	printf("New macro: %s[%d:%d]\n", name, m->len, m->size);
157 193
 	return 1;
158 194
 }
159 195
 
160 196
 int
161
-makelabel(char *name, Uint16 addr, Uint8 len)
197
+makelabel(char *name, Uint16 addr, Uint8 len, Macro *m)
162 198
 {
163 199
 	Label *l;
164 200
 	if(findlabel(name))
... ...
@@ -171,6 +207,8 @@ makelabel(char *name, Uint16 addr, Uint8 len)
171 207
 	l->addr = addr;
172 208
 	l->len = len;
173 209
 	scpy(name, l->name, 64);
210
+	if(m)
211
+		l->macro = m;
174 212
 	printf("New label: %s, at 0x%02x[%d]\n", l->name, l->addr, l->len);
175 213
 	return 1;
176 214
 }
... ...
@@ -180,18 +218,23 @@ makeconst(char *id, FILE *f)
180 218
 {
181 219
 	char wv[64];
182 220
 	fscanf(f, "%s", wv);
183
-	return makelabel(id, shex(wv), 1);
221
+	return makelabel(id, shex(wv), 1, 0);
184 222
 }
185 223
 
186 224
 int
187 225
 makevariable(char *id, Uint16 *addr, FILE *f)
188 226
 {
189 227
 	char wv[64];
190
-	Uint8 origin;
228
+	Uint8 origin, len;
229
+	Macro *m = NULL;
191 230
 	fscanf(f, "%s", wv);
192 231
 	origin = *addr;
193
-	*addr += shex(wv);
194
-	return makelabel(id, origin, shex(wv));
232
+	if((m = findmacro(wv)))
233
+		len = m->size;
234
+	else
235
+		len = shex(wv);
236
+	*addr += len;
237
+	return makelabel(id, origin, len, m);
195 238
 }
196 239
 
197 240
 int
... ...
@@ -247,13 +290,14 @@ pass1(FILE *f)
247 290
 	int ccmnt = 0, cstrg = 0, cbits = 0;
248 291
 	Uint16 addr = 0;
249 292
 	char w[64];
293
+	printf("Pass 1\n");
250 294
 	while(fscanf(f, "%s", w) == 1) {
251 295
 		if(skipblock(w, &ccmnt, '(', ')')) continue;
252 296
 		if(skipstring(w, &cstrg, &addr)) continue;
253 297
 		if(skipblock(w, &cbits, '[', ']'))
254 298
 			addr += w[0] != '[' && w[0] != ']' ? 2 : 0;
255 299
 		else if(w[0] == '@') {
256
-			if(!makelabel(w + 1, addr, 0))
300
+			if(!makelabel(w + 1, addr, 0, NULL))
257 301
 				return error("Pass1 failed", w);
258 302
 		} else if(w[0] == ';') {
259 303
 			if(!makevariable(w + 1, &addr, f))
... ...
@@ -264,7 +308,7 @@ pass1(FILE *f)
264 308
 		} else if(w[0] == ':') {
265 309
 			if(!makeconst(w + 1, f))
266 310
 				return error("Pass1 failed", w);
267
-		} else if(findopcode(w) || scmp(w, "BRK"))
311
+		} else if(findopcode(w) || scmp(w, "BRK", 4))
268 312
 			addr += 1;
269 313
 		else {
270 314
 			switch(w[0]) {
... ...
@@ -289,6 +333,7 @@ pass2(FILE *f)
289 333
 {
290 334
 	int ccmnt = 0, cstrg = 0, cbits = 0, cmacro = 0;
291 335
 	char w[64];
336
+	printf("Pass 2\n");
292 337
 	while(fscanf(f, "%s", w) == 1) {
293 338
 		Uint8 op = 0;
294 339
 		Label *l;
... ...
@@ -300,7 +345,7 @@ pass2(FILE *f)
300 345
 		/* clang-format off */
301 346
 		if(skipblock(w, &cbits, '[', ']')) { if(w[0] != '[' && w[0] != ']') { pushshort(shex(w), 0); } }
302 347
 		else if(w[0] == '|') p.ptr = shex(w + 1);
303
-		else if((op = findopcode(w)) || scmp(w, "BRK")) pushbyte(op, 0);
348
+		else if((op = findopcode(w)) || scmp(w, "BRK", 4)) pushbyte(op, 0);
304 349
 		else if(w[0] == ':') fscanf(f, "%s", w);
305 350
 		else if(w[0] == ';') fscanf(f, "%s", w);
306 351
 		else if(w[0] == '.' && sihx(w + 1) && slen(w + 1) == 2) pushbyte(shex(w + 1), 0);
... ...
@@ -311,10 +356,12 @@ pass2(FILE *f)
311 356
 		else if(w[0] == '+' && sihx(w + 1) && slen(w + 1) == 4) pushshort((Sint16)shex(w + 1), 1);
312 357
 		else if(w[0] == '-' && sihx(w + 1) && slen(w + 1) == 2) pushbyte((Sint8)(shex(w + 1) * -1), 1);
313 358
 		else if(w[0] == '-' && sihx(w + 1) && slen(w + 1) == 4) pushshort((Sint16)(shex(w + 1) * -1), 1);
314
-		else if(w[0] == '=' && (l = findlabel(w + 1)) && l->len){ pushshort(l->addr, 1); pushbyte(findopcode(l->len == 2 ? "STR2" : "STR"),0); }
315
-		else if(w[0] == '~' && (l = findlabel(w + 1)) && l->len){ pushshort(l->addr, 1); pushbyte(findopcode(l->len == 2 ? "LDR2" : "LDR"),0); }
316
-		else if((l = findlabel(w + 1))) pushshort(l->addr, w[0] == ',');
317
-		else return error("Unknown label in second pass", w);
359
+		else if(w[0] == '=' && (l = findlabel(w + 1)) && l->len){ pushshort(l->addr + l->offset, 1); pushbyte(findopcode(l->len == 2 ? "STR2" : "STR"),0); }
360
+		else if(w[0] == '~' && (l = findlabel(w + 1)) && l->len){ pushshort(l->addr + l->offset, 1); pushbyte(findopcode(l->len == 2 ? "LDR2" : "LDR"),0); }
361
+		else if((l = findlabel(w + 1))) pushshort(l->addr + l->offset, w[0] == ',');
362
+		else {
363
+			return error("Unknown label in second pass", w);
364
+		}
318 365
 		/* clang-format on */
319 366
 	}
320 367
 	return 1;
... ...
@@ -3,28 +3,22 @@
3 3
 :dev/r fff8 ( std read port )
4 4
 :dev/w fff9 ( std write port )
5 5
 
6
-&point2d { x 2 y 2 }
7
-&point3d { x 2 y 2 z 2 }
6
+&Rect2d { x 2 y 2 width 2 height 2 }
8 7
 
9
-;position point2d
10
-;vertex point3d
8
+;rc1 Rect2d
11 9
 
12 10
 ( TODO )
13 11
 
14 12
 |0100 @RESET
15
-
16
-	,position:x #0002 STR2
17
-
18
-	~position:x
19
-
20
-	#02 =position:x
21
-
22
-	#abcd =vertex:x
13
+	
14
+	#abcd ,rc1.height STR2
15
+	,rc1.height LDR2
16
+	,rc1.height LDR2
23 17
 
24 18
 BRK
25 19
 
26 20
 |c000 @FRAME BRK 
27 21
 |d000 @ERROR BRK 
28 22
 
29
-|FFF0 [ f2ac 35bb 2b53 ] ( palette )
23
+|FFF0 [ 0f32 0f32 0f32 ] ( palette )
30 24
 |FFFA .RESET .FRAME .ERROR