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