comparison src/ploki/parse.c @ 4223:ac0403686959

<oerjan> rm -rf src/ploki; mv ploki src
author HackBot
date Fri, 20 Dec 2013 22:18:50 +0000
parents
children
comparison
equal deleted inserted replaced
4222:b0f3e267bb1e 4223:ac0403686959
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 }