home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
unix
/
volume21
/
p2c
/
part27
< prev
next >
Wrap
Text File
|
1990-04-05
|
53KB
|
1,926 lines
Subject: v21i072: Pascal to C translator, Part27/32
Newsgroups: comp.sources.unix
Approved: rsalz@uunet.UU.NET
X-Checksum-Snefru: 4ea6754b 000f0649 c85b054a 545aa469
Submitted-by: Dave Gillespie <daveg@csvax.caltech.edu>
Posting-number: Volume 21, Issue 72
Archive-name: p2c/part27
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of archive 27 (of 32)."
# Contents: src/decl.c.2
# Wrapped by rsalz@litchi.bbn.com on Mon Mar 26 14:29:50 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'src/decl.c.2' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/decl.c.2'\"
else
echo shar: Extracting \"'src/decl.c.2'\" \(49154 characters\)
sed "s/^X//" >'src/decl.c.2' <<'END_OF_FILE'
X return 0;
X }
X if (args) {
X if (mp1->kind == MK_PARAM && mp1->othername)
X tp1 = mp1->rectype;
X if (mp2->kind == MK_PARAM && mp2->othername)
X tp2 = mp2->rectype;
X }
X if (tp1 == tp2)
X return 1;
X switch (mixtypes) {
X case 0:
X return 0;
X case 1:
X return (findbasetype(tp1, flags) == findbasetype(tp2, flags));
X default:
X if (findbasetype(tp1, flags) != findbasetype(tp2, flags))
X return 0;
X while (tp1->kind == TK_POINTER && tp1->basetype)
X tp1 = tp1->basetype;
X while (tp2->kind == TK_POINTER && tp2->basetype)
X tp2 = tp2->basetype;
X return (tp1 == tp2);
X }
X}
X
X
X
Xvoid declarefiles(fnames)
XStrlist *fnames;
X{
X Meaning *mp;
X char *cp;
X
X while (fnames) {
X mp = (Meaning *)fnames->value;
X if (mp->kind == MK_VAR || mp->kind == MK_FIELD) {
X if (mp->namedfile) {
X output(storageclassname(varstorageclass(mp)));
X output(format_ss("%s %s", charname,
X format_s(name_FNVAR, fnames->s)));
X output(format_s("[%s];\n", *name_FNSIZE ? name_FNSIZE : "80"));
X }
X if (mp->bufferedfile && *declbufname) {
X cp = format_s("%s", storageclassname(varstorageclass(mp)));
X if (*cp && isspace(cp[strlen(cp)-1]))
X cp[strlen(cp)-1] = 0;
X if (*cp || !*declbufncname) {
X output(declbufname);
X output("(");
X output(fnames->s);
X output(",");
X output(cp);
X } else {
X output(declbufncname);
X output("(");
X output(fnames->s);
X }
X output(",");
X out_type(mp->type->basetype->basetype, 1);
X output(");\n");
X }
X }
X strlist_eat(&fnames);
X }
X}
X
X
X
Xchar *variantfieldname(num)
Xint num;
X{
X if (num >= 0)
X return format_d("U%d", num);
X else
X return format_d("UM%d", -num);
X}
X
X
Xint record_is_union(tp)
XType *tp;
X{
X return (tp->fbase && tp->fbase->kind == MK_VARIANT);
X}
X
X
Xvoid outfieldlist(mp)
XMeaning *mp;
X{
X Meaning *mp0;
X int num, only_union, empty, saveindent, saveindent2;
X Strlist *fnames, *fn;
X
X if (!mp) {
X output("int empty_struct; /* Pascal record was empty */\n");
X return;
X }
X only_union = (mp && mp->kind == MK_VARIANT);
X fnames = NULL;
X while (mp && mp->kind == MK_FIELD) {
X flushcomments(&mp->comments, CMT_PRE, -1);
X output(storageclassname(varstorageclass(mp) & 0x10));
X outbasetype(mp->type, 0);
X output(" \005");
X for (;;) {
X outdeclarator(mp->type, mp->name, 0);
X if (mp->val.i && (mp->type != tp_abyte || mp->val.i != 8))
X output(format_d(" : %d", mp->val.i));
X if (isfiletype(mp->type)) {
X fn = strlist_append(&fnames, mp->name);
X fn->value = (long)mp;
X }
X mp->wasdeclared = 1;
X if (!mp->cnext || mp->cnext->kind != MK_FIELD ||
X varstorageclass(mp) != varstorageclass(mp->cnext) ||
X !mixable(mp, mp->cnext, 0, 0))
X break;
X mp = mp->cnext;
X output(",\001 ");
X }
X output(";");
X outtrailcomment(mp->comments, -1, declcommentindent);
X flushcomments(&mp->comments, -1, -1);
X mp = mp->cnext;
X }
X declarefiles(fnames);
X if (mp) {
X saveindent = outindent;
X empty = 1;
X if (!only_union) {
X output("union {\n");
X moreindent(tabsize);
X moreindent(structindent);
X }
X while (mp) {
X mp0 = mp->ctx;
X num = ord_value(mp->val);
X while (mp && mp->ctx == mp0)
X mp = mp->cnext;
X if (mp0) {
X empty = 0;
X if (!mp0->cnext && mp0->kind == MK_FIELD) {
X outfieldlist(mp0);
X } else {
X if (mp0->kind == MK_VARIANT)
X output("union {\n");
X else
X output("struct {\n");
X saveindent2 = outindent;
X moreindent(tabsize);
X moreindent(structindent);
X outfieldlist(mp0);
X outindent = saveindent2;
X output("} ");
X output(format_s(name_VARIANT, variantfieldname(num)));
X output(";\n");
X }
X flushcomments(&mp0->comments, -1, -1);
X }
X }
X if (empty)
X output("int empty_union; /* Pascal variant record was empty */\n");
X if (!only_union) {
X outindent = saveindent;
X output("} ");
X output(format_s(name_UNION, ""));
X output(";\n");
X }
X }
X}
X
X
X
Xvoid outbasetype(type, flags)
XType *type;
Xint flags;
X{
X Meaning *mp;
X int saveindent;
X
X type = findbasetype(type, flags);
X switch (type->kind) {
X
X case TK_INTEGER:
X if (type == tp_uint) {
X output("unsigned");
X } else if (type == tp_sint) {
X if (useAnyptrMacros == 1)
X output("Signed int");
X else if (hassignedchar)
X output("signed int");
X else
X output("int"); /* will sign-extend by hand */
X } else if (type == tp_unsigned) {
X output("unsigned long");
X } else if (type != tp_int)
X output(integername);
X else
X output("int");
X break;
X
X case TK_SUBR:
X if (type == tp_special_anyptr) {
X output("Anyptr");
X } else if (type == tp_abyte) {
X output("char");
X } else if (type == tp_ubyte) {
X output(ucharname);
X } else if (type == tp_sbyte) {
X output(scharname);
X if (signedchars != 1 && !hassignedchar)
X note("'signed char' may not be valid in all compilers [102]");
X } else {
X if (type == tp_ushort)
X output("unsigned ");
X output("short");
X }
X break;
X
X case TK_CHAR:
X if (type == tp_uchar) {
X output(ucharname);
X } else if (type == tp_schar) {
X output(scharname);
X if (signedchars != 1 && !hassignedchar)
X note("'signed char' may not be valid in all compilers [102]");
X } else
X output(charname);
X break;
X
X case TK_BOOLEAN:
X output((*name_BOOLEAN) ? name_BOOLEAN : ucharname);
X break;
X
X case TK_REAL:
X if (type == tp_longreal)
X output("double");
X else
X output("float");
X break;
X
X case TK_VOID:
X if (ansiC == 0)
X output("int");
X else if (useAnyptrMacros == 1)
X output("Void");
X else
X output("void");
X break;
X
X case TK_PROCPTR:
X output(name_PROCEDURE);
X break;
X
X case TK_FILE:
X output("FILE");
X break;
X
X case TK_SPECIAL:
X if (type == tp_jmp_buf)
X output("jmp_buf");
X break;
X
X default:
X if (type->meaning && type->meaning->kind == MK_TYPE &&
X type->meaning->wasdeclared) {
X output(type->meaning->name);
X } else {
X switch (type->kind) {
X
X case TK_ENUM:
X output("enum {\n");
X saveindent = outindent;
X moreindent(tabsize);
X moreindent(structindent);
X mp = type->fbase;
X while (mp) {
X output(mp->name);
X mp = mp->xnext;
X if (mp)
X output(",\001 ");
X }
X outindent = saveindent;
X output("\n}");
X break;
X
X case TK_RECORD:
X if (record_is_union(type))
X output("union ");
X else
X output("struct ");
X if (type->meaning)
X output(format_s(name_STRUCT, type->meaning->name));
X if (!type->structdefd) {
X if (type->meaning) {
X type->structdefd = 1;
X output(" ");
X }
X output("{\n");
X saveindent = outindent;
X moreindent(tabsize);
X moreindent(structindent);
X outfieldlist(type->fbase);
X outindent = saveindent;
X output("}");
X }
X break;
X
X default:
X break;
X
X }
X }
X break;
X }
X}
X
X
X
Xvoid out_type(type, witharrays)
XType *type;
Xint witharrays;
X{
X if (!witharrays && type->kind == TK_ARRAY)
X type = makepointertype(type->basetype);
X outbasetype(type, 0);
X outdeclarator(type, "", 0); /* write an "abstract declarator" */
X}
X
X
X
X
Xint varstorageclass(mp)
XMeaning *mp;
X{
X int sclass;
X
X if (mp->kind == MK_PARAM || mp->kind == MK_VARPARAM ||
X mp->kind == MK_FIELD)
X sclass = 0;
X else if (blockkind == TOK_EXPORT)
X if (usevextern)
X if (mp->constdefn &&
X (mp->kind == MK_VAR ||
X mp->kind == MK_VARREF))
X sclass = 2; /* extern */
X else
X sclass = 1; /* vextern */
X else
X sclass = 0; /* (plain) */
X else if (mp->isfunction && mp->kind != MK_FUNCTION)
X sclass = 2; /* extern */
X else if (mp->ctx->kind == MK_MODULE &&
X (var_static != 0 ||
X (findsymbol(mp->name)->flags & NEEDSTATIC)) &&
X !mp->exported && !mp->istemporary && blockkind != TOK_END)
X sclass = (useAnyptrMacros) ? 4 : 3; /* (private) */
X else if (mp->isforward)
X sclass = 3; /* static */
X else
X sclass = 0; /* (plain) */
X if (mp->volatilequal)
X sclass |= 0x10;
X if (mp->constqual)
X sclass |= 0x20;
X if (debug>2) fprintf(outf, "varstorageclass(%s) = %d\n", mp->name, sclass);
X return sclass;
X}
X
X
Xchar *storageclassname(i)
Xint i;
X{
X char *scname;
X
X switch (i & 0xf) {
X case 1:
X scname = "vextern ";
X break;
X case 2:
X scname = "extern ";
X break;
X case 3:
X scname = "static ";
X break;
X case 4:
X scname = "Static ";
X break;
X default:
X scname = "";
X break;
X }
X if (i & 0x10)
X if (useAnyptrMacros == 1)
X scname = format_s("%sVolatile ", scname);
X else if (ansiC > 0)
X scname = format_s("%svolatile ", scname);
X if (i & 0x20)
X if (useAnyptrMacros == 1)
X scname = format_s("%sConst ", scname);
X else if (ansiC > 0)
X scname = format_s("%sconst ", scname);
X return scname;
X}
X
X
X
Xvoid declarevar(mp, which)
XMeaning *mp;
Xint which; /* 0x1=header, 0x2=body, 0x4=trailer, 0x8=in varstruct */
X{
X int isstatic, isstructconst, saveindent;
X
X isstructconst = checkstructconst(mp);
X isstatic = varstorageclass(mp);
X if (which & 0x8)
X isstatic &= 0x10; /* clear all but Volatile flags */
X flushcomments(&mp->comments, CMT_PRE, -1);
X if (which & 0x1) {
X if (isstructconst)
X outsection(minorspace);
X output(storageclassname(isstatic));
X outbasetype(mp->type, 0);
X output(" \005");
X }
X if (which & 0x2) {
X outdeclarator(mp->type, mp->name, 0);
X if (mp->constdefn && blockkind != TOK_EXPORT &&
X (mp->kind == MK_VAR || mp->kind == MK_VARREF)) {
X if (mp->varstructflag) { /* move init code into function body */
X intwarning("declarevar",
X format_s("Variable %s initializer not removed [125]", mp->name));
X } else {
X output(" = ");
X if (isstructconst) {
X output("{\n");
X saveindent = outindent;
X moreindent(tabsize);
X moreindent(structinitindent);
X out_expr((Expr *)mp->constdefn->val.i);
X outindent = saveindent;
X output("\n}");
X } else
X out_expr(mp->constdefn);
X }
X }
X }
X if (which & 0x4) {
X output(";");
X outtrailcomment(mp->comments, -1, declcommentindent);
X flushcomments(&mp->comments, -1, -1);
X if (isstructconst)
X outsection(minorspace);
X }
X}
X
X
X
X
XStatic int checkvarmacdef(ex, mp)
XExpr *ex;
XMeaning *mp;
X{
X int i;
X
X if ((ex->kind == EK_NAME || ex->kind == EK_BICALL) &&
X !strcmp(ex->val.s, mp->name)) {
X ex->kind = EK_VAR;
X ex->val.i = (long)mp;
X ex->val.type = mp->type;
X return 1;
X }
X if (ex->kind == EK_VAR && ex->val.i == (long)mp)
X return 1;
X i = ex->nargs;
X while (--i >= 0)
X if (checkvarmacdef(ex->args[i], mp))
X return 1;
X return 0;
X}
X
X
Xint checkvarmac(mp)
XMeaning *mp;
X{
X if (mp->kind != MK_VARMAC && mp->kind != MK_FUNCTION)
X return 0;
X if (!mp->constdefn)
X return 0;
X return checkvarmacdef(mp->constdefn, mp);
X}
X
X
X
X#define varkind(k) ((k)==MK_VAR||(k)==MK_VARREF||(k)==MK_PARAM||(k)==MK_VARPARAM)
X
Xint declarevars(ctx, invarstruct)
XMeaning *ctx;
Xint invarstruct;
X{
X Meaning *mp, *mp0, *mp2;
X Strlist *fnames, *fn;
X int flag, first;
X
X if (ctx->kind == MK_FUNCTION && ctx->varstructflag && !invarstruct) {
X output("struct ");
X output(format_s(name_LOC, ctx->name));
X output(" ");
X output(format_s(name_VARS, ctx->name));
X output(";\n");
X flag = 1;
X } else
X flag = 0;
X if (debug>2) {
X fprintf(outf,"declarevars:\n");
X for (mp = ctx->cbase; mp; mp = mp->xnext) {
X fprintf(outf, " %-22s%-15s%3d", mp->name,
X meaningkindname(mp->kind),
X mp->refcount);
X if (mp->wasdeclared)
X fprintf(outf, " [decl]");
X if (mp->varstructflag)
X fprintf(outf, " [struct]");
X fprintf(outf, "\n");
X }
X }
X fnames = NULL;
X for (;;) {
X mp = ctx->cbase;
X while (mp && (!(varkind(mp->kind) || checkvarmac(mp)) ||
X mp->wasdeclared || mp->varstructflag != invarstruct ||
X mp->refcount <= 0))
X mp = mp->cnext;
X if (!mp)
X break;
X flag = 1;
X first = 1;
X mp0 = mp2 = mp;
X while (mp) {
X if ((varkind(mp->kind) || checkvarmac(mp)) &&
X !mp->wasdeclared &&
X varstorageclass(mp) == varstorageclass(mp0) &&
X mp->varstructflag == invarstruct && mp->refcount > 0) {
X if (mixable(mp2, mp, 0, 0) || first) {
X if (!first)
X output(",\001 ");
X declarevar(mp, (first ? 0x3 : 0x2) |
X (invarstruct ? 0x8 : 0));
X mp2 = mp;
X mp->wasdeclared = 1;
X if (isfiletype(mp->type)) {
X fn = strlist_append(&fnames, mp->name);
X fn->value = (long)mp;
X }
X first = 0;
X } else
X if (mixvars != 1)
X break;
X }
X if (first) {
X intwarning("declarevars",
X format_s("Unable to declare %s [126]", mp->name));
X mp->wasdeclared = 1;
X first = 0;
X }
X if (mixvars == 0)
X break;
X mp = mp->cnext;
X }
X declarevar(mp2, 0x4);
X }
X declarefiles(fnames);
X return flag;
X}
X
X
X
Xvoid redeclarevars(ctx)
XMeaning *ctx;
X{
X Meaning *mp;
X
X for (mp = ctx->cbase; mp; mp = mp->cnext) {
X if ((mp->kind == MK_VAR || mp->kind == MK_VARREF) &&
X mp->constdefn) {
X mp->wasdeclared = 0; /* mark for redeclaration, this time */
X } /* with its initializer */
X }
X}
X
X
X
X
X
Xvoid out_argdecls(ftype)
XType *ftype;
X{
X Meaning *mp, *mp0;
X Type *tp;
X int done;
X int flag = 1;
X char *name;
X
X done = 0;
X do {
X mp = ftype->fbase;
X while (mp && mp->wasdeclared)
X mp = mp->xnext;
X if (mp) {
X if (flag)
X output("\n");
X flag = 0;
X mp0 = mp;
X outbasetype(mp->othername ? mp->rectype : mp->type,
X ODECL_CHARSTAR|ODECL_FREEARRAY);
X output(" \005");
X while (mp) {
X if (!mp->wasdeclared) {
X if (mp == mp0 ||
X mixable(mp0, mp, 1, ODECL_CHARSTAR|ODECL_FREEARRAY)) {
X if (mp != mp0)
X output(",\001 ");
X name = (mp->othername) ? mp->othername : mp->name;
X tp = (mp->othername) ? mp->rectype : mp->type;
X outdeclarator(tp, name,
X ODECL_CHARSTAR|ODECL_FREEARRAY);
X mp->wasdeclared = 1;
X } else
X if (mixvars != 1)
X break;
X }
X mp = mp->xnext;
X }
X output(";\n");
X } else
X done = 1;
X } while (!done);
X for (mp0 = ftype->fbase; mp0 && (mp0->type != tp_strptr ||
X !mp0->anyvarflag); mp0 = mp0->xnext) ;
X if (mp0) {
X output("int ");
X for (mp = mp0; mp; mp = mp->xnext) {
X if (mp->type == tp_strptr && mp->anyvarflag) {
X if (mp != mp0) {
X if (mixvars == 0)
X output(";\nint ");
X else
X output(",\001 ");
X }
X output(format_s(name_STRMAX, mp->name));
X }
X }
X output(";\n");
X }
X if (ftype->meaning && ftype->meaning->ctx->kind == MK_FUNCTION &&
X ftype->meaning->ctx->varstructflag) {
X if (flag)
X output("\n");
X output("struct ");
X output(format_s(name_LOC, ftype->meaning->ctx->name));
X output(" *");
X output(format_s(name_LINK, ftype->meaning->ctx->name));
X output(";\n");
X }
X}
X
X
X
X
Xvoid makevarstruct(func)
XMeaning *func;
X{
X int flag = 0;
X int saveindent;
X
X outsection(minfuncspace);
X output(format_s("\n/* Local variables for %s: */\n", func->name));
X output("struct ");
X output(format_s(name_LOC, func->name));
X output(" {\n");
X saveindent = outindent;
X moreindent(tabsize);
X moreindent(structindent);
X if (func->ctx->kind == MK_FUNCTION && func->ctx->varstructflag) {
X output("struct ");
X output(format_s(name_LOC, func->ctx->name));
X output(" *");
X output(format_s(name_LINK, func->ctx->name));
X output(";\n");
X flag++;
X }
X flag += declarevars(func, 1);
X if (!flag) /* Avoid generating an empty struct */
X output("int _meef_;\n"); /* (I don't think this will ever happen) */
X outindent = saveindent;
X output("} ;\n");
X outsection(minfuncspace);
X strlist_insert(&varstructdecllist, func->name);
X}
X
X
X
X
X
X
XType *maketype(kind)
Xenum typekind kind;
X{
X Type *tp;
X tp = ALLOC(1, Type, types);
X tp->kind = kind;
X tp->basetype = NULL;
X tp->indextype = NULL;
X tp->pointertype = NULL;
X tp->meaning = NULL;
X tp->fbase = NULL;
X tp->smin = NULL;
X tp->smax = NULL;
X tp->issigned = 0;
X tp->dumped = 0;
X tp->structdefd = 0;
X return tp;
X}
X
X
X
X
XType *makesubrangetype(type, smin, smax)
XType *type;
XExpr *smin, *smax;
X{
X Type *tp;
X
X if (type->kind == TK_SUBR)
X type = type->basetype;
X tp = maketype(TK_SUBR);
X tp->basetype = type;
X tp->smin = smin;
X tp->smax = smax;
X return tp;
X}
X
X
X
XType *makesettype(setof)
XType *setof;
X{
X Type *tp;
X long smax;
X
X if (ord_range(setof, NULL, &smax) && smax < setbits && smallsetconst >= 0)
X tp = maketype(TK_SMALLSET);
X else
X tp = maketype(TK_SET);
X tp->basetype = tp_integer;
X tp->indextype = setof;
X return tp;
X}
X
X
X
XType *makestringtype(len)
Xint len;
X{
X Type *type;
X int index;
X
X len |= 1;
X if (len >= stringceiling)
X type = tp_str255;
X else {
X index = (len-1) / 2;
X if (stringtypecache[index])
X return stringtypecache[index];
X type = maketype(TK_STRING);
X type->basetype = tp_char;
X type->indextype = makesubrangetype(tp_integer,
X makeexpr_long(0),
X makeexpr_long(len));
X stringtypecache[index] = type;
X }
X return type;
X}
X
X
X
XType *makepointertype(type)
XType *type;
X{
X Type *tp;
X
X if (type->pointertype)
X return type->pointertype;
X tp = maketype(TK_POINTER);
X tp->basetype = type;
X type->pointertype = tp;
X return tp;
X}
X
X
X
X
X
XValue p_constant(type)
XType *type;
X{
X Value val;
X Expr *ex;
X
X ex = p_expr(type);
X if (type)
X ex = gentle_cast(ex, type);
X val = eval_expr(ex);
X freeexpr(ex);
X if (!val.type) {
X warning("Expected a constant [127]");
X val.type = (type) ? type : tp_integer;
X }
X return val;
X}
X
X
X
X
Xint typebits(smin, smax)
Xlong smin, smax;
X{
X unsigned long size;
X int bits;
X
X if (smin >= 0 || (smin == -1 && smax == 0)) {
X bits = 1;
X size = smax;
X } else {
X bits = 2;
X smin = -1L - smin;
X if (smin >= smax)
X size = smin;
X else
X size = smax;
X }
X while (size > 1) {
X bits++;
X size >>= 1;
X }
X return bits;
X}
X
X
Xint packedsize(fname, typep, sizep, mode)
Xchar *fname;
XType **typep;
Xlong *sizep;
Xint mode;
X{
X Type *tp = *typep;
X long smin, smax;
X int res, issigned;
X short savefold;
X long size;
X
X if (packing == 0) /* suppress packing */
X return 0;
X if (tp->kind != TK_SUBR && tp->kind != TK_INTEGER && tp->kind != TK_ENUM &&
X tp->kind != TK_CHAR && tp->kind != TK_BOOLEAN)
X return 0;
X if (tp == tp_unsigned)
X return 0;
X if (!ord_range(tp, &smin, &smax)) {
X savefold = foldconsts;
X foldconsts = 1;
X res = ord_range(tp, &smin, &smax);
X foldconsts = savefold;
X if (res) {
X note(format_s("Field width for %s is based on expansion of #defines [103]",
X fname));
X } else {
X note(format_ss("Cannot compute size of field %s; assuming %s [104]",
X fname, integername));
X return 0;
X }
X } else {
X if (tp->kind == TK_ENUM)
X note(format_ssd("Field width for %s assumes enum%s has %d elements [105]",
X fname,
X (tp->meaning) ? format_s(" %s", tp->meaning->name) : "",
X smax + 1));
X }
X issigned = (smin < 0);
X size = typebits(smin, smax);
X if (size >= ((sizeof_long > 0) ? sizeof_long : 32))
X return 0;
X if (packing != 1) {
X if (size <= 8)
X size = 8;
X else if (size <= 16)
X size = 16;
X else
X return 0;
X }
X if (!issigned) {
X *typep = (mode == 0) ? tp_int : tp_uint;
X } else {
X if (mode == 2 && !hassignedchar && !*signextname)
X return 0;
X *typep = (mode == 1) ? tp_int : tp_sint;
X }
X *sizep = size;
X return issigned;
X}
X
X
X
XStatic void fielddecl(mp, type, tp2, val, ispacked, aligned)
XMeaning *mp;
XType **type, **tp2;
Xlong *val;
Xint ispacked, *aligned;
X{
X long smin, smax, smin2, smax2;
X
X *tp2 = *type;
X *val = 0;
X if (ispacked && !mp->constdefn && *type != tp_unsigned) {
X (void)packedsize(mp->sym->name, tp2, val, signedfield);
X if (*aligned && *val &&
X (ord_type(*type)->kind == TK_CHAR ||
X ord_type(*type)->kind == TK_INTEGER) &&
X ord_range(findbasetype(*type, 0), &smin, &smax)) {
X if (ord_range(*type, &smin2, &smax2)) {
X if (typebits(smin, smax) == 16 &&
X typebits(smin2, smax2) == 8 && *val == 8) {
X *tp2 = tp_abyte;
X }
X }
X if (typebits(smin, smax) == *val &&
X *val != 7) { /* don't be fooled by tp_abyte */
X /* don't need to use a bit-field for this field */
X /* so not specifying one may make it more efficient */
X /* (and also helps to simulate HP's $allow_packed$ mode) */
X *val = 0;
X *tp2 = *type;
X }
X }
X if (*aligned && *val == 8 &&
X (ord_type(*type)->kind == TK_BOOLEAN ||
X ord_type(*type)->kind == TK_ENUM)) {
X *val = 0;
X *tp2 = tp_ubyte;
X }
X }
X if (*val != 8 && *val != 16)
X *aligned = (*val == 0);
X}
X
X
X
X/* This function locates byte-sized fields which were unaligned, but which
X are followed by aligned quantities so that they can be made aligned
X with no loss in storage efficiency. */
X
XStatic void realignfields(firstmp, stopmp)
XMeaning *firstmp, *stopmp;
X{
X Meaning *mp;
X
X for (mp = firstmp; mp && mp != stopmp; mp = mp->cnext) {
X if (mp->kind == MK_FIELD) {
X if (mp->val.i == 16) {
X if (mp->type == tp_uint)
X mp->type = tp_ushort;
X else
X mp->type = tp_sshort;
X mp->val.i = 0;
X } else if (mp->val.i == 8) {
X if (mp->type == tp_uint) {
X mp->type = tp_ubyte;
X mp->val.i = 0;
X } else if (hassignedchar || signedchars == 1) {
X mp->type = tp_sbyte;
X mp->val.i = 0;
X } else
X mp->type = tp_abyte;
X }
X }
X }
X}
X
Xstatic void tryrealignfields(firstmp)
XMeaning *firstmp;
X{
X Meaning *mp, *head;
X
X head = NULL;
X for (mp = firstmp; mp; mp = mp->cnext) {
X if (mp->kind == MK_FIELD) {
X if (mp->val.i == 8 || mp->val.i == 16) {
X if (!head)
X head = mp;
X } else {
X if (mp->val.i == 0)
X realignfields(head, mp);
X head = NULL;
X }
X }
X }
X realignfields(head, NULL);
X}
X
X
X
Xvoid decl_comments(mp)
XMeaning *mp;
X{
X Strlist *cmt;
X
X if (spitcomments != 1) {
X changecomments(curcomments, -1, -1, CMT_PRE, 0);
X strlist_mix(&mp->comments, curcomments);
X curcomments = NULL;
X cmt = grabcomment(CMT_TRAIL);
X if (cmt) {
X changecomments(mp->comments, CMT_TRAIL, -1, CMT_PRE, -1);
X strlist_mix(&mp->comments, cmt);
X }
X if (mp->comments)
X mp->refcount++; /* force it to be included if it has comments */
X }
X}
X
X
X
X
X
XStatic void p_fieldlist(tp, flast, ispacked, tname)
XType *tp;
XMeaning **flast;
Xint ispacked;
XMeaning *tname;
X{
X Meaning *firstm, *lastm, *veryfirstm;
X Symbol *sym;
X Type *type, *tp2;
X long li1, li2;
X int aligned, constflag, volatileflag;
X short saveskipind;
X Strlist *l1;
X
X saveskipind = skipindices;
X skipindices = 0;
X aligned = 1;
X lastm = NULL;
X veryfirstm = NULL;
X while (curtok == TOK_IDENT) {
X firstm = addfield(curtoksym, &flast, tp, tname);
X if (!veryfirstm)
X veryfirstm = firstm;
X lastm = firstm;
X gettok();
X decl_comments(lastm);
X while (curtok == TOK_COMMA) {
X gettok();
X if (wexpecttok(TOK_IDENT))
X lastm = addfield(curtoksym, &flast, tp, tname);
X gettok();
X decl_comments(lastm);
X }
X if (wneedtok(TOK_COLON)) {
X constflag = volatileflag = 0;
X p_attributes();
X if ((l1 = strlist_find(attrlist, "READONLY")) != NULL) {
X constflag = 1;
X strlist_delete(&attrlist, l1);
X }
X if ((l1 = strlist_find(attrlist, "VOLATILE")) != NULL) {
X volatileflag = 1;
X strlist_delete(&attrlist, l1);
X }
X type = p_type(firstm);
X decl_comments(lastm);
X fielddecl(firstm, &type, &tp2, &li1, ispacked, &aligned);
X for (;;) {
X firstm->type = tp2;
X firstm->val.type = type;
X firstm->val.i = li1;
X firstm->constqual = constflag;
X firstm->volatilequal = volatileflag;
X tp->meaning = tname;
X setupfilevar(firstm);
X tp->meaning = NULL;
X if (firstm == lastm)
X break;
X firstm = firstm->cnext;
X }
X } else
X skiptotoken2(TOK_SEMI, TOK_CASE);
X if (curtok == TOK_SEMI)
X gettok();
X }
X if (curtok == TOK_CASE) {
X gettok();
X if (curtok == TOK_COLON)
X gettok();
X wexpecttok(TOK_IDENT);
X sym = curtoksym;
X if (curtokmeaning)
X type = curtokmeaning->type;
X gettok();
X if (curtok == TOK_COLON) {
X firstm = addfield(sym, &flast, tp, tname);
X if (!veryfirstm)
X veryfirstm = firstm;
X gettok();
X firstm->isforward = 1;
X firstm->val.type = type = p_type(firstm);
X fielddecl(firstm, &firstm->val.type, &firstm->type, &firstm->val.i,
X ispacked, &aligned);
X } else {
X firstm = NULL;
X }
X if (!wneedtok(TOK_OF)) {
X skiptotoken2(TOK_END, TOK_RPAR);
X goto bounce;
X }
X if (firstm)
X decl_comments(firstm);
X while (curtok == TOK_VBAR)
X gettok();
X while (curtok != TOK_END && curtok != TOK_RPAR) {
X firstm = NULL;
X for (;;) {
X lastm = addfield(NULL, &flast, tp, tname);
X if (!firstm)
X firstm = lastm;
X checkkeyword(TOK_OTHERWISE);
X if (curtok == TOK_ELSE || curtok == TOK_OTHERWISE) {
X lastm->val = make_ord(type, 999);
X break;
X } else {
X lastm->val = p_constant(type);
X if (curtok == TOK_DOTS) {
X gettok();
X li1 = ord_value(lastm->val);
X li2 = ord_value(p_constant(type));
X while (++li1 <= li2) {
X lastm = addfield(NULL, &flast, tp, tname);
X lastm->val = make_ord(type, li1);
X }
X }
X }
X if (curtok == TOK_COMMA)
X gettok();
X else
X break;
X }
X if (curtok == TOK_ELSE || curtok == TOK_OTHERWISE) {
X gettok();
X } else if (!wneedtok(TOK_COLON) ||
X (!modula2 && !wneedtok(TOK_LPAR))) {
X skiptotoken2(TOK_END, TOK_RPAR);
X goto bounce;
X }
X p_fieldlist(tp, &lastm->ctx, ispacked, tname);
X while (firstm != lastm) {
X firstm->ctx = lastm->ctx;
X firstm = firstm->cnext;
X }
X if (modula2) {
X while (curtok == TOK_VBAR)
X gettok();
X } else {
X if (!wneedtok(TOK_RPAR))
X skiptotoken(TOK_RPAR);
X }
X if (curtok == TOK_SEMI)
X gettok();
X }
X if (modula2) {
X wneedtok(TOK_END);
X if (curtok == TOK_IDENT) {
X note("Record variants supported only at end of record [106]");
X p_fieldlist(tp, &lastm->ctx, ispacked, tname);
X }
X }
X }
X tryrealignfields(veryfirstm);
X if (lastm && curtok == TOK_END) {
X strlist_mix(&lastm->comments, curcomments);
X curcomments = NULL;
X }
X
X bounce:
X skipindices = saveskipind;
X}
X
X
X
XStatic Type *p_arraydecl(tname, ispacked, confp)
Xchar *tname;
Xint ispacked;
XMeaning ***confp;
X{
X Type *tp, *tp2;
X Meaning *mp;
X long size, smin, smax, bitsize, fullbitsize;
X int issigned, bpower, hasrange;
X
X tp = maketype(TK_ARRAY);
X if (confp == NULL) {
X tp->indextype = p_type(NULL);
X if (tp->indextype->kind == TK_SUBR) {
X if (ord_range(tp->indextype, &smin, NULL) &&
X smin > 0 && smin <= skipindices && !ispacked) {
X tp->smin = makeexpr_val(make_ord(tp->indextype->basetype, smin));
X tp->indextype = makesubrangetype(tp->indextype->basetype,
X makeexpr_val(make_ord(
X tp->indextype->basetype, 0)),
X copyexpr(tp->indextype->smax));
X }
X }
X } else {
X if (modula2) {
X **confp = mp = addmeaning(findsymbol(format_s(name_ALOW, tname)), MK_PARAM);
X mp->fakeparam = 1;
X mp->constqual = 1;
X mp->xnext = addmeaning(findsymbol(format_s(name_AHIGH, tname)), MK_PARAM);
X mp->xnext->fakeparam = 1;
X mp->xnext->constqual = 1;
X *confp = &mp->xnext->xnext;
X tp2 = maketype(TK_SUBR);
X tp2->basetype = tp_integer;
X mp->type = tp_integer;
X mp->xnext->type = mp->type;
X tp2->smin = makeexpr_long(0);
X tp2->smax = makeexpr_minus(makeexpr_var(mp->xnext),
X makeexpr_var(mp));
X tp->indextype = tp2;
X tp->structdefd = 1;
X } else {
X wexpecttok(TOK_IDENT);
X tp2 = maketype(TK_SUBR);
X if (peeknextchar() != ',' &&
X (!curtokmeaning || curtokmeaning->kind != MK_TYPE)) {
X mp = addmeaning(curtoksym, MK_PARAM);
X gettok();
X wneedtok(TOK_DOTS);
X wexpecttok(TOK_IDENT);
X mp->xnext = addmeaning(curtoksym, MK_PARAM);
X gettok();
X if (wneedtok(TOK_COLON)) {
X tp2->basetype = p_type(NULL);
X } else {
X tp2->basetype = tp_integer;
X }
X } else {
X mp = addmeaning(findsymbol(format_s(name_ALOW, tname)), MK_PARAM);
X mp->xnext = addmeaning(findsymbol(format_s(name_AHIGH, tname)), MK_PARAM);
X tp2->basetype = p_type(NULL);
X }
X mp->fakeparam = 1;
X mp->constqual = 1;
X mp->xnext->fakeparam = 1;
X mp->xnext->constqual = 1;
X **confp = mp;
X *confp = &mp->xnext->xnext;
X mp->type = tp2->basetype;
X mp->xnext->type = tp2->basetype;
X tp2->smin = makeexpr_var(mp);
X tp2->smax = makeexpr_var(mp->xnext);
X tp->indextype = tp2;
X tp->structdefd = 1; /* conformant array flag */
X }
X }
X if (curtok == TOK_COMMA || curtok == TOK_SEMI) {
X gettok();
X tp->basetype = p_arraydecl(tname, ispacked, confp);
X return tp;
X } else {
X if (!modula2) {
X if (!wneedtok(TOK_RBR))
X skiptotoken(TOK_OF);
X }
X if (!wneedtok(TOK_OF))
X skippasttotoken(TOK_OF, TOK_COMMA);
X checkkeyword(TOK_VARYING);
X if (confp != NULL &&
X (curtok == TOK_ARRAY || curtok == TOK_PACKED ||
X curtok == TOK_VARYING)) {
X tp->basetype = p_conformant_array(tname, confp);
X } else
X tp->basetype = p_type(NULL);
X if (!ispacked)
X return tp;
X size = 0;
X tp2 = tp->basetype;
X if (!tname)
X tname = "array";
X issigned = packedsize(tname, &tp2, &size, 1);
X if (!size || size > 8 ||
X (issigned && !packsigned) ||
X (size > 4 &&
X (!issigned || (signedchars == 1 || hassignedchar))))
X return tp;
X bpower = 0;
X while ((1<<bpower) < size)
X bpower++; /* round size up to power of two */
X size = 1<<bpower; /* size = # bits in an array element */
X tp->escale = bpower;
X tp->issigned = issigned;
X hasrange = ord_range(tp->indextype, &smin, &smax) &&
X (smax < 100000); /* don't be confused by giant arrays */
X if (hasrange &&
X (bitsize = (smax - smin + 1) * size)
X <= ((sizeof_integer > 0) ? sizeof_integer : 32)) {
X if (bitsize > ((sizeof_short > 0) ? sizeof_short : 16)) {
X tp2 = (issigned) ? tp_integer : tp_unsigned;
X fullbitsize = ((sizeof_integer > 0) ? sizeof_integer : 32);
X } else if (bitsize > ((sizeof_char > 0) ? sizeof_char : 8) ||
X (issigned && !(signedchars == 1 || hassignedchar))) {
X tp2 = (issigned) ? tp_sshort : tp_ushort;
X fullbitsize = ((sizeof_short > 0) ? sizeof_short : 16);
X } else {
X tp2 = (issigned) ? tp_sbyte : tp_ubyte;
X fullbitsize = ((sizeof_char > 0) ? sizeof_char : 8);
X }
X tp->kind = TK_SMALLARRAY;
X if (ord_range(tp->indextype, &smin, NULL) &&
X smin > 0 && smin <= fullbitsize - bitsize) {
X tp->smin = makeexpr_val(make_ord(tp->indextype->basetype, smin));
X tp->indextype = makesubrangetype(tp->indextype->basetype,
X makeexpr_val(make_ord(
X tp->indextype->basetype, 0)),
X copyexpr(tp->indextype->smax));
X }
X } else {
X if (!issigned)
X tp2 = tp_ubyte;
X else if (signedchars == 1 || hassignedchar)
X tp2 = tp_sbyte;
X else
X tp2 = tp_sshort;
X }
X tp->smax = makeexpr_type(tp->basetype);
X tp->basetype = tp2;
X return tp;
X }
X}
X
X
X
XStatic Type *p_conformant_array(tname, confp)
Xchar *tname;
XMeaning ***confp;
X{
X int ispacked;
X Meaning *mp;
X Type *tp, *tp2;
X
X p_attributes();
X ignore_attributes();
X if (curtok == TOK_PACKED) {
X ispacked = 1;
X gettok();
X } else
X ispacked = 0;
X checkkeyword(TOK_VARYING);
X if (curtok == TOK_VARYING) {
X gettok();
X wneedtok(TOK_LBR);
X wexpecttok(TOK_IDENT);
X mp = addmeaning(curtoksym, MK_PARAM);
X mp->fakeparam = 1;
X mp->constqual = 1;
X **confp = mp;
X *confp = &mp->xnext;
X mp->type = tp_integer;
X tp2 = maketype(TK_SUBR);
X tp2->basetype = tp_integer;
X tp2->smin = makeexpr_long(1);
X tp2->smax = makeexpr_var(mp);
X tp = maketype(TK_STRING);
X tp->indextype = tp2;
X tp->basetype = tp_char;
X tp->structdefd = 1; /* conformant array flag */
X gettok();
X wneedtok(TOK_RBR);
X skippasttoken(TOK_OF);
X tp->basetype = p_type(NULL);
X return tp;
X }
X if (wneedtok(TOK_ARRAY) &&
X (modula2 || wneedtok(TOK_LBR))) {
X return p_arraydecl(tname, ispacked, confp);
X } else {
X return tp_integer;
X }
X}
X
X
X
X
X/* VAX Pascal: */
Xvoid p_attributes()
X{
X Strlist *l1;
X
X if (modula2)
X return;
X while (curtok == TOK_LBR) {
X implementationmodules = 1; /* auto-detect VAX Pascal */
X do {
X gettok();
X if (!wexpecttok(TOK_IDENT)) {
X skippasttoken(TOK_RBR);
X return;
X }
X l1 = strlist_append(&attrlist, strupper(curtokbuf));
X l1->value = -1;
X gettok();
X if (curtok == TOK_LPAR) {
X gettok();
X if (!strcmp(l1->s, "CHECK") ||
X !strcmp(l1->s, "OPTIMIZE") ||
X !strcmp(l1->s, "KEY") ||
X !strcmp(l1->s, "COMMON") ||
X !strcmp(l1->s, "PSECT") ||
X !strcmp(l1->s, "EXTERNAL") ||
X !strcmp(l1->s, "GLOBAL") ||
X !strcmp(l1->s, "WEAK_EXTERNAL") ||
X !strcmp(l1->s, "WEAK_GLOBAL")) {
X l1->value = (long)stralloc(curtokbuf);
X gettok();
X while (curtok == TOK_COMMA) {
X gettok();
X gettok();
X }
X } else if (!strcmp(l1->s, "INHERIT") ||
X !strcmp(l1->s, "IDENT") ||
X !strcmp(l1->s, "ENVIRONMENT")) {
X p_expr(NULL);
X while (curtok == TOK_COMMA) {
X gettok();
X p_expr(NULL);
X }
X } else {
X l1->value = ord_value(p_constant(tp_integer));
X while (curtok == TOK_COMMA) {
X gettok();
X p_expr(NULL);
X }
X }
X if (!wneedtok(TOK_RPAR)) {
X skippasttotoken(TOK_RPAR, TOK_LBR);
X }
X }
X } while (curtok == TOK_COMMA);
X if (!wneedtok(TOK_RBR)) {
X skippasttoken(TOK_RBR);
X }
X }
X}
X
X
Xvoid ignore_attributes()
X{
X while (attrlist) {
X if (strcmp(attrlist->s, "HIDDEN") &&
X strcmp(attrlist->s, "INHERIT") &&
X strcmp(attrlist->s, "ENVIRONMENT"))
X warning(format_s("Type attribute %s ignored [128]", attrlist->s));
X strlist_eat(&attrlist);
X }
X}
X
X
Xint size_attributes()
X{
X int size = -1;
X Strlist *l1;
X
X if ((l1 = strlist_find(attrlist, "BIT")) != NULL)
X size = 1;
X else if ((l1 = strlist_find(attrlist, "BYTE")) != NULL)
X size = 8;
X else if ((l1 = strlist_find(attrlist, "WORD")) != NULL)
X size = 16;
X else if ((l1 = strlist_find(attrlist, "LONG")) != NULL)
X size = 32;
X else if ((l1 = strlist_find(attrlist, "QUAD")) != NULL)
X size = 64;
X else if ((l1 = strlist_find(attrlist, "OCTA")) != NULL)
X size = 128;
X else
X return -1;
X if (l1->value >= 0)
X size *= l1->value;
X strlist_delete(&attrlist, l1);
X return size;
X}
X
X
Xvoid p_mech_spec(doref)
Xint doref;
X{
X if (curtok == TOK_IDENT && doref &&
X !strcicmp(curtokbuf, "%REF")) {
X note("Mechanism specified %REF treated like VAR [107]");
X curtok = TOK_VAR;
X return;
X }
X if (curtok == TOK_IDENT &&
X (!strcicmp(curtokbuf, "%REF") ||
X !strcicmp(curtokbuf, "%IMMED") ||
X !strcicmp(curtokbuf, "%DESCR") ||
X !strcicmp(curtokbuf, "%STDESCR"))) {
X note(format_s("Mechanism specifier %s ignored [108]", curtokbuf));
X gettok();
X }
X}
X
X
XType *p_modula_subrange(basetype)
XType *basetype;
X{
X Type *tp;
X Value val;
X
X wneedtok(TOK_LBR);
X tp = maketype(TK_SUBR);
X tp->smin = p_ord_expr();
X if (basetype)
X tp->smin = gentle_cast(tp->smin, basetype);
X if (wexpecttok(TOK_DOTS)) {
X gettok();
X tp->smax = p_ord_expr();
X if (tp->smax->val.type->kind == TK_REAL &&
X tp->smax->kind == EK_CONST &&
X strlen(tp->smax->val.s) == 12 &&
X strcmp(tp->smax->val.s, "2147483648.0") >= 0 &&
X strcmp(tp->smax->val.s, "4294967295.0") <= 0) {
X tp = tp_unsigned;
X } else if (basetype) {
X tp->smin = gentle_cast(tp->smin, basetype);
X tp->basetype = basetype;
X } else {
X basetype = ord_type(tp->smin->val.type);
X if (basetype->kind == TK_INTEGER) {
X val = eval_expr(tp->smin);
X if (val.type && val.i >= 0)
X basetype = tp_unsigned;
X else
X basetype = tp_integer;
X }
X tp->basetype = basetype;
X }
X } else {
X tp = tp_integer;
X }
X if (!wneedtok(TOK_RBR))
X skippasttotoken(TOK_RBR, TOK_SEMI);
X return tp;
X}
X
X
Xvoid makefakestruct(tp, tname)
XType *tp;
XMeaning *tname;
X{
X Symbol *sym;
X
X if (!tname)
X return;
X while (tp && (tp->kind == TK_ARRAY || tp->kind == TK_FILE))
X tp = tp->basetype;
X if (tp && tp->kind == TK_RECORD && !tp->meaning) {
X sym = findsymbol(format_s(name_FAKESTRUCT, tname->name));
X silentalreadydef++;
X tp->meaning = addmeaning(sym, MK_TYPE);
X silentalreadydef--;
X tp->meaning->type = tp;
X tp->meaning->refcount++;
X declaretype(tp->meaning);
X }
X}
X
X
XType *p_type(tname)
XMeaning *tname;
X{
X Type *tp;
X int ispacked = 0;
X Meaning **flast;
X Meaning *mp;
X Strlist *sl;
X int num, isfunc, saveind, savenotephase, sizespec;
X Expr *ex;
X Value val;
X static int proctypecount = 0;
X
X p_attributes();
X sizespec = size_attributes();
X ignore_attributes();
X tp = tp_integer;
X if (curtok == TOK_PACKED) {
X ispacked = 1;
X gettok();
X }
X checkkeyword(TOK_VARYING);
X if (modula2)
X checkkeyword(TOK_POINTER);
X switch (curtok) {
X
X case TOK_RECORD:
X gettok();
X savenotephase = notephase;
X notephase = 1;
X tp = maketype(TK_RECORD);
X p_fieldlist(tp, &(tp->fbase), ispacked, tname);
X notephase = savenotephase;
X if (!wneedtok(TOK_END)) {
X skippasttoken(TOK_END);
X }
X break;
X
X case TOK_ARRAY:
X gettok();
X if (!modula2) {
X if (!wneedtok(TOK_LBR))
X break;
X }
X tp = p_arraydecl(tname ? tname->name : NULL, ispacked, NULL);
X makefakestruct(tp, tname);
X break;
X
X case TOK_VARYING:
X gettok();
X tp = maketype(TK_STRING);
X if (wneedtok(TOK_LBR)) {
X ex = p_ord_expr();
X if (!wneedtok(TOK_RBR))
X skippasttoken(TOK_RBR);
X } else
X ex = makeexpr_long(stringdefault);
X if (wneedtok(TOK_OF))
X tp->basetype = p_type(NULL);
X else
X tp->basetype = tp_char;
X val = eval_expr(ex);
X if (val.type) {
X if (val.i > 255 && val.i > stringceiling) {
X note(format_d("Strings longer than %d may have problems [109]",
X stringceiling));
X }
X if (stringceiling != 255 &&
X (val.i >= 255 || val.i > stringceiling)) {
X freeexpr(ex);
X ex = makeexpr_long(stringceiling);
X }
X }
X tp->indextype = makesubrangetype(tp_integer, makeexpr_long(0), ex);
X break;
X
X case TOK_SET:
X gettok();
X if (!wneedtok(TOK_OF))
X break;
X tp = p_type(NULL);
X if (tp == tp_integer || tp == tp_unsigned)
X tp = makesubrangetype(tp, makeexpr_long(0),
X makeexpr_long(defaultsetsize-1));
X if (tp->kind == TK_ENUM && !tp->meaning && useenum) {
X outbasetype(tp, 0);
X output(";");
X }
X tp = makesettype(tp);
X break;
X
X case TOK_FILE:
X gettok();
X tp = maketype(TK_FILE);
X if (curtok == TOK_OF) {
X gettok();
X tp->basetype = p_type(NULL);
X } else {
X tp->basetype = tp_abyte;
X }
X if (tp->basetype->kind == TK_CHAR && charfiletext) {
X tp = tp_text;
X } else {
X makefakestruct(tp, tname);
X tp = makepointertype(tp);
X }
X break;
X
X case TOK_PROCEDURE:
X case TOK_FUNCTION:
X isfunc = (curtok == TOK_FUNCTION);
X gettok();
X if (curtok != TOK_LPAR && !isfunc && hasstaticlinks == 1) {
X tp = tp_proc;
X break;
X }
X proctypecount++;
X mp = addmeaning(findsymbol(format_d("__PROCPTR%d",
X proctypecount)),
X MK_FUNCTION);
X pushctx(mp);
X tp = maketype((hasstaticlinks != 0) ? TK_PROCPTR : TK_CPROCPTR);
X tp->basetype = p_funcdecl(&isfunc, 1);
X tp->fbase = mp; /* (saved, but not currently used) */
X tp->escale = hasstaticlinks;
X popctx();
X break;
X
X case TOK_HAT:
X case TOK_ADDR:
X case TOK_POINTER:
X if (curtok == TOK_POINTER) {
X gettok();
X wneedtok(TOK_TO);
X if (curtok == TOK_IDENT && !strcmp(curtokbuf, "WORD")) {
X tp = tp_anyptr;
X gettok();
X break;
X }
X } else
X gettok();
X p_attributes();
X ignore_attributes();
X tp = maketype(TK_POINTER);
X if (curtok == TOK_IDENT &&
X (!curtokmeaning || curtokmeaning->kind != MK_TYPE ||
X (deferallptrs && curtokmeaning->ctx != curctx))) {
X struct ptrdesc *pd;
X pd = ALLOC(1, struct ptrdesc, ptrdescs);
X pd->sym = curtoksym;
X pd->tp = tp;
X pd->next = ptrbase;
X ptrbase = pd;
X tp->basetype = tp_abyte;
X anydeferredptrs = 1;
X gettok();
X } else {
X tp->basetype = p_type(NULL);
X if (!tp->basetype->pointertype)
X tp->basetype->pointertype = tp;
X }
X break;
X
X case TOK_LPAR:
X if (!useenum)
X outsection(minorspace);
X enum_tname = tname;
X tp = maketype(TK_ENUM);
X flast = &(tp->fbase);
X num = 0;
X do {
X gettok();
X if (!wexpecttok(TOK_IDENT)) {
X skiptotoken(TOK_RPAR);
X break;
X }
X sl = strlist_find(constmacros, curtoksym->name);
X mp = addmeaningas(curtoksym, MK_CONST,
X (*enumformat) ? MK_VARIANT :
X (useenum) ? MK_VAR : MK_CONST);
X mp->val.type = tp;
X mp->val.i = num++;
X mp->type = tp;
X if (sl) {
X mp->constdefn = (Expr *)sl->value;
X mp->anyvarflag = 1; /* Make sure constant is folded */
X strlist_delete(&constmacros, sl);
X if (mp->constdefn->kind == EK_NAME)
X strchange(&mp->name, mp->constdefn->val.s);
X } else {
X if (!useenum) {
X output(format_s("#define %s", mp->name));
X mp->isreturn = 1;
X out_spaces(constindent, 0, 0, 0);
X saveind = outindent;
X outindent = cur_column();
X output(format_d("%d\n", mp->val.i));
X outindent = saveind;
X }
X }
X *flast = mp;
X flast = &(mp->xnext);
X gettok();
X } while (curtok == TOK_COMMA);
X if (!wneedtok(TOK_RPAR))
X skippasttoken(TOK_RPAR);
X tp->smin = makeexpr_long(0);
X tp->smax = makeexpr_long(num-1);
X if (!useenum)
X outsection(minorspace);
X break;
X
X case TOK_LBR:
X tp = p_modula_subrange(NULL);
X break;
X
X case TOK_IDENT:
X if (!curtokmeaning) {
X undefsym(curtoksym);
X tp = tp_integer;
X mp = addmeaning(curtoksym, MK_TYPE);
X mp->type = tp;
X gettok();
X break;
X } else if (curtokmeaning == mp_string) {
X gettok();
X tp = maketype(TK_STRING);
X tp->basetype = tp_char;
X if (curtok == TOK_LBR) {
X gettok();
X ex = p_ord_expr();
X if (!wneedtok(TOK_RBR))
X skippasttoken(TOK_RBR);
X } else {
X ex = makeexpr_long(stringdefault);
X }
X val = eval_expr(ex);
X if (val.type && stringceiling != 255 &&
X (val.i >= 255 || val.i > stringceiling)) {
X freeexpr(ex);
X ex = makeexpr_long(stringceiling);
X }
X tp->indextype = makesubrangetype(tp_integer, makeexpr_long(0), ex);
X break;
X } else if (curtokmeaning->kind == MK_TYPE) {
X tp = curtokmeaning->type;
X if (sizespec > 0) {
X if (ord_type(tp)->kind == TK_INTEGER && sizespec <= 32) {
X if (checkconst(tp->smin, 0)) {
X if (sizespec == 32)
X tp = tp_unsigned;
X else
X tp = makesubrangetype(tp_unsigned,
X makeexpr_long(0),
X makeexpr_long((1L << sizespec) - 1));
X } else {
X tp = makesubrangetype(tp_integer,
X makeexpr_long(- ((1L << (sizespec-1)))),
X makeexpr_long((1L << (sizespec-1)) - 1));
X }
X sizespec = -1;
X }
X }
X gettok();
X if (curtok == TOK_LBR) {
X if (modula2) {
X tp = p_modula_subrange(tp);
X } else {
X gettok();
X ex = p_expr(tp_integer);
X note("UCSD size spec ignored; using 'long int' [110]");
X if (ord_type(tp)->kind == TK_INTEGER)
X tp = tp_integer;
X if (!wneedtok(TOK_RBR))
X skippasttotoken(TOK_RBR, TOK_SEMI);
X }
X }
X break;
X }
X
X /* fall through */
X default:
X tp = maketype(TK_SUBR);
X tp->smin = p_ord_expr();
X if (wexpecttok(TOK_DOTS)) {
X gettok();
X tp->smax = p_ord_expr();
X if (tp->smax->val.type->kind == TK_REAL &&
X tp->smax->kind == EK_CONST &&
X strlen(tp->smax->val.s) == 12 &&
X strcmp(tp->smax->val.s, "2147483648.0") >= 0 &&
END_OF_FILE
if test 49154 -ne `wc -c <'src/decl.c.2'`; then
echo shar: \"'src/decl.c.2'\" unpacked with wrong size!
fi
# end of 'src/decl.c.2'
fi
echo shar: End of archive 27 \(of 32\).
cp /dev/null ark27isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 32 archives.
echo "Now see PACKNOTES and the README"
rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0