3 # Copyright © 2021, 2023 Nick Bowler
5 # Generate a function to return the C keyword corresponding to a specifier
6 # type as a string, for internal use by the output routines.
8 # License WTFPL2: Do What The Fuck You Want To Public License, version 2.
9 # This is free software: you are free to do what the fuck you want to.
10 # There is NO WARRANTY, to the extent permitted by law.
15 print " * Automatically generated by gen-specstr.awk from " FILENAME;
17 print " * Automatically generated by gen-specstr.awk";
19 print " * Do not edit.";
24 kinds["TYPE"] = kinds["STOR"] = kinds["QUAL"] = kinds["FUNC"] = 1;
28 # Locate all the relevant identifiers in cdecl.h. We assume everything
29 # is in numerically increasing order within the various enums.
31 sub(/[^ABCDEFGHIJKLMNOPQRSTUVWXYZ_].*/, "", $1);
33 split($1, parts, "_");
34 if (parts[2] == "SPEC") {
41 print "cannot create skip table";
45 skiptab[x] = parts[3];
48 if (parts[2] in kinds) {
49 kind_counts[parts[2]]++;
50 specs[count++] = parts[3];
55 # Create the token table. The first 5 entries key off of bits 9 through 11,
56 # which is sufficient to distinguish the different specifier kinds and is
57 # used to partition the rest of the token table.
64 skip_pos = ++skip_count;
65 for (i = 0; i < skip_count; i++) {
66 offset_table = offset_table skip_pos ", ";
67 skip_pos += kind_counts[skiptab[i]];
69 sub(/ $/, "\n\t\t", offset_table);
71 for (i = 0; i < count; i++) {
76 if (specs[i] == "IDENT")
79 s = "PACK_TOKEN(T_" specs[i] ")";
80 offset_table = offset_table s suffix;
83 print "static const char *spec_string(unsigned type)"
85 print "\tstatic const uint_least8_t idx[] = {";
86 print "\t\t" offset_table;
89 print "\tunsigned x = (type & 0xff) + idx[type >> 9];";
90 print "\tassert(x < sizeof idx);";
91 print "\tif (!(x = idx[x]))";
92 print "\t\treturn \"\";";
93 print "\treturn cdecl__token_name(UNPACK_TOKEN(x));";