home *** CD-ROM | disk | FTP | other *** search
- /* << ACE >>
-
- -- Amiga BASIC Compiler --
-
- ** Parser: subprogram code **
- ** Copyright (C) 1998 David Benn
- **
- ** This program is free software; you can redistribute it and/or
- ** modify it under the terms of the GNU General Public License
- ** as published by the Free Software Foundation; either version 2
- ** of the License, or (at your option) any later version.
- **
- ** This program is distributed in the hope that it will be useful,
- ** but WITHOUT ANY WARRANTY; without even the implied warranty of
- ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ** GNU General Public License for more details.
- **
- ** You should have received a copy of the GNU General Public License
- ** along with this program; if not, write to the Free Software
- ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
- Author: David J Benn
- Date: 26th October-30th November, 1st-13th December 1991,
- 14th,20th-27th January 1992,
- 2nd-17th, 21st-29th February 1992,
- 1st,13th,14th,22nd,23rd March 1992,
- 21st,22nd April 1992,
- 2nd,3rd,11th,15th,16th May 1992,
- 7th,8th,9th,11th,13th,14th,28th,29th,30th June 1992,
- 2nd-8th,14th-19th,26th-29th July 1992,
- 1st-3rd,7th,8th,9th August 1992,
- 6th,7th December 1992,
- 24th March 1993,
- 14th,20th,30th June 1993,
- 18th December 1993,
- 12th,21st June 1994
- */
-
- #include "acedef.h"
- #include <string.h>
-
- /* locals */
- static char *frame_ptr[] = {"(a4)", "(a5)"};
-
- /* externals */
- extern int sym;
- extern int typ;
- extern int lev;
- extern char id[MAXIDSIZE];
- extern SYM *curr_item;
- extern CODE *curr_code;
- extern int addr[2];
-
- /* functions */
- void forward_ref (void)
- {
- char sub_name[80];
- SYM *sub_ptr;
- short param_count = 0;
- int param_type;
- int sub_type = undefined;
- /* declare a forward reference to a SUB -- see declare()
- NO checking against symbol table is carried out */
-
- insymbol ();
-
- /* type identifiers */
- if (sym == shortintsym || sym == longintsym || sym == addresssym ||
- sym == singlesym || sym == stringsym)
- {
- switch (sym)
- {
- case shortintsym:
- sub_type = shorttype;
- break;
- case longintsym:
- sub_type = longtype;
- break;
- case addresssym:
- sub_type = longtype;
- break;
- case singlesym:
- sub_type = singletype;
- break;
- case stringsym:
- sub_type = stringtype;
- break;
- }
- insymbol ();
- }
-
- if (sym != ident)
- _error (7);
- else
- {
- /* get the name */
- strcpy (sub_name, "_SUB_");
- strcat (sub_name, id);
-
- /* enter it into symbol table & mark as forward ref. */
- if (!exist (sub_name, subprogram))
- {
- if (sub_type == undefined)
- sub_type = typ;
- enter (sub_name, sub_type, subprogram, 0);
- curr_item->decl = fwdref;
- }
- else
- _error (33); /* subprogram already declared */
-
- sub_ptr = curr_item;
-
- /* get parameters -- if any */
- insymbol ();
- if (sym != lparen)
- {
- /* Is this an external subprogram? */
- if (sym == externalsym)
- {
- insymbol ();
- enter_XREF (sub_name);
- sub_ptr->address = extfunc;
- }
-
- sub_ptr->no_of_params = 0;
- return; /* no parameters -> return sym */
- }
- else
- {
- /* parameters expected */
- do
- {
- param_type = undefined;
-
- insymbol ();
-
- /* type identifiers */
- if (sym == shortintsym || sym == longintsym || sym == addresssym ||
- sym == singlesym || sym == stringsym)
- {
- switch (sym)
- {
- case shortintsym:
- param_type = shorttype;
- break;
- case longintsym:
- param_type = longtype;
- break;
- case addresssym:
- param_type = longtype;
- break;
- case singlesym:
- param_type = singletype;
- break;
- case stringsym:
- param_type = stringtype;
- break;
- }
- insymbol ();
- }
-
- if (sym != ident)
- _error (7); /* ident expected */
- else
- {
- /* store parameter type */
- if (param_type == undefined)
- param_type = typ;
- sub_ptr->p_type[param_count] = param_type;
- param_count++;
- }
- insymbol ();
- }
- while ((sym == comma) && (param_count < MAXPARAMS));
-
- sub_ptr->no_of_params = param_count;
-
- if (param_count == MAXPARAMS)
- _error (42); /* too many */
-
- if (sym != rparen)
- _error (9);
- insymbol ();
-
- /* Is this an external subprogram? */
- if (sym == externalsym)
- {
- insymbol ();
- enter_XREF (sub_name);
- sub_ptr->address = extfunc;
- }
- }
- }
- }
-
-
- void sub_params (SYM * sub_ptr)
- {
- SHORT param_count = 0;
- int param_type;
- char addrbuf[40];
-
- /* parse current SUB's formal parameter list */
-
- insymbol ();
- if (sym != lparen)
- {
- sub_ptr->no_of_params = 0;
- return; /* no parameters -> return sym */
- }
- else
- {
- /* if actual parameters passed, Forbid() called -> Permit() */
- gen ("movea.l", "_AbsExecBase", "a6");
- gen ("jsr", "_LVOPermit(a6)", " ");
- enter_XREF ("_AbsExecBase");
- enter_XREF ("_LVOPermit");
-
- /* formal parameters expected */
- do
- {
- param_type = undefined;
-
- insymbol ();
-
- /* type identifiers */
- if (sym == shortintsym || sym == longintsym || sym == addresssym ||
- sym == singlesym || sym == stringsym)
- {
- switch (sym)
- {
- case shortintsym:
- param_type = shorttype;
- break;
- case longintsym:
- param_type = longtype;
- break;
- case addresssym:
- param_type = longtype;
- break;
- case singlesym:
- param_type = singletype;
- break;
- case stringsym:
- param_type = stringtype;
- break;
- }
- insymbol ();
- }
-
- if (sym != ident)
- _error (7); /* ident expected */
- else
- {
- if (!exist (id, variable)) /* treat param's as local variables */
- {
- /* if type not already specified, take type indicated by ident */
- if (param_type == undefined)
- param_type = typ;
-
- /* enter parameter as a variable into symbol table */
- enter (id, param_type, variable, 0);
-
- /* string parameter? -> associate with BSS object */
- if (curr_item->type == stringtype)
- {
- itoa (-1 * curr_item->address, addrbuf, 10);
- strcat (addrbuf, frame_ptr[ONE]);
- gen ("move.l", addrbuf, "-(sp)"); /* push value parameter */
- assign_to_string_variable (curr_item, MAXSTRLEN);
- }
- }
- else
- _error (38); /* duplicate parameter */
- }
-
- /* store parameter type */
- sub_ptr->p_type[param_count] = param_type;
- param_count++;
-
- insymbol ();
- }
- while ((sym == comma) && (param_count < MAXPARAMS));
-
- sub_ptr->no_of_params = param_count;
-
- if (param_count == MAXPARAMS)
- _error (42); /* too many */
-
- if (sym != rparen)
- _error (9);
- insymbol ();
- }
- }
-
- void parse_shared_vars (void)
- {
- SYM *zero_ptr, *one_ptr;
- int i;
- char buf0[40], buf1[40], num[40];
- BOOL share_it;
-
- /* get the SHARED list for current SUB and store details */
-
- do
- {
- share_it = FALSE;
- insymbol ();
- if (sym != ident)
- _error (7); /* identifier expected */
- else
- {
- lev = ZERO;
- if (exist (id, variable) || exist (id, structure))
- {
- share_it = TRUE;
- zero_ptr = curr_item;
- lev = ONE;
- enter (id, zero_ptr->type, zero_ptr->object, 0); /* variable or structure */
- one_ptr = curr_item;
- /* add another 2 bytes to address if short */
- if (one_ptr->type == shorttype)
- {
- addr[lev] += 2;
- one_ptr->address = addr[lev];
- }
- zero_ptr->shared = TRUE;
- one_ptr->shared = TRUE;
- if (one_ptr->type == stringtype)
- one_ptr->new_string_var = FALSE; /* don't want a new BSS object! */
- if (one_ptr->object == structure)
- one_ptr->other = zero_ptr->other; /* pointer to structdef SYM node */
- }
- else if (exist (id, array))
- {
- share_it = TRUE;
- zero_ptr = curr_item;
- lev = ONE;
- enter (id, zero_ptr->type, array, zero_ptr->dims);
- one_ptr = curr_item;
- zero_ptr->shared = TRUE;
- one_ptr->shared = TRUE;
- /* copy array index values from level ZERO to ONE */
- for (i = 0; i <= zero_ptr->dims; i++)
- one_ptr->index[i] = zero_ptr->index[i];
- /* get string array element size? */
- if (one_ptr->type == stringtype)
- one_ptr->numconst.longnum = zero_ptr->numconst.longnum;
- }
- else
- {
- _error (40);
- lev = ONE;
- }
-
- if (share_it)
- {
- /* copy size information for SIZEOF? */
- if (one_ptr->type == stringtype ||
- one_ptr->object == array ||
- one_ptr->object == structure)
- one_ptr->size = zero_ptr->size;
-
- /* copy address of object from level ZERO to level ONE stack frame */
-
- /* frame location of level ONE object */
- itoa (-1 * one_ptr->address, buf1, 10);
- strcat (buf1, "(a5)");
-
- /* if simple numeric variable (short,long,single) or structure
- -> get address */
- if ((zero_ptr->type != stringtype) && (zero_ptr->object != array))
- {
- strcpy (num, "#\0");
- itoa (zero_ptr->address, buf0, 10);
- strcat (num, buf0);
- gen ("move.l", "a4", "d0"); /* frame pointer */
- gen ("sub.l", num, "d0"); /* offset from frame top */
- gen ("move.l", "d0", buf1); /* store address in level ONE frame */
- }
- else
- {
- /* array or string -> level ZERO already contains address */
- itoa (-1 * zero_ptr->address, buf0, 10);
- strcat (buf0, "(a4)");
- gen ("move.l", buf0, buf1);
- }
- }
- }
-
- insymbol ();
- }
- while (sym == comma);
- }
-