1988-10-26 15:21:11 +00:00
|
|
|
/* H I G H L E V E L S Y M B O L E N T R Y */
|
|
|
|
|
2017-11-14 22:04:01 +00:00
|
|
|
#include <string.h>
|
1988-10-26 15:21:11 +00:00
|
|
|
#include <alloc.h>
|
|
|
|
#include <assert.h>
|
|
|
|
#include <em_arith.h>
|
|
|
|
#include <em_label.h>
|
|
|
|
|
2013-05-14 19:47:04 +00:00
|
|
|
#include "parameters.h"
|
1988-10-26 15:21:11 +00:00
|
|
|
#include "LLlex.h"
|
|
|
|
#include "def.h"
|
|
|
|
#include "idf.h"
|
|
|
|
#include "main.h"
|
|
|
|
#include "node.h"
|
|
|
|
#include "scope.h"
|
|
|
|
#include "type.h"
|
2019-02-23 17:15:23 +00:00
|
|
|
#include "progs.h"
|
|
|
|
#include "enter.h"
|
2019-02-23 16:44:50 +00:00
|
|
|
#ifdef DBSYMTAB
|
|
|
|
#include "stab.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
extern int proclevel;
|
|
|
|
extern int parlevel;
|
|
|
|
|
1988-10-26 15:21:11 +00:00
|
|
|
|
|
|
|
|
2019-02-23 16:44:50 +00:00
|
|
|
struct def *Enter(char *name, long kind, register struct type *type, int pnam)
|
1988-10-26 15:21:11 +00:00
|
|
|
{
|
|
|
|
/* Enter a definition for "name" with kind "kind" and type
|
2019-02-23 16:44:50 +00:00
|
|
|
"type" in the Current Scope. If it is a standard name, also
|
|
|
|
put its number in the definition structure, and mark the
|
|
|
|
name as set, to inhibit warnings about used before set.
|
|
|
|
*/
|
1988-10-26 15:21:11 +00:00
|
|
|
register struct def *df;
|
|
|
|
|
|
|
|
df = define(str2idf(name, 0), CurrentScope, kind);
|
|
|
|
df->df_type = type;
|
2019-02-23 16:44:50 +00:00
|
|
|
if (pnam)
|
|
|
|
{
|
1989-05-03 10:30:22 +00:00
|
|
|
df->df_value.df_reqname = pnam;
|
|
|
|
df->df_flags |= D_SET;
|
|
|
|
}
|
1991-02-15 18:00:26 +00:00
|
|
|
#ifdef DBSYMTAB
|
2019-02-23 16:44:50 +00:00
|
|
|
else if (options['g'])
|
|
|
|
stb_string(df, kind);
|
1991-02-15 18:00:26 +00:00
|
|
|
#endif /* DBSYMTAB */
|
1988-10-26 15:21:11 +00:00
|
|
|
return df;
|
|
|
|
}
|
|
|
|
|
2019-02-23 16:44:50 +00:00
|
|
|
void EnterProgList(register struct node *Idlist)
|
1988-10-26 15:21:11 +00:00
|
|
|
{
|
|
|
|
register struct node *idlist = Idlist;
|
|
|
|
register struct def *df;
|
|
|
|
|
2019-02-23 16:44:50 +00:00
|
|
|
for (; idlist; idlist = idlist->nd_next)
|
|
|
|
if (!strcmp(input, idlist->nd_IDF->id_text)
|
|
|
|
|| !strcmp(output, idlist->nd_IDF->id_text))
|
|
|
|
{
|
1988-10-26 15:21:11 +00:00
|
|
|
/* the occurence of input or output as program-
|
1989-05-03 10:30:22 +00:00
|
|
|
* parameter is their declaration as a GLOBAL
|
|
|
|
* variable of type text
|
1988-10-26 15:21:11 +00:00
|
|
|
*/
|
2019-02-23 16:44:50 +00:00
|
|
|
if ( (df = define(idlist->nd_IDF, CurrentScope,
|
|
|
|
D_VARIABLE)) )
|
|
|
|
{
|
1988-10-26 15:21:11 +00:00
|
|
|
df->df_type = text_type;
|
1989-05-03 10:30:22 +00:00
|
|
|
df->df_flags |= (D_SET | D_PROGPAR | D_NOREG);
|
2019-02-23 16:44:50 +00:00
|
|
|
if (!strcmp(input, idlist->nd_IDF->id_text))
|
|
|
|
{
|
1988-10-26 15:21:11 +00:00
|
|
|
df->var_name = input;
|
1988-11-16 15:18:21 +00:00
|
|
|
set_inp();
|
1988-10-26 15:21:11 +00:00
|
|
|
}
|
2019-02-23 16:44:50 +00:00
|
|
|
else
|
|
|
|
{
|
1988-10-26 15:21:11 +00:00
|
|
|
df->var_name = output;
|
1988-11-16 15:18:21 +00:00
|
|
|
set_outp();
|
1988-10-26 15:21:11 +00:00
|
|
|
}
|
1991-02-15 18:00:26 +00:00
|
|
|
#ifdef DBSYMTAB
|
2019-02-23 16:44:50 +00:00
|
|
|
if (options['g'])
|
|
|
|
stb_string(df, D_VARIABLE);
|
1991-02-15 18:00:26 +00:00
|
|
|
#endif /* DBSYMTAB */
|
1988-10-26 15:21:11 +00:00
|
|
|
}
|
|
|
|
}
|
2019-02-23 16:44:50 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
if ( (df = define(idlist->nd_IDF, CurrentScope,
|
|
|
|
D_PARAMETER)) )
|
|
|
|
{
|
1988-10-26 15:21:11 +00:00
|
|
|
df->df_type = error_type;
|
1988-11-16 15:18:21 +00:00
|
|
|
df->df_flags |= D_PROGPAR;
|
1989-05-03 10:30:22 +00:00
|
|
|
df->var_name = idlist->nd_IDF->id_text;
|
1988-10-26 15:21:11 +00:00
|
|
|
}
|
|
|
|
}
|
2019-02-23 16:44:50 +00:00
|
|
|
|
1988-10-26 15:21:11 +00:00
|
|
|
FreeNode(Idlist);
|
|
|
|
}
|
|
|
|
|
2019-02-23 16:44:50 +00:00
|
|
|
void EnterEnumList(struct node *Idlist, register struct type *type)
|
1988-10-26 15:21:11 +00:00
|
|
|
{
|
|
|
|
/* Put a list of enumeration literals in the symbol table.
|
2019-02-23 16:44:50 +00:00
|
|
|
They all have type "type". Also assign numbers to them.
|
|
|
|
*/
|
1990-12-11 13:52:08 +00:00
|
|
|
register struct def *df, *df1 = 0;
|
1988-10-26 15:21:11 +00:00
|
|
|
register struct node *idlist = Idlist;
|
|
|
|
|
|
|
|
type->enm_ncst = 0;
|
2019-02-23 16:44:50 +00:00
|
|
|
for (; idlist; idlist = idlist->nd_next)
|
|
|
|
if ( (df = define(idlist->nd_IDF, CurrentScope, D_ENUM)) )
|
|
|
|
{
|
1988-10-26 15:21:11 +00:00
|
|
|
df->df_type = type;
|
|
|
|
df->enm_val = (type->enm_ncst)++;
|
1989-05-03 10:30:22 +00:00
|
|
|
df->df_flags |= D_SET;
|
2019-02-23 16:44:50 +00:00
|
|
|
if (!df1)
|
|
|
|
{
|
1990-12-11 13:52:08 +00:00
|
|
|
type->enm_enums = df;
|
|
|
|
}
|
2019-02-23 16:44:50 +00:00
|
|
|
else
|
|
|
|
df1->enm_next = df;
|
1990-12-11 13:52:08 +00:00
|
|
|
df1 = df;
|
1988-10-26 15:21:11 +00:00
|
|
|
}
|
|
|
|
FreeNode(Idlist);
|
|
|
|
}
|
|
|
|
|
2019-02-23 16:44:50 +00:00
|
|
|
void EnterFieldList(struct node *Idlist, register struct type *type,
|
|
|
|
struct scope *scope, arith *addr, unsigned short packed)
|
1988-10-26 15:21:11 +00:00
|
|
|
{
|
|
|
|
/* Put a list of fields in the symbol table.
|
2019-02-23 16:44:50 +00:00
|
|
|
They all have type "type", and are put in scope "scope".
|
|
|
|
*/
|
1988-10-26 15:21:11 +00:00
|
|
|
register struct def *df;
|
|
|
|
register struct node *idlist = Idlist;
|
|
|
|
|
2019-02-23 16:44:50 +00:00
|
|
|
for (; idlist; idlist = idlist->nd_next)
|
|
|
|
if ( (df = define(idlist->nd_IDF, scope, D_FIELD)) )
|
|
|
|
{
|
1988-10-26 15:21:11 +00:00
|
|
|
df->df_type = type;
|
2019-02-23 16:44:50 +00:00
|
|
|
if (packed)
|
|
|
|
{
|
1988-10-26 15:21:11 +00:00
|
|
|
df->fld_flags |= F_PACKED;
|
|
|
|
df->fld_off = align(*addr, type->tp_palign);
|
|
|
|
*addr = df->fld_off + type->tp_psize;
|
|
|
|
}
|
2019-02-23 16:44:50 +00:00
|
|
|
else
|
|
|
|
{
|
1988-10-26 15:21:11 +00:00
|
|
|
df->fld_off = align(*addr, type->tp_align);
|
|
|
|
*addr = df->fld_off + type->tp_size;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
FreeNode(Idlist);
|
|
|
|
}
|
|
|
|
|
2019-02-23 16:44:50 +00:00
|
|
|
void EnterVarList(struct node *Idlist, struct type *type, int local)
|
1988-10-26 15:21:11 +00:00
|
|
|
{
|
|
|
|
/* Enter a list of identifiers representing variables into the
|
2019-02-23 16:44:50 +00:00
|
|
|
name list. "type" represents the type of the variables.
|
|
|
|
"local" is set if the variables are declared local to a
|
|
|
|
procedure.
|
|
|
|
*/
|
1988-10-26 15:21:11 +00:00
|
|
|
register struct def *df;
|
|
|
|
register struct node *idlist = Idlist;
|
|
|
|
register struct scopelist *sc = CurrVis;
|
|
|
|
|
2019-02-23 16:44:50 +00:00
|
|
|
for (; idlist; idlist = idlist->nd_next)
|
|
|
|
{
|
|
|
|
if (!(df = define(idlist->nd_IDF, CurrentScope, D_VARIABLE)))
|
|
|
|
continue; /* skip this identifier */
|
1988-10-26 15:21:11 +00:00
|
|
|
df->df_type = type;
|
2019-02-23 16:44:50 +00:00
|
|
|
if (local)
|
|
|
|
{
|
1988-10-26 15:21:11 +00:00
|
|
|
/* subtract size, which is already aligned, of
|
|
|
|
* variable to the offset, as the variable list
|
|
|
|
* exists only local to a procedure
|
|
|
|
*/
|
|
|
|
sc->sc_scope->sc_off -= type->tp_size;
|
|
|
|
df->var_off = sc->sc_scope->sc_off;
|
|
|
|
}
|
2019-02-23 16:44:50 +00:00
|
|
|
else
|
|
|
|
{ /* Global name */
|
1988-10-26 15:21:11 +00:00
|
|
|
df->var_name = df->df_idf->id_text;
|
|
|
|
df->df_flags |= D_NOREG;
|
|
|
|
}
|
1991-02-15 18:00:26 +00:00
|
|
|
#ifdef DBSYMTAB
|
2019-02-23 16:44:50 +00:00
|
|
|
if (options['g'])
|
|
|
|
stb_string(df, D_VARIABLE);
|
1991-02-15 18:00:26 +00:00
|
|
|
#endif /* DBSYMTAB */
|
1988-10-26 15:21:11 +00:00
|
|
|
}
|
|
|
|
FreeNode(Idlist);
|
|
|
|
}
|
|
|
|
|
2019-02-23 16:44:50 +00:00
|
|
|
|
|
|
|
static void LinkParam(struct paramlist **parlist, struct def *df)
|
|
|
|
{
|
|
|
|
static struct paramlist *pr;
|
|
|
|
|
|
|
|
if (!*parlist)
|
|
|
|
*parlist = pr = new_paramlist();
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pr->next = new_paramlist();
|
|
|
|
pr = pr->next;
|
|
|
|
}
|
|
|
|
pr->par_def = df;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
arith EnterParamList(register struct node *fpl, struct paramlist **parlist)
|
1988-10-26 15:21:11 +00:00
|
|
|
{
|
|
|
|
register arith nb_pars = (proclevel > 1) ? pointer_size : 0;
|
|
|
|
register struct node *id;
|
|
|
|
struct type *tp;
|
|
|
|
struct def *df;
|
|
|
|
|
2019-02-23 16:44:50 +00:00
|
|
|
for (; fpl; fpl = fpl->nd_right)
|
|
|
|
{
|
1988-10-26 15:21:11 +00:00
|
|
|
assert(fpl->nd_class == Link);
|
|
|
|
|
|
|
|
tp = fpl->nd_type;
|
2019-02-23 16:44:50 +00:00
|
|
|
for (id = fpl->nd_left; id; id = id->nd_next)
|
|
|
|
if ( (df = define(id->nd_IDF, CurrentScope, D_VARIABLE)) )
|
|
|
|
{
|
|
|
|
df->var_off = nb_pars;
|
|
|
|
if (fpl->nd_INT & D_VARPAR || IsConformantArray(tp))
|
|
|
|
nb_pars += pointer_size;
|
|
|
|
else
|
|
|
|
nb_pars += tp->tp_size;
|
|
|
|
LinkParam(parlist, df);
|
|
|
|
df->df_type = tp;
|
|
|
|
df->df_flags |= fpl->nd_INT;
|
|
|
|
}
|
1988-10-26 15:21:11 +00:00
|
|
|
|
2019-02-23 16:44:50 +00:00
|
|
|
while (IsConformantArray(tp))
|
|
|
|
{
|
1988-10-26 15:21:11 +00:00
|
|
|
/* we need room for the descriptors */
|
|
|
|
|
|
|
|
tp->arr_sclevel = CurrentScope->sc_level;
|
|
|
|
tp->arr_cfdescr = nb_pars;
|
|
|
|
nb_pars += 3 * word_size;
|
|
|
|
tp = tp->arr_elem;
|
2019-02-23 16:44:50 +00:00
|
|
|
}
|
1988-10-26 15:21:11 +00:00
|
|
|
}
|
|
|
|
return nb_pars;
|
|
|
|
}
|
|
|
|
|
2019-02-23 16:44:50 +00:00
|
|
|
arith EnterParTypes(register struct node *fpl, struct paramlist **parlist)
|
1988-10-26 15:21:11 +00:00
|
|
|
{
|
2013-05-12 19:45:55 +00:00
|
|
|
/* parameters.h in heading of procedural and functional
|
2019-02-23 16:44:50 +00:00
|
|
|
parameters (only types are important, not the names).
|
|
|
|
*/
|
1989-05-03 10:30:22 +00:00
|
|
|
register arith nb_pars = 0;
|
1988-10-26 15:21:11 +00:00
|
|
|
register struct node *id;
|
1989-05-03 10:30:22 +00:00
|
|
|
struct type *tp;
|
1988-10-26 15:21:11 +00:00
|
|
|
struct def *df;
|
|
|
|
|
2019-02-23 16:44:50 +00:00
|
|
|
for (; fpl; fpl = fpl->nd_right)
|
|
|
|
{
|
1989-05-03 10:30:22 +00:00
|
|
|
tp = fpl->nd_type;
|
2019-02-23 16:44:50 +00:00
|
|
|
for (id = fpl->nd_left; id; id = id->nd_next)
|
|
|
|
if ( (df = new_def()) )
|
|
|
|
{
|
|
|
|
if (fpl->nd_INT & D_VARPAR || IsConformantArray(tp))
|
1989-05-03 10:30:22 +00:00
|
|
|
nb_pars += pointer_size;
|
|
|
|
else
|
|
|
|
nb_pars += tp->tp_size;
|
1988-10-26 15:21:11 +00:00
|
|
|
LinkParam(parlist, df);
|
1989-05-03 10:30:22 +00:00
|
|
|
df->df_type = tp;
|
1988-10-26 15:21:11 +00:00
|
|
|
df->df_flags |= fpl->nd_INT;
|
|
|
|
}
|
2019-02-23 16:44:50 +00:00
|
|
|
while (IsConformantArray(tp))
|
|
|
|
{
|
1989-05-03 10:30:22 +00:00
|
|
|
nb_pars += 3 * word_size;
|
|
|
|
tp = tp->arr_elem;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nb_pars;
|
1988-10-26 15:21:11 +00:00
|
|
|
}
|
|
|
|
|