minor changes concerning void and pre-processor

This commit is contained in:
eck 1989-09-29 16:20:38 +00:00
parent 26cc87efe6
commit 4bde31f78a
22 changed files with 101 additions and 115 deletions

View file

@ -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;

View file

@ -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;

View file

@ -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 */

View file

@ -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;

View file

@ -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 '~':

View file

@ -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 */

View file

@ -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);

View file

@ -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 */

View file

@ -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) {

View file

@ -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 */

View file

@ -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.
*/ */

View file

@ -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);
} }
} }
} }

View file

@ -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__ */

View file

@ -44,8 +44,6 @@ getwdir(fn)
int NoUnstack; int NoUnstack;
int InputLevel; int InputLevel;
#if 0
#endif
AtEoIT() AtEoIT()
{ {

View file

@ -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);

View file

@ -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 */
}; };

View file

@ -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

View file

@ -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;
} }

View file

@ -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

View file

@ -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:

View file

@ -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"},

View file

@ -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);