recognize expressions

This commit is contained in:
ceriel 1990-09-07 14:56:24 +00:00
parent 2c9fbebe4e
commit 24920dfa75
15 changed files with 527 additions and 84 deletions

View file

@ -75,6 +75,8 @@ HSRC = {
scope.h, scope.h,
langdep.h, langdep.h,
sizes.h, sizes.h,
token.h,
expr.h,
rd.h rd.h
} ; } ;

View file

@ -14,28 +14,24 @@
#include "idf.h" #include "idf.h"
#include "symbol.h" #include "symbol.h"
#include "tree.h" #include "tree.h"
#include "langdep.h"
#include "token.h"
extern char *Salloc(); extern char *Salloc();
extern t_lineno currline; extern t_lineno currline;
extern FILE *db_in; extern FILE *db_in;
int errorgiven; int errorgiven;
int extended_charset = 0; static int extended_charset = 0;
static int in_expression = 0;
jmp_buf jmpbuf; jmp_buf jmpbuf;
static int init_del(); static int init_del();
static int skip_to_eol(); static int skip_to_eol();
static struct token { struct token tok, aside;
int tokno;
long ival;
char *str;
double fval;
struct idf *idf;
} tok, aside;
#define TOK tok.tokno #define prio(op) ((*(currlang->op_prio))(op))
#define ASIDE aside.tokno
} }
%start Commands, commands; %start Commands, commands;
@ -160,7 +156,7 @@ trace_command(p_tree *p;)
{ p_tree whr = 0, cond = 0, exp = 0; } { p_tree whr = 0, cond = 0, exp = 0; }
: :
TRACE TRACE
[ ON expression(&exp) ]? [ ON expression(&exp, 1) ]?
where(&whr)? where(&whr)?
condition(&cond)? { *p = mknode(OP_TRACE, whr, cond, exp); } condition(&cond)? { *p = mknode(OP_TRACE, whr, cond, exp); }
; ;
@ -234,19 +230,19 @@ delete_command(p_tree *p;)
print_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 = &((*p)->t_args[0]);
} }
[ ',' { *p = mknode(OP_LINK, *p, (p_tree) 0); [ ',' { *p = mknode(OP_LINK, *p, (p_tree) 0);
p = &((*p)->t_args[1]); p = &((*p)->t_args[1]);
} }
expression(p) expression(p, 1)
]* ]*
; ;
condition(p_tree *p;) condition(p_tree *p;)
: :
IF expression(p) IF expression(p, 1)
; ;
where(p_tree *p;) where(p_tree *p;)
@ -256,9 +252,57 @@ where(p_tree *p;)
position(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;) position(p_tree *p;)
@ -357,10 +401,11 @@ LLlex()
if (c == EOF) return c; if (c == EOF) return c;
switch(class(c)) { switch(class(c)) {
case STSTR: case STSTR:
TOK = get_string(c); TOK = (*currlang->get_string)(c);
break; break;
case STIDF: case STIDF:
TOK = get_name(c); if (in_expression) TOK = (*currlang->get_name)(c);
else TOK = get_name(c);
break; break;
case STDOT: case STDOT:
c = getc(db_in); c = getc(db_in);
@ -371,15 +416,20 @@ LLlex()
} }
/* Fall through */ /* Fall through */
case STNUM: case STNUM:
TOK = get_number(c); TOK = (*currlang->get_number)(c);
break; break;
case STNL: case STNL:
case STSIMP:
TOK = c; TOK = c;
break; break;
case STSIMP:
if (! in_expression) {
TOK = c;
break;
}
/* Fall through */
default: default:
error("illegal character '\\0%o'", c); TOK = (*currlang->get_token)(c);
return LLlex(); break;
} }
return TOK; return TOK;
} }
@ -450,7 +500,8 @@ quoted(ch)
} }
int get_string(c) int
get_string(c)
int c; int c;
{ {
register int ch; register int ch;

View file

@ -447,16 +447,24 @@ type(p_type *ptp; int *type_index;)
; ;
structure_type(register p_type tp;) 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 */ integer_const(&(tp->ty_size)) /* size in bytes */
{ open_scope((p_symbol) 0, 0); }
[ { fldp = get_field_space(tp); } [ { fldp = get_field_space(tp); }
name(&(fldp->fld_name)) name(&(fldp->fld_name))
{ s = NewSymbol(fldp->fld_name, CurrentScope, FIELD, currnam);
s->sy_field = fldp;
}
type(&(fldp->fld_type), (int *) 0) ',' type(&(fldp->fld_type), (int *) 0) ','
integer_const(&(fldp->fld_pos)) ',' /* offset in bits */ integer_const(&(fldp->fld_pos)) ',' /* offset in bits */
integer_const(&(fldp->fld_bitsize)) ';' /* size in bits */ integer_const(&(fldp->fld_bitsize)) ';' /* size in bits */
]* ]*
';' { end_field(tp); } ';' { end_field(tp);
close_scope();
}
; ;
enum_type(register p_type tp;) enum_type(register p_type tp;)

View file

@ -3,6 +3,7 @@
#include "position.h" #include "position.h"
#include "operator.h" #include "operator.h"
#include "tree.h" #include "tree.h"
#include "expr.h"
int int
eval_cond(p) eval_cond(p)

View file

@ -23,6 +23,11 @@ struct langdep {
/* language dependant routines: */ /* language dependant routines: */
int (*printstring)(); int (*printstring)();
long (*arrayelsize)(); long (*arrayelsize)();
int (*op_prio)();
int (*get_string)();
int (*get_name)();
int (*get_number)();
int (*get_token)();
}; };
extern struct langdep *m2_dep, *currlang; extern struct langdep *m2_dep, *currlang;

View file

@ -30,7 +30,7 @@ main(argc, argv)
while (p = strindex(progname, '/')) { while (p = strindex(progname, '/')) {
progname = p + 1; progname = p + 1;
} }
if (argv[1][0] == '-') { if (argv[1] && argv[1][0] == '-') {
switch(argv[1][1]) { switch(argv[1][1]) {
case 'd': case 'd':
debug++; debug++;

View file

@ -4,12 +4,27 @@
#include <stdio.h> #include <stdio.h>
#include "class.h"
#include "langdep.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 static int
print_string(); print_string(),
get_number(),
get_name(),
get_token(),
op_prio();
static long static long
array_elsize(); array_elsize();
@ -31,7 +46,12 @@ static struct langdep m2 = {
"}", "}",
print_string, print_string,
array_elsize array_elsize,
op_prio,
get_string,
get_name,
get_number,
get_token
}; };
struct langdep *m2_dep = &m2; struct langdep *m2_dep = &m2;
@ -59,3 +79,295 @@ array_elsize(size)
if (! (size % int_size)) return size; if (! (size % int_size)) return size;
return ((size + int_size - 1) / int_size) * int_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();
}
}

View file

@ -5,6 +5,8 @@ OP_RUN 1 start_child
OP_INPUT 1 0 OP_INPUT 1 0
OP_OUTPUT 1 0 OP_OUTPUT 1 0
OP_INTEGER 0 0 OP_INTEGER 0 0
OP_REAL 0 0
OP_STRING 0 0
OP_NAME 0 0 OP_NAME 0 0
OP_AT 0 0 OP_AT 0 0
OP_IN 1 0 OP_IN 1 0
@ -22,3 +24,5 @@ OP_PRINT 1 do_print
OP_DUMP 0 do_dump OP_DUMP 0 do_dump
OP_RESTORE 0 do_restore OP_RESTORE 0 do_restore
OP_TRACE 3 do_trace OP_TRACE 3 do_trace
OP_UNOP 1 0
OP_BINOP 2 0

View file

@ -99,11 +99,11 @@ print_params(tp, AB, static_link)
fprintf(db_out, currlang->addr_fmt, BUFTOA(p)); fprintf(db_out, currlang->addr_fmt, BUFTOA(p));
} }
else { else {
print_val(par->par_type, q, 1, 0, param_bytes); print_val(par->par_type, size, q, 1, 0);
} }
free(q); 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); if (i) fputs(", ", db_out);
p += param_size(par->par_type, par->par_kind); p += param_size(par->par_type, par->par_kind);
par++; par++;
@ -111,29 +111,27 @@ print_params(tp, AB, static_link)
free(param_bytes); 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 */ 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 */ char *addr; /* address to get value from */
int compressed; /* for parameter lists */ int compressed; /* for parameter lists */
int indent; /* indentation */ int indent; /* indentation */
char *AB; /* argument base for dynamic subranges */
{ {
long sz;
register int i; register int i;
long elsize; long elsize;
if (indent == 0) indent = 4; if (indent == 0) indent = 4;
switch(tp->ty_class) { switch(tp->ty_class) {
case T_SUBRANGE: case T_SUBRANGE:
print_val(tp->ty_base, addr, compressed, indent, AB); print_val(tp->ty_base, tp->ty_size, addr, compressed, indent);
break; break;
case T_ARRAY: case T_ARRAY:
if (tp->ty_elements == char_type || if (tp->ty_elements == char_type ||
tp->ty_elements == uchar_type) { tp->ty_elements == uchar_type) {
print_val(string_type, addr, compressed, indent, AB); print_val(string_type, tp_sz, addr, compressed, indent);
break; break;
} }
if ((sz = tp->ty_size) == 0) sz = compute_size(tp, AB);
if (compressed) { if (compressed) {
fprintf(db_out, currlang->open_array_display); fprintf(db_out, currlang->open_array_display);
} }
@ -146,8 +144,8 @@ print_val(tp, addr, compressed, indent, AB)
} }
indent += 4; indent += 4;
elsize = (*currlang->arrayelsize)(tp->ty_elements->ty_size); elsize = (*currlang->arrayelsize)(tp->ty_elements->ty_size);
for (i = sz/elsize; i; i--) { for (i = tp_sz/elsize; i; i--) {
print_val(tp->ty_elements, addr, compressed, indent, AB); print_val(tp->ty_elements, tp->ty_elements->ty_size, addr, compressed, indent);
addr += elsize; addr += elsize;
if (compressed && i > 1) { if (compressed && i > 1) {
fprintf(db_out, ", ..."); fprintf(db_out, ", ...");
@ -176,13 +174,14 @@ print_val(tp, addr, compressed, indent, AB)
} }
indent += 4; indent += 4;
for (i = tp->ty_nfields; i; i--, fld++) { 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 (! 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 */ /* apparently a bit field */
/* ??? */ /* ??? */
fprintf(db_out, "<bitfield, %d, %d>", fld->fld_bitsize, fld->fld_type->ty_size); fprintf(db_out, "<bitfield, %d, %d>", 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) { if (compressed && i > 1) {
fprintf(db_out, ", ..."); fprintf(db_out, ", ...");
break; break;
@ -200,9 +199,9 @@ print_val(tp, addr, compressed, indent, AB)
fprintf(db_out, "<union>"); fprintf(db_out, "<union>");
break; break;
case T_ENUM: case T_ENUM:
print_literal(tp, tp->ty_size == 1 print_literal(tp, tp_sz == 1
? (*addr & 0xFF) ? (*addr & 0xFF)
: tp->ty_size == 2 : tp_sz == 2
? (BUFTOS(addr) & 0xFFFF) ? (BUFTOS(addr) & 0xFFFF)
: (int) BUFTOL(addr)); : (int) BUFTOL(addr));
break; break;
@ -281,16 +280,16 @@ print_val(tp, addr, compressed, indent, AB)
break; break;
} }
case T_UNSIGNED: case T_UNSIGNED:
print_unsigned(tp, tp->ty_size == 1 print_unsigned(tp, tp_sz == 1
? (*addr & 0xFF) ? (*addr & 0xFF)
: tp->ty_size == 2 : tp_sz == 2
? (BUFTOS(addr) & 0xFFFF) ? (BUFTOS(addr) & 0xFFFF)
: BUFTOL(addr)); : BUFTOL(addr));
break; break;
case T_INTEGER: case T_INTEGER:
print_integer(tp, tp->ty_size == 1 print_integer(tp, tp_sz == 1
? *addr ? *addr
: tp->ty_size == 2 : tp_sz == 2
? BUFTOS(addr) ? BUFTOS(addr)
: BUFTOL(addr)); : BUFTOL(addr));
break; break;
@ -308,13 +307,12 @@ print_sym(sym)
p_symbol sym; p_symbol sym;
{ {
char *buf; char *buf;
char *AB; long size;
if (get_value(sym, &buf, &AB)) { if (get_value(sym, &buf, &size)) {
fputs(" = ", db_out); 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 (buf) free(buf);
if (AB) free(AB);
fputs("\n", db_out); fputs("\n", db_out);
return 1; return 1;
} }

View file

@ -31,7 +31,7 @@ typedef struct symbol {
#define REGVAR 0x0080 #define REGVAR 0x0080
#define LOCVAR 0x0100 #define LOCVAR 0x0100
#define VARPAR 0x0200 #define VARPAR 0x0200
/* #define SYMENTRY 0x0400 /* a non-dbx entry */ #define FIELD 0x0400
#define FILESYM 0x0800 /* a filename */ #define FILESYM 0x0800 /* a filename */
#define FILELINK 0x1000 /* a filename without its suffix */ #define FILELINK 0x1000 /* a filename without its suffix */
struct idf *sy_idf; /* reference back to its idf structure */ 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 outname syv_onam; /* for non-dbx entries */
struct file *syv_file; /* for FILESYM */ struct file *syv_file; /* for FILESYM */
struct symbol *syv_fllink; /* for FILELINK */ struct symbol *syv_fllink; /* for FILELINK */
struct fields *syv_field;
} sy_v; } sy_v;
#define sy_const sy_v.syv_const #define sy_const sy_v.syv_const
#define sy_name sy_v.syv_name #define sy_name sy_v.syv_name
#define sy_onam sy_v.syv_onam #define sy_onam sy_v.syv_onam
#define sy_file sy_v.syv_file #define sy_file sy_v.syv_file
#define sy_filelink sy_v.syv_fllink #define sy_filelink sy_v.syv_fllink
#define sy_field sy_v.syv_field
} t_symbol, *p_symbol; } t_symbol, *p_symbol;
/* ALLOCDEF "symbol" 50 */ /* ALLOCDEF "symbol" 50 */

16
util/grind/token.h Normal file
View file

@ -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

View file

@ -29,6 +29,11 @@ struct tokenname tkspec[] = { /* the names of the special tokens */
{INTEGER, "number"}, {INTEGER, "number"},
{REAL, "real"}, {REAL, "real"},
{CHAR, "char"}, {CHAR, "char"},
{BIN_OP, "<operator>"},
{PREF_OR_BIN_OP, "<operator>"},
{PREF_OP, "<operator>"},
{POST_OP, "<operator>"},
{SEL_OP, "<operator>"},
{0, ""} {0, ""}
}; };
#endif #endif

View file

@ -44,6 +44,12 @@ mknode(va_alist)
case OP_INTEGER: case OP_INTEGER:
p->t_ival = va_arg(ap, long); p->t_ival = va_arg(ap, long);
break; 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: case OP_AT:
p->t_lino = va_arg(ap, long); p->t_lino = va_arg(ap, long);
p->t_filename = va_arg(ap, char *); p->t_filename = va_arg(ap, char *);
@ -74,23 +80,10 @@ freenode(p)
register int na, i; register int na, i;
if (! p) return; if (! p) return;
switch(p->t_oper) { na = nargs(p->t_oper);
case OP_NAME: assert(na <= MAXARGS);
case OP_INTEGER: for (i = 0; i < na; i++) {
case OP_AT: freenode(p->t_args[i]);
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;
} }
free_tree(p); free_tree(p);
} }
@ -219,6 +212,12 @@ print_node(p, top_level)
case OP_INTEGER: case OP_INTEGER:
fprintf(db_out, "%d", p->t_ival); fprintf(db_out, "%d", p->t_ival);
break; 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); if (top_level) fputs("\n", db_out);
} }
@ -548,7 +547,7 @@ do_print(p)
break; break;
case OP_NAME: case OP_NAME:
case OP_SELECT: case OP_SELECT:
sym = identify(p, VAR|REGVAR|LOCVAR|VARPAR); sym = identify(p, VAR|REGVAR|LOCVAR|VARPAR|CONST);
if (! sym) return; if (! sym) return;
print_node(p, 0); print_node(p, 0);
if (! print_sym(sym)) { if (! print_sym(sym)) {

View file

@ -3,11 +3,14 @@
#define MAXARGS 3 #define MAXARGS 3
typedef struct tree { 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 */ t_addr t_address; /* some operators use an address */
int t_itemno; /* item number in status list */ int t_itemno; /* item number in status list */
union { union {
long tt_ival; long tt_ival;
char *tt_sval;
double tt_fval;
struct { struct {
struct idf *tt_idf; struct idf *tt_idf;
char *tt_str; char *tt_str;
@ -17,6 +20,8 @@ typedef struct tree {
t_position tt_pos; t_position tt_pos;
} t_xxxx; } t_xxxx;
#define t_ival t_xxxx.tt_ival #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_idf t_xxxx.tt_x.tt_idf
#define t_str t_xxxx.tt_x.tt_str #define t_str t_xxxx.tt_x.tt_str
#define t_sc t_xxxx.tt_x.tt_scope #define t_sc t_xxxx.tt_x.tt_scope

View file

@ -12,20 +12,21 @@ int stack_offset; /* for up and down commands */
extern long pointer_size; extern long pointer_size;
extern t_addr *get_EM_regs(); extern t_addr *get_EM_regs();
extern char *memcpy();
/* Get the value of the symbol indicated by sym. /* Get the value of the symbol indicated by sym.
Return 0 on failure, Return 0 on failure,
1 on success. 1 on success.
On success, 'buf' contains the value, and 'AB' may contain the parameters On success, 'buf' contains the value, and 'size' contains the size.
of the procedure invocation containing sym. For 'buf', storage is allocated by Malloc; this storage must
For both of these, storage is allocated by Malloc; this storage must
be freed by caller (I don't like this any more than you do, but caller be freed by caller (I don't like this any more than you do, but caller
does not know sizes). does not know sizes).
*/ */
int int
get_value(sym, buf, AB) get_value(sym, buf, psize)
register p_symbol sym; register p_symbol sym;
char **buf, **AB; char **buf;
long *psize;
{ {
p_type tp = sym->sy_type; p_type tp = sym->sy_type;
long size = tp->ty_size; long size = tp->ty_size;
@ -33,9 +34,9 @@ get_value(sym, buf, AB)
t_addr *EM_regs; t_addr *EM_regs;
int i; int i;
p_scope sc, symsc; p_scope sc, symsc;
char *AB;
*buf = 0; *buf = 0;
*AB = 0;
switch(sym->sy_class) { switch(sym->sy_class) {
case VAR: case VAR:
/* exists if child exists; nm_value contains addres */ /* exists if child exists; nm_value contains addres */
@ -44,7 +45,40 @@ get_value(sym, buf, AB)
retval = 1; retval = 1;
} }
break; 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 VARPAR:
case LOCVAR: case LOCVAR:
/* first find the stack frame in which it resides */ /* first find the stack frame in which it resides */
@ -97,28 +131,29 @@ get_value(sym, buf, AB)
size = proctype->ty_nbparams; size = proctype->ty_nbparams;
if (has_static_link(sc)) size += pointer_size; if (has_static_link(sc)) size += pointer_size;
*AB = Malloc((unsigned) size); AB = Malloc((unsigned) size);
if (! get_bytes(size, EM_regs[AB_OFF], *AB)) { if (! get_bytes(size, EM_regs[AB_OFF], AB)) {
break; break;
} }
if ((size = tp->ty_size) == 0) { if ((size = tp->ty_size) == 0) {
size = compute_size(tp, *AB); size = compute_size(tp, AB);
} }
} }
*buf = Malloc((unsigned) size); *buf = Malloc((unsigned) size);
*psize = size;
if (get_bytes(size, if (get_bytes(size,
(t_addr) BUFTOA(*AB+sym->sy_name.nm_value), (t_addr) BUFTOA(AB+sym->sy_name.nm_value),
*buf)) { *buf)) {
retval = 1; retval = 1;
} }
free(AB);
break; break;
} }
if (retval == 0) { if (retval == 0) {
if (*buf) free(*buf); if (*buf) free(*buf);
if (*AB) free(*AB);
*buf = 0; *buf = 0;
*AB = 0; *psize = 0;
} }
return retval; return retval;