X-Git-Url: https://git.draconx.ca/gitweb/cdecl99.git/blobdiff_plain/af1f874c4c58d0bd8becd52c892d0b358d08736e..566e87bb15a98ed499e79b45f6c834ad0ffdc3b7:/src/gen-specstr.awk diff --git a/src/gen-specstr.awk b/src/gen-specstr.awk index 68401c1..c07856e 100755 --- a/src/gen-specstr.awk +++ b/src/gen-specstr.awk @@ -22,8 +22,7 @@ END { BEGIN { kinds["TYPE"] = kinds["STOR"] = kinds["QUAL"] = kinds["FUNC"] = 1; - underscore["BOOL"] = underscore["COMPLEX"] = underscore["IMAGINARY"] = 1; - count = 0; + count = maxwidth = 0; } # Locate all the relevant identifiers in cdecl.h. We assume everything @@ -48,40 +47,17 @@ $1 ~ /^CDECL_/ { if (parts[2] in kinds) { kind_counts[parts[2]]++; + specs[count++] = parts[3]; - if (parts[3] == "IDENT") { - s = ""; - } else if (parts[3] in underscore) { - s = "_" substr(parts[3], 1, 1) tolower(substr(parts[3], 2)); - } else { - s = tolower(parts[3]); - } - rspecs[s] = count; - specs[count++] = s; + if (length(parts[3]) > maxwidth) + maxwidth = length(parts[3]); } } END { - string_table = ""; - - # The basic approach is to first generate a suffix-compressed string - # table containing all the specifier strings (not a lot of overlap in - # C specifiers, but there is (un)signed. - count = bucketsort(sorted_specs, specs); - for (i = 0; i < count; i++) { - s = sorted_specs[i]; - - if ((n = index(string_table, s "\1")) > 0) { - offsets[rspecs[s]] = n - 1; - } else { - offsets[rspecs[s]] = length(string_table); - string_table = string_table s "\1"; - } - } - - # Next, we create the index table. The first 5 entries key off of bits 9 - # through 11, which is sufficient to distinguish the different specifier - # kinds and is used to partition the rest of the index table. + # Create the token table. The first 5 entries key off of bits 9 through 11, + # which is sufficient to distinguish the different specifier kinds and is + # used to partition the rest of the token table. skip_count = 0; for (i in skiptab) { if (skip_count < i) @@ -95,59 +71,28 @@ END { } sub(/ $/, "\n\t\t", offset_table); - # Then, each remaining entry in the index table is an offset into the - # string table. for (i = 0; i < count; i++) { - suffix = "\t/* " (specs[i] ? specs[i] : "\"\"") " */"; + suffix = ""; if (i+1 < count) - suffix = "," suffix "\n\t\t"; - offset_table = offset_table offsets[i] suffix; - } + suffix = ",\n\t\t"; - sub(/\1$/, "", string_table); - gsub(/\1/, "\"\n\t\t\"\\0\" \"", string_table); + if (specs[i] == "IDENT") + s = "0"; + else + s = "T_" substr(specs[i] " ", 1, maxwidth) " - 256"; + offset_table = offset_table s suffix; + } print "static const char *spec_string(unsigned type)" print "{" - print "\tstatic const char tab[] ="; - print "\t\t \"" string_table "\";\n"; print "\tstatic const uint_least8_t idx[] = {"; print "\t\t" offset_table; print "\t};\n"; print "\tunsigned x = (type & 0xff) + idx[type >> 9];"; print "\tassert(x < sizeof idx);"; - print "\treturn tab + idx[x];"; + print "\tif (!(x = idx[x]))"; + print "\t\treturn \"\";"; + print "\treturn cdecl__token_name(x + 256);"; print "}"; } - -# bucketsort(dst, src) -# -# -# Sort the elements of src by descending string length, -# placing them into dst[0] ... dst[n]. -# -# Returns the number of elements. -function bucketsort(dst, src, buckets, max, count, i, t) -{ - for (t in src) { - i = length(src[t]); - if (i > max) { max = i; } - buckets[i]++; - } - - for (i = max; i >= 0; i--) { - if (i in buckets) { - t = buckets[i]; - buckets[i] = count; - count += t; - } - } - - for (t in src) { - i = length(t = src[t]); - dst[buckets[i]++] = t; - } - - return count; -}