minor changes concerning void and pre-processor
This commit is contained in:
parent
26cc87efe6
commit
4bde31f78a
22 changed files with 101 additions and 115 deletions
|
@ -203,8 +203,7 @@ garbage:
|
||||||
ptok->tk_bts = string_token("file specifier",
|
ptok->tk_bts = string_token("file specifier",
|
||||||
'>', &(ptok->tk_len));
|
'>', &(ptok->tk_len));
|
||||||
return ptok->tk_symb = FILESPECIFIER;
|
return ptok->tk_symb = FILESPECIFIER;
|
||||||
}
|
} else if (nch == '<') {
|
||||||
if (nch == '<') {
|
|
||||||
if ((nch = GetChar()) == '=')
|
if ((nch = GetChar()) == '=')
|
||||||
return ptok->tk_symb = LEFTAB;
|
return ptok->tk_symb = LEFTAB;
|
||||||
UnGetChar();
|
UnGetChar();
|
||||||
|
@ -321,15 +320,9 @@ garbage:
|
||||||
idef->id_line = ptok->tk_line;
|
idef->id_line = ptok->tk_line;
|
||||||
#ifndef NOPP
|
#ifndef NOPP
|
||||||
if (idef->id_macro && ReplaceMacros && !NoExpandNext) {
|
if (idef->id_macro && ReplaceMacros && !NoExpandNext) {
|
||||||
#if 0
|
|
||||||
if (idef->id_macro->mc_count > 0)
|
|
||||||
idef->id_macro->mc_count--;
|
|
||||||
else
|
|
||||||
#endif /* 0 */
|
|
||||||
if (replace(idef))
|
if (replace(idef))
|
||||||
goto again;
|
goto again;
|
||||||
}
|
}
|
||||||
NoExpandNext = 0;
|
|
||||||
if (UnknownIdIsZero && idef->id_reserved != SIZEOF) {
|
if (UnknownIdIsZero && idef->id_reserved != SIZEOF) {
|
||||||
ptok->tk_ival = (arith)0;
|
ptok->tk_ival = (arith)0;
|
||||||
ptok->tk_fund = INT;
|
ptok->tk_fund = INT;
|
||||||
|
|
|
@ -143,14 +143,13 @@ relbalance(e1p, oper, e2p)
|
||||||
function2pointer(*e2p);
|
function2pointer(*e2p);
|
||||||
if ((*e1p)->ex_type->tp_fund == POINTER)
|
if ((*e1p)->ex_type->tp_fund == POINTER)
|
||||||
ch3pointer(e2p, oper, (*e1p)->ex_type);
|
ch3pointer(e2p, oper, (*e1p)->ex_type);
|
||||||
else
|
else if ((*e2p)->ex_type->tp_fund == POINTER)
|
||||||
if ((*e2p)->ex_type->tp_fund == POINTER)
|
|
||||||
ch3pointer(e1p, oper, (*e2p)->ex_type);
|
ch3pointer(e1p, oper, (*e2p)->ex_type);
|
||||||
else
|
else if ((*e1p)->ex_type == (*e2p)->ex_type
|
||||||
if ( (*e1p)->ex_type == (*e2p)->ex_type &&
|
&& (*e1p)->ex_type->tp_fund == ENUM) {}
|
||||||
(*e1p)->ex_type->tp_fund == ENUM
|
else if (oper == ':'
|
||||||
)
|
&& (*e1p)->ex_type->tp_fund == VOID
|
||||||
{}
|
&& (*e2p)->ex_type->tp_fund == VOID) {}
|
||||||
else
|
else
|
||||||
arithbalance(e1p, oper, e2p);
|
arithbalance(e1p, oper, e2p);
|
||||||
}
|
}
|
||||||
|
@ -160,7 +159,7 @@ ch3pointer(expp, oper, tp)
|
||||||
register struct type *tp;
|
register struct type *tp;
|
||||||
{
|
{
|
||||||
/* Checks whether *expp may be compared to tp using oper,
|
/* Checks whether *expp may be compared to tp using oper,
|
||||||
as described in chapter 7.6 and 7.7.
|
as described in chapter 3.3.8 and 3.3.9.
|
||||||
tp is known to be a pointer.
|
tp is known to be a pointer.
|
||||||
*/
|
*/
|
||||||
register struct expr *exp = *expp;
|
register struct expr *exp = *expp;
|
||||||
|
|
|
@ -195,8 +195,9 @@ ch3cast(expp, oper, tp)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif NOBITFIELD
|
#endif NOBITFIELD
|
||||||
if (equal_type(tp, oldtp, 0)) {
|
if (equal_type(tp, oldtp, oper != CAST)) {
|
||||||
/* life is easy */
|
/* life is easy */
|
||||||
|
(*expp)->ex_type = tp; /* so qualifiers are allright */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if (tp->tp_fund == VOID) {
|
if (tp->tp_fund == VOID) {
|
||||||
|
@ -382,14 +383,16 @@ equal_type(tp, otp, check_qual)
|
||||||
|
|
||||||
case POINTER:
|
case POINTER:
|
||||||
if (equal_type(tp->tp_up, otp->tp_up, check_qual)) {
|
if (equal_type(tp->tp_up, otp->tp_up, check_qual)) {
|
||||||
if (otp->tp_up->tp_typequal & TQ_CONST) {
|
if (check_qual) {
|
||||||
if (!(tp->tp_up->tp_typequal & TQ_CONST)) {
|
if (otp->tp_up->tp_typequal & TQ_CONST) {
|
||||||
strict("illegal use of pointer to const object");
|
if (!(tp->tp_up->tp_typequal & TQ_CONST)) {
|
||||||
|
strict("illegal use of pointer to const object");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
if (otp->tp_up->tp_typequal & TQ_VOLATILE) {
|
||||||
if (otp->tp_up->tp_typequal & TQ_VOLATILE) {
|
if (!(tp->tp_up->tp_typequal & TQ_VOLATILE)) {
|
||||||
if (!(tp->tp_up->tp_typequal & TQ_VOLATILE)) {
|
strict("illegal use of pointer to volatile object");
|
||||||
strict("illegal use of pointer to volatile object");
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -568,8 +571,8 @@ ch3asgn(expp, oper, expr)
|
||||||
/* Preserve volatile markers across the tree.
|
/* Preserve volatile markers across the tree.
|
||||||
This is questionable, depending on the way the optimizer
|
This is questionable, depending on the way the optimizer
|
||||||
wants this information.
|
wants this information.
|
||||||
vol = (exp->ex_flags & EX_VOLATILE) || (expr->ex_flags & EX_VOLATILE);
|
|
||||||
*/
|
*/
|
||||||
|
vol = (exp->ex_flags & EX_VOLATILE) || (expr->ex_flags & EX_VOLATILE);
|
||||||
|
|
||||||
if (oper == '=') {
|
if (oper == '=') {
|
||||||
ch3cast(&expr, oper, exp->ex_type);
|
ch3cast(&expr, oper, exp->ex_type);
|
||||||
|
@ -587,7 +590,7 @@ ch3asgn(expp, oper, expr)
|
||||||
((typeof (f op e))f op (typeof (f op e))e),
|
((typeof (f op e))f op (typeof (f op e))e),
|
||||||
where f ~ extmp and e ~ expr.
|
where f ~ extmp and e ~ expr.
|
||||||
We want to use (typeof (f op e))e.
|
We want to use (typeof (f op e))e.
|
||||||
Ch7bin does not create a tree if both operands
|
Ch3bin does not create a tree if both operands
|
||||||
were illegal or constants!
|
were illegal or constants!
|
||||||
*/
|
*/
|
||||||
tp = extmp->ex_type; /* perform the arithmetic in type tp */
|
tp = extmp->ex_type; /* perform the arithmetic in type tp */
|
||||||
|
|
|
@ -167,7 +167,7 @@ ch3bin(expp, oper, expr)
|
||||||
case RIGHTAB:
|
case RIGHTAB:
|
||||||
opnd2integral(expp, oper);
|
opnd2integral(expp, oper);
|
||||||
opnd2integral(&expr, oper);
|
opnd2integral(&expr, oper);
|
||||||
arithbalance(expp, oper, &expr); /* ch. 7.5 */
|
arithbalance(expp, oper, &expr); /* ch. 3.3.7 */
|
||||||
ch3cast(&expr, oper, int_type); /* cvt. rightop to int */
|
ch3cast(&expr, oper, int_type); /* cvt. rightop to int */
|
||||||
non_commutative_binop(expp, oper, expr);
|
non_commutative_binop(expp, oper, expr);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -100,7 +100,7 @@ ch3mon(oper, expp)
|
||||||
(*expp)->ex_type = pointer_to((*expp)->ex_type,
|
(*expp)->ex_type = pointer_to((*expp)->ex_type,
|
||||||
(*expp)->ex_type->tp_typequal);
|
(*expp)->ex_type->tp_typequal);
|
||||||
(*expp)->ex_lvalue = 0;
|
(*expp)->ex_lvalue = 0;
|
||||||
(*expp)->ex_flags &= ~EX_READONLY;
|
(*expp)->ex_flags &= ~(EX_READONLY | EX_VOLATILE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case '~':
|
case '~':
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
#define STGARB 2 /* garbage ascii character: not allowed in C */
|
#define STGARB 2 /* garbage ascii character: not allowed in C */
|
||||||
#define STSIMP 3 /* this character can occur as token in C */
|
#define STSIMP 3 /* this character can occur as token in C */
|
||||||
#define STCOMP 4 /* this one can start a compound token in C */
|
#define STCOMP 4 /* this one can start a compound token in C */
|
||||||
#define STELL 5 /* possible start of wide char stuff or idf */
|
#define STELL 5 /* wide character- or string- constant prefix */
|
||||||
#define STIDF 6 /* being the initial character of an identifier */
|
#define STIDF 6 /* being the initial character of an identifier */
|
||||||
#define STCHAR 7 /* the starter of a character constant */
|
#define STCHAR 7 /* the starter of a character constant */
|
||||||
#define STSTR 8 /* the starter of a string */
|
#define STSTR 8 /* the starter of a string */
|
||||||
|
|
|
@ -641,14 +641,7 @@ parameter_declarator(register struct declarator *dc;)
|
||||||
parameter_type_list(&pl)
|
parameter_type_list(&pl)
|
||||||
|
|
|
|
||||||
formal_list(&fm)
|
formal_list(&fm)
|
||||||
|
|
]?
|
||||||
/* empty */
|
|
||||||
{
|
|
||||||
pl = new_proto();
|
|
||||||
pl->pl_type = void_type;
|
|
||||||
pl->pl_flag = PL_VOID;
|
|
||||||
}
|
|
||||||
]
|
|
||||||
')'
|
')'
|
||||||
{ add_decl_unary(dc, FUNCTION, 0, (arith)0, fm, pl);
|
{ add_decl_unary(dc, FUNCTION, 0, (arith)0, fm, pl);
|
||||||
reject_params(dc);
|
reject_params(dc);
|
||||||
|
|
|
@ -117,7 +117,7 @@ check_array_subscript(expr)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if (size == 0) {
|
if (size == 0) {
|
||||||
warning("array size is 0");
|
strict("array size is 0");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if (size & ~max_unsigned) { /* absolutely ridiculous */
|
if (size & ~max_unsigned) { /* absolutely ridiculous */
|
||||||
|
|
|
@ -39,8 +39,8 @@ GetIdentifier(skiponerr)
|
||||||
{
|
{
|
||||||
/* returns a pointer to the descriptor of the identifier that is
|
/* returns a pointer to the descriptor of the identifier that is
|
||||||
read from the input stream. When the input doe not contain
|
read from the input stream. When the input doe not contain
|
||||||
an identifier, the rest of the line is skipped and a
|
an identifier, the rest of the line is skipped when
|
||||||
null-pointer is returned.
|
skiponerr is on, and a null-pointer is returned.
|
||||||
The substitution of macros is disabled.
|
The substitution of macros is disabled.
|
||||||
*/
|
*/
|
||||||
int tmp = UnknownIdIsZero;
|
int tmp = UnknownIdIsZero;
|
||||||
|
@ -422,7 +422,7 @@ do_undef()
|
||||||
if (id->id_macro->mc_flag & NOUNDEF) {
|
if (id->id_macro->mc_flag & NOUNDEF) {
|
||||||
lexerror("it is not allowed to undef %s", id->id_text);
|
lexerror("it is not allowed to undef %s", id->id_text);
|
||||||
} else {
|
} else {
|
||||||
free(id->id_text);
|
free(id->id_macro->mc_text);
|
||||||
free_macro(id->id_macro);
|
free_macro(id->id_macro);
|
||||||
id->id_macro = (struct macro *) 0;
|
id->id_macro = (struct macro *) 0;
|
||||||
}
|
}
|
||||||
|
@ -539,7 +539,6 @@ macro_def(id, text, nformals, length, flags)
|
||||||
newdef->mc_nps = nformals; /* nr of formals */
|
newdef->mc_nps = nformals; /* nr of formals */
|
||||||
newdef->mc_length = length; /* length of repl. text */
|
newdef->mc_length = length; /* length of repl. text */
|
||||||
newdef->mc_flag = flags; /* special flags */
|
newdef->mc_flag = flags; /* special flags */
|
||||||
newdef->mc_count = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -699,11 +698,17 @@ domacro()
|
||||||
|
|
||||||
EoiForNewline = 1;
|
EoiForNewline = 1;
|
||||||
if ((tok = GetToken(&tk)) == IDENTIFIER) {
|
if ((tok = GetToken(&tk)) == IDENTIFIER) {
|
||||||
if (strcmp(tk.tk_idf->id_text, "line") != 0) {
|
if (strcmp(tk.tk_idf->id_text, "line")
|
||||||
|
&& strcmp(tk.tk_idf->id_text, "pragma")) {
|
||||||
error("illegal # line");
|
error("illegal # line");
|
||||||
SkipToNewLine(0);
|
SkipToNewLine(0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else if ( !strcmp(tk.tk_idf->id_text, "pragma")) {
|
||||||
|
do_pragma();
|
||||||
|
EoiForNewline = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
tok = GetToken(&tk);
|
tok = GetToken(&tk);
|
||||||
}
|
}
|
||||||
if (tok != INTEGER) {
|
if (tok != INTEGER) {
|
||||||
|
|
|
@ -635,6 +635,7 @@ EVAL(expr, val, code, true_label, false_label)
|
||||||
default:
|
default:
|
||||||
crash("(EVAL) bad expression class");
|
crash("(EVAL) bad expression class");
|
||||||
}
|
}
|
||||||
|
if (expr->ex_flags & EX_VOLATILE) C_nop();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* compare() serves as an auxiliary function of EVAL */
|
/* compare() serves as an auxiliary function of EVAL */
|
||||||
|
|
|
@ -22,7 +22,7 @@ int InSizeof = 0; /* inside a sizeof- expression */
|
||||||
int ResultKnown = 0; /* result of the expression is already known */
|
int ResultKnown = 0; /* result of the expression is already known */
|
||||||
|
|
||||||
/* Since the grammar in the standard is not LL(n), it is modified so that
|
/* Since the grammar in the standard is not LL(n), it is modified so that
|
||||||
* it accepts basically the same grammar. Thsi means that there is no 1-1
|
* it accepts basically the same grammar. This means that there is no 1-1
|
||||||
* mapping from the grammar in the standard to the grammar given here.
|
* mapping from the grammar in the standard to the grammar given here.
|
||||||
* Such is life.
|
* Such is life.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -210,7 +210,7 @@ declare_idf(ds, dc, lvl)
|
||||||
}
|
}
|
||||||
else if (type->tp_fund != LABEL) {
|
else if (type->tp_fund != LABEL) {
|
||||||
/* CJ */
|
/* CJ */
|
||||||
warning("%s has size 0", idf->id_text);
|
strict("%s has size 0", idf->id_text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,6 +74,7 @@ init_pp()
|
||||||
/* __DATE__ */
|
/* __DATE__ */
|
||||||
sprintf(dbuf, "\"%.3s %.2d %d\"", months[tp->tm_mon],
|
sprintf(dbuf, "\"%.3s %.2d %d\"", months[tp->tm_mon],
|
||||||
tp->tm_mday, tp->tm_year+1900);
|
tp->tm_mday, tp->tm_year+1900);
|
||||||
|
if (tp->tm_mday < 10) dbuf[5] = ' '; /* hack */
|
||||||
macro_def(str2idf("__DATE__"), dbuf, -1, strlen(dbuf), NOUNDEF);
|
macro_def(str2idf("__DATE__"), dbuf, -1, strlen(dbuf), NOUNDEF);
|
||||||
|
|
||||||
/* __TIME__ */
|
/* __TIME__ */
|
||||||
|
|
|
@ -44,8 +44,6 @@ getwdir(fn)
|
||||||
|
|
||||||
int NoUnstack;
|
int NoUnstack;
|
||||||
int InputLevel;
|
int InputLevel;
|
||||||
#if 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
AtEoIT()
|
AtEoIT()
|
||||||
{
|
{
|
||||||
|
|
|
@ -475,8 +475,11 @@ check_ival(expp, tp)
|
||||||
if (expr->VL_CLASS == Name) {
|
if (expr->VL_CLASS == Name) {
|
||||||
register struct idf *idf = expr->VL_IDF;
|
register struct idf *idf = expr->VL_IDF;
|
||||||
|
|
||||||
if (idf->id_def->df_level >= L_LOCAL)
|
if (idf->id_def->df_level >= L_LOCAL
|
||||||
|
&& idf->id_def->df_sc != GLOBAL
|
||||||
|
&& idf->id_def->df_sc != EXTERN) {
|
||||||
illegal_init_cst(expr);
|
illegal_init_cst(expr);
|
||||||
|
}
|
||||||
else /* e.g., int f(); int p = f; */
|
else /* e.g., int f(); int p = f; */
|
||||||
if (idf->id_def->df_type->tp_fund == FUNCTION)
|
if (idf->id_def->df_type->tp_fund == FUNCTION)
|
||||||
C_con_pnam(idf->id_text);
|
C_con_pnam(idf->id_text);
|
||||||
|
|
|
@ -11,10 +11,10 @@
|
||||||
/* The flags of the mc_flag field of the macro structure. Note that
|
/* The flags of the mc_flag field of the macro structure. Note that
|
||||||
these flags can be set simultaneously.
|
these flags can be set simultaneously.
|
||||||
*/
|
*/
|
||||||
#define NOFLAG 0 /* no special flags */
|
#define NOFLAG 0 /* no special flags */
|
||||||
#define FUNC 0x1 /* function attached */
|
#define FUNC 0x1 /* function attached */
|
||||||
#define NOUNDEF 0x2 /* special macro */
|
#define NOUNDEF 0x2 /* reserved macro */
|
||||||
#define NOREPLACE 0x4 /* prevent recursion */
|
#define NOREPLACE 0x4 /* prevent recursion */
|
||||||
|
|
||||||
#define FORMALP 0200 /* mask for creating macro formal parameter */
|
#define FORMALP 0200 /* mask for creating macro formal parameter */
|
||||||
|
|
||||||
|
@ -28,7 +28,6 @@ struct macro {
|
||||||
char * mc_text; /* the replacement text */
|
char * mc_text; /* the replacement text */
|
||||||
int mc_nps; /* number of formal parameters */
|
int mc_nps; /* number of formal parameters */
|
||||||
int mc_length; /* length of replacement text */
|
int mc_length; /* length of replacement text */
|
||||||
int mc_count; /* # of "concurrent" invocations*/
|
|
||||||
char mc_flag; /* marking this macro */
|
char mc_flag; /* marking this macro */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -11,9 +11,6 @@
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "idf.h"
|
#include "idf.h"
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include "nopp.h"
|
|
||||||
|
|
||||||
#ifndef NOPP
|
|
||||||
#include "ifdepth.h"
|
#include "ifdepth.h"
|
||||||
#include "botch_free.h"
|
#include "botch_free.h"
|
||||||
#include "nparams.h"
|
#include "nparams.h"
|
||||||
|
@ -58,15 +55,9 @@ do_pragma()
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case P_UNKNOWN:
|
case P_UNKNOWN:
|
||||||
strict("unknown pragma directive %s", id->id_text);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
strict("unimplemented pragma directive");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
SkipToNewLine(0);
|
SkipToNewLine(0);
|
||||||
}
|
}
|
||||||
else strict("unrecognized pragma line");
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
|
@ -40,23 +40,20 @@ replace(idf)
|
||||||
higher interface to the real thing: expand_macro().
|
higher interface to the real thing: expand_macro().
|
||||||
*/
|
*/
|
||||||
struct repl *repl;
|
struct repl *repl;
|
||||||
|
|
||||||
if (!(idf->id_macro)) return 0;
|
if (!(idf->id_macro)) return 0;
|
||||||
if (idf->id_macro->mc_flag & NOREPLACE){
|
if (idf->id_macro->mc_flag & NOREPLACE)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
repl = new_repl();
|
repl = new_repl();
|
||||||
repl->r_ptr = repl->r_text;
|
repl->r_ptr = repl->r_text;
|
||||||
repl->r_args = new_args();
|
repl->r_args = new_args();
|
||||||
repl->r_idf = idf;
|
repl->r_idf = idf;
|
||||||
/* repl->r_level = InputLevel; /* ?? temporary */
|
if (!expand_macro(repl, idf))
|
||||||
if (!expand_macro(repl, idf)) {
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
InputLevel++;
|
InputLevel++;
|
||||||
InsertText(repl->r_text, repl->r_ptr - repl->r_text);
|
InsertText(repl->r_text, repl->r_ptr - repl->r_text);
|
||||||
repl->r_level = InputLevel;
|
|
||||||
idf->id_macro->mc_flag |= NOREPLACE;
|
idf->id_macro->mc_flag |= NOREPLACE;
|
||||||
|
repl->r_level = InputLevel;
|
||||||
repl->next = ReplaceList;
|
repl->next = ReplaceList;
|
||||||
ReplaceList = repl;
|
ReplaceList = repl;
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -122,7 +119,7 @@ expand_macro(repl, idf)
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (strcmp("defined", idf->id_text))
|
if (strcmp("defined", idf->id_text))
|
||||||
crash("in %s, %u: assertion %s failed",
|
crash("in %s, %u: assertion %s failed",
|
||||||
__FILE__, __LINE__ - 2,
|
__FILE__, __LINE__ - 2,
|
||||||
"strcmp(\"defined\", idf->id_text)");
|
"strcmp(\"defined\", idf->id_text)");
|
||||||
#endif
|
#endif
|
||||||
if (!AccDefined) return 0;
|
if (!AccDefined) return 0;
|
||||||
|
@ -133,10 +130,6 @@ expand_macro(repl, idf)
|
||||||
ch = GetChar();
|
ch = GetChar();
|
||||||
ch = skipspaces(ch,1);
|
ch = skipspaces(ch,1);
|
||||||
if (ch != '(') { /* no replacement if no () */
|
if (ch != '(') { /* no replacement if no () */
|
||||||
/* This is obscure. See the examples for the
|
|
||||||
replace algorithm in section 3`.8.3.5.
|
|
||||||
lexwarning("macro %s needs arguments", idf->id_text);
|
|
||||||
*/
|
|
||||||
UnGetChar();
|
UnGetChar();
|
||||||
return 0;
|
return 0;
|
||||||
} else
|
} else
|
||||||
|
@ -153,7 +146,7 @@ expand_macro(repl, idf)
|
||||||
|
|
||||||
#define a +
|
#define a +
|
||||||
a+b; --> + + b ;
|
a+b; --> + + b ;
|
||||||
|
|
||||||
'a' must be substituded, but the result should be
|
'a' must be substituded, but the result should be
|
||||||
three tokens: + + ID. Because this preprocessor is
|
three tokens: + + ID. Because this preprocessor is
|
||||||
character based, we have a problem.
|
character based, we have a problem.
|
||||||
|
@ -201,7 +194,7 @@ expand_defined(repl)
|
||||||
}
|
}
|
||||||
|
|
||||||
getactuals(repl, idf)
|
getactuals(repl, idf)
|
||||||
struct repl* repl;
|
struct repl *repl;
|
||||||
register struct idf *idf;
|
register struct idf *idf;
|
||||||
{
|
{
|
||||||
/* Get the actual parameters from the input stream.
|
/* Get the actual parameters from the input stream.
|
||||||
|
@ -217,7 +210,7 @@ getactuals(repl, idf)
|
||||||
args->a_expvec[0] = args->a_expptr = &args->a_expbuf[0];
|
args->a_expvec[0] = args->a_expptr = &args->a_expbuf[0];
|
||||||
args->a_rawvec[0] = args->a_rawptr = &args->a_rawbuf[0];
|
args->a_rawvec[0] = args->a_rawptr = &args->a_rawbuf[0];
|
||||||
if ((ch = GetChar()) != ')') {
|
if ((ch = GetChar()) != ')') {
|
||||||
PushBack();
|
UnGetChar();
|
||||||
while ((ch = actual(repl)) != ')' ) {
|
while ((ch = actual(repl)) != ')' ) {
|
||||||
if (ch != ',') {
|
if (ch != ',') {
|
||||||
lexerror("illegal macro call");
|
lexerror("illegal macro call");
|
||||||
|
@ -257,11 +250,11 @@ struct repl *repl;
|
||||||
like macro calls. It makes the following code
|
like macro calls. It makes the following code
|
||||||
work:
|
work:
|
||||||
|
|
||||||
#define def(a,b) x(a,b)
|
#define def(a,b) x(a,b)
|
||||||
#define glue(a,b) a ## b
|
#define glue(a,b) a ## b
|
||||||
|
|
||||||
glue(abc,def(a,b))
|
glue(abc,def(a,b))
|
||||||
|
|
||||||
Results in:
|
Results in:
|
||||||
|
|
||||||
abcdef(a,b);
|
abcdef(a,b);
|
||||||
|
@ -371,7 +364,8 @@ actual(repl)
|
||||||
}
|
}
|
||||||
UnGetChar();
|
UnGetChar();
|
||||||
} else if (ch == '(' || ch == '[' || ch == '{') {
|
} else if (ch == '(' || ch == '[' || ch == '{') {
|
||||||
/* a comma may occur within these constructions */
|
/* a comma may occur within these constructions ???
|
||||||
|
*/
|
||||||
level++;
|
level++;
|
||||||
stash(repl, ch, !nostashraw);
|
stash(repl, ch, !nostashraw);
|
||||||
} else if (ch == ')' || ch == ']' || ch == '}') {
|
} else if (ch == ')' || ch == ']' || ch == '}') {
|
||||||
|
@ -392,7 +386,7 @@ actual(repl)
|
||||||
/* newlines are accepted as white spaces */
|
/* newlines are accepted as white spaces */
|
||||||
LineNumber++;
|
LineNumber++;
|
||||||
while ((ch = GetChar()), class(ch) == STSKIP)
|
while ((ch = GetChar()), class(ch) == STSKIP)
|
||||||
/* VOID */;
|
/* EMPTY */;
|
||||||
|
|
||||||
/* This piece of code needs some explanation:
|
/* This piece of code needs some explanation:
|
||||||
consider the call of a macro defined as:
|
consider the call of a macro defined as:
|
||||||
|
@ -456,7 +450,7 @@ macro_func(idef)
|
||||||
register struct idf *idef;
|
register struct idf *idef;
|
||||||
{
|
{
|
||||||
/* macro_func() performs the special actions needed with some
|
/* macro_func() performs the special actions needed with some
|
||||||
macros. These macros are __FILE__ and __LINE__ which
|
macros. These macros are __FILE__ and __LINE__ which
|
||||||
replacement texts must be evaluated at the time they are
|
replacement texts must be evaluated at the time they are
|
||||||
used.
|
used.
|
||||||
*/
|
*/
|
||||||
|
@ -504,7 +498,7 @@ macro2buffer(repl, idf, args)
|
||||||
| TOKEN '##' PARAMETER
|
| TOKEN '##' PARAMETER
|
||||||
| PARAMETER '##' PARAMETER
|
| PARAMETER '##' PARAMETER
|
||||||
;
|
;
|
||||||
|
|
||||||
As the grammar indicates, we could make a DFA and
|
As the grammar indicates, we could make a DFA and
|
||||||
use this finite state machine for the replacement
|
use this finite state machine for the replacement
|
||||||
list parsing (inserting the arguments, etc.).
|
list parsing (inserting the arguments, etc.).
|
||||||
|
@ -526,11 +520,11 @@ macro2buffer(repl, idf, args)
|
||||||
do {
|
do {
|
||||||
*repl->r_ptr++ = *ptr;
|
*repl->r_ptr++ = *ptr;
|
||||||
if (*ptr == '\\')
|
if (*ptr == '\\')
|
||||||
*repl->r_ptr++ = *++ptr;
|
*repl->r_ptr++ = *++ptr;
|
||||||
if (*ptr == '\0') {
|
if (*ptr == '\0') {
|
||||||
lexerror("unterminated string");
|
lexerror("unterminated string");
|
||||||
*repl->r_ptr = '\0';
|
*repl->r_ptr = '\0';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ptr++;
|
ptr++;
|
||||||
} while (*ptr != delim || *ptr == '\0');
|
} while (*ptr != delim || *ptr == '\0');
|
||||||
|
@ -543,21 +537,20 @@ macro2buffer(repl, idf, args)
|
||||||
/* trim the actual replacement list */
|
/* trim the actual replacement list */
|
||||||
--repl->r_ptr;
|
--repl->r_ptr;
|
||||||
while (is_wsp(*repl->r_ptr)
|
while (is_wsp(*repl->r_ptr)
|
||||||
&& repl->r_ptr >= repl->r_text)
|
&& repl->r_ptr >= repl->r_text)
|
||||||
--repl->r_ptr;
|
--repl->r_ptr;
|
||||||
|
|
||||||
/* ## occurred at the beginning of the
|
/* ## occurred at the beginning of the replacement list.
|
||||||
replacement list.
|
*/
|
||||||
*/
|
|
||||||
if (repl->r_ptr == repl->r_text
|
if (repl->r_ptr == repl->r_text
|
||||||
&& is_wsp(*repl->r_ptr)) {
|
&& is_wsp(*repl->r_ptr)) {
|
||||||
err = 1;
|
err = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
while(*repl->r_ptr == TOKSEP
|
while(*repl->r_ptr == TOKSEP
|
||||||
&& repl->r_ptr >= repl->r_text)
|
&& repl->r_ptr >= repl->r_text)
|
||||||
--repl->r_ptr;
|
--repl->r_ptr;
|
||||||
|
|
||||||
tmpptr = repl->r_ptr;
|
tmpptr = repl->r_ptr;
|
||||||
++repl->r_ptr;
|
++repl->r_ptr;
|
||||||
|
@ -567,7 +560,7 @@ macro2buffer(repl, idf, args)
|
||||||
ptr++;
|
ptr++;
|
||||||
|
|
||||||
/* ## occurred at the end of the replacement list.
|
/* ## occurred at the end of the replacement list.
|
||||||
*/
|
*/
|
||||||
if (*ptr & FORMALP) {
|
if (*ptr & FORMALP) {
|
||||||
register int n = *ptr++ & 0177;
|
register int n = *ptr++ & 0177;
|
||||||
register char *p;
|
register char *p;
|
||||||
|
@ -598,13 +591,13 @@ macro2buffer(repl, idf, args)
|
||||||
if (*tmpptr == NOEXPM) *tmpptr = TOKSEP;
|
if (*tmpptr == NOEXPM) *tmpptr = TOKSEP;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else
|
} else /* # operator */
|
||||||
ptr = stringify(repl, ptr, args);
|
ptr = stringify(repl, ptr, args);
|
||||||
} else if (*ptr & FORMALP) {
|
} else if (*ptr & FORMALP) {
|
||||||
/* insert actual parameter */
|
/* insert actual parameter */
|
||||||
register int n = *ptr++ & 0177;
|
register int n = *ptr++ & 0177;
|
||||||
register char *p, *q;
|
register char *p, *q;
|
||||||
|
|
||||||
ASSERT(n > 0);
|
ASSERT(n > 0);
|
||||||
|
|
||||||
/* This is VERY dirty, we look ahead for the
|
/* This is VERY dirty, we look ahead for the
|
||||||
|
@ -613,7 +606,7 @@ macro2buffer(repl, idf, args)
|
||||||
one.
|
one.
|
||||||
*/
|
*/
|
||||||
for (p = ptr; (*p & FORMALP) == 0 && is_wsp(*p); p++)
|
for (p = ptr; (*p & FORMALP) == 0 && is_wsp(*p); p++)
|
||||||
/* EMPTY */;
|
/* EMPTY */;
|
||||||
if (*p == '#' && p[1] == '#')
|
if (*p == '#' && p[1] == '#')
|
||||||
q = args->a_rawvec[n-1];
|
q = args->a_rawvec[n-1];
|
||||||
else
|
else
|
||||||
|
@ -632,7 +625,6 @@ macro2buffer(repl, idf, args)
|
||||||
*repl->r_ptr = '\0';
|
*repl->r_ptr = '\0';
|
||||||
if (err)
|
if (err)
|
||||||
lexerror("illegal use of the ## operator");
|
lexerror("illegal use of the ## operator");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
|
@ -664,7 +656,7 @@ stringify(repl, ptr, args)
|
||||||
if (*ptr & FORMALP) {
|
if (*ptr & FORMALP) {
|
||||||
register int n = *ptr++ & 0177;
|
register int n = *ptr++ & 0177;
|
||||||
register char *p;
|
register char *p;
|
||||||
|
|
||||||
ASSERT(n != 0);
|
ASSERT(n != 0);
|
||||||
p = args->a_rawvec[n-1];
|
p = args->a_rawvec[n-1];
|
||||||
*repl->r_ptr++ = '"';
|
*repl->r_ptr++ = '"';
|
||||||
|
@ -692,11 +684,12 @@ stringify(repl, ptr, args)
|
||||||
|
|
||||||
/* trim spaces in the replacement list */
|
/* trim spaces in the replacement list */
|
||||||
for (--repl->r_ptr; is_wsp(*repl->r_ptr); repl->r_ptr--)
|
for (--repl->r_ptr; is_wsp(*repl->r_ptr); repl->r_ptr--)
|
||||||
/* VOID */;
|
/* EMPTY */;
|
||||||
*++repl->r_ptr = '"';
|
*++repl->r_ptr = '"';
|
||||||
++repl->r_ptr; /* oops, one to far */
|
++repl->r_ptr; /* oops, one to far */
|
||||||
} else
|
} else
|
||||||
error("illegal use of # operator");
|
error("illegal use of # operator");
|
||||||
|
*repl->r_ptr = '\0';
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ skipspaces(ch, skipnl)
|
||||||
return '/';
|
return '/';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(nlseen && ch == '#') {
|
else if (nlseen && ch == '#') {
|
||||||
domacro();
|
domacro();
|
||||||
ch = GetChar();
|
ch = GetChar();
|
||||||
} else
|
} else
|
||||||
|
|
|
@ -60,9 +60,16 @@ code_startswitch(expp)
|
||||||
|
|
||||||
switch (fund) {
|
switch (fund) {
|
||||||
case LONG:
|
case LONG:
|
||||||
|
/* switches on longs should work. Unfortunately, no backend
|
||||||
|
* has simplemented switches with sizes other than the
|
||||||
|
* word_size. Furthermore, building the rom should then be
|
||||||
|
* done using C_rom_icon().
|
||||||
|
* Just cast the expression to int and give a warning when
|
||||||
|
* this means truncation.
|
||||||
|
*/
|
||||||
if (long_size > int_size)
|
if (long_size > int_size)
|
||||||
warning("can't switch on longs (cast to int)");
|
warning("can't switch on longs (cast to int)");
|
||||||
int2int(expp, int_type);
|
int2int(expp, int_type); /* for now ??? */
|
||||||
break;
|
break;
|
||||||
case FLOAT:
|
case FLOAT:
|
||||||
case DOUBLE:
|
case DOUBLE:
|
||||||
|
|
|
@ -37,6 +37,16 @@ struct tokenname tkspec[] = { /* the names of the special tokens */
|
||||||
|
|
||||||
#ifdef ____
|
#ifdef ____
|
||||||
struct tokenname tkcomp[] = { /* names of the composite tokens */
|
struct tokenname tkcomp[] = { /* names of the composite tokens */
|
||||||
|
{PLUSAB, "+="},
|
||||||
|
{MINAB, "-="},
|
||||||
|
{TIMESAB, "*="},
|
||||||
|
{DIVAB, "/="},
|
||||||
|
{MODAB, "%="},
|
||||||
|
{LEFTAB, "<<="},
|
||||||
|
{RIGHTAB, ">>="},
|
||||||
|
{ANDAB, "&="},
|
||||||
|
{XORAB, "^="},
|
||||||
|
{ORAB, "|="},
|
||||||
{NOTEQUAL, "!="},
|
{NOTEQUAL, "!="},
|
||||||
{AND, "&&"},
|
{AND, "&&"},
|
||||||
{PLUSPLUS, "++"},
|
{PLUSPLUS, "++"},
|
||||||
|
@ -113,16 +123,6 @@ struct tokenname tkfunny[] = { /* internal keywords */
|
||||||
{CASTAB, "castab"},
|
{CASTAB, "castab"},
|
||||||
{POSTINCR, "postfix ++"},
|
{POSTINCR, "postfix ++"},
|
||||||
{POSTDECR, "postfix --"},
|
{POSTDECR, "postfix --"},
|
||||||
{PLUSAB, "+="},
|
|
||||||
{MINAB, "-="},
|
|
||||||
{TIMESAB, "*="},
|
|
||||||
{DIVAB, "/="},
|
|
||||||
{MODAB, "%="},
|
|
||||||
{LEFTAB, "<<="},
|
|
||||||
{RIGHTAB, ">>="},
|
|
||||||
{ANDAB, "&="},
|
|
||||||
{XORAB, "^="},
|
|
||||||
{ORAB, "|="},
|
|
||||||
|
|
||||||
{INT2INT, "int2int"},
|
{INT2INT, "int2int"},
|
||||||
{INT2FLOAT, "int2float"},
|
{INT2FLOAT, "int2float"},
|
||||||
|
|
|
@ -112,7 +112,7 @@ construct_type(fund, tp, qual, count, pl)
|
||||||
count = (arith)-1;
|
count = (arith)-1;
|
||||||
}
|
}
|
||||||
else if (tp->tp_size == 0) /* CJ */
|
else if (tp->tp_size == 0) /* CJ */
|
||||||
warning("array elements have size 0");
|
strict("array elements have size 0");
|
||||||
if (count >= (arith)0)
|
if (count >= (arith)0)
|
||||||
count *= tp->tp_size;
|
count *= tp->tp_size;
|
||||||
dtp = array_of(tp, count, qual);
|
dtp = array_of(tp, count, qual);
|
||||||
|
|
Loading…
Reference in a new issue