safety commit, newer version
This commit is contained in:
		
							parent
							
								
									851a68883c
								
							
						
					
					
						commit
						f2764393be
					
				
					 15 changed files with 444 additions and 126 deletions
				
			
		|  | @ -76,12 +76,12 @@ idf.o: idf.h | |||
| input.o: f_info.h input.h | ||||
| type.o: Lpars.h def.h def_sizes.h idf.h type.h | ||||
| def.o: Lpars.h debug.h def.h idf.h main.h scope.h | ||||
| scope.o: debug.h scope.h | ||||
| scope.o: LLlex.h debug.h def.h idf.h scope.h type.h | ||||
| misc.o: LLlex.h f_info.h idf.h misc.h | ||||
| enter.o: def.h idf.h misc.h scope.h type.h | ||||
| tokenfile.o: Lpars.h | ||||
| program.o: LLlex.h Lpars.h def.h idf.h main.h misc.h scope.h type.h | ||||
| declar.o: LLlex.h Lpars.h def.h idf.h misc.h scope.h type.h | ||||
| expression.o: Lpars.h | ||||
| expression.o: LLlex.h Lpars.h def.h idf.h scope.h | ||||
| statement.o: Lpars.h | ||||
| Lpars.o: Lpars.h | ||||
|  |  | |||
|  | @ -27,15 +27,17 @@ ProcedureDeclaration | |||
| 
 | ||||
| ProcedureHeading(struct def **pdf; int type;) | ||||
| { | ||||
| 	struct type *tp; | ||||
| 	struct paramlist *params = 0; | ||||
| } : | ||||
| 	PROCEDURE IDENT | ||||
| 			{ assert(type == D_PROCEDURE || type == D_PROCHEAD); | ||||
| 			  *pdf = define(dot.TOK_IDF, CurrentScope, D_PROCHEAD); | ||||
| 			  *pdf = define(dot.TOK_IDF, CurrentScope, type); | ||||
| 			  if (type == D_PROCEDURE) { | ||||
| 				open_scope(OPENSCOPE, 0); | ||||
| 			  } | ||||
| 			} | ||||
| 	FormalParameters(type, &((*pdf)->df_type))? | ||||
| 	FormalParameters(type, ¶ms, &tp)? | ||||
| ; | ||||
| 
 | ||||
| block: | ||||
|  | @ -54,15 +56,31 @@ declaration: | |||
| 	ModuleDeclaration ';' | ||||
| ; | ||||
| 
 | ||||
| FormalParameters(int doparams; struct type **tp;) : | ||||
| 	'(' [ FPSection(doparams) [ ';' FPSection(doparams)]* ]? ')' | ||||
| 	[ ':' qualident | ||||
| FormalParameters(int doparams; struct paramlist **pr; struct type **tp;) | ||||
| { | ||||
| 	struct def *df; | ||||
| 	register struct paramlist *pr1; | ||||
| } : | ||||
| 	'(' | ||||
| 	[ | ||||
| 		FPSection(doparams, pr) | ||||
| 		[ | ||||
| 			{ for (pr1 = *pr; pr1->next; pr1 = pr1->next) ; } | ||||
| 			';' FPSection(doparams, &(pr1->next)) | ||||
| 		]* | ||||
| 	]? | ||||
| 	')' | ||||
| 			{ *tp = 0; } | ||||
| 	[ ':' qualident(D_TYPE | D_HTYPE, &df, "type") | ||||
| 			{ /* ???? *tp = df->df_type; */ } | ||||
| 	]? | ||||
| ; | ||||
| 
 | ||||
| FPSection(int doparams;) | ||||
| FPSection(int doparams; struct paramlist **ppr;) | ||||
| { | ||||
| 	struct id_list *FPList; | ||||
| 	register struct id_list *pid; | ||||
| 	register struct paramlist *pr = 0; | ||||
| 	int VARflag = 0; | ||||
| } : | ||||
| 	[ | ||||
|  | @ -74,70 +92,88 @@ FPSection(int doparams;) | |||
| 				EnterIdList(FPList, | ||||
| 					    D_VARIABLE, | ||||
| 					    VARflag, | ||||
| 					    (struct type *) 0	/* ???? */ | ||||
| 					    (struct type *) 0	/* ???? */, | ||||
| 					    CurrentScope | ||||
| 				); | ||||
| 			  } | ||||
| 			  *ppr = pr = new_paramlist(); | ||||
| 			  pr->par_type = 0;	/* ??? */ | ||||
| 			  pr->par_var = VARflag; | ||||
| 			  for (pid = FPList->next; pid; pid = pid->next) { | ||||
| 				pr->next = new_paramlist(); | ||||
| 				pr = pr->next; | ||||
| 				pr->par_type = 0;	/* ??? */ | ||||
| 				pr->par_var = VARflag; | ||||
| 			  } | ||||
| 			  pr->next = 0; | ||||
| 			  FreeIdList(FPList); | ||||
| 			} | ||||
| ; | ||||
| 
 | ||||
| FormalType: | ||||
| 	[ ARRAY OF ]? qualident | ||||
| FormalType | ||||
| { | ||||
| 	struct def *df; | ||||
| 	int ARRAYflag = 0; | ||||
| } : | ||||
| 	[ ARRAY OF	{ ARRAYflag = 1; } | ||||
| 	]? | ||||
| 	qualident(D_TYPE | D_HTYPE, &df, "type") | ||||
| ; | ||||
| 
 | ||||
| TypeDeclaration | ||||
| { | ||||
| 	struct def *df; | ||||
| 	struct idf *id; | ||||
| 	struct type *tp; | ||||
| }: | ||||
| 	IDENT		{ id = dot.TOK_IDF; } | ||||
| 	'=' type	{ df = define(id, CurrentScope, D_TYPE); | ||||
| 			  /* ???? */ | ||||
| 	IDENT		{ df = define(dot.TOK_IDF, CurrentScope, D_TYPE); } | ||||
| 	'=' type(&tp) | ||||
| 			{ df->df_type = tp; | ||||
| 			} | ||||
| ; | ||||
| 
 | ||||
| type: | ||||
| 	SimpleType | ||||
| type(struct type **ptp;): | ||||
| 	SimpleType(ptp) | ||||
| | | ||||
| 	ArrayType | ||||
| 	ArrayType(ptp) | ||||
| | | ||||
| 	RecordType | ||||
| 	RecordType(ptp) | ||||
| | | ||||
| 	SetType | ||||
| 	SetType(ptp) | ||||
| | | ||||
| 	PointerType | ||||
| 	PointerType(ptp) | ||||
| | | ||||
| 	ProcedureType | ||||
| 	ProcedureType(ptp) | ||||
| ; | ||||
| 
 | ||||
| SimpleType: | ||||
| 	qualident | ||||
| SimpleType(struct type **ptp;) | ||||
| { | ||||
| 	struct def *df; | ||||
| } : | ||||
| 	qualident(D_TYPE | D_HTYPE, &df, "type") | ||||
| 	[ | ||||
| 
 | ||||
| 	| | ||||
| 		SubrangeType | ||||
| 		SubrangeType(ptp) | ||||
| 		/* | ||||
| 		 * The subrange type is given a base type by the | ||||
| 		 * qualident (this is new modula-2). | ||||
| 		 */ | ||||
| 			{ /* ???? (*ptp)->next = df->df_type; */ } | ||||
| 	] | ||||
| | | ||||
| 	enumeration | ||||
| 	enumeration(ptp) | ||||
| | | ||||
| 	SubrangeType | ||||
| 	SubrangeType(ptp) | ||||
| ; | ||||
| 
 | ||||
| enumeration | ||||
| enumeration(struct type **ptp;) | ||||
| { | ||||
| 	struct id_list *EnumList; | ||||
| } : | ||||
| 	'(' IdentList(&EnumList) ')' | ||||
| 			{ | ||||
| 			  EnterIdList(EnumList, | ||||
| 				      D_ENUM, | ||||
| 				      0, | ||||
| 				      (struct type *) 0 /* ???? */ | ||||
| 			  ); | ||||
| 			  *ptp = standard_type(ENUMERATION,int_align,int_size); | ||||
| 			  EnterIdList(EnumList, D_ENUM, 0, *ptp, CurrentScope); | ||||
| 			  FreeIdList(EnumList); | ||||
| 			} | ||||
| 
 | ||||
|  | @ -157,43 +193,102 @@ IdentList(struct id_list **p;) | |||
| 				{ q->next = 0; } | ||||
| ; | ||||
| 
 | ||||
| SubrangeType: | ||||
| SubrangeType(struct type **ptp;) | ||||
| { | ||||
| 	struct type *tp; | ||||
| }: | ||||
| 	/* | ||||
| 	   This is not exactly the rule in the new report, but see | ||||
| 	   the rule for "SimpleType". | ||||
| 	*/ | ||||
| 	'[' ConstExpression UPTO ConstExpression ']' | ||||
| 	'[' ConstExpression | ||||
| 	UPTO ConstExpression | ||||
| 	']' | ||||
| 	/* | ||||
| 	   Evaluate the expressions. Check that they are indeed constant. | ||||
| 	   ??? | ||||
| 	   Leave the basetype of the subrange in tp; | ||||
| 	*/ | ||||
| 			{ | ||||
| 			  /* For the time being: */ | ||||
| 			  tp = int_type; | ||||
| 			  tp = construct_type(SUBRANGE, tp, (arith) 0); | ||||
| 			  *ptp = tp; | ||||
| 			} | ||||
| ; | ||||
| 
 | ||||
| ArrayType: | ||||
| 	ARRAY SimpleType [ ',' SimpleType ]* OF type | ||||
| ArrayType(struct type **ptp;) | ||||
| { | ||||
| 	struct type *tp; | ||||
| 	register struct type *tp2; | ||||
| } : | ||||
| 	ARRAY SimpleType(&tp) | ||||
| 			{ | ||||
| 			  *ptp = tp2 = construct_type(ARRAY, tp); | ||||
| 			} | ||||
| 	[ | ||||
| 		',' SimpleType(&tp) | ||||
| 			{ tp2 = tp2->tp_value.tp_arr.ar_elem =  | ||||
| 				construct_type(ARRAY, tp); | ||||
| 			} | ||||
| 	]* OF type(&tp) | ||||
| 			{ tp2->tp_value.tp_arr.ar_elem = tp; } | ||||
| ; | ||||
| 
 | ||||
| RecordType: | ||||
| 	RECORD FieldListSequence END | ||||
| RecordType(struct type **ptp;) | ||||
| { | ||||
| 	int scopenr; | ||||
| } | ||||
| : | ||||
| 	RECORD | ||||
| 			{ scopenr = uniq_scope(); } | ||||
| 	FieldListSequence(scopenr) | ||||
| 			{ | ||||
| 			  *ptp = standard_type(RECORD, record_align, (arith) 0 /* ???? */); | ||||
| 			  (*ptp)->tp_value.tp_record.rc_scopenr = scopenr; | ||||
| 			} | ||||
| 	END | ||||
| ; | ||||
| 
 | ||||
| FieldListSequence: | ||||
| 	FieldList [ ';' FieldList ]* | ||||
| FieldListSequence(int scopenr;): | ||||
| 	FieldList(scopenr) | ||||
| 	[ | ||||
| 		';' FieldList(scopenr) | ||||
| 	]* | ||||
| ; | ||||
| 
 | ||||
| FieldList | ||||
| FieldList(int scopenr;) | ||||
| { | ||||
| 	struct id_list *FldList; | ||||
| 	struct idf *id; | ||||
| 	struct def *df, *df1; | ||||
| 	struct type *tp; | ||||
| } : | ||||
| [ | ||||
| 	IdentList(&FldList) ':' type | ||||
| 	IdentList(&FldList) ':' type(&tp) | ||||
| | | ||||
| 	CASE IDENT?			/* Changed rule in new modula-2 */ | ||||
| 	':' qualident | ||||
| 	OF variant [ '|' variant ]* | ||||
| 	[ ELSE FieldListSequence ]? | ||||
| 	CASE | ||||
| 	[ | ||||
| 		IDENT		{ id = dot.TOK_IDF; } | ||||
| 	| | ||||
| 				{ id = gen_anon_idf(); } | ||||
| 	]			/* Changed rule in new modula-2 */ | ||||
| 	':' qualident(D_TYPE|D_HTYPE, &df, "type") | ||||
| 				{ df1 = define(id, scopenr, D_FIELD); | ||||
| 				  df1->df_type = df->df_type; | ||||
| 				} | ||||
| 	OF variant(scopenr) | ||||
| 	[ | ||||
| 		'|' variant(scopenr) | ||||
| 	]* | ||||
| 	[ ELSE FieldListSequence(scopenr) | ||||
| 	]? | ||||
| 	END | ||||
| ]? | ||||
| ; | ||||
| 
 | ||||
| variant: | ||||
| 	[ CaseLabelList ':' FieldListSequence ]? | ||||
| variant(int scopenr;): | ||||
| 	[ CaseLabelList ':' FieldListSequence(scopenr) ]? | ||||
| 					/* Changed rule in new modula-2 */ | ||||
| ; | ||||
| 
 | ||||
|  | @ -205,21 +300,59 @@ CaseLabels: | |||
| 	ConstExpression [ UPTO ConstExpression ]? | ||||
| ; | ||||
| 
 | ||||
| SetType: | ||||
| 	SET OF SimpleType | ||||
| SetType(struct type **ptp;) | ||||
| { | ||||
| 	struct type *tp; | ||||
| } : | ||||
| 	SET OF SimpleType(&tp) | ||||
| 			{ | ||||
| 			  *ptp = construct_type(SET, tp, (arith) 0 /* ???? */); | ||||
| 			} | ||||
| ; | ||||
| 
 | ||||
| PointerType: | ||||
| 	POINTER TO type | ||||
| PointerType(struct type **ptp;) | ||||
| { | ||||
| 	struct type *tp; | ||||
| 	register struct def *df; | ||||
| 	struct def *lookfor(); | ||||
| } : | ||||
| 	POINTER TO | ||||
| 	[ %if ( (df = lookup(dot.TOK_IDF, CurrentScope))) | ||||
| 		IDENT | ||||
| 				{ | ||||
| 				  if (!(df->df_kind & (D_TYPE | D_HTYPE))) { | ||||
| 					error("\"%s\" is not a type identifier", | ||||
| 						df->df_idf->id_text); | ||||
| 				  } | ||||
| 				  if (!df->df_type) { | ||||
| 					error("type \"%s\" not declared", | ||||
| 						df->df_idf->id_text); | ||||
| 				  } | ||||
| 				  *ptp = df->df_type; | ||||
| 				} | ||||
| 	| %if (df = lookfor(dot.TOK_IDF, 0), df->df_kind == D_MODULE) | ||||
| 		type(&tp) | ||||
| 				{ *ptp = construct_type(POINTER, tp); } | ||||
| 	| | ||||
| 		IDENT | ||||
| 				{ *ptp = construct_type(POINTER, NULLTYPE); | ||||
| 				  Forward(&dot, &((*ptp)->next)); | ||||
| 				} | ||||
| 	] | ||||
| ; | ||||
| 
 | ||||
| ProcedureType: | ||||
| ProcedureType(struct type **ptp;): | ||||
| 	PROCEDURE FormalTypeList? | ||||
| 			{ *ptp = 0; } | ||||
| ; | ||||
| 
 | ||||
| FormalTypeList: | ||||
| FormalTypeList | ||||
| { | ||||
| 	struct def *df; | ||||
| } : | ||||
| 	'(' [ VAR? FormalType [ ',' VAR? FormalType ]* ]? ')' | ||||
| 	[ ':' qualident ]? | ||||
| 	[ ':' qualident(1, &df, "type") | ||||
| 	]? | ||||
| ; | ||||
| 
 | ||||
| ConstantDeclaration | ||||
|  | @ -236,17 +369,14 @@ ConstantDeclaration | |||
| VariableDeclaration | ||||
| { | ||||
| 	struct id_list *VarList; | ||||
| 	struct type *tp; | ||||
| } : | ||||
| 	IdentList(&VarList) | ||||
| 	[ | ||||
| 		ConstExpression | ||||
| 	]? | ||||
| 	':' type | ||||
| 			{ EnterIdList(VarList, | ||||
| 				      D_VARIABLE, | ||||
| 				      0, | ||||
| 				      (struct type *) 0	/* ???? */ | ||||
| 				     ); | ||||
| 	':' type(&tp) | ||||
| 			{ EnterIdList(VarList, D_VARIABLE, 0, tp, CurrentScope); | ||||
| 			  FreeIdList(VarList); | ||||
| 			} | ||||
| ; | ||||
|  |  | |||
|  | @ -38,21 +38,24 @@ struct def	{		/* list of definitions for a name */ | |||
| 	struct def *next; | ||||
| 	struct idf *df_idf;	/* link back to the name */ | ||||
| 	int df_scope;		/* Scope in which this definition resides */ | ||||
| 	char df_kind;		/* The kind of this definition: */ | ||||
| #define D_MODULE	0x00 | ||||
| #define D_PROCEDURE	0x01 | ||||
| #define D_VARIABLE	0x02 | ||||
| #define D_FIELD		0x03 | ||||
| #define D_TYPE		0x04 | ||||
| #define D_ENUM		0x05 | ||||
| #define D_CONST		0x06 | ||||
| #define D_IMPORT	0x07 | ||||
| #define D_PROCHEAD	0x08	/* A procedure heading in a definition module */ | ||||
| #define D_HIDDEN	0x09	/* A hidden type */ | ||||
| #define D_HTYPE		0x0A	/* Definition of a hidden type seen */ | ||||
| #define D_STDPROC	0x0B	/* A standard procedure */ | ||||
| #define D_STDFUNC	0x0C	/* A standard function */ | ||||
| #define D_ISEXPORTED	0xFF	/* Not yet defined */ | ||||
| 	short df_kind;		/* The kind of this definition: */ | ||||
| #define D_MODULE	0x0001 | ||||
| #define D_PROCEDURE	0x0002 | ||||
| #define D_VARIABLE	0x0004 | ||||
| #define D_FIELD		0x0008 | ||||
| #define D_TYPE		0x0010 | ||||
| #define D_ENUM		0x0020 | ||||
| #define D_CONST		0x0040 | ||||
| #define D_IMPORT	0x0080 | ||||
| #define D_PROCHEAD	0x0100	/* A procedure heading in a definition module */ | ||||
| #define D_HIDDEN	0x0200	/* A hidden type */ | ||||
| #define D_HTYPE		0x0400	/* Definition of a hidden type seen */ | ||||
| #define D_STDPROC	0x0800	/* A standard procedure */ | ||||
| #define D_STDFUNC	0x1000	/* A standard function */ | ||||
| #define D_ERROR		0x2000	/* A compiler generated definition for an | ||||
| 				   undefined variable | ||||
| 				*/ | ||||
| #define D_ISEXPORTED	0x4000	/* Not yet defined */ | ||||
| 	char df_flags; | ||||
| #define D_ADDRESS	0x01	/* Set if address was taken */ | ||||
| #define D_USED		0x02	/* Set if used */ | ||||
|  | @ -74,6 +77,9 @@ struct def	{		/* list of definitions for a name */ | |||
| 
 | ||||
| /* ALLOCDEF "def" */ | ||||
| 
 | ||||
| struct def | ||||
| extern struct def | ||||
| 	*define(), | ||||
| 	*lookup(); | ||||
| 	*lookup(), | ||||
| 	*ill_df; | ||||
| 
 | ||||
| #define NULLDEF ((struct def *) 0) | ||||
|  |  | |||
|  | @ -14,21 +14,30 @@ static char *RcsId = "$Header$"; | |||
| 
 | ||||
| struct def *h_def;		/* Pointer to free list of def structures */ | ||||
| 
 | ||||
| static struct def illegal_def = | ||||
| 	{0, 0, -20 /* Illegal scope */, D_ERROR}; | ||||
| 
 | ||||
| struct def *ill_df = &illegal_def; | ||||
| 
 | ||||
| struct def * | ||||
| define(id, scope, kind) | ||||
| 	register struct idf *id; | ||||
| 	register struct scope *scope; | ||||
| { | ||||
| 	/*	Declare an identifier in a scope, but first check if it
 | ||||
| 		already has been defined. If so, error message. | ||||
| 	*/ | ||||
| 	register struct def *df = lookup(id, scope->sc_scope); | ||||
| 	register struct def *df; | ||||
| 
 | ||||
| 	DO_DEBUG(debug(3,"Defining identifier %s in scope %d", id->id_text, scope->sc_scope)); | ||||
| 	DO_DEBUG(debug(4,"Defining identifier %s in scope %d", id->id_text, scope)); | ||||
| 	df = lookup(id, scope); | ||||
| 	if (	/* Already in this scope */ | ||||
| 		df | ||||
| 	   ||	/* A closed scope, and id defined in the pervasive scope */ | ||||
| 		(scopeclosed(scope) && (df = lookup(id, 0))) | ||||
| 		( CurrentScope == scope  | ||||
| 		&& | ||||
| 		  scopeclosed(currscope) | ||||
| 		&& | ||||
| 		  (df = lookup(id, 0))) | ||||
| 	   ) { | ||||
| 		switch(df->df_kind) { | ||||
| 		case D_PROCHEAD: | ||||
|  | @ -43,17 +52,17 @@ define(id, scope, kind) | |||
| 				return df; | ||||
| 			} | ||||
| 			break; | ||||
| 		case D_ERROR: | ||||
| 		case D_ISEXPORTED: | ||||
| 			df->df_kind = kind; | ||||
| 			return df; | ||||
| 			break; | ||||
| 		} | ||||
| 		error("Identifier \"%s\" already declared", id->id_text); | ||||
| 		error("identifier \"%s\" already declared", id->id_text); | ||||
| 		return df; | ||||
| 	} | ||||
| 	df = new_def(); | ||||
| 	df->df_idf = id; | ||||
| 	df->df_scope = scope->sc_scope; | ||||
| 	df->df_scope = scope; | ||||
| 	df->df_kind = kind; | ||||
| 	df->next = id->id_def; | ||||
| 	id->id_def = df; | ||||
|  | @ -73,7 +82,7 @@ lookup(id, scope) | |||
| 
 | ||||
| 	df1 = 0; | ||||
| 	df = id->id_def; | ||||
| 	DO_DEBUG(debug(3,"Looking for identifier %s in scope %d", id->id_text, scope)); | ||||
| 	DO_DEBUG(debug(4,"Looking for identifier %s in scope %d", id->id_text, scope)); | ||||
| 	while (df) { | ||||
| 		if (df->df_scope == scope) { | ||||
| 			if (df1) { | ||||
|  |  | |||
|  | @ -32,24 +32,50 @@ Enter(name, kind, type, pnam) | |||
| 	return df; | ||||
| } | ||||
| 
 | ||||
| EnterIdList(idlist, kind, flags, type) | ||||
| EnterIdList(idlist, kind, flags, type, scope) | ||||
| 	register struct id_list *idlist; | ||||
| 	struct type *type; | ||||
| { | ||||
| 	register struct def *df; | ||||
| 	struct def *last = 0; | ||||
| 	struct def *first = 0, *last = 0; | ||||
| 	int assval = 0; | ||||
| 
 | ||||
| 	while (idlist) { | ||||
| 		df = define(idlist->id_ptr, CurrentScope, kind); | ||||
| 		df = define(idlist->id_ptr, scope, kind); | ||||
| 		df->df_type = type; | ||||
| 		df->df_flags = flags; | ||||
| 		if (kind == D_ENUM) { | ||||
| 			if (!first) first = df; | ||||
| 			df->df_value.df_enum.en_val = assval++; | ||||
| 			if (last) last->df_value.df_enum.en_next = df; | ||||
| 			last = df; | ||||
| 		} | ||||
| 		idlist = idlist->next; | ||||
| 	} | ||||
| 	if (last) last->df_value.df_enum.en_next = 0; | ||||
| 	if (last) { | ||||
| 		/* Also meaning : enumeration */ | ||||
| 		last->df_value.df_enum.en_next = 0; | ||||
| 		type->tp_value.tp_enum.en_enums = first; | ||||
| 		type->tp_value.tp_enum.en_ncst = assval; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| /*	Look for an identifier in the current visibility range.
 | ||||
| 	If it is not defined, give an error message, and | ||||
| 	create a dummy definition. | ||||
| */ | ||||
| struct def * | ||||
| lookfor(id, give_error) | ||||
| 	struct idf *id; | ||||
| { | ||||
| 	register struct scope *sc = currscope; | ||||
| 	struct def *df; | ||||
| 
 | ||||
| 	while (sc) { | ||||
| 		df = lookup(id, sc->sc_scope); | ||||
| 		if (df) return df; | ||||
| 		sc = nextvisible(sc); | ||||
| 	} | ||||
| 	if (give_error) error("Identifier \"%s\" not declared", id->id_text); | ||||
| 	return define(id, CurrentScope, D_ERROR); | ||||
| } | ||||
|  |  | |||
|  | @ -132,7 +132,7 @@ _error(class, expr, fmt, argv) | |||
| 	case LEXERROR: | ||||
| 	case CRASH: | ||||
| 	case FATAL: | ||||
| 		/*
 | ||||
| 		/* ????
 | ||||
| 		if (C_busy()) | ||||
| 			C_ms_err(); | ||||
| 		*/ | ||||
|  | @ -164,7 +164,7 @@ _error(class, expr, fmt, argv) | |||
| 	switch (class)	{	 | ||||
| 	case WARNING: | ||||
| 	case ERROR: | ||||
| 		ln = /* expr ? expr->ex_line : */ dot.tk_lineno; | ||||
| 		ln = /* ???? expr ? expr->ex_line : */ dot.tk_lineno; | ||||
| 		break; | ||||
| 	case LEXWARNING: | ||||
| 	case LEXERROR: | ||||
|  |  | |||
|  | @ -1,5 +1,15 @@ | |||
| /* E X P R E S S I O N S */ | ||||
| 
 | ||||
| { | ||||
| static char *RcsId = "$Header$"; | ||||
| 
 | ||||
| #include	<alloc.h> | ||||
| #include	<em_arith.h> | ||||
| #include	<em_label.h> | ||||
| #include	"LLlex.h" | ||||
| #include	"idf.h" | ||||
| #include	"def.h" | ||||
| #include	"scope.h" | ||||
| } | ||||
| 
 | ||||
| number: | ||||
|  | @ -8,8 +18,44 @@ number: | |||
| 	REAL | ||||
| ; | ||||
| 
 | ||||
| qualident: | ||||
| 	IDENT selector* | ||||
| qualident(int types; struct def **pdf; char *str;) | ||||
| { | ||||
| 	int scope; | ||||
| 	register struct def *df; | ||||
| 	struct def *lookfor(); | ||||
| } : | ||||
| 	IDENT		{ if (types) { | ||||
| 				df = lookfor(dot.TOK_IDF, 1); | ||||
| 				if (df->df_kind == D_ERROR) { | ||||
| 					*pdf = df; | ||||
| 					types = 0; | ||||
| 				} | ||||
| 			  } | ||||
| 			} | ||||
| 	[ | ||||
| 			{ if (types &&!(scope = has_selectors(df))) { | ||||
| 				types = 0; | ||||
| 				*pdf = ill_df; | ||||
| 			  } | ||||
| 			} | ||||
| 		/* selector */ | ||||
| 		'.' IDENT | ||||
| 			{ if (types) { | ||||
| 				df = lookup(dot.TOK_IDF, scope); | ||||
| 				if (!df) { | ||||
| 					error("identifier \"%s\" not declared", | ||||
| 					      dot.TOK_IDF->id_text); | ||||
| 					types = 0; | ||||
| 					df = ill_df; | ||||
| 				} | ||||
| 			  } | ||||
| 			} | ||||
| 	]* | ||||
| 			{ if (types && !(types & df->df_kind)) { | ||||
| 				error("identifier \"%s\" is not a %s", | ||||
| 					dot.TOK_IDF, str); | ||||
| 			  } | ||||
| 			} | ||||
| ; | ||||
| 
 | ||||
| selector: | ||||
|  | @ -52,8 +98,11 @@ MulOperator: | |||
| 	'*' | '/' | DIV | MOD | AND | '&' | ||||
| ; | ||||
| 
 | ||||
| factor: | ||||
| 	qualident | ||||
| factor | ||||
| { | ||||
| 	struct def *df; | ||||
| } : | ||||
| 	qualident(0, &df, (char *) 0) | ||||
| 	[ | ||||
| 		designator_tail? ActualParameters? | ||||
| 	| | ||||
|  | @ -83,15 +132,25 @@ element: | |||
| 	expression [ UPTO expression ]? | ||||
| ; | ||||
| 
 | ||||
| designator: | ||||
| 	qualident designator_tail? | ||||
| designator | ||||
| { | ||||
| 	struct def *df; | ||||
| } : | ||||
| 	qualident(0, &df, (char *) 0) | ||||
| 	designator_tail? | ||||
| ; | ||||
| 
 | ||||
| designator_tail: | ||||
| 	visible_designator_tail | ||||
| 	[ selector | visible_designator_tail ]* | ||||
| 	[ | ||||
| 		selector | ||||
| 	| | ||||
| 		visible_designator_tail | ||||
| 	]* | ||||
| ; | ||||
| 
 | ||||
| visible_designator_tail: | ||||
| 	'[' ExpList ']' | '^' | ||||
| 	'[' ExpList ']' | ||||
| | | ||||
| 	'^' | ||||
| ; | ||||
|  |  | |||
|  | @ -121,8 +121,6 @@ Option(str) | |||
| 	options[str[1]]++;	/* switch option on	*/ | ||||
| } | ||||
| 
 | ||||
| #define NULLTYPE	((struct type *) 0) | ||||
| 
 | ||||
| add_standards() | ||||
| { | ||||
| 	register struct def *df; | ||||
|  | @ -157,15 +155,13 @@ add_standards() | |||
| 	(void) Enter("NIL", D_CONST, nil_type, 0); | ||||
| 	(void) Enter("PROC", | ||||
| 		     D_TYPE, | ||||
| 		     construct_type(PROCEDURE, NULLTYPE, (arith) 0), | ||||
| 		     construct_type(PROCEDURE, NULLTYPE), | ||||
| 		     0); | ||||
| 	tp = construct_type(SUBRANGE, int_type, (arith) 0); | ||||
| 	tp = construct_type(SUBRANGE, int_type); | ||||
| 	tp->tp_value.tp_subrange.su_lb = 0; | ||||
| 	tp->tp_value.tp_subrange.su_ub = wrd_size * 8 - 1; | ||||
| 	(void) Enter("BITSET", | ||||
| 		     D_TYPE, | ||||
| 		     construct_type(SET, tp, wrd_size), | ||||
| 		     0); | ||||
| 	df = Enter("BITSET", D_TYPE, construct_type(SET, tp), 0); | ||||
| 	df->df_type->tp_size = wrd_size; | ||||
| 	df = Enter("FALSE", D_ENUM, bool_type, 0); | ||||
| 	df->df_value.df_enum.en_val = 0; | ||||
| 	df->df_value.df_enum.en_next = Enter("TRUE", D_ENUM, bool_type, 0); | ||||
|  |  | |||
|  | @ -12,3 +12,6 @@ struct id_list { | |||
| /* ALLOCDEF "id_list" */ | ||||
| 
 | ||||
| #define is_anon_idf(x)	((x)->id_text[0] == '#') | ||||
| 
 | ||||
| extern struct idf | ||||
| 	*gen_anon_idf(); | ||||
|  |  | |||
|  | @ -83,7 +83,7 @@ DefinitionModule | |||
| 	MODULE IDENT	{  | ||||
| 			  df = define(dot.TOK_IDF, CurrentScope, D_MODULE); | ||||
| 			  open_scope(CLOSEDSCOPE, 0); | ||||
| 			  df->df_value.df_module.mo_scope = CurrentScope->sc_scope; | ||||
| 			  df->df_value.df_module.mo_scope = CurrentScope; | ||||
| 			} | ||||
| 	';' | ||||
| 	import(0)*  | ||||
|  | @ -98,12 +98,13 @@ DefinitionModule | |||
| definition | ||||
| { | ||||
| 	struct def *df; | ||||
| 	struct type *tp; | ||||
| } : | ||||
| 	CONST [ ConstantDeclaration ';' ]* | ||||
| | | ||||
| 	TYPE | ||||
| 	[ IDENT  | ||||
| 	  [ '=' type  | ||||
| 	  [ '=' type(&tp) | ||||
| 	  | /* empty */ | ||||
| 	    /* | ||||
| 	       Here, the exported type has a hidden implementation. | ||||
|  |  | |||
|  | @ -4,12 +4,18 @@ static char *RcsId = "$Header$"; | |||
| 
 | ||||
| #include	<assert.h> | ||||
| #include	<alloc.h> | ||||
| #include	<em_arith.h> | ||||
| #include	<em_label.h> | ||||
| #include	"LLlex.h" | ||||
| #include	"idf.h" | ||||
| #include	"scope.h" | ||||
| #include	"type.h" | ||||
| #include	"def.h" | ||||
| #include	"debug.h" | ||||
| 
 | ||||
| static int maxscope;		/* maximum assigned scope number */ | ||||
| 
 | ||||
| struct scope *CurrentScope; | ||||
| struct scope *currscope; | ||||
| 
 | ||||
| /* STATICALLOCDEF "scope" */ | ||||
| 
 | ||||
|  | @ -29,29 +35,32 @@ open_scope(scopetype, scopenr) | |||
| 	sc->sc_scope = scopenr == 0 ? ++maxscope : scopenr; | ||||
| 	assert(scopetype == OPENSCOPE || scopetype == CLOSEDSCOPE); | ||||
| 	DO_DEBUG(debug(1, "Opening a %s scope", scopetype == OPENSCOPE ? "open" : "closed")); | ||||
| 	sc1 = CurrentScope; | ||||
| 	sc1 = currscope; | ||||
| 	if (scopetype == CLOSEDSCOPE) { | ||||
| 		sc1 = new_scope(); | ||||
| 		sc1->sc_scope = 0;			/* Pervasive scope nr */ | ||||
| 		sc1->next = CurrentScope; | ||||
| 		sc1->sc_scope = 0;		/* Pervasive scope nr */ | ||||
| 		sc1->next = currscope; | ||||
| 	} | ||||
| 	sc->next = sc1; | ||||
| 	CurrentScope = sc; | ||||
| 	currscope = sc; | ||||
| } | ||||
| 
 | ||||
| static rem_forwards(); | ||||
| 
 | ||||
| close_scope() | ||||
| { | ||||
| 	register struct scope *sc = CurrentScope; | ||||
| 	register struct scope *sc = currscope; | ||||
| 
 | ||||
| 	assert(sc != 0); | ||||
| 	DO_DEBUG(debug(1, "Closing a scope")); | ||||
| 	if (sc->sc_forw) rem_forwards(sc->sc_forw); | ||||
| 	if (sc->next && (sc->next->sc_scope == 0)) { | ||||
| 		struct scope *sc1 = sc; | ||||
| 
 | ||||
| 		sc = sc->next; | ||||
| 		free_scope(sc1); | ||||
| 	} | ||||
| 	CurrentScope = sc->next; | ||||
| 	currscope = sc->next; | ||||
| 	free_scope(sc); | ||||
| } | ||||
| 
 | ||||
|  | @ -61,5 +70,61 @@ init_scope() | |||
| 
 | ||||
| 	sc->sc_scope = 0; | ||||
| 	sc->next = 0; | ||||
| 	CurrentScope = sc; | ||||
| 	currscope = sc; | ||||
| } | ||||
| 
 | ||||
| int | ||||
| uniq_scope() | ||||
| { | ||||
| 	return ++maxscope; | ||||
| } | ||||
| 
 | ||||
| struct forwards { | ||||
| 	struct forwards *next; | ||||
| 	struct token fo_tok; | ||||
| 	struct type **fo_ptyp; | ||||
| }; | ||||
| 
 | ||||
| /* STATICALLOCDEF "forwards" */ | ||||
| 
 | ||||
| /*	Enter a forward reference into a list belonging to the
 | ||||
| 	current scope. This is used for POINTER declarations, which | ||||
| 	may have forward references that must howewer be declared in the | ||||
| 	same scope. | ||||
| */ | ||||
| Forward(tk, ptp) | ||||
| 	struct token *tk; | ||||
| 	struct type **ptp; | ||||
| { | ||||
| 	register struct forwards *f = new_forwards(); | ||||
| 
 | ||||
| 	f->fo_tok = *tk; | ||||
| 	f->fo_ptyp = ptp; | ||||
| 	f->next = currscope->sc_forw; | ||||
| 	currscope->sc_forw = f; | ||||
| } | ||||
| 
 | ||||
| /*	When closing a scope, all forward references must be resolved
 | ||||
| */ | ||||
| static | ||||
| rem_forwards(fo) | ||||
| 	struct forwards *fo; | ||||
| { | ||||
| 	register struct forwards *f; | ||||
| 	struct token savetok; | ||||
| 	register struct def *df; | ||||
| 	struct def *lookfor(); | ||||
| 
 | ||||
| 	savetok = dot; | ||||
| 	while (f = fo) { | ||||
| 		dot = f->fo_tok; | ||||
| 		df = lookfor(dot.TOK_IDF, 1); | ||||
| 		if (!(df->df_kind & (D_TYPE | D_HTYPE | D_ERROR))) { | ||||
| 			error("identifier \"%s\" not a type", df->df_idf->id_text); | ||||
| 		} | ||||
| 		*(f->fo_ptyp) = df->df_type; | ||||
| 		fo = f->next; | ||||
| 		free_forwards(f); | ||||
| 	} | ||||
| 	dot = savetok; | ||||
| } | ||||
|  |  | |||
|  | @ -7,6 +7,7 @@ | |||
| 
 | ||||
| struct scope { | ||||
| 	struct scope *next; | ||||
| 	struct forwards *sc_forw; | ||||
| 	int sc_scope;		/* The scope number. Scope number 0 indicates
 | ||||
| 				   both the pervasive scope and the end of a | ||||
| 				   visibility range | ||||
|  | @ -14,7 +15,9 @@ struct scope { | |||
| }; | ||||
| 
 | ||||
| extern struct scope | ||||
| 	*CurrentScope; | ||||
| 	*currscope; | ||||
| 
 | ||||
| #define nextvisible(x)	((x)->sc_scope ? (x)->next : (struct scope *) 0) | ||||
| #define scopeclosed(x)	((x)->next->sc_scope == 0) | ||||
| #define enclosing(x)	((x)->next->scope != 0 ? (struct scope *) 0 : (x)->next->next) | ||||
| #define CurrentScope	(currscope->sc_scope) | ||||
|  |  | |||
|  | @ -86,6 +86,7 @@ struct tokenname tkstandard[] =	{	/* standard identifiers */ | |||
| 	{CARDINAL, ""}, | ||||
| 	{LONGREAL, ""}, | ||||
| 	{SUBRANGE, ""}, | ||||
| 	{ENUMERATION, ""}, | ||||
| 	{ERRONEOUS, ""}, | ||||
| 	{0, ""} | ||||
| }; | ||||
|  |  | |||
|  | @ -22,7 +22,7 @@ struct subrange { | |||
| }; | ||||
| 
 | ||||
| struct array { | ||||
| 	struct type *ar_index;	/* Type of index */ | ||||
| 	struct type *ar_elem;	/* Type of elements */ | ||||
| 	arith ar_lb, ar_ub;	/* Lower bound and upper bound */ | ||||
| 	label ar_descr;		/* Label of array descriptor */ | ||||
| }; | ||||
|  | @ -90,3 +90,5 @@ struct type | |||
| 	*create_type(), | ||||
| 	*construct_type(), | ||||
| 	*standard_type(); | ||||
| 
 | ||||
| #define NULLTYPE ((struct type *) 0) | ||||
|  |  | |||
|  | @ -64,9 +64,8 @@ create_type(fund) | |||
| } | ||||
| 
 | ||||
| struct type * | ||||
| construct_type(fund, tp, count) | ||||
| construct_type(fund, tp) | ||||
| 	struct type *tp; | ||||
| 	arith count; | ||||
| { | ||||
| 	/*	fund must be a type constructor.
 | ||||
| 		The pointer to the constructed type is returned. | ||||
|  | @ -82,13 +81,10 @@ construct_type(fund, tp, count) | |||
| 		break; | ||||
| 	case SET: | ||||
| 		dtp->tp_align = wrd_align; | ||||
| 		dtp->tp_size = align((count + 7) / 8, wrd_align); | ||||
| 		dtp->next = tp; | ||||
| 		break; | ||||
| 	case ARRAY: | ||||
| 		dtp->tp_align = tp->tp_align; | ||||
| 		if (tp->tp_size < 0) dtp->tp_size = -1; | ||||
| 		else dtp->tp_size = count * tp->tp_size; | ||||
| 		dtp->next = tp; | ||||
| 		break; | ||||
| 	case SUBRANGE: | ||||
|  | @ -134,3 +130,24 @@ init_types() | |||
| 	nil_type = standard_type(POINTER, ptr_align, ptr_size); | ||||
| 	error_type = standard_type(ERRONEOUS, 1, (arith) 1); | ||||
| } | ||||
| 
 | ||||
| int | ||||
| has_selectors(df) | ||||
| 	register struct def *df; | ||||
| { | ||||
| 
 | ||||
| 	switch(df->df_kind) { | ||||
| 	case D_MODULE: | ||||
| 		return df->df_value.df_module.mo_scope; | ||||
| 	case D_VARIABLE: {	 | ||||
| 		register struct type *tp = df->df_type; | ||||
| 
 | ||||
| 		if (tp->tp_fund == RECORD) { | ||||
| 			return tp->tp_value.tp_record.rc_scopenr; | ||||
| 		} | ||||
| 		break; | ||||
| 		} | ||||
| 	} | ||||
| 	error("no selectors for \"%s\"", df->df_idf->id_text); | ||||
| 	return 0; | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue