newer version
This commit is contained in:
		
							parent
							
								
									64a9f1e5d7
								
							
						
					
					
						commit
						7d76f2829a
					
				
					 8 changed files with 177 additions and 76 deletions
				
			
		|  | @ -24,7 +24,7 @@ ProcedureDeclaration | ||||||
| 	';' block IDENT | 	';' block IDENT | ||||||
| 			{ match_id(dot.TOK_IDF, df->df_idf); | 			{ match_id(dot.TOK_IDF, df->df_idf); | ||||||
| 			  df->prc_scope = CurrentScope->sc_scope; | 			  df->prc_scope = CurrentScope->sc_scope; | ||||||
| 			  close_scope(); | 			  close_scope(SC_CHKFORW); | ||||||
| 			} | 			} | ||||||
| ; | ; | ||||||
| 
 | 
 | ||||||
|  | @ -39,6 +39,7 @@ ProcedureHeading(struct def **pdf; int type;) | ||||||
| 			{ assert(type & (D_PROCEDURE | D_PROCHEAD)); | 			{ assert(type & (D_PROCEDURE | D_PROCHEAD)); | ||||||
| 			  if (type == D_PROCHEAD) { | 			  if (type == D_PROCHEAD) { | ||||||
| 				df = define(dot.TOK_IDF, CurrentScope, type); | 				df = define(dot.TOK_IDF, CurrentScope, type); | ||||||
|  | 				df->for_node = MkNode(Name, NULLNODE, NULLNODE, &dot); | ||||||
| 			  } | 			  } | ||||||
| 			  else { | 			  else { | ||||||
| 				df = lookup(dot.TOK_IDF, | 				df = lookup(dot.TOK_IDF, | ||||||
|  |  | ||||||
|  | @ -43,12 +43,15 @@ struct dfproc { | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct import { | struct import { | ||||||
| 	union { | 	struct def *im_def;	/* imported definition */ | ||||||
| 		struct def *im_def; /* imported definition */ | #define imp_def		df_value.df_import.im_def | ||||||
| 		struct node *im_nodef; /* imported from undefined name */ | }; | ||||||
| 	} im_u; | 
 | ||||||
| #define imp_def		df_value.df_import.im_u.im_def | struct dforward { | ||||||
| #define imp_nodef	df_value.df_import.im_u.im_nodef | 	int fo_scope; | ||||||
|  | 	struct node *fo_node; | ||||||
|  | #define for_node	df_value.df_forward.fo_node | ||||||
|  | #define for_scope	df_value.df_forward.fo_scope | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct def	{		/* list of definitions for a name */ | struct def	{		/* list of definitions for a name */ | ||||||
|  | @ -92,6 +95,7 @@ struct def	{		/* list of definitions for a name */ | ||||||
| 		struct field df_field; | 		struct field df_field; | ||||||
| 		struct import df_import; | 		struct import df_import; | ||||||
| 		struct dfproc df_proc; | 		struct dfproc df_proc; | ||||||
|  | 		struct dforward df_forward; | ||||||
| 		int df_stdname;	/* define for standard name */ | 		int df_stdname;	/* define for standard name */ | ||||||
| 	} df_value; | 	} df_value; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -61,13 +61,23 @@ define(id, scope, kind) | ||||||
| 			} | 			} | ||||||
| 			break; | 			break; | ||||||
| 		case D_FORWMODULE: | 		case D_FORWMODULE: | ||||||
| 			if (kind & (D_FORWMODULE|D_MODULE)) { | 			if (kind == D_FORWMODULE) { | ||||||
|  | 				df->df_kind = kind; | ||||||
|  | 				return df; | ||||||
|  | 			} | ||||||
|  | 			if (kind == D_MODULE) { | ||||||
|  | 				FreeNode(df->for_node); | ||||||
|  | 				df->mod_scope = df->for_scope; | ||||||
| 				df->df_kind = kind; | 				df->df_kind = kind; | ||||||
| 				return df; | 				return df; | ||||||
| 			} | 			} | ||||||
| 			break; | 			break; | ||||||
| 		case D_ERROR: |  | ||||||
| 		case D_FORWARD: | 		case D_FORWARD: | ||||||
|  | 			if (kind != D_FORWARD) { | ||||||
|  | 				FreeNode(df->for_node); | ||||||
|  | 			} | ||||||
|  | 			/* Fall Through */ | ||||||
|  | 		case D_ERROR: | ||||||
| 			df->df_kind = kind; | 			df->df_kind = kind; | ||||||
| 			return df; | 			return df; | ||||||
| 		} | 		} | ||||||
|  | @ -77,11 +87,11 @@ error("identifier \"%s\" already declared", id->id_text); | ||||||
| 		return df; | 		return df; | ||||||
| 	} | 	} | ||||||
| 	df = new_def(); | 	df = new_def(); | ||||||
|  | 	df->df_flags = 0; | ||||||
| 	df->df_idf = id; | 	df->df_idf = id; | ||||||
| 	df->df_scope = scope->sc_scope; | 	df->df_scope = scope->sc_scope; | ||||||
| 	df->df_kind = kind; | 	df->df_kind = kind; | ||||||
| 	df->next = id->id_def; | 	df->next = id->id_def; | ||||||
| 	df->df_flags = 0; |  | ||||||
| 	id->id_def = df; | 	id->id_def = df; | ||||||
| 
 | 
 | ||||||
| 	/* enter the definition in the list of definitions in this scope */ | 	/* enter the definition in the list of definitions in this scope */ | ||||||
|  | @ -100,30 +110,17 @@ lookup(id, scope) | ||||||
| 		otherwise return 0. | 		otherwise return 0. | ||||||
| 	*/ | 	*/ | ||||||
| 	register struct def *df, *df1; | 	register struct def *df, *df1; | ||||||
|  | 	struct def *retval; | ||||||
| 
 | 
 | ||||||
| 	df1 = 0; | 	df1 = 0; | ||||||
| 	df = id->id_def; | 	df = id->id_def; | ||||||
| 	DO_DEBUG(5, debug("Looking for identifier \"%s\" in scope %d", id->id_text, scope)); | 	DO_DEBUG(5, debug("Looking for identifier \"%s\" in scope %d", id->id_text, scope)); | ||||||
| 	while (df) { | 	while (df) { | ||||||
| 		if (df->df_scope == scope) { | 		if (df->df_scope == scope) { | ||||||
|  | 			retval = df; | ||||||
| 			if (df->df_kind == D_IMPORT) { | 			if (df->df_kind == D_IMPORT) { | ||||||
| 				df = df->imp_def; | 				retval = df->imp_def; | ||||||
| 				assert(df != 0); | 				assert(retval != 0); | ||||||
| 				return df; |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			if (df->df_kind == D_UNDEF_IMPORT) {	 |  | ||||||
| 				df1 = df->imp_def; |  | ||||||
| 				assert(df1 != 0); |  | ||||||
| 				if (df1->df_kind == D_MODULE) { |  | ||||||
| 					df1 = lookup(id, df1->mod_scope); |  | ||||||
| 					if (df1) { |  | ||||||
| 						df->df_kind = D_IMPORT; |  | ||||||
| 						df->imp_def = df1; |  | ||||||
| 					} |  | ||||||
| 					return df1; |  | ||||||
| 				} |  | ||||||
| 				return df; |  | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			if (df1) { | 			if (df1) { | ||||||
|  | @ -131,7 +128,7 @@ lookup(id, scope) | ||||||
| 				df->next = id->id_def; | 				df->next = id->id_def; | ||||||
| 				id->id_def = df; | 				id->id_def = df; | ||||||
| 			} | 			} | ||||||
| 			return df; | 			return retval; | ||||||
| 		} | 		} | ||||||
| 		df1 = df; | 		df1 = df; | ||||||
| 		df = df->next; | 		df = df->next; | ||||||
|  | @ -148,9 +145,19 @@ Export(ids, qualified) | ||||||
| 		in this scope as "imported". | 		in this scope as "imported". | ||||||
| 	*/ | 	*/ | ||||||
| 	register struct def *df, *df1; | 	register struct def *df, *df1; | ||||||
|  | 	struct node *nd = ids; | ||||||
| 
 | 
 | ||||||
| 	while (ids) { | 	while (ids) { | ||||||
| 		df = define(ids->nd_IDF, CurrentScope, D_FORWARD); | 		df = lookup(ids->nd_IDF, CurrentScope->sc_scope); | ||||||
|  | 		if (df && (df->df_flags & (D_EXPORTED|D_QEXPORTED))) { | ||||||
|  | node_error(ids, "Identifier \"%s\" occurs more than once in export list", | ||||||
|  | df->df_idf->id_text); | ||||||
|  | 		} | ||||||
|  | 		else if (!df) { | ||||||
|  | 			df = define(ids->nd_IDF, CurrentScope, D_FORWARD); | ||||||
|  | 			df->for_node = MkNode(Name,NULLNODE,NULLNODE, | ||||||
|  | 					&(ids->nd_token)); | ||||||
|  | 		} | ||||||
| 		if (qualified) { | 		if (qualified) { | ||||||
| 			df->df_flags |= D_QEXPORTED; | 			df->df_flags |= D_QEXPORTED; | ||||||
| 		} | 		} | ||||||
|  | @ -175,6 +182,7 @@ Export(ids, qualified) | ||||||
| 		} | 		} | ||||||
| 		ids = ids->next; | 		ids = ids->next; | ||||||
| 	} | 	} | ||||||
|  | 	FreeNode(nd); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| Import(ids, idn, local) | Import(ids, idn, local) | ||||||
|  | @ -195,6 +203,7 @@ Import(ids, idn, local) | ||||||
| 		identifiers defined in this module. | 		identifiers defined in this module. | ||||||
| 	*/ | 	*/ | ||||||
| 	register struct def *df; | 	register struct def *df; | ||||||
|  | 	struct def *df1 = 0; | ||||||
| 	int scope; | 	int scope; | ||||||
| 	int kind; | 	int kind; | ||||||
| 	int imp_kind; | 	int imp_kind; | ||||||
|  | @ -204,7 +213,8 @@ Import(ids, idn, local) | ||||||
| 
 | 
 | ||||||
| 	kind = D_IMPORT; | 	kind = D_IMPORT; | ||||||
| 	scope = enclosing(CurrentScope)->sc_scope; | 	scope = enclosing(CurrentScope)->sc_scope; | ||||||
| 	if (!idn) imp_kind = FROM_ENCLOSING; | 
 | ||||||
|  | 	if (! idn) imp_kind = FROM_ENCLOSING; | ||||||
| 	else { | 	else { | ||||||
| 		imp_kind = FROM_MODULE; | 		imp_kind = FROM_MODULE; | ||||||
| 		if (local) { | 		if (local) { | ||||||
|  | @ -217,25 +227,39 @@ Import(ids, idn, local) | ||||||
| 				*/ | 				*/ | ||||||
| 				df->df_scope = scope; | 				df->df_scope = scope; | ||||||
| 				df->df_kind = D_FORWMODULE; | 				df->df_kind = D_FORWMODULE; | ||||||
| 				df->mod_scope = -1; | 				open_scope(CLOSEDSCOPE, 0); | ||||||
| 				kind = D_UNDEF_IMPORT; | 				df->for_scope = CurrentScope->sc_scope; | ||||||
|  | 				df->for_node = MkNode(Name, NULLNODE, | ||||||
|  | 						NULLNODE, &(idn->nd_token)); | ||||||
|  | 				close_scope(); | ||||||
|  | 				df1 = df; | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		else { | 		else	df = GetDefinitionModule(idn->nd_IDF); | ||||||
| 			df = GetDefinitionModule(idn->nd_IDF); | 
 | ||||||
| 		} |  | ||||||
| 		if (!(df->df_kind & (D_MODULE|D_FORWMODULE))) { | 		if (!(df->df_kind & (D_MODULE|D_FORWMODULE))) { | ||||||
| 			/* enter all "ids" with type D_ERROR */ | 			/* enter all "ids" with type D_ERROR */ | ||||||
| 			kind = D_ERROR; | 			kind = D_ERROR; | ||||||
| 			if (df->df_kind != D_ERROR) { | 			if (df->df_kind != D_ERROR) { | ||||||
| node_error(idn, "identifier \"%s\" does not represent a module", idn->nd_IDF->id_text); | node_error(idn, "identifier \"%s\" does not represent a module", | ||||||
|  | idn->nd_IDF->id_text); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		else	scope = df->mod_scope; | 		else	scope = df->mod_scope; | ||||||
|  | 		FreeNode(idn); | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
|  | 	idn = ids; | ||||||
| 	while (ids) { | 	while (ids) { | ||||||
| 		if (imp_kind == FROM_MODULE) { | 		if (imp_kind == FROM_MODULE) { | ||||||
| 			if (scope == -1) { | 			if (df1 != 0) { | ||||||
|  | 				open_scope(CLOSEDSCOPE, df1->mod_scope); | ||||||
|  | 				df = define(ids->nd_IDF, | ||||||
|  | 					    CurrentScope, | ||||||
|  | 					    D_FORWARD); | ||||||
|  | 				df->for_node = MkNode(Name, NULLNODE, | ||||||
|  | 						NULLNODE, &(ids->nd_token)); | ||||||
|  | 				close_scope(0); | ||||||
| 			} | 			} | ||||||
| 			else if (!(df = lookup(ids->nd_IDF, scope))) { | 			else if (!(df = lookup(ids->nd_IDF, scope))) { | ||||||
| node_error(ids, "identifier \"%s\" not declared in qualifying module", | node_error(ids, "identifier \"%s\" not declared in qualifying module", | ||||||
|  | @ -250,13 +274,18 @@ ids->nd_IDF->id_text); | ||||||
| 		else { | 		else { | ||||||
| 			if (local) { | 			if (local) { | ||||||
| 				df = lookfor(ids, enclosing(CurrentScope), 0); | 				df = lookfor(ids, enclosing(CurrentScope), 0); | ||||||
| 			} else df = GetDefinitionModule(ids->nd_IDF); | 			} else	df = GetDefinitionModule(ids->nd_IDF); | ||||||
| 			if (df->df_kind == D_ERROR) { | 			if (df->df_kind == D_ERROR) { | ||||||
| node_error(ids, "identifier \"%s\" not visible in enclosing scope", | 				/* It was not yet defined in the enclosing
 | ||||||
| ids->nd_IDF->id_text); | 				   scope. | ||||||
|  | 				*/ | ||||||
|  | 				df->df_kind = D_FORWARD; | ||||||
|  | 				df->for_node = MkNode(Name, NULLNODE, NULLNODE, | ||||||
|  | 							&(ids->nd_token)); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		DO_DEBUG(2, debug("importing \"%s\", kind %d", ids->nd_IDF->id_text, df->df_kind)); | DO_DEBUG(2, debug("importing \"%s\", kind %d", ids->nd_IDF->id_text, | ||||||
|  | df->df_kind)); | ||||||
| 		define(ids->nd_IDF, CurrentScope, kind)->imp_def = df; | 		define(ids->nd_IDF, CurrentScope, kind)->imp_def = df; | ||||||
| 		if (df->df_kind == D_TYPE && | 		if (df->df_kind == D_TYPE && | ||||||
| 		    df->df_type->tp_fund == T_ENUMERATION) { | 		    df->df_type->tp_fund == T_ENUMERATION) { | ||||||
|  | @ -266,6 +295,7 @@ ids->nd_IDF->id_text); | ||||||
| 		} | 		} | ||||||
| 		ids = ids->next; | 		ids = ids->next; | ||||||
| 	} | 	} | ||||||
|  | 	FreeNode(idn); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| exprt_literals(df, toscope) | exprt_literals(df, toscope) | ||||||
|  | @ -290,26 +320,18 @@ RemImports(pdf) | ||||||
| 		neccesary because the implementation module might import | 		neccesary because the implementation module might import | ||||||
| 		them again. | 		them again. | ||||||
| 	*/ | 	*/ | ||||||
| 	register struct def *df = *pdf, *df1 = 0; | 	register struct def *df = *pdf; | ||||||
| 
 | 
 | ||||||
| 	while (df) { | 	while (df) { | ||||||
| 		if (df->df_kind == D_IMPORT) { | 		if (df->df_kind == D_IMPORT) { | ||||||
| 			RemFromId(df); | 			RemFromId(df); | ||||||
| 			if (df1) { | 			*pdf = df->df_nextinscope; | ||||||
| 				df1->df_nextinscope = df->df_nextinscope; | 			free_def(df); | ||||||
| 				free_def(df); |  | ||||||
| 				df = df1->df_nextinscope; |  | ||||||
| 			} |  | ||||||
| 			else { |  | ||||||
| 				*pdf = df->df_nextinscope; |  | ||||||
| 				free_def(df); |  | ||||||
| 				df = *pdf; |  | ||||||
| 			} |  | ||||||
| 		} | 		} | ||||||
| 		else { | 		else { | ||||||
| 			df1 = df; | 			pdf = &(df->df_nextinscope); | ||||||
| 			df = df->df_nextinscope; |  | ||||||
| 		} | 		} | ||||||
|  | 		df = *pdf; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -49,8 +49,12 @@ qualident(int types; struct def **pdf; char *str; struct node **p;) | ||||||
| 				assert(nd->nd_class == Def); | 				assert(nd->nd_class == Def); | ||||||
| 				*pdf = df = nd->nd_def; | 				*pdf = df = nd->nd_def; | ||||||
| 			  	if ( !((types|D_ERROR) & df->df_kind)) { | 			  	if ( !((types|D_ERROR) & df->df_kind)) { | ||||||
| 					error("identifier \"%s\" is not a %s", | 					if (df->df_kind == D_FORWARD) { | ||||||
| 					df->df_idf->id_text, str); | node_error(*pnd,"%s \"%s\" not declared", str, df->df_idf->id_text); | ||||||
|  | 					} | ||||||
|  | 					else { | ||||||
|  | node_error(*pnd,"identifier \"%s\" is not a %s", df->df_idf->id_text, str); | ||||||
|  | 					} | ||||||
| 				} | 				} | ||||||
| 			  } | 			  } | ||||||
| 			  if (!p) FreeNode(nd); | 			  if (!p) FreeNode(nd); | ||||||
|  |  | ||||||
|  | @ -38,6 +38,7 @@ FreeNode(nd) | ||||||
| 	/*	Put nodes that are no longer needed back onto the free
 | 	/*	Put nodes that are no longer needed back onto the free
 | ||||||
| 		list | 		list | ||||||
| 	*/ | 	*/ | ||||||
|  | 	if (!nd) return; | ||||||
| 	if (nd->nd_left) FreeNode(nd->nd_left); | 	if (nd->nd_left) FreeNode(nd->nd_left); | ||||||
| 	if (nd->nd_right) FreeNode(nd->nd_right); | 	if (nd->nd_right) FreeNode(nd->nd_right); | ||||||
| 	free_node(nd); | 	free_node(nd); | ||||||
|  |  | ||||||
|  | @ -15,7 +15,11 @@ static  char *RcsId = "$Header$"; | ||||||
| #include	"node.h" | #include	"node.h" | ||||||
| #include	"debug.h" | #include	"debug.h" | ||||||
| 
 | 
 | ||||||
| static struct idf *impl_name = 0; | static int DEFofIMPL = 0;	/* Flag indicating that we are currently | ||||||
|  | 				   parsing the definition module of the | ||||||
|  | 				   implementation module currently being | ||||||
|  | 				   compiled | ||||||
|  | 				*/ | ||||||
| static struct def *impl_df; | static struct def *impl_df; | ||||||
| } | } | ||||||
| /* | /* | ||||||
|  | @ -45,8 +49,11 @@ ModuleDeclaration | ||||||
| 	MODULE IDENT		{ | 	MODULE IDENT		{ | ||||||
| 				  id = dot.TOK_IDF; | 				  id = dot.TOK_IDF; | ||||||
| 				  df = define(id, CurrentScope, D_MODULE); | 				  df = define(id, CurrentScope, D_MODULE); | ||||||
| 				  open_scope(CLOSEDSCOPE, 0); | 				  if (!df->mod_scope) {	 | ||||||
| 				  df->mod_scope = CurrentScope->sc_scope; | 				  	open_scope(CLOSEDSCOPE, 0); | ||||||
|  | 				  	df->mod_scope = CurrentScope->sc_scope; | ||||||
|  | 				  } | ||||||
|  | 				  else	open_scope(CLOSEDSCOPE, df->mod_scope); | ||||||
| 				  df->df_type =  | 				  df->df_type =  | ||||||
| 					standard_type(T_RECORD, 0, (arith) 0); | 					standard_type(T_RECORD, 0, (arith) 0); | ||||||
| 				  df->df_type->rec_scope = df->mod_scope; | 				  df->df_type->rec_scope = df->mod_scope; | ||||||
|  | @ -55,7 +62,7 @@ ModuleDeclaration | ||||||
| 	import(1)* | 	import(1)* | ||||||
| 	export(0)? | 	export(0)? | ||||||
| 	block | 	block | ||||||
| 	IDENT			{ close_scope(); | 	IDENT			{ close_scope(SC_CHKFORW|SC_CHKPROC); | ||||||
| 				  match_id(id, dot.TOK_IDF); | 				  match_id(id, dot.TOK_IDF); | ||||||
| 				} | 				} | ||||||
| ; | ; | ||||||
|  | @ -78,9 +85,13 @@ export(int def;) | ||||||
| 	]? | 	]? | ||||||
| 	IdentList(&ExportList) ';' | 	IdentList(&ExportList) ';' | ||||||
| 			{ | 			{ | ||||||
| 			  if (!def) Export(ExportList, QUALflag); | 			  if (!def) { | ||||||
| 			  else warning("export list in definition module ignored"); | 				Export(ExportList, QUALflag); | ||||||
| 			  FreeNode(ExportList); | 			  } | ||||||
|  | 			  else { | ||||||
|  | 			  warning("export list in definition module ignored"); | ||||||
|  | 				FreeNode(ExportList); | ||||||
|  | 			  } | ||||||
| 			} | 			} | ||||||
| ; | ; | ||||||
| 
 | 
 | ||||||
|  | @ -101,8 +112,6 @@ import(int local;) | ||||||
| 	*/ | 	*/ | ||||||
| 			{ | 			{ | ||||||
| 			  Import(ImportList, id, local); | 			  Import(ImportList, id, local); | ||||||
| 			  FreeNode(ImportList); |  | ||||||
| 			  if (id) FreeNode(id); |  | ||||||
| 			} | 			} | ||||||
| ; | ; | ||||||
| 
 | 
 | ||||||
|  | @ -130,7 +139,7 @@ DefinitionModule | ||||||
| 	*/ | 	*/ | ||||||
| 	definition* END IDENT | 	definition* END IDENT | ||||||
| 			{ | 			{ | ||||||
| 			  if (id == impl_name) { | 			  if (DEFofIMPL) { | ||||||
| 				/* Just read the definition module of the | 				/* Just read the definition module of the | ||||||
| 				   implementation module being compiled | 				   implementation module being compiled | ||||||
| 				*/ | 				*/ | ||||||
|  | @ -143,7 +152,7 @@ DefinitionModule | ||||||
| 				df->df_flags |= D_QEXPORTED; | 				df->df_flags |= D_QEXPORTED; | ||||||
| 				df = df->df_nextinscope; | 				df = df->df_nextinscope; | ||||||
| 			  } | 			  } | ||||||
| 			  if (!SYSTEMModule) close_scope(); | 			  if (!SYSTEMModule) close_scope(SC_CHKFORW); | ||||||
| 			  DefinitionModule = 0; | 			  DefinitionModule = 0; | ||||||
| 			  match_id(id, dot.TOK_IDF); | 			  match_id(id, dot.TOK_IDF); | ||||||
| 			} | 			} | ||||||
|  | @ -185,9 +194,10 @@ ProgramModule(int state;) | ||||||
| 	IDENT		{  | 	IDENT		{  | ||||||
| 			  id = dot.TOK_IDF; | 			  id = dot.TOK_IDF; | ||||||
| 			  if (state == IMPLEMENTATION) { | 			  if (state == IMPLEMENTATION) { | ||||||
| 				   impl_name = id; | 				   DEFofIMPL = 1; | ||||||
| 				   df = GetDefinitionModule(id); | 				   df = GetDefinitionModule(id); | ||||||
| 				   scope = df->mod_scope; | 				   scope = df->mod_scope; | ||||||
|  | 				   DEFofIMPL = 0; | ||||||
| 			  } | 			  } | ||||||
| 			  DefinitionModule = 0; | 			  DefinitionModule = 0; | ||||||
| 			  open_scope(CLOSEDSCOPE, scope); | 			  open_scope(CLOSEDSCOPE, scope); | ||||||
|  | @ -196,7 +206,7 @@ ProgramModule(int state;) | ||||||
| 	priority? | 	priority? | ||||||
| 	';' import(0)* | 	';' import(0)* | ||||||
| 	block IDENT | 	block IDENT | ||||||
| 			{ close_scope(); | 			{ close_scope(SC_CHKFORW|SC_CHKPROC); | ||||||
| 			  match_id(id, dot.TOK_IDF); | 			  match_id(id, dot.TOK_IDF); | ||||||
| 			} | 			} | ||||||
| 	'.' | 	'.' | ||||||
|  |  | ||||||
|  | @ -92,21 +92,73 @@ Forward(tk, ptp) | ||||||
| 	CurrentScope->sc_forw = f; | 	CurrentScope->sc_forw = f; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| close_scope() | close_scope(flag) | ||||||
| { | { | ||||||
|  | 	/*	Close a scope. If "flag" is set, check for forward declarations,
 | ||||||
|  | 		either POINTER declarations, or EXPORTs, or forward references | ||||||
|  | 		to MODULES | ||||||
|  | 	*/ | ||||||
| 	register struct scope *sc = CurrentScope; | 	register struct scope *sc = CurrentScope; | ||||||
|  | 	register struct def *df, *dfback = 0; | ||||||
| 
 | 
 | ||||||
| 	assert(sc != 0); | 	assert(sc != 0); | ||||||
| 	DO_DEBUG(1, debug("Closing a scope")); | 	DO_DEBUG(1, debug("Closing a scope")); | ||||||
| 	if (sc->sc_forw) rem_forwards(sc->sc_forw); |  | ||||||
| 	if (sc->next && (sc->next->sc_scope == 0)) { |  | ||||||
| 		struct scope *sc1 = sc; |  | ||||||
| 
 | 
 | ||||||
|  | 	if (flag) { | ||||||
|  | 		if (sc->sc_forw) rem_forwards(sc->sc_forw); | ||||||
|  | 		df = sc->sc_def; | ||||||
|  | 		while(df) { | ||||||
|  | 			if (flag & SC_CHKPROC) { | ||||||
|  | 				if (df->df_kind == D_PROCHEAD) { | ||||||
|  | 					/* A not defined procedure
 | ||||||
|  | 					*/ | ||||||
|  | node_error(df->for_node, "procedure \"%s\" not defined", df->df_idf->id_text); | ||||||
|  | 					FreeNode(df->for_node); | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 			if ((flag & SC_CHKFORW) &&  | ||||||
|  | 			    df->df_kind & (D_FORWARD|D_FORWMODULE)) { | ||||||
|  | 				/* These definitions must be found in
 | ||||||
|  | 				   the enclosing closed scope, which of course | ||||||
|  | 				   may be the scope that is now closed! | ||||||
|  | 				*/ | ||||||
|  | 				struct def *df1 = df->df_nextinscope; | ||||||
|  | 
 | ||||||
|  | 				if (scopeclosed(CurrentScope)) { | ||||||
|  | 					/* Indeed, the scope was a closed
 | ||||||
|  | 					   scope, so give error message | ||||||
|  | 					*/ | ||||||
|  | node_error(df->for_node, "identifier \"%s\" not declared", df->df_idf->id_text); | ||||||
|  | 					FreeNode(df->for_node); | ||||||
|  | 					dfback = df; | ||||||
|  | 				} | ||||||
|  | 				else { | ||||||
|  | 					/* This scope was an open scope.
 | ||||||
|  | 					   Maybe the definitions are in the | ||||||
|  | 					   enclosing scope? | ||||||
|  | 					*/ | ||||||
|  | 					struct scope *sc; | ||||||
|  | 
 | ||||||
|  | 					sc = enclosing(CurrentScope); | ||||||
|  | 					df->df_nextinscope = sc->sc_def; | ||||||
|  | 					sc->sc_def = df; | ||||||
|  | 					df->df_scope = sc->sc_scope; | ||||||
|  | 					if (dfback) dfback->df_nextinscope = df1; | ||||||
|  | 					else sc->sc_def = df1; | ||||||
|  | 				} | ||||||
|  | 				df = df1; | ||||||
|  | 			} | ||||||
|  | 			else { | ||||||
|  | 				dfback = df; | ||||||
|  | 				df = df->df_nextinscope; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (sc->next && (sc->next->sc_scope == 0)) { | ||||||
| 		sc = sc->next; | 		sc = sc->next; | ||||||
| 		free_scope(sc1); |  | ||||||
| 	} | 	} | ||||||
| 	CurrentScope = sc->next; | 	CurrentScope = sc->next; | ||||||
| 	free_scope(sc); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static | static | ||||||
|  | @ -121,7 +173,7 @@ rem_forwards(fo) | ||||||
| 
 | 
 | ||||||
| 	while (f = fo) { | 	while (f = fo) { | ||||||
| 		df = lookfor(&(f->fo_tok), CurrentScope, 1); | 		df = lookfor(&(f->fo_tok), CurrentScope, 1); | ||||||
| 		if (!(df->df_kind & (D_TYPE | D_HTYPE | D_ERROR))) { | 		if (!(df->df_kind & (D_TYPE|D_HTYPE|D_ERROR))) { | ||||||
| 			node_error(&(f->fo_tok), "identifier \"%s\" not a type", | 			node_error(&(f->fo_tok), "identifier \"%s\" not a type", | ||||||
| 			      df->df_idf->id_text); | 			      df->df_idf->id_text); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | @ -5,6 +5,13 @@ | ||||||
| #define OPENSCOPE	0	/* Indicating an open scope */ | #define OPENSCOPE	0	/* Indicating an open scope */ | ||||||
| #define CLOSEDSCOPE	1	/* Indicating a closed scope (module) */ | #define CLOSEDSCOPE	1	/* Indicating a closed scope (module) */ | ||||||
| 
 | 
 | ||||||
|  | #define SC_CHKFORW	1	/* Check for forward definitions when closing | ||||||
|  | 				   a scope | ||||||
|  | 				*/ | ||||||
|  | #define SC_CHKPROC	2	/* Check for forward procedure definitions | ||||||
|  | 				   when closing a scope | ||||||
|  | 				*/ | ||||||
|  | 
 | ||||||
| struct scope { | struct scope { | ||||||
| 	struct scope *next; | 	struct scope *next; | ||||||
| 	struct forwards *sc_forw; | 	struct forwards *sc_forw; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue