domacro.o: LLlex.h Lpars.h arith.h assert.h botch_free.h class.h debug.h file_info.h idf.h idfsize.h ifdepth.h input.h interface.h macro.h nofloat.h nopp.h nparams.h parbufsize.h spec_arith.h textsize.h
replace.o: LLlex.h arith.h assert.h class.h debug.h file_info.h idf.h input.h interface.h macro.h nofloat.h nopp.h pathlength.h spec_arith.h static.h strsize.h
init.o: class.h idf.h interface.h macro.h nopp.h
-options.o: align.h arith.h botch_free.h class.h idf.h idfsize.h macro.h maxincl.h nobitfield.h nofloat.h nopp.h sizes.h spec_arith.h use_tmp.h
+options.o: align.h arith.h botch_free.h class.h dataflow.h idf.h idfsize.h macro.h maxincl.h nobitfield.h nofloat.h nopp.h sizes.h spec_arith.h use_tmp.h
scan.o: class.h idf.h input.h interface.h lapbuf.h macro.h nopp.h nparams.h
skip.o: LLlex.h arith.h class.h file_info.h input.h interface.h nofloat.h nopp.h spec_arith.h
-stack.o: Lpars.h arith.h botch_free.h debug.h def.h idf.h level.h mes.h nobitfield.h nofloat.h nopp.h spec_arith.h stack.h struct.h type.h use_tmp.h
+stack.o: Lpars.h arith.h botch_free.h debug.h def.h idf.h level.h mes.h nobitfield.h nofloat.h nopp.h spec_arith.h stack.h struct.h type.h
type.o: Lpars.h align.h arith.h botch_free.h def.h idf.h nobitfield.h nofloat.h nopp.h sizes.h spec_arith.h type.h
ch7mon.o: Lpars.h arith.h botch_free.h def.h expr.h idf.h label.h nobitfield.h nofloat.h nopp.h spec_arith.h type.h
label.o: Lpars.h arith.h def.h idf.h label.h level.h nobitfield.h nofloat.h nopp.h spec_arith.h type.h
!File: idfsize.h
-#define IDFSIZE 30 /* maximum significant length of an identifier */
+#define IDFSIZE 64 /* maximum significant length of an identifier */
!File: numsize.h
!File: debug.h
-#define DEBUG 1 /* perform various self-tests */
+#undef DEBUG 1 /* perform various self-tests */
!File: use_tmp.h
--- /dev/null
+static char Version[] = "ACK CEM compiler Version 3.1";
int
any2arith(expp, oper)
register struct expr **expp;
+ register int oper;
{
/* Turns any expression into int_type, long_type or
double_type.
int
int2int(expp, tp)
register struct expr **expp;
- struct type *tp;
+ register struct type *tp;
{
/* The expression *expp, which is of some integral type, is
converted to the integral type tp.
*/
if (is_cp_cst(*expp)) {
+ register struct type *tp1 = (*expp)->ex_type;
+
(*expp)->ex_type = tp;
+ if (! tp1->tp_unsigned && tp->tp_unsigned) {
+ /* Avoid "unreal" overflow warnings, such as
+ caused by f.i.:
+ unsigned int x = ~0;
+ unsigned int y = -1;
+ */
+ extern long full_mask[];
+ long remainder = (*expp)->VL_VALUE &
+ ~full_mask[tp->tp_size];
+
+ if (remainder == 0 ||
+ remainder == ~full_mask[tp->tp_size]) {
+ (*expp)->VL_VALUE &= ~remainder;
+ }
+ }
cut_size(*expp);
}
else {
#ifndef NOFLOAT
int
int2float(expp, tp)
- struct expr **expp;
+ register struct expr **expp;
struct type *tp;
{
/* The expression *expp, which is of some integral type, is
}
float2float(expp, tp)
- struct expr **expp;
+ register struct expr **expp;
struct type *tp;
{
/* The expression *expp, which is of some floating type, is
#endif NOFLOAT
array2pointer(expp)
- struct expr **expp;
+ register struct expr **expp;
{
/* The expression, which must be an array, is converted
to a pointer.
register struct expr **expp;
int oper;
{
- register int fund;
+ int fund;
if ((*expp)->ex_type->tp_fund == FUNCTION)
function2pointer(expp);
ch7bin(expp, '&', intexpr(fd->fd_mask, INT));
}
else { /* take care of the sign bit: sign extend if needed */
- register arith bits_in_type = atype->tp_size * 8;
+ arith bits_in_type = atype->tp_size * 8;
ch7bin(expp, LEFT,
intexpr(bits_in_type - fd->fd_width - fd->fd_shift,
/* $Header$ */
/* A S M */
+/*ARGSUSED*/
code_asm(s, l)
char *s;
int l;
{
/* 'asm' '(' string ')' ';'
*/
- s = s; l = l;
- error("\"asm instruction not implemented", s);
+ error("\"asm\" instruction not implemented");
}
set_traps(trap);
ProgCall = *argv++;
+ append(&CEM_FLAGS, "-L");
while (--argc > 0) {
if (*(str = *argv++) != '-') {
append(&SRCFILES, str);
case 'O':
append(&O_FLAGS, "-O");
break;
- case 'p':
- append(&CEM_FLAGS, "-p");
- break;
case 'R':
if (str[2] == '\0')
append(&CEM_FLAGS, str);
needs not be specified.
.br
\fIOptions\fP is a, possibly empty, sequence of the following combinations:
-.IP \fB\-C\fR
-list the sequence of input tokens while maintaining the comments.
.IP \fB\-D\fIname\fR=\fItext\fR
.br
define \fIname\fR as a macro with \fItext\fR as its replacement text.
.IP \fB\-D\fIname\fR
.br
the same as \fB\-D\fIname\fR=1.
-.IP \fB\-E\fR
-list the sequence of input tokens and delete any comments.
-Control lines of the form
-.RS
-.RS
-#\fBline\fR <\fIinteger\fR> "\fIfilename\fR"
-.RE
-are generated whenever needed.
-.RE
.IP \fB\-I\fIdirname\fR
.br
insert \fIdirname\fR in the list of include directories.
don't generate the EM \fBfil\fR and \fBlin\fR instructions
that usually are generated to enable
an interpreter to keep track of the current location in the source code.
-.IP \fB\-P\fR
-like \fB\-E\fR but without #\fBline\fR control lines.
+.IP \fB\-p\fR
+generate code at each procedure entry to call the routine
+.BR procentry ,
+and at each return to call the routine
+.BE procexit .
+These routines are supplied with one parameter, a pointer to a
+string containing the name of the procedure.
.IP \fB\-R\fR
interpret the input as restricted C (according to the language as
described in \fIThe C programming language\fR by Kernighan and Ritchie.)
to force a certain option to be handed over to \fBcemcom\fR.
.LP
.SH FILES
-.IR /usr/em/lib/em_cemcom :
+.IR ~em/lib/em_cemcom :
the compiler
.SH DIAGNOSTICS
All warning and error messages are written on standard error output.
-.SH BUGS
-Feel free to report them to erikb@vu44.uucp
.SH REFERENCE
Baalbergen, E.H., D. Grune, M. Waage ;"\fIThe CEM compiler\fR",
Informatica Manual IM-4
*/
int
is_integral_type(tp)
- struct type *tp;
+ register struct type *tp;
{
switch (tp->tp_fund) {
case CHAR:
int
is_arith_type(tp)
- struct type *tp;
+ register struct type *tp;
{
switch (tp->tp_fund) {
case CHAR:
lab_count = (label) 1;
return_label = text_label();
return_expr_occurred = 0;
+ prc_entry(name);
if (! options['L']) { /* profiling */
if (strcmp(last_fn_given, FileName) != 0) {
/* previous function came from other file */
if (options['d'])
DfaEndFunction();
#endif DATAFLOW
+ prc_exit();
C_ret((arith)0);
if (return_expr_occurred != 0) {
C_df_ilb(return_label);
+ prc_exit();
if (func_res_label != 0) {
C_lae_dlb(func_res_label, (arith)0);
store_block(func_tp->tp_size, func_tp->tp_align);
{
/* do_return generates a direct return */
/* isn't a jump to the return label smarter ??? */
+ prc_exit();
C_ret((arith)0);
}
loc_init(expr, id)
struct expr *expr;
- struct idf *id;
+ register struct idf *id;
{
/* loc_init() generates code for the assignment of
expression expr to the local variable described by id.
which may contain break or continue
*/
register struct stmt_block *sbp = stmt_stack;
- stmt_stack = stmt_stack->next;
+ stmt_stack = sbp->next;
free_stmt_block(sbp);
}
+
+static label l1;
+
+prc_entry(name)
+ char *name;
+{
+ if (options['p']) {
+ C_df_dlb(l1 = data_label());
+ C_rom_scon(name, (arith) (strlen(name) + 1));
+ C_lae_dlb(l1);
+ C_cal("procentry");
+ C_asp(pointer_size);
+ }
+}
+
+prc_exit()
+{
+ if (options['p']) {
+ C_lae_dlb(l1);
+ C_cal("procexit");
+ C_asp(pointer_size);
+ }
+}
*/
conversion(from_type, to_type)
- struct type *from_type, *to_type;
+ register struct type *from_type, *to_type;
{
- arith from_size;
- arith to_size;
+ register arith from_size = from_type->tp_size;
+ register arith to_size = to_type->tp_size;
if (from_type == to_type) /* a little optimisation */
return;
- from_size = from_type->tp_size;
- to_size = to_type->tp_size;
switch (fundamental(from_type)) {
case T_SIGNED:
switch (fundamental(to_type)) {
#ifndef NOFLOAT
case T_FLOATING:
C_loc(from_size < word_size ? word_size : from_size);
- C_loc(to_size < word_size ? word_size : to_size);
+ C_loc(to_size);
C_cif();
break;
#endif NOFLOAT
break;
#ifndef NOFLOAT
case T_FLOATING:
- C_loc(from_size < word_size ? word_size : from_size);
+ C_loc(from_size);
C_loc(to_size < word_size ? word_size : to_size);
switch (fundamental(to_type)) {
case T_SIGNED:
/* The constant value of the expression expr is made to
conform to the size of the type of the expression.
*/
- arith o1 = expr->VL_VALUE;
+ register arith o1 = expr->VL_VALUE;
int uns = expr->ex_type->tp_unsigned;
int size = (int) expr->ex_type->tp_size;
makes all hope of writing a specific grammar for typedefs illusory.
*/
-decl_specifiers /* non-empty */ (struct decspecs *ds;)
+decl_specifiers /* non-empty */ (register struct decspecs *ds;)
/* Reads a non-empty decl_specifiers and fills the struct
decspecs *ds.
*/
;
/* 8.1 */
-other_specifier(struct decspecs *ds;):
-[
+other_specifier(register struct decspecs *ds;):
[ AUTO | STATIC | EXTERN | TYPEDEF | REGISTER ]
{ if (ds->ds_sc_given)
error("repeated storage class specifier");
error("unsigned specified twice");
else ds->ds_unsigned = 1;
}
-]
;
/* 8.2 */
{*tpp = Ds.ds_type;}
;
-single_type_specifier(struct decspecs *ds;):
-[
+single_type_specifier(register struct decspecs *ds;):
TYPE_IDENTIFIER /* this includes INT, CHAR, etc. */
{idf2type(dot.tk_idf, &ds->ds_type);}
|
struct_or_union_specifier(&ds->ds_type)
|
enum_specifier(&ds->ds_type)
-]
;
/* 8.3 */
[ ',' init_declarator(ds) ]*
;
-init_declarator(struct decspecs *ds;)
+init_declarator(register struct decspecs *ds;)
{
struct declarator Dc;
struct expr *expr = (struct expr *) 0;
we just include the (formal) parameter list in the declarator
description list dc.
*/
-declarator(struct declarator *dc;)
+declarator(register struct declarator *dc;)
{
arith count;
struct formal *fm = 0;
}
:
-[
primary_declarator(dc)
[%while(1) /* int i (M + 2) / 4;
is a function, not an
|
'*' declarator(dc)
{add_decl_unary(dc, POINTER, (arith)0, NO_PARAMS);}
-]
;
-primary_declarator(struct declarator *dc;) :
-[
+primary_declarator(register struct declarator *dc;) :
identifier(&dc->dc_idf)
|
'(' declarator(dc) ')'
-]
;
arrayer(arith *sizep;)
:
identifier(&idf)
{
- struct formal *new = new_formal();
+ register struct formal *new = new_formal();
new->fm_idf = idf;
new->next = *fmp;
;
/* Change 2 */
-enum_specifier(struct type **tpp;)
+enum_specifier(register struct type **tpp;)
{
struct idf *idf;
arith l = (arith)0;
]
;
-enumerator_pack(struct type *tp; arith *lp;) :
+enumerator_pack(register struct type *tp; arith *lp;) :
'{'
enumerator(tp, lp)
[%while(AHEAD != '}') /* >>> conflict on ',' */
;
/* 8.5 */
-struct_or_union_specifier(struct type **tpp;)
+struct_or_union_specifier(register struct type **tpp;)
{
int fund;
- struct idf *idf;
+ struct idf *idfX;
+ register struct idf *idf;
}
:
[ STRUCT | UNION ]
}
struct_declaration_pack(*tpp)
|
- identifier(&idf)
+ identifier(&idfX) { idf = idfX; }
[
{
declare_struct(fund, idf, tpp);
]
;
-struct_declaration_pack(struct type *stp;)
+struct_declaration_pack(register struct type *stp;)
{
struct sdef **sdefp = &stp->tp_sdef;
arith size = (arith)0;
;
/* 8.6 */
-initializer(struct idf *idf; struct expr **expp;) :
+initializer(register struct idf *idf; register struct expr **expp;) :
[
'='
|
/* This code is an abject copy of that of 'declarator', for lack of
a two-level grammar.
*/
-abstract_declarator(struct declarator *dc;)
+abstract_declarator(register struct declarator *dc;)
{arith count;}
:
-[
primary_abstract_declarator(dc)
[
'(' ')'
|
'*' abstract_declarator(dc)
{add_decl_unary(dc, POINTER, (arith)0, NO_PARAMS);}
-]
;
primary_abstract_declarator(struct declarator *dc;) :
if (gencode) {
EVAL(right, RVAL, TRUE, l_true,
l_false);
- C_df_ilb(l_false);
- C_loc((arith)0);
- C_bra(l_end);
C_df_ilb(l_true);
C_loc((arith)1);
+ C_bra(l_end);
+ C_df_ilb(l_false);
+ C_loc((arith)0);
C_df_ilb(l_end);
}
else {
break;
case '!':
if (true_label == 0) {
+ EVAL(right, RVAL, gencode, NO_LABEL, NO_LABEL);
if (gencode) {
- label l_true = text_label();
- label l_false = text_label();
- label l_end = text_label();
-
- EVAL(right, RVAL, TRUE, l_false,
- l_true);
- C_df_ilb(l_false);
- C_loc((arith)0);
- C_bra(l_end);
- C_df_ilb(l_true);
- C_loc((arith)1);
- C_df_ilb(l_end);
+ C_teq();
}
- else
- EVAL(right, RVAL, FALSE, NO_LABEL,
- NO_LABEL);
}
else
EVAL(right, RVAL, gencode, false_label,
}
check_conditional(expr, oper, pos_descr)
- struct expr *expr;
+ register struct expr *expr;
char *pos_descr;
{
/* Warn if restricted C is in effect and the expression expr,
}
dot2expr(expp)
- register struct expr **expp;
+ struct expr **expp;
{
/* The token in dot is converted into an expression, a
pointer to which is stored in *expp.
*/
- *expp = new_expr();
- (*expp)->ex_file = dot.tk_file;
- (*expp)->ex_line = dot.tk_line;
+ register struct expr *ex = new_expr();
+
+ *expp = ex;
+ ex->ex_file = dot.tk_file;
+ ex->ex_line = dot.tk_line;
switch (DOT) {
case IDENTIFIER:
- idf2expr(*expp);
+ idf2expr(ex);
break;
case STRING:
- string2expr(*expp);
+ string2expr(ex);
break;
case INTEGER:
- int2expr(*expp);
+ int2expr(ex);
break;
#ifndef NOFLOAT
case FLOATING:
- float2expr(*expp);
+ float2expr(ex);
break;
#endif NOFLOAT
default:
struct expr *
new_oper(tp, e1, oper, e2)
struct type *tp;
- struct expr *e1, *e2;
+ register struct expr *e1, *e2;
{
/* A new expression is constructed which consists of the
operator oper which has e1 and e2 as operands; for a
/* 7 */
initial_value(struct expr **expp;) :
-[
assignment_expression(expp)
{
if ((*expp)->ex_type->tp_fund == ARRAY)
}
|
initial_value_pack(expp)
-]
;
initial_value_pack(struct expr **expp;) :
/* 7.1 */
-primary(struct expr **expp;) :
-[
+primary(register struct expr **expp;) :
IDENTIFIER
{dot2expr(expp);}
|
|
'(' expression(expp) ')'
{(*expp)->ex_flags |= EX_PARENS;}
-]
;
-secundary(struct expr **expp;) :
+secundary(register struct expr **expp;) :
primary(expp)
[
index_pack(expp)
%first first_of_type_specifier, type_specifier;
-unary(struct expr **expp;)
+unary(register struct expr **expp;)
{struct type *tp; int oper;}
:
-[%if (first_of_type_specifier(AHEAD))
+%if (first_of_type_specifier(AHEAD))
cast(&tp) unary(expp)
{ ch7cast(expp, CAST, tp);
(*expp)->ex_flags |= EX_CAST;
{ch7mon(oper, expp);}
|
size_of(expp)
-]
;
-size_of(struct expr **expp;)
+size_of(register struct expr **expp;)
{struct type *tp;}
:
SIZEOF
;
postop(int *oper;):
-[
PLUSPLUS {*oper = POSTINCR;}
|
MINMIN {*oper = POSTDECR;}
-]
;
multop:
{*oper = DOT;}
;
-asgnop(int *oper;):
-[
+asgnop(register int *oper;):
'=' {*oper = DOT;}
|
'+' '=' {*oper = PLUSAB;}
symbol2str(DOT));
*oper = DOT;
}
-]
;
constant(struct expr **expp;) :
register struct mkey *mk = &mkey[0];
while (mk->mk_reserved) {
- struct idf *idf = str2idf(mk->mk_reserved);
+ register struct idf *idf = str2idf(mk->mk_reserved);
if (idf->id_resmac)
fatal("maximum identifier length insufficient");
#ifndef NOPP
char *
getwdir(fn)
- char *fn;
+ register char *fn;
{
register char *p;
char *strrindex();
}
enter_label(idf, defining)
- struct idf *idf;
+ register struct idf *idf;
{
/* The identifier idf is entered as a label. If it is new,
it is entered into the idf list with the largest possible
If defining, the label comes from a label statement.
*/
if (idf->id_def) {
- struct def *def = idf->id_def;
+ register struct def *def = idf->id_def;
if (def->df_sc == LABEL) {
if (defining && def->df_initialized)
}
unstack_label(idf)
- struct idf *idf;
+ register struct idf *idf;
{
/* The scope in which the label idf occurred is left.
*/
/* ALLOCDEF "macro" 20 */
+struct mlist {
+ struct mlist *next;
+ struct macro *m_mac;
+ char *m_repl;
+};
+
+/* ALLOCDEF "mlist" 20 */
+
/* `token' numbers of keywords of command-line processor
*/
#define K_UNKNOWN 0
}
char *source = 0;
-char *destination = 0;
char *nmlist = 0;
char tmpf[256];
#endif
char *result;
+ register char *destination = 0;
+#ifdef DEBUG
#ifndef NOPP
- int pp_only = options['E'] || options['P'];
+ int pp_only = options['E'] || options['P'] || options['C'];
#endif NOPP
+#endif
switch (argc) {
case 1:
+#ifdef DEBUG
#ifndef NOPP
if (!pp_only)
#endif NOPP
+#endif
fatal("%s: destination file not specified", prog_name);
break;
case 2:
#endif NOPP
PushLex();
+#ifdef DEBUG
#ifndef NOPP
if (pp_only) /* run the preprocessor as if it is stand-alone */
preprocess();
- else {
+ else
#endif NOPP
+#endif DEBUG
+ {
#ifdef USE_TMP
if (!options['N']) {
init_code(tmpfile);
}
else
- init_code(destination);
-#else USE_TMP
- init_code(destination);
#endif USE_TMP
+ init_code(destination);
/* compile the source text */
C_program();
if (options['f'] || options['t'])
dumpidftab("end of main", options['f'] ? 0 : 0);
#endif DEBUG
-#ifndef NOPP
}
-#endif NOPP
PopLex();
}
}
}
+#ifdef DEBUG
#ifndef NOPP
preprocess()
{
}
}
#endif NOPP
+#endif DEBUG
#ifdef USE_TMP
AppendFile(src, dst)
#include "sizes.h"
#include "align.h"
#include "use_tmp.h"
+#include "dataflow.h"
#ifndef NOPP
extern char *inctable[MAXINCL];
options[*text] = 1; /* flags, debug options etc. */
break;
+#ifdef DATAFLOW
+ case 'd':
+#endif DATAFLOW
+ case 'p': /* procentry/procexit */
+ case 'L' : /* no fil/lin */
+ case 'n': /* use no registers */
+ case 'w': /* no warnings will be given */
+ case 'R': /* strict version */
+ options[*(text-1)] = 1;
+ break;
+
+#ifdef ___XXX___
+deleted, is now a debug-flag
case 'C' : /* E option + comment output */
#ifndef NOPP
options['E'] = 1;
warning("-C option ignored");
#endif NOPP
break;
+#endif ___XXX___
case 'D' : { /* -Dname : predefine name */
#ifndef NOPP
break;
}
+#ifdef ___XXX___
case 'E' : /* run preprocessor only, with #<int> */
#ifndef NOPP
options['E'] = 1;
warning("-E option ignored");
#endif NOPP
break;
+#endif ___XXX___
case 'I' : /* -Ipath : insert "path" into include list */
#ifndef NOPP
#endif NOPP
break;
- case 'L' :
- options['L'] = 1; /* no fil/lin */
- break;
-
case 'M': /* maximum identifier length */
idfsize = txt2int(&text);
if (*text || idfsize <= 0)
#endif USE_TMP
break;
+#ifdef ___XXX___
case 'P' : /* run preprocessor stand-alone, without #'s */
#ifndef NOPP
options['E'] = 1;
warning("-P option ignored");
#endif NOPP
break;
-
- case 'R':
- options['R'] = 1;
- break;
+#endif ___XXX___
#ifdef USE_TMP
case 'T' :
}
break;
}
- case 'n':
- options['n'] = 1; /* use no registers */
- break;
- case 'w':
- options['w'] = 1; /* no warnings will be given */
- break;
}
}
control_if_expression
{
- struct expr *expr;
+ struct expr *exprX;
}
:
- constant_expression(&expr)
+ constant_expression(&exprX)
{
#ifndef NOPP
+ register struct expr *expr = exprX;
if (expr->ex_flags & EX_SIZEOF)
expr_error(expr,
"sizeof not allowed in preprocessor");
Ds = null_decspecs;
Dc = null_declarator;
}
-[
ext_decl_specifiers(&Ds)
[
declarator(&Dc)
{remove_declarator(&Dc);}
|
asm_statement /* top level, would you believe */
-]
;
ext_decl_specifiers(struct decspecs *ds;) :
-[%prefer /* the thin ice in R.M. 11.1 */
+%prefer /* the thin ice in R.M. 11.1 */
decl_specifiers(ds)
|
empty
{do_decspecs(ds);}
-]
;
-non_function(struct decspecs *ds; struct declarator *dc;)
+non_function(register struct decspecs *ds; register struct declarator *dc;)
{
struct expr *expr = (struct expr *) 0;
}
arith fbytes, nbytes;
}
:
- { struct idf *idf = dc->dc_idf;
+ { register struct idf *idf = dc->dc_idf;
init_idf(idf);
stack_level(); /* L_FORMAL1 declarations */
char *strcpy(), *strcat();
char *long2str();
-PRIVATE struct macro *ReplaceList; /* list of currently active macros */
+PRIVATE struct mlist *ReplaceList; /* list of currently active macros */
EXPORT int
replace(idef)
some error has occurred.
*/
register struct macro *mac = idef->id_macro;
- register char c;
+ register struct mlist *repl;
+ register int c;
char **actpars, **getactuals();
char *reptext, *macro2buffer();
int size;
if (mac->mc_flag & FUNC) {
struct idf *param = str2idf(*actpars);
+ repl = new_mlist();
if (param->id_macro)
reptext = "1";
else
reptext = "0";
InsertText(reptext, 1);
- mac->next = ReplaceList;
- ReplaceList = mac;
+ repl->next = ReplaceList;
+ ReplaceList = repl;
+ repl->m_mac = mac;
return 1;
}
}
+ repl = new_mlist();
+ repl->m_mac = mac;
if (mac->mc_flag & FUNC) /* this macro leads to special action */
macro_func(idef);
- if (mac->mc_nps <= 0)
+ if (mac->mc_nps <= 0) {
+ reptext = mac->mc_text;
+ size = mac->mc_length;
mac->mc_flag |= NOREPLACE;
- reptext = macro2buffer(idef, actpars, &size); /* create input buffer */
+ }
+ else {
+ reptext = macro2buffer(idef, actpars, &size); /* create input buffer */
+ repl->m_repl = reptext;
+ }
InsertText(reptext, size);
- mac->next = ReplaceList;
- ReplaceList = mac;
+ repl->next = ReplaceList;
+ ReplaceList = repl;
return 1;
}
EXPORT
EnableMacros()
{
- register struct macro *p = ReplaceList;
+ register struct mlist *p = ReplaceList;
ASSERT(Unstacked > 0);
while (Unstacked > 0) {
+ struct mlist *nxt = p->next;
+
ASSERT(p != 0);
- p->mc_flag &= ~NOREPLACE;
- p->mc_count = 0;
- p = p->next;
+ p->m_mac->mc_flag &= ~NOREPLACE;
+ if (p->m_mac->mc_count) p->m_mac->mc_count--;
+ if (p->m_repl) free(p->m_repl);
+ free_mlist(p);
+ p = nxt;
Unstacked--;
}
ReplaceList = p;
PRIVATE char **
getactuals(idef)
- struct idf *idef;
+ register struct idf *idef;
{
/* getactuals() collects the actual parameters and turns them
into a list of strings, a pointer to which is returned.
/* A new level is added on top of the identifier stack.
*/
register struct stack_level *stl = new_stack_level();
+ register struct stack_level *loclev = local_level;
- local_level->sl_next = stl;
- stl->sl_previous = local_level;
+ loclev->sl_next = stl;
+ stl->sl_previous = loclev;
stl->sl_level = ++level;
stl->sl_local_offset =
- stl->sl_max_block = local_level->sl_local_offset;
+ stl->sl_max_block = loclev->sl_local_offset;
local_level = stl;
}
/* 9 */
statement
:
-[%if (AHEAD != ':')
+%if (AHEAD != ':')
expression_statement
|
label ':' statement
';'
|
asm_statement
-]
;
expression_statement