decl.c.1
上传用户:upcnvip
上传日期:2007-01-06
资源大小:474k
文件大小:48k
源码类别:

编译器/解释器

开发平台:

C/C++

  1. /* "p2c", a Pascal to C translator.
  2.    Copyright (C) 1989 David Gillespie.
  3.    Author's address: daveg@csvax.caltech.edu; 256-80 Caltech/Pasadena CA 91125.
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation (any version).
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; see the file COPYING.  If not, write to
  13. the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
  14. #define PROTO_DECL_C
  15. #include "trans.h"
  16. #define MAXIMPORTS 100
  17. Static struct ptrdesc {
  18.     struct ptrdesc *next;
  19.     Symbol *sym;
  20.     Type *tp;
  21. } *ptrbase;
  22. Static struct ctxstack {
  23.     struct ctxstack *next;
  24.     Meaning *ctx, *ctxlast;
  25.     struct tempvarlist *tempvars;
  26.     int tempvarcount, importmark;
  27. } *ctxtop;
  28. Static struct tempvarlist {
  29.     struct tempvarlist *next;
  30.     Meaning *tvar;
  31.     int active;
  32. } *tempvars, *stmttempvars;
  33. Static int tempvarcount;
  34. Static int stringtypecachesize;
  35. Static Type **stringtypecache;
  36. Static Meaning *importlist[MAXIMPORTS];
  37. Static int firstimport;
  38. Static Type *tp_special_anyptr;
  39. Static int wasaliased;
  40. Static int deferallptrs;
  41. Static int anydeferredptrs;
  42. Static int silentalreadydef;
  43. Static int nonloclabelcount;
  44. Static Strlist *varstructdecllist;
  45. Static Meaning *findstandardmeaning(kind, name)
  46. enum meaningkind kind;
  47. char *name;
  48. {
  49.     Meaning *mp;
  50.     Symbol *sym;
  51.     sym = findsymbol(fixpascalname(name));
  52.     for (mp = sym->mbase; mp && mp->ctx != curctx; mp = mp->snext) ;
  53.     if (mp) {
  54. if (mp->kind == kind)
  55.     mp->refcount = 1;
  56. else
  57.     mp = NULL;
  58.     }
  59.     return mp;
  60. }
  61. Static Meaning *makestandardmeaning(kind, name)
  62. enum meaningkind kind;
  63. char *name;
  64. {
  65.     Meaning *mp;
  66.     Symbol *sym;
  67.     sym = findsymbol(fixpascalname(name));
  68.     for (mp = sym->mbase; mp && mp->ctx != curctx; mp = mp->snext) ;
  69.     if (!mp) {
  70.         mp = addmeaning(sym, kind);
  71.         strchange(&mp->name, stralloc(name));
  72.         if (debug < 4)
  73.             mp->dumped = partialdump;     /* prevent irrelevant dumping */
  74.     } else {
  75.         mp->kind = kind;
  76.     }
  77.     mp->refcount = 1;
  78.     return mp;
  79. }
  80. Static Type *makestandardtype(kind, mp)
  81. enum typekind kind;
  82. Meaning *mp;
  83. {
  84.     Type *tp;
  85.     tp = maketype(kind);
  86.     tp->meaning = mp;
  87.     if (mp)
  88.         mp->type = tp;
  89.     return tp;
  90. }
  91. Static Stmt *nullspecialproc(mp)
  92. Meaning *mp;
  93. {
  94.     warning(format_s("Procedure %s not yet supported [118]", mp->name));
  95.     if (curtok == TOK_LPAR)
  96.         skipparens();
  97.     return NULL;
  98. }
  99. Meaning *makespecialproc(name, handler)
  100. char *name;
  101. Stmt *(*handler)();
  102. {
  103.     Meaning *mp;
  104.     if (!handler)
  105.         handler = nullspecialproc;
  106.     mp = makestandardmeaning(MK_SPECIAL, name);
  107.     mp->handler = (Expr *(*)())handler;
  108.     return mp;
  109. }
  110. Static Stmt *nullstandardproc(ex)
  111. Expr *ex;
  112. {
  113.     warning(format_s("Procedure %s not yet supported [118]", ((Meaning *)ex->val.i)->name));
  114.     return makestmt_call(ex);
  115. }
  116. Meaning *makestandardproc(name, handler)
  117. char *name;
  118. Stmt *(*handler)();
  119. {
  120.     Meaning *mp;
  121.     if (!handler)
  122.         handler = nullstandardproc;
  123.     mp = findstandardmeaning(MK_FUNCTION, name);
  124.     if (mp) {
  125. mp->handler = (Expr *(*)())handler;
  126. if (mp->isfunction) {
  127.     warning(format_s("Procedure %s was declared as a function [119]", name));
  128.     mp->isfunction = 0;
  129. }
  130.     } else if (debug > 0)
  131. warning(format_s("Procedure %s was never declared [120]", name));
  132.     return mp;
  133. }
  134. Static Expr *nullspecialfunc(mp)
  135. Meaning *mp;
  136. {
  137.     warning(format_s("Function %s not yet supported [121]", mp->name));
  138.     if (curtok == TOK_LPAR)
  139.         skipparens();
  140.     return makeexpr_long(0);
  141. }
  142. Meaning *makespecialfunc(name, handler)
  143. char *name;
  144. Expr *(*handler)();
  145. {
  146.     Meaning *mp;
  147.     if (!handler)
  148.         handler = nullspecialfunc;
  149.     mp = makestandardmeaning(MK_SPECIAL, name);
  150.     mp->isfunction = 1;
  151.     mp->handler = handler;
  152.     return mp;
  153. }
  154. Static Expr *nullstandardfunc(ex)
  155. Expr *ex;
  156. {
  157.     warning(format_s("Function %s not yet supported [121]", ((Meaning *)ex->val.i)->name));
  158.     return ex;
  159. }
  160. Meaning *makestandardfunc(name, handler)
  161. char *name;
  162. Expr *(*handler)();
  163. {
  164.     Meaning *mp;
  165.     if (!handler)
  166.         handler = nullstandardfunc;
  167.     mp = findstandardmeaning(MK_FUNCTION, name);
  168.     if (mp) {
  169. mp->handler = handler;
  170. if (!mp->isfunction) {
  171.     warning(format_s("Function %s was declared as a procedure [122]", name));
  172.     mp->isfunction = 1;
  173. }
  174.     } else if (debug > 0)
  175. warning(format_s("Function %s was never declared [123]", name));
  176.     return mp;
  177. }
  178. Static Expr *nullspecialvar(mp)
  179. Meaning *mp;
  180. {
  181.     warning(format_s("Variable %s not yet supported [124]", mp->name));
  182.     if (curtok == TOK_LPAR || curtok == TOK_LBR)
  183.         skipparens();
  184.     return makeexpr_var(mp);
  185. }
  186. Meaning *makespecialvar(name, handler)
  187. char *name;
  188. Expr *(*handler)();
  189. {
  190.     Meaning *mp;
  191.     if (!handler)
  192.         handler = nullspecialvar;
  193.     mp = makestandardmeaning(MK_SPVAR, name);
  194.     mp->handler = handler;
  195.     return mp;
  196. }
  197. void setup_decl()
  198. {
  199.     Meaning *mp, *mp2, *mp_turbo_shortint;
  200.     Symbol *sym;
  201.     Type *tp;
  202.     int i;
  203.     numimports = 0;
  204.     firstimport = 0;
  205.     permimports = NULL;
  206.     stringceiling = stringceiling | 1;   /* round up to odd */
  207.     stringtypecachesize = (stringceiling + 1) >> 1;
  208.     stringtypecache = ALLOC(stringtypecachesize, Type *, misc);
  209.     curctxlast = NULL;
  210.     curctx = NULL;   /* the meta-ctx has no parent ctx */
  211.     curctx = nullctx = makestandardmeaning(MK_MODULE, "SYSTEM");
  212.     strlist_add(&permimports, "SYSTEM")->value = (long)nullctx;
  213.     ptrbase = NULL;
  214.     tempvars = NULL;
  215.     stmttempvars = NULL;
  216.     tempvarcount = 0;
  217.     deferallptrs = 0;
  218.     silentalreadydef = 0;
  219.     varstructdecllist = NULL;
  220.     nonloclabelcount = -1;
  221.     for (i = 0; i < stringtypecachesize; i++)
  222.         stringtypecache[i] = NULL;
  223.     tp_integer = makestandardtype(TK_INTEGER, makestandardmeaning(MK_TYPE,
  224.                      (integer16) ? "LONGINT" : "INTEGER"));
  225.     tp_integer->smin = makeexpr_long(MININT);             /* "long" */
  226.     tp_integer->smax = makeexpr_long(MAXINT);
  227.     if (sizeof_int >= 32) {
  228.         tp_int = tp_integer;                              /* "int" */
  229.     } else {
  230.         tp_int = makestandardtype(TK_INTEGER,
  231.                      (integer16 > 1) ? makestandardmeaning(MK_TYPE, "INTEGER")
  232.      : NULL);
  233.         tp_int->smin = makeexpr_long(min_sshort);
  234.         tp_int->smax = makeexpr_long(max_sshort);
  235.     }
  236.     mp = makestandardmeaning(MK_TYPE, "C_INT");
  237.     mp->type = tp_int;
  238.     if (!tp_int->meaning)
  239. tp_int->meaning = mp;
  240.     mp_unsigned = makestandardmeaning(MK_TYPE, "UNSIGNED");
  241.     tp_unsigned = makestandardtype(TK_INTEGER, mp_unsigned);
  242.     tp_unsigned->smin = makeexpr_long(0);                 /* "unsigned long" */
  243.     tp_unsigned->smax = makeexpr_long(MAXINT);
  244.     if (sizeof_int >= 32) {
  245.         tp_uint = tp_unsigned;                            /* "unsigned int" */
  246. mp_uint = mp_unsigned;
  247.     } else {
  248. mp_uint = makestandardmeaning(MK_TYPE, "C_UINT");
  249.         tp_uint = makestandardtype(TK_INTEGER, mp_uint);
  250.         tp_uint->smin = makeexpr_long(0);
  251.         tp_uint->smax = makeexpr_long(MAXINT);
  252.     }
  253.     tp_sint = makestandardtype(TK_INTEGER, NULL);
  254.     tp_sint->smin = copyexpr(tp_int->smin);               /* "signed int" */
  255.     tp_sint->smax = copyexpr(tp_int->smax);
  256.     tp_char = makestandardtype(TK_CHAR, makestandardmeaning(MK_TYPE, "CHAR"));
  257.     if (unsignedchar == 0) {
  258. tp_char->smin = makeexpr_long(-128);              /* "char" */
  259. tp_char->smax = makeexpr_long(127);
  260.     } else {
  261. tp_char->smin = makeexpr_long(0);
  262. tp_char->smax = makeexpr_long(255);
  263.     }
  264.     tp_charptr = makestandardtype(TK_POINTER, NULL);      /* "unsigned char *" */
  265.     tp_charptr->basetype = tp_char;
  266.     tp_char->pointertype = tp_charptr;
  267.     mp_schar = makestandardmeaning(MK_TYPE, "SCHAR");     /* "signed char" */
  268.     tp_schar = makestandardtype(TK_CHAR, mp_schar);
  269.     tp_schar->smin = makeexpr_long(-128);
  270.     tp_schar->smax = makeexpr_long(127);
  271.     mp_uchar = makestandardmeaning(MK_TYPE, "UCHAR");     /* "unsigned char" */
  272.     tp_uchar = makestandardtype(TK_CHAR, mp_uchar);
  273.     tp_uchar->smin = makeexpr_long(0);
  274.     tp_uchar->smax = makeexpr_long(255);
  275.     tp_boolean = makestandardtype(TK_BOOLEAN, makestandardmeaning(MK_TYPE, "BOOLEAN"));
  276.     tp_boolean->smin = makeexpr_long(0);                  /* "boolean" */
  277.     tp_boolean->smax = makeexpr_long(1);
  278.     sym = findsymbol("Boolean");
  279.     sym->flags |= SSYNONYM;
  280.     strlist_append(&sym->symbolnames, "===")->value = (long)tp_boolean->meaning->sym;
  281.     tp_real = makestandardtype(TK_REAL, makestandardmeaning(MK_TYPE, "REAL"));
  282.                                                           /* "float" or "double" */
  283.     mp = makestandardmeaning(MK_TYPE, "LONGREAL");
  284.     if (doublereals)
  285. mp->type = tp_longreal = tp_real;
  286.     else
  287. tp_longreal = makestandardtype(TK_REAL, mp);
  288.     tp_void = makestandardtype(TK_VOID, NULL);            /* "void" */
  289.     mp = makestandardmeaning(MK_TYPE, "SINGLE");
  290.     if (doublereals)
  291. makestandardtype(TK_REAL, mp);
  292.     else
  293. mp->type = tp_real;
  294.     makestandardmeaning(MK_TYPE, "SHORTREAL")->type = mp->type;
  295.     mp = makestandardmeaning(MK_TYPE, "DOUBLE");
  296.     mp->type = tp_longreal;
  297.     mp = makestandardmeaning(MK_TYPE, "EXTENDED");
  298.     mp->type = tp_longreal;   /* good enough */
  299.     mp = makestandardmeaning(MK_TYPE, "QUADRUPLE");
  300.     mp->type = tp_longreal;   /* good enough */
  301.     tp_sshort = makestandardtype(TK_SUBR, makestandardmeaning(MK_TYPE,
  302.                   (integer16 == 1) ? "INTEGER" : "SWORD"));
  303.     tp_sshort->basetype = tp_integer;                     /* "short" */
  304.     tp_sshort->smin = makeexpr_long(min_sshort);
  305.     tp_sshort->smax = makeexpr_long(max_sshort);
  306.     if (integer16) {
  307. if (integer16 != 2) {
  308.     mp = makestandardmeaning(MK_TYPE, "SWORD");
  309.     mp->type = tp_sshort;
  310. }
  311.     } else {
  312. mp = makestandardmeaning(MK_TYPE, "LONGINT");
  313. mp->type = tp_integer;
  314.     }
  315.     tp_ushort = makestandardtype(TK_SUBR, makestandardmeaning(MK_TYPE, modula2 ? "UWORD" : "WORD"));
  316.     tp_ushort->basetype = tp_integer;                     /* "unsigned short" */
  317.     tp_ushort->smin = makeexpr_long(0);
  318.     tp_ushort->smax = makeexpr_long(max_ushort);
  319.     mp = makestandardmeaning(MK_TYPE, "CARDINAL");
  320.     mp->type = (integer16) ? tp_ushort : tp_unsigned;
  321.     mp = makestandardmeaning(MK_TYPE, "LONGCARD");
  322.     mp->type = tp_unsigned;
  323.     if (modula2) {
  324. mp = makestandardmeaning(MK_TYPE, "WORD");
  325. mp->type = tp_integer;
  326.     } else {
  327. makestandardmeaning(MK_TYPE, "UWORD")->type = tp_ushort;
  328.     }
  329.     tp_sbyte = makestandardtype(TK_SUBR, NULL);           /* "signed char" */
  330.     tp_sbyte->basetype = tp_integer;
  331.     tp_sbyte->smin = makeexpr_long(min_schar);
  332.     tp_sbyte->smax = makeexpr_long(max_schar);
  333.     mp_turbo_shortint = (which_lang == LANG_TURBO) ? makestandardmeaning(MK_TYPE, "SHORTINT") : NULL;
  334.     mp = makestandardmeaning(MK_TYPE, "SBYTE");
  335.     if (needsignedbyte || signedchars == 1 || hassignedchar) {
  336. mp->type = tp_sbyte;
  337. if (mp_turbo_shortint)
  338.     mp_turbo_shortint->type = tp_sbyte;
  339. tp_sbyte->meaning = mp_turbo_shortint ? mp_turbo_shortint : mp;
  340.     } else {
  341. mp->type = tp_sshort;
  342. if (mp_turbo_shortint)
  343.     mp_turbo_shortint->type = tp_sshort;
  344.     }
  345.     tp_ubyte = makestandardtype(TK_SUBR, makestandardmeaning(MK_TYPE, "BYTE"));
  346.     tp_ubyte->basetype = tp_integer;                      /* "unsigned char" */
  347.     tp_ubyte->smin = makeexpr_long(0);
  348.     tp_ubyte->smax = makeexpr_long(max_uchar);
  349.     if (signedchars == 1)
  350.         tp_abyte = tp_sbyte;                              /* "char" */
  351.     else if (signedchars == 0)
  352.         tp_abyte = tp_ubyte;
  353.     else {
  354.         tp_abyte = makestandardtype(TK_SUBR, NULL);
  355.         tp_abyte->basetype = tp_integer;
  356.         tp_abyte->smin = makeexpr_long(0);
  357.         tp_abyte->smax = makeexpr_long(max_schar);
  358.     }
  359.     mp = makestandardmeaning(MK_TYPE, "POINTER");
  360.     mp2 = makestandardmeaning(MK_TYPE, "ANYPTR");
  361.     tp_anyptr = makestandardtype(TK_POINTER, (which_lang == LANG_HP) ? mp2 : mp);
  362.     ((which_lang == LANG_HP) ? mp : mp2)->type = tp_anyptr;
  363.     tp_anyptr->basetype = tp_void;                        /* "void *" */
  364.     tp_void->pointertype = tp_anyptr;
  365.     if (useAnyptrMacros == 1) {
  366.         tp_special_anyptr = makestandardtype(TK_SUBR, NULL);
  367.         tp_special_anyptr->basetype = tp_integer;
  368.         tp_special_anyptr->smin = makeexpr_long(0);
  369.         tp_special_anyptr->smax = makeexpr_long(max_schar);
  370.     } else
  371.         tp_special_anyptr = NULL;
  372.     tp_proc = maketype(TK_PROCPTR);
  373.     tp_proc->basetype = maketype(TK_FUNCTION);
  374.     tp_proc->basetype->basetype = tp_void;
  375.     tp_proc->escale = 1;   /* saved "hasstaticlinks" */
  376.     tp_str255 = makestandardtype(TK_STRING, NULL);             /* "Char []" */
  377.     tp_str255->basetype = tp_char;
  378.     tp_str255->indextype = makestandardtype(TK_SUBR, NULL);
  379.     tp_str255->indextype->basetype = tp_integer;
  380.     tp_str255->indextype->smin = makeexpr_long(0);
  381.     tp_str255->indextype->smax = makeexpr_long(stringceiling);
  382.     tp_strptr = makestandardtype(TK_POINTER, NULL);            /* "Char *" */
  383.     tp_str255->pointertype = tp_strptr;
  384.     tp_strptr->basetype = tp_str255;
  385.     mp_string = makestandardmeaning(MK_TYPE, "STRING");
  386.     tp = makestandardtype(TK_STRING, mp_string);
  387.     tp->basetype = tp_char;
  388.     tp->indextype = tp_str255->indextype;
  389.     tp_smallset = maketype(TK_SMALLSET);
  390.     tp_smallset->basetype = tp_integer;
  391.     tp_smallset->indextype = tp_boolean;
  392.     tp_text = makestandardtype(TK_POINTER, makestandardmeaning(MK_TYPE, "TEXT"));
  393.     tp_text->basetype = makestandardtype(TK_FILE, NULL);       /* "FILE *" */
  394.     tp_text->basetype->basetype = tp_char;
  395.     tp_text->basetype->pointertype = tp_text;
  396.     tp_jmp_buf = makestandardtype(TK_SPECIAL, NULL);
  397.     mp = makestandardmeaning(MK_TYPE, "INTERACTIVE");
  398.     mp->type = tp_text;
  399.     mp = makestandardmeaning(MK_TYPE, "BITSET");
  400.     mp->type = makesettype(makesubrangetype(tp_integer, makeexpr_long(0),
  401.     makeexpr_long(setbits-1)));
  402.     mp->type->meaning = mp;
  403.     mp = makestandardmeaning(MK_TYPE, "INTSET");
  404.     mp->type = makesettype(makesubrangetype(tp_integer, makeexpr_long(0),
  405.     makeexpr_long(defaultsetsize-1)));
  406.     mp->type->meaning = mp;
  407.     mp_input = makestandardmeaning(MK_VAR, "INPUT");
  408.     mp_input->type = tp_text;
  409.     mp_input->name = stralloc("stdin");
  410.     ex_input = makeexpr_var(mp_input);
  411.     mp_output = makestandardmeaning(MK_VAR, "OUTPUT");
  412.     mp_output->type = tp_text;
  413.     mp_output->name = stralloc("stdout");
  414.     ex_output = makeexpr_var(mp_output);
  415.     mp_stderr = makestandardmeaning(MK_VAR, "STDERR");
  416.     mp_stderr->type = tp_text;
  417.     mp_stderr->name = stralloc("stderr");
  418.     mp_escapecode = makestandardmeaning(MK_VAR, "ESCAPECODE");
  419.     mp_escapecode->type = tp_sshort;
  420.     mp_escapecode->name = stralloc(name_ESCAPECODE);
  421.     mp_ioresult = makestandardmeaning(MK_VAR, "IORESULT");
  422.     mp_ioresult->type = tp_integer;
  423.     mp_ioresult->name = stralloc(name_IORESULT);
  424.     mp_false = makestandardmeaning(MK_CONST, "FALSE");
  425.     mp_false->type = mp_false->val.type = tp_boolean;
  426.     mp_false->val.i = 0;
  427.     mp_true = makestandardmeaning(MK_CONST, "TRUE");
  428.     mp_true->type = mp_true->val.type = tp_boolean;
  429.     mp_true->val.i = 1;
  430.     mp_maxint = makestandardmeaning(MK_CONST, "MAXINT");
  431.     mp_maxint->type = mp_maxint->val.type = tp_integer;
  432.     mp_maxint->val.i = MAXINT;
  433.     mp_maxint->name = stralloc((integer16) ? "SHORT_MAX" :
  434.                                (sizeof_int >= 32) ? "INT_MAX" : "LONG_MAX");
  435.     mp = makestandardmeaning(MK_CONST, "MAXLONGINT");
  436.     mp->type = mp->val.type = tp_integer;
  437.     mp->val.i = MAXINT;
  438.     mp->name = stralloc("LONG_MAX");
  439.     mp_minint = makestandardmeaning(MK_CONST, "MININT");
  440.     mp_minint->type = mp_minint->val.type = tp_integer;
  441.     mp_minint->val.i = MININT;
  442.     mp_minint->name = stralloc((integer16) ? "SHORT_MIN" :
  443.                                (sizeof_int >= 32) ? "INT_MIN" : "LONG_MIN");
  444.     mp = makestandardmeaning(MK_CONST, "MAXCHAR");
  445.     mp->type = mp->val.type = tp_char;
  446.     mp->val.i = 127;
  447.     mp->name = stralloc("CHAR_MAX");
  448.     mp = makestandardmeaning(MK_CONST, "MINCHAR");
  449.     mp->type = mp->val.type = tp_char;
  450.     mp->val.i = 0;
  451.     mp->anyvarflag = 1;
  452.     mp = makestandardmeaning(MK_CONST, "BELL");
  453.     mp->type = mp->val.type = tp_char;
  454.     mp->val.i = 7;
  455.     mp->anyvarflag = 1;
  456.     mp = makestandardmeaning(MK_CONST, "TAB");
  457.     mp->type = mp->val.type = tp_char;
  458.     mp->val.i = 9;
  459.     mp->anyvarflag = 1;
  460.     mp_str_hp = mp_str_turbo = NULL;
  461.     mp_val_modula = mp_val_turbo = NULL;
  462.     mp_blockread_ucsd = mp_blockread_turbo = NULL;
  463.     mp_blockwrite_ucsd = mp_blockwrite_turbo = NULL;
  464.     mp_dec_dec = mp_dec_turbo = NULL;
  465. }
  466. /* This makes sure that if A imports B and then C, C's interface is not
  467.    parsed in the environment of B */
  468. int push_imports()
  469. {
  470.     int mark = firstimport;
  471.     Meaning *mp;
  472.     while (firstimport < numimports) {
  473. if (!strlist_cifind(permimports, importlist[firstimport]->sym->name)) {
  474.     for (mp = importlist[firstimport]->cbase; mp; mp = mp->cnext)
  475. mp->isactive = 0;
  476. }
  477.         firstimport++;
  478.     }
  479.     return mark;
  480. }
  481. void pop_imports(mark)
  482. int mark;
  483. {
  484.     Meaning *mp;
  485.     while (firstimport > mark) {
  486.         firstimport--;
  487.         for (mp = importlist[firstimport]->cbase; mp; mp = mp->cnext)
  488.             mp->isactive = 1;
  489.     }
  490. }
  491. void import_ctx(ctx)
  492. Meaning *ctx;
  493. {
  494.     Meaning *mp;
  495.     int i;
  496.     for (i = firstimport; i < numimports && importlist[i] != ctx; i++) ;
  497.     if (i >= numimports) {
  498.         if (numimports == MAXIMPORTS)
  499.             error(format_d("Maximum of %d simultaneous imports exceeded", MAXIMPORTS));
  500.         importlist[numimports++] = ctx;
  501.     }
  502.     for (mp = ctx->cbase; mp; mp = mp->cnext) {
  503.         if (mp->exported)
  504.             mp->isactive = 1;
  505.     }
  506. }
  507. void perm_import(ctx)
  508. Meaning *ctx;
  509. {
  510.     Meaning *mp;
  511.     /* Import permanently, as in Turbo's "system" unit */
  512.     for (mp = ctx->cbase; mp; mp = mp->cnext) {
  513.         if (mp->exported)
  514.             mp->isactive = 1;
  515.     }
  516. }
  517. void unimport(mark)
  518. int mark;
  519. {
  520.     Meaning *mp;
  521.     while (numimports > mark) {
  522.         numimports--;
  523. if (!strlist_cifind(permimports, importlist[numimports]->sym->name)) {
  524.     for (mp = importlist[numimports]->cbase; mp; mp = mp->cnext)
  525. mp->isactive = 0;
  526. }
  527.     }
  528. }
  529. void activatemeaning(mp)
  530. Meaning *mp;
  531. {
  532.     Meaning *mp2;
  533.     if (debug>1) fprintf(outf, "Reviving %sn", curctxlast->name);
  534.     mp->isactive = 1;
  535.     if (mp->sym->mbase != mp) {     /* move to front of symbol list */
  536.         mp2 = mp->sym->mbase;
  537.         for (;;) {
  538.             if (!mp2) {
  539. /* Not on symbol list: must be a special kludge meaning */
  540.                 return;
  541.             }
  542.             if (mp2->snext == mp)
  543.                 break;
  544.             mp2 = mp2->snext;
  545.         }
  546.         mp2->snext = mp->snext;
  547.         mp->snext = mp->sym->mbase;
  548.         mp->sym->mbase = mp;
  549.     }
  550. }
  551. void pushctx(ctx)
  552. Meaning *ctx;
  553. {
  554.     struct ctxstack *top;
  555.     top = ALLOC(1, struct ctxstack, ctxstacks);
  556.     top->ctx = curctx;
  557.     top->ctxlast = curctxlast;
  558.     top->tempvars = tempvars;
  559.     top->tempvarcount = tempvarcount;
  560.     top->importmark = numimports;
  561.     top->next = ctxtop;
  562.     ctxtop = top;
  563.     curctx = ctx;
  564.     curctxlast = ctx->cbase;
  565.     if (curctxlast) {
  566.         activatemeaning(curctxlast);
  567.         while (curctxlast->cnext) {
  568.             curctxlast = curctxlast->cnext;
  569.             activatemeaning(curctxlast);
  570.         }
  571.     }
  572.     tempvars = NULL;
  573.     tempvarcount = 0;
  574.     if (blockkind != TOK_IMPORT && blockkind != TOK_EXPORT)
  575. progress();
  576. }
  577. void popctx()
  578. {
  579.     struct ctxstack *top;
  580.     struct tempvarlist *tv;
  581.     Meaning *mp;
  582.     if (!strlist_cifind(permimports, curctx->sym->name)) {
  583. for (mp = curctx->cbase; mp; mp = mp->cnext) {
  584.     if (debug>1) fprintf(outf, "Hiding %sn", mp->name);
  585.     mp->isactive = 0;
  586. }
  587.     }
  588.     top = ctxtop;
  589.     ctxtop = top->next;
  590.     curctx = top->ctx;
  591.     curctxlast = top->ctxlast;
  592.     while (tempvars) {
  593.         tv = tempvars->next;
  594.         FREE(tempvars);
  595.         tempvars = tv;
  596.     }
  597.     tempvars = top->tempvars;
  598.     tempvarcount = top->tempvarcount;
  599.     unimport(top->importmark);
  600.     FREE(top);
  601.     if (blockkind != TOK_IMPORT && blockkind != TOK_EXPORT)
  602. progress();
  603. }
  604. void forget_ctx(ctx, all)
  605. Meaning *ctx;
  606. int all;
  607. {
  608.     register Meaning *mp, **mpprev, *mp2, **mpp2;
  609.     if (ctx->kind == MK_FUNCTION && ctx->isfunction && ctx->cbase)
  610. mpprev = &ctx->cbase->cnext;   /* Skip return-value variable */
  611.     else
  612. mpprev = &ctx->cbase;
  613.     while ((mp = *mpprev) != NULL) {
  614. if (all ||
  615.     (mp->kind != MK_PARAM &&
  616.      mp->kind != MK_VARPARAM)) {
  617.     *mpprev = mp->cnext;
  618.     mpp2 = &mp->sym->mbase;
  619.     while ((mp2 = *mpp2) != NULL && mp2 != mp)
  620. mpp2 = &mp2->snext;
  621.     if (mp2)
  622. *mpp2 = mp2->snext;
  623.     if (mp->kind == MK_CONST)
  624. free_value(&mp->val);
  625.     freeexpr(mp->constdefn);
  626.     if (mp->cbase)
  627. forget_ctx(mp, 1);
  628.     if (mp->kind == MK_FUNCTION && mp->val.i)
  629. free_stmt((Stmt *)mp->val.i);
  630.     strlist_empty(&mp->comments);
  631.     if (mp->name)
  632. FREE(mp->name);
  633.     if (mp->othername)
  634. FREE(mp->othername);
  635.     FREE(mp);
  636. } else
  637.     mpprev = &mp->cnext;
  638.     }
  639. }
  640. void handle_nameof()
  641. {
  642.     Strlist *sl, *sl2;
  643.     Symbol *sp;
  644.     char *cp;
  645.     for (sl = nameoflist; sl; sl = sl->next) {
  646.         cp = my_strchr(sl->s, '.');
  647.         if (cp) {
  648.             sp = findsymbol(fixpascalname(cp + 1));
  649.             sl2 = strlist_add(&sp->symbolnames, 
  650.                               format_ds("%.*s", (int)(cp - sl->s), sl->s));
  651.         } else {
  652.             sp = findsymbol(fixpascalname(sl->s));
  653.             sl2 = strlist_add(&sp->symbolnames, "");
  654.         }
  655.         sl2->value = sl->value;
  656.         if (debug > 0)
  657.             fprintf(outf, "symbol %s gets "%s" -> "%s"n",
  658.                           sp->name, sl2->s, sl2->value);
  659.     }
  660.     strlist_empty(&nameoflist);
  661. }
  662. Static void initmeaning(mp)
  663. Meaning *mp;
  664. {
  665. /*    mp->serial = curserial = ++serialcount;    */
  666.     mp->cbase = NULL;
  667.     mp->xnext = NULL;
  668.     mp->othername = NULL;
  669.     mp->type = NULL;
  670.     mp->needvarstruct = 0;
  671.     mp->varstructflag = 0;
  672.     mp->wasdeclared = 0;
  673.     mp->isforward = 0;
  674.     mp->isfunction = 0;
  675.     mp->istemporary = 0;
  676.     mp->volatilequal = 0;
  677.     mp->constqual = 0;
  678.     mp->warnifused = (warnnames > 0);
  679.     mp->constdefn = NULL;
  680.     mp->val.i = 0;
  681.     mp->val.s = NULL;
  682.     mp->val.type = NULL;
  683.     mp->refcount = 1;
  684.     mp->anyvarflag = 0;
  685.     mp->isactive = 1;
  686.     mp->exported = 0;
  687.     mp->handler = NULL;
  688.     mp->dumped = 0;
  689.     mp->isreturn = 0;
  690.     mp->fakeparam = 0;
  691.     mp->namedfile = 0;
  692.     mp->bufferedfile = 0;
  693.     mp->comments = NULL;
  694. }
  695. int issafename(sp, isglobal, isdefine)
  696. Symbol *sp;
  697. int isglobal, isdefine;
  698. {
  699.     if (isdefine && curctx->kind != MK_FUNCTION) {
  700. if (sp->flags & FWDPARAM)
  701.     return 0;
  702.     }
  703.     if ((sp->flags & AVOIDNAME) ||
  704. (isdefine && (sp->flags & AVOIDFIELD)) ||
  705.         (isglobal && (sp->flags & AVOIDGLOB)))
  706.         return 0;
  707.     else
  708.         return 1;
  709. }
  710. static Meaning *enum_tname;
  711. void setupmeaning(mp, sym, kind, namekind)
  712. Meaning *mp;
  713. Symbol *sym;
  714. enum meaningkind kind, namekind;
  715. {
  716.     char *name, *symfmt, *editfmt, *cp, *cp2;
  717.     int altnum, isglobal, isdefine;
  718.     Symbol *sym2;
  719.     Strlist *sl;
  720.     if (!sym)
  721. sym = findsymbol("Spam");   /* reduce crashes due to internal errors */
  722.     if (sym->mbase && sym->mbase->ctx == curctx &&
  723. curctx != NULL && !silentalreadydef)
  724.         alreadydef(sym);
  725.     mp->sym = sym;
  726.     mp->snext = sym->mbase;
  727.     sym->mbase = mp;
  728.     if (sym == curtoksym) {
  729. sym->kwtok = TOK_NONE;
  730. sym->flags &= ~KWPOSS;
  731.     }
  732.     mp->ctx = curctx;
  733.     mp->kind = kind;
  734.     if (pascalcasesens && curctx && curctx->sym && kind != MK_SYNONYM &&
  735. strlist_cifind(permimports, curctx->sym->name)) { /* a built-in name */
  736. Meaning *mp2;
  737. if (islower(sym->name[0]))
  738.     sym2 = findsymbol(strupper(sym->name));
  739. else
  740.     sym2 = findsymbol(strlower(sym->name));
  741. mp2 = addmeaning(sym2, MK_SYNONYM);
  742. mp2->xnext = mp;
  743.     }
  744.     if (kind == MK_VAR) {
  745.         sl = strlist_find(varmacros, sym->name);
  746.         if (sl) {
  747.             kind = namekind = MK_VARMAC;
  748.             mp->constdefn = (Expr *)sl->value;
  749.             strlist_delete(&varmacros, sl);
  750.         }
  751.     }
  752.     if (kind == MK_FUNCTION || kind == MK_SPECIAL) {
  753.         sl = strlist_find(funcmacros, sym->name);
  754.         if (sl) {
  755.             mp->constdefn = (Expr *)sl->value;
  756.             strlist_delete(&funcmacros, sl);
  757.         }
  758.     }
  759.     if (kind == MK_VAR || kind == MK_VARREF || kind == MK_VARMAC ||
  760. kind == MK_TYPE || kind == MK_CONST || kind == MK_FUNCTION) {
  761.         mp->exported = (blockkind == TOK_IMPORT || blockkind == TOK_EXPORT);
  762. if (blockkind == TOK_IMPORT)
  763.     mp->wasdeclared = 1;   /* suppress future declaration */
  764.     } else
  765.         mp->exported = 0;
  766.     if (sym == curtoksym)
  767.         name = curtokcase;
  768.     else
  769.         name = sym->name;
  770.     isdefine = (namekind == MK_CONST);
  771.     isglobal = (!curctx ||
  772. curctx->kind != MK_FUNCTION ||
  773.                 namekind == MK_FUNCTION ||
  774. namekind == MK_TYPE ||
  775.                 isdefine) &&
  776.                (curctx != nullctx);
  777.     mp->refcount = isglobal ? 1 : 0;   /* make sure globals don't disappear */
  778.     if (namekind == MK_SYNONYM)
  779. return;
  780.     if (!mp->exported || !*exportsymbol)
  781.         symfmt = "";
  782.     else if (*export_symbol && my_strchr(name, '_'))
  783.         symfmt = export_symbol;
  784.     else
  785.         symfmt = exportsymbol;
  786.     wasaliased = 0;
  787.     if (*externalias && !my_strchr(externalias, '%')) {
  788.         register int i;
  789.         name = format_s("%s", externalias);
  790.         i = numparams;
  791.         while (--i >= 0 && strcmp(rctable[i].name, "ALIAS")) ;
  792.         if (i < 0 || !undooption(i, ""))
  793.             *externalias = 0;
  794.         wasaliased = 1;
  795.     } else if (sym->symbolnames) {
  796.         if (curctx) {
  797.             if (debug > 2)
  798.                 fprintf(outf, "checking for "%s" of %sn", curctx->name, sym->name);
  799.             sl = strlist_cifind(sym->symbolnames, curctx->sym->name);
  800.             if (sl) {
  801.                 if (debug > 2)
  802.                     fprintf(outf, "found "%s"n", sl->value);
  803.                 name = (char *)sl->value;
  804.                 wasaliased = 1;
  805.             }
  806.         }
  807.         if (!wasaliased) {
  808.             if (debug > 2)
  809.                 fprintf(outf, "checking for "" of %sn", sym->name);
  810.             sl = strlist_find(sym->symbolnames, "");
  811.             if (sl) {
  812.                 if (debug > 2)
  813.                     fprintf(outf, "found "%s"n", sl->value);
  814.                 name = (char *)sl->value;
  815.                 wasaliased = 1;
  816.             }
  817.         }
  818.     }
  819.     if (!*symfmt || wasaliased)
  820. symfmt = "%s";
  821.     altnum = -1;
  822.     do {
  823.         altnum++;
  824.         cp = format_ss(symfmt, name, curctx ? curctx->name : "");
  825. switch (namekind) {
  826.   case MK_CONST:
  827.     editfmt = constformat;
  828.     break;
  829.   case MK_MODULE:
  830.     editfmt = moduleformat;
  831.     break;
  832.   case MK_FUNCTION:
  833.     editfmt = functionformat;
  834.     break;
  835.   case MK_VAR:
  836.   case MK_VARPARAM:
  837.   case MK_VARREF:
  838.   case MK_VARMAC:
  839.   case MK_SPVAR:
  840.     editfmt = varformat;
  841.     break;
  842.   case MK_TYPE:
  843.     editfmt = typeformat;
  844.     break;
  845.   case MK_VARIANT:   /* A true kludge! */
  846.     editfmt = enumformat;
  847.     break;
  848.   default:
  849.     editfmt = "";
  850. }
  851. if (!*editfmt)
  852.     editfmt = symbolformat;
  853. if (*editfmt)
  854.     if (editfmt == enumformat)
  855. cp = format_ss(editfmt, cp,
  856.        enum_tname ? enum_tname->name : "ENUM");
  857.     else
  858. cp = format_ss(editfmt, cp,
  859.        curctx ? curctx->name : "");
  860. if (dollar_idents == 2) {
  861.     for (cp2 = cp; *cp2; cp2++)
  862. if (*cp2 == '$' || *cp2 == '%')
  863.     *cp2 = '_';
  864. }
  865.         sym2 = findsymbol(findaltname(cp, altnum));
  866.     } while (!issafename(sym2, isglobal, isdefine) &&
  867.      namekind != MK_MODULE && !wasaliased);
  868.     mp->name = stralloc(sym2->name);
  869.     if (sym2->flags & WARNNAME)
  870.         note(format_s("A symbol named %s was defined [100]", mp->name));
  871.     if (isglobal) {
  872.         switch (namekind) {     /* prevent further name conflicts */
  873.             case MK_CONST:
  874.     case MK_VARIANT:
  875.             case MK_TYPE:
  876.                 sym2->flags |= AVOIDNAME;
  877.                 break;
  878.             case MK_VAR:
  879.             case MK_VARREF:
  880.             case MK_FUNCTION:
  881.                 sym2->flags |= AVOIDGLOB;
  882.                 break;
  883.     default:
  884. /* name is completely local */
  885. break;
  886.         }
  887.     }
  888.     if (debug > 4)
  889. fprintf(outf, "Created meaning %sn", mp->name);
  890. }
  891. Meaning *addmeaningas(sym, kind, namekind)
  892. Symbol *sym;
  893. enum meaningkind kind, namekind;
  894. {
  895.     Meaning *mp;
  896.     mp = ALLOC(1, Meaning, meanings);
  897.     initmeaning(mp);
  898.     setupmeaning(mp, sym, kind, namekind);
  899.     mp->cnext = NULL;
  900.     if (curctx) {
  901.         if (curctxlast)
  902.             curctxlast->cnext = mp;
  903.         else
  904.             curctx->cbase = mp;
  905.         curctxlast = mp;
  906.     }
  907.     return mp;
  908. }
  909. Meaning *addmeaning(sym, kind)
  910. Symbol *sym;
  911. enum meaningkind kind;
  912. {
  913.     return addmeaningas(sym, kind, kind);
  914. }
  915. Meaning *addmeaningafter(mpprev, sym, kind)
  916. Meaning *mpprev;
  917. Symbol *sym;
  918. enum meaningkind kind;
  919. {
  920.     Meaning *mp;
  921.     if (!mpprev->cnext && mpprev->ctx == curctx)
  922.         return addmeaning(sym, kind);
  923.     mp = ALLOC(1, Meaning, meanings);
  924.     initmeaning(mp);
  925.     setupmeaning(mp, sym, kind, kind);
  926.     mp->ctx = mpprev->ctx;
  927.     mp->cnext = mpprev->cnext;
  928.     mpprev->cnext = mp;
  929.     return mp;
  930. }
  931. void unaddmeaning(mp)
  932. Meaning *mp;
  933. {
  934.     Meaning *prev;
  935.     prev = mp->ctx;
  936.     while (prev && prev != mp)
  937. prev = prev->cnext;
  938.     if (prev)
  939. prev->cnext = mp->cnext;
  940.     else
  941. mp->ctx = mp->cnext;
  942.     if (!mp->cnext && mp->ctx == curctx)
  943. curctxlast = prev;
  944. }
  945. void readdmeaning(mp)
  946. Meaning *mp;
  947. {
  948.     mp->cnext = NULL;
  949.     if (curctx) {
  950.         if (curctxlast)
  951.             curctxlast->cnext = mp;
  952.         else
  953.             curctx->cbase = mp;
  954.         curctxlast = mp;
  955.     }
  956. }
  957. Meaning *addfield(sym, flast, rectype, tname)
  958. Symbol *sym;
  959. Meaning ***flast;
  960. Type *rectype;
  961. Meaning *tname;
  962. {
  963.     Meaning *mp;
  964.     int altnum;
  965.     Symbol *sym2;
  966.     Strlist *sl;
  967.     char *name, *name2;
  968.     mp = ALLOC(1, Meaning, meanings);
  969.     initmeaning(mp);
  970.     mp->sym = sym;
  971.     if (sym) {
  972.         mp->snext = sym->fbase;
  973.         sym->fbase = mp;
  974.         if (sym == curtoksym)
  975.             name2 = curtokcase;
  976.         else
  977.             name2 = sym->name;
  978. name = name2;
  979.         if (tname)
  980.             sl = strlist_find(fieldmacros,
  981.                               format_ss("%s.%s", tname->sym->name, sym->name));
  982.         else
  983.             sl = NULL;
  984.         if (sl) {
  985.             mp->constdefn = (Expr *)sl->value;
  986.             strlist_delete(&fieldmacros, sl);
  987.             altnum = 0;
  988.         } else {
  989.             altnum = -1;
  990.             do {
  991.                 altnum++;
  992. if (*fieldformat)
  993.     name = format_ss(fieldformat, name2,
  994.      tname && tname->name ? tname->name
  995.                           : "FIELD");
  996.                 sym2 = findsymbol(findaltname(name, altnum));
  997.             } while (!issafename(sym2, 0, 0) ||
  998.      ((sym2->flags & AVOIDFIELD) && !reusefieldnames));
  999.     sym2->flags |= AVOIDFIELD;
  1000.         }
  1001.         mp->kind = MK_FIELD;
  1002.         mp->name = stralloc(findaltname(name, altnum));
  1003.     } else {
  1004.         mp->name = stralloc("(variant)");
  1005.         mp->kind = MK_VARIANT;
  1006.     }
  1007.     mp->cnext = NULL;
  1008.     **flast = mp;
  1009.     *flast = &(mp->cnext);
  1010.     mp->ctx = NULL;
  1011.     mp->rectype = rectype;
  1012.     mp->val.i = 0;
  1013.     return mp;
  1014. }
  1015. int isfiletype(type)
  1016. Type *type;
  1017. {
  1018.     return (type->kind == TK_POINTER &&
  1019.             type->basetype->kind == TK_FILE);
  1020. }
  1021. Meaning *isfilevar(ex)
  1022. Expr *ex;
  1023. {
  1024.     Meaning *mp;
  1025.     if (ex->kind == EK_VAR) {
  1026. mp = (Meaning *)ex->val.i;
  1027. if (mp->kind == MK_VAR)
  1028.     return mp;
  1029.     } else if (ex->kind == EK_DOT) {
  1030. mp = (Meaning *)ex->val.i;
  1031. if (mp && mp->kind == MK_FIELD)
  1032.     return mp;
  1033.     }
  1034.     return NULL;
  1035. }
  1036. Type *findbasetype_(type, flags)
  1037. Type *type;
  1038. int flags;
  1039. {
  1040.     long smin, smax;
  1041.     for (;;) {
  1042.         switch (type->kind) {
  1043.             case TK_POINTER:
  1044.                 if (type->basetype == tp_void) {     /* ANYPTR */
  1045.                     if (tp_special_anyptr)
  1046.                         return tp_special_anyptr;   /* write "Anyptr" */
  1047.                     if (!voidstar)
  1048.                         return tp_abyte;    /* write "char *", not "void *" */
  1049.                 }
  1050.                 switch (type->basetype->kind) {
  1051.                     case TK_ARRAY:       /* use basetype's basetype: */
  1052.                     case TK_STRING:      /* ^array[5] of array[3] of integer */
  1053.                     case TK_SET:         /*  => int (*a)[3]; */
  1054.         if (stararrays == 1 ||
  1055.     !(flags & ODECL_FREEARRAY) ||
  1056.     type->basetype->structdefd) {
  1057.     type = type->basetype;
  1058.     flags &= ~ODECL_CHARSTAR;
  1059. }
  1060.                         break;
  1061.     default:
  1062. break;
  1063.                 }
  1064.                 break;
  1065.             case TK_FUNCTION:
  1066.             case TK_STRING:
  1067.             case TK_SET:
  1068.             case TK_SMALLSET:
  1069.             case TK_SMALLARRAY:
  1070.                 if (!type->basetype)
  1071.                     return type;
  1072.                 break;
  1073.             case TK_ARRAY:
  1074.                 if (type->meaning && type->meaning->kind == MK_TYPE &&
  1075.                     type->meaning->wasdeclared)
  1076.                     return type;
  1077.                 break;
  1078.             case TK_FILE:
  1079.                 return tp_text->basetype;
  1080.             case TK_PROCPTR:
  1081. return tp_proc;
  1082.     case TK_CPROCPTR:
  1083. type = type->basetype->basetype;
  1084. continue;
  1085.             case TK_ENUM:
  1086.                 if (useenum)
  1087.                     return type;
  1088.                 else if (!enumbyte ||
  1089.  type->smax->kind != EK_CONST ||
  1090.  type->smax->val.i > 255)
  1091.     return tp_sshort;
  1092. else if (type->smax->val.i > 127)
  1093.                     return tp_ubyte;
  1094. else
  1095.                     return tp_abyte;
  1096.             case TK_BOOLEAN:
  1097.                 if (*name_BOOLEAN)
  1098.                     return type;
  1099.                 else
  1100.                     return tp_ubyte;
  1101.             case TK_SUBR:
  1102.                 if (type == tp_abyte || type == tp_ubyte || type == tp_sbyte ||
  1103.                     type == tp_ushort || type == tp_sshort) {
  1104.                     return type;
  1105.                 } else if ((type->basetype->kind == TK_ENUM && useenum) ||
  1106.                            type->basetype->kind == TK_BOOLEAN && *name_BOOLEAN) {
  1107.                     return type->basetype;
  1108.                 } else {
  1109.                     if (ord_range(type, &smin, &smax)) {
  1110.                         if (squeezesubr != 0) {
  1111.                             if (smin >= 0 && smax <= max_schar)
  1112.                                 return tp_abyte;
  1113.                             else if (smin >= 0 && smax <= max_uchar)
  1114.                                 return tp_ubyte;
  1115.                             else if (smin >= min_schar && smax <= max_schar &&
  1116.      (signedchars == 1 || hassignedchar))
  1117.                                 return tp_sbyte;
  1118.                             else if (smin >= min_sshort && smax <= max_sshort)
  1119.                                 return tp_sshort;
  1120.                             else if (smin >= 0 && smax <= max_ushort)
  1121.                                 return tp_ushort;
  1122.                             else
  1123.                                 return tp_integer;
  1124.                         } else {
  1125.                             if (smin >= min_sshort && smax <= max_sshort)
  1126.                                 return tp_sshort;
  1127.                             else
  1128.                                 return tp_integer;
  1129.                         }
  1130.                     } else
  1131.                         return tp_integer;
  1132.                 }
  1133.     case TK_CHAR:
  1134. if (type == tp_schar &&
  1135.     (signedchars != 1 && !hassignedchar)) {
  1136.     return tp_sshort;
  1137. }
  1138. return type;
  1139.             default:
  1140.                 return type;
  1141.         }
  1142.         type = type->basetype;
  1143.     }
  1144. }
  1145. Type *findbasetype(type, flags)
  1146. Type *type;
  1147. int flags;
  1148. {
  1149.     if (debug>1) {
  1150. fprintf(outf, "findbasetype(");
  1151. dumptypename(type, 1);
  1152. fprintf(outf, ",%d) = ", flags);
  1153. type = findbasetype_(type, flags);
  1154. dumptypename(type, 1);
  1155. fprintf(outf, "n");
  1156. return type;
  1157.     }
  1158.     return findbasetype_(type, flags);
  1159. }
  1160. Expr *arraysize(tp, incskipped)
  1161. Type *tp;
  1162. int incskipped;
  1163. {
  1164.     Expr *ex, *minv, *maxv;
  1165.     int denom;
  1166.     ord_range_expr(tp->indextype, &minv, &maxv);
  1167.     if (maxv->kind == EK_VAR && maxv->val.i == (long)mp_maxint &&
  1168. !exprdependsvar(minv, mp_maxint)) {
  1169.         return NULL;
  1170.     } else {
  1171.         ex = makeexpr_plus(makeexpr_minus(copyexpr(maxv),
  1172.                                           copyexpr(minv)),
  1173.                            makeexpr_long(1));
  1174.         if (tp->smin && !incskipped) {
  1175.             ex = makeexpr_minus(ex, copyexpr(tp->smin));
  1176.         }
  1177.         if (tp->smax) {
  1178.             denom = (tp->basetype == tp_sshort) ? 16 : 8;
  1179.             denom >>= tp->escale;
  1180.             ex = makeexpr_div(makeexpr_plus(ex, makeexpr_long(denom-1)),
  1181.                               makeexpr_long(denom));
  1182.         }
  1183.         return ex;
  1184.     }
  1185. }
  1186. Type *promote_type(tp)
  1187. Type *tp;
  1188. {
  1189.     Type *tp2;
  1190.     if (tp->kind == TK_ENUM) {
  1191. if (promote_enums == 0 ||
  1192.     (promote_enums < 0 &&
  1193.      (useenum)))
  1194.     return tp;
  1195.     }
  1196.     if (tp->kind == TK_ENUM ||
  1197.          tp->kind == TK_SUBR ||
  1198.          tp->kind == TK_INTEGER ||
  1199.          tp->kind == TK_CHAR ||
  1200.          tp->kind == TK_BOOLEAN) {
  1201.         tp2 = findbasetype(tp, 0);
  1202. if (tp2 == tp_ushort && sizeof_int == 16)
  1203.     return tp_uint;
  1204.         else if (tp2 == tp_sbyte || tp2 == tp_ubyte ||
  1205.  tp2 == tp_abyte || tp2 == tp_char ||
  1206.  tp2 == tp_sshort || tp2 == tp_ushort ||
  1207.  tp2 == tp_boolean || tp2->kind == TK_ENUM) {
  1208.             return tp_int;
  1209.         }
  1210.     }
  1211.     if (tp == tp_real)
  1212. return tp_longreal;
  1213.     return tp;
  1214. }
  1215. Type *promote_type_bin(t1, t2)
  1216. Type *t1, *t2;
  1217. {
  1218.     t1 = promote_type(t1);
  1219.     t2 = promote_type(t2);
  1220.     if (t1 == tp_longreal || t2 == tp_longreal)
  1221. return tp_longreal;
  1222.     if (t1 == tp_unsigned || t2 == tp_unsigned)
  1223. return tp_unsigned;
  1224.     if (t1 == tp_integer || t2 == tp_integer) {
  1225. if ((t1 == tp_uint || t2 == tp_uint) &&
  1226.     sizeof_int > 0 &&
  1227.     sizeof_int < (sizeof_long > 0 ? sizeof_long : 32))
  1228.     return tp_uint;
  1229. return tp_integer;
  1230.     }
  1231.     if (t1 == tp_uint || t2 == tp_uint)
  1232. return tp_uint;
  1233.     return t1;
  1234. }
  1235. #if 0
  1236. void predeclare_varstruct(mp)
  1237. Meaning *mp;
  1238. {
  1239.     if (mp->ctx &&
  1240.  mp->ctx->kind == MK_FUNCTION &&
  1241.  mp->ctx->varstructflag &&
  1242.  (usePPMacros != 0 || prototypes != 0) &&
  1243.  !strlist_find(varstructdecllist, mp->ctx->name)) {
  1244. output("struct ");
  1245. output(format_s(name_LOC, mp->ctx->name));
  1246. output(" ;n");
  1247. strlist_insert(&varstructdecllist, mp->ctx->name);
  1248.     }
  1249. }
  1250. #endif
  1251. Static void declare_args(type, isheader, isforward)
  1252. Type *type;
  1253. int isheader, isforward;
  1254. {
  1255.     Meaning *mp = type->fbase;
  1256.     Type *tp;
  1257.     int firstflag = 0;
  1258.     int usePP, dopromote, proto, showtypes, shownames;
  1259.     int staticlink;
  1260.     char *name;
  1261. #if 1   /* This seems to work better! */
  1262.     isforward = !isheader;
  1263. #endif
  1264.     usePP = (isforward && usePPMacros != 0);
  1265.     dopromote = (promoteargs == 1 ||
  1266.  (promoteargs < 0 && (usePP || !fullprototyping)));
  1267.     if (ansiC == 1 && blockkind != TOK_EXPORT)
  1268. usePP = 0;
  1269.     if (usePP)
  1270.         proto = (prototypes) ? prototypes : 1;
  1271.     else
  1272.         proto = (isforward || fullprototyping) ? prototypes : 0;
  1273.     showtypes = (proto > 0);
  1274.     shownames = (proto == 1 || isheader);
  1275.     staticlink = (type->issigned ||
  1276.                   (type->meaning &&
  1277.                    type->meaning->ctx->kind == MK_FUNCTION &&
  1278.                    type->meaning->ctx->varstructflag));
  1279.     if (mp || staticlink) {
  1280.         if (usePP)
  1281.             output(" PP(");
  1282.         output("(");
  1283.         if (showtypes || shownames) {
  1284.             firstflag = 0;
  1285.             while (mp) {
  1286.                 if (firstflag++) output(",02 ");
  1287.                 name = (mp->othername && isheader) ? mp->othername : mp->name;
  1288.                 tp = (mp->othername) ? mp->rectype : mp->type;
  1289.                 if (!showtypes) {
  1290.                     output(name);
  1291.                 } else {
  1292.     output(storageclassname(varstorageclass(mp)));
  1293.     if (!shownames || (isforward && *name == '_')) {
  1294. out_type(tp, 1);
  1295.     } else {
  1296. if (dopromote)
  1297.     tp = promote_type(tp);
  1298. outbasetype(tp, ODECL_CHARSTAR|ODECL_FREEARRAY);
  1299. output(" ");
  1300. outdeclarator(tp, name,
  1301.       ODECL_CHARSTAR|ODECL_FREEARRAY);
  1302.     }
  1303. }
  1304.                 if (isheader)
  1305.                     mp->wasdeclared = showtypes;
  1306.                 if (mp->type == tp_strptr && mp->anyvarflag) {     /* VAR STRING parameter */
  1307.                     output(",02 ");
  1308.                     if (showtypes) {
  1309. if (useAnyptrMacros == 1 || useconsts == 2)
  1310.     output("Const ");
  1311. else if (ansiC > 0)
  1312.     output("const ");
  1313.                         output("int");
  1314.     }
  1315.                     if (shownames) {
  1316.                         if (showtypes)
  1317.                             output(" ");
  1318.                         output(format_s(name_STRMAX, mp->name));
  1319.                     }
  1320.                 }
  1321.                 mp = mp->xnext;
  1322.             }
  1323.             if (staticlink) {     /* sub-procedure with static link */
  1324.                 if (firstflag++) output(",02 ");
  1325.                 if (type->issigned) {
  1326.                     if (showtypes)
  1327. if (tp_special_anyptr)
  1328.     output("Anyptr ");
  1329. else if (voidstar)
  1330.     output("void *");
  1331. else
  1332.     output("char *");
  1333.                     if (shownames)
  1334.                         output("_link");
  1335.                 } else {
  1336.                     mp = type->meaning->ctx;
  1337.                     if (showtypes) {
  1338.                         output("struct ");
  1339.                         output(format_s(name_LOC, mp->name));
  1340.                         output(" *");
  1341.                     }
  1342.                     if (shownames) {
  1343.                         output(format_s(name_LINK, mp->name));
  1344.                     }
  1345.                 }
  1346.             }
  1347.         }
  1348.         output(")");
  1349.         if (usePP)
  1350.             output(")");
  1351.     } else {
  1352.         if (usePP)
  1353.             output(" PV()");
  1354.         else if (void_args)
  1355.             output("(void)");
  1356.         else
  1357.             output("()");
  1358.     }
  1359. }
  1360. void outdeclarator(type, name, flags)
  1361. Type *type;
  1362. char *name;
  1363. int flags;
  1364. {
  1365.     int i, depth, anyptrs, anyarrays;
  1366.     Expr *dimen[30];
  1367.     Expr *ex, *maxv;
  1368.     Type *tp, *functype;
  1369.     Expr funcdummy;   /* yow */
  1370.     anyptrs = 0;
  1371.     anyarrays = 0;
  1372.     functype = NULL;
  1373.     for (depth = 0, tp = type; tp; tp = tp->basetype) {
  1374.         switch (tp->kind) {
  1375.             case TK_POINTER:
  1376.                 if (tp->basetype) {
  1377.                     switch (tp->basetype->kind) {
  1378.         case TK_VOID:
  1379.     if (tp->basetype == tp_void &&
  1380. tp_special_anyptr) {
  1381. tp = tp_special_anyptr;
  1382. continue;
  1383.     }
  1384.     break;
  1385.                         case TK_ARRAY:    /* ptr to array of x => ptr to x */
  1386.                         case TK_STRING:   /*                or => array of x */
  1387.                         case TK_SET:
  1388.     if (stararrays == 1 ||
  1389. !(flags & ODECL_FREEARRAY) ||
  1390. (tp->basetype->structdefd &&
  1391.  stararrays != 2)) {
  1392. tp = tp->basetype;
  1393. flags &= ~ODECL_CHARSTAR;
  1394.     } else {
  1395. continue;
  1396.     }
  1397.                             break;
  1398. default:
  1399.     break;
  1400.                     }
  1401.                 }
  1402.                 dimen[depth++] = NULL;
  1403.                 anyptrs++;
  1404.                 continue;
  1405.             case TK_ARRAY:
  1406. flags &= ~ODECL_CHARSTAR;
  1407.                 if (tp->meaning && tp->meaning->kind == MK_TYPE &&
  1408.                     tp->meaning->wasdeclared)
  1409.                     break;
  1410. if (tp->structdefd) {    /* conformant array */
  1411.     if (!variablearrays &&
  1412. !(tp->basetype->kind == TK_ARRAY &&
  1413.   tp->basetype->structdefd))   /* avoid mult. notes */
  1414. note("Conformant array code may not work in all compilers [101]");
  1415. }
  1416.                 ex = arraysize(tp, 1);
  1417.                 if (!ex)
  1418.                     ex = makeexpr_name("", tp_integer);
  1419.                 dimen[depth++] = ex;
  1420. anyarrays++;
  1421.                 continue;
  1422.             case TK_SET:
  1423.                 ord_range_expr(tp->indextype, NULL, &maxv);
  1424.                 maxv = enum_to_int(copyexpr(maxv));
  1425.                 if (ord_type(maxv->val.type)->kind == TK_CHAR)
  1426.                     maxv->val.type = tp_integer;
  1427.                 dimen[depth++] = makeexpr_plus(makeexpr_div(maxv, makeexpr_setbits()),
  1428.                                                makeexpr_long(2));
  1429.                 break;
  1430.             case TK_STRING:
  1431.                 if ((flags & ODECL_CHARSTAR) && stararrays == 1) {
  1432.                     dimen[depth++] = NULL;
  1433.                 } else {
  1434.                     ord_range_expr(tp->indextype, NULL, &maxv);
  1435.                     dimen[depth++] = makeexpr_plus(copyexpr(maxv), makeexpr_long(1));
  1436.                 }
  1437.                 continue;
  1438.             case TK_FILE:
  1439.                 break;
  1440.     case TK_CPROCPTR:
  1441. dimen[depth++] = NULL;
  1442. anyptrs++;
  1443. if (procptrprototypes)
  1444.     continue;
  1445.                 dimen[depth++] = &funcdummy;
  1446. break;
  1447.             case TK_FUNCTION:
  1448.                 dimen[depth++] = &funcdummy;
  1449.                 if (!functype)
  1450.                     functype = tp;
  1451.                 continue;
  1452.     default:
  1453. break;
  1454.         }
  1455.         break;
  1456.     }
  1457.     if (!*name && depth && (spaceexprs > 0 ||
  1458.                             (spaceexprs != 0 && !dimen[depth-1])))
  1459.         output(" ");    /* spacing for abstract declarator */
  1460.     if ((flags & ODECL_FUNCTION) && anyptrs)
  1461.         output(" ");
  1462.     if (anyarrays > 1 && !(flags & ODECL_FUNCTION))
  1463. output("03");
  1464.     for (i = depth; --i >= 0; ) {
  1465.         if (!dimen[i])
  1466.             output("*");
  1467.         if (i > 0 &&
  1468.             ((dimen[i] && !dimen[i-1]) ||
  1469.              (dimen[i-1] && !dimen[i] && extraparens > 0)))
  1470.             output("(");
  1471.     }
  1472.     if (flags & ODECL_FUNCTION)
  1473.         output("n");
  1474.     if (anyarrays > 1 && (flags & ODECL_FUNCTION))
  1475. output("03");
  1476.     output(name);
  1477.     for (i = 0; i < depth; i++) {
  1478.         if (i > 0 &&
  1479.             ((dimen[i] && !dimen[i-1]) ||
  1480.              (dimen[i-1] && !dimen[i] && extraparens > 0)))
  1481.             output(")");
  1482.         if (dimen[i]) {
  1483.             if (dimen[i] == &funcdummy) {
  1484. if (lookback(1) == ')')
  1485.     output("02");
  1486. if (functype)
  1487.     declare_args(functype, (flags & ODECL_HEADER) != 0,
  1488.            (flags & ODECL_FORWARD) != 0);
  1489. else
  1490.     output("()");
  1491.             } else {
  1492. if (lookback(1) == ']')
  1493.     output("02");
  1494.                 output("[");
  1495.                 if (!(flags & ODECL_FREEARRAY) || stararrays == 0 || i > 0)
  1496.                     out_expr(dimen[i]);
  1497.                 freeexpr(dimen[i]);
  1498.                 output("]");
  1499.             }
  1500.         }
  1501.     }
  1502.     if (anyarrays > 1)
  1503. output("04");
  1504. }
  1505. /* Find out if types t1 and t2 will work out to be the same C type,
  1506.    for purposes of type-casting */
  1507. Type *canonicaltype(type)
  1508. Type *type;
  1509. {
  1510.     if (type->kind == TK_SUBR || type->kind == TK_ENUM ||
  1511.         type->kind == TK_PROCPTR)
  1512.         type = findbasetype(type, 0);
  1513.     if (type == tp_char)
  1514.         return tp_ubyte;
  1515.     if (type->kind == TK_POINTER) {
  1516.         if (type->basetype->kind == TK_ARRAY ||
  1517.             type->basetype->kind == TK_STRING ||
  1518.             type->basetype->kind == TK_SET)
  1519.             return makepointertype(canonicaltype(type->basetype->basetype));
  1520.         else if (type->basetype == tp_void)
  1521.             return (voidstar) ? tp_anyptr : makepointertype(tp_abyte);
  1522.         else if (type->basetype->kind == TK_FILE)
  1523.             return tp_text;
  1524.         else
  1525.             return makepointertype(canonicaltype(type->basetype));
  1526.     }
  1527.     return type;
  1528. }
  1529. int similartypes(t1, t2)
  1530. Type *t1, *t2;
  1531. {
  1532.     t1 = canonicaltype(t1);
  1533.     t2 = canonicaltype(t2);
  1534.     return (t1 == t2);
  1535. }
  1536. Static int checkstructconst(mp)
  1537. Meaning *mp;
  1538. {
  1539.     return (mp->kind == MK_VAR &&
  1540.     mp->constdefn &&
  1541.             mp->constdefn->kind == EK_CONST &&
  1542.             (mp->constdefn->val.type->kind == TK_ARRAY ||
  1543.              mp->constdefn->val.type->kind == TK_RECORD));
  1544. }
  1545. Static int mixable(mp1, mp2, args, flags)
  1546. Meaning *mp1, *mp2;
  1547. int args, flags;
  1548. {
  1549.     Type *tp1 = mp1->type, *tp2 = mp2->type;
  1550.     if (mixvars == 0)
  1551.         return 0;
  1552.     if (mp1->kind == MK_FIELD &&
  1553.         (mp1->val.i || mp2->val.i) && mixfields == 0)
  1554.         return 0;
  1555.     if (checkstructconst(mp1) || checkstructconst(mp2))
  1556.         return 0;
  1557.     if (mp1->comments) {
  1558. if (findcomment(mp1->comments, CMT_NOT | CMT_PRE, -1))
  1559.     return 0;
  1560.     }
  1561.     if (mp2->comments) {
  1562. if (findcomment(mp2->comments, CMT_PRE, -1))
  1563.     return 0;
  1564.     }
  1565.     if ((mp1->constdefn && (mp1->kind == MK_VAR || mp1->kind == MK_VARREF)) ||
  1566. (mp2->constdefn && (mp2->kind == MK_VAR || mp2->kind == MK_VARREF))) {
  1567.         if (mixinits == 0)
  1568.             return 0;
  1569.         if (mixinits != 1 &&
  1570.             (!mp1->constdefn || !mp2->constdefn))