home *** CD-ROM | disk | FTP | other *** search
- 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
-