1: #line 56 "./lpsrc/flx_docgen.ipk"
2: include "std";
3: include "flx_lex";
4: include "flx_token";
5: include "flx_grammar";
6:
7: open flx_token;
8: open flx_grammar;
9: open Text_file;
10:
11: use Lexer::sub;
12: use Lexer::eq;
13:
14: fun chop_directory (s:string)=
15: {
16: var i = len s - 1;
17: until i == -1 do
18: if s.[i] == "/".[0] do return s.[i+1 to]; done;
19: --i;
20: done;
21: return s;
22: }
23:
24: fun chop_extension (s:string)=
25: {
26: var i = len s - 1;
27: until i == -1 do
28: if s.[i] == ".".[0] do return s.[to i]; done;
29: --i;
30: done;
31: return s;
32: }
33:
34: keywords :=
35: ("all",TOK_ALL),
36: ("assert",TOK_ASSERT),
37: ("axiom",TOK_AXIOM),
38: ("body",TOK_BODY),
39: ("call",TOK_CALL),
40: ("case",TOK_CASE),
41: ("caseno",TOK_CASENO),
42: ("class",TOK_CLASS),
43: ("comment",TOK_COMMENT_KEYWORD),
44: ("compound",TOK_COMPOUND),
45: ("const",TOK_CONST),
46: ("cclass",TOK_CCLASS),
47: ("cstruct",TOK_CSTRUCT),
48: ("ctor",TOK_CTOR),
49: ("ctypes",TOK_CTYPES),
50: ("def",TOK_DEF),
51: ("do",TOK_DO),
52: ("done",TOK_DONE),
53: ("elif",TOK_ELIF),
54: ("else",TOK_ELSE),
55: ("endif",TOK_ENDIF),
56: ("endmatch",TOK_ENDMATCH),
57: ("enum",TOK_ENUM),
58: ("expect",TOK_EXPECT),
59: ("export",TOK_EXPORT),
60: ("for",TOK_FOR),
61: ("forget",TOK_FORGET),
62: ("fork",TOK_FORK),
63: ("functor",TOK_FUNCTOR),
64: ("fun",TOK_FUNCTION),
65: ("goto",TOK_GOTO),
66: ("header",TOK_HEADER),
67: ("ident",TOK_IDENT),
68: ("include",TOK_INCLUDE),
69: ("incomplete",TOK_INCOMPLETE),
70: ("inf",TOK_INF),
71: ("in",TOK_IN),
72: ("is",TOK_IS),
73: ("inherit",TOK_INHERIT),
74: ("inline",TOK_INLINE),
75: ("jump",TOK_JUMP),
76: ("let",TOK_LET),
77: ("loop",TOK_LOOP),
78: ("lval",TOK_LVAL),
79: ("macro",TOK_MACRO),
80: ("module",TOK_MODULE),
81: ("NaN",TOK_NAN),
82: ("new",TOK_NEW),
83: ("noinline",TOK_NOINLINE),
84: ("nonterm",TOK_NONTERM),
85: ("noreturn",TOK_NORETURN),
86: ("not",TOK_NOT),
87: ("obj",TOK_OBJECT),
88: ("open",TOK_OPEN),
89: ("package",TOK_PACKAGE),
90: ("pod",TOK_POD),
91: ("private",TOK_PRIVATE),
92: ("proc",TOK_PROCEDURE),
93: ("property",TOK_PROPERTY),
94: ("reduce",TOK_REDUCE),
95: ("rename",TOK_RENAME),
96: ("requires",TOK_REQUIRES),
97: ("return",TOK_RETURN),
98: ("struct",TOK_STRUCT),
99: ("then",TOK_THEN),
100: ("todo",TOK_TODO),
101: ("to",TOK_TO),
102: ("typedef",TOK_TYPEDEF),
103: ("type",TOK_TYPE),
104: ("union",TOK_UNION),
105: ("use",TOK_USE),
106: ("val",TOK_VAL),
107: ("var",TOK_VAR),
108: ("when",TOK_WHEN),
109: ("with",TOK_WITH),
110: ("_",TOK_UNDERSCORE),
111: ("_gc_pointer",TOK_GC_POINTER),
112: ("_gc_type",TOK_GC_TYPE),
113: ("_svc",TOK_SVC),
114: ("_deref",TOK_DEREF),
115: ("and",TOK_AND),
116: ("as",TOK_AS),
117: ("callback",TOK_CALLBACK),
118: ("code",TOK_CODE),
119: ("if",TOK_IF),
120: ("isin",TOK_ISIN),
121: ("match",TOK_MATCH),
122: ("noexpand",TOK_NOEXPAND),
123: ("of",TOK_OF),
124: ("or",TOK_OR),
125: ("parse",TOK_PARSE),
126: ("regexp",TOK_REGEXP),
127: ("reglex",TOK_REGLEX),
128: ("regmatch",TOK_REGMATCH),
129: ("the",TOK_THE),
130: ("typematch",TOK_TYPEMATCH),
131: #line 92 "./lpsrc/flx_docgen.ipk"
132: ("",TOK_EOF)
133: ;
134:
135: fun find_keyword(k:string) =
136: {
137: var i=0;
138: var key = keywords.[i];
139: until key.(0) == k or key.(0) == "" do
140: ++i;
141: key = keywords.[i];
142: done;
143: return key.(1);
144: }
145:
146: fun get_pretoken() =
147: {
148: open Flx_lex;
149: def var j, var des = pre_flx_lex (i1, i2);
150: match des with
151: | qQuote => { j,des = parse_q_string (j,i2); }
152: | qqqQuote => { j,des = parse_qqq_string (j,i2); }
153: | dQuote => { j,des = parse_d_string (j,i2); }
154: | dddQuote => { j,des = parse_ddd_string (j,i2); }
155: | rqQuote => { j,des = parse_rq_string (j,i2); }
156: | rqqqQuote => { j,des = parse_rqqq_string (j,i2); }
157: | rdQuote => { j,des = parse_rd_string (j,i2); }
158: | rdddQuote => { j,des = parse_rddd_string (j,i2); }
159: | Preprocessor => { j = to_eol(j,i2) - 1; }
160: | Cpp_comment => { j = to_eol(j,i2) - 1; }
161: | C_comment => { j = to_end_c_comment (j,i2); }
162: | _ => {}
163: endmatch;
164: lexeme := Lexer::string_between(i1,j);
165: i1 = j;
166: return
167: match des with
168: | Eol => TOK_EOF
169: | Ident =>
170: match find_keyword lexeme with
171: | TOK_EOF => TOK_NAME lexeme
172: | ?k => k
173: endmatch
174:
175:
176:
177:
178: | qQuote => TOK_STRING lexeme.[1 to -1]
179: | qqqQuote => TOK_STRING lexeme.[3 to -3]
180: | dQuote => TOK_STRING lexeme.[1 to -1]
181: | dddQuote => TOK_STRING lexeme.[3 to -3]
182:
183: | wqQuote => TOK_STRING lexeme.[1 to -1]
184: | wqqqQuote => TOK_STRING lexeme.[3 to -3]
185: | wdQuote => TOK_STRING lexeme.[1 to -1]
186: | wdddQuote => TOK_STRING lexeme.[3 to -3]
187:
188: | uqQuote => TOK_STRING lexeme.[1 to -1]
189: | uqqqQuote => TOK_STRING lexeme.[3 to -3]
190: | udQuote => TOK_STRING lexeme.[1 to -1]
191: | udddQuote => TOK_STRING lexeme.[1 to -1]
192:
193: | rqQuote => TOK_STRING lexeme.[1 to -1]
194: | rqqqQuote => TOK_STRING lexeme.[3 to -3]
195: | rdQuote => TOK_STRING lexeme.[1 to -1]
196: | rdddQuote => TOK_STRING lexeme.[3 to -3]
197:
198:
199: | DOLLAR => TOK_DOLLAR
200: | QUEST => TOK_QUEST
201: | EXCLAMATION => TOK_EXCLAMATION
202: | LPAR => TOK_LPAR
203: | RPAR => TOK_RPAR
204: | LSQB => TOK_LSQB
205: | RSQB => TOK_RSQB
206: | LBRACE => TOK_LBRACE
207: | RBRACE => TOK_RBRACE
208: | COLON => TOK_COLON
209: | COMMA => TOK_COMMA
210: | SEMI => TOK_SEMI
211: | PLUS => TOK_PLUS
212: | MINUS => TOK_MINUS
213: | STAR => TOK_STAR
214: | SLASH => TOK_SLASH
215: | VBAR => TOK_VBAR
216: | AMPER => TOK_AMPER
217: | LESS => TOK_LESS
218: | GREATER => TOK_GREATER
219: | EQUAL => TOK_EQUAL
220: | DOT => TOK_DOT
221: | PERCENT => TOK_PERCENT
222: | BACKQUOTE => TOK_BACKQUOTE
223: | TILDE => TOK_TILDE
224: | CIRCUMFLEX => TOK_CIRCUMFLEX
225: | HASH => TOK_HASH
226: | ANDLESS => TOK_ANDLESS
227: | ANDGREATER => TOK_ANDGREATER
228: | EQEQUAL => TOK_EQEQUAL
229: | NOTEQUAL => TOK_NOTEQUAL
230: | LESSEQUAL => TOK_LESSEQUAL
231: | GREATEREQUAL => TOK_GREATEREQUAL
232: | LEFTSHIFT => TOK_LEFTSHIFT
233: | RIGHTSHIFT => TOK_RIGHTSHIFT
234: | STARSTAR => TOK_STARSTAR
235: | LESSCOLON => TOK_LESSCOLON
236: | COLONGREATER => TOK_COLONGREATER
237: | DOTDOT => TOK_DOTDOT
238: | COLONCOLON => TOK_COLONCOLON
239: | PLUSPLUS => TOK_PLUSPLUS
240: | MINUSMINUS => TOK_MINUSMINUS
241: | PLUSEQUAL => TOK_PLUSEQUAL
242: | MINUSEQUAL => TOK_MINUSEQUAL
243: | STAREQUAL => TOK_STAREQUAL
244: | SLASHEQUAL => TOK_SLASHEQUAL
245: | PERCENTEQUAL => TOK_PERCENTEQUAL
246: | CARETEQUAL => TOK_CARETEQUAL
247: | VBAREQUAL => TOK_VBAREQUAL
248: | AMPEREQUAL => TOK_AMPEREQUAL
249: | TILDEEQUAL => TOK_TILDEEQUAL
250: | COLONEQUAL => TOK_COLONEQUAL
251: | RIGHTARROW => TOK_RIGHTARROW
252: | EQRIGHTARROW => TOK_EQRIGHTARROW
253: | LEFTARROW => TOK_LEFTARROW
254: | LSQANGLE => TOK_LSQANGLE
255: | RSQANGLE => TOK_RSQANGLE
256: | LSQBAR => TOK_LSQBAR
257: | RSQBAR => TOK_RSQBAR
258: | AMPERAMPER => TOK_AMPERAMPER
259: | VBARVBAR => TOK_VBARVBAR
260: | SLOSHAMPER => TOK_SLOSHAMPER
261: | SLOSHVBAR => TOK_SLOSHVBAR
262: | SLOSHCIRCUMFLEX => TOK_SLOSHCIRCUMFLEX
263: | HASHBANG => TOK_HASHBANG
264: | LEFTSHIFTEQUAL => TOK_LEFTSHIFTEQUAL
265: | RIGHTSHIFTEQUAL => TOK_RIGHTSHIFTEQUAL
266: | LEFTRIGHTARROW => TOK_LEFTRIGHTARROW
267: | ANDEQEQUAL => TOK_ANDEQEQUAL
268: | ANDNOTEQUAL => TOK_ANDNOTEQUAL
269: | ANDLESSEQUAL => TOK_ANDLESSEQUAL
270: | ANDGREATEREQUAL => TOK_ANDGREATEREQUAL
271: | DOTDOTDOT => TOK_DOTDOTDOT
272: | DOTRIGHTARROW => TOK_DOTRIGHTARROW
273: | LONGRIGHTARROW => TOK_LONGRIGHTARROW
274: | PARSE_ACTION => TOK_PARSE_ACTION
275: | HASHBANGSLASH => TOK_HASHBANGSLASH
276: #line 168 "./lpsrc/flx_docgen.ipk"
277: | Preprocessor => TOK_EOF
278: | Cpp_comment => TOK_EOF
279: | C_comment => TOK_EOF
280: | White => TOK_EOF
281:
282:
283: | Int => TOK_INTEGER (lexeme,"")
284: | Float => TOK_FLOAT lexeme
285: | _ => TOK_ERROR lexeme
286: endmatch
287: ;
288: }
289:
290: endmarker := caseno TOK_ENDMARKER;
291: eol := '\n';
292:
293: var eof = false;
294:
295: kfun := keywrd "fun ";
296: kproc := keywrd "proc ";
297: ktype := keywrd "type ";
298: kctype := keywrd "ctype ";
299:
300:
301: var outdir = "doc_out/";
302:
303: var i = 1;
304: var filename = System::argv 1;
305: if filename.[to 9] == "--outdir=" do
306: outdir = filename.[9 to];
307: ++i;
308: filename = System::argv i;
309: done;
310:
311:
312: C_hack::ignore(System::system("mkdir -p " + outdir));
313:
314:
315: mfile := outdir + "/index.html";
316: mf := fopen_output mfile;
317: writeln (mf, start_page "Felix Library");
318: writeln (mf,"<H1>"+outdir+"</H1>");
319:
320: until filename == "" do
321: handle_file filename;
322: ++i;
323: filename = System::argv i;
324: done;
325: writeln (mf,"</HTML></BODY>");
326: fclose mf;
327:
328: var data: string;
329: var i1:Lexer::iterator;
330: var i2:Lexer::iterator;
331:
332: proc handle_file(filename: string)
333: {
334: print "Filename "; print filename; endl;
335: data = load filename;
336: eof = false;
337:
338: i2 = Lexer::end_iterator data;
339: i1 = Lexer::start_iterator data;
340: var x =
341: parse the get_token with
342: | cu: flx_grammar::top => cu
343: endmatch
344: ;
345:
346: d :=
347: match x with
348: | case 1 => "Failure"
349: | case 2 _ => "Success"
350: endmatch
351: ;
352:
353: print d; endl;
354:
355: if caseno x == 0 return;
356:
357: statements :=
358: match x with
359: | case 2 ?cu =>
360: match cu with
361: | compilation_unit_1 ?sts => sts
362: endmatch
363: endmatch
364: ;
365:
366: basename := chop_extension (chop_directory filename);
367: fn := outdir+'/'+basename+'_flx.html';
368: f := fopen_output fn;
369: writeln (f, start_page basename);
370: writeln (f,"<H1>"+filename+"</H1>");
371: writeln (mf,
372: '<div class="toc_entry">'
373: (keywrd 'File ') '<A HREF="' basename '_flx.html">' filename '</A>'
374: '</div>'
375: );
376: handle_statements (f, statements);
377: writeln (f,"</HTML></BODY>");
378: fclose f;
379: }
380:
381: fun get_token(): flx_token_t =
382: {
383: retry:>
384: if i1 == i2 do
385: if eof do
386: return TOK_EOF;
387: else
388: eof = true;
389: return TOK_ENDMARKER;
390: done;
391: else
392: t := get_pretoken();
393: if caseno t == caseno TOK_EOF goto retry;
394: return t;
395: done;
396: }
397:
398:
399: fun start_page(title:string)=>
400: '<html>' eol
401: '<head>' eol
402: '<meta http-equiv="Content-Type" content="text/html; charset="utf-8">' eol
403: '<link rel="stylesheet" href="flxdoc_style.css" type="text/css">' eol
404: '<title>' title '</title>' eol
405: '</head>' eol
406: '<body>' eol
407: ;
408:
409: fun dcl (name:string) =>
410: '<span class="dcl">' name '</span>'
411: ;
412:
413: fun keywrd (kwd:string) =>
414: '<span class="keyword">' kwd '</span>'
415: ;
416:
417:
418: proc handle_statements (f:text_file, sts:statement_aster_t)
419: {
420: match sts with
421: | statement_aster_1 (?s,?sts) =>
422: {
423: handle_statement (f,s,"");
424: handle_statements (f,sts);
425: }
426:
427: | statement_aster_2 => {}
428: endmatch
429: ;
430: }
431:
432:
433: proc handle_statement (f:text_file, s:statement_t,desc:string) {
434: match s with
435: | statement_1 ?s =>
436: {
437: writeln(f,'<div class="topentry">');
438: handle_binding_definition (f,s,desc);
439: writeln(f,'</div>');
440: }
441: | statement_2 ?s =>
442: {
443: writeln(f,'<div class="topentry">');
444: handle_declarative (f,s,desc);
445: writeln(f,'</div>');
446: }
447: | statement_3 ?s => {}
448: | statement_4 ?s =>
449: let inclusion_1 ?s = s in
450: {
451: writeln(f,'<div class="topentry">');
452: writeln(f, keywrd "include "+ s);
453: writeln(f,'</div>');
454: }
455:
456:
457: | statement_5 ?s => { handle_directive (f,s); }
458: | statement_6 ?s => { handle_publish (f,s); }
459: | statement_7 ?s =>
460: let comment_1 ?s = s in
461: { writeln(f,'<div class="comment">' s '</div>'); }
462:
463: | statement_8 ?s => {}
464: endmatch;
465: }
466:
467: proc handle_publish(f:text_file, p:publish_t)
468: {
469: match p with
470: | publish_1 (?desc,?bd) =>
471: {
472: writeln(f,'<div class="topentry">');
473: handle_binding_definition (f,bd,desc);
474: writeln(f,'</div>');
475: }
476: | publish_2 (?desc,?dcl) =>
477: {
478: writeln(f,'<div class="topentry">');
479: handle_declarative (f,dcl,desc);
480: writeln(f,'</div>');
481: }
482: | publish_3 ?dcl => {}
483: | publish_4 ?bd => {}
484: endmatch;
485: }
486:
487: proc print_description (f:text_file,desc:string)
488: {
489: if desc != "" do
490: writeln(f,'<div class="desc">' desc "</div>");
491: done;
492: }
493:
494: proc handle_directive (f:text_file, t:directive_t)
495: {
496: match t with
497: | directive_1 _ => {}
498: | directive_2 _ => {}
499: | directive_3 ?r =>
500: {
501: writeln(f,'<div class="topentry">');
502: handle_regdef (f,r);
503: writeln(f,'</div>');
504: }
505: | directive_4 ?g =>
506: {
507: writeln(f,'<div class="topentry">');
508: handle_glr_production (f,g);
509: writeln(f,'</div>');
510: }
511: | directive_5 ?m => {}
512: endmatch;
513: }
514:
515: proc handle_glr_production(f:text_file, t:glr_production_t)
516: {
517: proc handle_glr_matching (g:glr_matching_t)
518: {
519: match g with
520: | glr_matching_1 (?ges,_) =>
521: {
522: writeln(f,
523: '<div class="subentry">' +
524: keywrd "| " +
525: str ges +
526: '</div>'
527: );
528: }
529: | glr_matching_2 _ =>
530: {
531: writeln(f,
532: '<div class="subentry">'
533: (keywrd "| ")
534: '<span class="desc">epsilon</span>'
535: '</div>'
536: );
537: }
538: endmatch;
539: }
540:
541: proc handle_glr_matchings (t:glr_matchings_t)
542: {
543: match t with
544: | glr_matchings_1 (?g,?gs) =>
545: {
546: handle_glr_matching g;
547: handle_glr_matchings gs;
548: }
549: | glr_matchings_2 ?g =>
550: {
551: handle_glr_matching g;
552: }
553: endmatch;
554: }
555:
556: match t with
557: | glr_production_1 (?nt, ?t,?ms) =>
558: {
559: writeln (f,keywrd "nonterm "+ dcl nt+' : ' + str t+" = ");
560: handle_glr_matchings ms;
561: }
562: endmatch;
563: }
564:
565: proc handle_regdef (f:text_file, t:regdef_t)
566: {
567: match t with
568: | regdef_1 (?name,?re) =>
569: {
570: writeln (f,keywrd "regexp "+ dcl name+' = ' + str re);
571: }
572: endmatch;
573: }
574:
575: proc handle_binding_definition (f:text_file, s:binding_definition_t, desc:string)
576: {
577: match s with
578: | binding_definition_1 ?s => { handle_abstract_type (f,s); }
579: | binding_definition_2 ?s => { handle_const_def (f,s); }
580: | binding_definition_3 ?s => { handle_binding_header (f,s); }
581: | binding_definition_4 ?s => { handle_export (f,s); }
582: endmatch;
583: print_description (f,desc);
584: }
585:
586: proc handle_export (f:text_file, t:export_statement_t)
587: {
588: match t with
589: | export_statement_1 (?sn,?s) =>
590: { writeln(f,keywrd "export fun " + str sn + " as " + dcl s); }
591:
592: | export_statement_2 (?sn,?s) =>
593: { writeln(f,keywrd "export proc " + str sn + " as " + dcl s); }
594:
595: | export_statement_3 (?t,?s) =>
596: { writeln(f,keywrd "export type " + "(" + str t + ") as " + dcl s); }
597: endmatch;
598: }
599:
600: proc handle_binding_header (f:text_file, t:binding_header_t)
601: {
602: match t with
603: | binding_header_1 (_,_) => {}
604: | binding_header_2 (_,_) => {}
605: | binding_header_3 (_,_) => {}
606: | binding_header_4 (_,_) => {}
607: | binding_header_5 (?name,?tvs,?h,_) =>
608: { writeln(f,keywrd "header " + dcl name + str tvs); }
609:
610: | binding_header_6 (?name,?tvs,?b,_) =>
611: { writeln(f,keywrd "body " + dcl name + str tvs); }
612:
613: | binding_header_7 _ => {}
614: | binding_header_8 _ => {}
615: endmatch;
616: }
617:
618: proc handle_const_def (f:text_file, t:const_def_t)
619: {
620: match t with
621: | const_def_1 (?name,?tvs,?typ,?ct,_) =>
622: { handle_const (f,name,tvs,typ); }
623:
624: | const_def_2 (?name,?tvs,?typ,_) =>
625: { handle_const (f,name,tvs,typ); }
626: endmatch;
627: }
628:
629:
630: proc handle_const (f:text_file, name:string, tvs:tvarlist_t, typ:type_expr_t)
631: {
632: writeln(f,keywrd "const " + dcl name + str tvs + " : " + str typ);
633: }
634:
635: proc handle_declarative (f:text_file, dcl:declarative_t, desc:string)
636: {
637: match dcl with
638: | declarative_1 ?fn => { handle_function_definition (f,fn); }
639: | declarative_2 ?o => { print "object"; endl; }
640: | declarative_3 ?p => { handle_procedure_definition (f,p); }
641: | declarative_4 ?m => { handle_module (f,m,desc); }
642: | declarative_5 ?u => { handle_union (f,u); }
643: | declarative_6 ?s => { handle_struct (f,s); }
644: | declarative_7 ?t => { handle_type_alias (f,t); }
645: endmatch;
646: print_description (f,desc);
647: }
648:
649: proc handle_type_alias (f:text_file, t:type_alias_t)
650: {
651: match t with
652: | type_alias_1 (?name, ?tvs,?typ) =>
653: { handle_typedef (f,name,tvs,typ); }
654:
655: | type_alias_2 (?name, ?tvs, ?args,?rt,?te) =>
656: { handle_typefun (f,name,tvs,args,rt,te); }
657:
658: | type_alias_3 (?name, ?tvs, ?qn) =>
659: { handle_rename(f,name,tvs,qn); }
660:
661: | type_alias_4 (?name,?tvs,?qn) =>
662: { handle_fun_rename(f,name,tvs,qn); }
663:
664: | type_alias_5 ?qn =>
665: { handle_inherit(f,qn); }
666:
667: endmatch;
668: }
669:
670: proc handle_typedef (f:text_file, name:string, tvs:tvarlist_t,typ:type_expr_t)
671: {
672: s := keywrd "typedef " + dcl name + str tvs + " = " + str typ;
673: writeln(f,s);
674: }
675:
676:
677:
678: proc handle_typefun (f:text_file, name:string, tvs:tvarlist_t, args:fun_args_t, rt:type_expr_t, typ:type_expr_t)
679: {
680: s := keywrd "typedef fun " + dcl name + str tvs + str args + " : " + str rt + " = " + str typ;
681: writeln(f,s);
682: }
683:
684: proc handle_rename (f:text_file, name:string, tvs:tvarlist_t, qn:qualified_name_t)
685: {
686: s := keywrd "rename " + dcl name + str tvs + " = " + str qn;
687: writeln(f,s);
688: }
689:
690: proc handle_fun_rename (f:text_file, name:string, tvs:tvarlist_t, qn:qualified_name_t)
691: {
692: s := keywrd "rename fun " + dcl name + str tvs + " = " + str qn;
693: writeln(f,s);
694: }
695:
696: proc handle_inherit (f:text_file, qn:qualified_name_t)
697: {
698: writeln(f,keywrd "inherit " + str qn);
699: }
700:
701: proc handle_union (f:text_file, t:union_decl_t)
702: {
703: match t with
704: | union_decl_1 (?name,?es) =>
705: {
706: writeln(f,keywrd "enum " + dcl name);
707: handle_enum_items (f,es);
708: }
709: | union_decl_2 (?name,?tvs,?sms) =>
710: {
711: writeln(f,keywrd "union " + dcl name+ str tvs);
712: handle_sum_items(f,sms);
713: }
714:
715: | union_decl_3 (?name,?tvs,?sms) =>
716: {
717: writeln(f,keywrd "union " + dcl name+str tvs);
718: handle_sum_items(f,sms);
719: }
720: endmatch;
721: }
722:
723: proc handle_struct (f:text_file, t:struct_decl_t)
724: {
725: match t with
726: | struct_decl_1 (?name,?tvs,?scs) =>
727: {
728: writeln(f,keywrd "struct " + dcl name+str tvs);
729: handle_struct_items(f,scs);
730: }
731:
732: | struct_decl_2 (?name,?tvs,?scs) =>
733: {
734: writeln(f,keywrd "struct " + dcl name+str tvs);
735: handle_struct_items(f,scs);
736: }
737:
738: | struct_decl_3 (?name,?scs) =>
739: {
740: writeln(f,keywrd "struct " + dcl name);
741: handle_struct_items(f,scs);
742: }
743: endmatch;
744: }
745:
746: proc handle_struct_items (f:text_file, t:struct_component_aster_t)
747: {
748: match t with
749: | struct_component_aster_1 (?e,?es) =>
750: {
751: handle_struct_item (f,e);
752: handle_struct_items(f,es);
753: }
754: | struct_component_aster_2 => {}
755: endmatch;
756: }
757:
758: proc handle_struct_item (f:text_file, t:struct_component_t)
759: {
760: match t with
761: | struct_component_1 (?s,?t) =>
762: {
763: writeln(f,
764: '<div class="subentry">' +
765: keywrd "var " + (dcl s)+" : "+str t +
766: '</div>'
767: );
768: }
769: endmatch;
770: }
771:
772: proc handle_enum_items (f:text_file, t:enum_items_t)
773: {
774: match t with
775: | enum_items_1 (?es,?e) =>
776: let enum_item_1 ?name = e in
777: {
778: handle_enum_items(f,es);
779: writeln(f,
780: '<div class="subentry">' +
781: keywrd "| " + (dcl name) +
782: '</div>'
783: );
784: }
785: | enum_items_2 ?e =>
786: let enum_item_1 ?name = e in
787: {
788: writeln(f,
789: '<div class="subentry">' +
790: keywrd "| " + (dcl name) +
791: '</div>'
792: );
793: }
794: endmatch;
795: }
796:
797: proc handle_sum_items (f:text_file, t:type_sum_items_t)
798: {
799: match t with
800: | type_sum_items_1 (?es,?e) =>
801: {
802: handle_sum_items(f,es);
803: handle_sum_item (f,e);
804: }
805: | type_sum_items_2 ?e =>
806: {
807: handle_sum_item (f,e);
808: }
809: endmatch;
810: }
811:
812: proc handle_sum_item(f:text_file, t:type_sum_item_t)
813: {
814: match t with
815: | type_sum_item_1 (?name,?typ) =>
816: {
817: writeln(f,
818: '<div class="subentry">' +
819: keywrd "| " + (dcl name)+" of " + str typ +
820: '</div>'
821: );
822: }
823:
824: | type_sum_item_2 ?name =>
825: {
826: writeln(f,
827: '<div class="subentry">' +
828: keywrd "| " + (dcl name) +
829: '</div>'
830: );
831: }
832: endmatch;
833: }
834:
835: proc handle_function_definition (f:text_file, t:function_definition_t)
836: {
837: match t with
838: | function_definition_1 (?adjs,?name,?tvs,?args,?ote,_) =>
839: { handle_felix_function (f,adjs,name,tvs,args,ote); }
840:
841: | function_definition_2 (?adjs,?name,?tvs,?args,?ote,_) =>
842: { handle_felix_function (f,adjs,name,tvs,args,ote); }
843:
844: | function_definition_3 (?adjs,?name,?tvs,?t,_,_,_) =>
845: { handle_primitive_function (f,adjs,name,tvs,t); }
846:
847: | function_definition_4 (?adjs,?name,?tvs,?t,_) =>
848: { handle_primitive_function (f,adjs,name,tvs,t); }
849: endmatch;
850: }
851:
852: proc handle_procedure_definition (f:text_file, t:procedure_definition_t)
853: {
854: match t with
855: | procedure_definition_1 (?name, ?tvs,?oargs,_) =>
856: let ?adjs = adjectives_2 in
857: { handle_felix_procedure (f,adjs,name,tvs,oargs); }
858:
859: | procedure_definition_2 (?adj,?name,?tvs,_) =>
860: let ?adjs = adjectives_1 (adj,adjectives_2) in
861: let ?oargs = opt_fun_args_2 in
862: { handle_felix_procedure (f,adjs,name,tvs,oargs); }
863:
864: | procedure_definition_3 (?name,?tvs,?t,_,_) =>
865: { handle_primitive_procedure (f,name,tvs,t); }
866:
867: endmatch;
868: }
869:
870: proc handle_felix_function
871: (
872: f:text_file,
873: adjs:adjectives_t,
874: name:string,
875: tvs:tvarlist_t,
876: args:fun_args_t,
877: ote:opt_type_expr_t
878: )
879: {
880: s:= kfun (str adjs) (dcl name) (str tvs) " : " (str args) (str ote);
881: writeln(f,s);
882: }
883:
884: proc handle_felix_procedure
885: (
886: f:text_file,
887: adjs:adjectives_t,
888: name:string,
889: tvs:tvarlist_t,
890: oargs:opt_fun_args_t
891: )
892: {
893: s:= kproc (str adjs) (dcl name) (str tvs) " : " (str oargs);
894: writeln(f,s);
895: }
896:
897: proc handle_primitive_function
898: (
899: f:text_file,
900: adjs:adjectives_t,
901: name:string,
902: tvs:tvarlist_t,
903: t:type_expr_t
904: )
905: {
906: s :=kfun (str adjs) (dcl name) (str tvs) " : " (str t);
907: writeln(f,s);
908: }
909:
910: proc handle_primitive_procedure
911: (
912: f:text_file,
913: name:string,
914: tvs:tvarlist_t,
915: t:type_expr_t
916: )
917: {
918: s := kproc (dcl name) (str tvs) " : " (str t);
919: writeln(f,s);
920: }
921:
922: proc handle_module (f:text_file, m:module_definition_t, desc:string)
923: {
924: (let module_definition_1 (?name, ?tvs,?sts) = m in
925: let compound_1 ?sts = sts in
926: {
927: s:= keywrd "module" " <A HREF=" name ".html>" name "</A>" (str tvs);
928: writeln(f,s);
929: g := fopen_output (outdir + '/'+name + ".html");
930: writeln(g,start_page name);
931: writeln(g,"<H1>Module " name (str tvs) "</H1>");
932: print_description (g,desc);
933: handle_statements (g,sts);
934: writeln(g,"</HTML></BODY>");
935: fclose g;
936: });
937: }
938:
939: proc handle_abstract_type (f:text_file, s: abstract_type_t)
940: {
941: match s with
942: | abstract_type_1 (?qs, ?bncl, ?rqs) =>
943: { handle_ctypes (f,qs,bncl); }
944:
945: | abstract_type_2 (?qs, ?name, ?tvl, ?ct,?rqs) =>
946: { handle_ctype (f,qs,name,tvl); }
947:
948: endmatch;
949: }
950:
951: proc handle_ctypes (f:text_file, qs:type_quals_t, bncl: basic_name_comma_list_t)
952: {
953: sqs := str qs;
954:
955: proc handle_inner_ctype (name:basic_name_t)
956: {
957: s := sqs " " kctype (dcl (str name));
958: writeln(f,s);
959: }
960:
961: proc handle_bncl(bncl: basic_name_comma_list_t)
962: {
963: match bncl with
964: | basic_name_comma_list_1 (?name,?bncl') =>
965: {
966: handle_inner_ctype name;
967: handle_bncl bncl';
968: }
969: | basic_name_comma_list_2 ?name =>
970: {
971: handle_inner_ctype name;
972: }
973: | basic_name_comma_list_3 => {}
974: endmatch;
975: }
976:
977: handle_bncl bncl;
978: }
979:
980: proc handle_ctype (f:text_file, qs:type_quals_t,name:string,tvl:tvarlist_t)
981: {
982: sqs := str qs;
983: s:= sqs " " ktype (dcl name) + (str tvl);
984: writeln(f,s);
985: }
986:
987: fun html(s:string):string =
988: {
989: var s' = "";
990: n := len s;
991: var i =0; until i == n do
992: ch := s.[i];
993: if ch == '<'.[0] do s' += '<';
994: elif ch == '>'.[0] do s' += '>';
995: elif ch == '&'.[0] do s' += '&';
996: else s' += ch;
997: done;
998: ++i;
999: done;
1000: return s';
1001: }
1002:
1003:
1004:
1005: fun str : expr_t -> string =
1006: | expr_1 (?p,?e1,?e2) => "let <pattern> = " + str e1 " in " + str e2
1007: | expr_2 ?r => let rvalue_1 ?l = r in str l
1008: ;
1009:
1010: fun str : lambda_t -> string =
1011: | lambda_1 ?t => str t
1012: | lambda_2 _ => "(fun ...)"
1013: | lambda_3 _ => "(fun ...)"
1014: | lambda_4 _ => "(fun ...)"
1015: | lambda_5 ?c => "{ ... }"
1016: ;
1017:
1018: fun str: dollar_apply_t -> string =
1019: | dollar_apply_1 (?a,?b) => (str a) " (" (str b) ")"
1020: | dollar_apply_2 ?x => str x
1021: ;
1022:
1023: fun str : tuple_t -> string =
1024: | tuple_1 (?o,?t) => str o + str t
1025: | tuple_2 ?o => str o
1026: ;
1027:
1028: fun str : tuple_suffix_t -> string =
1029: | tuple_suffix_1 (?o,?t) => ", " + str o + str t
1030: | tuple_suffix_2 ?o => ", " + str o
1031: ;
1032:
1033: fun str : or_condition_t -> string =
1034: | or_condition_1 (?s,?sl) => str s + " + " + str sl
1035: | or_condition_2 ?s => str s
1036: ;
1037:
1038: fun str : or_list_t -> string =
1039: | or_list_1 (?s,?sl) => str s + " + " + str sl
1040: | or_list_2 ?s => str s
1041: ;
1042:
1043: fun str : and_condition_t -> string =
1044: | and_condition_1 (?s,?sl) => str s + " + " + str sl
1045: | and_condition_2 ?s => str s
1046: ;
1047:
1048: fun str : and_list_t -> string =
1049: | and_list_1 (?s,?sl) => str s + " + " + str sl
1050: | and_list_2 ?s => str s
1051: ;
1052:
1053: fun str : not_condition_t -> string =
1054: | not_condition_1 (_,?a) => " not "+ str a
1055: | not_condition_2 ?a => str a
1056: ;
1057:
1058: fun str (t:comparison_t)=> 'comparison .. endcomparison';
1059:
1060: fun str: opt_type_expr_t -> string =
1061: | opt_type_expr_1 (?t,?e) => " : " + str t + " expect " + str e
1062: | opt_type_expr_2 ?t => " : " + str t
1063: | opt_type_expr_3 ?e => " exprect " + str e
1064: | opt_type_expr_4 => ""
1065: ;
1066:
1067: fun str (t: type_expr_t):string =>
1068: let type_expr_1 ?t = t in str t
1069: ;
1070:
1071: fun str : arrow_t -> string =
1072: | arrow_1 (?cl,?a) => str cl + " → "+str a
1073: | arrow_2 ?cl => str cl
1074: ;
1075:
1076: fun str : case_literal_t -> string =
1077: | case_literal_1 ?i => "case " + strint i
1078: | case_literal_2 (?i,?s) => "case " + strint i + str s
1079: | case_literal_3 ?s => str s
1080: ;
1081:
1082: fun str : sum_t -> string =
1083: | sum_1 (?s,?sl) => str s + " + " + str sl
1084: | sum_2 ?s => str s
1085: ;
1086:
1087: fun str : sum_list_t -> string =
1088: | sum_list_1 (?s,?sl) => str s + " + " + str sl
1089: | sum_list_2 ?s => str s
1090: ;
1091:
1092: fun str: subtraction_t -> string =
1093: | subtraction_1 (?s,?p) => str s + " - " + str p
1094: | subtraction_2 ?p => str p
1095: ;
1096:
1097: fun str : product_t -> string =
1098: | product_1 (?s,?sl) => str s + " * " + str sl
1099: | product_2 ?s => str s
1100: ;
1101:
1102: fun str : product_list_t -> string =
1103: | product_list_1 (?s,?sl) => str s + " * " + str sl
1104: | product_list_2 ?s => str s
1105: ;
1106:
1107: fun str : term_t -> string =
1108: | term_1 (?t,?p) => str t + " / " + str p
1109: | term_2 (?t,?p) => str t + " % " + str p
1110: | term_3 ?pr => str pr
1111: ;
1112:
1113: fun str : power_t -> string =
1114: | power_1( ?ss, ?pr) => str ss + " ** " + str pr
1115: | power_2 ?ss => str ss
1116: ;
1117:
1118: fun str : prefixed_t -> string =
1119: | prefixed_1 ?p => "lvalue[" + str p + "]"
1120: | prefixed_2 ?p => "+"+str p
1121: | prefixed_3 ?p => "-"+str p
1122: | prefixed_4 ?p => "~"+str p
1123: | prefixed_5 ?p => str p
1124: ;
1125:
1126: fun str : superscript_t -> string =
1127: | superscript_1 (?s,?r) => str s + " ^ " + str r
1128: | superscript_2 ?r => str r
1129: ;
1130:
1131: fun str : refr_t -> string =
1132: | refr_1 ?r => "&" + str r
1133: | refr_2 ?r => "*" + str r
1134: | refr_3 ?a => str a
1135: ;
1136:
1137: fun str : application_t -> string =
1138: | application_1 (?a,?c) => str a + " " + str c
1139: | application_2 ?c => "caseno " + str c
1140: | application_3 ?c => str c
1141: ;
1142:
1143: fun str : coercion_t -> string =
1144: | coercion_1 (?c,?f) => str c + " : " + str f
1145: | coercion_2 ?sn => str sn
1146: | coercion_3 ?f => str f
1147: ;
1148:
1149:
1150: fun str : factor_t -> string =
1151: | factor_1 ?dn => str dn
1152: | factor_2 (?f,?e) => str f + ".["+str e+"]"
1153: | factor_3 (?f,?e1,?e2) => str f + ".["+str e1+" to "+str e2+"]"
1154: | factor_4 (?f,?e) => str f + ".["+str e+" to]"
1155: | factor_5 (?f,?e) =>str f + ".[to "+str e+"]"
1156: | factor_6 (?f,?s) => str f + "." + str s
1157: | factor_7 (?f,(?s1,?s2)) => str f ".(" + s1+s2+")"
1158: ;
1159:
1160: fun str : dollar_name_t -> string =
1161: | dollar_name_1 ?qn => "$" + str qn
1162: | dollar_name_2 ?qn => "the " + str qn
1163: | dollar_name_3 ?qn => str qn
1164: | dollar_name_4 ?atom => str atom
1165: ;
1166:
1167: fun str: qualified_name_t -> string =
1168: | qualified_name_1 (?qn,?snp) => str qn + "::" + str snp
1169: | qualified_name_2 ?snp => str snp
1170: ;
1171:
1172: fun str : simple_name_parts_t -> string =
1173: | simple_name_parts_1 (?s,?ts) => s + "[" + str ts + "]"
1174: | simple_name_parts_2 ?s => s
1175: ;
1176:
1177: /*
1178: fun str : type_expr_comma_list_t -> string =
1179: | type_expr_comma_list_1 (?t,?ts) => str t + ", " + str ts
1180: | type_expr_comma_list_2 ?t => str t
1181: | type_expr_comma_list_3 => ""
1182: ;
1183: */
1184:
1185: fun str : suffixed_name_t -> string =
1186: | suffixed_name_1 (?qn,?t) => str qn + " of (" + str t + ")"
1187: ;
1188:
1189: fun str : atom_t -> string =
1190: | atom_1 => "..."
1191: | atom_2 _ => "typematch .. endmatch"
1192: | atom_3 (?e,?s) => "code["+str e + "] "+s
1193: | atom_4 (?e,?s) => "code["+str e + "] "+str s
1194: | atom_5 ?e => "["+str e+"]"
1195: | atom_6 ?e => "{"+str e+"]"
1196: | atom_7 _ => "parse .. endmatch"
1197: | atom_8 _ => "match .. endmatch"
1198: | atom_9 _ => "regmatch .. endmatch"
1199: | atom_10 _ => "{ ... }"
1200: | atom_11 ?e => "("+str e+")"
1201: | atom_12 => "()"
1202: | atom_13 ?e => str e
1203: | atom_14 _ => "if .. endif"
1204: ;
1205:
1206: fun str (t:expr_code_prefix_t):string =>
1207: let expr_code_prefix_1 ?e = t in str e
1208: ;
1209:
1210: fun str : literal_t -> string =
1211: | literal_1 (?s1,?s2) => s1 + s2
1212: | literal_2 ?s => s
1213: | literal_3 ?s => str s
1214: | literal_4 ?s => "c"+str s
1215: ;
1216:
1217: fun str (s:string):string => '"' + s '"';
1218:
1219: fun strint(i:string * string):string =>
1220: let ?i,?j = i in i+j
1221: ;
1222:
1223: fun str: opt_fun_args_t -> string =
1224: | opt_fun_args_1 ?a => str a
1225: | opt_fun_args_2 => "()"
1226: ;
1227:
1228: fun str: fun_args_t -> string =
1229: | fun_args_1 (?a,?args) => "(" (str a) ") → " + str args
1230: | fun_args_2 ?a => str a
1231: ;
1232:
1233: fun str: fun_arg_t -> string =
1234: | fun_arg_1 (?ps,?traint) => str ps + " when " + str traint
1235: | fun_arg_2 ?ps => str ps
1236: | fun_arg_3 ?s => s
1237: ;
1238:
1239: fun str: parameter_comma_list_t -> string =
1240: | parameter_comma_list_1 (?a,?ps) => str a + " * " + str ps
1241: | parameter_comma_list_2 ?p => str p
1242: | parameter_comma_list_3 => ""
1243: ;
1244:
1245: fun str: parameter_t -> string =
1246: | parameter_1 (?name,?t) => str t
1247: | parameter_2 ?name => "'" + name
1248: | parameter_3 (?name,?t) => "var " + str t
1249: | parameter_4 ?name => "var " + "'" + name
1250: ;
1251:
1252: fun str: type_qual_t -> string =
1253: | type_qual_1 => "incomplete "
1254: | type_qual_2 => "pod "
1255: ;
1256:
1257: fun str: type_quals_t -> string =
1258: | type_quals_1 (?q,?qs') => str q + str qs'
1259: | type_quals_2 => ""
1260: ;
1261:
1262: fun str (name:basic_name_t): string =>
1263: let basic_name_1 ?name = name in name
1264: ;
1265:
1266: fun str : basic_name_comma_list_t -> string =
1267: | basic_name_comma_list_1 (?name,?bncl) =>
1268: str name + ", " + str bncl
1269: | basic_name_comma_list_2 ?name => str name
1270: | basic_name_comma_list_3 => ""
1271: ;
1272:
1273: fun str : tvar_t -> string =
1274: | tvar_1 ?s => s
1275: | tvar_2 (?s,_) => s
1276: ;
1277:
1278: fun str : tvar_comma_list_t -> string =
1279: | tvar_comma_list_1 (?name,?bncl) =>
1280: str name + ", " + str bncl
1281: | tvar_comma_list_2 ?name => str name
1282: | tvar_comma_list_3 => ""
1283: ;
1284:
1285: fun str : tvarlist_t -> string =
1286: | tvarlist_1 ?bncl => "[" + str bncl + "]"
1287: | tvarlist_2 => ""
1288: ;
1289:
1290: fun str : adjectives_t -> string =
1291: | adjectives_1 (?adj,?adjs) => str adj + str adjs
1292: | adjectives_2 => ""
1293: ;
1294:
1295: fun str : adjective_t -> string =
1296: | adjective_1 => "inline "
1297: | adjective_2 => "noinline "
1298: ;
1299:
1300:
1301: fun str : re1_t -> string =
1302: | re1_1 (?r1,?r2) => str r1 + " | " + str r2
1303: | re1_2 ?r => str r
1304: ;
1305:
1306: fun str : re2_t -> string =
1307: | re2_1 (?r1,?r2) => str r1 + " " + str r2
1308: | re2_2 ?r => str r
1309: ;
1310:
1311: fun str : re3_t -> string =
1312: | re3_1 ?r => str r + "*"
1313: | re3_2 ?r => str r + "+"
1314: | re3_3 ?r => str r + "?"
1315: | re3_4 ?r => str r
1316: ;
1317:
1318: fun str : re4_t -> string =
1319: | re4_1 ?s => str s
1320: | re4_2 => '_'
1321: | re4_3 => '.'
1322: | re4_4 ?r => '(' + str r + ")"
1323: | re4_5 ?cs => '[' + str cs + ']'
1324: | re4_6 ?cs => '[^' + str cs + ']'
1325: | re4_7 ?name => str name
1326: ;
1327:
1328: fun str : re_name_t -> string =
1329: | re_name_1 (?r,?s) => str r + "::" + str s
1330: | re_name_2 ?s => s
1331: ;
1332:
1333: fun str: charset_t -> string =
1334: | charset_1 (?cs,?cs0) => str cs + " " + str cs0
1335: | charset_2 ?cs0 => str cs0
1336: ;
1337:
1338: fun str: charset0_t -> string =
1339: | charset0_1 (?i1,?i2) => strint i1 + " - " + strint i2
1340: | charset0_2 (?s1,?s2) => str s1 + " - " + str s2
1341: | charset0_3 ?s => str s
1342: | charset0_4 ?i => strint i
1343: ;
1344:
1345: fun str: glr_entries_t -> string =
1346: | glr_entries_1 (?g,?gs) => str g + " " + str gs
1347: | glr_entries_2 ?g => str g
1348: ;
1349:
1350: fun str: glr_entry_t -> string =
1351: | glr_entry_1 (?name,?nt) => name + " : " + str nt
1352: | glr_entry_2 ?qn => str qn
1353: ;
1354:
1355: fun str: glr_term_t -> string =
1356: | glr_term_1 ?qn => str qn
1357: | glr_term_2 ?alts => "(" + "..." + "}"
1358: | glr_term_3 ?seq => "(" + "..." + ")"
1359: | glr_term_4 ?quest => "(" + str quest+ ")?"
1360: | glr_term_5 ?star => "(" + str star + ")*"
1361: | glr_term_6 ?plus => "(" + str plus + ")+"
1362: ;
1363: