/* Copyright (c) 1982 Regents of the University of California */ static char sccsid[] = "@(#)printval.c 1.1 01/18/82"; /* * 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(")"); }