/* Copyright (c) 1979 Regents of the University of California */
* Tables for combination of operands.
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
->xtype
&XTYPE
;
e2_type
= exp2
->xtype
&XTYPE
;
if (exp1
->xtype
==XXTRN
+XUNDEF
)
if (exp2
->xtype
==XXTRN
+XUNDEF
)
if (exp1
->xloc
!=exp2
->xloc
&& e1_type
==e2_type
)
e1_type
= e2_type
= XTXRN
; /* error on != loc ctrs */
e1_type
>>= 1; /*dispost of the external (XXTRN) bit*/
exp1
->xvalue
+= exp2
->xvalue
;
type
= pltab
[e1_type
][e2_type
];
exp1
->xvalue
-= exp2
->xvalue
;
type
= mintab
[e1_type
][e2_type
];
exp1
->xvalue
|= exp2
->xvalue
;
exp1
->xvalue
^= exp2
->xvalue
;
exp1
->xvalue
&= exp2
->xvalue
;
exp1
->xvalue
|= ~exp2
->xvalue
;
exp1
->xvalue
<<= exp2
->xvalue
;
exp1
->xvalue
>>= exp2
->xvalue
;
exp1
->xvalue
|= ~ exp2
->xvalue
;
exp1
->xvalue
*= exp2
->xvalue
;
exp1
->xvalue
/= exp2
->xvalue
;
yyerror("Divide check (modulo)");
exp1
->xvalue
%= exp2
->xvalue
;
type
= othtab
[e1_type
][e2_type
];
yyerror("Internal error: unknown operator");
exp1
->xname
= exp2
->xname
;
(exp1
->xtype
|exp2
->xtype
) & (XFORW
|XXTRN
) );
yyerror("Relocation error");
#define clobber(val, set) tokensets[(val)] |= (set)
clobber(SEMI
, LINSTBEGIN
);
clobber(NAME
, YUKKYEXPRBEG
+ LINSTBEGIN
);
clobber(INSTn
, YUKKYEXPRBEG
);
clobber(INST0
, YUKKYEXPRBEG
);
clobber(REG
, 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*/
locxp
->xtype
= ((struct symtab
*)np
)->type
;
if (( ((struct symtab
*)np
)->type
&XTYPE
)==XUNDEF
) { /*forward*/
locxp
->xname
= (struct symtab
*)np
;
((struct symtab
*)np
)->type
|= XFORW
;
} else { /*otherwise, just get the value*/
locxp
->xvalue
= ((struct symtab
*)np
)->value
;
} else { /*INSTn or INST0 or REG*/
locxp
->xvalue
= ( (int)np
) & 0xFF;