3 (* Compile a list of variant tags into CPP defines *)
5 (* hash_variant, from ctype.ml *)
9 for i = 0 to String.length s - 1 do
10 accu := 223 * !accu + Char.code s.[i]
12 (* reduce to 31 bits *)
13 accu := !accu land (1 lsl 31 - 1);
14 (* make it signed for 64 bits architectures *)
15 if !accu > 0x3FFFFFFF then !accu - (1 lsl 31) else !accu
19 let lexer = make_lexer ["type"; "public"; "exception"; "="; "["; "]"; "`"; "|"]
21 let exn_name = ref "invalid_argument"
23 let may_string = parser
31 let rec ident_list = parser
32 [< ' Kwd "`"; ' Ident x; trans = may_string; _ = may_bar; s >] ->
33 (x, trans) :: ident_list s
36 let may_public = parser
37 [< ' Kwd "public" >] -> true
42 let declaration = parser
43 [< ' Kwd "type"; public = may_public; ' Ident name; ' Kwd "=";
44 prefix = may_string; ' Kwd "["; _ = may_bar;
45 tags = ident_list; ' Kwd "]"; suffix = may_string >] ->
47 if trans <> "" then trans else
50 String.sub tag ~pos:1 ~len:(String.length tag -1)
54 if prefix = "" then None, ""
56 Some (prefix.[String.length prefix - 1]),
57 String.sub prefix ~pos:0 ~len:(String.length prefix - 1)
60 prefix ^ String.uncapitalize tag ^ suffix
62 prefix ^ String.uppercase tag ^ suffix
66 String.capitalize name
70 ~order:(fun (tag1,_) (tag2,_) -> hash_variant tag1 < hash_variant tag2)
72 printf "/* %s : conversion table */\n" name;
73 if not public then printf "static ";
74 printf "lookup_info ml_table_%s[] = {\n" name;
75 printf " { 0, %d },\n" (List.length tags);
77 begin fun (tag,trans) ->
78 printf " { MLTAG_%s, %s },\n" tag (ctag tag trans)
81 printf "#define Val_%s(data) ml_lookup_from_c (ml_table_%s, data)\n"
83 printf "#define %s_val(key) ml_lookup_to_c (ml_table_%s, key)\n\n"
85 | [< 'Kwd"exception"; 'Ident name >] ->
87 | [< >] -> raise End_of_file
90 let chars = Stream.of_channel stdin in
91 let s = lexer chars in
93 while true do declaration s done
94 with End_of_file -> ()
96 Printf.eprintf "Parsing error \"%s\" at character %d on input stream"
97 err (Stream.count chars)
99 let _ = Printexc.print main ()