cosmopolitan/third_party/awk/maketab.c
2022-08-21 13:39:20 -07:00

202 lines
7.4 KiB
C

/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
│vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi│
╚──────────────────────────────────────────────────────────────────────────────╝
│ │
│ Copyright (C) Lucent Technologies 1997 │
│ All Rights Reserved │
│ │
│ Permission to use, copy, modify, and distribute this software and │
│ its documentation for any purpose and without fee is hereby │
│ granted, provided that the above copyright notice appear in all │
│ copies and that both that the copyright notice and this │
│ permission notice and warranty disclaimer appear in supporting │
│ documentation, and that the name Lucent Technologies or any of │
│ its entities not be used in advertising or publicity pertaining │
│ to distribution of the software without specific, written prior │
│ permission. │
│ │
│ LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, │
│ INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. │
│ IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY │
│ SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES │
│ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER │
│ IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, │
│ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF │
│ THIS SOFTWARE. │
│ │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/fmt/fmt.h"
#include "libc/mem/mem.h"
#include "libc/runtime/runtime.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "third_party/awk/awk.h"
#include "third_party/awk/awkgram.tab.h"
// clang-format off
/*
* this program makes the table to link function names
* and type indices that is used by execute() in run.c.
* it finds the indices in awkgram.tab.h, produced by bison.
*/
struct xx
{ int token;
const char *name;
const char *pname;
} proc[] = {
{ PROGRAM, "program", NULL },
{ BOR, "boolop", " || " },
{ AND, "boolop", " && " },
{ NOT, "boolop", " !" },
{ NE, "relop", " != " },
{ EQ, "relop", " == " },
{ LE, "relop", " <= " },
{ LT, "relop", " < " },
{ GE, "relop", " >= " },
{ GT, "relop", " > " },
{ ARRAY, "array", NULL },
{ INDIRECT, "indirect", "$(" },
{ SUBSTR, "substr", "substr" },
{ SUB, "sub", "sub" },
{ GSUB, "gsub", "gsub" },
{ INDEX, "sindex", "sindex" },
{ SPRINTF, "awksprintf", "sprintf " },
{ ADD, "arith", " + " },
{ MINUS, "arith", " - " },
{ MULT, "arith", " * " },
{ DIVIDE, "arith", " / " },
{ MOD, "arith", " % " },
{ UMINUS, "arith", " -" },
{ UPLUS, "arith", " +" },
{ POWER, "arith", " **" },
{ PREINCR, "incrdecr", "++" },
{ POSTINCR, "incrdecr", "++" },
{ PREDECR, "incrdecr", "--" },
{ POSTDECR, "incrdecr", "--" },
{ CAT, "cat", " " },
{ PASTAT, "pastat", NULL },
{ PASTAT2, "dopa2", NULL },
{ MATCH, "matchop", " ~ " },
{ NOTMATCH, "matchop", " !~ " },
{ MATCHFCN, "matchop", "matchop" },
{ INTEST, "intest", "intest" },
{ PRINTF, "awkprintf", "printf" },
{ PRINT, "printstat", "print" },
{ CLOSE, "closefile", "closefile" },
{ DELETE, "awkdelete", "awkdelete" },
{ SPLIT, "split", "split" },
{ ASSIGN, "assign", " = " },
{ ADDEQ, "assign", " += " },
{ SUBEQ, "assign", " -= " },
{ MULTEQ, "assign", " *= " },
{ DIVEQ, "assign", " /= " },
{ MODEQ, "assign", " %= " },
{ POWEQ, "assign", " ^= " },
{ CONDEXPR, "condexpr", " ?: " },
{ IF, "ifstat", "if(" },
{ WHILE, "whilestat", "while(" },
{ FOR, "forstat", "for(" },
{ DO, "dostat", "do" },
{ IN, "instat", "instat" },
{ NEXT, "jump", "next" },
{ NEXTFILE, "jump", "nextfile" },
{ EXIT, "jump", "exit" },
{ BREAK, "jump", "break" },
{ CONTINUE, "jump", "continue" },
{ RETURN, "jump", "ret" },
{ BLTIN, "bltin", "bltin" },
{ CALL, "call", "call" },
{ ARG, "arg", "arg" },
{ VARNF, "getnf", "NF" },
{ GETLINE, "awkgetline", "getline" },
{ 0, "", "" },
};
#define SIZE (LASTTOKEN - FIRSTTOKEN + 1)
const char *table[SIZE];
char *names[SIZE];
int main(int argc, char *argv[])
{
const struct xx *p;
int i, n, tok;
char c;
FILE *fp;
char buf[200], name[200], def[200];
enum { TOK_UNKNOWN, TOK_ENUM, TOK_DEFINE } tokentype = TOK_UNKNOWN;
printf("#include \"libc/calls/calls.h\"\n");
printf("#include \"libc/fmt/fmt.h\"\n");
printf("#include \"libc/stdio/lock.h\"\n");
printf("#include \"libc/stdio/stdio.h\"\n");
printf("#include \"libc/stdio/temp.h\"\n");
printf("#include \"third_party/awk/awk.h\"\n");
printf("#include \"third_party/awk/awkgram.tab.h\"\n\n");
if (argc != 2) {
fprintf(stderr, "usage: maketab YTAB_H\n");
exit(1);
}
if ((fp = fopen(argv[1], "r")) == NULL) {
fprintf(stderr, "maketab can't open %s!\n", argv[1]);
exit(1);
}
printf("static const char * const printname[%d] = {\n", SIZE);
i = 0;
while (fgets(buf, sizeof buf, fp) != NULL) {
// 199 is sizeof(def) - 1
if (tokentype != TOK_ENUM) {
n = sscanf(buf, "%1c %199s %199s %d", &c, def, name,
&tok);
if (n == 4 && c == '#' && strcmp(def, "define") == 0) {
tokentype = TOK_DEFINE;
} else if (tokentype != TOK_UNKNOWN) {
continue;
}
}
if (tokentype != TOK_DEFINE) {
/* not a valid #define, bison uses enums now */
n = sscanf(buf, "%199s = %d,\n", name, &tok);
if (n != 2)
continue;
tokentype = TOK_ENUM;
}
if (strcmp(name, "YYSTYPE_IS_DECLARED") == 0) {
tokentype = TOK_UNKNOWN;
continue;
}
if (tok < FIRSTTOKEN || tok > LASTTOKEN) {
tokentype = TOK_UNKNOWN;
/* fprintf(stderr, "maketab funny token %d %s ignored\n", tok, buf); */
continue;
}
names[tok-FIRSTTOKEN] = strdup(name);
if (names[tok-FIRSTTOKEN] == NULL) {
fprintf(stderr, "maketab out of space copying %s", name);
continue;
}
printf("\t\"%s\",\t/* %d */\n", name, tok);
i++;
}
printf("};\n\n");
for (p=proc; p->token!=0; p++)
table[p->token-FIRSTTOKEN] = p->name;
printf("\nCell *(*proctab[%d])(Node **, int) = {\n", SIZE);
for (i=0; i<SIZE; i++)
printf("\t%s,\t/* %s */\n",
table[i] ? table[i] : "nullproc", names[i] ? names[i] : "");
printf("};\n\n");
printf("const char *tokname(int n)\n"); /* print a tokname() function */
printf("{\n");
printf("\tstatic char buf[100];\n\n");
printf("\tif (n < FIRSTTOKEN || n > LASTTOKEN) {\n");
printf("\t\tsnprintf(buf, sizeof(buf), \"token %%d\", n);\n");
printf("\t\treturn buf;\n");
printf("\t}\n");
printf("\treturn printname[n-FIRSTTOKEN];\n");
printf("}\n");
return 0;
}