- fixes: improved POINTER TO IDENT mechanism, prevent core dump when
definition module not found, corrected typo. - changed mechanism for variables that have their address given. - added option for symmetric integer ranges
This commit is contained in:
		
							parent
							
								
									b93c1cb093
								
							
						
					
					
						commit
						efafb68f00
					
				
					 11 changed files with 57 additions and 21 deletions
				
			
		| 
						 | 
				
			
			@ -177,7 +177,7 @@ CodeCoercion(t1, t2)
 | 
			
		|||
		fund1 = T_CARDINAL;
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
	switch(fund2 = t1->tp_fund) {
 | 
			
		||||
	switch(fund2 = t2->tp_fund) {
 | 
			
		||||
	case T_WORD:
 | 
			
		||||
		fund2 = T_INTEGER;
 | 
			
		||||
		break;
 | 
			
		||||
| 
						 | 
				
			
			@ -556,7 +556,10 @@ CodeStd(nd)
 | 
			
		|||
			if (tp->tp_fund == T_INTEGER) C_adi(size);
 | 
			
		||||
			else	C_adu(size);
 | 
			
		||||
		}
 | 
			
		||||
		if (size == word_size) RangeCheck(tp, int_type);
 | 
			
		||||
		if (size == word_size) {
 | 
			
		||||
			RangeCheck(tp, tp->tp_fund == T_INTEGER ?
 | 
			
		||||
						int_type : card_type);
 | 
			
		||||
		}
 | 
			
		||||
		CodeDStore(left);
 | 
			
		||||
		break;
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,10 +21,8 @@ struct module {
 | 
			
		|||
struct variable {
 | 
			
		||||
	arith va_off;		/* address or offset of variable */
 | 
			
		||||
	char *va_name;		/* name of variable if given */
 | 
			
		||||
	char va_addrgiven;	/* an address was given in the program */
 | 
			
		||||
#define var_off		df_value.df_variable.va_off
 | 
			
		||||
#define var_name	df_value.df_variable.va_name
 | 
			
		||||
#define var_addrgiven	df_value.df_variable.va_addrgiven
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct constant {
 | 
			
		||||
| 
						 | 
				
			
			@ -74,8 +72,6 @@ struct dforward {
 | 
			
		|||
 | 
			
		||||
struct forwtype {
 | 
			
		||||
	struct node *f_node;
 | 
			
		||||
	struct type *f_type;
 | 
			
		||||
#define df_forw_type	df_value.df_fortype.f_type
 | 
			
		||||
#define df_forw_node	df_value.df_fortype.f_node
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -116,6 +112,7 @@ struct def	{		/* list of definitions for a name */
 | 
			
		|||
#define D_QEXPORTED	0x40	/* set if qualified exported */
 | 
			
		||||
#define D_BUSY		0x80	/* set if busy reading this definition module */
 | 
			
		||||
#define D_FOREIGN	0x100	/* set for foreign language modules */
 | 
			
		||||
#define D_ADDRGIVEN	0x200	/* set if address given for variable */
 | 
			
		||||
	struct type *df_type;
 | 
			
		||||
	union {
 | 
			
		||||
		struct module df_module;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -142,7 +142,6 @@ define(id, scope, kind)
 | 
			
		|||
			if (kind == D_FORWTYPE) return df;
 | 
			
		||||
			if (kind == D_TYPE) {
 | 
			
		||||
				df->df_kind = D_FTYPE;
 | 
			
		||||
				FreeNode(df->df_forw_node);
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				error("identifier \"%s\" must be a type",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -94,6 +94,7 @@ GetDefinitionModule(id, incr)
 | 
			
		|||
	struct scopelist *vis;
 | 
			
		||||
	char *fn = FileName;
 | 
			
		||||
	int ln = LineNumber;
 | 
			
		||||
	struct scope *newsc = CurrentScope;
 | 
			
		||||
 | 
			
		||||
	level += incr;
 | 
			
		||||
	df = lookup(id, GlobalScope, 1);
 | 
			
		||||
| 
						 | 
				
			
			@ -110,6 +111,7 @@ GetDefinitionModule(id, incr)
 | 
			
		|||
 | 
			
		||||
			ForeignFlag = 0;
 | 
			
		||||
			open_scope(CLOSEDSCOPE);
 | 
			
		||||
			newsc = CurrentScope;
 | 
			
		||||
			if (!is_anon_idf(id) && GetFile(id->id_text)) {
 | 
			
		||||
 | 
			
		||||
				DefModule();
 | 
			
		||||
| 
						 | 
				
			
			@ -136,7 +138,7 @@ GetDefinitionModule(id, incr)
 | 
			
		|||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				df = lookup(id, GlobalScope, 1);
 | 
			
		||||
				CurrentScope->sc_name = id->id_text;
 | 
			
		||||
				newsc->sc_name = id->id_text;
 | 
			
		||||
			}
 | 
			
		||||
			vis = CurrVis;
 | 
			
		||||
			close_scope(SC_CHKFORW);
 | 
			
		||||
| 
						 | 
				
			
			@ -145,6 +147,7 @@ GetDefinitionModule(id, incr)
 | 
			
		|||
			df = MkDef(id, GlobalScope, D_ERROR);
 | 
			
		||||
			df->df_type = error_type;
 | 
			
		||||
			df->mod_vis = vis;
 | 
			
		||||
			newsc->sc_definedby = df;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	else if (df->df_flags & D_BUSY) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -438,7 +438,7 @@ CodeVarDesig(df, ds)
 | 
			
		|||
	*/
 | 
			
		||||
	assert(ds->dsg_kind == DSG_INIT);
 | 
			
		||||
 | 
			
		||||
	if (df->var_addrgiven) {
 | 
			
		||||
	if (df->df_flags & D_ADDRGIVEN) {
 | 
			
		||||
		/* the programmer specified an address in the declaration of
 | 
			
		||||
		   the variable. Generate code to push the address.
 | 
			
		||||
		*/
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -65,6 +65,10 @@ make all procedure names global, so that \fIadb\fR(1) understands them.
 | 
			
		|||
.IP \fB\-i\fR\fInum\fR
 | 
			
		||||
maximum number of bits in a set. When not used, a default value is
 | 
			
		||||
retained.
 | 
			
		||||
.IP \fB\-s\fR
 | 
			
		||||
make INTEGER ranges symmetric, t.i., MIN(INTEGER) = - MAX(INTEGER).
 | 
			
		||||
This is useful for interpreters that use the "real" MIN(INTEGER) to
 | 
			
		||||
indicate "undefined".
 | 
			
		||||
.LP
 | 
			
		||||
.SH FILES
 | 
			
		||||
.IR ~em/lib/em_m2 :
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -133,8 +133,7 @@ EnterVarList(Idlist, type, local)
 | 
			
		|||
			*/
 | 
			
		||||
			register struct type *tp = idlist->nd_left->nd_type;
 | 
			
		||||
 | 
			
		||||
			df->var_addrgiven = 1;
 | 
			
		||||
			df->df_flags |= D_NOREG;
 | 
			
		||||
			df->df_flags |= D_ADDRGIVEN | D_NOREG;
 | 
			
		||||
			if (tp != error_type && !(tp->tp_fund & T_CARDINAL)){
 | 
			
		||||
				node_error(idlist->nd_left,
 | 
			
		||||
					   "illegal type for address");
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -80,6 +80,10 @@ By default, warnings in class \fBO\fR and \fBW\fR are given.
 | 
			
		|||
allow for warning messages whose class is a member of \fIclasses\fR.
 | 
			
		||||
.IP \fB\-x\fR
 | 
			
		||||
make all procedure names global, so that \fIadb\fR(1) understands them.
 | 
			
		||||
.IP \fB\-Xs\fR
 | 
			
		||||
make INTEGER ranges symmetric, t.i., MIN(INTEGER) = - MAX(INTEGER).
 | 
			
		||||
This is useful for interpreters that use the "real" MIN(INTEGER) to
 | 
			
		||||
indicate "undefined".
 | 
			
		||||
.LP
 | 
			
		||||
.SH SEE ALSO
 | 
			
		||||
\fIack\fR(1), \fIem_m2\fR(6)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -117,21 +117,31 @@ chk_forw(pdf)
 | 
			
		|||
	while (df = *pdf) {
 | 
			
		||||
		if (df->df_kind == D_FORWTYPE) {
 | 
			
		||||
			register struct def *df1 = df;
 | 
			
		||||
			register struct node *nd = df->df_forw_node;
 | 
			
		||||
 | 
			
		||||
			*pdf = df->df_nextinscope;
 | 
			
		||||
			RemoveFromIdList(df);
 | 
			
		||||
			df = lookfor(df->df_forw_node, CurrVis, 1);
 | 
			
		||||
			df = lookfor(nd, CurrVis, 1);
 | 
			
		||||
			if (! df->df_kind & (D_ERROR|D_FTYPE|D_TYPE)) {
 | 
			
		||||
node_error(df1->df_forw_node, "\"%s\" is not a type", df1->df_idf->id_text);
 | 
			
		||||
node_error(nd, "\"%s\" is not a type", df1->df_idf->id_text);
 | 
			
		||||
			}
 | 
			
		||||
			while (nd) {
 | 
			
		||||
				nd->nd_type->next = df->df_type;
 | 
			
		||||
				nd = nd->nd_right;
 | 
			
		||||
			}
 | 
			
		||||
			df1->df_forw_type->next = df->df_type;
 | 
			
		||||
			FreeNode(df1->df_forw_node);
 | 
			
		||||
			free_def(df1);
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
		else if (df->df_kind == D_FTYPE) {
 | 
			
		||||
			register struct node *nd = df->df_forw_node;
 | 
			
		||||
 | 
			
		||||
			df->df_kind = D_TYPE;
 | 
			
		||||
			df->df_forw_type->next = df->df_type;
 | 
			
		||||
			while (nd) {
 | 
			
		||||
				nd->nd_type->next = df->df_type;
 | 
			
		||||
				nd = nd->nd_right;
 | 
			
		||||
			}
 | 
			
		||||
			FreeNode(df->df_forw_node);
 | 
			
		||||
		}
 | 
			
		||||
		else if (df->df_kind & (D_FORWARD|D_FORWMODULE)) {
 | 
			
		||||
			/* These definitions must be found in
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -249,11 +249,16 @@ qualified_type(nd)
 | 
			
		|||
		else {
 | 
			
		||||
			register struct def *df = nd->nd_def;
 | 
			
		||||
 | 
			
		||||
			if (df->df_kind&(D_ISTYPE|D_FORWARD|D_ERROR)) {
 | 
			
		||||
			if (df->df_kind&(D_ISTYPE|D_FORWARD|D_FORWTYPE|D_ERROR)) {
 | 
			
		||||
			    if (! df->df_type) {
 | 
			
		||||
node_error(nd,"type \"%s\" not (yet) declared", df->df_idf->id_text);
 | 
			
		||||
			    }
 | 
			
		||||
			    else tp = df->df_type;
 | 
			
		||||
			    else {
 | 
			
		||||
				if (df->df_kind == D_FORWTYPE) {
 | 
			
		||||
					df->df_kind = D_FTYPE;
 | 
			
		||||
				}
 | 
			
		||||
			   	tp = df->df_type;
 | 
			
		||||
			    }
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
node_error(nd,"identifier \"%s\" is not a type", df->df_idf->id_text);
 | 
			
		||||
| 
						 | 
				
			
			@ -577,17 +582,25 @@ type_or_forward(ptp)
 | 
			
		|||
		in "dot". This routine handles the different cases.
 | 
			
		||||
	*/
 | 
			
		||||
	register struct node *nd;
 | 
			
		||||
	register struct def *df1;
 | 
			
		||||
 | 
			
		||||
	*ptp = construct_type(T_POINTER, NULLTYPE);
 | 
			
		||||
	if (lookup(dot.TOK_IDF, CurrentScope, 1)) {
 | 
			
		||||
	if ((df1 = lookup(dot.TOK_IDF, CurrentScope, 1))) {
 | 
			
		||||
		/* Either a Module or a Type, but in both cases defined
 | 
			
		||||
		   in this scope, so this is the correct identification
 | 
			
		||||
		*/
 | 
			
		||||
		if (df1->df_kind == D_FORWTYPE) {
 | 
			
		||||
			nd = new_node();
 | 
			
		||||
			nd->nd_token = dot;
 | 
			
		||||
			nd->nd_right = df1->df_forw_node;
 | 
			
		||||
			df1->df_forw_node = nd;
 | 
			
		||||
			nd->nd_type = *ptp;
 | 
			
		||||
		}
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
	nd = new_node();
 | 
			
		||||
	nd->nd_token = dot;
 | 
			
		||||
	if (lookfor(nd, CurrVis, 0)->df_kind == D_MODULE) {
 | 
			
		||||
	if ((df1 = lookfor(nd, CurrVis, 0))->df_kind == D_MODULE) {
 | 
			
		||||
		/* A Modulename in one of the enclosing scopes.
 | 
			
		||||
		   It is not clear from the language definition that
 | 
			
		||||
		   it is correct to handle these like this, but
 | 
			
		||||
| 
						 | 
				
			
			@ -610,10 +623,14 @@ type_or_forward(ptp)
 | 
			
		|||
 | 
			
		||||
		if (df->df_kind == D_TYPE) {
 | 
			
		||||
			(*ptp)->next = df->df_type;
 | 
			
		||||
			free_node(nd);
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			df->df_forw_type = *ptp;
 | 
			
		||||
			nd->nd_type = *ptp;
 | 
			
		||||
			df->df_forw_node = nd;
 | 
			
		||||
			if (df1->df_kind == D_TYPE) {
 | 
			
		||||
				df->df_type = df1->df_type;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return 0;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -325,7 +325,7 @@ WalkDef(df)
 | 
			
		|||
			WalkProcedure(df);
 | 
			
		||||
			break;
 | 
			
		||||
		case D_VARIABLE:
 | 
			
		||||
			if (!proclevel  && !df->var_addrgiven) {
 | 
			
		||||
			if (!proclevel  && !(df->df_flags & D_ADDRGIVEN)) {
 | 
			
		||||
				C_df_dnam(df->var_name);
 | 
			
		||||
				C_bss_cst(
 | 
			
		||||
					WA(df->df_type->tp_size),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue