]> git.draconx.ca Git - cdecl99.git/blobdiff - t/gen-typegen.awk
Rename "test" directory to "t".
[cdecl99.git] / t / gen-typegen.awk
diff --git a/t/gen-typegen.awk b/t/gen-typegen.awk
new file mode 100755 (executable)
index 0000000..a3a1527
--- /dev/null
@@ -0,0 +1,61 @@
+#!/bin/awk -f
+#
+# Copyright © 2021-2022 Nick Bowler
+#
+# Generate a mapping from a (random) integer to a list of type specifiers
+# represented by struct cdecl_declspec.  Used internally by declgen to
+# produce random valid declarations.
+#
+# License WTFPL2: Do What The Fuck You Want To Public License, version 2.
+# This is free software: you are free to do what the fuck you want to.
+# There is NO WARRANTY, to the extent permitted by law.
+
+END {
+  print "/*"
+  if (FILENAME) {
+    print " * Automatically generated by gen-typegen.awk from " FILENAME
+  } else {
+    print " * Automatically generated by gen-typegen.awk"
+  }
+  print " * Do not edit."
+  print " */"
+}
+
+BEGIN {
+  count = 0
+}
+
+$0 ~ /^[abcdefghijklmnopqrstuvwxyz_]/ {
+  for (i = 1; i <= NF; i++) {
+    sub(/_/, "", $i)
+    $i = "CDECL_TYPE_" toupper($i)
+  }
+  specs[count++] = $0
+}
+
+END {
+  print "static inline struct cdecl_declspec *"
+  print "gen_raw_typespec_(unsigned type, struct cdecl_declspec *next)\n{"
+  print "\tstruct cdecl_declspec *s = malloc_nofail(sizeof *s);"
+  print "\t*s = (struct cdecl_declspec) { .next = next, .type = type };"
+  print "\treturn s;\n}\n"
+
+  print "static inline struct cdecl_declspec *"
+  print "gen_raw_typespecs(unsigned rngval)\n{"
+  print "\tswitch (rngval) {"
+
+  for (i = 0; i < count; i++) {
+    print "\tcase " i ":"
+    $0 = specs[i]
+
+    for (j = 1; j <= NF; j++) {
+      prefix = j == 1 ? "return" : "";
+
+      printf "\t\t%6s gen_raw_typespec_(%s,\n", prefix, $j
+    }
+    printf "\t\t%25sNULL%s;\n", "", substr("))))))))", 1, NF);
+  }
+  print "\tdefault:\n\t\tassert(0);\n\t}"
+  print "}\n"
+  print "enum { GEN_TOTAL_TYPES = " count " };"
+}