/* Copyright (c) 1980 Regents of the University of California */
static char sccsid
[] = "@(#)asexpr.c 4.2 8/15/80";
* Tables for combination of operands.
#define XTXRN 5<<1 /* indexes last row/column when right shifted */
readonly
char pltab
[6][6] = {
/* UND ABS TXT DAT BSS EXT */
/*UND*/ XUNDEF
, XUNDEF
, XUNDEF
, XUNDEF
, XUNDEF
, XUNDEF
,
/*ABS*/ XUNDEF
, XABS
, XTEXT
, XDATA
, XBSS
, XXTRN
,
/*TXT*/ XUNDEF
, XTEXT
, ERR
, ERR
, ERR
, ERR
,
/*DAT*/ XUNDEF
, XDATA
, ERR
, ERR
, ERR
, ERR
,
/*BSS*/ XUNDEF
, XBSS
, ERR
, ERR
, ERR
, ERR
,
/*EXT*/ XUNDEF
, XXTRN
, ERR
, ERR
, ERR
, ERR
,
readonly
char mintab
[6][6] = {
/* UND ABS TXT DAT BSS EXT */
/*UND*/ XUNDEF
, XUNDEF
, XUNDEF
, XUNDEF
, XUNDEF
, XUNDEF
,
/*ABS*/ XUNDEF
, XABS
, ERR
, ERR
, ERR
, ERR
,
/*TXT*/ XUNDEF
, XTEXT
, XABS
, ERR
, ERR
, ERR
,
/*DAT*/ XUNDEF
, XDATA
, ERR
, XABS
, ERR
, ERR
,
/*BSS*/ XUNDEF
, XBSS
, ERR
, ERR
, XABS
, ERR
,
/*EXT*/ XUNDEF
, XXTRN
, ERR
, ERR
, ERR
, ERR
,
* table for other operators
readonly
char othtab
[6][6] = {
/* UND ABS TXT DAT BSS EXT */
/*UND*/ XUNDEF
, XUNDEF
, XUNDEF
, XUNDEF
, XUNDEF
, XUNDEF
,
/*ABS*/ XUNDEF
, XABS
, ERR
, ERR
, ERR
, ERR
,
/*TXT*/ XUNDEF
, ERR
, ERR
, ERR
, ERR
, ERR
,
/*DAT*/ XUNDEF
, ERR
, ERR
, ERR
, ERR
, ERR
,
/*BSS*/ XUNDEF
, ERR
, ERR
, ERR
, ERR
, ERR
,
/*EXT*/ XUNDEF
, ERR
, ERR
, ERR
, ERR
, ERR
,
register struct exp
*exp1
, *exp2
;
register e1_type
, e2_type
;
lastnam
=0; /* kludge for jxxx instructions */
e1_type
= exp1
->e_xtype
&XTYPE
;
e2_type
= exp2
->e_xtype
&XTYPE
;
if (exp1
->e_xtype
==XXTRN
+XUNDEF
)
if (exp2
->e_xtype
==XXTRN
+XUNDEF
)
if (exp1
->e_xloc
!=exp2
->e_xloc
&& e1_type
==e2_type
)
e1_type
= e2_type
= XTXRN
; /* error on != loc ctrs */
e1_type
>>= 1; /*dispose of the external (XXTRN) bit*/
exp1
->e_xvalue
+= exp2
->e_xvalue
;
back_type
= pltab
[e1_type
][e2_type
];
exp1
->e_xvalue
-= exp2
->e_xvalue
;
back_type
= mintab
[e1_type
][e2_type
];
exp1
->e_xvalue
|= exp2
->e_xvalue
;
exp1
->e_xvalue
^= exp2
->e_xvalue
;
exp1
->e_xvalue
&= exp2
->e_xvalue
;
exp1
->e_xvalue
|= ~exp2
->e_xvalue
;
exp1
->e_xvalue
<<= exp2
->e_xvalue
;
exp1
->e_xvalue
>>= exp2
->e_xvalue
;
exp1
->e_xvalue
|= ~ exp2
->e_xvalue
;
exp1
->e_xvalue
*= exp2
->e_xvalue
;
exp1
->e_xvalue
/= exp2
->e_xvalue
;
yyerror("Divide check (modulo)");
exp1
->e_xvalue
%= exp2
->e_xvalue
;
back_type
= othtab
[e1_type
][e2_type
];
yyerror("Internal error: unknown operator");
exp1
->e_xname
= exp2
->e_xname
;
exp1
->e_xtype
= back_type
| (
(exp1
->e_xtype
|exp2
->e_xtype
) & (XFORW
|XXTRN
) );
yyerror("Relocation error");
#define clobber(val, set) tokensets[(val)] |= (set)
clobber(SEMI
, LINSTBEGIN
);
clobber(INT
, LINSTBEGIN
);
clobber(NAME
, YUKKYEXPRBEG
+ LINSTBEGIN
);
clobber(INSTn
, YUKKYEXPRBEG
);
clobber(INST0
, YUKKYEXPRBEG
);
clobber(REG
, YUKKYEXPRBEG
);
clobber(BFINT
, YUKKYEXPRBEG
);
clobber(INT
, SAFEEXPRBEG
);
clobber(FLTNUM
, SAFEEXPRBEG
);
clobber(MINUS
, ADDOPS
+ EBEGOPS
);
clobber(TILDE
, MULOPS
+ EBEGOPS
);
clobber(REGOP
, MULOPS
); /* % */
* We keep the current token class in this global variable, so
* the recursive descent expression analyzers can talk amongst
* themselves, and so that we may use the macros shift and shift over
extern int yylval
; /*the value of the lexical value*/
extern struct exp
*xp
; /*the next free expression slot*/
int exprparse(inval
, backexpr
) /*return the value the read head is sitting on*/
register struct exp
*lexpr
;
while (INTOKSET(val
, ADDOPS
)){
lexpr
= combine(op
, lexpr
, boolterm());
register struct exp
*lexpr
;
while(INTOKSET(val
, BOOLOPS
)){
lexpr
= combine(op
, lexpr
, term());
register struct exp
*lexpr
;
while(INTOKSET(val
, MULOPS
)){
lexpr
= combine(op
, lexpr
, factor());
extern int droppedLP
; /*called exprparse after consuming an LP*/
if (val
== LP
|| droppedLP
){
val
= exprparse(val
, &lexpr
);
yyerror("right parenthesis expected");
if (INTOKSET(val
, YUKKYEXPRBEG
)){
lexpr
= yukkyexpr(val
, yylval
);
else if (INTOKSET(val
, SAFEEXPRBEG
)){
lexpr
= (struct exp
*)yylval
;
else if ( (val
== TILDE
) || (val
== MINUS
) ){
lexpr
= combine(op
, lexpr
, factor());
yyerror("Bad expression syntax");
struct exp
*yukkyexpr(val
, np
)
register struct exp
*locxp
;
extern int exprisname
; /*last factor is a name*/
if (val
== NAME
|| val
== BFINT
){
yylval
= ((struct exp
*)np
)->e_xvalue
;
if (lgensym
[yylval
] == 1)
yyerror("Reference to undefined local label %db", yylval
);
sprintf(yytext
, "L%d\001%d", yylval
, lgensym
[yylval
] + off
);
yylval
= np
= (int)*lookup(passno
== 1);
lastnam
= (struct symtab
*)np
;
locxp
->e_xtype
= ((struct symtab
*)np
)->s_type
;
if (( ((struct symtab
*)np
)->s_type
&XTYPE
)==XUNDEF
) { /*forward*/
locxp
->e_xname
= (struct symtab
*)np
;
((struct symtab
*)np
)->s_type
|= XFORW
;
} else { /*otherwise, just get the value*/
locxp
->e_xvalue
= ((struct symtab
*)np
)->s_value
;
} else { /*INSTn or INST0 or REG*/
locxp
->e_xvalue
= ( (int)np
) & 0xFF;
char *tok_name
[LASTTOKEN
- FIRSTTOKEN
+ 1];
FIRSTTOKEN
, "firsttoken", /* 0 */
ISPACE
, "ispace", /* 1 */
IGLOBAL
, "iglobal", /* 7 */
ILCOMM
, "ilcomm", /* 11 */
IFLOAT
, "ifloat", /* 12 */
IDOUBLE
, "idouble", /* 13 */
IASCII
, "iascii", /* 15 */
IASCIZ
, "iasciz", /* 16 */
ILINENO
, "ilineno", /* 19 */
IABORT
, "iabort", /* 20 */
ISTABSTR
, "istabstr", /* 24 */
ISTABNONE
, "istabnone", /* 25 */
ISTABDOT
, "istabdot", /* 26 */
IALIGN
, "ialign", /* 28 */
PARSEEOF
, "parseeof", /* 32 */
ILINESKIP
, "ilineskip", /* 33 */
FLTNUM
, "fltnum", /* 37 */
STRING
, "string", /* 39 */
SIZESPEC
, "sizespec", /* 41 */
NEEDSBUF
, "needsbuf", /* 48 */
SCANEOF
, "scaneof", /* 51 */
BADCHAR
, "badchar", /* 52 */
SIZEQUOTE
, "sizequote", /* 62 */
LASTTOKEN
, "lasttoken" /* 80 */
* turn a token type into a string
for (i
= FIRSTTOKEN
; i
<= LASTTOKEN
; i
++)
tok_name
[i
] = "NOT ASSIGNED";
for (i
= FIRSTTOKEN
; i
<= sizeof(tok_desc
)/sizeof(struct Tok_Desc
); i
++){
tok_name
[tok_desc
[i
].tok_which
] = tok_desc
[i
].tok_name
;
if (FIRSTTOKEN
<= token
&& token
<= LASTTOKEN
)
panic("Unknown token number, %d\n", token
);