From: ceriel Date: Fri, 7 Sep 1990 14:56:24 +0000 (+0000) Subject: recognize expressions X-Git-Tag: release-5-5~1557 X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=24920dfa75883d47180a6a8cbd42cf16f073ff7b;p=ack.git recognize expressions --- diff --git a/util/grind/Amakefile b/util/grind/Amakefile index d88c24522..09f3ae0b6 100644 --- a/util/grind/Amakefile +++ b/util/grind/Amakefile @@ -75,6 +75,8 @@ HSRC = { scope.h, langdep.h, sizes.h, + token.h, + expr.h, rd.h } ; diff --git a/util/grind/commands.g b/util/grind/commands.g index aa8694411..11e90e236 100644 --- a/util/grind/commands.g +++ b/util/grind/commands.g @@ -14,28 +14,24 @@ #include "idf.h" #include "symbol.h" #include "tree.h" +#include "langdep.h" +#include "token.h" extern char *Salloc(); extern t_lineno currline; extern FILE *db_in; int errorgiven; -int extended_charset = 0; +static int extended_charset = 0; +static int in_expression = 0; jmp_buf jmpbuf; static int init_del(); static int skip_to_eol(); -static struct token { - int tokno; - long ival; - char *str; - double fval; - struct idf *idf; -} tok, aside; +struct token tok, aside; -#define TOK tok.tokno -#define ASIDE aside.tokno +#define prio(op) ((*(currlang->op_prio))(op)) } %start Commands, commands; @@ -160,7 +156,7 @@ trace_command(p_tree *p;) { p_tree whr = 0, cond = 0, exp = 0; } : TRACE - [ ON expression(&exp) ]? + [ ON expression(&exp, 1) ]? where(&whr)? condition(&cond)? { *p = mknode(OP_TRACE, whr, cond, exp); } ; @@ -234,19 +230,19 @@ delete_command(p_tree *p;) print_command(p_tree *p;) : - PRINT expression(p) { *p = mknode(OP_PRINT, *p); + PRINT expression(p, 1){ *p = mknode(OP_PRINT, *p); p = &((*p)->t_args[0]); } [ ',' { *p = mknode(OP_LINK, *p, (p_tree) 0); p = &((*p)->t_args[1]); } - expression(p) + expression(p, 1) ]* ; condition(p_tree *p;) : - IF expression(p) + IF expression(p, 1) ; where(p_tree *p;) @@ -256,9 +252,57 @@ where(p_tree *p;) position(p) ; -expression(p_tree *p;) +expression(p_tree *p; int level;) + { int currprio, currop; } +: { in_expression++; } + factor(p) + [ %while ((currprio = prio(currop = (int) tok.ival)) > level) + [ BIN_OP | PREF_OR_BIN_OP ] + { *p = mknode(OP_BINOP, *p, (p_tree) 0); + (*p)->t_whichoper = currop; + } + expression(&((*p)->t_args[1]), currprio) + ]* + { in_expression--; } +; + +factor(p_tree *p;) : - qualified_name(p) + '(' expression(p, 1) ')' +| + INTEGER { *p = mknode(OP_INTEGER, tok.ival); } +| + REAL { *p = mknode(OP_REAL, tok.fval); } +| + STRING { *p = mknode(OP_STRING, tok.str); } +| + designator(p) +| + PREF_OP { *p = mknode(OP_UNOP, (p_tree) 0); + (*p)->t_whichoper = (int) tok.ival; + } + factor(&(*p)->t_args[0]) +; + +designator(p_tree *p;) +: + qualified_name(p) + [ + SEL_OP { *p = mknode(OP_BINOP, *p, (p_tree) 0); + (*p)->t_whichoper = (int) tok.ival; + } + name(&(*p)->t_args[1]) + | + '[' { *p = mknode(OP_BINOP, *p, (p_tree) 0); + (*p)->t_whichoper = '['; + } + expression(&(*p)->t_args[1], 1) + ']' + | + POST_OP { *p = mknode(OP_UNOP, *p); + (*p)->t_whichoper = (int) tok.ival; + } + ]* ; position(p_tree *p;) @@ -357,10 +401,11 @@ LLlex() if (c == EOF) return c; switch(class(c)) { case STSTR: - TOK = get_string(c); + TOK = (*currlang->get_string)(c); break; case STIDF: - TOK = get_name(c); + if (in_expression) TOK = (*currlang->get_name)(c); + else TOK = get_name(c); break; case STDOT: c = getc(db_in); @@ -371,15 +416,20 @@ LLlex() } /* Fall through */ case STNUM: - TOK = get_number(c); + TOK = (*currlang->get_number)(c); break; case STNL: - case STSIMP: TOK = c; break; + case STSIMP: + if (! in_expression) { + TOK = c; + break; + } + /* Fall through */ default: - error("illegal character '\\0%o'", c); - return LLlex(); + TOK = (*currlang->get_token)(c); + break; } return TOK; } @@ -450,7 +500,8 @@ quoted(ch) } -int get_string(c) +int +get_string(c) int c; { register int ch; diff --git a/util/grind/dbx_string.g b/util/grind/dbx_string.g index 012b80058..38829851f 100644 --- a/util/grind/dbx_string.g +++ b/util/grind/dbx_string.g @@ -447,16 +447,24 @@ type(p_type *ptp; int *type_index;) ; structure_type(register p_type tp;) - { register struct fields *fldp; } + { register struct fields *fldp; + register p_symbol s; + } : integer_const(&(tp->ty_size)) /* size in bytes */ + { open_scope((p_symbol) 0, 0); } [ { fldp = get_field_space(tp); } name(&(fldp->fld_name)) + { s = NewSymbol(fldp->fld_name, CurrentScope, FIELD, currnam); + s->sy_field = fldp; + } type(&(fldp->fld_type), (int *) 0) ',' integer_const(&(fldp->fld_pos)) ',' /* offset in bits */ integer_const(&(fldp->fld_bitsize)) ';' /* size in bits */ ]* - ';' { end_field(tp); } + ';' { end_field(tp); + close_scope(); + } ; enum_type(register p_type tp;) diff --git a/util/grind/expr.c b/util/grind/expr.c index 0ddbdc79a..fe786e529 100644 --- a/util/grind/expr.c +++ b/util/grind/expr.c @@ -3,6 +3,7 @@ #include "position.h" #include "operator.h" #include "tree.h" +#include "expr.h" int eval_cond(p) diff --git a/util/grind/langdep.h b/util/grind/langdep.h index 4fe6eb09f..b6a379218 100644 --- a/util/grind/langdep.h +++ b/util/grind/langdep.h @@ -23,6 +23,11 @@ struct langdep { /* language dependant routines: */ int (*printstring)(); long (*arrayelsize)(); + int (*op_prio)(); + int (*get_string)(); + int (*get_name)(); + int (*get_number)(); + int (*get_token)(); }; extern struct langdep *m2_dep, *currlang; diff --git a/util/grind/main.c b/util/grind/main.c index 6ac468f49..09a9676ef 100644 --- a/util/grind/main.c +++ b/util/grind/main.c @@ -30,7 +30,7 @@ main(argc, argv) while (p = strindex(progname, '/')) { progname = p + 1; } - if (argv[1][0] == '-') { + if (argv[1] && argv[1][0] == '-') { switch(argv[1][1]) { case 'd': debug++; diff --git a/util/grind/modula-2.c b/util/grind/modula-2.c index 10a351a89..b49491281 100644 --- a/util/grind/modula-2.c +++ b/util/grind/modula-2.c @@ -4,12 +4,27 @@ #include +#include "class.h" #include "langdep.h" +#include "Lpars.h" +#include "idf.h" +#include "token.h" +#include "expr.h" -extern FILE *db_out; +extern FILE *db_out, *db_in; + +extern int + get_string(); + +extern double + atof(); static int - print_string(); + print_string(), + get_number(), + get_name(), + get_token(), + op_prio(); static long array_elsize(); @@ -31,7 +46,12 @@ static struct langdep m2 = { "}", print_string, - array_elsize + array_elsize, + op_prio, + get_string, + get_name, + get_number, + get_token }; struct langdep *m2_dep = &m2; @@ -59,3 +79,295 @@ array_elsize(size) if (! (size % int_size)) return size; return ((size + int_size - 1) / int_size) * int_size; } + +static int +op_prio(op) + int op; +{ + /* ??? to be written ??? */ + return 1; +} + +static int +get_number(ch) + register int ch; +{ + /* The problem arising with the "parsing" of a number + is that we don't know the base in advance so we + have to read the number with the help of a rather + complex finite automaton. + */ + enum statetp {Oct,Hex,Dec,OctEndOrHex,End,Real}; + register enum statetp state; + char buf[512+1]; + register int base = 10; + register char *np = &buf[0]; + + *np++ = ch; + state = is_oct(ch) ? Oct : Dec; + ch = getc(db_in); + for (;;) { + switch(state) { + case Oct: + while (is_oct(ch)) { + if (np < &buf[512]) *np++ = ch; + ch = getc(db_in); + } + if (ch == 'B' || ch == 'C') { + state = OctEndOrHex; + break; + } + /* Fall Through */ + case Dec: + base = 10; + while (is_dig(ch)) { + if (np < &buf[512]) { + *np++ = ch; + } + ch = getc(db_in); + } + if (is_hex(ch)) state = Hex; + else if (ch == '.') state = Real; + else { + state = End; + if (ch == 'H') base = 16; + else ungetc(ch, db_in); + } + break; + + case Hex: + while (is_hex(ch)) { + if (np < &buf[512]) *np++ = ch; + ch = getc(db_in); + } + base = 16; + state = End; + if (ch != 'H') { + error("H expected after hex number"); + ungetc(ch, db_in); + } + break; + + case OctEndOrHex: + if (np < &buf[512]) *np++ = ch; + ch = getc(db_in); + if (ch == 'H') { + base = 16; + state = End; + break; + } + if (is_hex(ch)) { + state = Hex; + break; + } + ungetc(ch, db_in); + ch = *--np; + *np++ = '\0'; + /* Fall through */ + + case End: + *np = '\0'; + if (np >= &buf[512]) { + tok.ival = 1; + error("constant too long"); + } + else { + np = &buf[0]; + while (*np == '0') np++; + tok.ival = 0; + while (*np) { + int c; + + if (is_dig(*np)) { + c = *np++ - '0'; + } + else { + c = *np++ - 'A' + 10; + } + tok.ival *= base; + tok.ival += c; + } + } + return INTEGER; + } + if (state == Real) break; + } + + /* a real real constant */ + if (np < &buf[512]) *np++ = '.'; + + while (is_dig(ch)) { + /* Fractional part + */ + if (np < &buf[512]) *np++ = ch; + ch = getc(db_in); + } + + if (ch == 'E') { + /* Scale factor + */ + if (np < &buf[512]) *np++ = ch; + ch = getc(db_in); + if (ch == '+' || ch == '-') { + /* Signed scalefactor + */ + if (np < &buf[512]) *np++ = ch; + ch = getc(db_in); + } + if (is_dig(ch)) { + do { + if (np < &buf[512]) *np++ = ch; + ch = getc(db_in); + } while (is_dig(ch)); + } + else { + error("bad scale factor"); + } + } + + *np++ = '\0'; + ungetc(ch, db_in); + + if (np >= &buf[512]) { + tok.fval = 0.0; + error("real constant too long"); + } + else tok.fval = atof(buf); + return REAL; +} + +static int +get_name(c) + register int c; +{ + char buf[512+1]; + register char *p = &buf[0]; + register struct idf *id; + + do { + if (p - buf < 512) *p++ = c; + c = getc(db_in); + } while (in_idf(c)); + ungetc(c, db_in); + *p = 0; + /* now recognize AND, DIV, IN, MOD, NOT, OR */ + switch(buf[0]) { + case 'A': + if (strcmp(buf, "AND") == 0) { + tok.ival = E_AND; + return BIN_OP; + } + break; + case 'D': + if (strcmp(buf, "DIV") == 0) { + tok.ival = E_DIV; + return BIN_OP; + } + break; + case 'I': + if (strcmp(buf, "IN") == 0) { + tok.ival = E_IN; + return BIN_OP; + } + break; + case 'M': + if (strcmp(buf, "MOD") == 0) { + tok.ival = E_MOD; + return BIN_OP; + } + break; + case 'N': + if (strcmp(buf, "NOT") == 0) { + tok.ival = E_NOT; + return PREF_OP; + } + break; + case 'O': + if (strcmp(buf, "OR") == 0) { + tok.ival = E_OR; + return BIN_OP; + } + break; + } + id = str2idf(buf, 1); + tok.idf = id; + tok.str = id->id_text; + return id->id_reserved ? id->id_reserved : NAME; +} + +static int +get_token(c) + register int c; +{ + switch(c) { + case '(': + case ')': + case '[': + case ']': + case '`': + case '{': + case '}': + case ':': + case ',': + return c; + + case '.': + tok.ival = E_SELECT; + return SEL_OP; + case '+': + tok.ival = E_PLUS; + return PREF_OR_BIN_OP; + case '-': + tok.ival = E_MIN; + return PREF_OR_BIN_OP; + case '*': + tok.ival = E_MUL; + return BIN_OP; + case '/': + tok.ival = E_DIV; + return BIN_OP; + case '&': + tok.ival = E_AND; + return BIN_OP; + case '|': + tok.ival = E_OR; + return BIN_OP; + case '=': + tok.ival = E_EQUAL; + return BIN_OP; + case '#': + tok.ival = E_NOTEQUAL; + return BIN_OP; + case '<': + c = getc(db_in); + if (c == '>') { + tok.ival = E_NOTEQUAL; + return BIN_OP; + } + if (c == '=') { + tok.ival = E_LTEQUAL; + return BIN_OP; + } + ungetc(c, db_in); + tok.ival = E_LT; + return BIN_OP; + case '>': + c = getc(db_in); + if (c == '=') { + tok.ival = E_GTEQUAL; + return BIN_OP; + } + ungetc(c, db_in); + tok.ival = E_GT; + return BIN_OP; + case '^': + tok.ival = E_DEREF; + return POST_OP; + case '~': + tok.ival = E_NOT; + return PREF_OP; + default: + error("illegal character 0%o", c); + return LLlex(); + } +} diff --git a/util/grind/operators.ot b/util/grind/operators.ot index 01f2d49aa..48a611dd8 100644 --- a/util/grind/operators.ot +++ b/util/grind/operators.ot @@ -5,6 +5,8 @@ OP_RUN 1 start_child OP_INPUT 1 0 OP_OUTPUT 1 0 OP_INTEGER 0 0 +OP_REAL 0 0 +OP_STRING 0 0 OP_NAME 0 0 OP_AT 0 0 OP_IN 1 0 @@ -22,3 +24,5 @@ OP_PRINT 1 do_print OP_DUMP 0 do_dump OP_RESTORE 0 do_restore OP_TRACE 3 do_trace +OP_UNOP 1 0 +OP_BINOP 2 0 diff --git a/util/grind/print.c b/util/grind/print.c index bab80bb29..dc8eaa44d 100644 --- a/util/grind/print.c +++ b/util/grind/print.c @@ -99,11 +99,11 @@ print_params(tp, AB, static_link) fprintf(db_out, currlang->addr_fmt, BUFTOA(p)); } else { - print_val(par->par_type, q, 1, 0, param_bytes); + print_val(par->par_type, size, q, 1, 0); } free(q); } - else print_val(par->par_type, p, 1, 0, param_bytes); + else print_val(par->par_type, par->par_type->ty_size, p, 1, 0); if (i) fputs(", ", db_out); p += param_size(par->par_type, par->par_kind); par++; @@ -111,29 +111,27 @@ print_params(tp, AB, static_link) free(param_bytes); } -print_val(tp, addr, compressed, indent, AB) +print_val(tp, tp_sz, addr, compressed, indent) p_type tp; /* type of value to be printed */ + long tp_sz; /* size of object to be printed */ char *addr; /* address to get value from */ int compressed; /* for parameter lists */ int indent; /* indentation */ - char *AB; /* argument base for dynamic subranges */ { - long sz; register int i; long elsize; if (indent == 0) indent = 4; switch(tp->ty_class) { case T_SUBRANGE: - print_val(tp->ty_base, addr, compressed, indent, AB); + print_val(tp->ty_base, tp->ty_size, addr, compressed, indent); break; case T_ARRAY: if (tp->ty_elements == char_type || tp->ty_elements == uchar_type) { - print_val(string_type, addr, compressed, indent, AB); + print_val(string_type, tp_sz, addr, compressed, indent); break; } - if ((sz = tp->ty_size) == 0) sz = compute_size(tp, AB); if (compressed) { fprintf(db_out, currlang->open_array_display); } @@ -146,8 +144,8 @@ print_val(tp, addr, compressed, indent, AB) } indent += 4; elsize = (*currlang->arrayelsize)(tp->ty_elements->ty_size); - for (i = sz/elsize; i; i--) { - print_val(tp->ty_elements, addr, compressed, indent, AB); + for (i = tp_sz/elsize; i; i--) { + print_val(tp->ty_elements, tp->ty_elements->ty_size, addr, compressed, indent); addr += elsize; if (compressed && i > 1) { fprintf(db_out, ", ..."); @@ -176,13 +174,14 @@ print_val(tp, addr, compressed, indent, AB) } indent += 4; for (i = tp->ty_nfields; i; i--, fld++) { + long sz = fld->fld_type->ty_size; if (! compressed) fprintf(db_out, "%s = ", fld->fld_name); - if (fld->fld_bitsize != fld->fld_type->ty_size << 3) { + if (fld->fld_bitsize != sz << 3) { /* apparently a bit field */ /* ??? */ fprintf(db_out, "", fld->fld_bitsize, fld->fld_type->ty_size); } - else print_val(fld->fld_type, addr+(fld->fld_pos>>3), compressed, indent, AB); + else print_val(fld->fld_type, sz, addr+(fld->fld_pos>>3), compressed, indent); if (compressed && i > 1) { fprintf(db_out, ", ..."); break; @@ -200,9 +199,9 @@ print_val(tp, addr, compressed, indent, AB) fprintf(db_out, ""); break; case T_ENUM: - print_literal(tp, tp->ty_size == 1 + print_literal(tp, tp_sz == 1 ? (*addr & 0xFF) - : tp->ty_size == 2 + : tp_sz == 2 ? (BUFTOS(addr) & 0xFFFF) : (int) BUFTOL(addr)); break; @@ -281,16 +280,16 @@ print_val(tp, addr, compressed, indent, AB) break; } case T_UNSIGNED: - print_unsigned(tp, tp->ty_size == 1 + print_unsigned(tp, tp_sz == 1 ? (*addr & 0xFF) - : tp->ty_size == 2 + : tp_sz == 2 ? (BUFTOS(addr) & 0xFFFF) : BUFTOL(addr)); break; case T_INTEGER: - print_integer(tp, tp->ty_size == 1 + print_integer(tp, tp_sz == 1 ? *addr - : tp->ty_size == 2 + : tp_sz == 2 ? BUFTOS(addr) : BUFTOL(addr)); break; @@ -308,13 +307,12 @@ print_sym(sym) p_symbol sym; { char *buf; - char *AB; + long size; - if (get_value(sym, &buf, &AB)) { + if (get_value(sym, &buf, &size)) { fputs(" = ", db_out); - print_val(sym->sy_type, buf, 0, 0, AB); + print_val(sym->sy_type, size, buf, 0, 0); if (buf) free(buf); - if (AB) free(AB); fputs("\n", db_out); return 1; } diff --git a/util/grind/symbol.hh b/util/grind/symbol.hh index 251b755e0..582bad16e 100644 --- a/util/grind/symbol.hh +++ b/util/grind/symbol.hh @@ -31,7 +31,7 @@ typedef struct symbol { #define REGVAR 0x0080 #define LOCVAR 0x0100 #define VARPAR 0x0200 -/* #define SYMENTRY 0x0400 /* a non-dbx entry */ +#define FIELD 0x0400 #define FILESYM 0x0800 /* a filename */ #define FILELINK 0x1000 /* a filename without its suffix */ struct idf *sy_idf; /* reference back to its idf structure */ @@ -42,12 +42,14 @@ typedef struct symbol { /* struct outname syv_onam; /* for non-dbx entries */ struct file *syv_file; /* for FILESYM */ struct symbol *syv_fllink; /* for FILELINK */ + struct fields *syv_field; } sy_v; #define sy_const sy_v.syv_const #define sy_name sy_v.syv_name #define sy_onam sy_v.syv_onam #define sy_file sy_v.syv_file #define sy_filelink sy_v.syv_fllink +#define sy_field sy_v.syv_field } t_symbol, *p_symbol; /* ALLOCDEF "symbol" 50 */ diff --git a/util/grind/token.h b/util/grind/token.h new file mode 100644 index 000000000..9514cb17e --- /dev/null +++ b/util/grind/token.h @@ -0,0 +1,16 @@ +/* $Header$ */ + +/* token structure for lexical analyzer */ + +struct token { + int tokno; + long ival; + char *str; + double fval; + struct idf *idf; +}; + +extern struct token tok, aside; + +#define TOK tok.tokno +#define ASIDE aside.tokno diff --git a/util/grind/tokenname.c b/util/grind/tokenname.c index 7e378d72c..704dd8853 100644 --- a/util/grind/tokenname.c +++ b/util/grind/tokenname.c @@ -29,6 +29,11 @@ struct tokenname tkspec[] = { /* the names of the special tokens */ {INTEGER, "number"}, {REAL, "real"}, {CHAR, "char"}, + {BIN_OP, ""}, + {PREF_OR_BIN_OP, ""}, + {PREF_OP, ""}, + {POST_OP, ""}, + {SEL_OP, ""}, {0, ""} }; #endif diff --git a/util/grind/tree.c b/util/grind/tree.c index 112cbedac..51771ff07 100644 --- a/util/grind/tree.c +++ b/util/grind/tree.c @@ -44,6 +44,12 @@ mknode(va_alist) case OP_INTEGER: p->t_ival = va_arg(ap, long); break; + case OP_STRING: + p->t_sval = va_arg(ap, char *); + break; + case OP_REAL: + p->t_fval = va_arg(ap, double); + break; case OP_AT: p->t_lino = va_arg(ap, long); p->t_filename = va_arg(ap, char *); @@ -74,23 +80,10 @@ freenode(p) register int na, i; if (! p) return; - switch(p->t_oper) { - case OP_NAME: - case OP_INTEGER: - case OP_AT: - case OP_CONT: - case OP_NEXT: - case OP_STEP: - case OP_REGS: - case OP_DELETE: - break; - default: - na = nargs(p->t_oper); - assert(na <= MAXARGS); - for (i = 0; i < na; i++) { - freenode(p->t_args[i]); - } - break; + na = nargs(p->t_oper); + assert(na <= MAXARGS); + for (i = 0; i < na; i++) { + freenode(p->t_args[i]); } free_tree(p); } @@ -219,6 +212,12 @@ print_node(p, top_level) case OP_INTEGER: fprintf(db_out, "%d", p->t_ival); break; + case OP_STRING: + fprintf(db_out, "%s", p->t_sval); + break; + case OP_REAL: + fprintf(db_out, "%.14g", p->t_fval); + break; } if (top_level) fputs("\n", db_out); } @@ -548,7 +547,7 @@ do_print(p) break; case OP_NAME: case OP_SELECT: - sym = identify(p, VAR|REGVAR|LOCVAR|VARPAR); + sym = identify(p, VAR|REGVAR|LOCVAR|VARPAR|CONST); if (! sym) return; print_node(p, 0); if (! print_sym(sym)) { diff --git a/util/grind/tree.hh b/util/grind/tree.hh index 052030ef3..ae06adf93 100644 --- a/util/grind/tree.hh +++ b/util/grind/tree.hh @@ -3,11 +3,14 @@ #define MAXARGS 3 typedef struct tree { - int t_oper; /* operator */ + short t_oper; /* tree operator */ + short t_whichoper; /* expression operator */ t_addr t_address; /* some operators use an address */ int t_itemno; /* item number in status list */ union { long tt_ival; + char *tt_sval; + double tt_fval; struct { struct idf *tt_idf; char *tt_str; @@ -17,6 +20,8 @@ typedef struct tree { t_position tt_pos; } t_xxxx; #define t_ival t_xxxx.tt_ival +#define t_sval t_xxxx.tt_sval +#define t_fval t_xxxx.tt_fval #define t_idf t_xxxx.tt_x.tt_idf #define t_str t_xxxx.tt_x.tt_str #define t_sc t_xxxx.tt_x.tt_scope diff --git a/util/grind/value.c b/util/grind/value.c index 42d3de2bf..f9896e4aa 100644 --- a/util/grind/value.c +++ b/util/grind/value.c @@ -12,20 +12,21 @@ int stack_offset; /* for up and down commands */ extern long pointer_size; extern t_addr *get_EM_regs(); +extern char *memcpy(); /* Get the value of the symbol indicated by sym. Return 0 on failure, 1 on success. - On success, 'buf' contains the value, and 'AB' may contain the parameters - of the procedure invocation containing sym. - For both of these, storage is allocated by Malloc; this storage must + On success, 'buf' contains the value, and 'size' contains the size. + For 'buf', storage is allocated by Malloc; this storage must be freed by caller (I don't like this any more than you do, but caller does not know sizes). */ int -get_value(sym, buf, AB) +get_value(sym, buf, psize) register p_symbol sym; - char **buf, **AB; + char **buf; + long *psize; { p_type tp = sym->sy_type; long size = tp->ty_size; @@ -33,9 +34,9 @@ get_value(sym, buf, AB) t_addr *EM_regs; int i; p_scope sc, symsc; + char *AB; *buf = 0; - *AB = 0; switch(sym->sy_class) { case VAR: /* exists if child exists; nm_value contains addres */ @@ -44,7 +45,40 @@ get_value(sym, buf, AB) retval = 1; } break; - + case CONST: + *buf = Malloc((unsigned) tp->ty_size); + switch(tp->ty_class) { + case T_REAL: + if (tp->ty_size != sizeof(double)) { + *((float *) *buf) = sym->sy_const.co_rval; + } + else *((double *) *buf) = sym->sy_const.co_rval; + break; + case T_INTEGER: + case T_SUBRANGE: + case T_UNSIGNED: + case T_ENUM: + if (tp->ty_size == 1) { + *((char *) *buf) = sym->sy_const.co_ival; + } + else if (tp->ty_size == 2) { + *((short *) *buf) = sym->sy_const.co_ival; + } + else { + *((long *) *buf) = sym->sy_const.co_ival; + } + break; + case T_SET: + memcpy(*buf, sym->sy_const.co_setval, (int) tp->ty_size); + break; + case T_STRING: + memcpy(*buf, sym->sy_const.co_sval, (int) tp->ty_size); + break; + default: + fatal("strange constant"); + } + retval = 1; + break; case VARPAR: case LOCVAR: /* first find the stack frame in which it resides */ @@ -97,28 +131,29 @@ get_value(sym, buf, AB) size = proctype->ty_nbparams; if (has_static_link(sc)) size += pointer_size; - *AB = Malloc((unsigned) size); - if (! get_bytes(size, EM_regs[AB_OFF], *AB)) { + AB = Malloc((unsigned) size); + if (! get_bytes(size, EM_regs[AB_OFF], AB)) { break; } if ((size = tp->ty_size) == 0) { - size = compute_size(tp, *AB); + size = compute_size(tp, AB); } } *buf = Malloc((unsigned) size); + *psize = size; if (get_bytes(size, - (t_addr) BUFTOA(*AB+sym->sy_name.nm_value), + (t_addr) BUFTOA(AB+sym->sy_name.nm_value), *buf)) { retval = 1; } + free(AB); break; } if (retval == 0) { if (*buf) free(*buf); - if (*AB) free(*AB); *buf = 0; - *AB = 0; + *psize = 0; } return retval;