]> ocean-lang.org Git - ocean/blob - csrc/indent_test.mdc
indent_test: fix makefile
[ocean] / csrc / indent_test.mdc
1 This parser is primarily for testing indent and linebreak handling.
2 It reads a very simple code fragment with if/else statements and
3 simple assignments with expressions, and then prints out the same
4 with complete bracketing and indenting.
5
6 # File: indent_test.mk
7         itestCFLAGS := -Wall -g -fplan9-extensions
8         itestLDLIBS:= libparser.o libscanner.o libmdcode.o -licuuc
9
10         all :: itest
11         itest.c itest.h : indent_test.mdc parsergen
12                 ./parsergen -o itest --LALR --tag indent indent_test.mdc
13         indent_test.mk: indent_test.mdc md2c
14                 ./md2c indent_test.mdc
15         itest: itest.c | $(filter %.o,$(itestLDLIBS))
16                 $(CC) $(itestCFLAGS) $^ $(itestLDLIBS) -o $@
17
18         doitest: itest itest.code
19                 ./itest itest.code
20         checkitest: itest itest.code
21                 @grep -v '^#' itest.out > .tmp.out
22                 @./itest itest.code | diff -u - .tmp.out || echo itest FAILED
23                 @sed -e 'i\
24                 ' itest.code > itest2.code
25                 @./itest itest2.code| diff -u - .tmp.out || echo itest2 FAILED
26         demos :: doitest
27         tests :: checkitest
28
29 # indent: header
30
31  ./parsergen -o itest --LALR indent_test.cgm
32  cc -o itest itest.c lib*.o -licuuc -lgmp
33  ./itest itest.code
34
35         struct expression {
36                 struct text op;
37                 struct expression *left, *right;
38         };
39         struct statement {
40                 struct statement *next;
41                 struct expression *expr;
42                 struct statement *thenpart;
43                 struct statement *elsepart;
44         };
45
46 # indent: code
47         #include <unistd.h>
48         #include <stdlib.h>
49         #include <fcntl.h>
50         #include <sys/mman.h>
51         #include <stdio.h>
52         #include "mdcode.h"
53         #include "scanner.h"
54         #include "parser.h"
55         #include "itest.h"
56
57         static void free_expression(struct expression *e)
58         {
59                 if (!e)
60                         return;
61                 free_expression(e->left);
62                 free_expression(e->right);
63                 free(e);
64         }
65
66         static void free_statement(struct statement *s)
67         {
68                 if (!s)
69                         return;
70                 free_statement(s->next);
71                 free_expression(s->expr);
72                 free_statement(s->thenpart);
73                 free_statement(s->elsepart);
74                 free(s);
75         }
76
77         static void print_expression(struct expression *e)
78         {
79                 if (e->left && e->right) printf("(");
80                 if (e->left)
81                         print_expression(e->left);
82                 if (e->op.len)
83                         printf("%.*s", e->op.len, e->op.txt);
84                 if (e->right)
85                         print_expression(e->right);
86                 if (e->left && e->right) printf(")");
87         }
88
89         static void print_statement(struct statement *s, int depth)
90         {
91                 if (!s)
92                         return;
93                 if (!s->thenpart) {
94                         printf("%*.s", depth, "");
95                         print_expression(s->expr);
96                         printf(";\n");
97                 } else {
98                         printf("%*.sif ", depth, "");
99                         print_expression(s->expr);
100                         printf(":\n");
101                         print_statement(s->thenpart, depth+4);
102                         if (s->elsepart) {
103                                 printf("%*.selse:\n", depth, "");
104                                 print_statement(s->elsepart, depth+4);
105                         }
106                 }
107                 print_statement(s->next, depth);
108         }
109
110         int main(int argc, char *argv[])
111         {
112                 int fd = open(argv[1], O_RDONLY);
113                 int len = lseek(fd, 0, 2);
114                 char *file = mmap(NULL, len, PROT_READ, MAP_SHARED, fd, 0);
115                 struct section *s = code_extract(file, file+len, NULL);
116                 struct token_config config = {
117                         .ignored = (1 << TK_line_comment)
118                                  | (1 << TK_block_comment),
119                         .number_chars = ".,_+-",
120                         .word_start = "",
121                         .word_cont = "",
122                 };
123                 parse_itest(s->code, &config, argc > 2 ? stderr : NULL);
124                 while (s) {
125                         struct section *t = s->next;
126                         code_free(s->code);
127                         free(s);
128                         s = t;
129                 }
130                 exit(0);
131         }
132
133 # indent: grammar
134
135 ~~~~~~
136
137 Program -> Statementlist ${ print_statement($1, 0); }$
138
139 $*statement
140         Newlines -> NEWLINE
141                 | Newlines NEWLINE
142         Statementlist ->  Statements ${ $0 = $<1; }$
143                 | Newlines Statements ${ $0 = $<2; }$
144
145         Statements -> Statements Statement ${
146                                 {
147                                         struct statement **s;
148                                         $0 = $<1;
149                                         s = &$0;
150                                         while (*s)
151                                                 s = &(*s)->next;
152                                         *s = $<2;
153                                 }
154                                 }$
155                         | Statement ${ $0 = $<1; }$
156                         | ERROR ${ printf("statement ERROR\n"); $0 = NULL; }$
157
158         Open -> {
159                 | Newlines {
160         Close -> }
161                 | Newlines }
162         Block -> Open Statementlist Close ${ $0 = $<2; }$
163                 | Open SimpleStatements } ${ $0 = $<2; }$
164                 | : SimpleStatements ${ $0 = $<2; }$
165                 | : StatementBlock ${ $0 = $<2; }$
166         StatementBlock -> Statementlist $$OUT ${ $0 = $<1; }$
167
168         SimpleStatements -> SimpleStatements ; SimpleStatement ${
169                         {
170                                 struct statement **s;
171                                 $0 = $<1;
172                                 s = &$0;
173                                 while (*s)
174                                         s = &(*s)->next;
175                                 *s = $<3;
176                         }
177                         }$
178                 | SimpleStatement ${ $0 = $<1; }$
179                 | SimpleStatements ; ${ $0 = $<1; }$
180
181         SimpleStatement -> Factor = Expression ${
182                         $0 = calloc(1, sizeof(struct statement));
183                         $0->expr = calloc(1, sizeof(struct expression));
184                         $0->expr->left = $<1;
185                         $0->expr->op = $2.txt;
186                         $0->expr->right = $<3;
187                         }$
188         SSline -> SimpleStatements NEWLINE ${ $0 = $<1; }$
189         Statement -> SSline ${ $0 = $<1; }$
190                 | IfStatement $$NEWLINE ${ $0 = $<1; }$
191                 | Statement NEWLINE ${ $0 = $<1; }$
192
193         $RIGHT else
194
195         IfHead -> if Expression Block ${
196                                 $0 = calloc(1, sizeof(struct statement));
197                                 $0->expr = $<2;
198                                 $0->thenpart = $<3;
199                                 }$
200                 | IfHead NEWLINE ${ $0 = $<1; }$
201
202         IfStatement -> IfHead $$else ${ $0 = $<1; }$
203                 | IfHead else Block ${
204                         $0 = $<1;
205                         $0->elsepart = $<3;
206                         }$
207                 | IfHead else IfStatement ${
208                         $0 = $<1;
209                         $0->elsepart = $<3;
210                         }$
211
212 $*expression
213         Expression -> Expression + Term ${
214                                 $0 = calloc(1, sizeof(struct expression));
215                                 $0->op = $2.txt;
216                                 $0->left = $<1;
217                                 $0->right = $<3;
218                         }$
219                     | Expression - Term ${
220                                 $0 = calloc(1, sizeof(struct expression));
221                                 $0->op = $2.txt;
222                                 $0->left = $<1;
223                                 $0->right = $<3;
224                         }$
225                     | Term ${ $0 = $<1; }$
226         Term -> Term * Factor ${
227                                 $0 = calloc(1, sizeof(struct expression));
228                                 $0->op = $2.txt;
229                                 $0->left = $<1;
230                                 $0->right = $<3;
231                         }$
232               | Term / Factor ${
233                                 $0 = calloc(1, sizeof(struct expression));
234                                 $0->op = $2.txt;
235                                 $0->left = $<1;
236                                 $0->right = $<3;
237                         }$
238               | Factor ${ $0 = $<1; }$
239         Factor -> IDENTIFIER ${
240                                 $0 = calloc(1, sizeof(struct expression));
241                                 $0->op = $1.txt;
242                         }$
243 ~~~~~~
244
245 # File: itest.code
246
247         # test code
248         ~~~~~~
249         hello = yes; mister = no;
250         there = x;
251         all = y;
252         if cond + cond2 :
253                 hello = x;
254                 hello2 = x;
255
256                 sum = val +
257                  val;
258
259                 if condX:
260                  foo = x *
261                     x +
262                     y
263                     / two;
264          else if cond2:
265                 there1 =x
266                 there1a=x
267         there2=x
268         there3=x;
269         all = y;
270         if true {yes=x;} else : no=x
271         if true: yes = no; no = yes;
272         if false: yes=ok; else: no=ok
273
274         if false {
275                 print = OK
276         } else {
277                 print = not_OK
278         }
279
280         if a:
281                 if b:
282                         c= d
283         x = y
284
285 # File: itest.out
286         (hello=yes);
287         (mister=no);
288         (there=x);
289         (all=y);
290         if (cond+cond2):
291             (hello=x);
292             (hello2=x);
293             (sum=(val+val));
294             if condX:
295                 (foo=((x*x)+(y/two)));
296         else:
297             if cond2:
298                 (there1=x);
299                 (there1a=x);
300         (there2=x);
301         (there3=x);
302         (all=y);
303         if true:
304             (yes=x);
305         else:
306             (no=x);
307         if true:
308             (yes=no);
309             (no=yes);
310         if false:
311             (yes=ok);
312         else:
313             (no=ok);
314         if false:
315             (print=OK);
316         else:
317             (print=not_OK);
318         if a:
319             if b:
320                 (c=d);
321         (x=y);