newer version
This commit is contained in:
		
							parent
							
								
									f1a0c90fb1
								
							
						
					
					
						commit
						a9dfdc494b
					
				
					 21 changed files with 573 additions and 516 deletions
				
			
		|  | @ -33,7 +33,7 @@ int idfsize = IDFSIZE; | ||||||
| extern int	cntlines; | extern int	cntlines; | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| static | STATIC | ||||||
| SkipComment() | SkipComment() | ||||||
| { | { | ||||||
| 	/*	Skip Modula-2 comments (* ... *).
 | 	/*	Skip Modula-2 comments (* ... *).
 | ||||||
|  | @ -50,16 +50,12 @@ SkipComment() | ||||||
| 			cntlines++; | 			cntlines++; | ||||||
| #endif | #endif | ||||||
| 		} | 		} | ||||||
| 		else | 		else if (ch == '(') { | ||||||
| 		if (ch == '(') { |  | ||||||
| 			LoadChar(ch); | 			LoadChar(ch); | ||||||
| 			if (ch == '*') { | 			if (ch == '*') ++NestLevel; | ||||||
| 				++NestLevel; |  | ||||||
| 			} |  | ||||||
| 			else	continue; | 			else	continue; | ||||||
| 		} | 		} | ||||||
| 		else | 		else if (ch == '*') { | ||||||
| 		if (ch == '*') { |  | ||||||
| 			LoadChar(ch); | 			LoadChar(ch); | ||||||
| 			if (ch == ')') { | 			if (ch == ')') { | ||||||
| 				if (NestLevel-- == 0) return; | 				if (NestLevel-- == 0) return; | ||||||
|  | @ -70,7 +66,7 @@ SkipComment() | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static | STATIC | ||||||
| GetString(upto) | GetString(upto) | ||||||
| { | { | ||||||
| 	/*	Read a Modula-2 string, delimited by the character "upto".
 | 	/*	Read a Modula-2 string, delimited by the character "upto".
 | ||||||
|  | @ -118,11 +114,13 @@ LLlex() | ||||||
| 	register int ch, nch; | 	register int ch, nch; | ||||||
| 
 | 
 | ||||||
| 	toktype = error_type; | 	toktype = error_type; | ||||||
|  | 
 | ||||||
| 	if (ASIDE)	{	/* a token is put aside		*/ | 	if (ASIDE)	{	/* a token is put aside		*/ | ||||||
| 		*tk = aside; | 		*tk = aside; | ||||||
| 		ASIDE = 0; | 		ASIDE = 0; | ||||||
| 		return tk->tk_symb; | 		return tk->tk_symb; | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
| 	tk->tk_lineno = LineNumber; | 	tk->tk_lineno = LineNumber; | ||||||
| 
 | 
 | ||||||
| again: | again: | ||||||
|  | @ -216,8 +214,7 @@ again: | ||||||
| 			LoadChar(ch); | 			LoadChar(ch); | ||||||
| 		} while(in_idf(ch)); | 		} while(in_idf(ch)); | ||||||
| 
 | 
 | ||||||
| 		if (ch != EOI) | 		if (ch != EOI) PushBack(ch); | ||||||
| 			PushBack(ch); |  | ||||||
| 		*tg++ = '\0'; | 		*tg++ = '\0'; | ||||||
| 
 | 
 | ||||||
| 		tk->TOK_IDF = id = str2idf(buf, 1); | 		tk->TOK_IDF = id = str2idf(buf, 1); | ||||||
|  | @ -396,6 +393,7 @@ Sreal: | ||||||
| 				lexerror("floating constant too long"); | 				lexerror("floating constant too long"); | ||||||
| 			} | 			} | ||||||
| 			else	tk->TOK_REL = Salloc(buf, np - buf) + 1; | 			else	tk->TOK_REL = Salloc(buf, np - buf) + 1; | ||||||
|  | 			toktype = real_type; | ||||||
| 			return tk->tk_symb = REAL; | 			return tk->tk_symb = REAL; | ||||||
| 
 | 
 | ||||||
| 		default: | 		default: | ||||||
|  |  | ||||||
|  | @ -9,10 +9,11 @@ INCLUDES = -I$(HDIR) -I/usr/em/h -I$(PKGDIR) -I/user1/erikb/em/h | ||||||
| 
 | 
 | ||||||
| LSRC =	tokenfile.g program.g declar.g expression.g statement.g | LSRC =	tokenfile.g program.g declar.g expression.g statement.g | ||||||
| CC =	cc | CC =	cc | ||||||
| GEN =	LLgen | GEN =	/usr/em/util/LLgen/src/LLgen | ||||||
| GENOPTIONS = | GENOPTIONS = -d | ||||||
| PROFILE =  | PROFILE = -p | ||||||
| CFLAGS = $(PROFILE) $(INCLUDES) | CFLAGS = $(PROFILE) $(INCLUDES) -DSTATIC= | ||||||
|  | LINTFLAGS = -DSTATIC= -DNORCSID | ||||||
| LFLAGS = $(PROFILE) | LFLAGS = $(PROFILE) | ||||||
| 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 \
 | ||||||
|  | @ -46,7 +47,7 @@ clean: | ||||||
| 	rm -f $(OBJ) $(GENFILES) LLfiles  | 	rm -f $(OBJ) $(GENFILES) LLfiles  | ||||||
| 
 | 
 | ||||||
| lint:	LLfiles hfiles | lint:	LLfiles hfiles | ||||||
| 	lint $(INCLUDES) -DNORCSID `sources $(OBJ)` | 	lint $(INCLUDES) $(LINTFLAGS) `sources $(OBJ)` | ||||||
| 
 | 
 | ||||||
| tokenfile.g:	tokenname.c make.tokfile | tokenfile.g:	tokenname.c make.tokfile | ||||||
| 	make.tokfile <tokenname.c >tokenfile.g | 	make.tokfile <tokenname.c >tokenfile.g | ||||||
|  | @ -98,16 +99,17 @@ defmodule.o: LLlex.h debug.h def.h f_info.h idf.h input.h inputtype.h main.h sco | ||||||
| typequiv.o: LLlex.h def.h node.h type.h | typequiv.o: LLlex.h def.h node.h type.h | ||||||
| node.o: LLlex.h debug.h def.h node.h type.h | node.o: LLlex.h debug.h def.h node.h type.h | ||||||
| cstoper.o: LLlex.h Lpars.h debug.h idf.h node.h standards.h target_sizes.h type.h | cstoper.o: LLlex.h Lpars.h debug.h idf.h node.h standards.h target_sizes.h type.h | ||||||
| chk_expr.o: LLlex.h Lpars.h const.h debug.h def.h idf.h node.h scope.h standards.h type.h | chk_expr.o: LLlex.h Lpars.h chk_expr.h const.h debug.h def.h idf.h node.h scope.h standards.h type.h | ||||||
| options.o: idfsize.h main.h ndir.h type.h | options.o: idfsize.h main.h ndir.h type.h | ||||||
| walk.o: LLlex.h Lpars.h debug.h def.h desig.h f_info.h idf.h main.h node.h scope.h type.h | walk.o: LLlex.h Lpars.h chk_expr.h debug.h def.h desig.h f_info.h idf.h main.h node.h scope.h type.h | ||||||
| casestat.o: LLlex.h Lpars.h debug.h density.h desig.h node.h type.h | casestat.o: LLlex.h Lpars.h debug.h density.h desig.h node.h type.h | ||||||
| desig.o: LLlex.h debug.h def.h desig.h node.h scope.h type.h | desig.o: LLlex.h debug.h def.h desig.h node.h scope.h type.h | ||||||
| code.o: LLlex.h Lpars.h debug.h def.h desig.h node.h scope.h standards.h type.h | code.o: LLlex.h Lpars.h debug.h def.h desig.h node.h scope.h standards.h type.h | ||||||
| tmpvar.o: debug.h def.h scope.h type.h | tmpvar.o: debug.h def.h scope.h type.h | ||||||
|  | lookup.o: LLlex.h debug.h def.h idf.h node.h scope.h | ||||||
| tokenfile.o: Lpars.h | tokenfile.o: Lpars.h | ||||||
| program.o: LLlex.h Lpars.h debug.h def.h idf.h main.h node.h scope.h type.h | program.o: LLlex.h Lpars.h debug.h def.h idf.h main.h node.h scope.h type.h | ||||||
| declar.o: LLlex.h Lpars.h debug.h def.h idf.h main.h misc.h node.h scope.h type.h | declar.o: LLlex.h Lpars.h debug.h def.h idf.h main.h misc.h node.h scope.h type.h | ||||||
| expression.o: LLlex.h Lpars.h const.h debug.h def.h idf.h node.h type.h | expression.o: LLlex.h Lpars.h chk_expr.h const.h debug.h def.h idf.h node.h type.h | ||||||
| statement.o: LLlex.h Lpars.h def.h idf.h node.h scope.h type.h | statement.o: LLlex.h Lpars.h def.h idf.h node.h scope.h type.h | ||||||
| Lpars.o: Lpars.h | Lpars.o: Lpars.h | ||||||
|  |  | ||||||
|  | @ -23,32 +23,21 @@ static char *RcsId = "$Header$"; | ||||||
| #include	"scope.h" | #include	"scope.h" | ||||||
| #include	"const.h" | #include	"const.h" | ||||||
| #include	"standards.h" | #include	"standards.h" | ||||||
|  | #include	"chk_expr.h" | ||||||
| 
 | 
 | ||||||
| extern char *symbol2str(); | extern char *symbol2str(); | ||||||
| 
 | 
 | ||||||
| int | STATIC int | ||||||
| chk_expr(expp) | chk_arr(expp) | ||||||
| 	register struct node *expp; | 	struct node *expp; | ||||||
| { | { | ||||||
| 	/*	Check the expression indicated by expp for semantic errors,
 |  | ||||||
| 		identify identifiers used in it, replace constants by |  | ||||||
| 		their value, and try to evaluate the expression. |  | ||||||
| 	*/ |  | ||||||
| 
 |  | ||||||
| 	switch(expp->nd_class) { |  | ||||||
| 	case Arrsel: |  | ||||||
| 	return chk_designator(expp, DESIGNATOR|VARIABLE, D_USED); | 	return chk_designator(expp, DESIGNATOR|VARIABLE, D_USED); | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| 	case Oper: | STATIC int | ||||||
| 		return	chk_oper(expp); | chk_value(expp) | ||||||
| 
 | 	struct node *expp; | ||||||
| 	case Arrow: | { | ||||||
| 		return chk_designator(expp, DESIGNATOR|VARIABLE, D_USED); |  | ||||||
| 
 |  | ||||||
| 	case Uoper: |  | ||||||
| 		return	chk_uoper(expp); |  | ||||||
| 
 |  | ||||||
| 	case Value: |  | ||||||
| 	switch(expp->nd_symb) { | 	switch(expp->nd_symb) { | ||||||
| 	case REAL: | 	case REAL: | ||||||
| 	case STRING: | 	case STRING: | ||||||
|  | @ -56,48 +45,128 @@ chk_expr(expp) | ||||||
| 		return 1; | 		return 1; | ||||||
| 
 | 
 | ||||||
| 	default: | 	default: | ||||||
| 			crash("(chk_expr(Value))"); | 		crash("(chk_value)"); | ||||||
| 	} | 	} | ||||||
| 		break; | 	/*NOTREACHED*/ | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| 	case Xset: | STATIC int | ||||||
| 		return chk_set(expp); | chk_linkorname(expp) | ||||||
| 
 | 	register struct node *expp; | ||||||
| 	case Link: | { | ||||||
| 	case Name: |  | ||||||
| 	if (chk_designator(expp, VALUE|DESIGNATOR, D_USED)) { | 	if (chk_designator(expp, VALUE|DESIGNATOR, D_USED)) { | ||||||
| 		if (expp->nd_class == Def && | 		if (expp->nd_class == Def && | ||||||
| 		    expp->nd_def->df_kind == D_PROCEDURE) { | 		    expp->nd_def->df_kind == D_PROCEDURE) { | ||||||
| 			/* Check that this procedure is one that we
 | 			/* Check that this procedure is one that we
 | ||||||
| 			   may take the address from. | 			   may take the address from. | ||||||
| 			*/ | 			*/ | ||||||
| 				if (expp->nd_def->df_type == std_type) { | 			if (expp->nd_def->df_type == std_type || | ||||||
| 					/* Standard procedure. Illegal */ | 			    expp->nd_def->df_scope->sc_level > 0) { | ||||||
| node_error(expp, "address of standard procedure taken"); | 				/* Address of standard or nested procedure
 | ||||||
| 					return 0; | 				   taken. | ||||||
| 				} |  | ||||||
| 				if (expp->nd_def->df_scope->sc_level > 0) { |  | ||||||
| 					/* Address of nested procedure taken.
 |  | ||||||
| 					   Illegal. |  | ||||||
| 				*/ | 				*/ | ||||||
| node_error(expp, "address of a procedure local to another one taken"); | node_error(expp, "it is illegal to take the address of a standard or local procedure"); | ||||||
| 				return 0; | 				return 0; | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		return 1; | 		return 1; | ||||||
| 	} | 	} | ||||||
| 	return 0; | 	return 0; | ||||||
| 
 |  | ||||||
| 	case Call: |  | ||||||
| 		return chk_call(expp); |  | ||||||
| 
 |  | ||||||
| 	default: |  | ||||||
| 		crash("(chk_expr)"); |  | ||||||
| 	} |  | ||||||
| 	/*NOTREACHED*/ |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int | STATIC int | ||||||
|  | RemoveSet(set) | ||||||
|  | 	arith **set; | ||||||
|  | { | ||||||
|  | 	/*	This routine is only used for error exits of chk_el.
 | ||||||
|  | 		It frees the set indicated by "set", and returns 0. | ||||||
|  | 	*/ | ||||||
|  | 	if (*set) { | ||||||
|  | 		free((char *) *set); | ||||||
|  | 		*set = 0; | ||||||
|  | 	} | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | STATIC int | ||||||
|  | chk_el(expp, tp, set) | ||||||
|  | 	register struct node *expp; | ||||||
|  | 	register struct type *tp; | ||||||
|  | 	arith **set; | ||||||
|  | { | ||||||
|  | 	/*	Check elements of a set. This routine may call itself
 | ||||||
|  | 		recursively. | ||||||
|  | 		Also try to compute the set! | ||||||
|  | 	*/ | ||||||
|  | 	register struct node *left = expp->nd_left; | ||||||
|  | 	register struct node *right = expp->nd_right; | ||||||
|  | 	register int i; | ||||||
|  | 
 | ||||||
|  | 	if (expp->nd_class == Link && expp->nd_symb == UPTO) { | ||||||
|  | 		/* { ... , expr1 .. expr2,  ... }
 | ||||||
|  | 		   First check expr1 and expr2, and try to compute them. | ||||||
|  | 		*/ | ||||||
|  | 		if (!chk_el(left, tp, set) || !chk_el(right, tp, set)) { | ||||||
|  | 			return 0; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if (left->nd_class == Value && right->nd_class == Value) { | ||||||
|  | 			/* We have a constant range. Put all elements in the
 | ||||||
|  | 			   set | ||||||
|  | 			*/ | ||||||
|  | 
 | ||||||
|  | 		    	if (left->nd_INT > right->nd_INT) { | ||||||
|  | node_error(expp, "lower bound exceeds upper bound in range"); | ||||||
|  | 				return RemoveSet(set); | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			if (*set) { | ||||||
|  | 				for (i=left->nd_INT+1; i<right->nd_INT; i++) { | ||||||
|  | 					(*set)[i/wrd_bits] |= (1<<(i%wrd_bits)); | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		else if (*set) { | ||||||
|  | 			free((char *) *set); | ||||||
|  | 			*set = 0; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		return 1; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/* Here, a single element is checked
 | ||||||
|  | 	*/ | ||||||
|  | 	if (!chk_expr(expp)) { | ||||||
|  | 		return RemoveSet(set); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (!TstCompat(tp, expp->nd_type)) { | ||||||
|  | 		node_error(expp, "set element has incompatible type"); | ||||||
|  | 		return RemoveSet(set); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (expp->nd_class == Value) { | ||||||
|  | 		/* a constant element
 | ||||||
|  | 		*/ | ||||||
|  | 		i = expp->nd_INT; | ||||||
|  | 
 | ||||||
|  | 	    	if ((tp->tp_fund != T_ENUMERATION && | ||||||
|  | 		     (i < tp->sub_lb || i > tp->sub_ub)) | ||||||
|  | 		   || | ||||||
|  | 		    (tp->tp_fund == T_ENUMERATION && | ||||||
|  | 		     (i < 0 || i > tp->enm_ncst)) | ||||||
|  | 		   ) { | ||||||
|  | 			node_error(expp, "set element out of range"); | ||||||
|  | 			return RemoveSet(set); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if (*set) (*set)[i/wrd_bits] |= (1 << (i%wrd_bits)); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return 1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | STATIC int | ||||||
| chk_set(expp) | chk_set(expp) | ||||||
| 	register struct node *expp; | 	register struct node *expp; | ||||||
| { | { | ||||||
|  | @ -174,126 +243,49 @@ node_error(expp, "specifier does not represent a set type"); | ||||||
| 	return 1; | 	return 1; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int | STATIC struct node * | ||||||
| chk_el(expp, tp, set) |  | ||||||
| 	register struct node *expp; |  | ||||||
| 	register struct type *tp; |  | ||||||
| 	arith **set; |  | ||||||
| { |  | ||||||
| 	/*	Check elements of a set. This routine may call itself
 |  | ||||||
| 		recursively. |  | ||||||
| 		Also try to compute the set! |  | ||||||
| 	*/ |  | ||||||
| 	register struct node *left = expp->nd_left; |  | ||||||
| 	register struct node *right = expp->nd_right; |  | ||||||
| 	register int i; |  | ||||||
| 
 |  | ||||||
| 	if (expp->nd_class == Link && expp->nd_symb == UPTO) { |  | ||||||
| 		/* { ... , expr1 .. expr2,  ... }
 |  | ||||||
| 		   First check expr1 and expr2, and try to compute them. |  | ||||||
| 		*/ |  | ||||||
| 		if (!chk_el(left, tp, set) || !chk_el(right, tp, set)) { |  | ||||||
| 			return 0; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		if (left->nd_class == Value && right->nd_class == Value) { |  | ||||||
| 			/* We have a constant range. Put all elements in the
 |  | ||||||
| 			   set |  | ||||||
| 			*/ |  | ||||||
| 
 |  | ||||||
| 		    	if (left->nd_INT > right->nd_INT) { |  | ||||||
| node_error(expp, "lower bound exceeds upper bound in range"); |  | ||||||
| 				return rem_set(set); |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			if (*set) { |  | ||||||
| 				for (i=left->nd_INT+1; i<right->nd_INT; i++) { |  | ||||||
| 					(*set)[i/wrd_bits] |= (1<<(i%wrd_bits)); |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		else if (*set) { |  | ||||||
| 			free((char *) *set); |  | ||||||
| 			*set = 0; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		return 1; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	/* Here, a single element is checked
 |  | ||||||
| 	*/ |  | ||||||
| 	if (!chk_expr(expp)) { |  | ||||||
| 		return rem_set(set); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if (!TstCompat(tp, expp->nd_type)) { |  | ||||||
| 		node_error(expp, "set element has incompatible type"); |  | ||||||
| 		return rem_set(set); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if (expp->nd_class == Value) { |  | ||||||
| 		/* a constant element
 |  | ||||||
| 		*/ |  | ||||||
| 		i = expp->nd_INT; |  | ||||||
| 
 |  | ||||||
| 	    	if ((tp->tp_fund != T_ENUMERATION && |  | ||||||
| 		     (i < tp->sub_lb || i > tp->sub_ub)) |  | ||||||
| 		   || |  | ||||||
| 		    (tp->tp_fund == T_ENUMERATION && |  | ||||||
| 		     (i < 0 || i > tp->enm_ncst)) |  | ||||||
| 		   ) { |  | ||||||
| 			node_error(expp, "set element out of range"); |  | ||||||
| 			return rem_set(set); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		if (*set) (*set)[i/wrd_bits] |= (1 << (i%wrd_bits)); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return 1; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| int |  | ||||||
| rem_set(set) |  | ||||||
| 	arith **set; |  | ||||||
| { |  | ||||||
| 	/*	This routine is only used for error exits of chk_el.
 |  | ||||||
| 		It frees the set indicated by "set", and returns 0. |  | ||||||
| 	*/ |  | ||||||
| 	if (*set) { |  | ||||||
| 		free((char *) *set); |  | ||||||
| 		*set = 0; |  | ||||||
| 	} |  | ||||||
| 	return 0; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| struct node * |  | ||||||
| getarg(argp, bases, designator) | getarg(argp, bases, designator) | ||||||
| 	struct node **argp; | 	struct node **argp; | ||||||
| { | { | ||||||
|  | 	/*	This routine is used to fetch the next argument from an
 | ||||||
|  | 		argument list. The argument list is indicated by "argp". | ||||||
|  | 		The parameter "bases" is a bitset indicating which types | ||||||
|  | 		are allowed at this point, and "designator" is a flag | ||||||
|  | 		indicating that the address from this argument is taken, so | ||||||
|  | 		that it must be a designator and may not be a register | ||||||
|  | 		variable. | ||||||
|  | 	*/ | ||||||
| 	struct type *tp; | 	struct type *tp; | ||||||
| 	register struct node *arg = *argp; | 	register struct node *arg = *argp; | ||||||
|  | 	register struct node *left; | ||||||
| 
 | 
 | ||||||
| 	if (!arg->nd_right) { | 	if (! arg->nd_right) { | ||||||
| 		node_error(arg, "too few arguments supplied"); | 		node_error(arg, "too few arguments supplied"); | ||||||
| 		return 0; | 		return 0; | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
| 	arg = arg->nd_right; | 	arg = arg->nd_right; | ||||||
| 	if ((!designator && !chk_expr(arg->nd_left)) || | 	left = arg->nd_left; | ||||||
| 	    (designator && !chk_designator(arg->nd_left, DESIGNATOR, D_REFERRED))) { | 
 | ||||||
|  | 	if ((!designator && !chk_expr(left)) || | ||||||
|  | 	    (designator && | ||||||
|  | 	     !chk_designator(left, DESIGNATOR|VARIABLE, D_USED|D_NOREG))) { | ||||||
| 		return 0; | 		return 0; | ||||||
| 	} | 	} | ||||||
| 	tp = arg->nd_left->nd_type; | 
 | ||||||
|  | 	tp = left->nd_type; | ||||||
| 	if (tp->tp_fund == T_SUBRANGE) tp = tp->next; | 	if (tp->tp_fund == T_SUBRANGE) tp = tp->next; | ||||||
|  | 
 | ||||||
| 	if (bases && !(tp->tp_fund & bases)) { | 	if (bases && !(tp->tp_fund & bases)) { | ||||||
| 		node_error(arg, "unexpected type"); | 		node_error(arg, "unexpected type"); | ||||||
| 		return 0; | 		return 0; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	*argp = arg; | 	*argp = arg; | ||||||
| 	return arg->nd_left; | 	return left; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| struct node * | STATIC struct node * | ||||||
| getname(argp, kinds) | getname(argp, kinds) | ||||||
| 	struct node **argp; | 	struct node **argp; | ||||||
| { | { | ||||||
|  | @ -303,10 +295,11 @@ getname(argp, kinds) | ||||||
| 		node_error(arg, "too few arguments supplied"); | 		node_error(arg, "too few arguments supplied"); | ||||||
| 		return 0; | 		return 0; | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
| 	arg = arg->nd_right; | 	arg = arg->nd_right; | ||||||
| 	if (! chk_designator(arg->nd_left, 0, D_REFERRED)) return 0; | 	if (! chk_designator(arg->nd_left, 0, D_REFERRED)) return 0; | ||||||
| 
 | 
 | ||||||
| 	assert(arg->nd_left->nd_class == Def); | 	if (arg->nd_left->nd_class != Def); | ||||||
| 
 | 
 | ||||||
| 	if (!(arg->nd_left->nd_def->df_kind & kinds)) { | 	if (!(arg->nd_left->nd_def->df_kind & kinds)) { | ||||||
| 		node_error(arg, "unexpected type"); | 		node_error(arg, "unexpected type"); | ||||||
|  | @ -317,6 +310,42 @@ getname(argp, kinds) | ||||||
| 	return arg->nd_left; | 	return arg->nd_left; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | STATIC int | ||||||
|  | chk_proccall(expp) | ||||||
|  | 	register struct node *expp; | ||||||
|  | { | ||||||
|  | 	/*	Check a procedure call
 | ||||||
|  | 	*/ | ||||||
|  | 	register struct node *left; | ||||||
|  | 	struct node *arg; | ||||||
|  | 	register struct paramlist *param; | ||||||
|  | 
 | ||||||
|  | 	left = expp->nd_left; | ||||||
|  | 	arg = expp; | ||||||
|  | 	expp->nd_type = left->nd_type->next; | ||||||
|  | 
 | ||||||
|  | 	for (param = left->nd_type->prc_params; param; param = param->next) { | ||||||
|  | 		if (!(left = getarg(&arg, 0, IsVarParam(param)))) return 0; | ||||||
|  | 		if (left->nd_symb == STRING) { | ||||||
|  | 			TryToString(left, TypeOfParam(param)); | ||||||
|  | 		} | ||||||
|  | 		if (! TstParCompat(TypeOfParam(param), | ||||||
|  | 				   left->nd_type, | ||||||
|  | 				   IsVarParam(param), | ||||||
|  | 				   left)) { | ||||||
|  | node_error(left, "type incompatibility in parameter"); | ||||||
|  | 			return 0; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (arg->nd_right) { | ||||||
|  | 		node_error(arg->nd_right, "too many parameters supplied"); | ||||||
|  | 		return 0; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return 1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| int | int | ||||||
| chk_call(expp) | chk_call(expp) | ||||||
| 	register struct node *expp; | 	register struct node *expp; | ||||||
|  | @ -358,58 +387,7 @@ chk_call(expp) | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| chk_proccall(expp) | STATIC int | ||||||
| 	register struct node *expp; |  | ||||||
| { |  | ||||||
| 	/*	Check a procedure call
 |  | ||||||
| 	*/ |  | ||||||
| 	register struct node *left; |  | ||||||
| 	struct node *arg; |  | ||||||
| 	register struct paramlist *param; |  | ||||||
| 
 |  | ||||||
| 	left = 0; |  | ||||||
| 	arg = expp->nd_right; |  | ||||||
| 	/* First, reverse the order in the argument list */ |  | ||||||
| 	while (arg) { |  | ||||||
| 		expp->nd_right = arg; |  | ||||||
| 		arg = arg->nd_right; |  | ||||||
| 		expp->nd_right->nd_right = left; |  | ||||||
| 		left = expp->nd_right; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	left = expp->nd_left; |  | ||||||
| 	arg = expp; |  | ||||||
| 	expp->nd_type = left->nd_type->next; |  | ||||||
| 	param = left->nd_type->prc_params; |  | ||||||
| 
 |  | ||||||
| 	while (param) { |  | ||||||
| 		if (!(left = getarg(&arg, 0, IsVarParam(param)))) return 0; |  | ||||||
| 		if (left->nd_symb == STRING) { |  | ||||||
| 			TryToString(left, TypeOfParam(param)); |  | ||||||
| 		} |  | ||||||
| 		if (! TstParCompat(TypeOfParam(param), |  | ||||||
| 				   left->nd_type, |  | ||||||
| 				   IsVarParam(param), |  | ||||||
| 				   left)) { |  | ||||||
| node_error(left, "type incompatibility in parameter"); |  | ||||||
| 			return 0; |  | ||||||
| 		} |  | ||||||
| 		if (IsVarParam(param) && left->nd_class == Def) { |  | ||||||
| 			left->nd_def->df_flags |= D_NOREG; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		param = param->next; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if (arg->nd_right) { |  | ||||||
| 		node_error(arg->nd_right, "too many parameters supplied"); |  | ||||||
| 		return 0; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return 1; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static int |  | ||||||
| FlagCheck(expp, df, flag) | FlagCheck(expp, df, flag) | ||||||
| 	struct node *expp; | 	struct node *expp; | ||||||
| 	struct def *df; | 	struct def *df; | ||||||
|  | @ -461,7 +439,6 @@ chk_designator(expp, flag, dflags) | ||||||
| 	*/ | 	*/ | ||||||
| 	register struct def *df; | 	register struct def *df; | ||||||
| 	register struct type *tp; | 	register struct type *tp; | ||||||
| 	struct def *lookfor(); |  | ||||||
| 
 | 
 | ||||||
| 	expp->nd_type = error_type; | 	expp->nd_type = error_type; | ||||||
| 
 | 
 | ||||||
|  | @ -469,23 +446,20 @@ chk_designator(expp, flag, dflags) | ||||||
| 		expp->nd_def = lookfor(expp, CurrVis, 1); | 		expp->nd_def = lookfor(expp, CurrVis, 1); | ||||||
| 		expp->nd_class = Def; | 		expp->nd_class = Def; | ||||||
| 		expp->nd_type = expp->nd_def->df_type; | 		expp->nd_type = expp->nd_def->df_type; | ||||||
| 		if (expp->nd_type == error_type) return 0; |  | ||||||
| 	} | 	} | ||||||
|  | 	else if (expp->nd_class == Link) { | ||||||
|  | 		register struct node *left = expp->nd_left; | ||||||
| 
 | 
 | ||||||
| 	if (expp->nd_class == Link) { |  | ||||||
| 		assert(expp->nd_symb == '.'); | 		assert(expp->nd_symb == '.'); | ||||||
| 
 | 
 | ||||||
| 		if (! chk_designator(expp->nd_left, | 		if (! chk_designator(left, | ||||||
| 				     flag|HASSELECTORS, | 				     (flag&DESIGNATOR)|HASSELECTORS, | ||||||
| 				     dflags|D_NOREG)) return 0; | 				     dflags)) return 0; | ||||||
| 
 |  | ||||||
| 		tp = expp->nd_left->nd_type; |  | ||||||
| 
 | 
 | ||||||
|  | 		tp = left->nd_type; | ||||||
| 		assert(tp->tp_fund == T_RECORD); | 		assert(tp->tp_fund == T_RECORD); | ||||||
| 
 | 
 | ||||||
| 		df = lookup(expp->nd_IDF, tp->rec_scope); | 		if (!(df = lookup(expp->nd_IDF, tp->rec_scope))) { | ||||||
| 
 |  | ||||||
| 		if (!df) { |  | ||||||
| 			id_not_declared(expp); | 			id_not_declared(expp); | ||||||
| 			return 0; | 			return 0; | ||||||
| 		} | 		} | ||||||
|  | @ -493,17 +467,19 @@ chk_designator(expp, flag, dflags) | ||||||
| 			expp->nd_def = df; | 			expp->nd_def = df; | ||||||
| 			expp->nd_type = df->df_type; | 			expp->nd_type = df->df_type; | ||||||
| 			if (!(df->df_flags & (D_EXPORTED|D_QEXPORTED))) { | 			if (!(df->df_flags & (D_EXPORTED|D_QEXPORTED))) { | ||||||
|  | 				/* Fields of a record are always D_QEXPORTED,
 | ||||||
|  | 				   so ... | ||||||
|  | 				*/ | ||||||
| node_error(expp, "identifier \"%s\" not exported from qualifying module", | node_error(expp, "identifier \"%s\" not exported from qualifying module", | ||||||
| df->df_idf->id_text); | df->df_idf->id_text); | ||||||
| 				return 0; | 				return 0; | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (expp->nd_left->nd_class == Def && | 		if (left->nd_class == Def && | ||||||
| 		    expp->nd_left->nd_def->df_kind == D_MODULE) { | 		    left->nd_def->df_kind == D_MODULE) { | ||||||
| 			expp->nd_class = Def; | 			expp->nd_class = Def; | ||||||
| 			expp->nd_def = df; | 			FreeNode(left); | ||||||
| 			FreeNode(expp->nd_left); |  | ||||||
| 			expp->nd_left = 0; | 			expp->nd_left = 0; | ||||||
| 		} | 		} | ||||||
| 		else { | 		else { | ||||||
|  | @ -548,7 +524,7 @@ df->df_idf->id_text); | ||||||
| 		assert(expp->nd_symb == '['); | 		assert(expp->nd_symb == '['); | ||||||
| 
 | 
 | ||||||
| 		if (  | 		if (  | ||||||
| 		    	!chk_designator(expp->nd_left, DESIGNATOR|VARIABLE, dflags|D_NOREG) | 		     !chk_designator(expp->nd_left, DESIGNATOR|VARIABLE, dflags) | ||||||
| 		   || | 		   || | ||||||
| 		     !chk_expr(expp->nd_right) | 		     !chk_expr(expp->nd_right) | ||||||
| 		   || | 		   || | ||||||
|  | @ -598,7 +574,7 @@ symbol2str(expp->nd_symb)); | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| struct type * | STATIC struct type * | ||||||
| ResultOfOperation(operator, tp) | ResultOfOperation(operator, tp) | ||||||
| 	struct type *tp; | 	struct type *tp; | ||||||
| { | { | ||||||
|  | @ -616,13 +592,13 @@ ResultOfOperation(operator, tp) | ||||||
| 	return tp; | 	return tp; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int | STATIC int | ||||||
| Boolean(operator) | Boolean(operator) | ||||||
| { | { | ||||||
| 	return operator == OR || operator == AND || operator == '&'; | 	return operator == OR || operator == AND || operator == '&'; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int | STATIC int | ||||||
| AllowedTypes(operator) | AllowedTypes(operator) | ||||||
| { | { | ||||||
| 	switch(operator) { | 	switch(operator) { | ||||||
|  | @ -654,7 +630,23 @@ AllowedTypes(operator) | ||||||
| 	/*NOTREACHED*/ | 	/*NOTREACHED*/ | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int | STATIC int | ||||||
|  | chk_address(tpl, tpr) | ||||||
|  | 	register struct type *tpl, *tpr; | ||||||
|  | { | ||||||
|  | 	 | ||||||
|  | 	if (tpl == address_type) { | ||||||
|  | 		return tpr == address_type || tpr->tp_fund != T_POINTER; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (tpr == address_type) { | ||||||
|  | 		return tpl->tp_fund != T_POINTER; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | STATIC int | ||||||
| chk_oper(expp) | chk_oper(expp) | ||||||
| 	register struct node *expp; | 	register struct node *expp; | ||||||
| { | { | ||||||
|  | @ -741,23 +733,7 @@ node_error(expp,"operator \"%s\": illegal operand type(s)", symbol2str(expp->nd_ | ||||||
| 	return 1; | 	return 1; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int | STATIC int | ||||||
| chk_address(tpl, tpr) |  | ||||||
| 	register struct type *tpl, *tpr; |  | ||||||
| { |  | ||||||
| 	 |  | ||||||
| 	if (tpl == address_type) { |  | ||||||
| 		return tpr == address_type || tpr->tp_fund != T_POINTER; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if (tpr == address_type) { |  | ||||||
| 		return tpl->tp_fund != T_POINTER; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return 0; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| int |  | ||||||
| chk_uoper(expp) | chk_uoper(expp) | ||||||
| 	register struct node *expp; | 	register struct node *expp; | ||||||
| { | { | ||||||
|  | @ -826,7 +802,7 @@ chk_uoper(expp) | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| struct node * | STATIC struct node * | ||||||
| getvariable(argp) | getvariable(argp) | ||||||
| 	struct node **argp; | 	struct node **argp; | ||||||
| { | { | ||||||
|  | @ -916,7 +892,11 @@ DO_DEBUG(3,debug("standard name \"%s\", %d",left->nd_def->df_idf->id_text,std)); | ||||||
| 
 | 
 | ||||||
| 	case S_MAX: | 	case S_MAX: | ||||||
| 	case S_MIN: | 	case S_MIN: | ||||||
| 		if (!(left = getarg(&arg, T_DISCRETE, 0))) return 0; | 		if (!(left = getname(&arg, D_ISTYPE))) return 0; | ||||||
|  | 		if (!(left->nd_type->tp_fund & (T_DISCRETE))) { | ||||||
|  | 			node_error(left, "illegal type in MIN or MAX"); | ||||||
|  | 			return 0; | ||||||
|  | 		} | ||||||
| 		expp->nd_type = left->nd_type; | 		expp->nd_type = left->nd_type; | ||||||
| 		cstcall(expp,std); | 		cstcall(expp,std); | ||||||
| 		break; | 		break; | ||||||
|  | @ -1072,7 +1052,8 @@ TryToString(nd, tp) | ||||||
| 	struct node *nd; | 	struct node *nd; | ||||||
| 	struct type *tp; | 	struct type *tp; | ||||||
| { | { | ||||||
| 	/*	Try a coercion from character constant to string */ | 	/*	Try a coercion from character constant to string.
 | ||||||
|  | 	*/ | ||||||
| 	if (tp->tp_fund == T_ARRAY && nd->nd_type == char_type) { | 	if (tp->tp_fund == T_ARRAY && nd->nd_type == char_type) { | ||||||
| 		int ch = nd->nd_INT; | 		int ch = nd->nd_INT; | ||||||
| 
 | 
 | ||||||
|  | @ -1084,3 +1065,20 @@ TryToString(nd, tp) | ||||||
| 		nd->nd_SLE = 1; | 		nd->nd_SLE = 1; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | extern int	NodeCrash(); | ||||||
|  | 
 | ||||||
|  | int (*ChkTable[])() = { | ||||||
|  | 	chk_value, | ||||||
|  | 	chk_arr, | ||||||
|  | 	chk_oper, | ||||||
|  | 	chk_uoper, | ||||||
|  | 	chk_arr, | ||||||
|  | 	chk_call, | ||||||
|  | 	chk_linkorname, | ||||||
|  | 	NodeCrash, | ||||||
|  | 	chk_set, | ||||||
|  | 	NodeCrash, | ||||||
|  | 	NodeCrash, | ||||||
|  | 	chk_linkorname | ||||||
|  | }; | ||||||
|  |  | ||||||
							
								
								
									
										9
									
								
								lang/m2/comp/chk_expr.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								lang/m2/comp/chk_expr.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,9 @@ | ||||||
|  | /* E X P R E S S I O N   C H E C K I N G */ | ||||||
|  | 
 | ||||||
|  | /* $Header$ */ | ||||||
|  | 
 | ||||||
|  | extern int	(*ChkTable[])();	/* table of expression checking
 | ||||||
|  | 					   functions, indexed by node class | ||||||
|  | 					*/ | ||||||
|  | 
 | ||||||
|  | #define	chk_expr(expp)	((*ChkTable[(expp)->nd_class])(expp)) | ||||||
|  | @ -129,7 +129,6 @@ CodeExpr(nd, ds, true_label, false_label) | ||||||
| 		break; | 		break; | ||||||
| 
 | 
 | ||||||
| 	case Uoper: | 	case Uoper: | ||||||
| 		CodePExpr(nd->nd_right); |  | ||||||
| 		CodeUoper(nd); | 		CodeUoper(nd); | ||||||
| 		ds->dsg_kind = DSG_LOADED; | 		ds->dsg_kind = DSG_LOADED; | ||||||
| 		break; | 		break; | ||||||
|  | @ -194,9 +193,9 @@ CodeCoercion(t1, t2) | ||||||
| { | { | ||||||
| 	register int fund1, fund2; | 	register int fund1, fund2; | ||||||
| 
 | 
 | ||||||
| 	if (t1 == t2) return; |  | ||||||
| 	if (t1->tp_fund == T_SUBRANGE) t1 = t1->next; | 	if (t1->tp_fund == T_SUBRANGE) t1 = t1->next; | ||||||
| 	if (t2->tp_fund == T_SUBRANGE) t2 = t2->next; | 	if (t2->tp_fund == T_SUBRANGE) t2 = t2->next; | ||||||
|  | 	if (t1 == t2) return; | ||||||
| 	if ((fund1 = t1->tp_fund) == T_WORD) fund1 = T_INTEGER; | 	if ((fund1 = t1->tp_fund) == T_WORD) fund1 = T_INTEGER; | ||||||
| 	if ((fund2 = t2->tp_fund) == T_WORD) fund2 = T_INTEGER; | 	if ((fund2 = t2->tp_fund) == T_WORD) fund2 = T_INTEGER; | ||||||
| 	switch(fund1) { | 	switch(fund1) { | ||||||
|  | @ -291,9 +290,6 @@ CodeCall(nd) | ||||||
| 		and result is already done. | 		and result is already done. | ||||||
| 	*/ | 	*/ | ||||||
| 	register struct node *left = nd->nd_left; | 	register struct node *left = nd->nd_left; | ||||||
| 	register struct node *arg = nd; |  | ||||||
| 	register struct paramlist *param; |  | ||||||
| 	struct type *tp; |  | ||||||
| 
 | 
 | ||||||
| 	if (left->nd_type == std_type) { | 	if (left->nd_type == std_type) { | ||||||
| 		CodeStd(nd); | 		CodeStd(nd); | ||||||
|  | @ -311,15 +307,54 @@ CodeCall(nd) | ||||||
| 
 | 
 | ||||||
| 	assert(IsProcCall(left)); | 	assert(IsProcCall(left)); | ||||||
| 
 | 
 | ||||||
| 	for (param = left->nd_type->prc_params; param; param = param->next) { | 	if (nd->nd_right) { | ||||||
|  | 		CodeParameters(left->nd_type->prc_params, nd->nd_right); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (left->nd_class == Def && left->nd_def->df_kind == D_PROCEDURE) { | ||||||
|  | 		if (left->nd_def->df_scope->sc_level > 0) { | ||||||
|  | 			C_lxl((arith) proclevel - left->nd_def->df_scope->sc_level); | ||||||
|  | 		} | ||||||
|  | 		C_cal(NameOfProc(left->nd_def)); | ||||||
|  | 	} | ||||||
|  | 	else if (left->nd_class == Def && left->nd_def->df_kind == D_PROCHEAD) { | ||||||
|  | 		C_cal(left->nd_def->for_name); | ||||||
|  | 	} | ||||||
|  | 	else { | ||||||
|  | 		CodePExpr(left); | ||||||
|  | 		C_cai(); | ||||||
|  | 	} | ||||||
|  | 	if (left->nd_type->prc_nbpar) C_asp(left->nd_type->prc_nbpar); | ||||||
|  | 	if (left->nd_type->next) { | ||||||
|  | 		C_lfr(WA(left->nd_type->next->tp_size)); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | CodeParameters(param, arg) | ||||||
|  | 	struct paramlist *param; | ||||||
|  | 	struct node *arg; | ||||||
|  | { | ||||||
|  | 	register struct type *tp; | ||||||
|  | 	register struct node *left; | ||||||
|  | 	 | ||||||
|  | 	assert(param != 0 && arg != 0); | ||||||
|  | 
 | ||||||
|  | 	if (param->next) { | ||||||
|  | 		CodeParameters(param->next, arg->nd_right); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	tp = TypeOfParam(param); | 	tp = TypeOfParam(param); | ||||||
| 		arg = arg->nd_right; |  | ||||||
| 		assert(arg != 0); |  | ||||||
| 	left = arg->nd_left; | 	left = arg->nd_left; | ||||||
| 	if (IsConformantArray(tp)) { | 	if (IsConformantArray(tp)) { | ||||||
| 		C_loc(tp->arr_elsize); | 		C_loc(tp->arr_elsize); | ||||||
| 		if (IsConformantArray(left->nd_type)) { | 		if (IsConformantArray(left->nd_type)) { | ||||||
| 			DoHIGH(left); | 			DoHIGH(left); | ||||||
|  | 			if (tp->arr_elem->tp_size != left->nd_type->arr_elem->tp_size) { | ||||||
|  | 				/* This can only happen if the formal type is
 | ||||||
|  | 				   ARRAY OF WORD | ||||||
|  | 				*/ | ||||||
|  | 				/* ??? */ | ||||||
|  | 			} | ||||||
| 		} | 		} | ||||||
| 		else if (left->nd_symb == STRING) { | 		else if (left->nd_symb == STRING) { | ||||||
| 			C_loc(left->nd_SLE); | 			C_loc(left->nd_SLE); | ||||||
|  | @ -350,27 +385,6 @@ CodeCall(nd) | ||||||
| 		else CodePExpr(left); | 		else CodePExpr(left); | ||||||
| 		CheckAssign(left->nd_type, tp); | 		CheckAssign(left->nd_type, tp); | ||||||
| 	} | 	} | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	left = nd->nd_left; |  | ||||||
| 
 |  | ||||||
| 	if (left->nd_class == Def && left->nd_def->df_kind == D_PROCEDURE) { |  | ||||||
| 		if (left->nd_def->df_scope->sc_level > 0) { |  | ||||||
| 			C_lxl((arith) proclevel - left->nd_def->df_scope->sc_level); |  | ||||||
| 		} |  | ||||||
| 		C_cal(NameOfProc(left->nd_def)); |  | ||||||
| 	} |  | ||||||
| 	else if (left->nd_class == Def && left->nd_def->df_kind == D_PROCHEAD) { |  | ||||||
| 		C_cal(left->nd_def->for_name); |  | ||||||
| 	} |  | ||||||
| 	else { |  | ||||||
| 		CodePExpr(left); |  | ||||||
| 		C_cai(); |  | ||||||
| 	} |  | ||||||
| 	if (left->nd_type->prc_nbpar) C_asp(left->nd_type->prc_nbpar); |  | ||||||
| 	if (left->nd_type->next) { |  | ||||||
| 		C_lfr(WA(left->nd_type->next->tp_size)); |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| CodeStd(nd) | CodeStd(nd) | ||||||
|  | @ -387,7 +401,6 @@ CodeStd(nd) | ||||||
| 		if (tp->tp_fund == T_SUBRANGE) tp = tp->next; | 		if (tp->tp_fund == T_SUBRANGE) tp = tp->next; | ||||||
| 		arg = arg->nd_right; | 		arg = arg->nd_right; | ||||||
| 	} | 	} | ||||||
| 	Desig = InitDesig; |  | ||||||
| 
 | 
 | ||||||
| 	switch(std = nd->nd_left->nd_def->df_value.df_stdname) { | 	switch(std = nd->nd_left->nd_def->df_value.df_stdname) { | ||||||
| 	case S_ABS: | 	case S_ABS: | ||||||
|  | @ -546,14 +559,12 @@ CheckAssign(tpl, tpr) | ||||||
| 	*/ | 	*/ | ||||||
| 
 | 
 | ||||||
| 	arith llo, lhi, rlo, rhi; | 	arith llo, lhi, rlo, rhi; | ||||||
| 	label l = 0; |  | ||||||
| 	extern label getrck(); |  | ||||||
| 
 | 
 | ||||||
| 	if (bounded(tpl)) { | 	if (bounded(tpl)) { | ||||||
| 		/* in this case we might need a range check */ | 		/* in this case we might need a range check */ | ||||||
| 		if (!bounded(tpr)) { | 		if (!bounded(tpr)) { | ||||||
| 			/* yes, we need one */ | 			/* yes, we need one */ | ||||||
| 			l = getrck(tpl); | 			genrck(tpl); | ||||||
| 		} | 		} | ||||||
| 		else { | 		else { | ||||||
| 			/* both types are restricted. check the bounds
 | 			/* both types are restricted. check the bounds
 | ||||||
|  | @ -562,14 +573,9 @@ CheckAssign(tpl, tpr) | ||||||
| 			getbounds(tpl, &llo, &lhi); | 			getbounds(tpl, &llo, &lhi); | ||||||
| 			getbounds(tpr, &rlo, &rhi); | 			getbounds(tpr, &rlo, &rhi); | ||||||
| 			if (llo > rlo || lhi < rhi) { | 			if (llo > rlo || lhi < rhi) { | ||||||
| 				l = getrck(tpl); | 				genrck(tpl); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 |  | ||||||
| 		if (l) { |  | ||||||
| 			C_lae_dlb(l, (arith) 0); |  | ||||||
| 			C_rck(word_size); |  | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -916,6 +922,7 @@ CodeUoper(nd) | ||||||
| { | { | ||||||
| 	register struct type *tp = nd->nd_type; | 	register struct type *tp = nd->nd_type; | ||||||
| 
 | 
 | ||||||
|  | 	CodePExpr(nd->nd_right); | ||||||
| 	switch(nd->nd_symb) { | 	switch(nd->nd_symb) { | ||||||
| 	case '~': | 	case '~': | ||||||
| 	case NOT: | 	case NOT: | ||||||
|  |  | ||||||
|  | @ -461,7 +461,6 @@ PointerType(struct type **ptp;) | ||||||
| { | { | ||||||
| 	struct type *tp; | 	struct type *tp; | ||||||
| 	struct def *df; | 	struct def *df; | ||||||
| 	struct def *lookfor(); |  | ||||||
| 	struct node *nd; | 	struct node *nd; | ||||||
| } : | } : | ||||||
| 	POINTER TO | 	POINTER TO | ||||||
|  |  | ||||||
|  | @ -117,7 +117,11 @@ struct def	{		/* list of definitions for a name */ | ||||||
| 
 | 
 | ||||||
| extern struct def | extern struct def | ||||||
| 	*define(), | 	*define(), | ||||||
| 	*lookup(), | 	*DefineLocalModule(), | ||||||
|  | 	*MkDef(), | ||||||
| 	*ill_df; | 	*ill_df; | ||||||
| 
 | 
 | ||||||
|  | extern struct def | ||||||
|  | 	*lookup(), | ||||||
|  | 	*lookfor(); | ||||||
| #define NULLDEF ((struct def *) 0) | #define NULLDEF ((struct def *) 0) | ||||||
|  |  | ||||||
|  | @ -203,7 +203,7 @@ DeclProc(type) | ||||||
| 		df->for_node = MkLeaf(Name, &dot); | 		df->for_node = MkLeaf(Name, &dot); | ||||||
| 		sprint(buf,"%s_%s",CurrentScope->sc_name,df->df_idf->id_text); | 		sprint(buf,"%s_%s",CurrentScope->sc_name,df->df_idf->id_text); | ||||||
| 		df->for_name = Salloc(buf, (unsigned) (strlen(buf)+1)); | 		df->for_name = Salloc(buf, (unsigned) (strlen(buf)+1)); | ||||||
| 		C_exp(df->for_name); | 		if (CurrVis == Defined->mod_vis) C_exp(df->for_name); | ||||||
| 		open_scope(OPENSCOPE); | 		open_scope(OPENSCOPE); | ||||||
| 	} | 	} | ||||||
| 	else { | 	else { | ||||||
|  | @ -292,6 +292,51 @@ DefInFront(df) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | struct def * | ||||||
|  | DefineLocalModule(id) | ||||||
|  | 	struct idf *id; | ||||||
|  | { | ||||||
|  | 	/*	Create a definition for a local module. Also give it
 | ||||||
|  | 		a name to be used for code generation. | ||||||
|  | 	*/ | ||||||
|  | 	register struct def *df = define(id, CurrentScope, D_MODULE); | ||||||
|  | 	register struct type *tp; | ||||||
|  | 	register struct scope *sc; | ||||||
|  | 	static int modulecount = 0; | ||||||
|  | 	char buf[256]; | ||||||
|  | 	extern char *sprint(); | ||||||
|  | 	extern int proclevel; | ||||||
|  | 
 | ||||||
|  | 	sprint(buf, "_%d%s", ++modulecount, id->id_text); | ||||||
|  | 
 | ||||||
|  | 	if (!df->mod_vis) {	 | ||||||
|  | 		/* We never saw the name of this module before. Create a
 | ||||||
|  | 		   scope for it. | ||||||
|  | 		*/ | ||||||
|  | 	  	open_scope(CLOSEDSCOPE); | ||||||
|  | 	  	df->mod_vis = CurrVis; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	CurrVis = df->mod_vis; | ||||||
|  | 
 | ||||||
|  | 	sc = CurrentScope; | ||||||
|  | 	sc->sc_level = proclevel; | ||||||
|  | 	sc->sc_definedby = df; | ||||||
|  | 	sc->sc_name = Salloc(buf, (unsigned) (strlen(buf) + 1)); | ||||||
|  | 
 | ||||||
|  | 	/* Create a type for it
 | ||||||
|  | 	*/ | ||||||
|  | 	df->df_type = tp = standard_type(T_RECORD, 0, (arith) 0); | ||||||
|  | 	tp->rec_scope = sc; | ||||||
|  | 
 | ||||||
|  | 	/* Generate code that indicates that the initialization procedure
 | ||||||
|  | 	   for this module is local. | ||||||
|  | 	*/ | ||||||
|  | 	C_inp(buf); | ||||||
|  | 
 | ||||||
|  | 	return df; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| #ifdef DEBUG | #ifdef DEBUG | ||||||
| PrDef(df) | PrDef(df) | ||||||
| 	register struct def *df; | 	register struct def *df; | ||||||
|  |  | ||||||
|  | @ -25,7 +25,6 @@ static char *RcsId = "$Header$"; | ||||||
| #include	"node.h" | #include	"node.h" | ||||||
| 
 | 
 | ||||||
| extern int	proclevel; | extern int	proclevel; | ||||||
| struct desig	Desig; |  | ||||||
| struct desig	InitDesig = {DSG_INIT, 0, 0}; | struct desig	InitDesig = {DSG_INIT, 0, 0}; | ||||||
| 
 | 
 | ||||||
| CodeValue(ds, size) | CodeValue(ds, size) | ||||||
|  | @ -225,6 +224,7 @@ CodeVarDesig(df, ds) | ||||||
| 	*/ | 	*/ | ||||||
| 	assert(ds->dsg_kind == DSG_INIT); | 	assert(ds->dsg_kind == DSG_INIT); | ||||||
| 
 | 
 | ||||||
|  | 	df->df_flags |= D_USED; | ||||||
| 	if (df->var_addrgiven) { | 	if (df->var_addrgiven) { | ||||||
| 		/* the programmer specified an address in the declaration of
 | 		/* the programmer specified an address in the declaration of
 | ||||||
| 		   the variable. Generate code to push the address. | 		   the variable. Generate code to push the address. | ||||||
|  | @ -232,7 +232,6 @@ CodeVarDesig(df, ds) | ||||||
| 		CodeConst(df->var_off, pointer_size); | 		CodeConst(df->var_off, pointer_size); | ||||||
| 		ds->dsg_kind = DSG_PLOADED; | 		ds->dsg_kind = DSG_PLOADED; | ||||||
| 		ds->dsg_offset = 0; | 		ds->dsg_offset = 0; | ||||||
| 		df->df_flags |= D_NOREG; |  | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -243,7 +242,6 @@ CodeVarDesig(df, ds) | ||||||
| 		ds->dsg_name = df->var_name; | 		ds->dsg_name = df->var_name; | ||||||
| 		ds->dsg_offset = 0; | 		ds->dsg_offset = 0; | ||||||
| 		ds->dsg_kind = DSG_FIXED; | 		ds->dsg_kind = DSG_FIXED; | ||||||
| 		df->df_flags |= D_NOREG; |  | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -251,6 +249,8 @@ CodeVarDesig(df, ds) | ||||||
| 		/* the variable is local to a statically enclosing procedure.
 | 		/* the variable is local to a statically enclosing procedure.
 | ||||||
| 		*/ | 		*/ | ||||||
| 		assert(proclevel > sc->sc_level); | 		assert(proclevel > sc->sc_level); | ||||||
|  | 
 | ||||||
|  | 		df->df_flags |= D_NOREG; | ||||||
| 		if (df->df_flags & (D_VARPAR|D_VALPAR)) { | 		if (df->df_flags & (D_VARPAR|D_VALPAR)) { | ||||||
| 			/* value or var parameter
 | 			/* value or var parameter
 | ||||||
| 			*/ | 			*/ | ||||||
|  | @ -269,7 +269,6 @@ CodeVarDesig(df, ds) | ||||||
| 		else	C_lxl((arith) (proclevel - sc->sc_level)); | 		else	C_lxl((arith) (proclevel - sc->sc_level)); | ||||||
| 		ds->dsg_kind = DSG_PLOADED; | 		ds->dsg_kind = DSG_PLOADED; | ||||||
| 		ds->dsg_offset = df->var_off; | 		ds->dsg_offset = df->var_off; | ||||||
| 		df->df_flags |= D_NOREG; |  | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -50,6 +50,6 @@ struct withdesig { | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| extern struct withdesig	*WithDesigs; | extern struct withdesig	*WithDesigs; | ||||||
| extern struct desig	Desig, InitDesig; | extern struct desig	InitDesig; | ||||||
| 
 | 
 | ||||||
| #define NO_LABEL	((label) 0) | #define NO_LABEL	((label) 0) | ||||||
|  |  | ||||||
|  | @ -116,6 +116,7 @@ EnterVarList(Idlist, type, local) | ||||||
| 			/* An address was supplied
 | 			/* An address was supplied
 | ||||||
| 			*/ | 			*/ | ||||||
| 			df->var_addrgiven = 1; | 			df->var_addrgiven = 1; | ||||||
|  | 			df->df_flags |= D_NOREG; | ||||||
| 			if (idlist->nd_left->nd_type != card_type) { | 			if (idlist->nd_left->nd_type != card_type) { | ||||||
| node_error(idlist->nd_left,"Illegal type for address"); | node_error(idlist->nd_left,"Illegal type for address"); | ||||||
| 			} | 			} | ||||||
|  | @ -137,10 +138,13 @@ node_error(idlist->nd_left,"Illegal type for address"); | ||||||
| 			sprint(buf,"%s_%s", sc->sc_scope->sc_name, | 			sprint(buf,"%s_%s", sc->sc_scope->sc_name, | ||||||
| 					    df->df_idf->id_text); | 					    df->df_idf->id_text); | ||||||
| 			df->var_name = Salloc(buf, (unsigned)(strlen(buf)+1)); | 			df->var_name = Salloc(buf, (unsigned)(strlen(buf)+1)); | ||||||
|  | 			df->df_flags |= D_NOREG; | ||||||
| 
 | 
 | ||||||
|  			if (DefinitionModule) { |  			if (DefinitionModule) { | ||||||
|  | 				if (sc == Defined->mod_vis) { | ||||||
| 					C_exa_dnam(df->var_name); | 					C_exa_dnam(df->var_name); | ||||||
| 				} | 				} | ||||||
|  | 			} | ||||||
| 			else { | 			else { | ||||||
| 				C_ina_dnam(df->var_name); | 				C_ina_dnam(df->var_name); | ||||||
| 			} | 			} | ||||||
|  | @ -163,11 +167,16 @@ EnterParamList(ppr, Idlist, type, VARp, off) | ||||||
| 	register struct paramlist *pr; | 	register struct paramlist *pr; | ||||||
| 	register struct def *df; | 	register struct def *df; | ||||||
| 	register struct node *idlist = Idlist; | 	register struct node *idlist = Idlist; | ||||||
|  | 	static struct paramlist *last; | ||||||
| 
 | 
 | ||||||
| 	for ( ; idlist; idlist = idlist->next) { | 	for ( ; idlist; idlist = idlist->next) { | ||||||
| 		pr = new_paramlist(); | 		pr = new_paramlist(); | ||||||
| 		pr->next = *ppr; | 		pr->next = 0; | ||||||
|  | 		if (!*ppr) { | ||||||
| 			*ppr = pr; | 			*ppr = pr; | ||||||
|  | 		} | ||||||
|  | 		else	last->next = pr; | ||||||
|  | 		last = pr; | ||||||
| 		df = define(idlist->nd_IDF, CurrentScope, D_VARIABLE); | 		df = define(idlist->nd_IDF, CurrentScope, D_VARIABLE); | ||||||
| 		pr->par_def = df; | 		pr->par_def = df; | ||||||
| 		df->df_type = type; | 		df->df_type = type; | ||||||
|  | @ -188,7 +197,7 @@ EnterParamList(ppr, Idlist, type, VARp, off) | ||||||
| 	FreeNode(Idlist); | 	FreeNode(Idlist); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static | STATIC | ||||||
| DoImport(df, scope) | DoImport(df, scope) | ||||||
| 	register struct def *df; | 	register struct def *df; | ||||||
| 	struct scope *scope; | 	struct scope *scope; | ||||||
|  | @ -222,7 +231,7 @@ DoImport(df, scope) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static struct scopelist * | STATIC struct scopelist * | ||||||
| ForwModule(df, idn) | ForwModule(df, idn) | ||||||
| 	register struct def *df; | 	register struct def *df; | ||||||
| 	struct node *idn; | 	struct node *idn; | ||||||
|  | @ -248,7 +257,7 @@ ForwModule(df, idn) | ||||||
| 	return vis; | 	return vis; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static struct def * | STATIC struct def * | ||||||
| ForwDef(ids, scope) | ForwDef(ids, scope) | ||||||
| 	register struct node *ids; | 	register struct node *ids; | ||||||
| 	struct scope *scope; | 	struct scope *scope; | ||||||
|  | @ -351,7 +360,7 @@ EnterFromImportList(Idlist, Fromid, local) | ||||||
| 	register struct def *df; | 	register struct def *df; | ||||||
| 	struct scopelist *vis = enclosing(CurrVis); | 	struct scopelist *vis = enclosing(CurrVis); | ||||||
| 	int forwflag = 0; | 	int forwflag = 0; | ||||||
| 	extern struct def *lookfor(), *GetDefinitionModule(); | 	extern struct def *GetDefinitionModule(); | ||||||
| 
 | 
 | ||||||
| 	if (local) { | 	if (local) { | ||||||
| 		df = lookfor(Fromid, vis, 0); | 		df = lookfor(Fromid, vis, 0); | ||||||
|  | @ -412,7 +421,7 @@ EnterImportList(Idlist, local) | ||||||
| 	register struct node *idlist = Idlist; | 	register struct node *idlist = Idlist; | ||||||
| 	register struct def *df; | 	register struct def *df; | ||||||
| 	struct scopelist *vis = enclosing(CurrVis); | 	struct scopelist *vis = enclosing(CurrVis); | ||||||
| 	extern struct def *lookfor(), *GetDefinitionModule(); | 	extern struct def *GetDefinitionModule(); | ||||||
| 
 | 
 | ||||||
| 	for (; idlist; idlist = idlist->next) { | 	for (; idlist; idlist = idlist->next) { | ||||||
| 		if (local) df = ForwDef(idlist, vis->sc_scope); | 		if (local) df = ForwDef(idlist, vis->sc_scope); | ||||||
|  |  | ||||||
|  | @ -18,19 +18,17 @@ static char *RcsId = "$Header$"; | ||||||
| #include	"node.h" | #include	"node.h" | ||||||
| #include	"const.h" | #include	"const.h" | ||||||
| #include	"type.h" | #include	"type.h" | ||||||
|  | #include	"chk_expr.h" | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| number(struct node **p;) | number(struct node **p;) : | ||||||
| { |  | ||||||
| 	struct type *tp; |  | ||||||
| } : |  | ||||||
| [ | [ | ||||||
| 	%default | 	%default | ||||||
| 	INTEGER		{ tp = toktype; } | 	INTEGER | ||||||
| | | | | ||||||
| 	REAL		{ tp = real_type; } | 	REAL | ||||||
| ]			{ *p = MkLeaf(Value, &dot); | ]			{ *p = MkLeaf(Value, &dot); | ||||||
| 			  (*p)->nd_type = tp; | 			  (*p)->nd_type = toktype; | ||||||
| 			} | 			} | ||||||
| ; | ; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -16,8 +16,6 @@ static char *RcsId = "$Header$"; | ||||||
| #include	"LLlex.h" | #include	"LLlex.h" | ||||||
| #include	"node.h" | #include	"node.h" | ||||||
| 
 | 
 | ||||||
| extern struct def	*MkDef(); |  | ||||||
| 
 |  | ||||||
| struct def * | struct def * | ||||||
| lookup(id, scope) | lookup(id, scope) | ||||||
| 	register struct idf *id; | 	register struct idf *id; | ||||||
|  |  | ||||||
|  | @ -15,7 +15,7 @@ static char *RcsId = "$Header$"; | ||||||
| #include	"node.h" | #include	"node.h" | ||||||
| 
 | 
 | ||||||
| match_id(id1, id2) | match_id(id1, id2) | ||||||
| 	struct idf *id1, *id2; | 	register struct idf *id1, *id2; | ||||||
| { | { | ||||||
| 	/*	Check that identifiers id1 and id2 are equal. If they
 | 	/*	Check that identifiers id1 and id2 are equal. If they
 | ||||||
| 		are not, check that we did'nt generate them in the | 		are not, check that we did'nt generate them in the | ||||||
|  | @ -45,7 +45,7 @@ gen_anon_idf() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| id_not_declared(id) | id_not_declared(id) | ||||||
| 	struct node *id; | 	register struct node *id; | ||||||
| { | { | ||||||
| 	/*	The identifier "id" is not declared. If it is not generated,
 | 	/*	The identifier "id" is not declared. If it is not generated,
 | ||||||
| 		give an error message | 		give an error message | ||||||
|  |  | ||||||
|  | @ -19,6 +19,7 @@ struct node { | ||||||
| #define Def	9		/* an identified name */ | #define Def	9		/* an identified name */ | ||||||
| #define Stat	10		/* a statement */ | #define Stat	10		/* a statement */ | ||||||
| #define Link	11 | #define Link	11 | ||||||
|  | 				/* do NOT change the order or the numbers!!! */ | ||||||
| 	struct type *nd_type;	/* type of this node */ | 	struct type *nd_type;	/* type of this node */ | ||||||
| 	struct token nd_token; | 	struct token nd_token; | ||||||
| #define nd_set		nd_token.tk_data.tk_set | #define nd_set		nd_token.tk_data.tk_set | ||||||
|  |  | ||||||
|  | @ -64,11 +64,17 @@ FreeNode(nd) | ||||||
| 	free_node(nd); | 	free_node(nd); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | NodeCrash(expp) | ||||||
|  | 	struct node *expp; | ||||||
|  | { | ||||||
|  | 	crash("Illegal node %d", expp->nd_class); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| #ifdef DEBUG | #ifdef DEBUG | ||||||
| 
 | 
 | ||||||
| extern char *symbol2str(); | extern char *symbol2str(); | ||||||
| 
 | 
 | ||||||
| static | STATIC | ||||||
| printnode(nd) | printnode(nd) | ||||||
| 	register struct node *nd; | 	register struct node *nd; | ||||||
| { | { | ||||||
|  |  | ||||||
|  | @ -42,36 +42,13 @@ static  char *RcsId = "$Header$"; | ||||||
| ModuleDeclaration | ModuleDeclaration | ||||||
| { | { | ||||||
| 	struct idf *id; | 	struct idf *id; | ||||||
| 	register struct def *df; | 	struct def *df; | ||||||
| 	extern int proclevel; |  | ||||||
| 	static int modulecount = 0; |  | ||||||
| 	char buf[256]; |  | ||||||
| 	struct node *nd; | 	struct node *nd; | ||||||
| 	struct node *exportlist = 0; | 	struct node *exportlist = 0; | ||||||
| 	int qualified; | 	int qualified; | ||||||
| 	extern char *sprint(); |  | ||||||
| } : | } : | ||||||
| 	MODULE IDENT	{ | 	MODULE IDENT	{ id = dot.TOK_IDF; | ||||||
| 			  id = dot.TOK_IDF; | 			  df = DefineLocalModule(id); | ||||||
| 			  df = define(id, CurrentScope, D_MODULE); |  | ||||||
| 
 |  | ||||||
| 			  if (!df->mod_vis) {	 |  | ||||||
| 			  	open_scope(CLOSEDSCOPE); |  | ||||||
| 			  	df->mod_vis = CurrVis; |  | ||||||
| 			  } |  | ||||||
| 			  else { |  | ||||||
| 				CurrVis = df->mod_vis; |  | ||||||
| 				CurrentScope->sc_level = proclevel; |  | ||||||
| 			  } |  | ||||||
| 			  CurrentScope->sc_definedby = df; |  | ||||||
| 
 |  | ||||||
| 			  df->df_type = standard_type(T_RECORD, 0, (arith) 0); |  | ||||||
| 			  df->df_type->rec_scope = df->mod_vis->sc_scope; |  | ||||||
| 			  sprint(buf, "_%d%s", ++modulecount, id->id_text); |  | ||||||
| 			  CurrentScope->sc_name = |  | ||||||
| 				Salloc(buf, (unsigned) (strlen(buf) + 1)); |  | ||||||
| 			  if (! proclevel) C_ina_dnam(&buf[1]); |  | ||||||
| 			  C_inp(buf); |  | ||||||
| 			} | 			} | ||||||
| 	priority(&(df->mod_priority))? | 	priority(&(df->mod_priority))? | ||||||
| 	';' | 	';' | ||||||
|  | @ -92,7 +69,7 @@ priority(arith *pprio;) | ||||||
| 	struct node *nd; | 	struct node *nd; | ||||||
| } : | } : | ||||||
| 	'[' ConstExpression(&nd) ']' | 	'[' ConstExpression(&nd) ']' | ||||||
| 			{ if (!(nd->nd_type->tp_fund & T_INTORCARD)) { | 			{ if (!(nd->nd_type->tp_fund & T_CARDINAL)) { | ||||||
| 				node_error(nd, "Illegal priority"); | 				node_error(nd, "Illegal priority"); | ||||||
| 			  } | 			  } | ||||||
| 			  *pprio = nd->nd_INT; | 			  *pprio = nd->nd_INT; | ||||||
|  | @ -141,13 +118,12 @@ DefinitionModule | ||||||
| 	int dummy; | 	int dummy; | ||||||
| } : | } : | ||||||
| 	DEFINITION | 	DEFINITION | ||||||
| 	MODULE IDENT	{  | 	MODULE IDENT	{ id = dot.TOK_IDF; | ||||||
| 			  id = dot.TOK_IDF; |  | ||||||
| 			  df = define(id, GlobalScope, D_MODULE); | 			  df = define(id, GlobalScope, D_MODULE); | ||||||
| 			  if (!SYSTEMModule) open_scope(CLOSEDSCOPE); |  | ||||||
| 			  if (!Defined) Defined = df; | 			  if (!Defined) Defined = df; | ||||||
| 			  df->mod_vis = CurrVis; | 			  if (!SYSTEMModule) open_scope(CLOSEDSCOPE); | ||||||
| 			  CurrentScope->sc_name = id->id_text; | 			  CurrentScope->sc_name = id->id_text; | ||||||
|  | 			  df->mod_vis = CurrVis; | ||||||
| 			  df->df_type = standard_type(T_RECORD, 0, (arith) 0); | 			  df->df_type = standard_type(T_RECORD, 0, (arith) 0); | ||||||
| 			  df->df_type->rec_scope = df->mod_vis->sc_scope; | 			  df->df_type->rec_scope = df->mod_vis->sc_scope; | ||||||
| 			  DefinitionModule++; | 			  DefinitionModule++; | ||||||
|  | @ -222,8 +198,7 @@ ProgramModule | ||||||
| 	struct node *nd; | 	struct node *nd; | ||||||
| } : | } : | ||||||
| 	MODULE | 	MODULE | ||||||
| 	IDENT	{  | 	IDENT	{ id = dot.TOK_IDF; | ||||||
| 		  id = dot.TOK_IDF; |  | ||||||
| 		  if (state == IMPLEMENTATION) { | 		  if (state == IMPLEMENTATION) { | ||||||
| 			df = GetDefinitionModule(id); | 			df = GetDefinitionModule(id); | ||||||
| 			CurrVis = df->mod_vis; | 			CurrVis = df->mod_vis; | ||||||
|  | @ -232,11 +207,11 @@ ProgramModule | ||||||
| 		  } | 		  } | ||||||
| 		  else { | 		  else { | ||||||
| 			df = define(id, CurrentScope, D_MODULE); | 			df = define(id, CurrentScope, D_MODULE); | ||||||
| 		  	Defined = df; |  | ||||||
| 			open_scope(CLOSEDSCOPE); | 			open_scope(CLOSEDSCOPE); | ||||||
| 			df->mod_vis = CurrVis; | 			df->mod_vis = CurrVis; | ||||||
| 			CurrentScope->sc_name = id->id_text; | 			CurrentScope->sc_name = id->id_text; | ||||||
| 		  } | 		  } | ||||||
|  | 		  Defined = df; | ||||||
| 		  CurrentScope->sc_definedby = df; | 		  CurrentScope->sc_definedby = df; | ||||||
| 		} | 		} | ||||||
| 	priority(&(df->mod_priority))? | 	priority(&(df->mod_priority))? | ||||||
|  |  | ||||||
|  | @ -90,7 +90,7 @@ Forward(tk, ptp) | ||||||
| 	CurrentScope->sc_forw = f; | 	CurrentScope->sc_forw = f; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static | STATIC | ||||||
| chk_proc(df) | chk_proc(df) | ||||||
| 	register struct def *df; | 	register struct def *df; | ||||||
| { | { | ||||||
|  | @ -108,7 +108,7 @@ node_error(df->for_node, "procedure \"%s\" not defined", df->df_idf->id_text); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static | STATIC | ||||||
| chk_forw(pdf) | chk_forw(pdf) | ||||||
| 	register struct def **pdf; | 	register struct def **pdf; | ||||||
| { | { | ||||||
|  | @ -153,7 +153,7 @@ node_error((*pdf)->for_node, "identifier \"%s\" has not been declared", | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static | STATIC | ||||||
| rem_forwards(fo) | rem_forwards(fo) | ||||||
| 	struct forwards *fo; | 	struct forwards *fo; | ||||||
| { | { | ||||||
|  | @ -161,7 +161,6 @@ rem_forwards(fo) | ||||||
| 	*/ | 	*/ | ||||||
| 	register struct forwards *f; | 	register struct forwards *f; | ||||||
| 	register struct def *df; | 	register struct def *df; | ||||||
| 	struct def *lookfor(); |  | ||||||
| 
 | 
 | ||||||
| 	while (f = fo) { | 	while (f = fo) { | ||||||
| 		df = lookfor(&(f->fo_tok), CurrVis, 1); | 		df = lookfor(&(f->fo_tok), CurrVis, 1); | ||||||
|  | @ -181,11 +180,10 @@ Reverse(pdf) | ||||||
| 	/*	Reverse the order in the list of definitions in a scope.
 | 	/*	Reverse the order in the list of definitions in a scope.
 | ||||||
| 		This is neccesary because this list is built in reverse. | 		This is neccesary because this list is built in reverse. | ||||||
| 		Also, while we're at it, remove uninteresting definitions | 		Also, while we're at it, remove uninteresting definitions | ||||||
| 		from this list. The only interesting definitions are: | 		from this list. | ||||||
| 		D_MODULE, D_PROCEDURE, and D_PROCHEAD. |  | ||||||
| 	*/ | 	*/ | ||||||
| 	register struct def *df, *df1; | 	register struct def *df, *df1; | ||||||
| #define INTERESTING D_MODULE|D_PROCEDURE|D_PROCHEAD | #define INTERESTING D_MODULE|D_PROCEDURE|D_PROCHEAD|D_VARIABLE | ||||||
| 
 | 
 | ||||||
| 	df = 0; | 	df = 0; | ||||||
| 	df1 = *pdf; | 	df1 = *pdf; | ||||||
|  | @ -217,7 +215,6 @@ close_scope(flag) | ||||||
| 	register struct scope *sc = CurrentScope; | 	register struct scope *sc = CurrentScope; | ||||||
| 
 | 
 | ||||||
| 	assert(sc != 0); | 	assert(sc != 0); | ||||||
| 	DO_DEBUG(1, debug("Closing a scope")); |  | ||||||
| 
 | 
 | ||||||
| 	if (flag) { | 	if (flag) { | ||||||
| 		if (sc->sc_forw) rem_forwards(sc->sc_forw); | 		if (sc->sc_forw) rem_forwards(sc->sc_forw); | ||||||
|  |  | ||||||
|  | @ -83,13 +83,17 @@ ProcedureCall: | ||||||
| 
 | 
 | ||||||
| StatementSequence(register struct node **pnd;) | StatementSequence(register struct node **pnd;) | ||||||
| { | { | ||||||
|  | 	struct node *nd; | ||||||
| } : | } : | ||||||
| 	statement(pnd) | 	statement(pnd) | ||||||
| 	[ | 	[ | ||||||
| 		';'	{ *pnd = MkNode(Link, *pnd, NULLNODE, &dot); | 		';' statement(&nd) | ||||||
|  | 			{ if (nd) { | ||||||
|  | 				*pnd = MkNode(Link, *pnd, nd, &dot); | ||||||
|  | 				(*pnd)->nd_symb = ';'; | ||||||
| 			  	pnd = &((*pnd)->nd_right); | 			  	pnd = &((*pnd)->nd_right); | ||||||
| 			  } | 			  } | ||||||
| 		statement(pnd) | 			} | ||||||
| 	]* | 	]* | ||||||
| ; | ; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -21,9 +21,6 @@ static char *RcsId = "$Header$"; | ||||||
| #include	"const.h" | #include	"const.h" | ||||||
| #include	"scope.h" | #include	"scope.h" | ||||||
| 
 | 
 | ||||||
| /*	To be created dynamically in main() from defaults or from command
 |  | ||||||
| 	line parameters. |  | ||||||
| */ |  | ||||||
| int | int | ||||||
| 	word_align = AL_WORD, | 	word_align = AL_WORD, | ||||||
| 	int_align = AL_INT, | 	int_align = AL_INT, | ||||||
|  | @ -96,38 +93,34 @@ construct_type(fund, tp) | ||||||
| 
 | 
 | ||||||
| 	switch (fund)	{ | 	switch (fund)	{ | ||||||
| 	case T_PROCEDURE: | 	case T_PROCEDURE: | ||||||
|  | 		if (tp && !returntype(tp)) { | ||||||
|  | 			error("illegal procedure result type"); | ||||||
|  | 		} | ||||||
|  | 		/* Fall through */ | ||||||
| 	case T_POINTER: | 	case T_POINTER: | ||||||
| 	case T_HIDDEN: | 	case T_HIDDEN: | ||||||
| 		dtp->tp_align = pointer_align; | 		dtp->tp_align = pointer_align; | ||||||
| 		dtp->tp_size = pointer_size; | 		dtp->tp_size = pointer_size; | ||||||
| 		dtp->next = tp; |  | ||||||
| 		if (fund == T_PROCEDURE && tp) { |  | ||||||
| 			if (! returntype(tp)) { |  | ||||||
| 				error("illegal procedure result type"); |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		break; | 		break; | ||||||
| 
 | 
 | ||||||
| 	case T_SET: | 	case T_SET: | ||||||
| 		dtp->tp_align = word_align; | 		dtp->tp_align = word_align; | ||||||
| 		dtp->next = tp; |  | ||||||
| 		break; | 		break; | ||||||
| 
 | 
 | ||||||
| 	case T_ARRAY: | 	case T_ARRAY: | ||||||
| 		dtp->tp_align = tp->tp_align; | 		dtp->tp_align = tp->tp_align; | ||||||
| 		dtp->next = tp; |  | ||||||
| 		break; | 		break; | ||||||
| 
 | 
 | ||||||
| 	case T_SUBRANGE: | 	case T_SUBRANGE: | ||||||
| 		dtp->tp_align = tp->tp_align; | 		dtp->tp_align = tp->tp_align; | ||||||
| 		dtp->tp_size = tp->tp_size; | 		dtp->tp_size = tp->tp_size; | ||||||
| 		dtp->next = tp; |  | ||||||
| 		break; | 		break; | ||||||
| 
 | 
 | ||||||
| 	default: | 	default: | ||||||
| 		crash("funny type constructor"); | 		crash("funny type constructor"); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	dtp->next = tp; | ||||||
| 	return dtp; | 	return dtp; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -206,8 +199,11 @@ InitTypes() | ||||||
| 	address_type = construct_type(T_POINTER, word_type); | 	address_type = construct_type(T_POINTER, word_type); | ||||||
| 
 | 
 | ||||||
| 	/* create BITSET type
 | 	/* create BITSET type
 | ||||||
|  | 	   TYPE BITSET = SET OF [0..W-1]; | ||||||
|  | 	   The subrange is a subrange of type cardinal, because the lower bound | ||||||
|  | 	   is a non-negative integer (See Rep. 6.3) | ||||||
| 	*/ | 	*/ | ||||||
| 	tp = construct_type(T_SUBRANGE, int_type); | 	tp = construct_type(T_SUBRANGE, card_type); | ||||||
| 	tp->sub_lb = 0; | 	tp->sub_lb = 0; | ||||||
| 	tp->sub_ub = word_size * 8 - 1; | 	tp->sub_ub = word_size * 8 - 1; | ||||||
| 	bitset_type = set_type(tp); | 	bitset_type = set_type(tp); | ||||||
|  | @ -229,7 +225,7 @@ chk_basesubrange(tp, base) | ||||||
| 
 | 
 | ||||||
| 	if (base->tp_fund == T_SUBRANGE) { | 	if (base->tp_fund == T_SUBRANGE) { | ||||||
| 		/* Check that the bounds of "tp" fall within the range
 | 		/* Check that the bounds of "tp" fall within the range
 | ||||||
| 		   of "base" | 		   of "base". | ||||||
| 		*/ | 		*/ | ||||||
| 		if (base->sub_lb > tp->sub_lb || base->sub_ub < tp->sub_ub) { | 		if (base->sub_lb > tp->sub_lb || base->sub_ub < tp->sub_ub) { | ||||||
| 			error("Base type has insufficient range"); | 			error("Base type has insufficient range"); | ||||||
|  | @ -246,7 +242,7 @@ chk_basesubrange(tp, base) | ||||||
| 		error("Illegal base for a subrange"); | 		error("Illegal base for a subrange"); | ||||||
| 	} | 	} | ||||||
| 	else if (base == int_type && tp->next == card_type && | 	else if (base == int_type && tp->next == card_type && | ||||||
| 		 (tp->sub_ub > max_int || tp->sub_ub)) { | 		 (tp->sub_ub > max_int || tp->sub_ub < 0)) { | ||||||
| 		error("Upperbound to large for type INTEGER"); | 		error("Upperbound to large for type INTEGER"); | ||||||
| 	} | 	} | ||||||
| 	else if (base != tp->next && base != int_type) { | 	else if (base != tp->next && base != int_type) { | ||||||
|  | @ -269,7 +265,7 @@ subr_type(lb, ub) | ||||||
| 	register struct type *tp = lb->nd_type, *res; | 	register struct type *tp = lb->nd_type, *res; | ||||||
| 
 | 
 | ||||||
| 	if (!TstCompat(lb->nd_type, ub->nd_type)) { | 	if (!TstCompat(lb->nd_type, ub->nd_type)) { | ||||||
| 		node_error(ub, "Types of subrange bounds not compatible"); | 		node_error(ub, "Types of subrange bounds not equal"); | ||||||
| 		return error_type; | 		return error_type; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -306,32 +302,33 @@ subr_type(lb, ub) | ||||||
| 	return res; | 	return res; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| label | genrck(tp) | ||||||
| getrck(tp) |  | ||||||
| 	register struct type *tp; | 	register struct type *tp; | ||||||
| { | { | ||||||
| 	/*	generate a range check descriptor for type "tp" when
 | 	/*	generate a range check descriptor for type "tp" when
 | ||||||
| 		neccessary. Return its label | 		neccessary. Return its label. | ||||||
| 	*/ | 	*/ | ||||||
|  | 	arith lb, ub; | ||||||
|  | 	label ol, l; | ||||||
| 
 | 
 | ||||||
| 	assert(bounded(tp)); | 	getbounds(tp, &lb, &ub); | ||||||
| 
 | 
 | ||||||
| 	if (tp->tp_fund == T_SUBRANGE) { | 	if (tp->tp_fund == T_SUBRANGE) { | ||||||
| 		if (tp->sub_rck == (label) 0) { | 		if (!(ol = tp->sub_rck)) { | ||||||
| 			tp->sub_rck = data_label(); | 			tp->sub_rck = l = data_label(); | ||||||
| 			C_df_dlb(tp->sub_rck); |  | ||||||
| 			C_rom_cst(tp->sub_lb); |  | ||||||
| 			C_rom_cst(tp->sub_ub); |  | ||||||
| 		} | 		} | ||||||
| 		return tp->sub_rck; |  | ||||||
| 	} | 	} | ||||||
| 	if (tp->enm_rck == (label) 0) { | 	else if (!(ol = tp->enm_rck)) { | ||||||
| 		tp->enm_rck = data_label(); | 		tp->enm_rck = l = data_label(); | ||||||
| 		C_df_dlb(tp->enm_rck); |  | ||||||
| 		C_rom_cst((arith) 0); |  | ||||||
| 		C_rom_cst((arith) (tp->enm_ncst - 1)); |  | ||||||
| 	} | 	} | ||||||
| 	return tp->enm_rck; | 	if (!ol) { | ||||||
|  | 		ol = l; | ||||||
|  | 		C_df_dlb(ol); | ||||||
|  | 		C_rom_cst(lb); | ||||||
|  | 		C_rom_cst(ub); | ||||||
|  | 	} | ||||||
|  | 	C_lae_dlb(ol, (arith) 0); | ||||||
|  | 	C_rck(word_size); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| getbounds(tp, plo, phi) | getbounds(tp, plo, phi) | ||||||
|  | @ -352,6 +349,7 @@ getbounds(tp, plo, phi) | ||||||
| 		*phi = tp->enm_ncst - 1; | 		*phi = tp->enm_ncst - 1; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | 
 | ||||||
| struct type * | struct type * | ||||||
| set_type(tp) | set_type(tp) | ||||||
| 	register struct type *tp; | 	register struct type *tp; | ||||||
|  | @ -361,26 +359,20 @@ set_type(tp) | ||||||
| 	*/ | 	*/ | ||||||
| 	arith lb, ub; | 	arith lb, ub; | ||||||
| 
 | 
 | ||||||
| 	if (tp->tp_fund == T_SUBRANGE) { | 	if (! bounded(tp)) { | ||||||
| 		if ((lb = tp->sub_lb) < 0 || (ub = tp->sub_ub) > MAXSET - 1) { |  | ||||||
| 			error("Set type limits exceeded"); |  | ||||||
| 			return error_type; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	else if (tp->tp_fund == T_ENUMERATION || tp == char_type) { |  | ||||||
| 		lb = 0; |  | ||||||
| 		if ((ub = tp->enm_ncst - 1) > MAXSET - 1) { |  | ||||||
| 			error("Set type limits exceeded"); |  | ||||||
| 			return error_type; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	else { |  | ||||||
| 		error("illegal base type for set"); | 		error("illegal base type for set"); | ||||||
| 		return error_type; | 		return error_type; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	getbounds(tp, &lb, &ub); | ||||||
|  | 
 | ||||||
|  | 	if (lb < 0 || ub > MAXSET-1) { | ||||||
|  | 		error("Set type limits exceeded"); | ||||||
|  | 		return error_type; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	tp = construct_type(T_SET, tp); | 	tp = construct_type(T_SET, tp); | ||||||
| 	tp->tp_size = WA(((ub - lb) + 7)/8); | 	tp->tp_size = WA(((ub - lb) + 8)/8); | ||||||
| 	return tp; | 	return tp; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -412,47 +404,30 @@ ArraySizes(tp) | ||||||
| 	*/ | 	*/ | ||||||
| 	register struct type *index_type = tp->next; | 	register struct type *index_type = tp->next; | ||||||
| 	register struct type *elem_type = tp->arr_elem; | 	register struct type *elem_type = tp->arr_elem; | ||||||
|  | 	arith lo, hi; | ||||||
| 
 | 
 | ||||||
| 	tp->arr_elsize = ArrayElSize(elem_type); | 	tp->arr_elsize = ArrayElSize(elem_type); | ||||||
| 	tp->tp_align = elem_type->tp_align; | 	tp->tp_align = elem_type->tp_align; | ||||||
| 
 | 
 | ||||||
| 	/* check index type
 | 	/* check index type
 | ||||||
| 	*/ | 	*/ | ||||||
| 	if (! (index_type->tp_fund & T_INDEX)) { | 	if (! bounded(index_type)) { | ||||||
| 		error("Illegal index type"); | 		error("Illegal index type"); | ||||||
| 		tp->tp_size = 0; | 		tp->tp_size = 0; | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/* find out HIGH, LOW and size of ARRAY
 | 	getbounds(index_type, &lo, &hi); | ||||||
|  | 
 | ||||||
|  | 	tp->tp_size = WA((hi - lo + 1) * tp->arr_elsize); | ||||||
|  | 
 | ||||||
|  | 	/* generate descriptor and remember label.
 | ||||||
| 	*/ | 	*/ | ||||||
| 	tp->arr_descr = data_label(); | 	tp->arr_descr = data_label(); | ||||||
| 	C_df_dlb(tp->arr_descr); | 	C_df_dlb(tp->arr_descr); | ||||||
| 
 | 	C_rom_cst(lo); | ||||||
| 	switch(index_type->tp_fund) { | 	C_rom_cst(hi - lo); | ||||||
| 	case T_SUBRANGE: |  | ||||||
| 		tp->tp_size = tp->arr_elsize * |  | ||||||
| 			(index_type->sub_ub - index_type->sub_lb + 1); |  | ||||||
| 		C_rom_cst(index_type->sub_lb); |  | ||||||
| 		C_rom_cst(index_type->sub_ub - index_type->sub_lb); |  | ||||||
| 		break; |  | ||||||
| 
 |  | ||||||
| 	case T_CHAR: |  | ||||||
| 	case T_ENUMERATION: |  | ||||||
| 		tp->tp_size = tp->arr_elsize * index_type->enm_ncst; |  | ||||||
| 		C_rom_cst((arith) 0); |  | ||||||
| 		C_rom_cst((arith) (index_type->enm_ncst - 1)); |  | ||||||
| 		break; |  | ||||||
| 
 |  | ||||||
| 	default: |  | ||||||
| 		crash("Funny index type"); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	C_rom_cst(tp->arr_elsize); | 	C_rom_cst(tp->arr_elsize); | ||||||
| 	tp->tp_size = WA(tp->tp_size); |  | ||||||
| 
 |  | ||||||
| 	/* ??? overflow checking ???
 |  | ||||||
| 	*/ |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| FreeType(tp) | FreeType(tp) | ||||||
|  |  | ||||||
|  | @ -12,6 +12,7 @@ static char *RcsId = "$Header$"; | ||||||
| 
 | 
 | ||||||
| #include	<em_arith.h> | #include	<em_arith.h> | ||||||
| #include	<em_label.h> | #include	<em_label.h> | ||||||
|  | #include	<em_reg.h> | ||||||
| #include	<assert.h> | #include	<assert.h> | ||||||
| 
 | 
 | ||||||
| #include	"def.h" | #include	"def.h" | ||||||
|  | @ -24,6 +25,7 @@ static char *RcsId = "$Header$"; | ||||||
| #include	"desig.h" | #include	"desig.h" | ||||||
| #include	"f_info.h" | #include	"f_info.h" | ||||||
| #include	"idf.h" | #include	"idf.h" | ||||||
|  | #include	"chk_expr.h" | ||||||
| 
 | 
 | ||||||
| extern arith	NewPtr(); | extern arith	NewPtr(); | ||||||
| extern arith	NewInt(); | extern arith	NewInt(); | ||||||
|  | @ -49,7 +51,7 @@ data_label() | ||||||
| 	return ++datalabel; | 	return ++datalabel; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static | STATIC | ||||||
| DoProfil() | DoProfil() | ||||||
| { | { | ||||||
| 	static label	filename_label = 0; | 	static label	filename_label = 0; | ||||||
|  | @ -119,16 +121,14 @@ WalkModule(module) | ||||||
| 		struct node *nd; | 		struct node *nd; | ||||||
| 
 | 
 | ||||||
| 		if (state == IMPLEMENTATION) { | 		if (state == IMPLEMENTATION) { | ||||||
| 			label l1 = data_label(), l2 = text_label(); | 			label l1 = data_label(); | ||||||
| 			/* we don't actually prevent recursive calls,
 | 			/* we don't actually prevent recursive calls,
 | ||||||
| 			   but do nothing if called recursively | 			   but do nothing if called recursively | ||||||
| 			*/ | 			*/ | ||||||
| 			C_df_dlb(l1); | 			C_df_dlb(l1); | ||||||
| 			C_bss_cst(word_size, (arith) 0, 1); | 			C_bss_cst(word_size, (arith) 0, 1); | ||||||
| 			C_loe_dlb(l1, (arith) 0); | 			C_loe_dlb(l1, (arith) 0); | ||||||
| 			C_zeq(l2); | 			C_zne((label) 1); | ||||||
| 			C_ret((arith) 0); |  | ||||||
| 			C_df_ilb(l2); |  | ||||||
| 			C_loc((arith) 1); | 			C_loc((arith) 1); | ||||||
| 			C_ste_dlb(l1, (arith) 0); | 			C_ste_dlb(l1, (arith) 0); | ||||||
| 		} | 		} | ||||||
|  | @ -159,7 +159,8 @@ WalkProcedure(procedure) | ||||||
| 	*/ | 	*/ | ||||||
| 	struct scopelist *vis = CurrVis; | 	struct scopelist *vis = CurrVis; | ||||||
| 	register struct scope *sc; | 	register struct scope *sc; | ||||||
| 	register struct type *res_type; | 	register struct type *tp; | ||||||
|  | 	register struct paramlist *param; | ||||||
| 
 | 
 | ||||||
| 	proclevel++; | 	proclevel++; | ||||||
| 	CurrVis = procedure->prc_vis; | 	CurrVis = procedure->prc_vis; | ||||||
|  | @ -177,19 +178,20 @@ WalkProcedure(procedure) | ||||||
| 	MkCalls(sc->sc_def); | 	MkCalls(sc->sc_def); | ||||||
| 	return_expr_occurred = 0; | 	return_expr_occurred = 0; | ||||||
| 	instructionlabel = 2; | 	instructionlabel = 2; | ||||||
| 	func_type = res_type = procedure->df_type->next; | 	func_type = tp = procedure->df_type->next; | ||||||
| 	if (! returntype(res_type)) { | 	if (! returntype(tp)) { | ||||||
| 		node_error(procedure->prc_body, "illegal result type"); | 		node_error(procedure->prc_body, "illegal result type"); | ||||||
| 	} | 	} | ||||||
| 	WalkNode(procedure->prc_body, (label) 0); | 	WalkNode(procedure->prc_body, (label) 0); | ||||||
| 	C_df_ilb((label) 1); | 	C_df_ilb((label) 1); | ||||||
| 	if (res_type) { | 	if (tp) { | ||||||
| 		if (! return_expr_occurred) { | 		if (! return_expr_occurred) { | ||||||
| node_error(procedure->prc_body,"function procedure does not return a value"); | node_error(procedure->prc_body,"function procedure does not return a value"); | ||||||
| 		} | 		} | ||||||
| 		C_ret(WA(res_type->tp_size)); | 		C_ret(WA(tp->tp_size)); | ||||||
| 	} | 	} | ||||||
| 	else	C_ret((arith) 0); | 	else	C_ret((arith) 0); | ||||||
|  | 	RegisterMessages(sc->sc_def); | ||||||
| 	C_end(-sc->sc_off); | 	C_end(-sc->sc_off); | ||||||
| 	TmpClose(); | 	TmpClose(); | ||||||
| 	CurrVis = vis; | 	CurrVis = vis; | ||||||
|  | @ -257,7 +259,6 @@ WalkStat(nd, lab) | ||||||
| 	*/ | 	*/ | ||||||
| 	register struct node *left = nd->nd_left; | 	register struct node *left = nd->nd_left; | ||||||
| 	register struct node *right = nd->nd_right; | 	register struct node *right = nd->nd_right; | ||||||
| 	register struct desig *pds = &Desig; |  | ||||||
| 
 | 
 | ||||||
| 	if (!nd) { | 	if (!nd) { | ||||||
| 		/* Empty statement
 | 		/* Empty statement
 | ||||||
|  | @ -385,9 +386,10 @@ WalkStat(nd, lab) | ||||||
| 		{ | 		{ | ||||||
| 			struct scopelist link; | 			struct scopelist link; | ||||||
| 			struct withdesig wds; | 			struct withdesig wds; | ||||||
|  | 			struct desig ds; | ||||||
| 			arith tmp = 0; | 			arith tmp = 0; | ||||||
| 
 | 
 | ||||||
| 			WalkDesignator(left); | 			WalkDesignator(left, &ds); | ||||||
| 			if (left->nd_type->tp_fund != T_RECORD) { | 			if (left->nd_type->tp_fund != T_RECORD) { | ||||||
| 				node_error(left, "record variable expected"); | 				node_error(left, "record variable expected"); | ||||||
| 				break; | 				break; | ||||||
|  | @ -396,19 +398,21 @@ WalkStat(nd, lab) | ||||||
| 			wds.w_next = WithDesigs; | 			wds.w_next = WithDesigs; | ||||||
| 			WithDesigs = &wds; | 			WithDesigs = &wds; | ||||||
| 			wds.w_scope = left->nd_type->rec_scope; | 			wds.w_scope = left->nd_type->rec_scope; | ||||||
| 			if (pds->dsg_kind != DSG_PFIXED) { | 			if (ds.dsg_kind != DSG_PFIXED) { | ||||||
| 				/* In this case, we use a temporary variable
 | 				/* In this case, we use a temporary variable
 | ||||||
| 				*/ | 				*/ | ||||||
| 				CodeAddress(pds); | 				CodeAddress(&ds); | ||||||
| 				pds->dsg_kind = DSG_FIXED; | 				ds.dsg_kind = DSG_FIXED; | ||||||
| 				/* Only for the store ... */ | 				/* Create a designator structure for the
 | ||||||
| 				pds->dsg_offset = tmp = NewPtr(); | 				   temporary. | ||||||
| 				pds->dsg_name = 0; | 				*/ | ||||||
| 				CodeStore(pds, pointer_size); | 				ds.dsg_offset = tmp = NewPtr(); | ||||||
| 				pds->dsg_kind = DSG_PFIXED; | 				ds.dsg_name = 0; | ||||||
|  | 				CodeStore(&ds, pointer_size); | ||||||
|  | 				ds.dsg_kind = DSG_PFIXED; | ||||||
| 				/* the record is indirectly available */ | 				/* the record is indirectly available */ | ||||||
| 			} | 			} | ||||||
| 			wds.w_desig = *pds; | 			wds.w_desig = ds; | ||||||
| 			link.sc_scope = wds.w_scope; | 			link.sc_scope = wds.w_scope; | ||||||
| 			link.next = CurrVis; | 			link.next = CurrVis; | ||||||
| 			CurrVis = &link; | 			CurrVis = &link; | ||||||
|  | @ -439,7 +443,7 @@ node_error(right, "type incompatibility in RETURN statement"); | ||||||
| 		break; | 		break; | ||||||
| 
 | 
 | ||||||
| 	default: | 	default: | ||||||
| 		assert(0); | 		crash("(WalkStat)"); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -450,6 +454,7 @@ ExpectBool(nd, true_label, false_label) | ||||||
| 	/*	"nd" must indicate a boolean expression. Check this and
 | 	/*	"nd" must indicate a boolean expression. Check this and
 | ||||||
| 		generate code to evaluate the expression. | 		generate code to evaluate the expression. | ||||||
| 	*/ | 	*/ | ||||||
|  | 	struct desig ds; | ||||||
| 
 | 
 | ||||||
| 	if (!chk_expr(nd)) return; | 	if (!chk_expr(nd)) return; | ||||||
| 
 | 
 | ||||||
|  | @ -457,8 +462,8 @@ ExpectBool(nd, true_label, false_label) | ||||||
| 		node_error(nd, "boolean expression expected"); | 		node_error(nd, "boolean expression expected"); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	Desig = InitDesig; | 	ds = InitDesig; | ||||||
| 	CodeExpr(nd, &Desig,  true_label, false_label); | 	CodeExpr(nd, &ds,  true_label, false_label); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| WalkExpr(nd) | WalkExpr(nd) | ||||||
|  | @ -474,8 +479,9 @@ WalkExpr(nd) | ||||||
| 	CodePExpr(nd); | 	CodePExpr(nd); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| WalkDesignator(nd) | WalkDesignator(nd, ds) | ||||||
| 	struct node *nd; | 	struct node *nd; | ||||||
|  | 	struct desig *ds; | ||||||
| { | { | ||||||
| 	/*	Check designator and generate code for it
 | 	/*	Check designator and generate code for it
 | ||||||
| 	*/ | 	*/ | ||||||
|  | @ -484,8 +490,8 @@ WalkDesignator(nd) | ||||||
| 
 | 
 | ||||||
| 	if (! chk_designator(nd, DESIGNATOR|VARIABLE, D_DEFINED)) return; | 	if (! chk_designator(nd, DESIGNATOR|VARIABLE, D_DEFINED)) return; | ||||||
| 
 | 
 | ||||||
| 	Desig = InitDesig; | 	*ds = InitDesig; | ||||||
| 	CodeDesig(nd, &Desig); | 	CodeDesig(nd, ds); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| DoForInit(nd, left) | DoForInit(nd, left) | ||||||
|  | @ -527,13 +533,13 @@ DoAssign(nd, left, right) | ||||||
| 	register struct node *left, *right; | 	register struct node *left, *right; | ||||||
| { | { | ||||||
| 	/* May we do it in this order (expression first) ??? */ | 	/* May we do it in this order (expression first) ??? */ | ||||||
| 	struct desig ds; | 	struct desig dsl, dsr; | ||||||
| 
 | 
 | ||||||
| 	if (!chk_expr(right)) return; | 	if (!chk_expr(right)) return; | ||||||
| 	if (! chk_designator(left, DESIGNATOR|VARIABLE, D_DEFINED)) return; | 	if (! chk_designator(left, DESIGNATOR|VARIABLE, D_DEFINED)) return; | ||||||
| 	TryToString(right, left->nd_type); | 	TryToString(right, left->nd_type); | ||||||
| 	Desig = InitDesig; | 	dsr = InitDesig; | ||||||
| 	CodeExpr(right, &Desig, NO_LABEL, NO_LABEL); | 	CodeExpr(right, &dsr, NO_LABEL, NO_LABEL); | ||||||
| 
 | 
 | ||||||
| 	if (! TstAssCompat(left->nd_type, right->nd_type)) { | 	if (! TstAssCompat(left->nd_type, right->nd_type)) { | ||||||
| 		node_error(nd, "type incompatibility in assignment"); | 		node_error(nd, "type incompatibility in assignment"); | ||||||
|  | @ -541,17 +547,44 @@ DoAssign(nd, left, right) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (complex(right->nd_type)) { | 	if (complex(right->nd_type)) { | ||||||
| 		CodeAddress(&Desig); | 		CodeAddress(&dsr); | ||||||
| 	} | 	} | ||||||
| 	else { | 	else { | ||||||
| 		CodeValue(&Desig, right->nd_type->tp_size); | 		CodeValue(&dsr, right->nd_type->tp_size); | ||||||
| 		CheckAssign(left->nd_type, right->nd_type); | 		CheckAssign(left->nd_type, right->nd_type); | ||||||
| 	} | 	} | ||||||
| 	ds = Desig; | 	dsl = InitDesig; | ||||||
| 	Desig = InitDesig; | 	CodeDesig(left, &dsl); | ||||||
| 	CodeDesig(left, &Desig); |  | ||||||
| 
 | 
 | ||||||
| 	CodeAssign(nd, &ds, &Desig); | 	CodeAssign(nd, &dsr, &dsl); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | RegisterMessages(df) | ||||||
|  | 	register struct def *df; | ||||||
|  | { | ||||||
|  | 	struct type *tp; | ||||||
|  | 
 | ||||||
|  | 	for (; df; df = df->df_nextinscope) { | ||||||
|  | 		if (df->df_kind == D_VARIABLE && !(df->df_flags & D_NOREG)) { | ||||||
|  | 			/* Examine type and size
 | ||||||
|  | 			*/ | ||||||
|  | 			tp = df->df_type; | ||||||
|  | 			if (tp->tp_fund == T_SUBRANGE) tp = tp->next; | ||||||
|  | 			if ((tp->tp_fund & T_NUMERIC) && | ||||||
|  | 			     tp->tp_size <= dword_size) { | ||||||
|  | 				C_ms_reg(df->var_off, | ||||||
|  | 					 tp->tp_size, | ||||||
|  | 					 tp->tp_fund == T_REAL ? | ||||||
|  | 					    reg_float : reg_any, | ||||||
|  | 					 0); | ||||||
|  | 			} | ||||||
|  | 			else if ((df->df_flags & D_VARPAR) || | ||||||
|  | 				 tp->tp_fund == T_POINTER) { | ||||||
|  | 				C_ms_reg(df->var_off, pointer_size, | ||||||
|  | 					 reg_pointer, 0); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #ifdef DEBUG | #ifdef DEBUG | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue