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

  1. /* << ACE >>
  2.  
  3.    -- Amiga BASIC Compiler --
  4.  
  5.    ** Parser: statement code **
  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,12th,13th,27th-29th December 1992,
  33.        4th,6th,31st January 1993,
  34.        6th,12th,13th,15th,18th,28th February 1993,
  35.        1st,7th,24th March 1993,
  36.        9th May 1993,
  37.        12th,13th,30th June 1993,
  38.        1st July 1993,
  39.        5th,25th September 1993 
  40.        26th October 1993,
  41.        1st,2nd,8th,9th November 1993,
  42.        27th December 1993,
  43.        2nd,5th January 1994,
  44.        6th,15th,16th,27th February 1994,
  45.        4th April 1994,
  46.        14th,15th May 1994,
  47.        10th July 1994,
  48.        7th August 1994,
  49.        3rd,8th,17th September 1994,
  50.        5th March 1995,
  51.        8th August 1995,
  52.        10th March 1996,
  53.        11th,22nd June 1996,
  54.        4th September 1996
  55. */
  56.  
  57. #include "acedef.h"
  58.  
  59. /* locals */
  60. static    char     *frame_ptr[] = { "(a4)","(a5)" };
  61.  
  62. /* externals */
  63. extern    int    sym;
  64. extern    int    lastsym;
  65. extern    int    obj;
  66. extern    int    typ;
  67. extern    int     lev;
  68. extern    char    ch;
  69. extern    char       id[MAXIDSIZE]; 
  70. extern    char       ut_id[MAXIDSIZE];
  71. extern    SYM    *curr_item;
  72. extern    CODE    *curr_code;
  73. extern    CODE    *exit_for_cx;
  74.  
  75. extern    ACELIBS acelib[NUMACELIBS];
  76.  
  77. extern    char     librarybase[MAXIDSIZE+6];
  78. extern    BOOL     have_lparen;
  79. extern    BOOL     have_equal;
  80. extern    BOOL     restore_a4;
  81. extern    BOOL     restore_a5;
  82. extern    BOOL    narratorused;
  83. extern    BOOL    end_of_source;
  84. extern    char     exit_sub_name[80];
  85.  
  86. /* ------*/
  87. /* sound */
  88. /* ------*/
  89.  
  90. void sound()
  91. {
  92. /* make a tone of given period, duration and volume through 
  93.    the specified channel */
  94.  
  95. BOOL voice=FALSE;
  96. BOOL volume=FALSE;
  97.  
  98.  insymbol();
  99.  make_sure_short(expr());  /* period (short) 0..32767 */ 
  100.  
  101.  if (sym != comma) _error(16);
  102.  else
  103.  {
  104.   insymbol();
  105.   gen_Flt(expr());  /* duration (single) 0..77 */
  106.  }
  107.  
  108.  if (sym == comma)
  109.  {
  110.   insymbol();
  111.   if (sym != comma)  /* if comma -> skip volume */
  112.   {
  113.    make_sure_short(expr());  /* volume (short) 0..64 */
  114.    volume=TRUE;
  115.   }
  116.   else gen("moveq","#64","d2");  /* default volume = 64 */
  117.  }
  118.  else gen("moveq","#64","d2");  /* default volume = 64 */
  119.  
  120.  if (sym == comma)
  121.  {
  122.   insymbol();
  123.   make_sure_short(expr());  /* voice (short) 0..3 */
  124.   voice=TRUE;
  125.  }
  126.  else gen("moveq","#0","d3");  /* default voice = 0 */
  127.  
  128.  if (voice)  gen("move.w","(sp)+","d3");  /* pop voice */
  129.  if (volume) gen("move.w","(sp)+","d2");  /* pop volume */
  130.  
  131.  gen("move.l","(sp)+","d1");  /* pop duration */
  132.  gen("move.w","(sp)+","d0");  /* pop period */
  133.  
  134.  gen("jsr","_sound","  ");
  135.  enter_XREF("_sound");
  136.  enter_XREF("_DOSBase");
  137.  enter_XREF("_MathBase");
  138. }   
  139.  
  140. void handle_label(label_name)
  141. char *label_name;
  142. {
  143. int  oldlevel;
  144. char label_lab[50];
  145.  
  146.  /* create a new label */
  147.  
  148.     oldlevel=lev;  /* make all labels global -> level ZERO */ 
  149.     lev=ZERO;
  150.  
  151.     /* does label already exist? */
  152.     strcpy(label_lab,label_name);
  153.     strcat(label_lab,":\0");
  154.  
  155.     if (!exist(label_lab,label)) 
  156.     { 
  157.      /* no, so create it */
  158.      enter(label_lab,notype,label,0); 
  159.      gen(label_lab,"  ","  "); 
  160.      turn_event_off(label_name);  /* see event.c */
  161.     }
  162.     else _error(6);  /* duplicate label */
  163.     lev=oldlevel;
  164. }
  165.  
  166. /*-----------*/
  167. /* statement */
  168. /*-----------*/
  169.  
  170. void statement()
  171. {
  172. char  buf[50],destbuf[3],idholder[50],addrbuf[80],sub_name[80],numbuf[40];
  173. char  func_name[MAXIDSIZE],func_address[MAXIDSIZE+9];
  174. char  ext_name[MAXIDSIZE+1];
  175. int   commandsym;
  176. int   oldobj,oldtyp,stype;
  177. int   statetype;
  178. int   oldlevel;
  179. SYM   *func_item,*sub_item,*mc_item,*inc_item,*dec_item;
  180. BYTE  libnum;
  181. BOOL  need_symbol=TRUE;
  182. int   i;
  183. SHORT popcount;
  184.  
  185.  /* data object assignment (variable, subprogram or array element), 
  186.     label declaration or subprogram call without CALL? */
  187.  if (sym == ident)
  188.  {
  189.   /* make subprogram name */
  190.   strcpy(sub_name,"_SUB_");
  191.   strcat(sub_name,id);
  192.  
  193.   /* store id in case it's a function */
  194.   strcpy(func_name,id);
  195.   remove_qualifier(func_name);
  196.  
  197.   /* make external variable name 
  198.      by removing qualifier and 
  199.      adding an underscore prefix 
  200.      if one is not present. 
  201.   */
  202.   strcpy(buf,ut_id);
  203.   remove_qualifier(buf);
  204.   if (buf[0] != '_')
  205.   {
  206.    strcpy(ext_name,"_\0");
  207.    strcat(ext_name,buf);
  208.   }
  209.   else 
  210.       strcpy(ext_name,buf);
  211.  
  212.   /* assignment? */
  213.   strcpy(idholder,id);  /* save info for label or assign() */
  214.   oldobj=obj;
  215.   oldtyp=typ;
  216.  
  217.   insymbol();
  218.   
  219.   /* a variable/subprogram assignment or an array element assignment? */
  220.   if ((sym == equal) || (sym == memberpointer) || ((sym == lparen) 
  221.       && (!exist(sub_name,subprogram)) && (!exist(func_name,function))
  222.       && (!exist(ext_name,extfunc)))) 
  223.   {
  224.      strcpy(id,idholder);  /* restore info */
  225.      obj=oldobj;
  226.      typ=oldtyp;
  227.      if (sym == equal)  have_equal=TRUE;
  228.      if (sym == lparen) 
  229.          if (!exist(id,array)) { _error(71); insymbol(); return; } 
  230.      else
  231.      have_lparen=TRUE;
  232.      assign(); 
  233.      have_equal=FALSE;
  234.      have_lparen=FALSE;
  235.   }
  236.   else
  237.   /* implicit subprogram or function call (ie: without CALL command)? */
  238.   if (exist(func_name,function) || exist(sub_name,subprogram) ||
  239.       exist(ext_name,extfunc)) 
  240.   {
  241.     sub_item=curr_item; /* - store curr_item because the next call to exist()
  242.                  will clobber it! (for use by SUB call)
  243.                - if sub_item points to a function item,
  244.                  it makes no difference since func_item
  245.                  will be used instead. */
  246.     check_for_event();
  247.  
  248.     if (exist(ext_name,extfunc))
  249.     {
  250.      /* call external function */
  251.      call_external_function(ext_name,&need_symbol);
  252.      if (need_symbol) insymbol();
  253.     }
  254.     else
  255.     if (exist(func_name,function)) 
  256.     {
  257.      /* call shared library function */
  258.      func_item=curr_item;
  259.      if (func_item->no_of_params != 0)
  260.         { load_func_params(func_item); insymbol(); }
  261.  
  262.      /* call the function */
  263.      if ((libnum=check_for_ace_lib(func_item->libname)) == NEGATIVE) 
  264.         make_library_base(func_item->libname);
  265.      else
  266.         strcpy(librarybase,acelib[libnum].base);
  267.      gen("move.l",librarybase,"a6");
  268.      itoa(func_item->address,func_address,10);
  269.      strcat(func_address,"(a6)");
  270.      gen("jsr",func_address,"  ");
  271.      if (restore_a4) { gen("move.l","_a4_temp","a4"); restore_a4=FALSE; }
  272.      if (restore_a5) { gen("move.l","_a5_temp","a5"); restore_a5=FALSE; }
  273.     }
  274.     else
  275.     {
  276.       /* call SUB */
  277.       if (sub_item->no_of_params != 0) 
  278.          { load_params(sub_item); insymbol(); }
  279.       gen("jsr",sub_name,"  ");
  280.     }
  281.   }
  282.   else
  283.   {
  284.    /* label? */
  285.    if (sym == colon)
  286.         handle_label(idholder);
  287.    else 
  288.        _error(24);   /* colon expected */
  289.    insymbol();
  290.   }
  291.  }
  292.  else
  293.  /* line number? */
  294.  if (sym == shortconst || sym == longconst)
  295.  {
  296.   make_label_from_linenum(sym,idholder);
  297.   handle_label(idholder);
  298.   insymbol();
  299.  }
  300.  else
  301.  /* assign with LET ? */ 
  302.  if (sym == letsym) 
  303.  { 
  304.   insymbol();
  305.  
  306.   if (sym == ident)
  307.   {
  308.    strcpy(idholder,id);  /* save info for assign() */
  309.    oldobj=obj;
  310.    oldtyp=typ;
  311.  
  312.    insymbol();
  313.  
  314.    if ((sym == equal) || (sym == lparen) || (sym == memberpointer))
  315.    {
  316.      strcpy(id,idholder);  /* restore info */
  317.      obj=oldobj;
  318.      typ=oldtyp;
  319.      if (sym == equal) have_equal=TRUE;
  320.      if (sym == lparen) have_lparen=TRUE;
  321.      assign(); 
  322.      have_equal=FALSE;
  323.      have_lparen=FALSE;
  324.    }
  325.   }
  326.   else _error(7); 
  327.  }
  328.  else
  329.  /* multi-statement? */
  330.  if (sym == colon)
  331.  {
  332.   while (sym == colon) { insymbol(); statement(); }
  333.  }
  334.  else
  335.  /* assem */
  336.  if (sym == assemsym) assem();
  337.  else
  338.  /* area */
  339.  if (sym == areasym) area();
  340.  else
  341.  /* areafill */
  342.  if (sym == areafillsym) areafill();
  343.  else
  344.  /* back */
  345.  if (sym == backsym)
  346.  {
  347.   insymbol();
  348.   gen_Flt(expr());
  349.   gen("move.l","(sp)+","d0");
  350.   gen("jsr","_back","  ");
  351.   enter_XREF("_back");
  352.   enter_XREF("_MathBase");
  353.   enter_XREF("_MathTransBase");
  354.   enter_XREF("_GfxBase"); 
  355.  }
  356.  else
  357.  /* beep */
  358.  if (sym == beepsym) 
  359.  { 
  360.   gen("jsr","_beep","  ");
  361.   enter_XREF("_beep");
  362.   enter_XREF("_MathBase");  /* _sound needs mathffp.library */
  363.   insymbol();
  364.  }  
  365.  else
  366.  /* bevelbox */
  367.  if (sym == bevelboxsym) bevel_box();
  368.  else
  369.  /* event trapping activation/deactivation? */
  370.  if ((sym == breaksym) || (sym == mousesym) || 
  371.      (sym == timersym) || (sym == errorsym)) 
  372.     change_event_trapping_status(sym);
  373.  else
  374.  /* block */
  375.  if (sym == blocksym) block_statement();
  376.  else
  377.  /* call */
  378.  if (sym == callsym)
  379.  {
  380.   check_for_event();
  381.  
  382.   insymbol();
  383.   if (sym != ident) 
  384.      _error(32);
  385.   else
  386.   {
  387.    /* function? */
  388.    strcpy(func_name,id);
  389.    remove_qualifier(func_name);
  390.  
  391.    if (exist(func_name,function)) 
  392.    { 
  393.     func_item=curr_item;
  394.     if (func_item->no_of_params != 0)
  395.     { insymbol(); load_func_params(func_item); }
  396.     /* call it */
  397.     if ((libnum=check_for_ace_lib(func_item->libname)) == NEGATIVE) 
  398.        make_library_base(func_item->libname);
  399.     else
  400.        strcpy(librarybase,acelib[libnum].base);
  401.     gen("move.l",librarybase,"a6");
  402.     itoa(func_item->address,func_address,10);
  403.     strcat(func_address,"(a6)");
  404.     gen("jsr",func_address,"  ");
  405.     if (restore_a4) { gen("move.l","_a4_temp","a4"); restore_a4=FALSE; }
  406.     if (restore_a5) { gen("move.l","_a5_temp","a5"); restore_a5=FALSE; }
  407.    }
  408.    else
  409.    {
  410.     /* subprogram, machine code subroutine or external function? */
  411.     strcpy(sub_name,"_SUB_");
  412.     strcat(sub_name,id);
  413.  
  414.     if (!exist(sub_name,subprogram)) 
  415.     {
  416.      /* make external variable name 
  417.         by removing qualifier and 
  418.         adding an underscore prefix 
  419.         if one is not present. 
  420.      */
  421.      strcpy(buf,ut_id);
  422.      remove_qualifier(buf);
  423.      if (buf[0] != '_')
  424.      {
  425.       strcpy(ext_name,"_\0");
  426.       strcat(ext_name,buf);
  427.      }
  428.      else 
  429.          strcpy(ext_name,buf);
  430.  
  431.       if (exist(ext_name,extfunc))
  432.       { 
  433.        /* external function? */
  434.        insymbol();
  435.        call_external_function(ext_name,&need_symbol);
  436.       }
  437.      else
  438.      { 
  439.       /* machine code subroutine? */
  440.       if (exist(id,variable) && (curr_item->type == longtype))
  441.       {
  442.        mc_item=curr_item;
  443.        insymbol();
  444.        if (sym == lparen) { load_mc_params(mc_item); need_symbol=TRUE; } 
  445.        else 
  446.            { mc_item->no_of_params=0; need_symbol=FALSE; }
  447.  
  448.        /* call routine */
  449.        itoa(-1*mc_item->address,addrbuf,10);
  450.        strcat(addrbuf,frame_ptr[lev]);
  451.        gen("move.l",addrbuf,"a0");
  452.        gen("jsr","(a0)","  ");
  453.        /* pop parameters? */
  454.        if (mc_item->no_of_params != 0)
  455.        {
  456.          popcount=0;
  457.          for (i=0;i<mc_item->no_of_params;i++) 
  458.          {
  459.           if (mc_item->p_type[i] == shorttype) 
  460.         popcount += 2;
  461.           else
  462.         popcount += 4;
  463.          }
  464.         /* add popcount to sp */
  465.         strcpy(buf,"#\0");
  466.         itoa(popcount,numbuf,10);
  467.         strcat(buf,numbuf);
  468.         gen("add.l",buf,"sp");
  469.        }
  470.       }
  471.       else _error(37); /* undeclared subprogram */
  472.      }
  473.     }
  474.     else
  475.        {
  476.         /* user-defined subprogram */
  477.         if (curr_item->no_of_params != 0) 
  478.            { insymbol(); load_params(curr_item); }
  479.         gen("jsr",sub_name,"  ");
  480.        }
  481.    }
  482.   }
  483.   if (need_symbol) insymbol();
  484.  }
  485.  else
  486.  /* case */
  487.  if (sym == casesym) { check_for_event(); case_statement(); }
  488.  else
  489.  /* chdir */
  490.  if (sym == chdirsym) chdir();
  491.  else
  492.  /* circle */
  493.  if (sym == circlesym) circle();
  494.  else
  495.  /* clear */
  496.  if (sym == clearsym) 
  497.  { 
  498.     insymbol(); 
  499.     if (sym == allocsym) 
  500.        { gen("jsr","_clear_alloc","  "); enter_XREF("_clear_alloc"); }
  501.     insymbol();
  502.  }
  503.  else
  504.  /* close */
  505.  if (sym == closesym) close_a_file();
  506.  else
  507.  /* cls */
  508.  if (sym == clssym) 
  509.  { 
  510.   gen("jsr","_cls","  "); 
  511.   enter_XREF("_cls");
  512.   enter_XREF("_DOSBase"); /* need dos library */
  513.   insymbol(); 
  514.  }
  515.  else
  516.  /* color */
  517.  if (sym == colorsym) color();
  518.  else
  519.  /* common */
  520.  if (sym == commonsym) define_common_or_global_variable(sym);
  521.  else
  522.  /* const */
  523.  if (sym == constsym) define_constant();
  524.  else
  525.  /* data */
  526.  if (sym == datasym) get_data();
  527.  else
  528.  /* declare */
  529.  if (sym == declaresym) declare();
  530.  else
  531.  /* defint,deflng,defsng,defdbl,defstr -> global effects */
  532.  if (sym == defintsym) change_id_type(shorttype);
  533.  else
  534.  if (sym == deflngsym) change_id_type(longtype);
  535.  else
  536.  if (sym == defsngsym) change_id_type(singletype);
  537.  else
  538.  if (sym == defdblsym) change_id_type(singletype);
  539.  else
  540.  if (sym == defstrsym) change_id_type(stringtype);
  541.  else
  542.  /* dim */
  543.  if (sym == dimsym) dim();
  544.  else
  545.  /* end & stop */
  546.  if ((sym == endsym) || (sym == stopsym))
  547.  {
  548.   gen("jmp","_EXIT_PROG","  ");
  549.   insymbol();
  550.  }
  551.  else
  552.  /* exit (ie: EXIT SUB/FOR) */
  553.  if (sym == exitsym)
  554.  { 
  555.   insymbol();
  556.  
  557.   if (sym == forsym)
  558.   {
  559.       /* EXIT FOR */
  560.     gen("nop","  ","  ");
  561.     exit_for_cx = curr_code;
  562.     insymbol();
  563.   }
  564.   else
  565.   if (lev == ONE)
  566.   {  
  567.     /* EXIT SUB */
  568.        if (sym != subsym) 
  569.              _error(35);
  570.        else
  571.              gen("jmp",exit_sub_name,"  ");
  572.  
  573.        insymbol();
  574.   }
  575.   else
  576.      {
  577.           _error(36); /* can only use EXIT SUB in a subprogram! */
  578.           insymbol();
  579.      }
  580.  }
  581.  else
  582.  /* external */
  583.  if (sym == externalsym) define_external_object();
  584.  else
  585.  /* files */
  586.  if (sym == filessym) files();
  587.  else
  588.  /* fix */
  589.  if (sym == fixsym) 
  590.  {
  591.   insymbol();
  592.   if (make_integer(expr()) != longtype) make_long();
  593.   gen("move.l","(sp)+","d0");
  594.   gen("jsr","_fix","  ");
  595.   enter_XREF("_fix");
  596.  }
  597.  else
  598.  /* font */
  599.  if (sym == fontsym) text_font();
  600.  else
  601.  /* for.. */
  602.  if (sym == forsym) for_statement();
  603.  else
  604.  /* forward */
  605.  if (sym == forwardsym)
  606.  {
  607.   insymbol();
  608.   gen_Flt(expr());
  609.   gen("move.l","(sp)+","d0");
  610.   gen("jsr","_forward","  ");
  611.   enter_XREF("_forward");
  612.   enter_XREF("_MathBase");
  613.   enter_XREF("_MathTransBase");
  614.   enter_XREF("_GfxBase"); 
  615.  }  
  616.  else
  617.  /* gadget */
  618.  if (sym == gadgetsym) gadget();
  619.  else
  620.  /* get */
  621.  if (sym == getsym)
  622.  {
  623.      insymbol();
  624.     if (sym == lparen) 
  625.     {
  626.         /* Graphics GET */
  627.     }
  628.     else
  629.     {
  630.         /* Random File GET */
  631.         random_file_get();
  632.     }
  633.  }    
  634.  else
  635.  /* global */
  636.  if (sym == globalsym) define_common_or_global_variable(sym);
  637.  else
  638.  /* goto or gosub */
  639.  if ((sym == gotosym) || (sym == gosubsym))
  640.  {
  641.   check_for_event();
  642.   oldlevel=lev; /* labels are defined at level ZERO only */
  643.   lev=ZERO;
  644.   commandsym=sym;
  645.   insymbol();
  646.   if (sym == ident || sym == shortconst || sym==longconst)
  647.   {
  648.    if (sym != ident) make_label_from_linenum(sym,id);   
  649.    strcpy(buf,id);
  650.    strcat(buf,":\0");
  651.    if (!exist(buf,label)) 
  652.       strcpy(destbuf,"* "); /* mark for later check */
  653.    else 
  654.       strcpy(destbuf,"  ");
  655.  
  656.    /* generate approriate branch */
  657.    switch(commandsym)
  658.    {
  659.     case gotosym  : gen("jmp",id,destbuf); break;
  660.     case gosubsym : gen("jsr",id,destbuf); break;
  661.    }
  662.   }
  663.   lev=oldlevel;
  664.   insymbol(); 
  665.  }
  666.  else
  667.  /* home */
  668.  if (sym == homesym)
  669.  {
  670.   gen("jsr","_home","  ");
  671.   enter_XREF("_home");
  672.   enter_XREF("_GfxBase");
  673.   insymbol();
  674.  }
  675.  else
  676.  /* if...then...else... */
  677.  if (sym == ifsym) { check_for_event(); if_statement(); }
  678.  else
  679.  /* IFF */
  680.  if (sym == iffsym) iff();
  681.  else
  682.  /* kill */
  683.  if (sym == killsym) kill();
  684.  else
  685.  /* input */
  686.  if (sym == inputsym) 
  687.  { 
  688.   check_for_event(); 
  689.   insymbol();
  690.   if (sym == hash) input_from_file(); else input(); 
  691.  }
  692.  else
  693.  /* library */
  694.  if (sym == librarysym) library();
  695.  else
  696.  /* line or line input */
  697.  if (sym == linesym) 
  698.  {
  699.   insymbol();
  700.   if (sym == inputsym) line_input(); else draw_line();
  701.  }
  702.  else
  703.  /* locate */
  704.  if (sym == locatesym)
  705.  {
  706.   insymbol();
  707.   make_sure_short(expr());  /* ROW */
  708.  
  709.   if (sym == comma)
  710.   {
  711.    insymbol();
  712.    make_sure_short(expr());
  713.   }
  714.   else gen("move.w","#1","-(sp)");  /* COLUMN */
  715.  
  716.   gen("move.w","(sp)+","d1");  /* pop COLUMN */
  717.   gen("move.w","(sp)+","d0");  /* pop ROW */  
  718.  
  719.   gen("jsr","_locate","  ");
  720.   enter_XREF("_locate");
  721.   enter_XREF("_DOSBase");
  722.  }
  723.  else
  724.  /* longint */
  725.  if (sym == longintsym || sym == addresssym) declare_variable(longtype);
  726.  else
  727.  /* menu */
  728.  if (sym == menusym) menu();
  729.  else
  730.  /* message */
  731.  if (sym == messagesym) message();
  732.  else
  733.  /* msgbox */
  734.  if (sym == msgboxsym) MsgBox();
  735.  else
  736.  /* name */
  737.  if (sym == namesym) rename();
  738.  else
  739.  /* next */
  740.  if ((sym == nextsym) && (lastsym == colon)) 
  741.  {
  742.   lastsym=undefined;
  743.   return;  /* eg: for i=1 to 10:next */
  744.  }
  745.  else
  746.  /* on <event> | <integer-expression> */
  747.  if (sym == onsym) 
  748.  {
  749.   insymbol();
  750.   if (sym==breaksym || sym==mousesym || sym==menusym || 
  751.       sym==timersym || sym==errorsym || sym==windowsym || 
  752.       sym==gadgetsym)
  753.      get_event_trap_label();
  754.   else
  755.      on_branch();    
  756.  }
  757.  else
  758.  /* open */
  759.  if (sym == opensym) open_a_file();
  760.  else
  761.  /* option */
  762.  if (sym == optionsym) parse_option_list();
  763.  else
  764.  /* paint */
  765.  if (sym == paintsym) paint();
  766.  else
  767.  /* palette */
  768.  if (sym == palettesym)
  769.  {
  770.    insymbol();
  771.    make_sure_short(expr()); /* color-id */
  772.    if (sym != comma) _error(16);
  773.    else
  774.    {
  775.     insymbol();
  776.     gen_Flt(expr()); /* red */
  777.     if (sym != comma) _error(16);
  778.     else
  779.     {
  780.      insymbol();
  781.      gen_Flt(expr()); /* green */
  782.      if (sym != comma) _error(16);
  783.      else
  784.      {
  785.        insymbol();
  786.        gen_Flt(expr()); /* blue */
  787.        
  788.        /* pop parameters */
  789.        gen("move.l","(sp)+","d3"); /* blue */
  790.        gen("move.l","(sp)+","d2"); /* green */
  791.        gen("move.l","(sp)+","d1"); /* red */
  792.        gen("move.w","(sp)+","d0"); /* color-id  (0-31) */
  793.  
  794.        /* open the screen */
  795.        gen("jsr","_palette","  ");
  796.        enter_XREF("_palette");
  797.        enter_XREF("_GfxBase");
  798.        enter_XREF("_MathBase"); /* must convert 0-1 values to bytes: 0-15 */
  799.      }
  800.     }
  801.    }
  802.  }
  803.  else
  804.  /* pattern */
  805.  if (sym == patternsym) pattern();
  806.  else
  807.  /* pendown */
  808.  if (sym == pendownsym)
  809.  {
  810.   gen("jsr","_pendown","  ");
  811.   enter_XREF("_pendown");
  812.   insymbol();
  813.  }
  814.  else
  815.  /* penup */
  816.  if (sym == penupsym)
  817.  {
  818.   gen("jsr","_penup","  ");
  819.   enter_XREF("_penup");
  820.   insymbol();
  821.  }
  822.  else
  823.  /* poke */
  824.  if (sym == pokesym) poke();
  825.  else
  826.  /* pokew */
  827.  if (sym == pokewsym) pokew();
  828.  else
  829.  /* pokel */
  830.  if (sym == pokelsym) pokel();
  831.  else
  832.  /* print */
  833.  if ((sym == printsym) || (sym == question)) 
  834.  { 
  835.   check_for_event(); 
  836.   print_statement(); 
  837.   if (sym == hash && (lastsym == printsym || lastsym == question)) 
  838.      print_to_file();
  839.  }
  840.  else
  841.  /* prints */
  842.  if (sym == printssym)
  843.     { check_for_event(); prints_statement(); }    
  844.  else
  845.  /* pset */
  846.  if (sym == psetsym) pset(); 
  847.  else
  848.  /* put */
  849.  if (sym == putsym)
  850.  {
  851.      insymbol();
  852.     if (sym == stepsym || sym == lparen) 
  853.     {
  854.         /* Graphics PUT */
  855.     }
  856.     else
  857.     {
  858.         /* Random File PUT */
  859.         random_file_put();
  860.     }
  861.  }    
  862.  else
  863.  /* read */
  864.  if (sym == readsym) { check_for_event(); read_data(); }
  865.  else
  866.  /* rem */
  867.  if (sym == remsym)
  868.  {
  869.   while ((sym != endofline) && (!end_of_source)) nextch();
  870.   insymbol();
  871.  }
  872.  else
  873.  /* randomize */
  874.  if (sym == randomizesym)
  875.  {
  876.   insymbol();
  877.   statetype = expr();
  878.   if ((statetype = make_integer(statetype)) == notype) _error(4);
  879.   if (statetype == shorttype) make_long();
  880.   gen("move.l","(sp)+","d0");
  881.   gen("jsr","_randomise","  ");
  882.   enter_XREF("_randomise");
  883.   enter_XREF("_MathBase");
  884.  }
  885.  else
  886.  /* repeat */
  887.  if (sym == repeatsym) repeat_statement();
  888.  else
  889.  /* restore */
  890.  if (sym == restoresym) { gen("move.l","#_BASICdata","_dataptr"); insymbol(); }
  891.  else
  892.  /* return */
  893.  if (sym == returnsym)
  894.  {
  895.   check_for_event();
  896.   gen("rts","  ","  ");
  897.   insymbol();
  898.  }
  899.  else
  900.  /* say */
  901.  if (sym == saysym)
  902.  {
  903.   insymbol();
  904.   if (expr() != stringtype) _error(4);  /* phoneme string on stack */
  905.  
  906.   if (sym == comma)
  907.   {
  908.    insymbol();
  909.    if ((sym == ident) && (obj == variable)) 
  910.    {
  911.     if (!exist(id,array)) _error(28); 
  912.     else
  913.         if (curr_item->type != shorttype) _error(28); 
  914.         else
  915.            {
  916.         /* get address of array from stack frame */
  917.             itoa(-1*curr_item->address,addrbuf,10);
  918.             strcat(addrbuf,frame_ptr[lev]);
  919.         gen("move.l",addrbuf,"-(sp)"); /* push address of mode-array */
  920.         /* SIZE of array not checked here! (must be >= 9 elements) */
  921.            } 
  922.    insymbol();
  923.    }
  924.    else _error(28); 
  925.   }
  926.   else gen("move.l","#0","-(sp)");  /* no mode-array -> push NULL */
  927.  
  928.   gen("jsr","_say","  ");
  929.   gen("addq","#8","sp");  /* pop two parameters */
  930.   enter_XREF("_say");
  931.   enter_XREF("_cleanup_async_speech");
  932.   narratorused=TRUE;
  933.  }
  934.  else
  935.  /* screen */
  936.  if (sym == screensym) { screen(); check_for_event(); }
  937.  else
  938.  if (sym == scrollsym) scroll();
  939.  else
  940.  /* serial command */
  941.  if (sym == serialsym) { check_for_event(); serial_command(); }
  942.  else
  943.  /* setheading */
  944.  if (sym == setheadingsym)
  945.  {
  946.   insymbol();
  947.   make_sure_short(expr());
  948.   gen("move.w","(sp)+","d0");
  949.   gen("jsr","_setheading","  ");
  950.   enter_XREF("_setheading");
  951.  }
  952.  else
  953.  /* setxy */
  954.  if (sym == setxysym)
  955.  {
  956.   insymbol();
  957.   make_sure_short(expr()); /* x */
  958.   if (sym != comma) _error(16);
  959.   else
  960.   {
  961.    insymbol();
  962.    make_sure_short(expr()); /* y */
  963.    /* pop operands */
  964.    gen("move.w","(sp)+","d1"); /* y */
  965.    gen("move.w","(sp)+","d0"); /* x */
  966.    gen("jsr","_setxy","  ");
  967.    enter_XREF("_setxy");
  968.    enter_XREF("_GfxBase");
  969.   }
  970.  }
  971.  else
  972.  /* shared */
  973.  if (sym == sharedsym && lev == ZERO) { _error(69); insymbol(); }
  974.  else
  975.  /* shortint */
  976.  if (sym == shortintsym) declare_variable(shorttype);
  977.  else
  978.  /* single */
  979.  if (sym == singlesym) declare_variable(singletype);
  980.  else
  981.  /* sleep */
  982.  if (sym == sleepsym) 
  983.  {
  984.     insymbol();
  985.  
  986.     if (sym != forsym)
  987.     { 
  988.       /* SLEEP */
  989.       gen("jsr","_sleep","  "); enter_XREF("_sleep");
  990.     }
  991.     else
  992.     { 
  993.       /* SLEEP FOR <seconds> */ 
  994.       insymbol();
  995.       stype = expr();
  996.       if (stype == stringtype) _error(4);
  997.       else
  998.       {
  999.         gen_Flt(stype); 
  1000.           gen("jsr","_sleep_for_secs","  "); gen("addq","#4","sp");
  1001.           enter_XREF("_sleep_for_secs"); enter_XREF("_MathBase");
  1002.       }
  1003.     }
  1004.  }
  1005.  else
  1006.  /* string */
  1007.  if (sym == stringsym) declare_variable(stringtype);
  1008.  else
  1009.  /* sound */
  1010.  if (sym == soundsym) sound();
  1011.  else
  1012.  /* struct */
  1013.  if (sym == structsym) define_structure();
  1014.  else
  1015.  /* style */
  1016.  if (sym == stylesym) text_style();
  1017.  else
  1018.  /* swap */
  1019.  if (sym == swapsym) swap();
  1020.  else
  1021.  /* system */
  1022.  if (sym == systemsym)
  1023.  {
  1024.   insymbol();
  1025.   stype = make_integer(expr());
  1026.   if (stype == shorttype || stype == longtype)
  1027.   {
  1028.      /* SYSTEM returncode */
  1029.      if (stype == shorttype) make_long()  ; /* get short integer exit value */
  1030.      gen("move.l","(sp)+","_returncode");
  1031.      gen("jmp","_EXIT_PROG","  ");
  1032.      enter_XREF("_returncode");
  1033.   }
  1034.   else
  1035.   {
  1036.      /* SYSTEM command-string */
  1037.      gen("jsr","_system_call","  ");
  1038.      gen("addq","#4","sp");
  1039.      enter_XREF("_system_call");
  1040.   }
  1041.  }
  1042.  else
  1043.  /* turn */
  1044.  if (sym == turnsym)
  1045.  {
  1046.   insymbol();
  1047.   make_sure_short(expr());
  1048.   gen("move.w","(sp)+","d0");
  1049.   gen("jsr","_turn","  ");
  1050.   enter_XREF("_turn");
  1051.  }    
  1052.  else
  1053.  /* turnleft */
  1054.  if (sym == turnleftsym)
  1055.  {
  1056.   insymbol();
  1057.   make_sure_short(expr());
  1058.   gen("move.w","(sp)+","d0");
  1059.   gen("jsr","_turnleft","  ");
  1060.   enter_XREF("_turnleft");
  1061.  }    
  1062.  else
  1063.  /* turnright */
  1064.  if (sym == turnrightsym)
  1065.  {
  1066.   insymbol();
  1067.   make_sure_short(expr());
  1068.   gen("move.w","(sp)+","d0");
  1069.   gen("jsr","_turnright","  ");
  1070.   enter_XREF("_turnright");
  1071.  }    
  1072.  else
  1073.  /* until */
  1074.  if ((sym == untilsym) && (lastsym == colon)) 
  1075.  {
  1076.   lastsym=undefined;
  1077.   return; /* eg: repeat:..:until i>10 */
  1078.  }
  1079.  else
  1080.  /* wave */
  1081.  if (sym == wavesym) 
  1082.  {
  1083.   /* voice */
  1084.   insymbol();
  1085.   make_sure_short(expr());  /* voice (short) 0..3 */
  1086.  
  1087.   /* wave definition */
  1088.   if (sym != comma) _error(16);
  1089.   else
  1090.   {
  1091.    insymbol();
  1092.    if (sym == sinsym) 
  1093.    {
  1094.     gen("move.l","#0","a0");  /* SIN wave = 0 -> flag for _wave */
  1095.     insymbol();
  1096.    }
  1097.    else
  1098.    {
  1099.     /* now expect an address -> pointer to a block of bytes */
  1100.     if (expr() != longtype) _error(4);
  1101.     
  1102.     /* number of bytes? */
  1103.     if (sym != comma) _error(16);
  1104.     else
  1105.     {
  1106.      insymbol();
  1107.      if ((statetype=make_integer(expr())) == shorttype) make_long();  
  1108.  
  1109.      if (statetype == notype) _error(4); /* string -> type mismatch */
  1110.     }   
  1111.  
  1112.     gen("move.l","(sp)+","d1");  /* pop # of bytes of waveform data */
  1113.     gen("move.l","(sp)+","a0");  /* pop address of waveform data */
  1114.    }
  1115.   }
  1116.   gen("move.w","(sp)+","d0");  /* pop voice */
  1117.   gen("jsr","_wave","  "); 
  1118.   enter_XREF("_wave");
  1119.  }
  1120.  else
  1121.  /* while.. */
  1122.  if (sym == whilesym) while_statement();
  1123.  else
  1124.  /* wend */
  1125.  if ((sym == wendsym) && (lastsym == colon)) 
  1126.  {
  1127.   lastsym=undefined;
  1128.   return; /* eg: while i>2:wend */
  1129.  }
  1130.  else
  1131.  /* window */
  1132.  if (sym == windowsym) { window(); check_for_event(); }
  1133.  else
  1134.  /* write */
  1135.  if (sym == writesym) { check_for_event(); write_to_file(); }
  1136.  else
  1137.  /* ++ */
  1138.  if (sym == increment)
  1139.  { 
  1140.    insymbol();
  1141.                 if (sym != ident)
  1142.                 _error(7);
  1143.               else
  1144.           {
  1145.           /* it may be an external variable */
  1146.           strcpy(buf,ut_id);
  1147.           remove_qualifier(buf);
  1148.           if (buf[0] != '_')
  1149.           {
  1150.             sprintf(ext_name,"_%s",buf);
  1151.           }
  1152.           else
  1153.                 strcpy(ext_name,buf);
  1154.  
  1155.           if ((!exist(id,variable)) && (!exist(ext_name,extvar)))
  1156.              _error(19); /* simple variable expected */
  1157.           else
  1158.           {
  1159.            inc_item=curr_item;
  1160.            if (inc_item->type == stringtype)
  1161.               _error(4);
  1162.            else
  1163.            {
  1164.             /* get address of variable */
  1165.             address_of_object();
  1166.             gen("move.l","(sp)+","a0");
  1167.  
  1168.             /* increment it by 1 */
  1169.             switch(inc_item->type)
  1170.             {
  1171.              case shorttype  : gen("add.w","#1","(a0)");
  1172.                             break;
  1173.  
  1174.              case longtype   : gen("add.l","#1","(a0)");
  1175.                             break;
  1176.  
  1177.              case singletype : gen("movea.l","_MathBase","a6");
  1178.                        gen("move.l","(a0)","d0");
  1179.                        gen("move.l","#$80000041","d1");
  1180.                        gen("jsr","_LVOSPAdd(a6)","  ");
  1181.                        gen("move.l","d0","(a0)");
  1182.                        enter_XREF("_MathBase");
  1183.                        enter_XREF("_LVOSPAdd");
  1184.                        break;
  1185.             }
  1186.             }
  1187.            }
  1188.          insymbol();
  1189.         } 
  1190.  }         
  1191.  else
  1192.  /* -- */
  1193.  if (sym == decrement)
  1194.  { 
  1195.    insymbol();
  1196.                 if (sym != ident)
  1197.                 _error(7);
  1198.               else
  1199.           {
  1200.           /* it may be an external variable */
  1201.           strcpy(buf,ut_id);
  1202.           remove_qualifier(buf);
  1203.           if (buf[0] != '_')
  1204.           {
  1205.             sprintf(ext_name,"_%s",buf);
  1206.           }
  1207.           else
  1208.                 strcpy(ext_name,buf);
  1209.  
  1210.           if ((!exist(id,variable)) && (!exist(ext_name,extvar)))
  1211.              _error(19); /* simple variable expected */
  1212.           else
  1213.           {
  1214.            dec_item=curr_item;
  1215.            if (dec_item->type == stringtype)
  1216.               _error(4);
  1217.            else
  1218.            {
  1219.             /* get address of variable */
  1220.             address_of_object();
  1221.             gen("move.l","(sp)+","a0");
  1222.  
  1223.             /* increment it by 1 */
  1224.             switch(dec_item->type)
  1225.             {
  1226.              case shorttype  : gen("sub.w","#1","(a0)");
  1227.                             break;
  1228.  
  1229.              case longtype   : gen("sub.l","#1","(a0)");
  1230.                             break;
  1231.  
  1232.              case singletype : gen("movea.l","_MathBase","a6");
  1233.                        gen("move.l","(a0)","d0");
  1234.                        gen("move.l","#$80000041","d1");
  1235.                        gen("jsr","_LVOSPSub(a6)","  ");
  1236.                        gen("move.l","d0","(a0)");
  1237.                        enter_XREF("_MathBase");
  1238.                        enter_XREF("_LVOSPSub");
  1239.                        break;
  1240.             }
  1241.             }
  1242.            }
  1243.           insymbol();
  1244.         } 
  1245.  }         
  1246.  else
  1247.  /* *%<address> = <expr> */
  1248.  if (sym == shortpointer) 
  1249.  { 
  1250.   insymbol();
  1251.   if (expr() != longtype)  /* address */
  1252.      _error(4);
  1253.   else
  1254.   {
  1255.    if (sym != becomes)
  1256.       _error(5);
  1257.    else
  1258.    {
  1259.     insymbol();
  1260.     make_sure_short(expr());  
  1261.     gen("move.w","(sp)+","d0");  /* pop expression */ 
  1262.     gen("move.l","(sp)+","a0");  /* pop address */
  1263.     gen("move.w","d0","(a0)");   /* store expression */
  1264.    }
  1265.   }
  1266.  }
  1267.  else
  1268.  /* *&<address> = <expr> */
  1269.  if (sym == longpointer) 
  1270.  { 
  1271.   insymbol();
  1272.   if (expr() != longtype)  /* address */
  1273.      _error(4);
  1274.   else
  1275.   {
  1276.    if (sym != becomes)
  1277.       _error(5);
  1278.    else
  1279.    {
  1280.     insymbol();
  1281.     if ((statetype=make_integer(expr())) == notype)
  1282.        _error(4);
  1283.     else 
  1284.     {
  1285.      /* statetype is either short or long now */
  1286.      if (statetype == shorttype) make_long();
  1287.      gen("move.l","(sp)+","d0");  /* pop expression */ 
  1288.      gen("move.l","(sp)+","a0");  /* pop address */
  1289.      gen("move.l","d0","(a0)");   /* store expression */
  1290.     }
  1291.    }
  1292.   }
  1293.  }
  1294.  else
  1295.  /* *!<address> = <expr> */
  1296.  if (sym == singlepointer) 
  1297.  { 
  1298.   insymbol();
  1299.   if (expr() != longtype)  /* address */
  1300.      _error(4);
  1301.   else
  1302.   {
  1303.    if (sym != becomes)
  1304.       _error(5);
  1305.    else
  1306.    {
  1307.     insymbol();
  1308.     gen_Flt(expr());
  1309.     gen("move.l","(sp)+","d0");  /* pop expression */ 
  1310.     gen("move.l","(sp)+","a0");  /* pop address */
  1311.     gen("move.l","d0","(a0)");   /* store expression */
  1312.    }
  1313.   }
  1314.  }
  1315.  else
  1316.  /* feature not implemented? */  
  1317.  if (obj == rsvd_word) { _error(68); insymbol(); }
  1318.  else
  1319.  /* unknown */
  1320.  insymbol();
  1321. }
  1322.