many changes
This commit is contained in:
parent
641a446f01
commit
1feeb94dbf
|
@ -61,7 +61,6 @@ CSRC = {
|
||||||
value.c,
|
value.c,
|
||||||
type.c,
|
type.c,
|
||||||
rd.c,
|
rd.c,
|
||||||
default.c,
|
|
||||||
modula-2.c,
|
modula-2.c,
|
||||||
c.c
|
c.c
|
||||||
} ;
|
} ;
|
||||||
|
|
114
util/grind/c.c
114
util/grind/c.c
|
@ -25,11 +25,13 @@ extern double
|
||||||
|
|
||||||
static int
|
static int
|
||||||
print_string(),
|
print_string(),
|
||||||
|
print_char(),
|
||||||
get_number(),
|
get_number(),
|
||||||
get_string(),
|
get_string(),
|
||||||
get_token(),
|
get_token(),
|
||||||
print_op(),
|
print_op(),
|
||||||
op_prio();
|
unop_prio(),
|
||||||
|
binop_prio();
|
||||||
|
|
||||||
static long
|
static long
|
||||||
array_elsize();
|
array_elsize();
|
||||||
|
@ -43,7 +45,6 @@ static struct langdep c = {
|
||||||
"%lu",
|
"%lu",
|
||||||
"0x%lX",
|
"0x%lX",
|
||||||
"%g",
|
"%g",
|
||||||
"'\\%o'",
|
|
||||||
|
|
||||||
"{",
|
"{",
|
||||||
"}",
|
"}",
|
||||||
|
@ -53,8 +54,10 @@ static struct langdep c = {
|
||||||
"}",
|
"}",
|
||||||
|
|
||||||
print_string,
|
print_string,
|
||||||
|
print_char,
|
||||||
array_elsize,
|
array_elsize,
|
||||||
op_prio,
|
unop_prio,
|
||||||
|
binop_prio,
|
||||||
get_string,
|
get_string,
|
||||||
get_name,
|
get_name,
|
||||||
get_number,
|
get_number,
|
||||||
|
@ -64,6 +67,13 @@ static struct langdep c = {
|
||||||
|
|
||||||
struct langdep *c_dep = &c;
|
struct langdep *c_dep = &c;
|
||||||
|
|
||||||
|
static int
|
||||||
|
print_char(c)
|
||||||
|
int c;
|
||||||
|
{
|
||||||
|
fprintf(db_out, (c >= 040 && c < 0177) ? "'%c'" : "'\\0%o'", c);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
print_string(s, len)
|
print_string(s, len)
|
||||||
char *s;
|
char *s;
|
||||||
|
@ -89,12 +99,57 @@ array_elsize(size)
|
||||||
return ((size + int_size - 1) / int_size) * int_size;
|
return ((size + int_size - 1) / int_size) * int_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*ARGSUSED*/
|
|
||||||
static int
|
static int
|
||||||
op_prio(op)
|
unop_prio(op)
|
||||||
int op;
|
int op;
|
||||||
{
|
{
|
||||||
switch(op) {
|
switch(op) {
|
||||||
|
case E_NOT:
|
||||||
|
case E_BNOT:
|
||||||
|
case E_MIN:
|
||||||
|
case E_MUL:
|
||||||
|
case E_SELECT:
|
||||||
|
case E_PLUS:
|
||||||
|
return 12;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
binop_prio(op)
|
||||||
|
int op;
|
||||||
|
{
|
||||||
|
switch(op) {
|
||||||
|
case E_OR:
|
||||||
|
return 2;
|
||||||
|
case E_AND:
|
||||||
|
return 3;
|
||||||
|
case E_BOR:
|
||||||
|
return 4;
|
||||||
|
case E_BXOR:
|
||||||
|
return 5;
|
||||||
|
case E_BAND:
|
||||||
|
return 6;
|
||||||
|
case E_EQUAL:
|
||||||
|
case E_NOTEQUAL:
|
||||||
|
return 7;
|
||||||
|
case E_LT:
|
||||||
|
case E_LTEQUAL:
|
||||||
|
case E_GT:
|
||||||
|
case E_GTEQUAL:
|
||||||
|
return 8;
|
||||||
|
case E_LSFT:
|
||||||
|
case E_RSFT:
|
||||||
|
return 9;
|
||||||
|
case E_MIN:
|
||||||
|
case E_PLUS:
|
||||||
|
return 10;
|
||||||
|
case E_MUL:
|
||||||
|
case E_DIV:
|
||||||
|
case E_ZDIV:
|
||||||
|
case E_MOD:
|
||||||
|
case E_ZMOD:
|
||||||
|
return 11;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -194,6 +249,12 @@ get_token(c)
|
||||||
tok.ival = E_PLUS;
|
tok.ival = E_PLUS;
|
||||||
return PREF_OR_BIN_OP;
|
return PREF_OR_BIN_OP;
|
||||||
case '-':
|
case '-':
|
||||||
|
c = getc(db_in);
|
||||||
|
if (c == '>') {
|
||||||
|
tok.ival = E_DERSELECT;
|
||||||
|
return BIN_OP;
|
||||||
|
}
|
||||||
|
ungetc(c, db_in);
|
||||||
tok.ival = E_MIN;
|
tok.ival = E_MIN;
|
||||||
return PREF_OR_BIN_OP;
|
return PREF_OR_BIN_OP;
|
||||||
case '*':
|
case '*':
|
||||||
|
@ -244,6 +305,10 @@ get_token(c)
|
||||||
tok.ival = E_LTEQUAL;
|
tok.ival = E_LTEQUAL;
|
||||||
return BIN_OP;
|
return BIN_OP;
|
||||||
}
|
}
|
||||||
|
if (c == '<') {
|
||||||
|
tok.ival = E_LSFT;
|
||||||
|
return BIN_OP;
|
||||||
|
}
|
||||||
ungetc(c, db_in);
|
ungetc(c, db_in);
|
||||||
tok.ival = E_LT;
|
tok.ival = E_LT;
|
||||||
return BIN_OP;
|
return BIN_OP;
|
||||||
|
@ -253,6 +318,10 @@ get_token(c)
|
||||||
tok.ival = E_GTEQUAL;
|
tok.ival = E_GTEQUAL;
|
||||||
return BIN_OP;
|
return BIN_OP;
|
||||||
}
|
}
|
||||||
|
if (c == '>') {
|
||||||
|
tok.ival = E_RSFT;
|
||||||
|
return BIN_OP;
|
||||||
|
}
|
||||||
ungetc(c, db_in);
|
ungetc(c, db_in);
|
||||||
tok.ival = E_GT;
|
tok.ival = E_GT;
|
||||||
return BIN_OP;
|
return BIN_OP;
|
||||||
|
@ -265,6 +334,9 @@ get_token(c)
|
||||||
ungetc(c, db_in);
|
ungetc(c, db_in);
|
||||||
tok.ival = E_NOT;
|
tok.ival = E_NOT;
|
||||||
return PREF_OP;
|
return PREF_OP;
|
||||||
|
case '~':
|
||||||
|
tok.ival = E_BNOT;
|
||||||
|
return PREF_OP;
|
||||||
default:
|
default:
|
||||||
error("illegal character 0%o", c);
|
error("illegal character 0%o", c);
|
||||||
return LLlex();
|
return LLlex();
|
||||||
|
@ -360,12 +432,41 @@ print_op(p)
|
||||||
fputs("*", db_out);
|
fputs("*", db_out);
|
||||||
print_node(p->t_args[0], 0);
|
print_node(p->t_args[0], 0);
|
||||||
break;
|
break;
|
||||||
|
case E_BNOT:
|
||||||
|
fputs("~", db_out);
|
||||||
|
print_node(p->t_args[0], 0);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OP_BINOP:
|
case OP_BINOP:
|
||||||
|
if (p->t_whichoper == E_ARRAY) {
|
||||||
|
print_node(p->t_args[0], 0);
|
||||||
|
fputs("[", db_out);
|
||||||
|
print_node(p->t_args[1], 0);
|
||||||
|
fputs("]", db_out);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (p->t_whichoper == E_DERSELECT) {
|
||||||
|
print_node(p->t_args[0], 0);
|
||||||
|
fputs("->", db_out);
|
||||||
|
print_node(p->t_args[1], 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (p->t_whichoper == E_SELECT) {
|
||||||
|
print_node(p->t_args[0], 0);
|
||||||
|
fputs(".", db_out);
|
||||||
|
print_node(p->t_args[1], 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
fputs("(", db_out);
|
fputs("(", db_out);
|
||||||
print_node(p->t_args[0], 0);
|
print_node(p->t_args[0], 0);
|
||||||
switch(p->t_whichoper) {
|
switch(p->t_whichoper) {
|
||||||
|
case E_LSFT:
|
||||||
|
fputs("<<", db_out);
|
||||||
|
break;
|
||||||
|
case E_RSFT:
|
||||||
|
fputs(">>", db_out);
|
||||||
|
break;
|
||||||
case E_AND:
|
case E_AND:
|
||||||
fputs("&&", db_out);
|
fputs("&&", db_out);
|
||||||
break;
|
break;
|
||||||
|
@ -414,9 +515,6 @@ print_op(p)
|
||||||
case E_GT:
|
case E_GT:
|
||||||
fputs(">", db_out);
|
fputs(">", db_out);
|
||||||
break;
|
break;
|
||||||
case E_SELECT:
|
|
||||||
fputs(".", db_out);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
print_node(p->t_args[1], 0);
|
print_node(p->t_args[1], 0);
|
||||||
fputs(")", db_out);
|
fputs(")", db_out);
|
||||||
|
|
|
@ -32,7 +32,8 @@ static int skip_to_eol();
|
||||||
|
|
||||||
struct token tok, aside;
|
struct token tok, aside;
|
||||||
|
|
||||||
#define prio(op) ((*(currlang->op_prio))(op))
|
#define binprio(op) ((*(currlang->binop_prio))(op))
|
||||||
|
#define unprio(op) ((*(currlang->unop_prio))(op))
|
||||||
}
|
}
|
||||||
%start Commands, commands;
|
%start Commands, commands;
|
||||||
|
|
||||||
|
@ -100,6 +101,7 @@ command_line(p_tree *p;)
|
||||||
| delete_command(p)
|
| delete_command(p)
|
||||||
| print_command(p)
|
| print_command(p)
|
||||||
| trace_command(p)
|
| trace_command(p)
|
||||||
|
| set_command(p)
|
||||||
| { *p = 0; }
|
| { *p = 0; }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -241,6 +243,12 @@ print_command(p_tree *p;)
|
||||||
]*
|
]*
|
||||||
;
|
;
|
||||||
|
|
||||||
|
set_command(p_tree *p;)
|
||||||
|
:
|
||||||
|
SET expression(p, 1) { *p = mknode(OP_SET, *p, (p_tree) 0); }
|
||||||
|
TO expression(&((*p)->t_args[1]), 1)
|
||||||
|
;
|
||||||
|
|
||||||
condition(p_tree *p;)
|
condition(p_tree *p;)
|
||||||
:
|
:
|
||||||
IF expression(p, 1)
|
IF expression(p, 1)
|
||||||
|
@ -257,12 +265,13 @@ expression(p_tree *p; int level;)
|
||||||
{ int currprio, currop; }
|
{ int currprio, currop; }
|
||||||
: { in_expression++; }
|
: { in_expression++; }
|
||||||
factor(p)
|
factor(p)
|
||||||
[ %while ((currprio = prio(currop = (int) tok.ival)) > level)
|
[ %while ((currprio = binprio(currop = (int) tok.ival)) > level)
|
||||||
[ BIN_OP | PREF_OR_BIN_OP ]
|
[ BIN_OP | PREF_OR_BIN_OP ]
|
||||||
{ *p = mknode(OP_BINOP, *p, (p_tree) 0);
|
{ *p = mknode(OP_BINOP, *p, (p_tree) 0);
|
||||||
(*p)->t_whichoper = currop;
|
(*p)->t_whichoper = currop;
|
||||||
}
|
}
|
||||||
expression(&((*p)->t_args[1]), currprio)
|
expression(&((*p)->t_args[1]), currprio)
|
||||||
|
{ adjust_oper(p); }
|
||||||
]*
|
]*
|
||||||
{ in_expression--; }
|
{ in_expression--; }
|
||||||
;
|
;
|
||||||
|
@ -283,7 +292,7 @@ factor(p_tree *p;)
|
||||||
(*p)->t_whichoper = (int) tok.ival;
|
(*p)->t_whichoper = (int) tok.ival;
|
||||||
}
|
}
|
||||||
[ PREF_OP | PREF_OR_BIN_OP ]
|
[ PREF_OP | PREF_OR_BIN_OP ]
|
||||||
expression(&(*p)->t_args[0], prio((*p)->t_whichoper))
|
expression(&(*p)->t_args[0], unprio((*p)->t_whichoper))
|
||||||
;
|
;
|
||||||
|
|
||||||
designator(p_tree *p;)
|
designator(p_tree *p;)
|
||||||
|
@ -383,6 +392,8 @@ name(p_tree *p;)
|
||||||
| RESTORE
|
| RESTORE
|
||||||
| TRACE
|
| TRACE
|
||||||
| ON
|
| ON
|
||||||
|
| SET
|
||||||
|
| TO
|
||||||
] { *p = mknode(OP_NAME, tok.idf, tok.str); }
|
] { *p = mknode(OP_NAME, tok.idf, tok.str); }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,33 @@
|
||||||
/* $Header$ */
|
/* $Header$ */
|
||||||
|
|
||||||
|
/* This file contains the expression evaluator. It exports four routines:
|
||||||
|
- int eval_cond(p_tree p)
|
||||||
|
This routine evaluates the conditional expression indicated by p
|
||||||
|
and returns 1 if it evaluates to TRUE, or 0 if it could not be
|
||||||
|
evaluated for some reason or if it evalutes to FALSE.
|
||||||
|
If the expression cannot be evaluated, an error message is given.
|
||||||
|
- int eval_desig(p_tree p, t_addr *pbuf, long **psize, p_type *ptp)
|
||||||
|
This routine evaluates the expression indicated by p, which should
|
||||||
|
result in a designator. The result of the expression is an address
|
||||||
|
which is to be found in *pbuf. *psize will contain the size of the
|
||||||
|
designated object, and *ptp its type.
|
||||||
|
If the expression cannot be evaluated or does not result in a
|
||||||
|
designator, 0 is returned and an error message is given.
|
||||||
|
Otherwise, 1 is returned.
|
||||||
|
- int eval_expr(p_tree p, char **pbuf, long **psize, p_type *ptp)
|
||||||
|
This routine evaluates the expression indicated by p.
|
||||||
|
The result of the expression is left in *pbuf.
|
||||||
|
*psize will contain the size of the value, and *ptp its type.
|
||||||
|
If the expression cannot be evaluated, 0 is returned and an error
|
||||||
|
message is given. Otherwise, 1 is returned.
|
||||||
|
- int convert(char **pbuf, long *psize, p_type *ptp, p_type tp, long size)
|
||||||
|
This routine tries to convert the value in pbuf of size psize
|
||||||
|
and type ptp to type tp with size size. It returns 0 if this fails,
|
||||||
|
while producing an error message. Otherwise, it returns 1 and
|
||||||
|
the resulting value, type and size are left in pbuf, ptp, and
|
||||||
|
psize, respectively.
|
||||||
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <alloc.h>
|
#include <alloc.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
@ -14,6 +42,8 @@
|
||||||
|
|
||||||
extern FILE *db_out;
|
extern FILE *db_out;
|
||||||
|
|
||||||
|
/* buffer to integer and vice versa routines */
|
||||||
|
|
||||||
static long
|
static long
|
||||||
get_int(buf, size, class)
|
get_int(buf, size, class)
|
||||||
char *buf;
|
char *buf;
|
||||||
|
@ -22,12 +52,12 @@ get_int(buf, size, class)
|
||||||
long l;
|
long l;
|
||||||
|
|
||||||
switch((int)size) {
|
switch((int)size) {
|
||||||
case 1:
|
case sizeof(char):
|
||||||
l = *buf;
|
l = *buf;
|
||||||
if (class == T_INTEGER && l >= 0x7F) l -= 256;
|
if (class == T_INTEGER && l >= 0x7F) l -= 256;
|
||||||
else if (class != T_INTEGER && l < 0) l += 256;
|
else if (class != T_INTEGER && l < 0) l += 256;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case sizeof(short):
|
||||||
l = *((short *) buf);
|
l = *((short *) buf);
|
||||||
if (class == T_INTEGER && l >= 0x7FFF) l -= 65536;
|
if (class == T_INTEGER && l >= 0x7FFF) l -= 65536;
|
||||||
else if (class != T_INTEGER && l < 0) l += 65536;
|
else if (class != T_INTEGER && l < 0) l += 65536;
|
||||||
|
@ -38,6 +68,28 @@ get_int(buf, size, class)
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
put_int(buf, size, value)
|
||||||
|
char *buf;
|
||||||
|
long size;
|
||||||
|
long value;
|
||||||
|
{
|
||||||
|
switch((int)size) {
|
||||||
|
case sizeof(char):
|
||||||
|
*buf = value;
|
||||||
|
break;
|
||||||
|
case sizeof(short):
|
||||||
|
*((short *) buf) = value;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
*((long *) buf) = value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/*NOTREACHED*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/* buffer to real and vice versa routines */
|
||||||
|
|
||||||
static double
|
static double
|
||||||
get_real(buf, size)
|
get_real(buf, size)
|
||||||
char *buf;
|
char *buf;
|
||||||
|
@ -52,26 +104,6 @@ get_real(buf, size)
|
||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
|
||||||
put_int(buf, size, value)
|
|
||||||
char *buf;
|
|
||||||
long size;
|
|
||||||
long value;
|
|
||||||
{
|
|
||||||
switch((int)size) {
|
|
||||||
case 1:
|
|
||||||
*buf = value;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
*((short *) buf) = value;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
*((long *) buf) = value;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/* NOTREACHED */
|
|
||||||
}
|
|
||||||
|
|
||||||
static
|
static
|
||||||
put_real(buf, size, value)
|
put_real(buf, size, value)
|
||||||
char *buf;
|
char *buf;
|
||||||
|
@ -89,19 +121,24 @@ put_real(buf, size, value)
|
||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
int
|
||||||
convert(pbuf, psize, ptp, tp)
|
convert(pbuf, psize, ptp, tp, size)
|
||||||
char **pbuf;
|
char **pbuf;
|
||||||
long *psize;
|
long *psize;
|
||||||
p_type *ptp;
|
p_type *ptp;
|
||||||
p_type tp;
|
p_type tp;
|
||||||
|
long size;
|
||||||
{
|
{
|
||||||
|
/* Convert the value in pbuf, of size psize and type ptp, to type
|
||||||
|
tp and leave the resulting value in pbuf, the resulting size
|
||||||
|
in psize, and the resulting type in ptp.
|
||||||
|
*/
|
||||||
long l;
|
long l;
|
||||||
double d;
|
double d;
|
||||||
|
|
||||||
if (*ptp == tp) return 1;
|
if (*ptp == tp) return 1;
|
||||||
if (tp->ty_size > *psize) {
|
if (size > *psize) {
|
||||||
*pbuf = Realloc(*pbuf, (unsigned int) tp->ty_size);
|
*pbuf = Realloc(*pbuf, (unsigned int) size);
|
||||||
}
|
}
|
||||||
if ((*ptp)->ty_class == T_SUBRANGE) *ptp = (*ptp)->ty_base;
|
if ((*ptp)->ty_class == T_SUBRANGE) *ptp = (*ptp)->ty_base;
|
||||||
switch((*ptp)->ty_class) {
|
switch((*ptp)->ty_class) {
|
||||||
|
@ -117,17 +154,17 @@ convert(pbuf, psize, ptp, tp)
|
||||||
case T_UNSIGNED:
|
case T_UNSIGNED:
|
||||||
case T_POINTER:
|
case T_POINTER:
|
||||||
case T_ENUM:
|
case T_ENUM:
|
||||||
put_int(*pbuf, tp->ty_size, l);
|
put_int(*pbuf, size, l);
|
||||||
*psize = tp->ty_size;
|
*psize = size;
|
||||||
*ptp = tp;
|
*ptp = tp;
|
||||||
return 1;
|
return 1;
|
||||||
case T_REAL:
|
case T_REAL:
|
||||||
put_real(*pbuf,
|
put_real(*pbuf,
|
||||||
tp->ty_size,
|
size,
|
||||||
(*ptp)->ty_class == T_INTEGER
|
(*ptp)->ty_class == T_INTEGER
|
||||||
? (double) l
|
? (double) l
|
||||||
: (double) (unsigned long) l);
|
: (double) (unsigned long) l);
|
||||||
*psize = tp->ty_size;
|
*psize = size;
|
||||||
*ptp = tp;
|
*ptp = tp;
|
||||||
return 1;
|
return 1;
|
||||||
default:
|
default:
|
||||||
|
@ -142,14 +179,14 @@ convert(pbuf, psize, ptp, tp)
|
||||||
case T_INTEGER:
|
case T_INTEGER:
|
||||||
case T_UNSIGNED:
|
case T_UNSIGNED:
|
||||||
case T_POINTER:
|
case T_POINTER:
|
||||||
if (tp == bool_type) put_int(*pbuf, tp->ty_size, (long) (d != 0));
|
if (tp == bool_type) put_int(*pbuf, size, (long) (d != 0));
|
||||||
else put_int(*pbuf, tp->ty_size, (long) d);
|
else put_int(*pbuf, size, (long) d);
|
||||||
*psize = tp->ty_size;
|
*psize = size;
|
||||||
*ptp = tp;
|
*ptp = tp;
|
||||||
return 1;
|
return 1;
|
||||||
case T_REAL:
|
case T_REAL:
|
||||||
put_real(*pbuf, tp->ty_size, d);
|
put_real(*pbuf, size, d);
|
||||||
*psize = tp->ty_size;
|
*psize = size;
|
||||||
*ptp = tp;
|
*ptp = tp;
|
||||||
return 1;
|
return 1;
|
||||||
default:
|
default:
|
||||||
|
@ -171,9 +208,10 @@ eval_cond(p)
|
||||||
long size;
|
long size;
|
||||||
p_type tp;
|
p_type tp;
|
||||||
long val;
|
long val;
|
||||||
|
p_type target_tp = currlang->has_bool_type ? bool_type : int_type;
|
||||||
|
|
||||||
if (eval_expr(p, &buf, &size, &tp)) {
|
if (eval_expr(p, &buf, &size, &tp)) {
|
||||||
if (convert(&buf, &size, &tp, currlang->has_bool_type ? bool_type : int_type)) {
|
if (convert(&buf, &size, &tp, target_tp, target_tp->ty_size)) {
|
||||||
val = get_int(buf, size, T_UNSIGNED);
|
val = get_int(buf, size, T_UNSIGNED);
|
||||||
if (buf) free(buf);
|
if (buf) free(buf);
|
||||||
return (int) (val != 0);
|
return (int) (val != 0);
|
||||||
|
@ -183,6 +221,8 @@ eval_cond(p)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* one routine for each unary operator */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
do_not(p, pbuf, psize, ptp)
|
do_not(p, pbuf, psize, ptp)
|
||||||
p_tree p;
|
p_tree p;
|
||||||
|
@ -190,14 +230,64 @@ do_not(p, pbuf, psize, ptp)
|
||||||
long *psize;
|
long *psize;
|
||||||
p_type *ptp;
|
p_type *ptp;
|
||||||
{
|
{
|
||||||
|
p_type target_tp = currlang->has_bool_type ? bool_type : int_type;
|
||||||
|
|
||||||
if (eval_expr(p->t_args[0], pbuf, psize, ptp) &&
|
if (eval_expr(p->t_args[0], pbuf, psize, ptp) &&
|
||||||
convert(pbuf, psize, ptp, currlang->has_bool_type ? bool_type : int_type)) {
|
convert(pbuf, psize, ptp, target_tp, target_tp->ty_size)) {
|
||||||
put_int(*pbuf, *psize, (long) !get_int(*pbuf, *psize, T_UNSIGNED));
|
put_int(*pbuf, *psize, (long) !get_int(*pbuf, *psize, T_UNSIGNED));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
do_bnot(p, pbuf, psize, ptp)
|
||||||
|
p_tree p;
|
||||||
|
char **pbuf;
|
||||||
|
long *psize;
|
||||||
|
p_type *ptp;
|
||||||
|
{
|
||||||
|
if (eval_expr(p->t_args[0], pbuf, psize, ptp)) {
|
||||||
|
switch((*ptp)->ty_class) {
|
||||||
|
case T_INTEGER:
|
||||||
|
case T_ENUM:
|
||||||
|
case T_UNSIGNED:
|
||||||
|
case T_SUBRANGE:
|
||||||
|
put_int(*pbuf, *psize, ~get_int(*pbuf, *psize, T_UNSIGNED));
|
||||||
|
return 1;
|
||||||
|
default:
|
||||||
|
error("illegal operand type(s)");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
ptr_addr(p, paddr, psize, ptp)
|
||||||
|
p_tree p;
|
||||||
|
t_addr *paddr;
|
||||||
|
long *psize;
|
||||||
|
p_type *ptp;
|
||||||
|
{
|
||||||
|
char *buf;
|
||||||
|
|
||||||
|
if (eval_expr(p->t_args[0], &buf, psize, ptp)) {
|
||||||
|
switch((*ptp)->ty_class) {
|
||||||
|
case T_POINTER:
|
||||||
|
*ptp = (*ptp)->ty_ptrto;
|
||||||
|
*psize = (*ptp)->ty_size;
|
||||||
|
*paddr = get_int(buf, pointer_size, T_UNSIGNED);
|
||||||
|
free(buf);
|
||||||
|
return 1;
|
||||||
|
default:
|
||||||
|
error("illegal operand of DEREF");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
do_deref(p, pbuf, psize, ptp)
|
do_deref(p, pbuf, psize, ptp)
|
||||||
p_tree p;
|
p_tree p;
|
||||||
|
@ -205,25 +295,14 @@ do_deref(p, pbuf, psize, ptp)
|
||||||
long *psize;
|
long *psize;
|
||||||
p_type *ptp;
|
p_type *ptp;
|
||||||
{
|
{
|
||||||
char *addr;
|
t_addr addr;
|
||||||
|
|
||||||
if (eval_expr(p->t_args[0], pbuf, psize, ptp)) {
|
if (ptr_addr(p, &addr, psize, ptp)) {
|
||||||
switch((*ptp)->ty_class) {
|
*pbuf = Malloc((unsigned) *psize);
|
||||||
case T_POINTER:
|
if (! get_bytes(*psize, addr, *pbuf)) {
|
||||||
addr = *((char **) (*pbuf));
|
|
||||||
free(*pbuf);
|
|
||||||
*ptp = (*ptp)->ty_ptrto;
|
|
||||||
*psize = (*ptp)->ty_size;
|
|
||||||
*pbuf = Malloc((unsigned) (*ptp)->ty_size);
|
|
||||||
if (! get_bytes(*psize, (t_addr) addr, *pbuf)) {
|
|
||||||
error("could not get value");
|
error("could not get value");
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
default:
|
|
||||||
error("illegal operand of DEREF");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -301,6 +380,9 @@ static int (*un_op[])() = {
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
|
0,
|
||||||
|
do_bnot,
|
||||||
|
0,
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -389,11 +471,12 @@ do_andor(p, pbuf, psize, ptp)
|
||||||
char *buf;
|
char *buf;
|
||||||
long size;
|
long size;
|
||||||
p_type tp;
|
p_type tp;
|
||||||
|
p_type target_tp = currlang->has_bool_type ? bool_type : int_type;
|
||||||
|
|
||||||
if (eval_expr(p->t_args[0], pbuf, psize, ptp) &&
|
if (eval_expr(p->t_args[0], pbuf, psize, ptp) &&
|
||||||
convert(pbuf, psize, ptp, currlang->has_bool_type ? bool_type : int_type) &&
|
convert(pbuf, psize, ptp, target_tp, target_tp->ty_size) &&
|
||||||
eval_expr(p->t_args[1], &buf, &size, &tp) &&
|
eval_expr(p->t_args[1], &buf, &size, &tp) &&
|
||||||
convert(&buf, &size, &tp, currlang->has_bool_type ? bool_type : int_type)) {
|
convert(&buf, &size, &tp, target_tp, target_tp->ty_size)) {
|
||||||
l1 = get_int(*pbuf, *psize, T_UNSIGNED);
|
l1 = get_int(*pbuf, *psize, T_UNSIGNED);
|
||||||
l2 = get_int(buf, size, T_UNSIGNED);
|
l2 = get_int(buf, size, T_UNSIGNED);
|
||||||
put_int(*pbuf,
|
put_int(*pbuf,
|
||||||
|
@ -424,8 +507,8 @@ do_arith(p, pbuf, psize, ptp)
|
||||||
if (eval_expr(p->t_args[0], pbuf, psize, ptp) &&
|
if (eval_expr(p->t_args[0], pbuf, psize, ptp) &&
|
||||||
eval_expr(p->t_args[1], &buf, &size, &tp) &&
|
eval_expr(p->t_args[1], &buf, &size, &tp) &&
|
||||||
(balance_tp = balance(*ptp, tp)) &&
|
(balance_tp = balance(*ptp, tp)) &&
|
||||||
convert(pbuf, psize, ptp, balance_tp) &&
|
convert(pbuf, psize, ptp, balance_tp, balance_tp->ty_size) &&
|
||||||
convert(&buf, &size, &tp, balance_tp)) {
|
convert(&buf, &size, &tp, balance_tp, balance_tp->ty_size)) {
|
||||||
switch(balance_tp->ty_class) {
|
switch(balance_tp->ty_class) {
|
||||||
case T_INTEGER:
|
case T_INTEGER:
|
||||||
case T_ENUM:
|
case T_ENUM:
|
||||||
|
@ -537,6 +620,54 @@ do_arith(p, pbuf, psize, ptp)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
do_sft(p, pbuf, psize, ptp)
|
||||||
|
p_tree p;
|
||||||
|
char **pbuf;
|
||||||
|
long *psize;
|
||||||
|
p_type *ptp;
|
||||||
|
{
|
||||||
|
long l1, l2;
|
||||||
|
char *buf = 0;
|
||||||
|
long size;
|
||||||
|
p_type tp;
|
||||||
|
|
||||||
|
if (eval_expr(p->t_args[0], pbuf, psize, ptp) &&
|
||||||
|
eval_expr(p->t_args[1], &buf, &size, &tp) &&
|
||||||
|
convert(&buf, &size, &tp, int_type, int_size)) {
|
||||||
|
tp = *ptp;
|
||||||
|
if (tp->ty_class == T_SUBRANGE) {
|
||||||
|
tp = tp->ty_base;
|
||||||
|
}
|
||||||
|
switch(tp->ty_class) {
|
||||||
|
case T_INTEGER:
|
||||||
|
case T_ENUM:
|
||||||
|
case T_UNSIGNED:
|
||||||
|
l1 = get_int(*pbuf, *psize, tp->ty_class);
|
||||||
|
l2 = get_int(buf, size, T_INTEGER);
|
||||||
|
free(buf);
|
||||||
|
buf = 0;
|
||||||
|
switch(p->t_whichoper) {
|
||||||
|
case E_LSFT:
|
||||||
|
l1 <<= (int) l2;
|
||||||
|
break;
|
||||||
|
case E_RSFT:
|
||||||
|
if (tp->ty_class == T_INTEGER) l1 >>= (int) l2;
|
||||||
|
else l1 = (unsigned long) l1 >> (int) l2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
error("illegal operand type(s)");
|
||||||
|
free(buf);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (buf) free(buf);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
do_cmp(p, pbuf, psize, ptp)
|
do_cmp(p, pbuf, psize, ptp)
|
||||||
p_tree p;
|
p_tree p;
|
||||||
|
@ -553,8 +684,8 @@ do_cmp(p, pbuf, psize, ptp)
|
||||||
if (eval_expr(p->t_args[0], pbuf, psize, ptp) &&
|
if (eval_expr(p->t_args[0], pbuf, psize, ptp) &&
|
||||||
eval_expr(p->t_args[1], &buf, &size, &tp) &&
|
eval_expr(p->t_args[1], &buf, &size, &tp) &&
|
||||||
(balance_tp = balance(*ptp, tp)) &&
|
(balance_tp = balance(*ptp, tp)) &&
|
||||||
convert(pbuf, psize, ptp, balance_tp) &&
|
convert(pbuf, psize, ptp, balance_tp, balance_tp->ty_size) &&
|
||||||
convert(&buf, &size, &tp, balance_tp)) {
|
convert(&buf, &size, &tp, balance_tp, balance_tp->ty_size)) {
|
||||||
switch(balance_tp->ty_class) {
|
switch(balance_tp->ty_class) {
|
||||||
case T_INTEGER:
|
case T_INTEGER:
|
||||||
case T_ENUM:
|
case T_ENUM:
|
||||||
|
@ -665,7 +796,7 @@ do_in(p, pbuf, psize, ptp)
|
||||||
free(buf);
|
free(buf);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (! convert(pbuf, psize, ptp, tp->ty_setbase)) {
|
if (! convert(pbuf, psize, ptp, tp->ty_setbase, int_size)) {
|
||||||
free(buf);
|
free(buf);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -684,9 +815,9 @@ do_in(p, pbuf, psize, ptp)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
do_array(p, pbuf, psize, ptp)
|
array_addr(p, paddr, psize, ptp)
|
||||||
p_tree p;
|
p_tree p;
|
||||||
char **pbuf;
|
t_addr *paddr;
|
||||||
long *psize;
|
long *psize;
|
||||||
p_type *ptp;
|
p_type *ptp;
|
||||||
{
|
{
|
||||||
|
@ -695,7 +826,94 @@ do_array(p, pbuf, psize, ptp)
|
||||||
long size;
|
long size;
|
||||||
p_type tp;
|
p_type tp;
|
||||||
|
|
||||||
error("[ not implemented"); /* ??? */
|
if (eval_desig(p->t_args[0], paddr, psize, ptp) &&
|
||||||
|
eval_expr(p->t_args[1], &buf, &size, &tp)) {
|
||||||
|
if ((*ptp)->ty_class != T_ARRAY && (*ptp)->ty_class != T_POINTER) {
|
||||||
|
error("illegal left-hand side of [");
|
||||||
|
free(buf);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (! convert(&buf, &size, &tp, int_type, int_size)) {
|
||||||
|
free(buf);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
l = get_int(buf, size, T_INTEGER);
|
||||||
|
free(buf);
|
||||||
|
buf = 0;
|
||||||
|
if ((*ptp)->ty_class == T_ARRAY) {
|
||||||
|
if (l < (*ptp)->ty_lb || l > (*ptp)->ty_hb) {
|
||||||
|
error("array bound error");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
l -= (*ptp)->ty_lb;
|
||||||
|
*ptp = (*ptp)->ty_elements;
|
||||||
|
l *= (*currlang->arrayelsize)((*ptp)->ty_size);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*ptp = (*ptp)->ty_ptrto;
|
||||||
|
l *= (*ptp)->ty_size;
|
||||||
|
}
|
||||||
|
*psize = (*ptp)->ty_size;
|
||||||
|
*paddr += l;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
do_array(p, pbuf, psize, ptp)
|
||||||
|
p_tree p;
|
||||||
|
char **pbuf;
|
||||||
|
long *psize;
|
||||||
|
p_type *ptp;
|
||||||
|
{
|
||||||
|
t_addr a;
|
||||||
|
|
||||||
|
if (array_addr(p, &a, psize, ptp)) {
|
||||||
|
*pbuf = Malloc((unsigned int) *psize);
|
||||||
|
if (! get_bytes(*psize, a, *pbuf)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
select_addr(p, paddr, psize, ptp)
|
||||||
|
p_tree p;
|
||||||
|
t_addr *paddr;
|
||||||
|
long *psize;
|
||||||
|
p_type *ptp;
|
||||||
|
{
|
||||||
|
register p_type tp;
|
||||||
|
register struct fields *f;
|
||||||
|
register int nf;
|
||||||
|
|
||||||
|
if (eval_desig(p->t_args[0], paddr, psize, ptp)) {
|
||||||
|
tp = *ptp;
|
||||||
|
if (tp->ty_class != T_STRUCT && tp->ty_class != T_UNION) {
|
||||||
|
error("SELECT on non-struct");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (p->t_args[1]->t_oper != OP_NAME) {
|
||||||
|
error("right-hand side of SELECT not a name");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
for (nf = tp->ty_nfields, f = tp->ty_fields; nf; nf--, f++) {
|
||||||
|
if (! strcmp(f->fld_name, p->t_args[1]->t_str)) break;
|
||||||
|
}
|
||||||
|
if (! nf) {
|
||||||
|
error("'%s' not found", p->t_args[1]->t_str);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ??? this needs some work for bitfields ??? */
|
||||||
|
*paddr += f->fld_pos>>3;
|
||||||
|
*psize = f->fld_bitsize >> 3;
|
||||||
|
*ptp = f->fld_type;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -706,12 +924,14 @@ do_select(p, pbuf, psize, ptp)
|
||||||
long *psize;
|
long *psize;
|
||||||
p_type *ptp;
|
p_type *ptp;
|
||||||
{
|
{
|
||||||
long l;
|
t_addr a;
|
||||||
char *buf = 0;
|
if (select_addr(p, &a, psize, ptp)) {
|
||||||
long size;
|
*pbuf = Malloc((unsigned int) *psize);
|
||||||
p_type tp;
|
if (! get_bytes(*psize, a, *pbuf)) {
|
||||||
|
return 0;
|
||||||
error("SELECT not implemented"); /* ??? */
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -739,7 +959,10 @@ static int (*bin_op[])() = {
|
||||||
do_select,
|
do_select,
|
||||||
do_arith,
|
do_arith,
|
||||||
do_arith,
|
do_arith,
|
||||||
do_arith
|
do_arith,
|
||||||
|
0,
|
||||||
|
do_sft,
|
||||||
|
do_sft
|
||||||
};
|
};
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -810,3 +1033,73 @@ eval_expr(p, pbuf, psize, ptp)
|
||||||
}
|
}
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern t_addr get_addr();
|
||||||
|
|
||||||
|
int
|
||||||
|
eval_desig(p, paddr, psize, ptp)
|
||||||
|
p_tree p;
|
||||||
|
t_addr *paddr;
|
||||||
|
long *psize;
|
||||||
|
p_type *ptp;
|
||||||
|
{
|
||||||
|
register p_symbol sym;
|
||||||
|
int retval = 0;
|
||||||
|
t_addr a;
|
||||||
|
|
||||||
|
switch(p->t_oper) {
|
||||||
|
case OP_NAME:
|
||||||
|
case OP_SELECT:
|
||||||
|
sym = identify(p, VAR|REGVAR|LOCVAR|VARPAR);
|
||||||
|
if (! sym) return 0;
|
||||||
|
if (! (a = get_addr(sym, psize))) {
|
||||||
|
print_node(p, 0);
|
||||||
|
fputs(" currently not available\n", db_out);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*paddr = a;
|
||||||
|
*ptp = sym->sy_type;
|
||||||
|
retval = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OP_UNOP:
|
||||||
|
switch(p->t_whichoper) {
|
||||||
|
case E_DEREF:
|
||||||
|
if (ptr_addr(p, paddr, psize, ptp)) {
|
||||||
|
retval = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
print_node(p, 0);
|
||||||
|
fputs(" not a designator\n", db_out);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OP_BINOP:
|
||||||
|
switch(p->t_whichoper) {
|
||||||
|
case E_ARRAY:
|
||||||
|
if (array_addr(p, paddr, psize, ptp)) {
|
||||||
|
retval = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case E_SELECT:
|
||||||
|
if (select_addr(p, paddr, psize, ptp)) {
|
||||||
|
retval = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
print_node(p, 0);
|
||||||
|
fputs(" not a designator\n", db_out);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (! retval) {
|
||||||
|
*psize = 0;
|
||||||
|
}
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
|
@ -29,3 +29,7 @@
|
||||||
#define E_BAND 21 /* bitwise and */
|
#define E_BAND 21 /* bitwise and */
|
||||||
#define E_BOR 22 /* bitwise or */
|
#define E_BOR 22 /* bitwise or */
|
||||||
#define E_BXOR 23
|
#define E_BXOR 23
|
||||||
|
#define E_BNOT 24
|
||||||
|
#define E_DERSELECT 25 /* -> in C */
|
||||||
|
#define E_LSFT 26
|
||||||
|
#define E_RSFT 27
|
||||||
|
|
|
@ -46,6 +46,6 @@ find_language(suff)
|
||||||
p = p->l_next;
|
p = p->l_next;
|
||||||
}
|
}
|
||||||
if (! currlang) {
|
if (! currlang) {
|
||||||
currlang = def_dep;
|
currlang = c_dep;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,6 @@ struct langdep {
|
||||||
char *uns_fmt; /* unsigneds (format for long) */
|
char *uns_fmt; /* unsigneds (format for long) */
|
||||||
char *addr_fmt; /* address (format for long) */
|
char *addr_fmt; /* address (format for long) */
|
||||||
char *real_fmt; /* real (format for double) */
|
char *real_fmt; /* real (format for double) */
|
||||||
char *char_fmt; /* character (format for int) */
|
|
||||||
|
|
||||||
/* display openers and closers: */
|
/* display openers and closers: */
|
||||||
char *open_array_display;
|
char *open_array_display;
|
||||||
|
@ -25,8 +24,10 @@ struct langdep {
|
||||||
|
|
||||||
/* language dependant routines: */
|
/* language dependant routines: */
|
||||||
int (*printstring)();
|
int (*printstring)();
|
||||||
|
int (*printchar)();
|
||||||
long (*arrayelsize)();
|
long (*arrayelsize)();
|
||||||
int (*op_prio)();
|
int (*binop_prio)();
|
||||||
|
int (*unop_prio)();
|
||||||
int (*get_string)();
|
int (*get_string)();
|
||||||
int (*get_name)();
|
int (*get_name)();
|
||||||
int (*get_number)();
|
int (*get_number)();
|
||||||
|
@ -34,7 +35,7 @@ struct langdep {
|
||||||
int (*printop)();
|
int (*printop)();
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct langdep *m2_dep, *def_dep, *c_dep, *currlang;
|
extern struct langdep *m2_dep, *c_dep, *currlang;
|
||||||
|
|
||||||
extern int find_language();
|
extern int find_language();
|
||||||
|
|
||||||
|
|
|
@ -23,12 +23,14 @@ extern double
|
||||||
|
|
||||||
static int
|
static int
|
||||||
print_string(),
|
print_string(),
|
||||||
|
print_char(),
|
||||||
get_number(),
|
get_number(),
|
||||||
get_name(),
|
get_name(),
|
||||||
get_token(),
|
get_token(),
|
||||||
get_string(),
|
get_string(),
|
||||||
print_op(),
|
print_op(),
|
||||||
op_prio();
|
binop_prio(),
|
||||||
|
unop_prio();
|
||||||
|
|
||||||
static long
|
static long
|
||||||
array_elsize();
|
array_elsize();
|
||||||
|
@ -41,8 +43,7 @@ static struct langdep m2 = {
|
||||||
"%lXH",
|
"%lXH",
|
||||||
"%lu",
|
"%lu",
|
||||||
"%lXH",
|
"%lXH",
|
||||||
"%g",
|
"%G",
|
||||||
"%oC",
|
|
||||||
|
|
||||||
"[",
|
"[",
|
||||||
"]",
|
"]",
|
||||||
|
@ -52,8 +53,10 @@ static struct langdep m2 = {
|
||||||
"}",
|
"}",
|
||||||
|
|
||||||
print_string,
|
print_string,
|
||||||
|
print_char,
|
||||||
array_elsize,
|
array_elsize,
|
||||||
op_prio,
|
binop_prio,
|
||||||
|
unop_prio,
|
||||||
get_string,
|
get_string,
|
||||||
get_name,
|
get_name,
|
||||||
get_number,
|
get_number,
|
||||||
|
@ -63,6 +66,13 @@ static struct langdep m2 = {
|
||||||
|
|
||||||
struct langdep *m2_dep = &m2;
|
struct langdep *m2_dep = &m2;
|
||||||
|
|
||||||
|
static int
|
||||||
|
print_char(c)
|
||||||
|
int c;
|
||||||
|
{
|
||||||
|
fprintf(db_out, (c >= 040 && c < 0177) ? "'%c'" : "%oC", c);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
print_string(s, len)
|
print_string(s, len)
|
||||||
char *s;
|
char *s;
|
||||||
|
@ -89,16 +99,26 @@ array_elsize(size)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
op_prio(op)
|
unop_prio(op)
|
||||||
int op;
|
int op;
|
||||||
{
|
{
|
||||||
switch(op) {
|
switch(op) {
|
||||||
case E_NOT:
|
case E_NOT:
|
||||||
return 5;
|
return 5;
|
||||||
|
case E_MIN:
|
||||||
|
case E_PLUS:
|
||||||
|
return 3;
|
||||||
case E_SELECT:
|
case E_SELECT:
|
||||||
return 9;
|
return 9;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
binop_prio(op)
|
||||||
|
int op;
|
||||||
|
{
|
||||||
|
switch(op) {
|
||||||
case E_AND:
|
case E_AND:
|
||||||
case E_MUL:
|
case E_MUL:
|
||||||
case E_DIV:
|
case E_DIV:
|
||||||
|
@ -230,6 +250,7 @@ get_number(ch)
|
||||||
/* a real real constant */
|
/* a real real constant */
|
||||||
if (np < &buf[512]) *np++ = '.';
|
if (np < &buf[512]) *np++ = '.';
|
||||||
|
|
||||||
|
ch = getc(db_in);
|
||||||
while (is_dig(ch)) {
|
while (is_dig(ch)) {
|
||||||
/* Fractional part
|
/* Fractional part
|
||||||
*/
|
*/
|
||||||
|
@ -452,6 +473,19 @@ print_op(p)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OP_BINOP:
|
case OP_BINOP:
|
||||||
|
if (p->t_whichoper == E_ARRAY) {
|
||||||
|
print_node(p->t_args[0], 0);
|
||||||
|
fputs("[", db_out);
|
||||||
|
print_node(p->t_args[1], 0);
|
||||||
|
fputs("]", db_out);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (p->t_whichoper == E_SELECT) {
|
||||||
|
print_node(p->t_args[0], 0);
|
||||||
|
fputs(".", db_out);
|
||||||
|
print_node(p->t_args[1], 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
fputs("(", db_out);
|
fputs("(", db_out);
|
||||||
print_node(p->t_args[0], 0);
|
print_node(p->t_args[0], 0);
|
||||||
switch(p->t_whichoper) {
|
switch(p->t_whichoper) {
|
||||||
|
@ -497,9 +531,6 @@ print_op(p)
|
||||||
case E_GT:
|
case E_GT:
|
||||||
fputs(">", db_out);
|
fputs(">", db_out);
|
||||||
break;
|
break;
|
||||||
case E_SELECT:
|
|
||||||
fputs(".", db_out);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
print_node(p->t_args[1], 0);
|
print_node(p->t_args[1], 0);
|
||||||
fputs(")", db_out);
|
fputs(")", db_out);
|
||||||
|
|
|
@ -20,6 +20,7 @@ OP_WHERE 0 do_where
|
||||||
OP_STATUS 0 do_status
|
OP_STATUS 0 do_status
|
||||||
OP_DELETE 0 do_delete
|
OP_DELETE 0 do_delete
|
||||||
OP_SELECT 2 0
|
OP_SELECT 2 0
|
||||||
|
OP_SET 2 do_set
|
||||||
OP_PRINT 1 do_print
|
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
|
||||||
|
|
|
@ -40,7 +40,7 @@ print_unsigned(tp, v)
|
||||||
long v;
|
long v;
|
||||||
{
|
{
|
||||||
if (tp == uchar_type) {
|
if (tp == uchar_type) {
|
||||||
fprintf(db_out, currlang->char_fmt, (int) v);
|
(*currlang->printchar)((int) v);
|
||||||
}
|
}
|
||||||
else fprintf(db_out, currlang->uns_fmt, v);
|
else fprintf(db_out, currlang->uns_fmt, v);
|
||||||
}
|
}
|
||||||
|
@ -51,7 +51,7 @@ print_integer(tp, v)
|
||||||
long v;
|
long v;
|
||||||
{
|
{
|
||||||
if (tp == char_type) {
|
if (tp == char_type) {
|
||||||
fprintf(db_out, currlang->char_fmt, (int) v);
|
(*currlang->printchar)((int) v);
|
||||||
}
|
}
|
||||||
else fprintf(db_out, currlang->decint_fmt, v);
|
else fprintf(db_out, currlang->decint_fmt, v);
|
||||||
}
|
}
|
||||||
|
@ -301,20 +301,3 @@ print_val(tp, tp_sz, addr, compressed, indent)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
print_sym(sym)
|
|
||||||
p_symbol sym;
|
|
||||||
{
|
|
||||||
char *buf;
|
|
||||||
long size;
|
|
||||||
|
|
||||||
if (get_value(sym, &buf, &size)) {
|
|
||||||
fputs(" = ", db_out);
|
|
||||||
print_val(sym->sy_type, size, buf, 0, 0);
|
|
||||||
if (buf) free(buf);
|
|
||||||
fputs("\n", db_out);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
|
@ -373,11 +373,33 @@ get_bytes(size, from, to)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (answer.m_type == FAIL) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
assert(answer.m_type == DATA && answer.m_size == m.m_size);
|
assert(answer.m_type == DATA && answer.m_size == m.m_size);
|
||||||
|
|
||||||
return ureceive(to, answer.m_size);
|
return ureceive(to, answer.m_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
set_bytes(size, from, to)
|
||||||
|
long size;
|
||||||
|
char *from;
|
||||||
|
t_addr to;
|
||||||
|
{
|
||||||
|
struct message_hdr m;
|
||||||
|
|
||||||
|
m.m_type = SETBYTES;
|
||||||
|
m.m_size = size;
|
||||||
|
ATOBUF(m.m_buf, (char *) to);
|
||||||
|
|
||||||
|
return uputm(&m)
|
||||||
|
&& usend(from, size)
|
||||||
|
&& ugetm(&m)
|
||||||
|
&& m.m_type != FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
get_dump(globmessage, globbuf, stackmessage, stackbuf)
|
get_dump(globmessage, globbuf, stackmessage, stackbuf)
|
||||||
struct message_hdr *globmessage, *stackmessage;
|
struct message_hdr *globmessage, *stackmessage;
|
||||||
|
@ -389,6 +411,7 @@ get_dump(globmessage, globbuf, stackmessage, stackbuf)
|
||||||
if (! could_send(&m, 0)) {
|
if (! could_send(&m, 0)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
if (answer.m_type == FAIL) return 0;
|
||||||
assert(answer.m_type == DGLOB);
|
assert(answer.m_type == DGLOB);
|
||||||
*globmessage = answer;
|
*globmessage = answer;
|
||||||
*globbuf = Malloc((unsigned) answer.m_size);
|
*globbuf = Malloc((unsigned) answer.m_size);
|
||||||
|
@ -441,6 +464,7 @@ get_EM_regs(level)
|
||||||
if (! could_send(&m, 0)) {
|
if (! could_send(&m, 0)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
if (answer.m_type == FAIL) return 0;
|
||||||
*to++ = (t_addr) BUFTOA(answer.m_buf);
|
*to++ = (t_addr) BUFTOA(answer.m_buf);
|
||||||
*to++ = (t_addr) BUFTOA(answer.m_buf+pointer_size);
|
*to++ = (t_addr) BUFTOA(answer.m_buf+pointer_size);
|
||||||
*to++ = (t_addr) BUFTOA(answer.m_buf+2*pointer_size);
|
*to++ = (t_addr) BUFTOA(answer.m_buf+2*pointer_size);
|
||||||
|
@ -458,7 +482,7 @@ set_pc(PC)
|
||||||
m.m_type = SETEMREGS;
|
m.m_type = SETEMREGS;
|
||||||
m.m_size = 0;
|
m.m_size = 0;
|
||||||
ATOBUF(m.m_buf+PC_OFF*pointer_size, (char *)PC);
|
ATOBUF(m.m_buf+PC_OFF*pointer_size, (char *)PC);
|
||||||
return could_send(&m, 0);
|
return could_send(&m, 0) && answer.m_type != FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -469,7 +493,7 @@ send_cont(stop_message)
|
||||||
|
|
||||||
m.m_type = (CONT | (db_ss ? DB_SS : 0));
|
m.m_type = (CONT | (db_ss ? DB_SS : 0));
|
||||||
m.m_size = 0;
|
m.m_size = 0;
|
||||||
return could_send(&m, stop_message);
|
return could_send(&m, stop_message) && answer.m_type != FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -482,7 +506,7 @@ do_single_step(type, count)
|
||||||
m.m_type = type | (db_ss ? DB_SS : 0);
|
m.m_type = type | (db_ss ? DB_SS : 0);
|
||||||
m.m_size = count;
|
m.m_size = count;
|
||||||
single_stepping = 1;
|
single_stepping = 1;
|
||||||
if (could_send(&m, 1)) {
|
if (could_send(&m, 1) && answer.m_type != FAIL) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
single_stepping = 0;
|
single_stepping = 0;
|
||||||
|
|
|
@ -94,17 +94,6 @@ Lookfromscope(id, class, sc)
|
||||||
return (p_symbol) 0;
|
return (p_symbol) 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Lookup a definition for 'id' with class in the 'class' bitset,
|
|
||||||
starting in scope 'CurrentScope' and also looking in enclosing scopes.
|
|
||||||
*/
|
|
||||||
p_symbol
|
|
||||||
Lookfor(id, class)
|
|
||||||
register struct idf *id;
|
|
||||||
int class;
|
|
||||||
{
|
|
||||||
return Lookfromscope(id, class, CurrentScope);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern char *strrindex();
|
extern char *strrindex();
|
||||||
|
|
||||||
p_symbol
|
p_symbol
|
||||||
|
@ -153,12 +142,12 @@ consistent(p, sc)
|
||||||
|
|
||||||
switch(p->t_oper) {
|
switch(p->t_oper) {
|
||||||
case OP_NAME:
|
case OP_NAME:
|
||||||
sym = Lookfromscope(p->t_idf, FILELINK|FILESYM|PROC|MODULE, sc);
|
sym = Lookfromscope(p->t_idf, FILELINK|FILESYM|PROC|FUNCTION|MODULE, sc);
|
||||||
return sym != 0;
|
return sym != 0;
|
||||||
|
|
||||||
case OP_SELECT:
|
case OP_SELECT:
|
||||||
arg = p->t_args[1];
|
arg = p->t_args[1];
|
||||||
sym = Lookfromscope(arg->t_idf, FILELINK|FILESYM|PROC|MODULE, sc);
|
sym = Lookfromscope(arg->t_idf, FILELINK|FILESYM|PROC|FUNCTION|MODULE, sc);
|
||||||
if (sym == 0) return 0;
|
if (sym == 0) return 0;
|
||||||
return consistent(p, sym->sy_scope);
|
return consistent(p, sym->sy_scope);
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/* $Header$
|
/* $Header$ */
|
||||||
Symbol table data structure.
|
|
||||||
|
/* Symbol table data structure.
|
||||||
Each identifier structure refers to a list of possible meanings of this
|
Each identifier structure refers to a list of possible meanings of this
|
||||||
identifier. Each of these meanings is represented by a "symbol" structure.
|
identifier. Each of these meanings is represented by a "symbol" structure.
|
||||||
*/
|
*/
|
||||||
|
@ -39,14 +40,12 @@ typedef struct symbol {
|
||||||
union {
|
union {
|
||||||
t_const syv_const; /* CONST */
|
t_const syv_const; /* CONST */
|
||||||
t_name syv_name;
|
t_name syv_name;
|
||||||
/* 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;
|
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_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
|
#define sy_field sy_v.syv_field
|
||||||
|
@ -54,7 +53,7 @@ typedef struct symbol {
|
||||||
|
|
||||||
/* ALLOCDEF "symbol" 50 */
|
/* ALLOCDEF "symbol" 50 */
|
||||||
|
|
||||||
extern p_symbol NewSymbol(), Lookup(), Lookfor(), Lookfromscope(), add_file();
|
extern p_symbol NewSymbol(), Lookup(), Lookfromscope(), add_file();
|
||||||
extern p_symbol identify();
|
extern p_symbol identify();
|
||||||
|
|
||||||
extern p_symbol currfile;
|
extern p_symbol currfile;
|
||||||
|
|
|
@ -60,6 +60,8 @@ struct tokenname tkidf[] = { /* names of the identifier tokens */
|
||||||
{DUMP, "dump"},
|
{DUMP, "dump"},
|
||||||
{RESTORE, "restore"},
|
{RESTORE, "restore"},
|
||||||
{TRACE, "trace"},
|
{TRACE, "trace"},
|
||||||
|
{SET, "set"},
|
||||||
|
{TO, "to"},
|
||||||
{-1, "quit"},
|
{-1, "quit"},
|
||||||
{0, ""}
|
{0, ""}
|
||||||
};
|
};
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include "symbol.h"
|
#include "symbol.h"
|
||||||
#include "langdep.h"
|
#include "langdep.h"
|
||||||
#include "type.h"
|
#include "type.h"
|
||||||
|
#include "expr.h"
|
||||||
|
|
||||||
extern FILE *db_out;
|
extern FILE *db_out;
|
||||||
extern t_lineno currline;
|
extern t_lineno currline;
|
||||||
|
@ -75,6 +76,21 @@ mknode(va_alist)
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
adjust_oper(pp)
|
||||||
|
p_tree *pp;
|
||||||
|
{
|
||||||
|
register p_tree p = *pp, p1;
|
||||||
|
|
||||||
|
switch(p->t_whichoper) {
|
||||||
|
case E_DERSELECT:
|
||||||
|
p1 = mknode(OP_UNOP, p->t_args[0]);
|
||||||
|
p1->t_whichoper = E_DEREF;
|
||||||
|
p->t_args[0] = p1;
|
||||||
|
p->t_whichoper = E_SELECT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
freenode(p)
|
freenode(p)
|
||||||
register p_tree p;
|
register p_tree p;
|
||||||
{
|
{
|
||||||
|
@ -112,6 +128,12 @@ print_node(p, top_level)
|
||||||
fputs("file ", db_out);
|
fputs("file ", db_out);
|
||||||
print_node(p->t_args[0], 0);
|
print_node(p->t_args[0], 0);
|
||||||
break;
|
break;
|
||||||
|
case OP_SET:
|
||||||
|
fputs("set ", db_out);
|
||||||
|
print_node(p->t_args[0], 0);
|
||||||
|
fputs(" to ", db_out);
|
||||||
|
print_node(p->t_args[1], 0);
|
||||||
|
break;
|
||||||
case OP_DELETE:
|
case OP_DELETE:
|
||||||
fprintf(db_out, "delete %d", p->t_ival);
|
fprintf(db_out, "delete %d", p->t_ival);
|
||||||
break;
|
break;
|
||||||
|
@ -332,7 +354,7 @@ get_pos(p)
|
||||||
|
|
||||||
case OP_NAME:
|
case OP_NAME:
|
||||||
case OP_SELECT:
|
case OP_SELECT:
|
||||||
sym = identify(p, PROC|MODULE);
|
sym = identify(p, FUNCTION|PROC|MODULE);
|
||||||
if (! sym) {
|
if (! sym) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -563,6 +585,27 @@ do_print(p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
do_set(p)
|
||||||
|
p_tree p;
|
||||||
|
{
|
||||||
|
char *buf = 0;
|
||||||
|
long size, size2;
|
||||||
|
p_type tp, tp2;
|
||||||
|
t_addr a;
|
||||||
|
|
||||||
|
if (! eval_desig(p->t_args[0], &a, &size, &tp) ||
|
||||||
|
! eval_expr(p->t_args[1], &buf, &size2, &tp2) ||
|
||||||
|
! convert(&buf, &size2, &tp2, tp, size)) {
|
||||||
|
if (buf) free(buf);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! set_bytes(size, buf, a)) {
|
||||||
|
error("could not handle this SET request");
|
||||||
|
}
|
||||||
|
free(buf);
|
||||||
|
}
|
||||||
|
|
||||||
perform(p, a)
|
perform(p, a)
|
||||||
register p_tree p;
|
register p_tree p;
|
||||||
t_addr a;
|
t_addr a;
|
||||||
|
|
|
@ -177,6 +177,25 @@ array_type(bound_type, el_type)
|
||||||
|
|
||||||
tp->ty_class = T_ARRAY;
|
tp->ty_class = T_ARRAY;
|
||||||
tp->ty_index = bound_type;
|
tp->ty_index = bound_type;
|
||||||
|
switch(bound_type->ty_class) {
|
||||||
|
case T_SUBRANGE:
|
||||||
|
if (bound_type->ty_A) break;
|
||||||
|
tp->ty_lb = bound_type->ty_low;
|
||||||
|
tp->ty_hb = bound_type->ty_up;
|
||||||
|
break;
|
||||||
|
case T_ENUM:
|
||||||
|
tp->ty_lb = 0;
|
||||||
|
tp->ty_hb = bound_type->ty_nenums-1;
|
||||||
|
break;
|
||||||
|
case T_UNSIGNED:
|
||||||
|
tp->ty_lb = 0;
|
||||||
|
tp->ty_hb = bound_type->ty_size == 1 ? 255 : 65535L;
|
||||||
|
break;
|
||||||
|
case T_INTEGER:
|
||||||
|
tp->ty_lb = bound_type->ty_size == 1 ? -128 : -32768;
|
||||||
|
tp->ty_hb = bound_type->ty_size == 1 ? 127 : 32767;
|
||||||
|
break;
|
||||||
|
}
|
||||||
tp->ty_elements = el_type;
|
tp->ty_elements = el_type;
|
||||||
tp->ty_size = (*currlang->arrayelsize)(el_type->ty_size) * nel(bound_type);
|
tp->ty_size = (*currlang->arrayelsize)(el_type->ty_size) * nel(bound_type);
|
||||||
return tp;
|
return tp;
|
||||||
|
@ -384,8 +403,10 @@ compute_size(tp, AB)
|
||||||
if (tp->ty_index->ty_A & 1) {
|
if (tp->ty_index->ty_A & 1) {
|
||||||
low = BUFTOI(AB+tp->ty_index->ty_low);
|
low = BUFTOI(AB+tp->ty_index->ty_low);
|
||||||
} else low = tp->ty_index->ty_low;
|
} else low = tp->ty_index->ty_low;
|
||||||
|
tp->ty_lb = low;
|
||||||
if (tp->ty_index->ty_A & 2) {
|
if (tp->ty_index->ty_A & 2) {
|
||||||
high = BUFTOI(AB+tp->ty_index->ty_up);
|
high = BUFTOI(AB+tp->ty_index->ty_up);
|
||||||
} else high = tp->ty_index->ty_up;
|
} else high = tp->ty_index->ty_up;
|
||||||
|
tp->ty_hb = high;
|
||||||
return (high - low + 1) * tp->ty_elements->ty_size;
|
return (high - low + 1) * tp->ty_elements->ty_size;
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,9 +63,12 @@ typedef struct type {
|
||||||
#define ty_fileof ty_v.typ_ptrto
|
#define ty_fileof ty_v.typ_ptrto
|
||||||
/* arrays: */
|
/* arrays: */
|
||||||
struct {
|
struct {
|
||||||
|
long typ_lb, typ_hb;
|
||||||
struct type *typ_index;
|
struct type *typ_index;
|
||||||
struct type *typ_elements;
|
struct type *typ_elements;
|
||||||
} ty_array;
|
} ty_array;
|
||||||
|
#define ty_lb ty_v.ty_array.typ_lb
|
||||||
|
#define ty_hb ty_v.ty_array.typ_hb
|
||||||
#define ty_index ty_v.ty_array.typ_index
|
#define ty_index ty_v.ty_array.typ_index
|
||||||
#define ty_elements ty_v.ty_array.typ_elements
|
#define ty_elements ty_v.ty_array.typ_elements
|
||||||
/* subranges: */
|
/* subranges: */
|
||||||
|
@ -115,5 +118,5 @@ extern long
|
||||||
extern p_type char_type, uchar_type, bool_type, int_type,
|
extern p_type char_type, uchar_type, bool_type, int_type,
|
||||||
long_type, double_type, string_type;
|
long_type, double_type, string_type;
|
||||||
extern p_type void_type, incomplete_type;
|
extern p_type void_type, incomplete_type;
|
||||||
extern long int_size;
|
extern long int_size, pointer_size;
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
/* $Header$ */
|
/* $Header$ */
|
||||||
|
|
||||||
#include <alloc.h>
|
#include <alloc.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
#include "position.h"
|
#include "position.h"
|
||||||
#include "scope.h"
|
#include "scope.h"
|
||||||
#include "symbol.h"
|
#include "symbol.h"
|
||||||
#include "type.h"
|
#include "type.h"
|
||||||
#include "message.h"
|
#include "message.h"
|
||||||
|
#include "langdep.h"
|
||||||
|
|
||||||
int stack_offset; /* for up and down commands */
|
int stack_offset; /* for up and down commands */
|
||||||
|
|
||||||
|
@ -14,70 +16,27 @@ extern long pointer_size;
|
||||||
extern t_addr *get_EM_regs();
|
extern t_addr *get_EM_regs();
|
||||||
extern char *memcpy();
|
extern char *memcpy();
|
||||||
|
|
||||||
/* Get the value of the symbol indicated by sym.
|
/* Get the address of the object indicated by sym.
|
||||||
Return 0 on failure,
|
Return 0 on failure,
|
||||||
1 on success.
|
address on success.
|
||||||
On success, 'buf' contains the value, and 'size' contains the size.
|
*psize will contain size of object.
|
||||||
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
|
t_addr
|
||||||
get_value(sym, buf, psize)
|
get_addr(sym, psize)
|
||||||
register p_symbol sym;
|
register p_symbol sym;
|
||||||
char **buf;
|
|
||||||
long *psize;
|
long *psize;
|
||||||
{
|
{
|
||||||
p_type tp = sym->sy_type;
|
p_type tp = sym->sy_type;
|
||||||
long size = tp->ty_size;
|
long size = tp->ty_size;
|
||||||
int retval = 0;
|
|
||||||
t_addr *EM_regs;
|
t_addr *EM_regs;
|
||||||
int i;
|
int i;
|
||||||
p_scope sc, symsc;
|
p_scope sc, symsc;
|
||||||
char *AB;
|
|
||||||
|
|
||||||
*buf = 0;
|
*psize = size;
|
||||||
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 */
|
||||||
*buf = Malloc((unsigned) size);
|
return (t_addr) sym->sy_name.nm_value;
|
||||||
if (get_bytes(size, (t_addr) sym->sy_name.nm_value, *buf)) {
|
|
||||||
retval = 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CONST:
|
|
||||||
*buf = Malloc((unsigned) size);
|
|
||||||
switch(tp->ty_class) {
|
|
||||||
case T_REAL:
|
|
||||||
if (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 (size == 1) {
|
|
||||||
*((char *) *buf) = sym->sy_const.co_ival;
|
|
||||||
}
|
|
||||||
else if (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) size);
|
|
||||||
break;
|
|
||||||
case T_STRING:
|
|
||||||
memcpy(*buf, sym->sy_const.co_sval, (int) size);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
fatal("strange constant");
|
|
||||||
}
|
|
||||||
retval = 1;
|
|
||||||
break;
|
break;
|
||||||
case VARPAR:
|
case VARPAR:
|
||||||
case LOCVAR:
|
case LOCVAR:
|
||||||
|
@ -110,17 +69,8 @@ get_value(sym, buf, psize)
|
||||||
|
|
||||||
if (sym->sy_class == LOCVAR) {
|
if (sym->sy_class == LOCVAR) {
|
||||||
/* Either local variable or value parameter */
|
/* Either local variable or value parameter */
|
||||||
*buf = Malloc((unsigned) size);
|
return EM_regs[sym->sy_name.nm_value < 0 ? LB_OFF : AB_OFF] +
|
||||||
if (get_bytes(size,
|
(t_addr) sym->sy_name.nm_value;
|
||||||
EM_regs[sym->sy_name.nm_value < 0
|
|
||||||
? LB_OFF
|
|
||||||
: AB_OFF
|
|
||||||
] +
|
|
||||||
(t_addr) sym->sy_name.nm_value,
|
|
||||||
*buf)) {
|
|
||||||
retval = 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we get here, we have a var parameter. Get the parameters
|
/* If we get here, we have a var parameter. Get the parameters
|
||||||
|
@ -128,6 +78,8 @@ get_value(sym, buf, psize)
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
p_type proctype = sc->sc_definedby->sy_type;
|
p_type proctype = sc->sc_definedby->sy_type;
|
||||||
|
t_addr a;
|
||||||
|
char *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;
|
||||||
|
@ -137,15 +89,84 @@ get_value(sym, buf, psize)
|
||||||
}
|
}
|
||||||
if ((size = tp->ty_size) == 0) {
|
if ((size = tp->ty_size) == 0) {
|
||||||
size = compute_size(tp, AB);
|
size = compute_size(tp, AB);
|
||||||
|
*psize = size;
|
||||||
}
|
}
|
||||||
|
a = (t_addr) BUFTOA(AB+sym->sy_name.nm_value);
|
||||||
|
free(AB);
|
||||||
|
return a;
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the value of the symbol indicated by sym.
|
||||||
|
Return 0 on failure,
|
||||||
|
1 on success.
|
||||||
|
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, psize)
|
||||||
|
register p_symbol sym;
|
||||||
|
char **buf;
|
||||||
|
long *psize;
|
||||||
|
{
|
||||||
|
p_type tp = sym->sy_type;
|
||||||
|
int retval = 0;
|
||||||
|
t_addr a;
|
||||||
|
long size = tp->ty_size;
|
||||||
|
|
||||||
|
*buf = 0;
|
||||||
|
switch(sym->sy_class) {
|
||||||
|
case CONST:
|
||||||
*buf = Malloc((unsigned) size);
|
*buf = Malloc((unsigned) size);
|
||||||
if (get_bytes(size,
|
switch(tp->ty_class) {
|
||||||
(t_addr) BUFTOA(AB+sym->sy_name.nm_value),
|
case T_REAL:
|
||||||
*buf)) {
|
if (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 (size == sizeof(char)) {
|
||||||
|
*((char *) *buf) = sym->sy_const.co_ival;
|
||||||
|
}
|
||||||
|
else if (size == sizeof(short)) {
|
||||||
|
*((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) size);
|
||||||
|
break;
|
||||||
|
case T_STRING:
|
||||||
|
memcpy(*buf, sym->sy_const.co_sval, (int) size);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fatal("strange constant");
|
||||||
|
}
|
||||||
|
retval = 1;
|
||||||
|
break;
|
||||||
|
case VAR:
|
||||||
|
case VARPAR:
|
||||||
|
case LOCVAR:
|
||||||
|
a = get_addr(sym, psize);
|
||||||
|
if (a) {
|
||||||
|
size = *psize;
|
||||||
|
*buf = Malloc((unsigned) size);
|
||||||
|
if (get_bytes(size, a, *buf)) {
|
||||||
retval = 1;
|
retval = 1;
|
||||||
}
|
}
|
||||||
free(AB);
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue