- /* asexpr.c */
+ /* asexpr.c */
/*
* (C) Copyright 1989-1995
#include <string.h>
#include "asm.h"
-/*)Module asexpr.c
- *
- * The module asexpr.c contains the routines to evaluate
- * arithmetic/numerical expressions. The functions in
- * asexpr.c perform a recursive evaluation of the arithmetic
- * expression read from the assembler-source text line.
- * The expression may include binary/unary operators, brackets,
- * symbols, labels, and constants in hexadecimal, decimal, octal
- * and binary. Arithmetic operations are prioritized and
- * evaluated by normal arithmetic conventions.
- *
- * asexpr.c contains the following functions:
- * VOID abscheck()
- * Addr_T absexpr()
- * VOID clrexpr()
- * int digit()
- * VOID expr()
- * int oprio()
- * VOID term()
- *
- * asexpr.c contains no local/static variables
+/*)Module asexpr.c
+ *
+ * The module asexpr.c contains the routines to evaluate
+ * arithmetic/numerical expressions. The functions in
+ * asexpr.c perform a recursive evaluation of the arithmetic
+ * expression read from the assembler-source text line.
+ * The expression may include binary/unary operators, brackets,
+ * symbols, labels, and constants in hexadecimal, decimal, octal
+ * and binary. Arithmetic operations are prioritized and
+ * evaluated by normal arithmetic conventions.
+ *
+ * asexpr.c contains the following functions:
+ * VOID abscheck()
+ * Addr_T absexpr()
+ * VOID clrexpr()
+ * int digit()
+ * VOID expr()
+ * int oprio()
+ * VOID term()
+ *
+ * asexpr.c contains no local/static variables
*/
-/*)Function VOID expr(esp, n)
- *
- * expr * esp pointer to an expr structure
- * int n a firewall priority; all top
- * level calls (from the user)
- * should be made with n set to 0.
- *
- * The function expr() evaluates an expression and
- * stores its value and relocation information into
- * the expr structure supplied by the user.
- *
- * local variables:
- * int c current assembler-source
- * text character
- * int p current operator priority
- * area * ap pointer to an area structure
- * exp re internal expr structure
- *
- * global variables:
- * char ctype[] array of character types, one per
- * ASCII character
- *
- * functions called:
- * VOID abscheck() asexpr.c
- * VOID clrexpr() asexpr.c
- * VOID expr() asexpr.c
- * int getnb() aslex.c
- * int oprio() asexpr.c
- * VOID qerr() assubr.c
- * VOID rerr() assubr.c
- * VOID term() asexpr.c
- * VOID unget() aslex.c
- *
- *
- * side effects:
- * An expression is evaluated modifying the user supplied
- * expr structure, a sym structure maybe created for an
- * undefined symbol, and the parse of the expression may
- * terminate if a 'q' error occurs.
+/*)Function VOID expr(esp, n)
+ *
+ * expr * esp pointer to an expr structure
+ * int n a firewall priority; all top
+ * level calls (from the user)
+ * should be made with n set to 0.
+ *
+ * The function expr() evaluates an expression and
+ * stores its value and relocation information into
+ * the expr structure supplied by the user.
+ *
+ * local variables:
+ * int c current assembler-source
+ * text character
+ * int p current operator priority
+ * area * ap pointer to an area structure
+ * exp re internal expr structure
+ *
+ * global variables:
+ * char ctype[] array of character types, one per
+ * ASCII character
+ *
+ * functions called:
+ * VOID abscheck() asexpr.c
+ * VOID clrexpr() asexpr.c
+ * VOID expr() asexpr.c
+ * int getnb() aslex.c
+ * int oprio() asexpr.c
+ * VOID qerr() assubr.c
+ * VOID rerr() assubr.c
+ * VOID term() asexpr.c
+ * VOID unget() aslex.c
+ *
+ *
+ * side effects:
+ * An expression is evaluated modifying the user supplied
+ * expr structure, a sym structure maybe created for an
+ * undefined symbol, and the parse of the expression may
+ * terminate if a 'q' error occurs.
*/
VOID
term(esp);
while (ctype[c = getnb()] & BINOP) {
- /*
- * Handle binary operators + - * / & | % ^ << >>
- */
+ /*
+ * Handle binary operators + - * / & | % ^ << >>
+ */
if ((p = oprio(c)) <= n)
break;
if ((c == '>' || c == '<') && c != get())
qerr();
- clrexpr(&re);
+ clrexpr(&re);
expr(&re, p);
- esp->e_rlcf |= re.e_rlcf;
+ esp->e_rlcf |= re.e_rlcf;
if (c == '+') {
- /*
- * esp + re, at least one must be absolute
- */
+ /*
+ * esp + re, at least one must be absolute
+ */
if (esp->e_base.e_ap == NULL) {
- /*
- * esp is absolute (constant),
- * use area from re
- */
+ /*
+ * esp is absolute (constant),
+ * use area from re
+ */
esp->e_base.e_ap = re.e_base.e_ap;
} else
if (re.e_base.e_ap) {
- /*
- * re should be absolute (constant)
- */
+ /*
+ * re should be absolute (constant)
+ */
rerr();
}
if (esp->e_flag && re.e_flag)
esp->e_addr += re.e_addr;
} else
if (c == '-') {
- /*
- * esp - re
- */
+ /*
+ * esp - re
+ */
if ((ap = re.e_base.e_ap) != NULL) {
if (esp->e_base.e_ap == ap) {
esp->e_base.e_ap = NULL;
rerr();
esp->e_addr -= re.e_addr;
} else {
- /*
- * Both operands (esp and re) must be constants
- */
- /* SD :- moved the abscheck to each case
- case and change the right shift operator.. if
- right shift by 8 bits of a relocatable address then
- the user wants the higher order byte. set the R_MSB
- for the expression */
+ /*
+ * Both operands (esp and re) must be constants
+ */
+ /* SD :- moved the abscheck to each case
+ case and change the right shift operator.. if
+ right shift by 8 bits of a relocatable address then
+ the user wants the higher order byte. set the R_MSB
+ for the expression */
switch (c) {
case '*':
- abscheck(esp);
- abscheck(&re);
- esp->e_addr *= re.e_addr;
- break;
+ abscheck(esp);
+ abscheck(&re);
+ esp->e_addr *= re.e_addr;
+ break;
case '/':
- abscheck(esp);
- abscheck(&re);
- esp->e_addr /= re.e_addr;
- break;
+ abscheck(esp);
+ abscheck(&re);
+ esp->e_addr /= re.e_addr;
+ break;
case '&':
- abscheck(esp);
- abscheck(&re);
- esp->e_addr &= re.e_addr;
- break;
+ abscheck(esp);
+ abscheck(&re);
+ esp->e_addr &= re.e_addr;
+ break;
case '|':
- abscheck(esp);
- abscheck(&re);
- esp->e_addr |= re.e_addr;
- break;
+ abscheck(esp);
+ abscheck(&re);
+ esp->e_addr |= re.e_addr;
+ break;
case '%':
- abscheck(esp);
- abscheck(&re);
- esp->e_addr %= re.e_addr;
- break;
+ abscheck(esp);
+ abscheck(&re);
+ esp->e_addr %= re.e_addr;
+ break;
case '^':
- abscheck(esp);
- abscheck(&re);
- esp->e_addr ^= re.e_addr;
- break;
+ abscheck(esp);
+ abscheck(&re);
+ esp->e_addr ^= re.e_addr;
+ break;
case '<':
- abscheck(esp);
- abscheck(&re);
- esp->e_addr <<= re.e_addr;
- break;
+ abscheck(esp);
+ abscheck(&re);
+ esp->e_addr <<= re.e_addr;
+ break;
case '>':
- /* SD change here */
- abscheck(&re);
- /* if the left is a relative address &
- the right side is == 8 then */
- if (esp->e_base.e_ap && re.e_addr == 8) {
- esp->e_rlcf |= R_MSB ;
- break;
- }
- else if (esp->e_base.e_ap && re.e_addr == 16)
- {
- if (flat24Mode)
- {
- esp->e_rlcf |= R_HIB;
- }
- else
- {
- warnBanner();
- fprintf(stderr,
- "(expr >> 16) is only meaningful in "
- ".flat24 mode.\n");
- qerr();
- }
-
- break;
- }
- /* else continue with the normal processing */
- abscheck(esp);
- esp->e_addr >>= re.e_addr;
- break;
-
- default:
- qerr();
- break;
- }
+ /* SD change here */
+ abscheck(&re);
+ /* if the left is a relative address &
+ the right side is == 8 then */
+ if (esp->e_base.e_ap && re.e_addr == 8) {
+ esp->e_rlcf |= R_MSB ;
+ break;
+ }
+ else if (esp->e_base.e_ap && re.e_addr == 16)
+ {
+ if (flat24Mode)
+ {
+ esp->e_rlcf |= R_HIB;
+ }
+ else
+ {
+ warnBanner();
+ fprintf(stderr,
+ "(expr >> 16) is only meaningful in "
+ ".flat24 mode.\n");
+ qerr();
+ }
+
+ break;
+ }
+ /* else continue with the normal processing */
+ abscheck(esp);
+ esp->e_addr >>= re.e_addr;
+ break;
+
+ default:
+ qerr();
+ break;
+ }
}
}
unget(c);
}
-/*)Function Addr_T absexpr()
+/*)Function Addr_T absexpr()
*
- * The function absexpr() evaluates an expression, verifies it
- * is absolute (i.e. not position dependent or relocatable), and
- * returns its value.
+ * The function absexpr() evaluates an expression, verifies it
+ * is absolute (i.e. not position dependent or relocatable), and
+ * returns its value.
*
- * local variables:
- * expr e expr structure
+ * local variables:
+ * expr e expr structure
*
- * global variables:
- * none
+ * global variables:
+ * none
*
- * functions called:
- * VOID abscheck() asexpr.c
- * VOID clrexpr() asexpr.c
- * VOID expr() asexpr.c
+ * functions called:
+ * VOID abscheck() asexpr.c
+ * VOID clrexpr() asexpr.c
+ * VOID expr() asexpr.c
*
- * side effects:
- * If the expression is not absolute then
- * a 'r' error is reported.
+ * side effects:
+ * If the expression is not absolute then
+ * a 'r' error is reported.
*/
Addr_T
{
struct expr e;
- clrexpr(&e);
- expr(&e, 0);
- abscheck(&e);
- return (e.e_addr);
+ clrexpr(&e);
+ expr(&e, 0);
+ abscheck(&e);
+ return (e.e_addr);
}
-/*)Function VOID term(esp)
- *
- * expr * esp pointer to an expr structure
- *
- * The function term() evaluates a single constant
- * or symbol value prefaced by any unary operator
- * ( +, -, ~, ', ", >, or < ). This routine is also
- * responsible for setting the relocation type to symbol
- * based (e.flag != 0) on global references.
- *
- * local variables:
- * int c current character
- * char id[] symbol name
- * char * jp pointer to assembler-source text
- * int n constant evaluation running sum
- * int r current evaluation radix
- * sym * sp pointer to a sym structure
- * tsym * tp pointer to a tsym structure
- * int v current digit evaluation
- *
- * global variables:
- * char ctype[] array of character types, one per
- * ASCII character
- * sym * symp pointer to a symbol structure
- *
- * functions called:
- * VOID abscheck() asexpr.c
- * int digit() asexpr.c
- * VOID err() assubr.c
- * VOID expr() asexpr.c
- * int is_abs() asexpr.c
- * int get() aslex.c
- * VOID getid() aslex.c
- * int getmap() aslex.c
- * int getnb() aslex.c
- * sym * lookup() assym.c
- * VOID qerr() assubr.c
- * VOID unget() aslex.c
- *
- * side effects:
- * An arithmetic term is evaluated, a symbol structure
- * may be created, term evaluation may be terminated
- * by a 'q' error.
+/*)Function VOID term(esp)
+ *
+ * expr * esp pointer to an expr structure
+ *
+ * The function term() evaluates a single constant
+ * or symbol value prefaced by any unary operator
+ * ( +, -, ~, ', ", >, or < ). This routine is also
+ * responsible for setting the relocation type to symbol
+ * based (e.flag != 0) on global references.
+ *
+ * local variables:
+ * int c current character
+ * char id[] symbol name
+ * char * jp pointer to assembler-source text
+ * int n constant evaluation running sum
+ * int r current evaluation radix
+ * sym * sp pointer to a sym structure
+ * tsym * tp pointer to a tsym structure
+ * int v current digit evaluation
+ *
+ * global variables:
+ * char ctype[] array of character types, one per
+ * ASCII character
+ * sym * symp pointer to a symbol structure
+ *
+ * functions called:
+ * VOID abscheck() asexpr.c
+ * int digit() asexpr.c
+ * VOID err() assubr.c
+ * VOID expr() asexpr.c
+ * int is_abs() asexpr.c
+ * int get() aslex.c
+ * VOID getid() aslex.c
+ * int getmap() aslex.c
+ * int getnb() aslex.c
+ * sym * lookup() assym.c
+ * VOID qerr() assubr.c
+ * VOID unget() aslex.c
+ *
+ * side effects:
+ * An arithmetic term is evaluated, a symbol structure
+ * may be created, term evaluation may be terminated
+ * by a 'q' error.
*/
VOID
register struct expr *esp;
{
register int c, n;
- register char *jp;
+ register const char *jp;
char id[NCPS];
struct sym *sp;
struct tsym *tp;
int r=0, v;
c = getnb();
- /*
- * Discard the unary '+' at this point and
- * also any reference to numerical arguments
- * associated with the '#' prefix.
- */
+ /*
+ * Discard the unary '+' at this point and
+ * also any reference to numerical arguments
+ * associated with the '#' prefix.
+ */
while (c == '+' || c == '#') { c = getnb(); }
- /*
- * Evaluate all binary operators
- * by recursively calling expr().
- */
+ /*
+ * Evaluate all binary operators
+ * by recursively calling expr().
+ */
if (c == LFTERM) {
expr(esp, 0);
if (getnb() != RTTERM)
}
if (c == '>' || c == '<') {
expr(esp, 100);
- if (is_abs (esp)) {
- /*
- * evaluate msb/lsb directly
- */
- if (c == '>')
- esp->e_addr >>= 8;
- esp->e_addr &= 0377;
- return;
- } else {
- /*
- * let linker perform msb/lsb, lsb is default
- */
- esp->e_rlcf |= R_BYT2;
- if (c == '>')
- esp->e_rlcf |= R_MSB;
- return;
- }
+ if (is_abs (esp)) {
+ /*
+ * evaluate msb/lsb directly
+ */
+ if (c == '>')
+ esp->e_addr >>= 8;
+ esp->e_addr &= 0377;
+ return;
+ } else {
+ /*
+ * let linker perform msb/lsb, lsb is default
+ */
+ esp->e_rlcf |= R_BYT2;
+ if (c == '>')
+ esp->e_rlcf |= R_MSB;
+ return;
+ }
}
- /*
- * Evaluate digit sequences as local symbols
- * if followed by a '$' or as constants.
- */
+ /*
+ * Evaluate digit sequences as local symbols
+ * if followed by a '$' or as constants.
+ */
if (ctype[c] & DIGIT) {
esp->e_mode = S_USER;
jp = ip;
esp->e_addr = n;
return;
}
- /*
- * Evaluate '$' sequences as a temporary radix
- * if followed by a '%', '&', '#', or '$'.
- */
+ /*
+ * Evaluate '$' sequences as a temporary radix
+ * if followed by a '%', '&', '#', or '$'.
+ */
if (c == '$') {
c = get();
if (c == '%' || c == '&' || c == '#' || c == '$') {
- switch (c) {
- case '%':
- r = 2;
- break;
- case '&':
- r = 8;
- break;
- case '#':
- r = 10;
- break;
- case '$':
- r = 16;
- break;
- default:
- break;
- }
- c = get();
- n = 0;
- while ((v = digit(c, r)) >= 0) {
- n = r*n + v;
- c = get();
- }
- unget(c);
- esp->e_mode = S_USER;
- esp->e_addr = n;
- return;
- }
- unget(c);
- c = '$';
+ switch (c) {
+ case '%':
+ r = 2;
+ break;
+ case '&':
+ r = 8;
+ break;
+ case '#':
+ r = 10;
+ break;
+ case '$':
+ r = 16;
+ break;
+ default:
+ break;
+ }
+ c = get();
+ n = 0;
+ while ((v = digit(c, r)) >= 0) {
+ n = r*n + v;
+ c = get();
+ }
+ unget(c);
+ esp->e_mode = S_USER;
+ esp->e_addr = n;
+ return;
+ }
+ unget(c);
+ c = '$';
}
- /*
- * Evaluate symbols and labels
- */
+ /*
+ * Evaluate symbols and labels
+ */
if (ctype[c] & LETTER) {
esp->e_mode = S_USER;
getid(id, c);
sp = lookup(id);
if (sp->s_type == S_NEW) {
esp->e_addr = 0;
- if (sp->s_flag&S_GBL) {
- esp->e_flag = 1;
- esp->e_base.e_sp = sp;
- return;
- }
- /* err('u'); */
+ if (sp->s_flag&S_GBL) {
+ esp->e_flag = 1;
+ esp->e_base.e_sp = sp;
+ return;
+ }
+ /* err('u'); */
} else {
esp->e_mode = sp->s_type;
esp->e_addr = sp->s_addr;
}
return;
}
- /*
- * Else not a term.
- */
+ /*
+ * Else not a term.
+ */
qerr();
}
-/*)Function int digit(c, r)
+/*)Function int digit(c, r)
*
- * int c digit character
- * int r current radix
+ * int c digit character
+ * int r current radix
*
- * The function digit() returns the value of c
- * in the current radix r. If the c value is not
- * a number of the current radix then a -1 is returned.
+ * The function digit() returns the value of c
+ * in the current radix r. If the c value is not
+ * a number of the current radix then a -1 is returned.
*
- * local variables:
- * none
+ * local variables:
+ * none
*
- * global variables:
- * char ctype[] array of character types, one per
- * ASCII character
+ * global variables:
+ * char ctype[] array of character types, one per
+ * ASCII character
*
- * functions called:
- * none
+ * functions called:
+ * none
*
- * side effects:
- * none
+ * side effects:
+ * none
*/
int
return (-1);
}
-/*)Function VOID abscheck(esp)
+/*)Function VOID abscheck(esp)
*
- * expr * esp pointer to an expr structure
+ * expr * esp pointer to an expr structure
*
- * The function abscheck() tests the evaluation of an
- * expression to verify it is absolute. If the evaluation
- * is relocatable then an 'r' error is noted and the expression
- * made absolute.
+ * The function abscheck() tests the evaluation of an
+ * expression to verify it is absolute. If the evaluation
+ * is relocatable then an 'r' error is noted and the expression
+ * made absolute.
*
- * Note: The area type (i.e. ABS) is not checked because
- * the linker can be told to explicitly relocate an
- * absolute area.
+ * Note: The area type (i.e. ABS) is not checked because
+ * the linker can be told to explicitly relocate an
+ * absolute area.
*
- * local variables:
- * none
+ * local variables:
+ * none
*
- * global variables:
- * none
+ * global variables:
+ * none
*
- * functions called:
- * VOID rerr() assubr.c
+ * functions called:
+ * VOID rerr() assubr.c
*
- * side effects:
- * The expression may be changed to absolute and the
- * 'r' error invoked.
+ * side effects:
+ * The expression may be changed to absolute and the
+ * 'r' error invoked.
*/
VOID
}
}
-/*)Function int is_abs(esp)
+/*)Function int is_abs(esp)
*
- * expr * esp pointer to an expr structure
+ * expr * esp pointer to an expr structure
*
- * The function is_abs() tests the evaluation of an
- * expression to verify it is absolute. If the evaluation
- * is absolute then 1 is returned, else 0 is returned.
+ * The function is_abs() tests the evaluation of an
+ * expression to verify it is absolute. If the evaluation
+ * is absolute then 1 is returned, else 0 is returned.
*
- * Note: The area type (i.e. ABS) is not checked because
- * the linker can be told to explicitly relocate an
- * absolute area.
+ * Note: The area type (i.e. ABS) is not checked because
+ * the linker can be told to explicitly relocate an
+ * absolute area.
*
- * local variables:
- * none
+ * local variables:
+ * none
*
- * global variables:
- * none
+ * global variables:
+ * none
*
- * functions called:
- * none
+ * functions called:
+ * none
*
- * side effects:
- * none
+ * side effects:
+ * none
*/
int
register struct expr *esp;
{
if (esp->e_flag || esp->e_base.e_ap) {
- return(0);
+ return(0);
}
- return(1);
+ return(1);
}
-/*)Function int oprio(c)
+/*)Function int oprio(c)
*
- * int c operator character
+ * int c operator character
*
- * The function oprio() returns a relative priority
- * for all valid unary and binary operators.
+ * The function oprio() returns a relative priority
+ * for all valid unary and binary operators.
*
- * local variables:
- * none
+ * local variables:
+ * none
*
- * global variables:
- * none
+ * global variables:
+ * none
*
- * functions called:
- * none
+ * functions called:
+ * none
*
- * side effects:
- * none
+ * side effects:
+ * none
*/
-
+
int
oprio(c)
register int c;
return (0);
}
-/*)Function VOID clrexpr(esp)
+/*)Function VOID clrexpr(esp)
*
- * expr * esp pointer to expression structure
+ * expr * esp pointer to expression structure
*
- * The function clrexpr() clears the expression structure.
+ * The function clrexpr() clears the expression structure.
*
- * local variables:
- * none
+ * local variables:
+ * none
*
- * global variables:
- * none
+ * global variables:
+ * none
*
- * functions called:
- * none
+ * functions called:
+ * none
*
- * side effects:
- * expression structure cleared.
+ * side effects:
+ * expression structure cleared.
*/
-
+
VOID
clrexpr(esp)
register struct expr *esp;
{
- esp->e_mode = 0;
- esp->e_flag = 0;
- esp->e_addr = 0;
- esp->e_base.e_ap = NULL;
- esp->e_rlcf = 0;
+ esp->e_mode = 0;
+ esp->e_flag = 0;
+ esp->e_addr = 0;
+ esp->e_base.e_ap = NULL;
+ esp->e_rlcf = 0;
}