A newer version, safety commit
This commit is contained in:
		
							parent
							
								
									8546fbe868
								
							
						
					
					
						commit
						7f174a46c3
					
				
					 28 changed files with 1034 additions and 222 deletions
				
			
		|  | @ -1,20 +1,23 @@ | ||||||
| /*	LEXICAL ANALYSER FOR MODULA-2	*/ | /* L E X I C A L   A N A L Y S E R   F O R   M O D U L A - 2 */ | ||||||
| 
 | 
 | ||||||
| #include "input.h" | static char *RcsId = "$Header$"; | ||||||
| #include <alloc.h> | 
 | ||||||
| #include "f_info.h" | #include	<alloc.h> | ||||||
| #include "Lpars.h" | #include	<em_arith.h> | ||||||
| #include "class.h" | #include	"input.h" | ||||||
| #include "param.h" | #include	"f_info.h" | ||||||
| #include "idf.h" | #include	"Lpars.h" | ||||||
| #include "LLlex.h" | #include	"class.h" | ||||||
|  | #include	"idf.h" | ||||||
|  | #include	"LLlex.h" | ||||||
|  | 
 | ||||||
|  | #define IDFSIZE	256	/* Number of significant characters in an identifier */ | ||||||
|  | #define NUMSIZE	256	/* maximum number of characters in a number */ | ||||||
| 
 | 
 | ||||||
| long str2long(); | long str2long(); | ||||||
| 
 | 
 | ||||||
| struct token dot, aside; | struct token dot, aside; | ||||||
| 
 | 
 | ||||||
| static char *RcsId = "$Header$"; |  | ||||||
| 
 |  | ||||||
| /*	Skip Modula-2 like comment (* ... *).
 | /*	Skip Modula-2 like comment (* ... *).
 | ||||||
| 	Note that comment may be nested. | 	Note that comment may be nested. | ||||||
| */ | */ | ||||||
|  |  | ||||||
|  | @ -1,4 +1,4 @@ | ||||||
| /*	Token Descriptor Definition	*/ | /* T O K E N   D E S C R I P T O R   D E F I N I T I O N */ | ||||||
| 
 | 
 | ||||||
| /* $Header$ */ | /* $Header$ */ | ||||||
| 
 | 
 | ||||||
|  | @ -9,8 +9,8 @@ struct token	{ | ||||||
| 		struct idf *tk_idf;	/* IDENT	*/ | 		struct idf *tk_idf;	/* IDENT	*/ | ||||||
| 		char *tk_str;		/* STRING	*/ | 		char *tk_str;		/* STRING	*/ | ||||||
| 		struct {		/* INTEGER	*/ | 		struct {		/* INTEGER	*/ | ||||||
| 			int tk_type;	/* type	*/ | 			struct type *tk_type;	/* type	*/ | ||||||
| 			long tk_value;	/* value	*/ | 			arith tk_value;	/* value	*/ | ||||||
| 		} tk_int; | 		} tk_int; | ||||||
| 		char *tk_real;		/* REAL		*/ | 		char *tk_real;		/* REAL		*/ | ||||||
| 	} tk_data; | 	} tk_data; | ||||||
|  |  | ||||||
|  | @ -1,12 +1,15 @@ | ||||||
|  | /* S Y N T A X   E R R O R   R E P O R T I N G */ | ||||||
|  | 
 | ||||||
|  | static char *RcsId = "$Header$"; | ||||||
|  | 
 | ||||||
| #include	<alloc.h> | #include	<alloc.h> | ||||||
| #include	"f_info.h" | #include	<em_arith.h> | ||||||
| #include	"idf.h" | #include	"idf.h" | ||||||
| #include	"LLlex.h" | #include	"LLlex.h" | ||||||
| #include	"Lpars.h" | #include	"Lpars.h" | ||||||
| 
 | 
 | ||||||
| static char *RcsId = "$Header$"; |  | ||||||
| 
 |  | ||||||
| extern char *symbol2str(); | extern char *symbol2str(); | ||||||
|  | extern struct idf *gen_anon_idf(); | ||||||
| int err_occurred = 0; | int err_occurred = 0; | ||||||
| 
 | 
 | ||||||
| LLmessage(tk) | LLmessage(tk) | ||||||
|  | @ -21,28 +24,6 @@ LLmessage(tk) | ||||||
| 		error("%s deleted", symbol2str(dot.tk_symb)); | 		error("%s deleted", symbol2str(dot.tk_symb)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| struct idf * |  | ||||||
| gen_anon_idf() |  | ||||||
| { |  | ||||||
| 	/*	A new idf is created out of nowhere, to serve as an
 |  | ||||||
| 		anonymous name. |  | ||||||
| 	*/ |  | ||||||
| 	static int name_cnt; |  | ||||||
| 	char buff[100]; |  | ||||||
| 	char *sprintf(); |  | ||||||
| 
 |  | ||||||
| 	sprintf(buff, "#%d in %s, line %u", |  | ||||||
| 			++name_cnt, FileName, LineNumber); |  | ||||||
| 	return str2idf(buff, 1); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| int |  | ||||||
| is_anon_idf(idf) |  | ||||||
| 	struct idf *idf; |  | ||||||
| { |  | ||||||
| 	return idf->id_text[0] == '#'; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| insert_token(tk) | insert_token(tk) | ||||||
| 	int tk; | 	int tk; | ||||||
| { | { | ||||||
|  |  | ||||||
|  | @ -13,7 +13,8 @@ CFLAGS =	-DDEBUG -p $(INCLUDES) | ||||||
| LFLAGS =	-p | LFLAGS =	-p | ||||||
| LOBJ =	tokenfile.o program.o declar.o expression.o statement.o | LOBJ =	tokenfile.o program.o declar.o expression.o statement.o | ||||||
| COBJ =	LLlex.o LLmessage.o char.o error.o main.o \
 | COBJ =	LLlex.o LLmessage.o char.o error.o main.o \
 | ||||||
| 	symbol2str.o tokenname.o idf.o input.o idlist.o | 	symbol2str.o tokenname.o idf.o input.o type.o def.o \
 | ||||||
|  | 	scope.o misc.o print.o | ||||||
| OBJ =	$(COBJ) $(LOBJ) Lpars.o | OBJ =	$(COBJ) $(LOBJ) Lpars.o | ||||||
| GENFILES=	tokenfile.c \
 | GENFILES=	tokenfile.c \
 | ||||||
| 	program.c declar.c expression.c statement.c \
 | 	program.c declar.c expression.c statement.c \
 | ||||||
|  | @ -40,7 +41,10 @@ tokenfile.g:	tokenname.c make.tokfile | ||||||
| symbol2str.c:	tokenname.c make.tokcase | symbol2str.c:	tokenname.c make.tokcase | ||||||
| 	make.tokcase <tokenname.c >symbol2str.c | 	make.tokcase <tokenname.c >symbol2str.c | ||||||
| 
 | 
 | ||||||
| idlist.h:	idlist.H make.allocd | misc.h:		misc.H make.allocd | ||||||
|  | def.h:		def.H make.allocd | ||||||
|  | type.h:		type.H make.allocd | ||||||
|  | scope.c:	scope.C make.allocd | ||||||
| 
 | 
 | ||||||
| char.c: char.tab tab | char.c: char.tab tab | ||||||
| 	./tab -fchar.tab >char.c | 	./tab -fchar.tab >char.c | ||||||
|  | @ -61,19 +65,22 @@ depend: | ||||||
| 	make.allocd < $< > $@ | 	make.allocd < $< > $@ | ||||||
| 
 | 
 | ||||||
| #AUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTO
 | #AUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTO
 | ||||||
| LLlex.o: LLlex.h Lpars.h class.h f_info.h idf.h param.h | LLlex.o: LLlex.h Lpars.h class.h f_info.h idf.h input.h | ||||||
| LLmessage.o: LLlex.h Lpars.h f_info.h idf.h | LLmessage.o: LLlex.h Lpars.h idf.h | ||||||
| char.o: class.h | char.o: class.h | ||||||
| error.o: LLlex.h f_info.h | error.o: LLlex.h f_info.h input.h | ||||||
| main.o: LLlex.h Lpars.h f_info.h idf.h | main.o: LLlex.h Lpars.h debug.h f_info.h idf.h input.h main.h | ||||||
| symbol2str.o: Lpars.h | symbol2str.o: Lpars.h | ||||||
| tokenname.o: Lpars.h idf.h tokenname.h | tokenname.o: Lpars.h idf.h tokenname.h | ||||||
| idf.o: idf.h | idf.o: idf.h | ||||||
| input.o: f_info.h input.h | input.o: f_info.h input.h | ||||||
| idlist.o: idf.h idlist.h | type.o: Lpars.h def.h def_sizes.h idf.h type.h | ||||||
|  | def.o: Lpars.h def.h idf.h main.h scope.h | ||||||
|  | scope.o: scope.h | ||||||
|  | misc.o: LLlex.h f_info.h idf.h misc.h | ||||||
| tokenfile.o: Lpars.h | tokenfile.o: Lpars.h | ||||||
| program.o: Lpars.h idf.h idlist.h | program.o: LLlex.h Lpars.h idf.h main.h misc.h | ||||||
| declar.o: LLlex.h Lpars.h idf.h idlist.h | declar.o: LLlex.h Lpars.h def.h idf.h misc.h scope.h type.h | ||||||
| expression.o: Lpars.h | expression.o: Lpars.h | ||||||
| statement.o: Lpars.h | statement.o: Lpars.h | ||||||
| Lpars.o: Lpars.h | Lpars.o: Lpars.h | ||||||
|  |  | ||||||
|  | @ -1,4 +1,4 @@ | ||||||
| /*		U S E   O F   C H A R A C T E R   C L A S S E S		*/ | /* U S E   O F   C H A R A C T E R   C L A S S E S */ | ||||||
| 
 | 
 | ||||||
| /* $Header$ */ | /* $Header$ */ | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,17 +1,43 @@ | ||||||
| { | /* D E C L A R A T I O N S */ | ||||||
| #include "idf.h" |  | ||||||
| #include "idlist.h" |  | ||||||
| #include "LLlex.h" |  | ||||||
| 
 | 
 | ||||||
|  | { | ||||||
| static char *RcsId = "$Header$"; | static char *RcsId = "$Header$"; | ||||||
|  | 
 | ||||||
|  | #include	<em_arith.h> | ||||||
|  | #include	<em_label.h> | ||||||
|  | #include	"idf.h" | ||||||
|  | #include	"misc.h" | ||||||
|  | #include	"LLlex.h" | ||||||
|  | #include	"def.h" | ||||||
|  | #include	"type.h" | ||||||
|  | #include	"scope.h" | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ProcedureDeclaration: | ProcedureDeclaration | ||||||
| 	ProcedureHeading ';' block IDENT | { | ||||||
|  | 	register struct def *df; | ||||||
|  | } : | ||||||
|  | 	/* ProcedureHeading(&df) */ | ||||||
|  | 	PROCEDURE IDENT | ||||||
|  | 			{ df = define(dot.TOK_IDF, CurrentScope, D_PROCEDURE); | ||||||
|  | 			  open_scope(OPENSCOPE, 0); | ||||||
|  | 			} | ||||||
|  | 	FormalParameters? | ||||||
|  | 	';' block IDENT | ||||||
|  | 			{ match_id(dot.TOK_IDF, df->df_idf); | ||||||
|  | 			  close_scope(); | ||||||
|  | 			} | ||||||
| ; | ; | ||||||
| 
 | 
 | ||||||
| ProcedureHeading: | ProcedureHeading | ||||||
| 	PROCEDURE IDENT FormalParameters? | { | ||||||
|  | 	register struct def *df; | ||||||
|  | } : | ||||||
|  | 	/*	Only used for definition modules | ||||||
|  | 	*/ | ||||||
|  | 	PROCEDURE IDENT | ||||||
|  | 			{ df = define(dot.TOK_IDF, CurrentScope, D_PROCHEAD); } | ||||||
|  | 	FormalParameters? | ||||||
| ; | ; | ||||||
| 
 | 
 | ||||||
| block: | block: | ||||||
|  | @ -32,22 +58,34 @@ declaration: | ||||||
| 
 | 
 | ||||||
| FormalParameters: | FormalParameters: | ||||||
| 	'(' [ FPSection [ ';' FPSection ]* ]? ')' | 	'(' [ FPSection [ ';' FPSection ]* ]? ')' | ||||||
| 	[ ':' qualident ]? | 	[ ':' qualident | ||||||
|  | 	]? | ||||||
| ; | ; | ||||||
| 
 | 
 | ||||||
| FPSection | FPSection | ||||||
| { | { | ||||||
| 	struct id_list *FPList; | 	struct id_list *FPList; | ||||||
|  | 	int VARflag = 0; | ||||||
| } : | } : | ||||||
| 	VAR? IdentList(&FPList) ':' FormalType | 	[ | ||||||
|  | 		VAR	{ VARflag = 1; } | ||||||
|  | 	]? | ||||||
|  | 	IdentList(&FPList) ':' FormalType | ||||||
|  | 			{ | ||||||
|  | 			  FreeIdList(FPList); | ||||||
|  | 			} | ||||||
| ; | ; | ||||||
| 
 | 
 | ||||||
| FormalType: | FormalType: | ||||||
| 	[ ARRAY OF ]? qualident | 	[ ARRAY OF ]? qualident | ||||||
| ; | ; | ||||||
| 
 | 
 | ||||||
| TypeDeclaration: | TypeDeclaration | ||||||
| 	IDENT '=' type | { | ||||||
|  | 	register struct def *df; | ||||||
|  | }: | ||||||
|  | 	IDENT		{ df = define(dot.TOK_IDF, CurrentScope, D_TYPE); } | ||||||
|  | 	'=' type | ||||||
| ; | ; | ||||||
| 
 | 
 | ||||||
| type: | type: | ||||||
|  | @ -169,8 +207,12 @@ FormalTypeList: | ||||||
| 	[ ':' qualident ]? | 	[ ':' qualident ]? | ||||||
| ; | ; | ||||||
| 
 | 
 | ||||||
| ConstantDeclaration: | ConstantDeclaration | ||||||
| 	IDENT '=' ConstExpression | { | ||||||
|  | 	register struct def *df; | ||||||
|  | }: | ||||||
|  | 	IDENT		{ df = define(dot.TOK_IDF, CurrentScope, D_CONST); } | ||||||
|  | 	'=' ConstExpression | ||||||
| ; | ; | ||||||
| 
 | 
 | ||||||
| VariableDeclaration | VariableDeclaration | ||||||
|  |  | ||||||
							
								
								
									
										75
									
								
								lang/m2/comp/def.H
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								lang/m2/comp/def.H
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,75 @@ | ||||||
|  | /* I D E N T I F I E R   D E S C R I P T O R   S T R U C T U R E */ | ||||||
|  | 
 | ||||||
|  | /* $Header$ */ | ||||||
|  | 
 | ||||||
|  | struct module { | ||||||
|  | 	int mo_priority;	/* Priority of a module */ | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | struct variable { | ||||||
|  | 	char va_fixedaddress;	/* Flag, set if an address was given */ | ||||||
|  | 	arith va_off;		/* Address or offset of variable */ | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | struct constant { | ||||||
|  | 	struct expr *co_const;	/* A constant expression */ | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | struct enumval { | ||||||
|  | 	unsigned int en_val;	/* Value of this enumeration literal */ | ||||||
|  | 	struct def *en_next;	/* Next enumeration literal */ | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | struct field { | ||||||
|  | 	arith fld_off; | ||||||
|  | 	struct variant { | ||||||
|  | 		struct caselabellist *fld_cases; | ||||||
|  | 		label fld_casedescr; | ||||||
|  | 		struct def *fld_varianttag; | ||||||
|  | 	} *fld_variant; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | struct import { | ||||||
|  | 	int im_scopenr;		/* Scope number from which imported */ | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 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_ISEXPORTED	0xFF	/* Not yet defined */ | ||||||
|  | 	char df_flags; | ||||||
|  | #define D_ADDRESS	0x01	/* Set if address was taken */ | ||||||
|  | #define D_USED		0x02	/* Set if used */ | ||||||
|  | #define D_DEFINED	0x04	/* Set if it is assigned a value */ | ||||||
|  | #define D_VARPAR	0x08	/* Set if it is a VAR parameter */ | ||||||
|  | #define D_EXPORTED	0x40	/* Set if exported */ | ||||||
|  | #define D_QEXPORTED	0x80	/* Set if qualified exported */ | ||||||
|  | 	struct type *df_type; | ||||||
|  | 	union { | ||||||
|  | 		struct module df_module; | ||||||
|  | 		struct variable df_variable; | ||||||
|  | 		struct constant df_constant; | ||||||
|  | 		struct enumval df_enum; | ||||||
|  | 		struct field df_field; | ||||||
|  | 		struct import df_import; | ||||||
|  | 	} df_value; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /* ALLOCDEF "def" */ | ||||||
|  | 
 | ||||||
|  | struct def | ||||||
|  | 	*define(), | ||||||
|  | 	*lookup(); | ||||||
							
								
								
									
										83
									
								
								lang/m2/comp/def.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								lang/m2/comp/def.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,83 @@ | ||||||
|  | /* D E F I N I T I O N   M E C H A N I S M */ | ||||||
|  | 
 | ||||||
|  | static char *RcsId = "$Header$"; | ||||||
|  | 
 | ||||||
|  | #include	<alloc.h> | ||||||
|  | #include	<em_arith.h> | ||||||
|  | #include	<em_label.h> | ||||||
|  | #include	"Lpars.h" | ||||||
|  | #include	"def.h" | ||||||
|  | #include	"idf.h" | ||||||
|  | #include	"main.h" | ||||||
|  | #include	"scope.h" | ||||||
|  | 
 | ||||||
|  | struct def *h_def;		/* Pointer to free list of def structures */ | ||||||
|  | 
 | ||||||
|  | struct def * | ||||||
|  | define(id, scope, kind) | ||||||
|  | 	register struct idf *id; | ||||||
|  | 	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); | ||||||
|  | 
 | ||||||
|  | 	if (df) { | ||||||
|  | 		switch(df->df_kind) { | ||||||
|  | 		case D_PROCHEAD: | ||||||
|  | 			if (kind == D_PROCEDURE) { | ||||||
|  | 				df->df_kind = D_PROCEDURE; | ||||||
|  | 				return df; | ||||||
|  | 			} | ||||||
|  | 			break;	 | ||||||
|  | 		case D_HIDDEN: | ||||||
|  | 			if (kind == D_TYPE && state == IMPLEMENTATION) { | ||||||
|  | 				df->df_kind = D_HTYPE; | ||||||
|  | 				return df; | ||||||
|  | 			} | ||||||
|  | 			break; | ||||||
|  | 		case D_ISEXPORTED: | ||||||
|  | 			df->df_kind = kind; | ||||||
|  | 			return df; | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 		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_kind = kind; | ||||||
|  | 	df->next = id->id_def; | ||||||
|  | 	id->id_def = df; | ||||||
|  | 	return df; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | struct def * | ||||||
|  | lookup(id, scope) | ||||||
|  | 	register struct idf *id; | ||||||
|  | 	struct scope *scope; | ||||||
|  | { | ||||||
|  | 	/*	Look up a definition of an identifier in scope "scope".
 | ||||||
|  | 		Make the "def" list self-organizing. | ||||||
|  | 		Return a pointer to its "def" structure if it exists, | ||||||
|  | 		otherwise return 0. | ||||||
|  | 	*/ | ||||||
|  | 	register struct def *df, *df1; | ||||||
|  | 
 | ||||||
|  | 	df1 = 0; | ||||||
|  | 	df = id->id_def; | ||||||
|  | 	while (df) { | ||||||
|  | 		if (df->df_scope == scope->sc_scope) { | ||||||
|  | 			if (df1) { | ||||||
|  | 				df1->next = df->next; | ||||||
|  | 				df->next = id->id_def; | ||||||
|  | 				id->id_def = df; | ||||||
|  | 			} | ||||||
|  | 			return df; | ||||||
|  | 		} | ||||||
|  | 		df = df->next; | ||||||
|  | 	} | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
							
								
								
									
										22
									
								
								lang/m2/comp/def_sizes.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								lang/m2/comp/def_sizes.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,22 @@ | ||||||
|  | /* D E F A U L T   S I Z E S   A N D   A L I G N M E N T S */ | ||||||
|  | 
 | ||||||
|  | /* $Header$ */ | ||||||
|  | 
 | ||||||
|  | #define MAXSIZE		8	/* the maximum of the SZ_* constants	*/ | ||||||
|  | /* target machine sizes	*/ | ||||||
|  | #define	SZ_CHAR		(arith)1 | ||||||
|  | #define SZ_WORD		(arith)4 | ||||||
|  | #define	SZ_INT		(arith)4 | ||||||
|  | #define	SZ_LONG		(arith)4 | ||||||
|  | #define	SZ_FLOAT	(arith)4 | ||||||
|  | #define	SZ_DOUBLE	(arith)8 | ||||||
|  | #define	SZ_POINTER	(arith)4 | ||||||
|  | /* target machine alignment requirements	*/ | ||||||
|  | #define	AL_CHAR		1 | ||||||
|  | #define AL_WORD		(int) SZ_WORD | ||||||
|  | #define	AL_INT		(int) SZ_WORD | ||||||
|  | #define	AL_LONG		(int) SZ_WORD | ||||||
|  | #define	AL_FLOAT	(int) SZ_WORD | ||||||
|  | #define	AL_DOUBLE	(int) SZ_WORD | ||||||
|  | #define	AL_POINTER	(int) SZ_WORD | ||||||
|  | #define AL_STRUCT	1 | ||||||
|  | @ -1,105 +1,101 @@ | ||||||
| /*	E R R O R   A N D  D I A G N O S T I C   R O U T I N E S	*/ | /* E R R O R   A N D   D I A G N O S T I C   R O U T I N E S */ | ||||||
| 
 | 
 | ||||||
| /*	This file contains the (non-portable) error-message and diagnostic
 | /*	This file contains the (non-portable) error-message and diagnostic
 | ||||||
| 	giving functions.  Be aware that they are called with a variable | 	giving functions.  Be aware that they are called with a variable | ||||||
| 	number of arguments! | 	number of arguments! | ||||||
| */ | */ | ||||||
| 
 | 
 | ||||||
| #include	<stdio.h> | static char *RcsId = "$Header$"; | ||||||
|  | 
 | ||||||
|  | #include	<system.h> | ||||||
|  | #include	<em_arith.h> | ||||||
| #include	"input.h" | #include	"input.h" | ||||||
| #include	"f_info.h" | #include	"f_info.h" | ||||||
| #include	"LLlex.h" | #include	"LLlex.h" | ||||||
| 
 | 
 | ||||||
| static char *RcsId = "$Header$"; | #define MAXERR_LINE	5	/* Number of error messages on one line ... */ | ||||||
| 
 | #define	ERROUT		STDERR | ||||||
| #define	ERROUT	stderr |  | ||||||
| 
 | 
 | ||||||
|  | /* error classes */ | ||||||
| #define	ERROR		1 | #define	ERROR		1 | ||||||
| #define	WARNING		2 | #define	WARNING		2 | ||||||
| #define	LEXERROR	3 | #define	LEXERROR	3 | ||||||
| #define	LEXWARNING	4 | #define	LEXWARNING	4 | ||||||
| #define	CRASH		5 | #define	CRASH		5 | ||||||
| #define	FATAL		6 | #define	FATAL		6 | ||||||
| #define	NONFATAL	7 | #ifdef DEBUG | ||||||
| #ifdef	DEBUG | #define VDEBUG		7 | ||||||
| #define	VDEBUG		8 | #endif | ||||||
| #endif	DEBUG | 
 | ||||||
|  | #define NILEXPR	((struct expr *) 0) | ||||||
| 
 | 
 | ||||||
| int err_occurred; | int err_occurred; | ||||||
| /*
 |  | ||||||
| 	extern int ofd;		/* compact.c	* /
 |  | ||||||
| 	#define	compiling (ofd >= 0) |  | ||||||
| */ |  | ||||||
| 
 | 
 | ||||||
|  | extern char *symbol2str(); | ||||||
| extern char options[]; | extern char options[]; | ||||||
| 
 | 
 | ||||||
| /*	There are two general error message giving functions:
 | /*	There are three general error-message functions:
 | ||||||
| 	error() : syntactic and semantic error messages | 		lexerror()	lexical and pre-processor error messages | ||||||
| 	lexerror() : lexical and pre-processor error messages | 		error()		syntactic and semantic error messages | ||||||
| 	The difference lies in the fact that the first function deals with | 		expr_error()	errors in expressions | ||||||
| 	tokens already read in by the lexical analyzer so the name of the | 	The difference lies in the place where the file name and line | ||||||
| 	file it comes from and the linenumber must be retrieved from the | 	number come from. | ||||||
| 	token instead of looking at the global variables LineNumber and | 	Lexical errors report from the global variables LineNumber and | ||||||
| 	FileName. | 	FileName, expression errors get their information from the | ||||||
|  | 	expression, whereas other errors use the information in the token. | ||||||
| */ | */ | ||||||
| 
 | 
 | ||||||
|  | #ifdef DEBUG | ||||||
|  | /*VARARGS2*/ | ||||||
|  | debug(level, fmt, args) | ||||||
|  | 	char *fmt; | ||||||
|  | { | ||||||
|  | 	if (level <= options['D']) _error(VDEBUG, NILEXPR, fmt, &args); | ||||||
|  | } | ||||||
|  | #endif DEBUG | ||||||
|  | 
 | ||||||
| /*VARARGS1*/ | /*VARARGS1*/ | ||||||
| error(fmt, args) | error(fmt, args) | ||||||
| 	char *fmt; | 	char *fmt; | ||||||
| { | { | ||||||
| 	/*
 | 	_error(ERROR, NILEXPR, fmt, &args); | ||||||
| 		if (compiling) |  | ||||||
| 			C_ms_err(); |  | ||||||
| 	*/ |  | ||||||
| 	++err_occurred; |  | ||||||
| 	_error(ERROR, fmt, &args); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #ifdef DEBUG | /*VARARGS2*/ | ||||||
| debug(fmt, args) | expr_error(expr, fmt, args) | ||||||
|  | 	struct expr *expr; | ||||||
| 	char *fmt; | 	char *fmt; | ||||||
| { | { | ||||||
| 	if (options['D']) | 	_error(ERROR, expr, fmt, &args); | ||||||
| 		_error(VDEBUG, fmt, &args); | } | ||||||
|  | 
 | ||||||
|  | /*VARARGS1*/ | ||||||
|  | warning(fmt, args) | ||||||
|  | 	char *fmt; | ||||||
|  | { | ||||||
|  | 	_error(WARNING, NILEXPR, fmt, &args); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*VARARGS2*/ | ||||||
|  | expr_warning(expr, fmt, args) | ||||||
|  | 	struct expr *expr; | ||||||
|  | 	char *fmt; | ||||||
|  | { | ||||||
|  | 	_error(WARNING, expr, fmt, &args); | ||||||
| } | } | ||||||
| #endif DEBUG |  | ||||||
| 
 | 
 | ||||||
| /*VARARGS1*/ | /*VARARGS1*/ | ||||||
| lexerror(fmt, args) | lexerror(fmt, args) | ||||||
| 	char *fmt; | 	char *fmt; | ||||||
| { | { | ||||||
| 	/*
 | 	_error(LEXERROR, NILEXPR, fmt, &args); | ||||||
| 		if (compiling) |  | ||||||
| 			C_ms_err(); |  | ||||||
| 	*/ |  | ||||||
| 	++err_occurred; |  | ||||||
| 	_error(LEXERROR, fmt, &args); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /*VARARGS1*/ | /*VARARGS1*/ | ||||||
| lexwarning(fmt, args) char *fmt;	{ | lexwarning(fmt, args)  | ||||||
| 	if (options['w']) return; |  | ||||||
| 	_error(LEXWARNING, fmt, &args); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /*VARARGS1*/ |  | ||||||
| crash(fmt, args) |  | ||||||
| 	char *fmt; | 	char *fmt; | ||||||
| 	int args; |  | ||||||
| { | { | ||||||
| 	/*
 | 	_error(LEXWARNING, NILEXPR, fmt, &args); | ||||||
| 		if (compiling) |  | ||||||
| 			C_ms_err(); |  | ||||||
| 	*/ |  | ||||||
| 	_error(CRASH, fmt, &args); |  | ||||||
| 	fflush(ERROUT); |  | ||||||
| 	fflush(stderr); |  | ||||||
| 	fflush(stdout); |  | ||||||
| 	/*
 |  | ||||||
| 		cclose(); |  | ||||||
| 	*/ |  | ||||||
| 	abort();	/* produce core by "Illegal Instruction" */ |  | ||||||
| 			/* this should be changed into exit(1)	 */ |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /*VARARGS1*/ | /*VARARGS1*/ | ||||||
|  | @ -107,64 +103,103 @@ fatal(fmt, args) | ||||||
| 	char *fmt; | 	char *fmt; | ||||||
| 	int args; | 	int args; | ||||||
| { | { | ||||||
| 	/*
 | 
 | ||||||
| 		if (compiling) | 	_error(FATAL, NILEXPR, fmt, &args); | ||||||
| 			C_ms_err(); | 	sys_stop(S_EXIT); | ||||||
| 	*/ |  | ||||||
| 	_error(FATAL, fmt, &args); |  | ||||||
| 	exit(-1); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /*VARARGS1*/ | _error(class, expr, fmt, argv) | ||||||
| nonfatal(fmt, args) |  | ||||||
| 	char *fmt; |  | ||||||
| 	int args; |  | ||||||
| { |  | ||||||
| 	_error(NONFATAL, fmt, &args); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /*VARARGS1*/ |  | ||||||
| warning(fmt, args) |  | ||||||
| 	char *fmt; |  | ||||||
| { |  | ||||||
| 	if (options['w']) return; |  | ||||||
| 	_error(WARNING, fmt, &args); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| _error(class, fmt, argv) |  | ||||||
| 	int class; | 	int class; | ||||||
|  | 	struct expr *expr; | ||||||
| 	char *fmt; | 	char *fmt; | ||||||
| 	int argv[]; | 	int argv[]; | ||||||
| { | { | ||||||
|  | 	/*	_error attempts to limit the number of error messages
 | ||||||
|  | 		for a given line to MAXERR_LINE. | ||||||
|  | 	*/ | ||||||
|  | 	static unsigned int last_ln = 0; | ||||||
|  | 	static int e_seen = 0; | ||||||
|  | 	unsigned int ln = 0; | ||||||
|  | 	char *remark = 0; | ||||||
| 	 | 	 | ||||||
|  | 	/*	Since name and number are gathered from different places
 | ||||||
|  | 		depending on the class, we first collect the relevant | ||||||
|  | 		values and then decide what to print. | ||||||
|  | 	*/ | ||||||
|  | 	/* preliminaries */ | ||||||
| 	switch (class)	{ | 	switch (class)	{ | ||||||
| 
 |  | ||||||
| 	case ERROR: | 	case ERROR: | ||||||
| 	case LEXERROR: | 	case LEXERROR: | ||||||
| 		fprintf(ERROUT, "%s, line %ld: ", FileName, LineNumber); | 	case CRASH: | ||||||
|  | 	case FATAL: | ||||||
|  | 		/*
 | ||||||
|  | 		if (C_busy()) | ||||||
|  | 			C_ms_err(); | ||||||
|  | 		*/ | ||||||
|  | 		err_occurred = 1; | ||||||
| 		break; | 		break; | ||||||
|  | 	 | ||||||
| 	case WARNING: | 	case WARNING: | ||||||
| 	case LEXWARNING: | 	case LEXWARNING: | ||||||
| 		fprintf(ERROUT, "%s, line %ld: (warning) ", | 		if (options['w']) | ||||||
| 			FileName, LineNumber); | 			return; | ||||||
|  | 		break; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/* the remark */ | ||||||
|  | 	switch (class)	{	 | ||||||
|  | 	case WARNING: | ||||||
|  | 	case LEXWARNING: | ||||||
|  | 		remark = "(warning)"; | ||||||
| 		break; | 		break; | ||||||
| 	case CRASH: | 	case CRASH: | ||||||
| 		fprintf(ERROUT, "CRASH\007 %s, line %ld: \n", | 		remark = "CRASH\007"; | ||||||
| 			FileName, LineNumber); |  | ||||||
| 		break; | 		break; | ||||||
| 	case FATAL: | 	case FATAL: | ||||||
| 		fprintf(ERROUT, "%s, line %ld: fatal error -- ", | 		remark = "fatal error --"; | ||||||
| 			FileName, LineNumber); |  | ||||||
| 		break; | 		break; | ||||||
| 	case NONFATAL: |  | ||||||
| 		fprintf(ERROUT, "warning: ");	/* no line number ??? */ |  | ||||||
| 		break; |  | ||||||
| #ifdef DEBUG |  | ||||||
| 	case VDEBUG: |  | ||||||
| 		fprintf(ERROUT, "-D "); |  | ||||||
| 		break; |  | ||||||
| #endif DEBUG |  | ||||||
| 	} | 	} | ||||||
| 	_doprnt(fmt, argv, ERROUT); | 	 | ||||||
|  | 	/* the place */ | ||||||
|  | 	switch (class)	{	 | ||||||
|  | 	case WARNING: | ||||||
|  | 	case ERROR: | ||||||
|  | 		ln = /* expr ? expr->ex_line : */ dot.tk_lineno; | ||||||
|  | 		break; | ||||||
|  | 	case LEXWARNING: | ||||||
|  | 	case LEXERROR: | ||||||
|  | 	case CRASH: | ||||||
|  | 	case FATAL: | ||||||
|  | 		ln = LineNumber; | ||||||
|  | 		break; | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | #ifdef DEBUG | ||||||
|  | 	if (class != VDEBUG) { | ||||||
|  | #endif | ||||||
|  | 	if (ln == last_ln)	{ | ||||||
|  | 		/* we've seen this place before */ | ||||||
|  | 		e_seen++; | ||||||
|  | 		if (e_seen == MAXERR_LINE) | ||||||
|  | 			fmt = "etc ..."; | ||||||
|  | 		else | ||||||
|  | 		if (e_seen > MAXERR_LINE) | ||||||
|  | 			/* and too often, I'd say ! */ | ||||||
|  | 			return; | ||||||
|  | 	} | ||||||
|  | 	else	{ | ||||||
|  | 		/* brand new place */ | ||||||
|  | 		last_ln = ln; | ||||||
|  | 		e_seen = 0; | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | 	if (FileName) | ||||||
|  | 		fprintf(ERROUT, "\"%s\", line %u: ", FileName, ln); | ||||||
|  | 	if (remark) | ||||||
|  | 		fprintf(ERROUT, "%s ", remark); | ||||||
|  | #ifdef DEBUG | ||||||
|  | 	} | ||||||
|  | #endif | ||||||
|  | 	doprnt(ERROUT, fmt, argv);		/* contents of error */ | ||||||
| 	fprintf(ERROUT, "\n"); | 	fprintf(ERROUT, "\n"); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1,3 +1,5 @@ | ||||||
|  | /* F I L E   D E S C R I P T O R   S T R U C T U R E */ | ||||||
|  | 
 | ||||||
| /* $Header$ */ | /* $Header$ */ | ||||||
| 
 | 
 | ||||||
| struct f_info { | struct f_info { | ||||||
|  |  | ||||||
|  | @ -1,3 +1,5 @@ | ||||||
|  | /* I N S T A N T I A T I O N   O F   I D F   P A C K A G E */ | ||||||
|  | 
 | ||||||
| /* $Header$ */ | /* $Header$ */ | ||||||
| 
 | 
 | ||||||
| #include	"idf.h" | #include	"idf.h" | ||||||
|  |  | ||||||
|  | @ -1,5 +1,14 @@ | ||||||
|  | /* U S E R   D E C L A R E D   P A R T   O F   I D F */ | ||||||
|  | 
 | ||||||
| /* $Header$ */ | /* $Header$ */ | ||||||
| 
 | 
 | ||||||
| #define IDF_TYPE int | struct id_u { | ||||||
| #define id_reserved id_user | 	int id_res; | ||||||
|  | 	struct def *id_df; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | #define IDF_TYPE	struct id_u | ||||||
|  | #define id_reserved	id_user.id_res | ||||||
|  | #define id_def		id_user.id_df | ||||||
|  | 
 | ||||||
| #include	<idf_pkg.spec> | #include	<idf_pkg.spec> | ||||||
|  |  | ||||||
|  | @ -1,3 +1,5 @@ | ||||||
|  | /* I N S T A N T I A T I O N   O F   I N P U T   P A C K A G E */ | ||||||
|  | 
 | ||||||
| /* $Header$ */ | /* $Header$ */ | ||||||
| 
 | 
 | ||||||
| #include	"f_info.h" | #include	"f_info.h" | ||||||
|  |  | ||||||
|  | @ -1,3 +1,5 @@ | ||||||
|  | /* I N S T A N T I A T I O N   O F   I N P U T   M O D U L E */ | ||||||
|  | 
 | ||||||
| /* $Header$ */ | /* $Header$ */ | ||||||
| 
 | 
 | ||||||
| #define INP_NPUSHBACK 2 | #define INP_NPUSHBACK 2 | ||||||
|  |  | ||||||
|  | @ -1,18 +1,20 @@ | ||||||
| /* mod2 -- compiler , althans: een aanzet daartoe */ | /* M A I N   P R O G R A M */ | ||||||
| 
 |  | ||||||
| #include <stdio.h> |  | ||||||
| #undef BUFSIZ			/* Really neccesary??? */ |  | ||||||
| #include <system.h> |  | ||||||
| #include "input.h" |  | ||||||
| #include "f_info.h" |  | ||||||
| #include "idf.h" |  | ||||||
| #include "LLlex.h" |  | ||||||
| #include "Lpars.h" |  | ||||||
| 
 | 
 | ||||||
| static char *RcsId = "$Header$"; | static char *RcsId = "$Header$"; | ||||||
| 
 | 
 | ||||||
|  | #include	<system.h> | ||||||
|  | #include	<em_arith.h> | ||||||
|  | #include	"input.h" | ||||||
|  | #include	"f_info.h" | ||||||
|  | #include	"idf.h" | ||||||
|  | #include	"LLlex.h" | ||||||
|  | #include	"Lpars.h" | ||||||
|  | #include	"main.h" | ||||||
|  | #include	"debug.h" | ||||||
|  | 
 | ||||||
| char options[128]; | char options[128]; | ||||||
| char *ProgName; | char *ProgName; | ||||||
|  | int state; | ||||||
| extern int err_occurred; | extern int err_occurred; | ||||||
| 
 | 
 | ||||||
| main(argc, argv) | main(argc, argv) | ||||||
|  | @ -23,9 +25,6 @@ main(argc, argv) | ||||||
| 
 | 
 | ||||||
| 	ProgName = *argv++; | 	ProgName = *argv++; | ||||||
| 
 | 
 | ||||||
| # ifdef DEBUG |  | ||||||
| 	setbuf(stdout, (char *) 0); |  | ||||||
| # endif |  | ||||||
| 	while (--argc > 0) { | 	while (--argc > 0) { | ||||||
| 		if (**argv == '-') | 		if (**argv == '-') | ||||||
| 			Option(*argv++); | 			Option(*argv++); | ||||||
|  | @ -34,13 +33,13 @@ main(argc, argv) | ||||||
| 	} | 	} | ||||||
| 	Nargv[Nargc] = 0;	/* terminate the arg vector	*/ | 	Nargv[Nargc] = 0;	/* terminate the arg vector	*/ | ||||||
| 	if (Nargc != 2) { | 	if (Nargc != 2) { | ||||||
| 		fprintf(stderr, "%s: Use one file argument\n", ProgName); | 		fprintf(STDERR, "%s: Use one file argument\n", ProgName); | ||||||
| 		return 1; | 		return 1; | ||||||
| 	} | 	} | ||||||
| #ifdef DEBUG | #ifdef DEBUG | ||||||
| 	printf("Mod2 compiler -- Debug version\n"); | 	printf("Mod2 compiler -- Debug version\n"); | ||||||
| 	debug("-D: Debugging on"); |  | ||||||
| #endif DEBUG | #endif DEBUG | ||||||
|  | 	DO_DEBUG(debug(1,"Debugging level: %d", options['D'])); | ||||||
| 	return !Compile(Nargv[1]); | 	return !Compile(Nargv[1]); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -53,13 +52,15 @@ Compile(src) | ||||||
| 	printf("%s\n", src); | 	printf("%s\n", src); | ||||||
| #endif DEBUG | #endif DEBUG | ||||||
| 	if (! InsertFile(src, (char **) 0)) { | 	if (! InsertFile(src, (char **) 0)) { | ||||||
| 		fprintf(stderr,"%s: cannot open %s\n", ProgName, src); | 		fprintf(STDERR,"%s: cannot open %s\n", ProgName, src); | ||||||
| 		return 0; | 		return 0; | ||||||
| 	} | 	} | ||||||
| 	LineNumber = 1; | 	LineNumber = 1; | ||||||
| 	FileName = src; | 	FileName = src; | ||||||
| 	init_idf(); | 	init_idf(); | ||||||
| 	reserve(tkidf); | 	reserve(tkidf); | ||||||
|  | 	init_scope(); | ||||||
|  | 	init_types(); | ||||||
| #ifdef DEBUG | #ifdef DEBUG | ||||||
| 	if (options['L']) | 	if (options['L']) | ||||||
| 		LexScan(); | 		LexScan(); | ||||||
|  | @ -80,7 +81,7 @@ LexScan() | ||||||
| { | { | ||||||
| 	register int symb; | 	register int symb; | ||||||
| 
 | 
 | ||||||
| 	while ((symb = LLlex()) != EOF) { | 	while ((symb = LLlex()) != EOI) { | ||||||
| 		printf(">>> %s ", symbol2str(symb)); | 		printf(">>> %s ", symbol2str(symb)); | ||||||
| 		switch(symb) { | 		switch(symb) { | ||||||
| 
 | 
 | ||||||
|  | @ -107,15 +108,12 @@ LexScan() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| TimeScan() { | TimeScan() { | ||||||
| 	while (LLlex() != EOF) /* nothing */; | 	while (LLlex() != -1) /* nothing */; | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| Option(str) | Option(str) | ||||||
| 	char *str; | 	char *str; | ||||||
| { | { | ||||||
| #ifdef DEBUG |  | ||||||
| 	debug("option %c", str[1]); |  | ||||||
| #endif DEBUG |  | ||||||
| 	options[str[1]]++;	/* switch option on	*/ | 	options[str[1]]++;	/* switch option on	*/ | ||||||
| } | } | ||||||
|  |  | ||||||
							
								
								
									
										8
									
								
								lang/m2/comp/main.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								lang/m2/comp/main.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,8 @@ | ||||||
|  | /* S O M E   G L O B A L   V A R I A B L E S */ | ||||||
|  | 
 | ||||||
|  | /* $Header$ */ | ||||||
|  | 
 | ||||||
|  | extern int | ||||||
|  | 	state;		/* Indicates what we are compiling: A DEFINITION,
 | ||||||
|  | 			   an IMPLEMENTATION, or a PROGRAM module | ||||||
|  | 			*/ | ||||||
							
								
								
									
										12
									
								
								lang/m2/comp/misc.H
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								lang/m2/comp/misc.H
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,12 @@ | ||||||
|  | /* M I S C E L L A N E O U S */ | ||||||
|  | 
 | ||||||
|  | /* $Header$ */ | ||||||
|  | 
 | ||||||
|  | /*	Structure to link idf structures together
 | ||||||
|  | */ | ||||||
|  | struct id_list { | ||||||
|  | 	struct id_list *next; | ||||||
|  | 	struct idf *id_ptr; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /* ALLOCDEF "id_list" */ | ||||||
							
								
								
									
										63
									
								
								lang/m2/comp/misc.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								lang/m2/comp/misc.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,63 @@ | ||||||
|  | /* M I S C E L L A N E O U S    R O U T I N E S */ | ||||||
|  | 
 | ||||||
|  | static char *RcsId = "$Header$"; | ||||||
|  | 
 | ||||||
|  | #include	<alloc.h> | ||||||
|  | #include	<em_arith.h> | ||||||
|  | #include	"f_info.h" | ||||||
|  | #include	"misc.h" | ||||||
|  | #include	"LLlex.h" | ||||||
|  | #include	"idf.h" | ||||||
|  | 
 | ||||||
|  | match_id(id1, id2) | ||||||
|  | 	struct idf *id1, *id2; | ||||||
|  | { | ||||||
|  | 	/*	Check that identifiers id1 and id2 are equal. If they
 | ||||||
|  | 		are not, check that we did'nt generate them in the | ||||||
|  | 		first place, and if not, give an error message | ||||||
|  | 	*/ | ||||||
|  | 	if (id1 != id2 && !is_anon_idf(id1) && !is_anon_idf(id2)) { | ||||||
|  | 		error("Identifier \"%s\" does not match identifier \"%s\"", | ||||||
|  | 		      id1->id_text, | ||||||
|  | 		      id2->id_text | ||||||
|  | 		); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | struct id_list *h_id_list;	/* Header of free list of id_list structures */ | ||||||
|  | 
 | ||||||
|  | /*	FreeIdList: take a list of id_list structures and put them
 | ||||||
|  | 	on the free list of id_list structures | ||||||
|  | */ | ||||||
|  | FreeIdList(p) | ||||||
|  | 	struct id_list *p; | ||||||
|  | { | ||||||
|  | 	register struct id_list *q; | ||||||
|  | 
 | ||||||
|  | 	while (q = p) { | ||||||
|  | 		p = p->next; | ||||||
|  | 		free_id_list(q); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | struct idf * | ||||||
|  | gen_anon_idf() | ||||||
|  | { | ||||||
|  | 	/*	A new idf is created out of nowhere, to serve as an
 | ||||||
|  | 		anonymous name. | ||||||
|  | 	*/ | ||||||
|  | 	static int name_cnt; | ||||||
|  | 	char buff[100]; | ||||||
|  | 	char *sprintf(); | ||||||
|  | 
 | ||||||
|  | 	sprintf(buff, "#%d in %s, line %u", | ||||||
|  | 			++name_cnt, FileName, LineNumber); | ||||||
|  | 	return str2idf(buff, 1); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int | ||||||
|  | is_anon_idf(idf) | ||||||
|  | 	struct idf *idf; | ||||||
|  | { | ||||||
|  | 	return idf->id_text[0] == '#'; | ||||||
|  | } | ||||||
							
								
								
									
										144
									
								
								lang/m2/comp/print.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										144
									
								
								lang/m2/comp/print.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,144 @@ | ||||||
|  | /* P R I N T    R O U T I N E S */ | ||||||
|  | 
 | ||||||
|  | #include	<system.h> | ||||||
|  | #include	<em_arith.h> | ||||||
|  | 
 | ||||||
|  | #define SSIZE	1024	/* string-buffer size for print routines	*/ | ||||||
|  | 
 | ||||||
|  | char *long2str(); | ||||||
|  | 
 | ||||||
|  | doprnt(fp, fmt, argp) | ||||||
|  | 	File *fp; | ||||||
|  | 	char *fmt; | ||||||
|  | 	int argp[]; | ||||||
|  | { | ||||||
|  | 	char buf[SSIZE]; | ||||||
|  | 
 | ||||||
|  | 	sys_write(fp, buf, format(buf, fmt, (char *)argp)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*VARARGS1*/ | ||||||
|  | printf(fmt, args) | ||||||
|  | 	char *fmt; | ||||||
|  | 	char args; | ||||||
|  | { | ||||||
|  | 	char buf[SSIZE]; | ||||||
|  | 
 | ||||||
|  | 	sys_write(STDOUT, buf, format(buf, fmt, &args)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*VARARGS1*/ | ||||||
|  | fprintf(fp, fmt, args) | ||||||
|  | 	File *fp; | ||||||
|  | 	char *fmt; | ||||||
|  | 	char args; | ||||||
|  | { | ||||||
|  | 	char buf[SSIZE]; | ||||||
|  | 
 | ||||||
|  | 	sys_write(fp, buf, format(buf, fmt, &args)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*VARARGS1*/ | ||||||
|  | char * | ||||||
|  | sprintf(buf, fmt, args) | ||||||
|  | 	char *buf, *fmt; | ||||||
|  | 	char args; | ||||||
|  | { | ||||||
|  | 	buf[format(buf, fmt, &args)] = '\0'; | ||||||
|  | 	return buf; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int | ||||||
|  | format(buf, fmt, argp) | ||||||
|  | 	char *buf, *fmt; | ||||||
|  | 	char *argp; | ||||||
|  | { | ||||||
|  | 	register char *pf = fmt, *pa = argp; | ||||||
|  | 	register char *pb = buf; | ||||||
|  | 
 | ||||||
|  | 	while (*pf) { | ||||||
|  | 		if (*pf == '%') { | ||||||
|  | 			register int width, base, pad, npad; | ||||||
|  | 			char *arg; | ||||||
|  | 			char cbuf[2]; | ||||||
|  | 			char *badformat = "<bad format>"; | ||||||
|  | 			 | ||||||
|  | 			/* get padder */ | ||||||
|  | 			if (*++pf == '0') { | ||||||
|  | 				pad = '0'; | ||||||
|  | 				++pf; | ||||||
|  | 			} | ||||||
|  | 			else | ||||||
|  | 				pad = ' '; | ||||||
|  | 			 | ||||||
|  | 			/* get width */ | ||||||
|  | 			width = 0; | ||||||
|  | 			while (*pf >= '0' && *pf <= '9') | ||||||
|  | 				width = 10 * width + *pf++ - '0'; | ||||||
|  | 			 | ||||||
|  | 			/* get text and move pa */ | ||||||
|  | 			if (*pf == 's') { | ||||||
|  | 				arg = *(char **)pa; | ||||||
|  | 				pa += sizeof(char *); | ||||||
|  | 			} | ||||||
|  | 			else | ||||||
|  | 			if (*pf == 'c') { | ||||||
|  | 				cbuf[0] = * (char *) pa; | ||||||
|  | 				cbuf[1] = '\0'; | ||||||
|  | 				pa += sizeof(int); | ||||||
|  | 				arg = &cbuf[0]; | ||||||
|  | 			} | ||||||
|  | 			else | ||||||
|  | 			if (*pf == 'l') { | ||||||
|  | 				/* alignment ??? */ | ||||||
|  | 				if (base = integral(*++pf)) { | ||||||
|  | 					arg = long2str(*(long *)pa, base); | ||||||
|  | 					pa += sizeof(long); | ||||||
|  | 				} | ||||||
|  | 				else { | ||||||
|  | 					pf--; | ||||||
|  | 					arg = badformat; | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 			else | ||||||
|  | 			if (base = integral(*pf)) { | ||||||
|  | 				arg = long2str((long)*(int *)pa, base); | ||||||
|  | 				pa += sizeof(int); | ||||||
|  | 			} | ||||||
|  | 			else | ||||||
|  | 			if (*pf == '%') | ||||||
|  | 				arg = "%"; | ||||||
|  | 			else | ||||||
|  | 				arg = badformat; | ||||||
|  | 
 | ||||||
|  | 			npad = width - strlen(arg); | ||||||
|  | 
 | ||||||
|  | 			while (npad-- > 0) | ||||||
|  | 				*pb++ = pad; | ||||||
|  | 			 | ||||||
|  | 			while (*pb++ = *arg++); | ||||||
|  | 			pb--; | ||||||
|  | 			pf++; | ||||||
|  | 		} | ||||||
|  | 		else | ||||||
|  | 			*pb++ = *pf++; | ||||||
|  | 	} | ||||||
|  | 	return pb - buf; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | integral(c) | ||||||
|  | { | ||||||
|  | 	switch (c) { | ||||||
|  | 	case 'b': | ||||||
|  | 		return -2; | ||||||
|  | 	case 'd': | ||||||
|  | 		return 10; | ||||||
|  | 	case 'o': | ||||||
|  | 		return -8; | ||||||
|  | 	case 'u': | ||||||
|  | 		return -10; | ||||||
|  | 	case 'x': | ||||||
|  | 		return -16; | ||||||
|  | 	} | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | @ -1,8 +1,15 @@ | ||||||
| /* | /* O V E R A L L   S T R U C T U R E */ | ||||||
| 	Program: Modula-2 grammar in LL(1) form |  | ||||||
| 	Version: Mon Feb 24 14:29:39 MET 1986 |  | ||||||
| */ |  | ||||||
| 
 | 
 | ||||||
|  | { | ||||||
|  | static  char *RcsId = "$Header$"; | ||||||
|  | 
 | ||||||
|  | #include	<alloc.h> | ||||||
|  | #include	<em_arith.h> | ||||||
|  | #include	"idf.h" | ||||||
|  | #include	"misc.h" | ||||||
|  | #include	"main.h" | ||||||
|  | #include	"LLlex.h" | ||||||
|  | } | ||||||
| /* | /* | ||||||
| 	The grammar as given by Wirth is already almost LL(1); the | 	The grammar as given by Wirth is already almost LL(1); the | ||||||
| 	main problem is that the full form of a qualified designator | 	main problem is that the full form of a qualified designator | ||||||
|  | @ -17,19 +24,12 @@ | ||||||
| 	field identifiers. | 	field identifiers. | ||||||
| */ | */ | ||||||
| 
 | 
 | ||||||
| { |  | ||||||
| #include "idf.h" |  | ||||||
| #include "idlist.h" |  | ||||||
| 
 |  | ||||||
| static  char *RcsId = "$Header$"; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| %lexical LLlex; | %lexical LLlex; | ||||||
| 
 | 
 | ||||||
| %start	CompUnit, CompilationUnit; | %start	CompUnit, CompilationUnit; | ||||||
| 
 | 
 | ||||||
| ModuleDeclaration: | ModuleDeclaration: | ||||||
| 	MODULE IDENT priority? ';' import* export? block IDENT | 	MODULE IDENT priority? ';' import(1)* export? block IDENT | ||||||
| ; | ; | ||||||
| 
 | 
 | ||||||
| priority: | priority: | ||||||
|  | @ -41,14 +41,18 @@ export | ||||||
| 	struct id_list *ExportList; | 	struct id_list *ExportList; | ||||||
| } : | } : | ||||||
| 	EXPORT QUALIFIED? IdentList(&ExportList) ';' | 	EXPORT QUALIFIED? IdentList(&ExportList) ';' | ||||||
|  | 			{ | ||||||
|  | 			  FreeIdList(ExportList); | ||||||
|  | 			} | ||||||
| ; | ; | ||||||
| 
 | 
 | ||||||
| import | import(int local;) | ||||||
| { | { | ||||||
| 	struct id_list *ImportList; | 	struct id_list *ImportList; | ||||||
|  | 	struct idf *id = 0; | ||||||
| } : | } : | ||||||
| 	[ FROM | 	[ FROM | ||||||
| 	  IDENT | 	  IDENT		{ id = dot.TOK_IDF; } | ||||||
| 	]? | 	]? | ||||||
| 	IMPORT IdentList(&ImportList) ';' | 	IMPORT IdentList(&ImportList) ';' | ||||||
| 	/* | 	/* | ||||||
|  | @ -57,19 +61,19 @@ import | ||||||
| 	   If the FROM clause is present, the identifier in it is a module | 	   If the FROM clause is present, the identifier in it is a module | ||||||
| 	   name, otherwise the names in the import list are module names. | 	   name, otherwise the names in the import list are module names. | ||||||
| 	*/ | 	*/ | ||||||
|  | 			{ | ||||||
|  | 			  FreeIdList(ImportList); | ||||||
|  | 			} | ||||||
| ; | ; | ||||||
| 
 | 
 | ||||||
| DefinitionModule: | DefinitionModule: | ||||||
| 	DEFINITION | 	DEFINITION	{ state = DEFINITION; } | ||||||
| 	{ | 	MODULE IDENT | ||||||
| #ifdef DEBUG | 	';' | ||||||
| 		debug("Definition module"); | 	import(0)*  | ||||||
| #endif DEBUG | 	/*	export? | ||||||
| 	} |  | ||||||
| 	MODULE IDENT ';' import*  |  | ||||||
| 	/* export? |  | ||||||
| 
 | 
 | ||||||
| 	   New Modula-2 does not have export lists in definition modules. | 	   	New Modula-2 does not have export lists in definition modules. | ||||||
| 	*/ | 	*/ | ||||||
| 	definition* END IDENT '.' | 	definition* END IDENT '.' | ||||||
| ; | ; | ||||||
|  | @ -96,19 +100,17 @@ definition: | ||||||
| ; | ; | ||||||
| 
 | 
 | ||||||
| ProgramModule: | ProgramModule: | ||||||
| 	MODULE | 	MODULE		{ if (state != IMPLEMENTATION) state = PROGRAM; } | ||||||
| 	{ | 	IDENT priority? ';' import(0)* block IDENT '.' | ||||||
| #ifdef DEBUG |  | ||||||
| 		debug("Program module"); |  | ||||||
| #endif DEBUG |  | ||||||
| 	} |  | ||||||
| 	IDENT priority? ';' import* block IDENT '.' |  | ||||||
| ; | ; | ||||||
| 
 | 
 | ||||||
| Module: | Module: | ||||||
| 	DefinitionModule | 	DefinitionModule | ||||||
| | | | | ||||||
| 	IMPLEMENTATION? ProgramModule | 	[ | ||||||
|  | 		IMPLEMENTATION	{ state = IMPLEMENTATION; } | ||||||
|  | 	]? | ||||||
|  | 	ProgramModule | ||||||
| ; | ; | ||||||
| 
 | 
 | ||||||
| CompilationUnit: | CompilationUnit: | ||||||
|  |  | ||||||
							
								
								
									
										62
									
								
								lang/m2/comp/scope.C
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								lang/m2/comp/scope.C
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,62 @@ | ||||||
|  | /* S C O P E   M E C H A N I S M */ | ||||||
|  | 
 | ||||||
|  | static char *RcsId = "$Header$"; | ||||||
|  | 
 | ||||||
|  | #include	<assert.h> | ||||||
|  | #include	<alloc.h> | ||||||
|  | #include	"scope.h" | ||||||
|  | 
 | ||||||
|  | static int maxscope;		/* maximum assigned scope number */ | ||||||
|  | 
 | ||||||
|  | struct scope *CurrentScope; | ||||||
|  | 
 | ||||||
|  | /* STATICALLOCDEF "scope" */ | ||||||
|  | 
 | ||||||
|  | /*	Open a scope that is either open (automatic imports) or closed.
 | ||||||
|  | 	A closed scope is handled by adding an extra entry to the list | ||||||
|  | 	with scope number 0. This has two purposes: it makes scope 0 | ||||||
|  | 	visible, and it marks the end of a visibility list. | ||||||
|  | 	Scope 0 is the pervasive scope, the one that is always visible. | ||||||
|  | 	A disadvantage of this method is that we cannot open scope 0 | ||||||
|  | 	explicitly. | ||||||
|  | */ | ||||||
|  | open_scope(scopetype, scopenr) | ||||||
|  | { | ||||||
|  | 	register struct scope *sc = new_scope(); | ||||||
|  | 	register struct scope *sc1; | ||||||
|  | 
 | ||||||
|  | 	sc->sc_scope = scopenr == 0 ? ++maxscope : scopenr; | ||||||
|  | 	assert(scopetype == OPENSCOPE || scopetype == CLOSEDSCOPE); | ||||||
|  | 	sc1 = CurrentScope; | ||||||
|  | 	if (scopetype == CLOSEDSCOPE) { | ||||||
|  | 		sc1 = new_scope(); | ||||||
|  | 		sc1->sc_scope = 0;			/* Pervasive scope nr */ | ||||||
|  | 		sc1->next = CurrentScope; | ||||||
|  | 	} | ||||||
|  | 	sc->next = sc1; | ||||||
|  | 	CurrentScope = sc; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | close_scope() | ||||||
|  | { | ||||||
|  | 	register struct scope *sc = CurrentScope; | ||||||
|  | 
 | ||||||
|  | 	assert(sc != 0); | ||||||
|  | 	if (sc->next && (sc->next->sc_scope == 0)) { | ||||||
|  | 		struct scope *sc1 = sc; | ||||||
|  | 
 | ||||||
|  | 		sc = sc->next; | ||||||
|  | 		free_scope(sc1); | ||||||
|  | 	} | ||||||
|  | 	CurrentScope = sc->next; | ||||||
|  | 	free_scope(sc); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | init_scope() | ||||||
|  | { | ||||||
|  | 	register struct scope *sc = new_scope(); | ||||||
|  | 
 | ||||||
|  | 	sc->sc_scope = 0; | ||||||
|  | 	sc->next = 0; | ||||||
|  | 	CurrentScope = sc; | ||||||
|  | } | ||||||
							
								
								
									
										19
									
								
								lang/m2/comp/scope.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								lang/m2/comp/scope.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,19 @@ | ||||||
|  | /* S C O P E   M E C H A N I S M */ | ||||||
|  | 
 | ||||||
|  | /* $Header$ */ | ||||||
|  | 
 | ||||||
|  | #define OPENSCOPE	0	/* Indicating an open scope */ | ||||||
|  | #define CLOSEDSCOPE	1	/* Indicating a closed scope (module) */ | ||||||
|  | 
 | ||||||
|  | struct scope { | ||||||
|  | 	struct scope *next; | ||||||
|  | 	int sc_scope;		/* The scope number. Scope number 0 indicates
 | ||||||
|  | 				   both the pervasive scope and the end of a | ||||||
|  | 				   visibility range | ||||||
|  | 				*/ | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | extern struct scope | ||||||
|  | 	*CurrentScope; | ||||||
|  | 
 | ||||||
|  | #define nextvisible(x)	((x)->sc_scope ? (x)->next : (struct scope *) 0) | ||||||
|  | @ -1,3 +1,5 @@ | ||||||
|  | /* S T A T E M E N T S */ | ||||||
|  | 
 | ||||||
| { | { | ||||||
| static char *RcsId = "$Header$"; | static char *RcsId = "$Header$"; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1,6 +1,10 @@ | ||||||
| #include "tokenname.h" | /* T O K E N   D E F I N I T I O N S */ | ||||||
| #include "Lpars.h" | 
 | ||||||
| #include "idf.h" | static char *RcsId = "$Header$"; | ||||||
|  | 
 | ||||||
|  | #include	"tokenname.h" | ||||||
|  | #include	"Lpars.h" | ||||||
|  | #include	"idf.h" | ||||||
| 
 | 
 | ||||||
| /*	To centralize the declaration of %tokens, their presence in this
 | /*	To centralize the declaration of %tokens, their presence in this
 | ||||||
| 	file is taken as their declaration. The Makefile will produce | 	file is taken as their declaration. The Makefile will produce | ||||||
|  | @ -9,8 +13,6 @@ | ||||||
| 	Also, the "token2str.c" file is produced from this file. | 	Also, the "token2str.c" file is produced from this file. | ||||||
| */ | */ | ||||||
| 
 | 
 | ||||||
| static char *RcsId = "$Header$"; |  | ||||||
| 
 |  | ||||||
| struct tokenname tkspec[] =	{	/* the names of the special tokens */ | struct tokenname tkspec[] =	{	/* the names of the special tokens */ | ||||||
| 	{IDENT, "identifier"}, | 	{IDENT, "identifier"}, | ||||||
| 	{STRING, "string"}, | 	{STRING, "string"}, | ||||||
|  | @ -73,10 +75,18 @@ struct tokenname tkidf[] =	{	/* names of the identifier tokens */ | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct tokenname tkinternal[] = {	/* internal keywords	*/ | struct tokenname tkinternal[] = {	/* internal keywords	*/ | ||||||
|  | 	{PROGRAM, ""}, | ||||||
| 	{0, "0"} | 	{0, "0"} | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct tokenname tkstandard[] =	{	/* standard identifiers */ | struct tokenname tkstandard[] =	{	/* standard identifiers */ | ||||||
|  | 	{CHAR, "CHAR"}, | ||||||
|  | 	{BOOLEAN, "BOOLEAN"}, | ||||||
|  | 	{LONGINT, "LONGINT"}, | ||||||
|  | 	{CARDINAL, "CARDINAL"}, | ||||||
|  | 	{LONGREAL, "LONGREAL"}, | ||||||
|  | 	{SUBRANGE, ""}, | ||||||
|  | 	{ERRONEOUS, ""}, | ||||||
| 	{0, ""} | 	{0, ""} | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,4 +1,7 @@ | ||||||
|  | /* T O K E N N A M E   S T R U C T U R E */ | ||||||
|  | 
 | ||||||
| /* $Header$ */ | /* $Header$ */ | ||||||
|  | 
 | ||||||
| struct tokenname	{	/*	Used for defining the name of a
 | struct tokenname	{	/*	Used for defining the name of a
 | ||||||
| 					token as identified by its symbol | 					token as identified by its symbol | ||||||
| 				*/ | 				*/ | ||||||
|  |  | ||||||
							
								
								
									
										90
									
								
								lang/m2/comp/type.H
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								lang/m2/comp/type.H
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,90 @@ | ||||||
|  | /* T Y P E   D E S C R I P T O R   S T R U C T U R E */ | ||||||
|  | 
 | ||||||
|  | /* $Header$ */ | ||||||
|  | 
 | ||||||
|  | struct paramlist {		/* structure for parameterlist of a PROCEDURE */ | ||||||
|  | 	struct paramlist *next; | ||||||
|  | 	struct type *par_type;	/* Parameter type */ | ||||||
|  | 	int par_var;		/* flag, set if VAR parameter */ | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /* ALLOCDEF "paramlist" */ | ||||||
|  | 
 | ||||||
|  | struct enume { | ||||||
|  | 	struct def *en_enums;	/* Definitions of enumeration literals */ | ||||||
|  | 	unsigned int en_ncst;	/* Number of constants */ | ||||||
|  | 	label en_rck;		/* Label of range check descriptor */ | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | struct subrange { | ||||||
|  | 	arith su_lb, su_ub;	/* Lower bound and upper bound */ | ||||||
|  | 	label su_rck;		/* Label of range check descriptor */ | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | struct array { | ||||||
|  | 	struct type *ar_index;	/* Type of index */ | ||||||
|  | 	arith ar_lb, ar_ub;	/* Lower bound and upper bound */ | ||||||
|  | 	label ar_descr;		/* Label of array descriptor */ | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | struct record { | ||||||
|  | 	int rc_scopenr;		/* Scope number of this record */ | ||||||
|  | 				/* Members are in the symbol table */ | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | struct proc { | ||||||
|  | 	struct paramlist *pr_params; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | struct type	{ | ||||||
|  | 	struct type *next;	/* used with ARRAY, PROCEDURE, POINTER, SET,
 | ||||||
|  | 				   SUBRANGE | ||||||
|  | 				*/ | ||||||
|  | 	int tp_fund;		/* fundamental type  or constructor */ | ||||||
|  | 	int tp_align;		/* alignment requirement of this type */ | ||||||
|  | 	arith tp_size;		/* size of this type */ | ||||||
|  | /*	struct idf *tp_idf;	/* name of this type */ | ||||||
|  | 	union { | ||||||
|  | 	    struct enume tp_enum; | ||||||
|  | 	    struct subrange tp_subrange; | ||||||
|  | 	    struct array tp_arr; | ||||||
|  | 	    struct record tp_record; | ||||||
|  | 	    struct proc tp_proc; | ||||||
|  | 	} tp_value; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /* ALLOCDEF "type" */ | ||||||
|  | 
 | ||||||
|  | extern struct type | ||||||
|  | 	*char_type, | ||||||
|  | 	*int_type, | ||||||
|  | 	*card_type, | ||||||
|  | 	*longint_type, | ||||||
|  | 	*real_type, | ||||||
|  | 	*longreal_type, | ||||||
|  | 	*error_type; | ||||||
|  | 
 | ||||||
|  | extern int | ||||||
|  | 	wrd_align, | ||||||
|  | 	int_align, | ||||||
|  | 	lint_align, | ||||||
|  | 	real_align, | ||||||
|  | 	lreal_align, | ||||||
|  | 	ptr_align, | ||||||
|  | 	record_align; | ||||||
|  | 
 | ||||||
|  | extern arith | ||||||
|  | 	wrd_size, | ||||||
|  | 	int_size, | ||||||
|  | 	lint_size, | ||||||
|  | 	real_size, | ||||||
|  | 	lreal_size, | ||||||
|  | 	ptr_size; | ||||||
|  | 
 | ||||||
|  | extern arith | ||||||
|  | 	align(); | ||||||
|  | 
 | ||||||
|  | struct type | ||||||
|  | 	*create_type(), | ||||||
|  | 	*construct_type(), | ||||||
|  | 	*standard_type(); | ||||||
							
								
								
									
										134
									
								
								lang/m2/comp/type.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										134
									
								
								lang/m2/comp/type.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,134 @@ | ||||||
|  | /*	T Y P E   D E F I N I T I O N   M E C H A N I S M	 */ | ||||||
|  | 
 | ||||||
|  | static char *RcsId = "$Header$"; | ||||||
|  | 
 | ||||||
|  | #include	<assert.h> | ||||||
|  | #include	<alloc.h> | ||||||
|  | #include	<em_arith.h> | ||||||
|  | #include	<em_label.h> | ||||||
|  | #include	"def_sizes.h" | ||||||
|  | #include	"Lpars.h" | ||||||
|  | #include	"def.h" | ||||||
|  | #include	"type.h" | ||||||
|  | #include	"idf.h" | ||||||
|  | 
 | ||||||
|  | /*	To be created dynamically in main() from defaults or from command
 | ||||||
|  | 	line parameters. | ||||||
|  | */ | ||||||
|  | int | ||||||
|  | 	wrd_align = AL_WORD, | ||||||
|  | 	int_align = AL_INT, | ||||||
|  | 	lint_align = AL_LONG, | ||||||
|  | 	real_align = AL_FLOAT, | ||||||
|  | 	lreal_align = AL_DOUBLE, | ||||||
|  | 	ptr_align = AL_POINTER, | ||||||
|  | 	record_align = AL_STRUCT; | ||||||
|  | 
 | ||||||
|  | arith | ||||||
|  | 	wrd_size = SZ_WORD, | ||||||
|  | 	int_size = SZ_INT, | ||||||
|  | 	lint_size = SZ_LONG, | ||||||
|  | 	real_size = SZ_FLOAT, | ||||||
|  | 	lreal_size = SZ_DOUBLE, | ||||||
|  | 	ptr_size = SZ_POINTER; | ||||||
|  | 
 | ||||||
|  | struct type | ||||||
|  | 	*bool_type, | ||||||
|  | 	*char_type, | ||||||
|  | 	*int_type, | ||||||
|  | 	*card_type, | ||||||
|  | 	*longint_type, | ||||||
|  | 	*real_type, | ||||||
|  | 	*longreal_type, | ||||||
|  | 	*error_type; | ||||||
|  | 
 | ||||||
|  | struct paramlist *h_paramlist; | ||||||
|  | 
 | ||||||
|  | struct type *h_type; | ||||||
|  | 
 | ||||||
|  | struct type * | ||||||
|  | create_type(fund) | ||||||
|  | 	register int fund; | ||||||
|  | { | ||||||
|  | 	/*	A brand new struct type is created, and its tp_fund set
 | ||||||
|  | 		to fund. | ||||||
|  | 	*/ | ||||||
|  | 	register struct type *ntp = new_type(); | ||||||
|  | 
 | ||||||
|  | 	clear((char *)ntp, sizeof(struct type)); | ||||||
|  | 	ntp->tp_fund = fund; | ||||||
|  | 	ntp->tp_size = (arith)-1; | ||||||
|  | 
 | ||||||
|  | 	return ntp; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | struct type * | ||||||
|  | construct_type(fund, tp, count) | ||||||
|  | 	struct type *tp; | ||||||
|  | 	arith count; | ||||||
|  | { | ||||||
|  | 	/*	fund must be a type constructor.
 | ||||||
|  | 		The pointer to the constructed type is returned. | ||||||
|  | 	*/ | ||||||
|  | 	struct type *dtp = create_type(fund); | ||||||
|  | 
 | ||||||
|  | 	switch (fund)	{ | ||||||
|  | 	case PROCEDURE: | ||||||
|  | 	case POINTER: | ||||||
|  | 		dtp->tp_align = ptr_align; | ||||||
|  | 		dtp->tp_size = ptr_size; | ||||||
|  | 		dtp->next = tp; | ||||||
|  | 		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: | ||||||
|  | 		dtp->tp_align = tp->tp_align; | ||||||
|  | 		dtp->tp_size = tp->tp_size; | ||||||
|  | 		dtp->next = tp; | ||||||
|  | 		break; | ||||||
|  | 	default: | ||||||
|  | 		assert(0); | ||||||
|  | 	} | ||||||
|  | 	return dtp; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | arith | ||||||
|  | align(pos, al) | ||||||
|  | 	arith pos; | ||||||
|  | 	int al; | ||||||
|  | { | ||||||
|  | 	return ((pos + al - 1) / al) * al; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | struct type * | ||||||
|  | standard_type(fund, align, size) | ||||||
|  | 	int align; arith size; | ||||||
|  | { | ||||||
|  | 	register struct type *tp = create_type(fund); | ||||||
|  | 
 | ||||||
|  | 	tp->tp_align = align; | ||||||
|  | 	tp->tp_size = size; | ||||||
|  | 
 | ||||||
|  | 	return tp; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | init_types() | ||||||
|  | { | ||||||
|  | 	char_type = standard_type(CHAR, 1, (arith) 1); | ||||||
|  | 	bool_type = standard_type(BOOLEAN, 1, (arith) 1); | ||||||
|  | 	int_type = standard_type(INTEGER, int_align, int_size); | ||||||
|  | 	longint_type = standard_type(LONGINT, lint_align, lint_size); | ||||||
|  | 	card_type = standard_type(CARDINAL, int_align, int_size); | ||||||
|  | 	real_type = standard_type(REAL, real_align, real_size); | ||||||
|  | 	longreal_type = standard_type(LONGREAL, lreal_align, lreal_size); | ||||||
|  | 	error_type = standard_type(ERRONEOUS, 1, (arith) 1); | ||||||
|  | } | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue