Browse code

Progress on macros

neauoire authored on 23/02/2021 06:15:02
Showing 5 changed files
... ...
@@ -29,6 +29,7 @@ evaluxn(u, u->vframe); /* Each frame
29 29
 - `@label`, assign the current address to a label.
30 30
 - `;variable 2`, assign an address to a label automatically.
31 31
 - `:const 1a2b`, assign an address to a label manually.
32
+- `&macro { x 2 y 2 }`, define a macro named `macro`.
32 33
 
33 34
 ### Write
34 35
 
... ...
@@ -21,14 +21,23 @@ typedef struct {
21 21
 	Uint8 data[65536];
22 22
 } Program;
23 23
 
24
+typedef struct {
25
+	char name[64], keys[16][64];
26
+	Uint8 len, lens[16];
27
+} Macro;
28
+
24 29
 typedef struct {
25 30
 	Uint8 len;
26 31
 	Uint16 addr;
27 32
 	char name[64];
28 33
 } Label;
29 34
 
35
+int macroslen;
36
+Macro macros[256];
37
+
30 38
 int labelslen;
31 39
 Label labels[256];
40
+
32 41
 Program p;
33 42
 
34 43
 /* clang-format off */
... ...
@@ -69,6 +78,16 @@ pushshort(Uint16 s, int lit)
69 78
 	pushbyte(s & 0xff, 0);
70 79
 }
71 80
 
81
+Macro *
82
+findmacro(char *s)
83
+{
84
+	int i;
85
+	for(i = 0; i < macroslen; ++i)
86
+		if(scmp(macros[i].name, s))
87
+			return &macros[i];
88
+	return NULL;
89
+}
90
+
72 91
 Label *
73 92
 findlabel(char *s)
74 93
 {
... ...
@@ -108,6 +127,36 @@ error(char *name, char *id)
108 127
 	return 0;
109 128
 }
110 129
 
130
+int
131
+makemacro(char *name, FILE *f)
132
+{
133
+	Uint8 mode = 0;
134
+	Macro *m;
135
+	char wv[64];
136
+	if(findmacro(name))
137
+		return error("Macro duplicate", name);
138
+	if(sihx(name))
139
+		return error("Macro name is hex number", name);
140
+	if(findopcode(name))
141
+		return error("Macro name is invalid", name);
142
+	m = &macros[macroslen++];
143
+	while(fscanf(f, "%s", wv)) {
144
+		if(wv[0] == '{')
145
+			continue;
146
+		if(wv[0] == '}')
147
+			break;
148
+		if(mode == 0)
149
+			scpy(wv, m->keys[m->len], 64);
150
+		else {
151
+			m->lens[m->len] = shex(wv);
152
+			m->len++;
153
+		}
154
+		mode = !mode;
155
+	}
156
+	printf("New macro: %s[%d items]\n", name, m->len);
157
+	return 1;
158
+}
159
+
111 160
 int
112 161
 makelabel(char *name, Uint16 addr, Uint8 len)
113 162
 {
... ...
@@ -140,33 +189,19 @@ makevariable(char *id, Uint16 *addr, FILE *f)
140 189
 	char wv[64];
141 190
 	Uint8 origin;
142 191
 	fscanf(f, "%s", wv);
143
-	if(!sihx(wv))
144
-		return error("Variable value is invalid", wv);
145 192
 	origin = *addr;
146 193
 	*addr += shex(wv);
147 194
 	return makelabel(id, origin, shex(wv));
148 195
 }
149 196
 
150 197
 int
151
-skipcomment(char *w, int *cap)
152
-{
153
-	if(w[0] == ')') {
154
-		*cap = 0;
155
-		return 1;
156
-	}
157
-	if(w[0] == '(') *cap = 1;
158
-	if(*cap) return 1;
159
-	return 0;
160
-}
161
-
162
-int
163
-skipbinary(char *w, int *cap)
198
+skipblock(char *w, int *cap, char a, char b)
164 199
 {
165
-	if(w[0] == ']') {
200
+	if(w[0] == b) {
166 201
 		*cap = 0;
167 202
 		return 1;
168 203
 	}
169
-	if(w[0] == '[') *cap = 1;
204
+	if(w[0] == a) *cap = 1;
170 205
 	if(*cap) return 1;
171 206
 	return 0;
172 207
 }
... ...
@@ -213,9 +248,9 @@ pass1(FILE *f)
213 248
 	Uint16 addr = 0;
214 249
 	char w[64];
215 250
 	while(fscanf(f, "%s", w) == 1) {
216
-		if(skipcomment(w, &ccmnt)) continue;
251
+		if(skipblock(w, &ccmnt, '(', ')')) continue;
217 252
 		if(skipstring(w, &cstrg, &addr)) continue;
218
-		if(skipbinary(w, &cbits))
253
+		if(skipblock(w, &cbits, '[', ']'))
219 254
 			addr += w[0] != '[' && w[0] != ']' ? 2 : 0;
220 255
 		else if(w[0] == '@') {
221 256
 			if(!makelabel(w + 1, addr, 0))
... ...
@@ -223,6 +258,9 @@ pass1(FILE *f)
223 258
 		} else if(w[0] == ';') {
224 259
 			if(!makevariable(w + 1, &addr, f))
225 260
 				return error("Pass1 failed", w);
261
+		} else if(w[0] == '&') {
262
+			if(!makemacro(w + 1, f))
263
+				return error("Pass1 failed", w);
226 264
 		} else if(w[0] == ':') {
227 265
 			if(!makeconst(w + 1, f))
228 266
 				return error("Pass1 failed", w);
... ...
@@ -249,16 +287,18 @@ pass1(FILE *f)
249 287
 int
250 288
 pass2(FILE *f)
251 289
 {
252
-	int ccmnt = 0, cstrg = 0, cbits = 0;
290
+	int ccmnt = 0, cstrg = 0, cbits = 0, cmacro = 0;
253 291
 	char w[64];
254 292
 	while(fscanf(f, "%s", w) == 1) {
255 293
 		Uint8 op = 0;
256 294
 		Label *l;
257 295
 		if(w[0] == '@') continue;
258
-		if(skipcomment(w, &ccmnt)) continue;
296
+		if(w[0] == '&') continue;
297
+		if(skipblock(w, &ccmnt, '(', ')')) continue;
298
+		if(skipblock(w, &cmacro, '{', '}')) continue;
259 299
 		if(capturestring(w, &cstrg)) continue;
260 300
 		/* clang-format off */
261
-		if(skipbinary(w, &cbits)) { if(w[0] != '[' && w[0] != ']') { pushshort(shex(w), 0); } }
301
+		if(skipblock(w, &cbits, '[', ']')) { if(w[0] != '[' && w[0] != ']') { pushshort(shex(w), 0); } }
262 302
 		else if(w[0] == '|') p.ptr = shex(w + 1);
263 303
 		else if((op = findopcode(w)) || scmp(w, "BRK")) pushbyte(op, 0);
264 304
 		else if(w[0] == ':') fscanf(f, "%s", w);
... ...
@@ -21,12 +21,21 @@ contexts:
21 21
     - match: '\|(\S+)\s?'
22 22
       scope: punctuation.definition
23 23
       pop: true
24
+    - match: '\_(\S+)\s?'
25
+      scope: punctuation.definition
26
+      pop: true
24 27
     - match: '\+(\S+)\s?'
25 28
       scope: keyword.control
26 29
       pop: true
27 30
     - match: '\-(\S+)\s?'
28 31
       scope: keyword.control
29 32
       pop: true
33
+    - match: '\~(\S+)\s?'
34
+      scope: keyword.control
35
+      pop: true
36
+    - match: '\=(\S+)\s?'
37
+      scope: keyword.control
38
+      pop: true
30 39
 
31 40
   strings:
32 41
     - match: '\:(\S+)\s?'
... ...
@@ -38,6 +47,9 @@ contexts:
38 47
     - match: '\@(\S+)\s?'
39 48
       scope: string.control
40 49
       pop: true
50
+    - match: '\&(\S+)\s?'
51
+      scope: string.control
52
+      pop: true
41 53
     - match: '\,(\S+)\s?'
42 54
       scope: keyword.control
43 55
       pop: true
... ...
@@ -50,11 +62,17 @@ contexts:
50 62
     - match: '\"(\S+)\s?'
51 63
       scope: keyword.control
52 64
       pop: true
65
+    - match: '\['
66
+      scope: punctuation.definition.keyword.usm
67
+      push:
68
+        - meta_scope: keyword.line.double-slash.usm
69
+        - match: '\]'
70
+          pop: true
53 71
 
54 72
   comments:
55 73
     - match: '\('
56
-      scope: punctuation.definition.comment.tome
74
+      scope: punctuation.definition.comment.usm
57 75
       push:
58
-        - meta_scope: comment.line.double-slash.tome
76
+        - meta_scope: comment.line.double-slash.usm
59 77
         - match: '\)'
60 78
           pop: true
61 79
new file mode 100644
... ...
@@ -0,0 +1,30 @@
1
+( blank )
2
+
3
+:dev/r fff8 ( std read port )
4
+:dev/w fff9 ( std write port )
5
+
6
+&point2d { x 2 y 2 }
7
+&point3d { x 2 y 2 z 2 }
8
+
9
+;position point2d
10
+;vertex point3d
11
+
12
+( TODO )
13
+
14
+|0100 @RESET
15
+
16
+	,position:x #0002 STR2
17
+
18
+	~position:x
19
+
20
+	#02 =position:x
21
+
22
+	#abcd =vertex:x
23
+
24
+BRK
25
+
26
+|c000 @FRAME BRK 
27
+|d000 @ERROR BRK 
28
+
29
+|FFF0 [ f2ac 35bb 2b53 ] ( palette )
30
+|FFFA .RESET .FRAME .ERROR
... ...
@@ -3,7 +3,7 @@
3 3
 :dev/r fff8 ( std read port )
4 4
 :dev/w fff9 ( std write port )
5 5
 
6
-( window ) ;wx1 2 ;wy1 2 ;wx2 2 ;wy2 2 
6
+( window )  ;wx1 2 ;wy1 2 ;wx2 2 ;wy2 2 
7 7
 ( drawing ) ;color 1 ;x1 2 ;x2 2 ;y1 2 ;y2 2
8 8
 ( mouse )   ;mousex 2 ;mousey 2 ;state 1
9 9