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,
langdep.h,
sizes.h,
token.h,
expr.h,
rd.h
} ;

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -4,12 +4,27 @@
#include <stdio.h>
#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();
}
}

View file

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

View file

@ -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, "<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) {
fprintf(db_out, ", ...");
break;
@ -200,9 +199,9 @@ print_val(tp, addr, compressed, indent, AB)
fprintf(db_out, "<union>");
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;
}

View file

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

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"},
{REAL, "real"},
{CHAR, "char"},
{BIN_OP, "<operator>"},
{PREF_OR_BIN_OP, "<operator>"},
{PREF_OP, "<operator>"},
{POST_OP, "<operator>"},
{SEL_OP, "<operator>"},
{0, ""}
};
#endif

View file

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

View file

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

View file

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