date and time created 82/01/18 19:21:19 by linton
authorMark Linton <linton@ucbvax.Berkeley.EDU>
Tue, 19 Jan 1982 11:21:19 +0000 (03:21 -0800)
committerMark Linton <linton@ucbvax.Berkeley.EDU>
Tue, 19 Jan 1982 11:21:19 +0000 (03:21 -0800)
SCCS-vsn: usr.bin/pascal/pdx/sym/printval.c 1.1

usr/src/usr.bin/pascal/pdx/sym/printval.c [new file with mode: 0644]

diff --git a/usr/src/usr.bin/pascal/pdx/sym/printval.c b/usr/src/usr.bin/pascal/pdx/sym/printval.c
new file mode 100644 (file)
index 0000000..689a636
--- /dev/null
@@ -0,0 +1,191 @@
+/* Copyright (c) 1982 Regents of the University of California */
+
+static char sccsid[] = "@(#)printval.c 1.1 %G%";
+
+/*
+ * Print out the value at the top of the stack using the given type.
+ */
+
+#include "defs.h"
+#include "sym.h"
+#include "btypes.h"
+#include "classes.h"
+#include "tree.h"
+#include "process.h"
+#include "mappings.h"
+#include "sym.rep"
+
+printval(s)
+SYM *s;
+{
+       SYM *t;
+       ADDRESS a;
+       int len;
+
+       if (s->class == REF) {
+               s = s->type;
+       }
+       switch(s->class) {
+               case ARRAY:
+                       t = rtype(s->type);
+                       if (t==t_char || (t->class==RANGE && t->type==t_char)) {
+                               len = size(s);
+                               sp -= len;
+                               printf("'%s'", sp);
+                               break;
+                       } else {
+                               printarray(s);
+                       }
+                       break;
+
+               case RECORD:
+                       printrecord(s);
+                       break;
+
+               case VARNT:
+                       error("can't print out variant records");
+                       break;
+
+               case RANGE:
+                       if (s == t_real) {
+                               printf("%g", pop(double));
+                       } else if (s == t_char) {
+                               printf("'%c'", pop(long));
+                       } else if (s == t_boolean) {
+                               printf(pop(BOOLEAN)==TRUE ? "true" : "false");
+                       } else {
+                               printf("%ld", pop(long));
+                       }
+                       break;
+
+               case FILET:
+               case PTR: {
+                       ADDRESS addr;
+
+                       addr = pop(ADDRESS);
+                       if (addr == 0) {
+                               printf("nil");
+                       } else {
+                               printf("0%o", addr);
+                       }
+                       break;
+               }
+
+               case FIELD:
+                       error("missing record specification");
+                       break;
+
+               case SCAL: {
+                       int scalar;
+                       BOOLEAN found;
+
+                       scalar = pop(long);
+                       found = FALSE;
+                       for (t = s->chain; t != NIL; t = t->chain) {
+                               if (t->symvalue.iconval == scalar) {
+                                       printf("%s", t->symbol);
+                                       found = TRUE;
+                                       break;
+                               }
+                       }
+                       if (!found) {
+                               printf("(scalar = %d)", scalar);
+                       }
+                       break;
+               }
+
+               case FPROC:
+               case FFUNC:
+               {
+                       ADDRESS a;
+
+                       a = fparamaddr(pop(long));
+                       t = whatblock(a);
+                       if (t == NIL) {
+                               printf("(proc %d)", a);
+                       } else {
+                               printf("%s", t->symbol);
+                       }
+                       break;
+               }
+
+               default:
+                       if (s->class < BADUSE || s->class > VARNT) {
+                               panic("printval: bad class %d", s->class);
+                       }
+                       error("don't know how to print a %s", classname(s));
+                       /* NOTREACHED */
+       }
+}
+
+/*
+ * Print out the value of a record, field by field.
+ */
+
+LOCAL printrecord(s)
+SYM *s;
+{
+       SYM *t;
+
+       if ((t = s->chain) == NIL) {
+               error("record has no fields");
+       }
+       printf("(");
+       sp -= size(s);
+       printfield(t);
+       printf(")");
+}
+
+/*
+ * Print out a field, first printing out other fields.
+ * This is done because the fields are chained together backwards.
+ */
+
+LOCAL printfield(s)
+SYM *s;
+{
+       STACK *savesp;
+
+       if (s->chain != NIL) {
+               printfield(s->chain);
+               printf(", ");
+       }
+       printf("%s = ", s->symbol);
+       savesp = sp;
+       sp += (s->symvalue.offset + size(s->type));
+       alignstack();
+       printval(s->type);
+       sp = savesp;
+}
+
+/*
+ * Print out the contents of an array.
+ * Haven't quite figured out what the best format is.
+ *
+ * This is rather inefficient.
+ *
+ * The "2*elsize" is there since "printval" drops the stack by elsize.
+ */
+
+LOCAL printarray(a)
+SYM *a;
+{
+       STACK *savesp, *newsp;
+       SYM *eltype;
+       long elsize;
+
+       savesp = sp;
+       sp -= size(a);
+       newsp = sp;
+       eltype = a->type;
+       elsize = size(eltype);
+       printf("(");
+       for (sp += elsize; sp <= savesp; sp += 2*elsize) {
+               if (sp - elsize != newsp) {
+                       printf(", ");
+               }
+               printval(eltype);
+       }
+       sp = newsp;
+       printf(")");
+}