4223
|
1 #include "IO.h"
|
|
2 #include "inc.h"
|
|
3 #include "main.h"
|
|
4 #include "main_label.h"
|
|
5 #include "mars.h"
|
|
6 #include "op.h"
|
|
7 #include "parse.h"
|
|
8 #include "text.h"
|
|
9 #include "venus.h"
|
|
10
|
|
11 #include <ctype.h>
|
|
12 #include <errno.h>
|
|
13 #include <stdio.h>
|
|
14 #include <stdlib.h>
|
|
15 #include <string.h>
|
|
16
|
|
17 static void skipline(IO *f) {
|
|
18 int c;
|
|
19
|
|
20 for (
|
|
21 c = io_peek(f, 0);
|
|
22 c != EOF && c != '\n';
|
|
23 c = io_peek(f, 0)
|
|
24 ) {
|
|
25 if (c == 'R' && io_cmppeek(f, 0, "REM", 3) == 0) {
|
|
26 io_read(f, NULL, 3);
|
|
27 skipline(f);
|
|
28 } else {
|
|
29 io_getc(f);
|
|
30 }
|
|
31 }
|
|
32 if (c == '\n') {
|
|
33 io_getc(f);
|
|
34 }
|
|
35 }
|
|
36
|
|
37 static IO *open_inc(const char *s, enum io_flags mode) {
|
|
38 size_t i;
|
|
39 String cur;
|
|
40
|
|
41 St_init(&cur);
|
|
42 for (i = 0; inc_ludes[i]; ++i) {
|
|
43 IO *tmp;
|
|
44
|
|
45 St_cpy_s(&cur, s);
|
|
46 St_tac_s(&cur, inc_ludes[i]);
|
|
47 if ((tmp = io_open(St_ptr(&cur), mode))) {
|
|
48 St_clear(&cur);
|
|
49 return tmp;
|
|
50 }
|
|
51 }
|
|
52 St_clear(&cur);
|
|
53
|
|
54 return NULL;
|
|
55 }
|
|
56
|
|
57 void parse(IO *f, struct text *text, size_t *line) {
|
|
58 int c;
|
|
59
|
|
60 while ((c = io_peek(f, 0)) != EOF) {
|
|
61 struct op node;
|
|
62 String label;
|
|
63 int is_static = 0;
|
|
64
|
|
65 for (
|
|
66 ;
|
|
67 c != EOF && c != '\n' && isspace(c);
|
|
68 c = io_peek(f, 0)
|
|
69 ) {
|
|
70 io_getc(f);
|
|
71 }
|
|
72 if (c == EOF) {
|
|
73 break;
|
|
74 }
|
|
75
|
|
76 if (io_cmppeek(f, 0, "INSERT", 6) == 0) {
|
|
77 size_t start;
|
|
78 size_t end;
|
|
79 String ifname;
|
|
80 IO *ifp;
|
|
81 int inc;
|
|
82
|
|
83 if (io_cmppeek(f, 6, " DA", 3) == 0) {
|
|
84 inc = 0;
|
|
85 start = 9;
|
|
86 } else {
|
|
87 inc = 1;
|
|
88 start = 6;
|
|
89 }
|
|
90
|
|
91 for (
|
|
92 ;
|
|
93 (c = io_peek(f, start)) != '\n' && isspace(c);
|
|
94 ++start
|
|
95 )
|
|
96 ;
|
|
97 if (c == '\n' || c == EOF) {
|
|
98 goto no_insert;
|
|
99 }
|
|
100 for (
|
|
101 end = start + 1;
|
|
102 (c = io_peek(f, end)) != '\n' && c != EOF;
|
|
103 ++end
|
|
104 )
|
|
105 ;
|
|
106 for (
|
|
107 ;
|
|
108 end > start && isspace(io_peek(f, end - 1));
|
|
109 --end
|
|
110 )
|
|
111 ;
|
|
112 if (io_cmppeek(f, end - 4, "HERE", 4)) {
|
|
113 goto no_insert;
|
|
114 }
|
|
115 for (
|
|
116 end -= 4;
|
|
117 isspace(io_peek(f, end - 1));
|
|
118 --end
|
|
119 )
|
|
120 ;
|
|
121 io_read(f, NULL, start);
|
|
122 St_init(&ifname);
|
|
123 if (end > start) {
|
|
124 io_read(f, &ifname, end - start);
|
|
125 }
|
|
126 if (!(ifp = (inc ? open_inc : io_open)(St_ptr(&ifname), IO_READ | IO_BUFFERED))) {
|
|
127 fprintf(stderr, "%s: %s: %s\n", Prog, St_ptr(&ifname), strerror(errno));
|
|
128 St_clear(&ifname);
|
|
129 exit(EXIT_FAILURE);
|
|
130 } else {
|
|
131 parse(ifp, text, line);
|
|
132 io_decr(ifp);
|
|
133 }
|
|
134 St_clear(&ifname);
|
|
135 io_getline(f, NULL);
|
|
136 continue;
|
|
137 }
|
|
138 no_insert:
|
|
139
|
|
140 op_init(&node);
|
|
141 node.line = *line;
|
|
142
|
|
143 St_init(&label);
|
|
144 if (io_cmppeek(f, 0, "FOR", 3) == 0) {
|
|
145 size_t p;
|
|
146 for (p = 3; (c = io_peek(f, p)) != '\n' && isspace(c); ++p)
|
|
147 ;
|
|
148 if (c != EOF && c != '\n') {
|
|
149 St_cat_c(&label, c);
|
|
150 for (++p; (c = io_peek(f, p)) != EOF && !isspace(c); ++p) {
|
|
151 St_cat_c(&label, c);
|
|
152 }
|
|
153 if (!ma_exists(&Mars, &label)) {
|
|
154 is_static = 1;
|
|
155 io_read(f, NULL, p);
|
|
156 } else {
|
|
157 St_zero(&label);
|
|
158 }
|
|
159 }
|
|
160 } else {
|
|
161 for (; (c = io_peek(f, 0)) == '0'; io_getc(f))
|
|
162 ;
|
|
163 for (; isdigit(c); c = io_peek(f, 0)) {
|
|
164 St_cat_c(&label, c);
|
|
165 io_getc(f);
|
|
166 }
|
|
167 }
|
|
168
|
|
169 for (
|
|
170 c = io_peek(f, 0);
|
|
171 c != EOF && c != '\n' && isspace(c);
|
|
172 c = io_peek(f, 0)
|
|
173 ) {
|
|
174 io_getc(f);
|
|
175 }
|
|
176
|
|
177 if (io_cmppeek(f, 0, "REM", 3) == 0) {
|
|
178 io_read(f, &node.txt, 3);
|
|
179 skipline(f);
|
|
180 } else {
|
|
181 size_t pos;
|
|
182
|
|
183 io_getline(f, &node.txt);
|
|
184 if ((pos = St_rstr_m(&node.txt, "?\?/\n", 4)) + 1u && pos + 4u == St_len(&node.txt)) {
|
|
185 String buf;
|
|
186 St_init(&buf);
|
|
187
|
|
188 do {
|
|
189 io_getline(f, &buf);
|
|
190 St_del(&node.txt, St_len(&node.txt) - 4u, 4);
|
|
191 St_cat(&node.txt, &buf);
|
|
192 } while ((pos = St_rstr_m(&node.txt, "?\?/\n", 4)) + 1u && pos + 4u == St_len(&node.txt));
|
|
193 St_clear(&buf);
|
|
194 }
|
|
195 }
|
|
196
|
|
197 {
|
|
198 struct op *tmp;
|
|
199 tmp = text_push(text, &node);
|
|
200 if (is_static) {
|
|
201 ma_enter(&Mars, &label, tmp);
|
|
202 } else {
|
|
203 ve_enter(&Venus, &label, tmp);
|
|
204 ++*line;
|
|
205 }
|
|
206 }
|
|
207 St_clear(&label);
|
|
208 }
|
|
209
|
|
210 }
|