home *** CD-ROM | disk | FTP | other *** search
- /* << ACE >>
-
- -- Amiga BASIC Compiler --
-
- ** Parser: Factor 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,29th December 1992,
- 15th,28th February 1993,
- 6th,12th,13th June 1993,
- 6th September 1993,
- 24th,27th,28th,31st December 1993,
- 2nd,5th January 1994,
- 21st June 1994,
- 22nd August 1994,
- 1st October 1994,
- 11th March 1995
- */
-
- #include <string.h>
- #include "acedef.h"
-
-
- /* locals */
- static char *frame_ptr[] = {"(a4)", "(a5)"};
-
- /* externals */
- extern int sym;
- extern int obj;
- extern int typ;
- extern char id[MAXIDSIZE];
- extern char ut_id[MAXIDSIZE];
- extern SHORT shortval;
- extern LONG longval;
- extern float singleval;
- extern char stringval[MAXSTRLEN];
- extern SYM *curr_item;
- extern CODE *curr_code;
- extern SHORT dimsize[255];
- extern BOOL end_of_source;
- extern FILE *dest;
- extern char ch;
- extern int lev;
- extern char numbuf[80];
- extern char librarybase[MAXIDSIZE + 6];
- extern ACELIBS acelib[NUMACELIBS];
- extern BOOL restore_a4;
- extern BOOL restore_a5;
- extern BOOL cli_args;
-
- /* functions */
- BOOL factorfunc (void)
- {
- /*
- ** Return TRUE if fsym is in the list of
- ** functions (generally parameterless)
- ** found in factor().
- ** PRINT needs this information.
- */
-
- switch (sym)
- {
- case argcountsym:
- return (TRUE);
- case csrlinsym:
- return (TRUE);
- case datestrsym:
- return (TRUE);
- case daysym:
- return (TRUE);
- case errsym:
- return (TRUE);
- case headingsym:
- return (TRUE);
- case inkeysym:
- return (TRUE);
- case possym:
- return (TRUE);
- case rndsym:
- return (TRUE); /* has optional parameter! */
- case systemsym:
- return (TRUE);
- case timersym:
- return (TRUE);
- case timestrsym:
- return (TRUE);
- case xcorsym:
- return (TRUE);
- case ycorsym:
- return (TRUE);
- default:
- return (FALSE);
- }
- }
-
- int factor (void)
- {
- char buf[80], srcbuf[80], sub_name[80];
- char func_name[MAXIDSIZE], func_address[MAXIDSIZE + 9];
- char ext_name[MAXIDSIZE + 1];
- int ftype = undefined;
- int arraytype = undefined;
- SYM *fact_item;
- int oldlevel;
- BYTE libnum;
- BOOL need_symbol;
-
- ftype = stringfunction();
- if (ftype != undefined)
- return (ftype);
-
- ftype = numericfunction();
- if (ftype != undefined)
- return (ftype);
-
- switch (sym)
- {
- case shortconst:
- sprintf (numbuf, "#%d", shortval);
- gen ("move.w", numbuf, "-(sp)");
- ftype = typ;
- insymbol ();
- return (ftype);
- break;
-
- case longconst:
- sprintf (numbuf, "#%ld", longval);
- gen ("move.l", numbuf, "-(sp)");
- ftype = typ;
- insymbol ();
- return (ftype);
- break;
-
- case singleconst:
- /* sprintf (numbuf, "#$%lx",singleval); original */
- sprintf (numbuf, "#$%x",singleval);
- gen ("move.l", numbuf, "-(sp)");
- ftype = typ;
- insymbol ();
- return (ftype);
- break;
-
- case stringconst:
- make_string_const (stringval);
- ftype = typ;
- insymbol ();
- return (ftype);
- break;
-
- case ident: /* does object exist? */
-
- /* in case it's a subprogram */
- strcpy (sub_name, "_SUB_");
- strcat (sub_name, id);
-
- /* store id in case it's a function */
- strcpy (func_name, id);
- remove_qualifier (func_name);
-
- /* make external variable name */
- /* add an underscore prefix
- if one is not present.
- */
- strcpy (buf, ut_id);
- remove_qualifier (buf);
- if (buf[0] != '_')
- {
- strcpy (ext_name, "_\0");
- strcat (ext_name, buf);
- }
- else
- strcpy (ext_name, buf);
-
- /* what sort of object is it? */
- if (exist (id, array))
- {
- obj = array;
- arraytype = typ = curr_item->type;
- }
- else if (exist (sub_name, subprogram))
- {
- obj = subprogram;
- typ = curr_item->type;
- }
- else if (exist (sub_name, definedfunc))
- {
- obj = definedfunc;
- typ = curr_item->type;
- }
- else if (exist (func_name, function))
- {
- obj = function;
- typ = curr_item->type;
- }
- else if (exist (ext_name, extfunc))
- {
- obj = extfunc;
- typ = curr_item->type;
- }
- else if (exist (ext_name, extvar))
- {
- obj = extvar;
- typ = curr_item->type;
- }
- else if (exist (id, structure))
- obj = structure;
- else if (exist (id, constant))
- {
- obj = constant;
- typ = curr_item->type;
- }
- else if (exist (id, obj)) /* obj == variable? */
- typ = curr_item->type;
- else
- {
- /* object doesn't exist so create a default variable */
- enter (id, typ, obj, 0);
- }
-
- fact_item = curr_item;
-
- /* frame address of object */
- if (obj == subprogram)
- {
- oldlevel = lev;
- lev = ZERO;
- }
-
- itoa (-1 * curr_item->address, srcbuf, 10);
- strcat (srcbuf, frame_ptr[lev]);
-
- if (obj == subprogram)
- lev = oldlevel;
-
- /*
- ** what sort of object? -> constant,variable,subprogram,
- ** function (library,external,defined),array,structure.
- */
-
- if (obj == variable) /* variable */
- {
- /* shared variable in SUB? */
- if ((fact_item->shared) && (lev == ONE) && (typ != stringtype))
- {
- gen ("move.l", srcbuf, "a0");
- if (typ == shorttype)
- gen ("move.w", "(a0)", "-(sp)");
- else
- gen ("move.l", "(a0)", "-(sp)");
- }
- else
- /* ordinary variable */
- if (typ == shorttype)
- gen ("move.w", srcbuf, "-(sp)");
- else /* string, long, single */
- gen ("move.l", srcbuf, "-(sp)"); /* push value */
-
- ftype = typ;
- insymbol ();
- if (sym == lparen)
- _error (71); /* undimensioned array? */
- return (ftype);
- }
- else if (obj == structure) /* structure */
- {
- ftype = push_struct (fact_item);
- return (ftype);
- }
- else if (obj == constant) /* defined constant */
- {
- push_num_constant (typ, fact_item);
- ftype = typ;
- insymbol ();
- if (sym == lparen)
- _error (71); /* undimensioned array? */
- return (ftype);
- }
- else if (obj == extvar) /* external variable */
- {
- if (typ == shorttype)
- /* short integer */
- gen ("move.w", ext_name, "-(sp)");
- else if (typ == stringtype)
- /* string */
- gen ("pea", ext_name, " ");
- else
- /* long integer, single-precision */
- gen ("move.l", ext_name, "-(sp)");
- ftype = typ;
- insymbol ();
- if (sym == lparen)
- _error (71); /* undimensioned array? */
- return (ftype);
- }
- else if (obj == subprogram || obj == definedfunc) /* subprogram */
- {
- /* CALL the subprogram */
- if (fact_item->no_of_params != 0)
- {
- insymbol ();
- load_params (fact_item);
- }
- gen ("jsr", sub_name, " ");
-
- /* push the return value */
- if (fact_item->type == shorttype)
- {
- if (fact_item->object == subprogram &&
- fact_item->address != extfunc)
- gen ("move.w", srcbuf, "-(sp)");
- else
- gen ("move.w", "d0", "-(sp)");
- }
- else
- /* string, long, single */
- {
- if (fact_item->object == subprogram &&
- fact_item->address != extfunc)
- gen ("move.l", srcbuf, "-(sp)"); /* push value */
- else
- gen ("move.l", "d0", "-(sp)");
- }
- ftype = fact_item->type;
- insymbol ();
- return (ftype);
- }
- else if (obj == function) /* library function */
- {
- if (fact_item->no_of_params != 0)
- {
- insymbol ();
- load_func_params (fact_item);
- }
- /* call it */
- if ((libnum = check_for_ace_lib (fact_item->libname)) == NEGATIVE)
- make_library_base (fact_item->libname);
- else
- strcpy (librarybase, acelib[libnum].base);
- gen ("move.l", librarybase, "a6");
- itoa (fact_item->address, func_address, 10);
- strcat (func_address, "(a6)");
- gen ("jsr", func_address, " ");
-
- if (fact_item->type == shorttype)
- gen ("move.w", "d0", "-(sp)");
- else
- gen ("move.l", "d0", "-(sp)"); /* push return value */
-
- if (restore_a4)
- {
- gen ("move.l", "_a4_temp", "a4");
- restore_a4 = FALSE;
- }
- if (restore_a5)
- {
- gen ("move.l", "_a5_temp", "a5");
- restore_a5 = FALSE;
- }
-
- ftype = fact_item->type;
- insymbol ();
- return (ftype);
- }
- else if (obj == extfunc)
- {
- /* external function call */
- insymbol ();
- call_external_function (ext_name, &need_symbol);
- /* push return value */
- if (fact_item->type == shorttype)
- gen ("move.w", "d0", "-(sp)");
- else
- gen ("move.l", "d0", "-(sp)");
- ftype = fact_item->type;
- if (need_symbol)
- insymbol ();
- return (ftype);
- }
- else if (obj == array)
- {
- push_indices (fact_item);
- get_abs_ndx (fact_item);
- gen ("move.l", srcbuf, "a0");
-
- if (arraytype == stringtype)
- {
- /* push start address of string within BSS object */
- gen ("adda.l", "d7", "a0");
- gen ("move.l", "a0", "-(sp)");
- }
- else if (arraytype == shorttype)
- gen ("move.w", "0(a0,d7.L)", "-(sp)");
- else
- gen ("move.l", "0(a0,d7.L)", "-(sp)");
-
- ftype = arraytype; /* typ killed by push_indices()! */
- insymbol ();
- return (ftype);
- }
- break;
-
- case lparen:
- insymbol ();
- ftype = expr ();
- if (sym != rparen)
- _error (9);
- insymbol ();
- return (ftype);
- break;
-
- /* @<object> */
- case atsymbol:
- insymbol ();
- if (sym != ident)
- {
- _error (7);
- ftype = undefined;
- insymbol ();
- }
- else
- {
- strcpy (buf, id);
- ftype = address_of_object ();
- /* structure and array code returns next symbol */
- if (!exist (buf, structure) && !exist (buf, array))
- insymbol ();
- }
- return (ftype);
- break;
-
- /* parameterless functions */
-
- case argcountsym:
- gen ("jsr", "_argcount", " ");
- gen ("move.l", "d0", "-(sp)");
- enter_XREF ("_argcount");
- ftype = longtype;
- cli_args = TRUE;
- insymbol ();
- return (ftype);
- break;
-
- case csrlinsym:
- gen ("jsr", "_csrlin", " ");
- gen ("move.w", "d0", "-(sp)");
- enter_XREF ("_csrlin");
- ftype = shorttype;
- insymbol ();
- return (ftype);
- break;
-
- case datestrsym:
- gen ("jsr", "_date", " ");
- gen ("move.l", "d0", "-(sp)");
- enter_XREF ("_date");
- enter_XREF ("_DOSBase"); /* DateStamp() needs dos.library */
- ftype = stringtype;
- insymbol ();
- return (ftype);
- break;
-
- case daysym:
- gen ("jsr", "_getday", " ");
- gen ("move.l", "d0", "-(sp)");
- enter_XREF ("_getday");
- ftype = longtype;
- insymbol ();
- return (ftype);
- break;
-
- case errsym:
- gen ("jsr", "_err", " ");
- gen ("move.l", "d0", "-(sp)");
- enter_XREF ("_err");
- ftype = longtype;
- insymbol ();
- return (ftype);
- break;
-
- case headingsym:
- gen ("jsr", "_heading", " ");
- gen ("move.w", "d0", "-(sp)");
- enter_XREF ("_heading");
- enter_XREF ("_IntuitionBase");
- ftype = shorttype;
- insymbol ();
- return (ftype);
- break;
-
- case inkeysym:
- gen ("jsr", "_inkey", " ");
- gen ("move.l", "d0", "-(sp)");
- enter_XREF ("_inkey");
- enter_XREF ("_DOSBase");
- ftype = stringtype;
- insymbol ();
- return (ftype);
- break;
-
- case possym:
- gen ("jsr", "_pos", " ");
- gen ("move.w", "d0", "-(sp)");
- enter_XREF ("_pos");
- ftype = shorttype;
- insymbol ();
- return (ftype);
- break;
-
- case rndsym:
- insymbol ();
- if (sym == lparen)
- {
- /* ignore dummy expression if exists */
- insymbol ();
- ftype = make_integer (expr ());
- switch (ftype)
- {
- case shorttype:
- gen ("move.w", "(sp)+", "d0");
- break;
-
- case longtype:
- gen ("move.l", "(sp)+", "d0");
- break;
-
- default:
- _error (4);
- }
- if (sym != rparen)
- _error (9);
- else
- insymbol ();
- }
- gen ("jsr", "_rnd", " ");
- gen ("move.l", "d0", "-(sp)");
- enter_XREF ("_rnd");
- enter_XREF ("_MathBase"); /* make sure mathffp lib is open */
- ftype = singletype;
- return (ftype);
- break;
-
- case systemsym:
- gen ("jsr", "_system_version", " ");
- gen ("move.w", "d0", "-(sp)");
- enter_XREF ("_system_version");
- ftype = shorttype;
- insymbol ();
- return (ftype);
- break;
-
- case timersym:
- gen ("jsr", "_timer", " ");
- gen ("move.l", "d0", "-(sp)");
- enter_XREF ("_timer");
- enter_XREF ("_DOSBase"); /* DateStamp() needs dos.library */
- enter_XREF ("_MathBase"); /* _timer needs basic ffp funcs */
- ftype = singletype;
- insymbol ();
- return (ftype);
- break;
-
- case timestrsym:
- gen ("jsr", "_timeofday", " ");
- gen ("move.l", "d0", "-(sp)");
- enter_XREF ("_timeofday");
- enter_XREF ("_DOSBase"); /* DateStamp() needs dos.library */
- ftype = stringtype;
- insymbol ();
- return (ftype);
- break;
-
- case xcorsym:
- gen ("jsr", "_xcor", " ");
- gen ("move.w", "d0", "-(sp)");
- enter_XREF ("_xcor");
- enter_XREF ("_GfxBase");
- ftype = shorttype;
- insymbol ();
- return (ftype);
- break;
-
- case ycorsym:
- gen ("jsr", "_ycor", " ");
- gen ("move.w", "d0", "-(sp)");
- enter_XREF ("_ycor");
- enter_XREF ("_GfxBase");
- ftype = shorttype;
- insymbol ();
- return (ftype);
- break;
- }
-
- /* none of the above! */
- ftype = undefined;
- _error (13); /* illegal expression */
- insymbol ();
- return (ftype);
- }
-