Permalink
Browse files

Add a separate module for pretty-printing runtime values

  • Loading branch information...
1 parent 9995e8c commit 4afab2a35cc713bfb9e13695e917289ca54be9a9 @nickg committed Apr 7, 2012
Showing with 107 additions and 42 deletions.
  1. +2 −1 src/rt/Makefile.am
  2. +92 −0 src/rt/pprint.c
  3. +2 −0 src/rt/rt.h
  4. +1 −41 src/rt/shell.c
  5. +7 −0 src/type.c
  6. +3 −0 src/type.h
View
@@ -2,7 +2,8 @@ noinst_LIBRARIES = libnvc-rt.a libjit.a
AM_CFLAGS = -Wall -Werror -I$(srcdir)/..
-libnvc_rt_a_SOURCES = rtkern.c slave.c shell.c alloc.c vcd.c heap.c
+libnvc_rt_a_SOURCES = rtkern.c slave.c shell.c alloc.c vcd.c heap.c \
+ pprint.c
libjit_a_SOURCES = jit.c
libjit_a_CFLAGS = $(AM_CFLAGS) $(LLVM_CFLAGS)
View
@@ -0,0 +1,92 @@
+//
+// Copyright (C) 2012 Nick Gasson
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+
+#include "util.h"
+#include "tree.h"
+#include "type.h"
+
+#include <inttypes.h>
+#include <stdio.h>
+#include <assert.h>
+
+static bool pp_char_enum(type_t type)
+{
+ bool all_char = true;
+ unsigned nlit = type_enum_literals(type);
+ for (unsigned i = 0; i < nlit; i++) {
+ tree_t lit = type_enum_literal(type, i);
+ all_char = all_char && (ident_char(tree_ident(lit), 0) == '\'');
+ }
+ return all_char;
+}
+
+static size_t pp_one(char *p, size_t len, type_t type, uint64_t value)
+{
+ switch (type_kind(type)) {
+ case T_INTEGER:
+ return snprintf(p, len, "%"PRIi64, value);
+
+ case T_ENUM:
+ {
+ assert(value < type_enum_literals(type));
+ const char *s = istr(tree_ident(type_enum_literal(type, value)));
+ if (*s == '\'')
+ return snprintf(p, len, "%c", *(s + 1));
+ else
+ return snprintf(p, len, "%s", s);
+ }
+
+ default:
+ return snprintf(p, len, "%"PRIx64, value);
+ }
+}
+
+const char *pprint(tree_t t, uint64_t *values, unsigned len)
+{
+ static char buf[1024];
+
+ char *p = buf;
+ const char *end = buf + sizeof(buf);
+
+ type_t type = tree_type(t);
+
+ if (type_is_array(type)) {
+ type_t elem = type_base_recur(type_elem(type));
+ bool all_char = pp_char_enum(elem);
+
+ p += snprintf(p, end - p, all_char ? "\"" : "(");
+
+ unsigned left = 0, right = len - 1, step = 1;
+ if (type_dim(type, 0).kind == RANGE_DOWNTO) {
+ left = len - 1;
+ right = 0;
+ step = -1;
+ }
+
+ for (unsigned i = left; i != right + step; i += step) {
+ if (!all_char && (i != left))
+ p += snprintf(p, end - p, ",");
+ p += pp_one(p, end - p, elem, values[i]);
+ }
+
+ p += snprintf(p, end - p, all_char ? "\"" : ")");
+ }
+ else
+ pp_one(p, end - p, type_base_recur(type), values[0]);
+
+ return buf;
+}
View
@@ -42,6 +42,8 @@ void jit_bind_fn(const char *name, void *ptr);
void shell_run(struct tree *e);
+const char *pprint(struct tree *t, uint64_t *values, unsigned len);
+
void vcd_init(const char *file, struct tree *top);
void vcd_restart(void);
View
@@ -41,46 +41,6 @@
#include <readline/history.h>
#endif
-static const char *shell_fmt_signal_value(tree_t t, uint64_t *values,
- unsigned len)
-{
- static char buf[256];
-
- char *p = buf;
- const char *end = buf + sizeof(buf);
-
- type_t type = tree_type(t);
- type_t base = (type_is_array(type) ? type_elem(type) : type);
-
- unsigned left = 0, right = len - 1, step = 1;
-
- if ((type_kind(type) == T_CARRAY)
- && (type_dim(type, 0).kind == RANGE_DOWNTO)) {
- left = len - 1;
- right = 0;
- step = -1;
- }
-
- for (unsigned i = left; i != right + step; i += step) {
- switch (type_kind(base)) {
- case T_INTEGER:
- p += snprintf(p, end - p, "%"PRIi64, values[i]);
- break;
-
- case T_ENUM:
- assert(values[i] < type_enum_literals(base));
- p += snprintf(p, end - p, "%s",
- istr(tree_ident(type_enum_literal(base, values[i]))));
- break;
-
- default:
- p += snprintf(p, end - p, "%"PRIx64, values[i]);
- }
- }
-
- return buf;
-}
-
static int shell_cmd_restart(ClientData cd, Tcl_Interp *interp,
int objc, Tcl_Obj *const objv[])
{
@@ -174,7 +134,7 @@ static int shell_cmd_show(ClientData cd, Tcl_Interp *interp,
printf("%-30s%-25s%s\n",
istr(tree_ident(d)),
type_pp(tree_type(d)),
- shell_fmt_signal_value(d, reply->values, msg.len));
+ pprint(d, reply->values, msg.len));
free(reply);
}
View
@@ -826,3 +826,10 @@ bool type_is_array(type_t t)
else
return (t->kind == T_CARRAY || t->kind == T_UARRAY);
}
+
+type_t type_base_recur(type_t t)
+{
+ while (t->kind == T_SUBTYPE)
+ t = t->base;
+ return t;
+}
View
@@ -142,4 +142,7 @@ void type_sweep(unsigned generation);
// Type or its parent type is an array
bool type_is_array(type_t t);
+// Helper to find ultimate base type
+type_t type_base_recur(type_t t);
+
#endif // _TYPE_H

0 comments on commit 4afab2a

Please sign in to comment.