home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 26 / AACD 26.iso / AACD / Programming / ace_gpl_release / src / ace / c / misc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-10-04  |  13.1 KB  |  592 lines

  1. /* << ACE >>
  2.  
  3.    -- Amiga BASIC Compiler --
  4.  
  5.    ** Parser: miscellaneous functions **
  6.    ** Copyright (C) 1998 David Benn
  7.    ** 
  8.    ** This program is free software; you can redistribute it and/or
  9.    ** modify it under the terms of the GNU General Public License
  10.    ** as published by the Free Software Foundation; either version 2
  11.    ** of the License, or (at your option) any later version.
  12.    **
  13.    ** This program is distributed in the hope that it will be useful,
  14.    ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.    ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.    ** GNU General Public License for more details.
  17.    **
  18.    ** You should have received a copy of the GNU General Public License
  19.    ** along with this program; if not, write to the Free Software
  20.    ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  21.  
  22.    Author: David J Benn
  23.      Date: 26th October-30th November, 1st-13th December 1991,
  24.        14th,20th-27th January 1992, 
  25.            2nd-17th, 21st-29th February 1992, 
  26.        1st,13th,14th,22nd,23rd March 1992,
  27.        21st,22nd April 1992,
  28.        2nd,3rd,11th,15th,16th May 1992,
  29.        7th,8th,9th,11th,13th,14th,28th,29th,30th June 1992,
  30.        2nd-8th,14th-19th,26th-29th July 1992,
  31.        1st-3rd,7th,8th,9th August 1992,
  32.        6th,7th,21st,22nd December 1992,
  33.        12th February 1993,
  34.        1st March 1993,
  35.        20th,30th June 1993,
  36.        1st,2nd July 1993,
  37.        26th October 1993,
  38.        14th,16th,17th,24th,25th December 1993,
  39.        2nd,5th,7th-9th,13th,14th January 1994,
  40.        6th,7th,15th,16th,26th,27th February 1994,
  41.        4th,13th,30th April 1994,
  42.        14th,15th May 1994,
  43.        12th,21st,22nd,25th June 1994,
  44.        10th,14th,24th July 1994,
  45.        3rd,22nd August 1994,
  46.        2nd,3rd,10th September 1994,
  47.        6th October 1995
  48. */
  49.  
  50. #include "acedef.h"
  51.  
  52. /* locals */
  53. static    char     *frame_ptr[] = { "(a4)","(a5)" };
  54.  
  55. /* externals */
  56. extern    BOOL    report_errors;
  57. extern    int    sym;
  58. extern    int    lastsym;
  59. extern    int    lev;
  60. extern    SHORT    shortval;
  61. extern    LONG    longval;
  62. extern    char       id[MAXIDSIZE]; 
  63. extern    char       ut_id[MAXIDSIZE]; 
  64. extern    char    lastline[MAXLINELEN];
  65. extern    char       string_const_start[7];
  66. extern    char       string_const_end[4];
  67. extern    BOOL    have_lparen;
  68. extern    BOOL    end_of_source;
  69. extern    BOOL    break_opt;
  70. extern    BOOL    asm_comments;
  71. extern    BOOL    error_log;
  72. extern    BOOL    make_icon;
  73. extern    BOOL    list_source;
  74. extern    BOOL    optimise_opt;
  75. extern    BOOL    wdw_close_opt;
  76. extern    BOOL    module_opt;
  77. extern    FILE    *err_log;
  78. extern    int    idtype[31];
  79. extern    int      strconstcount;
  80. extern    int      tempstrcount;
  81. extern    int      tempshortcount;
  82. extern    int      templongcount;
  83. extern    char     tempstrname[80],tempstrlabel[80];
  84. extern    char     tempshortname[80],tempshortlabel[80];
  85. extern    char     templongname[80],templonglabel[80];
  86.  
  87. /* redefine ZC's CTRL-C testing function to do nothing */ 
  88. long    Chk_Abort() { return 0; }
  89.  
  90. /* functions */
  91. void make_temp_long()
  92. {
  93.  /* make a long integer BSS object for temporary storage
  94.     of actual value parameters */
  95. char numbuf[40],storesize[40];
  96.  
  97.  itoa(templongcount++,numbuf,10);
  98.  strcpy(templongname,"_templong");
  99.  strcat(templongname,numbuf);
  100.  
  101.  strcpy(templonglabel,templongname);
  102.  strcat(templonglabel,":\0");
  103.  
  104.  strcpy(storesize,"ds.l 1 ");
  105.  enter_BSS(templonglabel,storesize);
  106. }
  107.  
  108. void make_temp_short()
  109. {
  110.  /* make a short integer BSS object for temporary storage
  111.     of actual value parameters */
  112. char numbuf[40],storesize[40];
  113.  
  114.  itoa(tempshortcount++,numbuf,10);
  115.  strcpy(tempshortname,"_tempshort");
  116.  strcat(tempshortname,numbuf);
  117.  
  118.  strcpy(tempshortlabel,tempshortname);
  119.  strcat(tempshortlabel,":\0");
  120.  
  121.  strcpy(storesize,"ds.l 1 ");
  122.  enter_BSS(tempshortlabel,storesize);
  123. }
  124.  
  125. void make_temp_string()
  126. {
  127. /* need a unique BSS string store for ALL string functions to prevent 
  128.    overwriting of string data */
  129. char numbuf[40],sizebuf[40],storesize[40];
  130.  
  131.  itoa(tempstrcount++,numbuf,10);
  132.  strcpy(tempstrname,"_tempstring");
  133.  strcat(tempstrname,numbuf);
  134.  
  135.  strcpy(tempstrlabel,tempstrname);
  136.  strcat(tempstrlabel,":\0");
  137.  
  138.  strcpy(storesize,"ds.b ");
  139.  itoa(MAXSTRLEN,sizebuf,10);
  140.  strcat(storesize,sizebuf);
  141.  enter_BSS(tempstrlabel,storesize);
  142. }
  143.  
  144. void make_string_const(string)
  145. char *string;
  146. {
  147. char *strbuf,buf[80],strlabel[80],strname[80];
  148.  
  149.  itoa(strconstcount++,buf,10);
  150.  /* label for DATA section */
  151.  strcpy(strlabel,"_stringconst");
  152.  strcat(strlabel,buf);
  153.  /* name for reference in code */
  154.  strcpy(strname,strlabel);
  155.  /* complete string label */
  156.  strcat(strlabel,":\0");
  157.  /* actual string constant */
  158.  strbuf=(char *)alloc(strlen(string)+10,MEMF_ANY); 
  159.                              /* +10 is for string_const_start/end (9) & '\0' */ 
  160.  strcpy(strbuf,string_const_start);
  161.  strcat(strbuf,string);
  162.  strcat(strbuf,string_const_end);
  163.  enter_DATA(strlabel,strbuf);
  164.  /*FreeMem(strbuf,strlen(string)+10);*/
  165.  /* push its address onto stack */
  166.  gen("pea",strname,"  ");
  167. }
  168.  
  169. void make_label_from_linenum(intconst,buf)
  170. int  intconst;
  171. char *buf;
  172. {
  173. /* turns a line number into a label */
  174.  
  175.  switch(intconst)
  176.  {
  177.   case shortconst : sprintf(buf,"_LINE%d",shortval); break;
  178.   case longconst  : sprintf(buf,"_LINE%ld",longval); break;
  179.  }
  180. }
  181.  
  182. LONG max_array_ndx(curr)
  183. SYM *curr;
  184. {
  185. /* Returns # of linear elements in an array.
  186.    eg: DIM X(10,10) yields 121 elements: 0..10, 0..10 -> 11 * 11 
  187. */
  188. int  i;
  189. LONG max=1;
  190.  
  191.  for (i=curr->dims;i>=0;i--) max *= curr->index[i];
  192.  return(max);
  193. }
  194.  
  195. void push_indices(curr)
  196. SYM *curr;
  197. {
  198. /* put array indices onto stack */
  199. int ndxcount=0;
  200.  
  201.  if (!have_lparen) 
  202.     insymbol(); 
  203.  else 
  204.     have_lparen=FALSE; /* don't want to leave this as TRUE, else if
  205.               push_indices() called from factor() etc, 
  206.               insymbol() won't be called here! */
  207.  if (sym != lparen)
  208.     _error(14);
  209.  else
  210.  {
  211.   do
  212.   {
  213.    insymbol();
  214.    make_sure_short(expr());
  215.    ndxcount++;
  216.   }
  217.   while ((sym == comma) && (ndxcount <= curr->dims));
  218.   
  219.   /* too few indices: comma expected (ndxcount should now be > curr->dims) */
  220.   if (ndxcount <= curr->dims) _error(16);  
  221.  
  222.   /* too many indices or syntax error */
  223.   if (sym != rparen) _error(9);  
  224.  }
  225. }
  226.   
  227. void get_abs_ndx(curr)
  228. SYM *curr;
  229. {
  230. /* calculate absolute pointer into array from multiple dimensions */
  231. int  i,ndx_mult=1;
  232. char mulbuf[40],srcbuf[40];
  233.  
  234.  gen("moveq","#0","d7");
  235.  
  236.  /* pop indices from stack one at a time */ 
  237.  for (i=curr->dims;i>=0;i--)
  238.  {
  239.   sprintf(mulbuf,"#%ld",ndx_mult);
  240.  
  241.   gen("move.w","(sp)+","d1");       
  242.   gen("ext.l","d1","  "); 
  243.   gen("move.l","d1","-(sp)");   /* push next index after coercing to long */
  244.   gen("move.l",mulbuf,"-(sp)"); /* push cumulative index */
  245.   gen("jsr","lmulu","  ");
  246.   gen("add.l","#8","sp");
  247.   
  248.   gen("add.l","d0","d7");  
  249.   ndx_mult *= curr->index[i];
  250.  }
  251.  
  252.  /* mutiply offset by data type size */
  253.  if (curr->type == stringtype)
  254.  {
  255.   /* multiply d7 (containing absolute index) by string element size */
  256.  
  257.   /* #string_element_size */
  258.   sprintf(srcbuf,"#%ld",curr->numconst.longnum);
  259.  
  260.   /* calculate absolute offset */  
  261.   gen("move.l","d7","-(sp)");
  262.   gen("move.l",srcbuf,"-(sp)");
  263.   gen("jsr","lmulu","  ");    /* d7*MAXSTRLEN */
  264.   gen("add.l","#8","sp");
  265.   gen("move.l","d0","d7");
  266.  }
  267.  else
  268.  if (curr->type == shorttype)
  269.     gen("lsl.l","#1","d7");  /* d7*2 */
  270.  else
  271.     /* long or single */
  272.     gen("lsl.l","#2","d7");  /* d7*4 */
  273.  
  274.  /* unsigned multiplication XREF */
  275.  enter_XREF("lmulu");
  276. }
  277.  
  278. void push_num_constant(typ,item)
  279. int typ;
  280. SYM *item;
  281. {
  282. /* push a numeric
  283.    constant onto 
  284.    the stack. 
  285. */
  286. char buf[40],numbuf[40];
  287.  
  288.  strcpy(numbuf,"#\0");
  289.  switch(typ)
  290.  {
  291.   case shorttype  : itoa(item->numconst.shortnum,buf,10); break;
  292.   case longtype   : ltoa(item->numconst.longnum,buf,10); break;
  293.   case singletype : sprintf(buf,"%lx",item->numconst.singlenum);
  294.                     strcat(numbuf,"$");
  295.               break;
  296.  }
  297.  
  298.  strcat(numbuf,buf);
  299.  
  300.  if (typ == shorttype)
  301.     gen("move.w",numbuf,"-(sp)");
  302.  else
  303.     gen("move.l",numbuf,"-(sp)");
  304. }
  305.  
  306. int push_struct(item)
  307. SYM *item;
  308. {
  309. /* push either the address of 
  310.    a structure variable or the
  311.    value of one of its members.
  312. */
  313. SYM    *structype;
  314. char   addrbuf[40],absbuf[40],numbuf[40];
  315. STRUCM *member;
  316. BOOL   found=FALSE;
  317. int    mbr_type=undefined;
  318.  
  319.  insymbol();
  320.  
  321.  if (sym == memberpointer)
  322.  {
  323.   /* push value of a member */
  324.   structype = item->other;  /* pointer to structure type definition */
  325.  
  326.   insymbol();
  327.  
  328.   if (sym != ident) 
  329.      _error(7);
  330.   else
  331.   {
  332.    /* does member exist? */
  333.    member = structype->structmem->next;
  334.    while ((member != NULL) && (!found)) 
  335.    {
  336.     if (strcmp(member->name,id) == 0)
  337.        found=TRUE;
  338.     else
  339.        member = member->next;
  340.    }
  341.    
  342.    /* dereference it? */
  343.    if (!found) 
  344.       _error(67);  /* not a member! */
  345.    else
  346.    {
  347.     /* save member type */
  348.     mbr_type = member->type;
  349.  
  350.     /* address of structure */
  351.     itoa(-1*item->address,addrbuf,10);
  352.     strcat(addrbuf,frame_ptr[lev]);
  353.  
  354.     if (item->shared && lev == ONE)
  355.     {
  356.        gen("movea.l",addrbuf,"a0");  /* struct variable address */
  357.        gen("movea.l","(a0)","a0");   /* start address of struct */        
  358.     }
  359.     else
  360.         gen("movea.l",addrbuf,"a0"); /* start address of struct */
  361.  
  362.     /* offset from struct start */ 
  363.     if (mbr_type != stringtype)
  364.     {
  365.      ltoa(member->offset,absbuf,10);
  366.      strcat(absbuf,"(a0)");
  367.     }
  368.  
  369.     /* push value */
  370.     if (mbr_type == bytetype)
  371.     {
  372.      gen("move.b",absbuf,"d0");
  373.      gen("ext.w","d0","  ");
  374.      gen("move.w","d0","-(sp)");
  375.      mbr_type=shorttype;              /* byte */
  376.     }
  377.     else
  378.     if (mbr_type == shorttype)
  379.        gen("move.w",absbuf,"-(sp)");  /* short */
  380.     else
  381.     if (mbr_type == stringtype)
  382.     {
  383.      sprintf(numbuf,"#%ld",member->offset);
  384.      gen("adda.l",numbuf,"a0");
  385.      gen("move.l","a0","-(sp)");  /* push string address */
  386.     }
  387.     else
  388.        gen("move.l",absbuf,"-(sp)");  /* long, single */ 
  389.    }
  390.   }
  391.   insymbol();
  392.   return(mbr_type);
  393.  }
  394.  else
  395.  {
  396.   /* push address of structure */
  397.   itoa(-1*item->address,addrbuf,10);
  398.   strcat(addrbuf,frame_ptr[lev]);
  399.  
  400.   if (item->shared && lev == ONE) 
  401.   {
  402.      gen("movea.l",addrbuf,"a0"); /* address of structure variable */
  403.      gen("move.l","(a0)","-(sp)");  /* start address of structure */
  404.   }
  405.   else
  406.       gen("move.l",addrbuf,"-(sp)");
  407.  
  408.   return(longtype);
  409.  }
  410. }
  411.  
  412. void change_id_type(newtype)
  413. int newtype;
  414. {
  415. int i,first,last;
  416.  
  417.  /* 
  418.  ** Change the data type of a range.
  419.  **
  420.  ** Note that "A-_" is acceptable
  421.  ** since ASC("_") > ASC("Z"). 
  422.  */
  423.  do
  424.  {
  425.   insymbol();
  426.   if (sym == ident) first=id[0]-'A'; else _error(7);
  427.   insymbol();
  428.   if (sym == minus)
  429.   {
  430.    /* range */
  431.    insymbol();
  432.    if (sym == ident) last=id[0]-'A'; else _error(7);
  433.    if (first > last) 
  434.           _error(31);
  435.    else
  436.        for (i=first;i<=last;i++) idtype[i]=newtype;
  437.    insymbol();
  438.   }
  439.   else
  440.   /* just a single one (letter or underscore) */
  441.   idtype[first]=newtype;
  442.  }
  443.  while (sym == comma);
  444. }
  445.  
  446. void gen_branch(branch,labname)
  447. char *branch,*labname;
  448. {
  449. char lablabel[MAXIDSIZE+1],destbuf[3];
  450.  
  451.  /* generate a jsr/jmp instruction */
  452.  
  453.  sprintf(lablabel,"%s:",labname);
  454.  
  455.  if (!exist(lablabel,label))
  456.     strcpy(destbuf,"* ");  /* for later check */
  457.  else
  458.     strcpy(destbuf,"  ");  /* label already defined */
  459.  
  460.  gen(branch,labname,destbuf);
  461. }
  462.  
  463. void assem()
  464. {
  465. /* 
  466. ** ASSEM..END ASSEM -- inline assembly code inclusion.
  467. */
  468.  
  469.  report_errors = FALSE;    /* suppress "unknown symbol" errors. */
  470.  
  471.  do
  472.  {
  473.   insymbol();
  474.  
  475.   /* generate code? */
  476.   if (sym == endofline && !end_of_source &&
  477.       lastsym != assemsym) gen(lastline,"  ","  ");  
  478.  }
  479.  while (sym != endsym && !end_of_source);
  480.  
  481.  insymbol();
  482.  if (sym != assemsym) _error(73);
  483.  else
  484.      insymbol();
  485.  
  486.  report_errors = TRUE;
  487. }
  488.  
  489. void parse_option_list()
  490. {
  491. char letter;
  492. BOOL activate;
  493. /* OPTION <switch>+|-[,<switch>+|-..] */
  494.  
  495.   do
  496.   {
  497.    insymbol();
  498.  
  499.    if (sym == ident && strlen(ut_id) == 1) 
  500.    {
  501.     letter=ut_id[0];
  502.  
  503.     insymbol();
  504.     if (sym == plus || sym == minus)
  505.     {
  506.      switch(sym) 
  507.      {
  508.       case plus  : activate=TRUE; break;
  509.       case minus : activate=FALSE; break; 
  510.      }
  511.  
  512.      switch(letter)
  513.      {
  514.       case 'b' : break_opt=activate; break;
  515.       case 'c' : asm_comments=activate; break;
  516.       case 'E' : if (activate && !error_log)
  517.              {
  518.            err_log = fopen("ace.err","w");
  519.           if (err_log == NULL) 
  520.              puts("Unable to open error log: ace.err!");
  521.           else
  522.               error_log=TRUE;
  523.              }
  524.          else
  525.          if (!activate && error_log)
  526.          {
  527.           if (err_log) 
  528.           { 
  529.            fclose(err_log);
  530.            err_log=NULL;
  531.            error_log=FALSE;
  532.           }
  533.           else
  534.               puts("Error log: ace.err not open!");
  535.          }
  536.              break;
  537.       case 'i' : make_icon=activate; break;
  538.       case 'l' : list_source=activate; break;
  539.       case 'm' : module_opt=activate; break;
  540.       case 'O' : optimise_opt=activate; break;
  541.       case 'w' : wdw_close_opt=activate; break;
  542.  
  543.       default  : _error(74); break;
  544.      }
  545.     }
  546.     else _error(74);
  547.    }
  548.    else _error(74);  /* compiler directive expected */
  549.  
  550.    insymbol();
  551.   }
  552.   while (sym == comma);
  553. }
  554.  
  555. void MsgBox()
  556. {
  557. /*
  558. ** MsgBox _statement_.
  559. **
  560. **    MSGBOX <message>,<button-text>
  561. **
  562. ** See also basfun.c for MsgBox *function*. 
  563. */
  564.  
  565.     insymbol();
  566.     
  567.     if (expr() != stringtype)     /* message */
  568.         _error(4);
  569.     else
  570.     {
  571.            if (sym != comma)
  572.                   _error(16);
  573.            else
  574.            {
  575.                 insymbol();
  576.                 if (expr() != stringtype)  /* response text */
  577.                 _error(4);
  578.             else
  579.                 {
  580.                 /* no second button! (pass NULL) */
  581.                      gen("move.l","#0","-(sp)");
  582.              
  583.                     /* call the function */
  584.                     gen("jsr","_sysrequest","  ");
  585.                     gen("add.l","#12","sp");
  586.                     enter_XREF("_sysrequest");
  587.                     enter_XREF("_IntuitionBase");
  588.                }
  589.           }
  590.      }
  591. }
  592.