aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/show-parse.c
diff options
Diffstat (limited to 'show-parse.c')
-rw-r--r--show-parse.c313
1 files changed, 313 insertions, 0 deletions
diff --git a/show-parse.c b/show-parse.c
new file mode 100644
index 00000000..a756e639
--- /dev/null
+++ b/show-parse.c
@@ -0,0 +1,313 @@
+/*
+ * sparse/show-parse.c
+ *
+ * Copyright (C) 2003 Linus Torvalds, all rights reserved.
+ *
+ * Print out results of parsing for debugging and testing.
+ */
+#include <stdarg.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "lib.h"
+#include "token.h"
+#include "parse.h"
+#include "symbol.h"
+#include "scope.h"
+#include "expression.h"
+
+/*
+ * Symbol type printout. The type system is by far the most
+ * complicated part of C - everything else is trivial.
+ */
+const char *modifier_string(unsigned long mod)
+{
+ static char buffer[100];
+ char *p = buffer;
+ const char *res,**ptr, *names[] = {
+ "auto", "register", "static", "extern",
+ "const", "volatile", "signed", "unsigned",
+ "char", "short", "long", "long",
+ NULL
+ };
+ ptr = names;
+ while ((res = *ptr++) != NULL) {
+ if (mod & 1) {
+ char c;
+ *p++ = ' ';
+ while ((c = *res++) != '\0')
+ *p++ = c;
+ }
+ mod >>= 1;
+ }
+ *p++ = 0;
+ *p++ = 0;
+ return buffer+1;
+}
+
+const char *type_string(unsigned int modifiers, struct symbol *sym)
+{
+ if (!sym)
+ return "<notype>";
+
+ if (sym == &int_type) {
+ if (modifiers & (SYM_CHAR | SYM_SHORT | SYM_LONG))
+ return "";
+ return "int";
+ }
+ if (sym == &fp_type)
+ return "float";
+ if (sym == &void_type)
+ return "void";
+ if (sym == &vector_type)
+ return "vector";
+ if (sym == &bad_type)
+ return "bad type";
+ if (sym->token)
+ return show_token(sym->token);
+ return "typedef";
+}
+
+static void show_one_symbol(struct symbol *sym, void *sep, int flags)
+{
+ show_symbol(sym);
+ if (!(flags & ITERATE_LAST))
+ printf("%s", (const char *)sep);
+}
+
+void show_symbol_list(struct symbol_list *list, const char *sep)
+{
+ symbol_iterate(list, show_one_symbol, (void *)sep);
+}
+
+void show_type_list(struct symbol *sym)
+{
+ while (sym) {
+ show_symbol(sym);
+ sym = sym->next;
+ }
+}
+
+void show_type(struct symbol *sym)
+{
+ struct ctype *ctype = &sym->ctype;
+
+ if (!sym) {
+ printf(" <typeless>");
+ return;
+ }
+
+ printf("%s", modifier_string(sym->ctype.modifiers));
+
+ switch (sym->type) {
+ case SYM_PTR:
+ printf("*(");
+ show_type(sym->ctype.base_type);
+ printf(")");
+ break;
+
+ case SYM_FN:
+ printf("<fn of>(");
+ show_type(sym->ctype.base_type);
+ printf(")(");
+ show_symbol_list(sym->arguments, ", ");
+ printf(")");
+ break;
+
+ case SYM_ARRAY:
+ printf("<array of>(");
+ show_type(sym->ctype.base_type);
+ printf(")[ ... ]");
+ break;
+
+ default:
+ printf("%s", type_string(ctype->modifiers, ctype->base_type));
+ break;
+ }
+}
+
+void show_symbol(struct symbol *sym)
+{
+ if (!sym) {
+ printf("<anon symbol>");
+ return;
+ }
+ printf("Symbol %s: ", show_token(sym->token));
+ show_type(sym);
+ switch (sym->type) {
+ case SYM_FN:
+ printf("\n");
+ show_statement(sym->stmt);
+ break;
+ default:
+ break;
+ }
+}
+
+
+/*
+ * Print out a statement
+ */
+void show_statement(struct statement *stmt)
+{
+ if (!stmt) {
+ printf("\t<nostatement>");
+ return;
+ }
+ switch (stmt->type) {
+ case STMT_RETURN:
+ printf("\treturn ");
+ show_expression(stmt->expression);
+ break;
+ case STMT_COMPOUND:
+ printf("{\n");
+ if (stmt->syms) {
+ printf("\t");
+ show_symbol_list(stmt->syms, "\n\t");
+ printf("\n\n");
+ }
+ show_statement_list(stmt->stmts, ";\n");
+ printf("\n}\n\n");
+ break;
+ case STMT_EXPRESSION:
+ printf("\t");
+ show_expression(stmt->expression);
+ return;
+ case STMT_IF:
+ printf("\tif (");
+ show_expression(stmt->if_conditional);
+ printf(")\n");
+ show_statement(stmt->if_true);
+ if (stmt->if_false) {
+ printf("\nelse\n");
+ show_statement(stmt->if_false);
+ }
+ break;
+ case STMT_SWITCH:
+ printf("\tswitch (");
+ show_expression(stmt->switch_expression);
+ printf(")\n");
+ show_statement(stmt->switch_statement);
+ break;
+
+ case STMT_CASE:
+ if (!stmt->case_expression)
+ printf("default");
+ else {
+ printf("case ");
+ show_expression(stmt->case_expression);
+ if (stmt->case_to) {
+ printf(" ... ");
+ show_expression(stmt->case_to);
+ }
+ }
+ printf(":");
+ show_statement(stmt->case_statement);
+ break;
+
+ case STMT_BREAK:
+ printf("\tbreak");
+ break;
+
+ case STMT_WHILE:
+ printf("\twhile (");
+ show_expression(stmt->e1);
+ printf(")\n");
+ show_statement(stmt->iterate);
+ break;
+
+ case STMT_DO:
+ printf("\tdo");
+ show_statement(stmt->iterate);
+ printf("\nwhile (");
+ show_expression(stmt->e1);
+ printf(")\n");
+ break;
+
+ case STMT_FOR:
+ printf("\tfor (" );
+ show_expression(stmt->e1);
+ printf(" ; ");
+ show_expression(stmt->e2);
+ printf(" ; ");
+ show_expression(stmt->e3);
+ printf(")\n");
+ show_statement(stmt->iterate);
+ break;
+
+ default:
+ printf("WTF");
+ }
+}
+
+static void show_one_statement(struct statement *stmt, void *sep, int flags)
+{
+ show_statement(stmt);
+ if (!(flags & ITERATE_LAST))
+ printf("%s", (const char *)sep);
+}
+
+void show_statement_list(struct statement_list *stmt, const char *sep)
+{
+ statement_iterate(stmt, show_one_statement, (void *)sep);
+}
+
+/*
+ * Print out an expression
+ */
+void show_expression(struct expression *expr)
+{
+ if (!expr)
+ return;
+
+ printf("< ");
+ switch (expr->type) {
+ case EXPR_BINOP:
+ show_expression(expr->left);
+ printf(" %s ", show_special(expr->op));
+ show_expression(expr->right);
+ break;
+ case EXPR_PREOP:
+ printf("%s<", show_special(expr->op));
+ show_expression(expr->unop);
+ printf(">");
+ break;
+ case EXPR_POSTOP:
+ show_expression(expr->unop);
+ printf(" %s ", show_special(expr->op));
+ break;
+ case EXPR_CONSTANT:
+ printf("%s", show_token(expr->token));
+ break;
+ case EXPR_SYMBOL:
+ if (!expr->symbol) {
+ warn(expr->token, "undefined symbol '%s'", show_token(expr->token));
+ printf("<nosymbol>");
+ break;
+ }
+ printf("<%s:", show_token(expr->symbol->token));
+ show_type(expr->symbol);
+ printf(">");
+ break;
+ case EXPR_DEREF:
+ show_expression(expr->deref);
+ printf("%s", show_special(expr->op));
+ printf("%s", show_token(expr->member));
+ break;
+ case EXPR_CAST:
+ printf("<cast>(");
+ show_type(expr->cast_type);
+ printf(")");
+ show_expression(expr->cast_expression);
+ break;
+ default:
+ printf("WTF");
+ }
+ printf(" >");
+}
+
+