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