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; | ||||
| #endif | ||||
| 
 | ||||
| static | ||||
| STATIC | ||||
| SkipComment() | ||||
| { | ||||
| 	/*	Skip Modula-2 comments (* ... *).
 | ||||
|  | @ -50,16 +50,12 @@ SkipComment() | |||
| 			cntlines++; | ||||
| #endif | ||||
| 		} | ||||
| 		else | ||||
| 		if (ch == '(') { | ||||
| 		else if (ch == '(') { | ||||
| 			LoadChar(ch); | ||||
| 			if (ch == '*') { | ||||
| 				++NestLevel; | ||||
| 			} | ||||
| 			if (ch == '*') ++NestLevel; | ||||
| 			else	continue; | ||||
| 		} | ||||
| 		else | ||||
| 		if (ch == '*') { | ||||
| 		else if (ch == '*') { | ||||
| 			LoadChar(ch); | ||||
| 			if (ch == ')') { | ||||
| 				if (NestLevel-- == 0) return; | ||||
|  | @ -70,7 +66,7 @@ SkipComment() | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| static | ||||
| STATIC | ||||
| GetString(upto) | ||||
| { | ||||
| 	/*	Read a Modula-2 string, delimited by the character "upto".
 | ||||
|  | @ -118,11 +114,13 @@ LLlex() | |||
| 	register int ch, nch; | ||||
| 
 | ||||
| 	toktype = error_type; | ||||
| 
 | ||||
| 	if (ASIDE)	{	/* a token is put aside		*/ | ||||
| 		*tk = aside; | ||||
| 		ASIDE = 0; | ||||
| 		return tk->tk_symb; | ||||
| 	} | ||||
| 
 | ||||
| 	tk->tk_lineno = LineNumber; | ||||
| 
 | ||||
| again: | ||||
|  | @ -216,8 +214,7 @@ again: | |||
| 			LoadChar(ch); | ||||
| 		} while(in_idf(ch)); | ||||
| 
 | ||||
| 		if (ch != EOI) | ||||
| 			PushBack(ch); | ||||
| 		if (ch != EOI) PushBack(ch); | ||||
| 		*tg++ = '\0'; | ||||
| 
 | ||||
| 		tk->TOK_IDF = id = str2idf(buf, 1); | ||||
|  | @ -396,6 +393,7 @@ Sreal: | |||
| 				lexerror("floating constant too long"); | ||||
| 			} | ||||
| 			else	tk->TOK_REL = Salloc(buf, np - buf) + 1; | ||||
| 			toktype = real_type; | ||||
| 			return tk->tk_symb = REAL; | ||||
| 
 | ||||
| 		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 | ||||
| CC =	cc | ||||
| GEN =	LLgen | ||||
| GENOPTIONS = | ||||
| PROFILE =  | ||||
| CFLAGS = $(PROFILE) $(INCLUDES) | ||||
| GEN =	/usr/em/util/LLgen/src/LLgen | ||||
| GENOPTIONS = -d | ||||
| PROFILE = -p | ||||
| CFLAGS = $(PROFILE) $(INCLUDES) -DSTATIC= | ||||
| LINTFLAGS = -DSTATIC= -DNORCSID | ||||
| LFLAGS = $(PROFILE) | ||||
| LOBJ =	tokenfile.o program.o declar.o expression.o statement.o | ||||
| COBJ =	LLlex.o LLmessage.o char.o error.o main.o \
 | ||||
|  | @ -46,7 +47,7 @@ clean: | |||
| 	rm -f $(OBJ) $(GENFILES) LLfiles  | ||||
| 
 | ||||
| lint:	LLfiles hfiles | ||||
| 	lint $(INCLUDES) -DNORCSID `sources $(OBJ)` | ||||
| 	lint $(INCLUDES) $(LINTFLAGS) `sources $(OBJ)` | ||||
| 
 | ||||
| tokenfile.g:	tokenname.c make.tokfile | ||||
| 	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 | ||||
| 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 | ||||
| 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 | ||||
| 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 | ||||
| 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 | ||||
| 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 | ||||
| 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 | ||||
| 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 | ||||
| Lpars.o: Lpars.h | ||||
|  |  | |||
|  | @ -23,81 +23,150 @@ static char *RcsId = "$Header$"; | |||
| #include	"scope.h" | ||||
| #include	"const.h" | ||||
| #include	"standards.h" | ||||
| #include	"chk_expr.h" | ||||
| 
 | ||||
| extern char *symbol2str(); | ||||
| 
 | ||||
| int | ||||
| chk_expr(expp) | ||||
| 	register struct node *expp; | ||||
| STATIC int | ||||
| chk_arr(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. | ||||
| 	*/ | ||||
| 	return chk_designator(expp, DESIGNATOR|VARIABLE, D_USED); | ||||
| } | ||||
| 
 | ||||
| 	switch(expp->nd_class) { | ||||
| 	case Arrsel: | ||||
| 		return chk_designator(expp, DESIGNATOR|VARIABLE, D_USED); | ||||
| 
 | ||||
| 	case Oper: | ||||
| 		return	chk_oper(expp); | ||||
| 
 | ||||
| 	case Arrow: | ||||
| 		return chk_designator(expp, DESIGNATOR|VARIABLE, D_USED); | ||||
| 
 | ||||
| 	case Uoper: | ||||
| 		return	chk_uoper(expp); | ||||
| 
 | ||||
| 	case Value: | ||||
| 		switch(expp->nd_symb) { | ||||
| 		case REAL: | ||||
| 		case STRING: | ||||
| 		case INTEGER: | ||||
| 			return 1; | ||||
| 
 | ||||
| 		default: | ||||
| 			crash("(chk_expr(Value))"); | ||||
| 		} | ||||
| 		break; | ||||
| 
 | ||||
| 	case Xset: | ||||
| 		return chk_set(expp); | ||||
| 
 | ||||
| 	case Link: | ||||
| 	case Name: | ||||
| 		if (chk_designator(expp, VALUE|DESIGNATOR, D_USED)) { | ||||
| 			if (expp->nd_class == Def && | ||||
| 			    expp->nd_def->df_kind == D_PROCEDURE) { | ||||
| 				/* Check that this procedure is one that we
 | ||||
| 				   may take the address from. | ||||
| 				*/ | ||||
| 				if (expp->nd_def->df_type == std_type) { | ||||
| 					/* Standard procedure. Illegal */ | ||||
| node_error(expp, "address of standard procedure taken"); | ||||
| 					return 0; | ||||
| 				} | ||||
| 				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"); | ||||
| 					return 0; | ||||
| 				} | ||||
| 			} | ||||
| 			return 1; | ||||
| 		} | ||||
| 		return 0; | ||||
| 
 | ||||
| 	case Call: | ||||
| 		return chk_call(expp); | ||||
| STATIC int | ||||
| chk_value(expp) | ||||
| 	struct node *expp; | ||||
| { | ||||
| 	switch(expp->nd_symb) { | ||||
| 	case REAL: | ||||
| 	case STRING: | ||||
| 	case INTEGER: | ||||
| 		return 1; | ||||
| 
 | ||||
| 	default: | ||||
| 		crash("(chk_expr)"); | ||||
| 		crash("(chk_value)"); | ||||
| 	} | ||||
| 	/*NOTREACHED*/ | ||||
| } | ||||
| 
 | ||||
| int | ||||
| STATIC int | ||||
| chk_linkorname(expp) | ||||
| 	register struct node *expp; | ||||
| { | ||||
| 	if (chk_designator(expp, VALUE|DESIGNATOR, D_USED)) { | ||||
| 		if (expp->nd_class == Def && | ||||
| 		    expp->nd_def->df_kind == D_PROCEDURE) { | ||||
| 			/* Check that this procedure is one that we
 | ||||
| 			   may take the address from. | ||||
| 			*/ | ||||
| 			if (expp->nd_def->df_type == std_type || | ||||
| 			    expp->nd_def->df_scope->sc_level > 0) { | ||||
| 				/* Address of standard or nested procedure
 | ||||
| 				   taken. | ||||
| 				*/ | ||||
| node_error(expp, "it is illegal to take the address of a standard or local procedure"); | ||||
| 				return 0; | ||||
| 			} | ||||
| 		} | ||||
| 		return 1; | ||||
| 	} | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| 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) | ||||
| 	register struct node *expp; | ||||
| { | ||||
|  | @ -174,126 +243,49 @@ node_error(expp, "specifier does not represent a set type"); | |||
| 	return 1; | ||||
| } | ||||
| 
 | ||||
| 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 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 * | ||||
| STATIC struct node * | ||||
| getarg(argp, bases, designator) | ||||
| 	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; | ||||
| 	register struct node *arg = *argp; | ||||
| 	register struct node *left; | ||||
| 
 | ||||
| 	if (!arg->nd_right) { | ||||
| 	if (! arg->nd_right) { | ||||
| 		node_error(arg, "too few arguments supplied"); | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
| 	arg = arg->nd_right; | ||||
| 	if ((!designator && !chk_expr(arg->nd_left)) || | ||||
| 	    (designator && !chk_designator(arg->nd_left, DESIGNATOR, D_REFERRED))) { | ||||
| 	left = arg->nd_left; | ||||
| 
 | ||||
| 	if ((!designator && !chk_expr(left)) || | ||||
| 	    (designator && | ||||
| 	     !chk_designator(left, DESIGNATOR|VARIABLE, D_USED|D_NOREG))) { | ||||
| 		return 0; | ||||
| 	} | ||||
| 	tp = arg->nd_left->nd_type; | ||||
| 
 | ||||
| 	tp = left->nd_type; | ||||
| 	if (tp->tp_fund == T_SUBRANGE) tp = tp->next; | ||||
| 
 | ||||
| 	if (bases && !(tp->tp_fund & bases)) { | ||||
| 		node_error(arg, "unexpected type"); | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
| 	*argp = arg; | ||||
| 	return arg->nd_left; | ||||
| 	return left; | ||||
| } | ||||
| 
 | ||||
| struct node * | ||||
| STATIC struct node * | ||||
| getname(argp, kinds) | ||||
| 	struct node **argp; | ||||
| { | ||||
|  | @ -303,10 +295,11 @@ getname(argp, kinds) | |||
| 		node_error(arg, "too few arguments supplied"); | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
| 	arg = arg->nd_right; | ||||
| 	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)) { | ||||
| 		node_error(arg, "unexpected type"); | ||||
|  | @ -317,6 +310,42 @@ getname(argp, kinds) | |||
| 	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 | ||||
| chk_call(expp) | ||||
| 	register struct node *expp; | ||||
|  | @ -358,58 +387,7 @@ chk_call(expp) | |||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| chk_proccall(expp) | ||||
| 	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 | ||||
| STATIC int | ||||
| FlagCheck(expp, df, flag) | ||||
| 	struct node *expp; | ||||
| 	struct def *df; | ||||
|  | @ -461,7 +439,6 @@ chk_designator(expp, flag, dflags) | |||
| 	*/ | ||||
| 	register struct def *df; | ||||
| 	register struct type *tp; | ||||
| 	struct def *lookfor(); | ||||
| 
 | ||||
| 	expp->nd_type = error_type; | ||||
| 
 | ||||
|  | @ -469,23 +446,20 @@ chk_designator(expp, flag, dflags) | |||
| 		expp->nd_def = lookfor(expp, CurrVis, 1); | ||||
| 		expp->nd_class = Def; | ||||
| 		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 == '.'); | ||||
| 
 | ||||
| 		if (! chk_designator(expp->nd_left, | ||||
| 				     flag|HASSELECTORS, | ||||
| 				     dflags|D_NOREG)) return 0; | ||||
| 
 | ||||
| 		tp = expp->nd_left->nd_type; | ||||
| 		if (! chk_designator(left, | ||||
| 				     (flag&DESIGNATOR)|HASSELECTORS, | ||||
| 				     dflags)) return 0; | ||||
| 
 | ||||
| 		tp = left->nd_type; | ||||
| 		assert(tp->tp_fund == T_RECORD); | ||||
| 
 | ||||
| 		df = lookup(expp->nd_IDF, tp->rec_scope); | ||||
| 
 | ||||
| 		if (!df) { | ||||
| 		if (!(df = lookup(expp->nd_IDF, tp->rec_scope))) { | ||||
| 			id_not_declared(expp); | ||||
| 			return 0; | ||||
| 		} | ||||
|  | @ -493,17 +467,19 @@ chk_designator(expp, flag, dflags) | |||
| 			expp->nd_def = df; | ||||
| 			expp->nd_type = df->df_type; | ||||
| 			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", | ||||
| df->df_idf->id_text); | ||||
| 				return 0; | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		if (expp->nd_left->nd_class == Def && | ||||
| 		    expp->nd_left->nd_def->df_kind == D_MODULE) { | ||||
| 		if (left->nd_class == Def && | ||||
| 		    left->nd_def->df_kind == D_MODULE) { | ||||
| 			expp->nd_class = Def; | ||||
| 			expp->nd_def = df; | ||||
| 			FreeNode(expp->nd_left); | ||||
| 			FreeNode(left); | ||||
| 			expp->nd_left = 0; | ||||
| 		} | ||||
| 		else { | ||||
|  | @ -548,12 +524,12 @@ df->df_idf->id_text); | |||
| 		assert(expp->nd_symb == '['); | ||||
| 
 | ||||
| 		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) | ||||
| 		   || | ||||
| 		    	expp->nd_left->nd_type == error_type | ||||
| 		   ) return 0; | ||||
| 		     expp->nd_left->nd_type == error_type | ||||
| 		   )	return 0; | ||||
| 
 | ||||
| 		tpr = expp->nd_right->nd_type; | ||||
| 		tpl = expp->nd_left->nd_type; | ||||
|  | @ -598,7 +574,7 @@ symbol2str(expp->nd_symb)); | |||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| struct type * | ||||
| STATIC struct type * | ||||
| ResultOfOperation(operator, tp) | ||||
| 	struct type *tp; | ||||
| { | ||||
|  | @ -616,13 +592,13 @@ ResultOfOperation(operator, tp) | |||
| 	return tp; | ||||
| } | ||||
| 
 | ||||
| int | ||||
| STATIC int | ||||
| Boolean(operator) | ||||
| { | ||||
| 	return operator == OR || operator == AND || operator == '&'; | ||||
| } | ||||
| 
 | ||||
| int | ||||
| STATIC int | ||||
| AllowedTypes(operator) | ||||
| { | ||||
| 	switch(operator) { | ||||
|  | @ -654,7 +630,23 @@ AllowedTypes(operator) | |||
| 	/*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) | ||||
| 	register struct node *expp; | ||||
| { | ||||
|  | @ -741,23 +733,7 @@ node_error(expp,"operator \"%s\": illegal operand type(s)", symbol2str(expp->nd_ | |||
| 	return 1; | ||||
| } | ||||
| 
 | ||||
| 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 | ||||
| STATIC int | ||||
| chk_uoper(expp) | ||||
| 	register struct node *expp; | ||||
| { | ||||
|  | @ -826,7 +802,7 @@ chk_uoper(expp) | |||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| struct node * | ||||
| STATIC struct node * | ||||
| getvariable(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_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; | ||||
| 		cstcall(expp,std); | ||||
| 		break; | ||||
|  | @ -1072,7 +1052,8 @@ TryToString(nd, tp) | |||
| 	struct node *nd; | ||||
| 	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) { | ||||
| 		int ch = nd->nd_INT; | ||||
| 
 | ||||
|  | @ -1084,3 +1065,20 @@ TryToString(nd, tp) | |||
| 		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; | ||||
| 
 | ||||
| 	case Uoper: | ||||
| 		CodePExpr(nd->nd_right); | ||||
| 		CodeUoper(nd); | ||||
| 		ds->dsg_kind = DSG_LOADED; | ||||
| 		break; | ||||
|  | @ -194,9 +193,9 @@ CodeCoercion(t1, t2) | |||
| { | ||||
| 	register int fund1, fund2; | ||||
| 
 | ||||
| 	if (t1 == t2) return; | ||||
| 	if (t1->tp_fund == T_SUBRANGE) t1 = t1->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 ((fund2 = t2->tp_fund) == T_WORD) fund2 = T_INTEGER; | ||||
| 	switch(fund1) { | ||||
|  | @ -291,9 +290,6 @@ CodeCall(nd) | |||
| 		and result is already done. | ||||
| 	*/ | ||||
| 	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) { | ||||
| 		CodeStd(nd); | ||||
|  | @ -311,49 +307,10 @@ CodeCall(nd) | |||
| 
 | ||||
| 	assert(IsProcCall(left)); | ||||
| 
 | ||||
| 	for (param = left->nd_type->prc_params; param; param = param->next) { | ||||
| 		tp = TypeOfParam(param); | ||||
| 		arg = arg->nd_right; | ||||
| 		assert(arg != 0); | ||||
| 		left = arg->nd_left; | ||||
| 		if (IsConformantArray(tp)) { | ||||
| 			C_loc(tp->arr_elsize); | ||||
| 			if (IsConformantArray(left->nd_type)) { | ||||
| 				DoHIGH(left); | ||||
| 			} | ||||
| 			else if (left->nd_symb == STRING) { | ||||
| 				C_loc(left->nd_SLE); | ||||
| 			} | ||||
| 			else if (tp->arr_elem == word_type) { | ||||
| 				C_loc(left->nd_type->tp_size / word_size - 1); | ||||
| 			} | ||||
| 			else { | ||||
| 				tp = left->nd_type->next; | ||||
| 				if (tp->tp_fund == T_SUBRANGE) { | ||||
| 					C_loc(tp->sub_ub - tp->sub_lb); | ||||
| 				} | ||||
| 				else	C_loc((arith) (tp->enm_ncst - 1)); | ||||
| 			} | ||||
| 			C_loc((arith) 0); | ||||
| 			if (left->nd_symb == STRING) { | ||||
| 				CodeString(left); | ||||
| 			} | ||||
| 			else	CodeDAddress(left); | ||||
| 		} | ||||
| 		else if (IsVarParam(param)) { | ||||
| 			CodeDAddress(left); | ||||
| 		} | ||||
| 		else { | ||||
| 			if (left->nd_type->tp_fund == T_STRING) { | ||||
| 				CodePadString(left, tp->tp_size); | ||||
| 			} | ||||
| 			else CodePExpr(left); | ||||
| 			CheckAssign(left->nd_type, tp); | ||||
| 		} | ||||
| 	if (nd->nd_right) { | ||||
| 		CodeParameters(left->nd_type->prc_params, nd->nd_right); | ||||
| 	} | ||||
| 
 | ||||
| 	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); | ||||
|  | @ -373,6 +330,63 @@ CodeCall(nd) | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| 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); | ||||
| 	left = arg->nd_left; | ||||
| 	if (IsConformantArray(tp)) { | ||||
| 		C_loc(tp->arr_elsize); | ||||
| 		if (IsConformantArray(left->nd_type)) { | ||||
| 			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) { | ||||
| 			C_loc(left->nd_SLE); | ||||
| 		} | ||||
| 		else if (tp->arr_elem == word_type) { | ||||
| 			C_loc(left->nd_type->tp_size / word_size - 1); | ||||
| 		} | ||||
| 		else { | ||||
| 			tp = left->nd_type->next; | ||||
| 			if (tp->tp_fund == T_SUBRANGE) { | ||||
| 				C_loc(tp->sub_ub - tp->sub_lb); | ||||
| 			} | ||||
| 			else	C_loc((arith) (tp->enm_ncst - 1)); | ||||
| 		} | ||||
| 		C_loc((arith) 0); | ||||
| 		if (left->nd_symb == STRING) { | ||||
| 			CodeString(left); | ||||
| 		} | ||||
| 		else	CodeDAddress(left); | ||||
| 	} | ||||
| 	else if (IsVarParam(param)) { | ||||
| 		CodeDAddress(left); | ||||
| 	} | ||||
| 	else { | ||||
| 		if (left->nd_type->tp_fund == T_STRING) { | ||||
| 			CodePadString(left, tp->tp_size); | ||||
| 		} | ||||
| 		else CodePExpr(left); | ||||
| 		CheckAssign(left->nd_type, tp); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| CodeStd(nd) | ||||
| 	struct node *nd; | ||||
| { | ||||
|  | @ -387,7 +401,6 @@ CodeStd(nd) | |||
| 		if (tp->tp_fund == T_SUBRANGE) tp = tp->next; | ||||
| 		arg = arg->nd_right; | ||||
| 	} | ||||
| 	Desig = InitDesig; | ||||
| 
 | ||||
| 	switch(std = nd->nd_left->nd_def->df_value.df_stdname) { | ||||
| 	case S_ABS: | ||||
|  | @ -546,14 +559,12 @@ CheckAssign(tpl, tpr) | |||
| 	*/ | ||||
| 
 | ||||
| 	arith llo, lhi, rlo, rhi; | ||||
| 	label l = 0; | ||||
| 	extern label getrck(); | ||||
| 
 | ||||
| 	if (bounded(tpl)) { | ||||
| 		/* in this case we might need a range check */ | ||||
| 		if (!bounded(tpr)) { | ||||
| 			/* yes, we need one */ | ||||
| 			l = getrck(tpl); | ||||
| 			genrck(tpl); | ||||
| 		} | ||||
| 		else { | ||||
| 			/* both types are restricted. check the bounds
 | ||||
|  | @ -562,14 +573,9 @@ CheckAssign(tpl, tpr) | |||
| 			getbounds(tpl, &llo, &lhi); | ||||
| 			getbounds(tpr, &rlo, &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; | ||||
| 
 | ||||
| 	CodePExpr(nd->nd_right); | ||||
| 	switch(nd->nd_symb) { | ||||
| 	case '~': | ||||
| 	case NOT: | ||||
|  |  | |||
|  | @ -461,7 +461,6 @@ PointerType(struct type **ptp;) | |||
| { | ||||
| 	struct type *tp; | ||||
| 	struct def *df; | ||||
| 	struct def *lookfor(); | ||||
| 	struct node *nd; | ||||
| } : | ||||
| 	POINTER TO | ||||
|  |  | |||
|  | @ -117,7 +117,11 @@ struct def	{		/* list of definitions for a name */ | |||
| 
 | ||||
| extern struct def | ||||
| 	*define(), | ||||
| 	*lookup(), | ||||
| 	*DefineLocalModule(), | ||||
| 	*MkDef(), | ||||
| 	*ill_df; | ||||
| 
 | ||||
| extern struct def | ||||
| 	*lookup(), | ||||
| 	*lookfor(); | ||||
| #define NULLDEF ((struct def *) 0) | ||||
|  |  | |||
|  | @ -203,7 +203,7 @@ DeclProc(type) | |||
| 		df->for_node = MkLeaf(Name, &dot); | ||||
| 		sprint(buf,"%s_%s",CurrentScope->sc_name,df->df_idf->id_text); | ||||
| 		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); | ||||
| 	} | ||||
| 	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 | ||||
| PrDef(df) | ||||
| 	register struct def *df; | ||||
|  |  | |||
|  | @ -25,7 +25,6 @@ static char *RcsId = "$Header$"; | |||
| #include	"node.h" | ||||
| 
 | ||||
| extern int	proclevel; | ||||
| struct desig	Desig; | ||||
| struct desig	InitDesig = {DSG_INIT, 0, 0}; | ||||
| 
 | ||||
| CodeValue(ds, size) | ||||
|  | @ -225,6 +224,7 @@ CodeVarDesig(df, ds) | |||
| 	*/ | ||||
| 	assert(ds->dsg_kind == DSG_INIT); | ||||
| 
 | ||||
| 	df->df_flags |= D_USED; | ||||
| 	if (df->var_addrgiven) { | ||||
| 		/* the programmer specified an address in the declaration of
 | ||||
| 		   the variable. Generate code to push the address. | ||||
|  | @ -232,7 +232,6 @@ CodeVarDesig(df, ds) | |||
| 		CodeConst(df->var_off, pointer_size); | ||||
| 		ds->dsg_kind = DSG_PLOADED; | ||||
| 		ds->dsg_offset = 0; | ||||
| 		df->df_flags |= D_NOREG; | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -243,7 +242,6 @@ CodeVarDesig(df, ds) | |||
| 		ds->dsg_name = df->var_name; | ||||
| 		ds->dsg_offset = 0; | ||||
| 		ds->dsg_kind = DSG_FIXED; | ||||
| 		df->df_flags |= D_NOREG; | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -251,6 +249,8 @@ CodeVarDesig(df, ds) | |||
| 		/* the variable is local to a statically enclosing procedure.
 | ||||
| 		*/ | ||||
| 		assert(proclevel > sc->sc_level); | ||||
| 
 | ||||
| 		df->df_flags |= D_NOREG; | ||||
| 		if (df->df_flags & (D_VARPAR|D_VALPAR)) { | ||||
| 			/* value or var parameter
 | ||||
| 			*/ | ||||
|  | @ -269,7 +269,6 @@ CodeVarDesig(df, ds) | |||
| 		else	C_lxl((arith) (proclevel - sc->sc_level)); | ||||
| 		ds->dsg_kind = DSG_PLOADED; | ||||
| 		ds->dsg_offset = df->var_off; | ||||
| 		df->df_flags |= D_NOREG; | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
|  |  | |||
|  | @ -50,6 +50,6 @@ struct withdesig { | |||
| }; | ||||
| 
 | ||||
| extern struct withdesig	*WithDesigs; | ||||
| extern struct desig	Desig, InitDesig; | ||||
| extern struct desig	InitDesig; | ||||
| 
 | ||||
| #define NO_LABEL	((label) 0) | ||||
|  |  | |||
|  | @ -116,6 +116,7 @@ EnterVarList(Idlist, type, local) | |||
| 			/* An address was supplied
 | ||||
| 			*/ | ||||
| 			df->var_addrgiven = 1; | ||||
| 			df->df_flags |= D_NOREG; | ||||
| 			if (idlist->nd_left->nd_type != card_type) { | ||||
| node_error(idlist->nd_left,"Illegal type for address"); | ||||
| 			} | ||||
|  | @ -137,9 +138,12 @@ node_error(idlist->nd_left,"Illegal type for address"); | |||
| 			sprint(buf,"%s_%s", sc->sc_scope->sc_name, | ||||
| 					    df->df_idf->id_text); | ||||
| 			df->var_name = Salloc(buf, (unsigned)(strlen(buf)+1)); | ||||
| 			df->df_flags |= D_NOREG; | ||||
| 
 | ||||
|  			if (DefinitionModule) { | ||||
| 				C_exa_dnam(df->var_name); | ||||
| 				if (sc == Defined->mod_vis) { | ||||
| 					C_exa_dnam(df->var_name); | ||||
| 				} | ||||
| 			} | ||||
| 			else { | ||||
| 				C_ina_dnam(df->var_name); | ||||
|  | @ -163,11 +167,16 @@ EnterParamList(ppr, Idlist, type, VARp, off) | |||
| 	register struct paramlist *pr; | ||||
| 	register struct def *df; | ||||
| 	register struct node *idlist = Idlist; | ||||
| 	static struct paramlist *last; | ||||
| 
 | ||||
| 	for ( ; idlist; idlist = idlist->next) { | ||||
| 		pr = new_paramlist(); | ||||
| 		pr->next = *ppr; | ||||
| 		*ppr = pr; | ||||
| 		pr->next = 0; | ||||
| 		if (!*ppr) { | ||||
| 			*ppr = pr; | ||||
| 		} | ||||
| 		else	last->next = pr; | ||||
| 		last = pr; | ||||
| 		df = define(idlist->nd_IDF, CurrentScope, D_VARIABLE); | ||||
| 		pr->par_def = df; | ||||
| 		df->df_type = type; | ||||
|  | @ -188,7 +197,7 @@ EnterParamList(ppr, Idlist, type, VARp, off) | |||
| 	FreeNode(Idlist); | ||||
| } | ||||
| 
 | ||||
| static | ||||
| STATIC | ||||
| DoImport(df, scope) | ||||
| 	register struct def *df; | ||||
| 	struct scope *scope; | ||||
|  | @ -222,7 +231,7 @@ DoImport(df, scope) | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| static struct scopelist * | ||||
| STATIC struct scopelist * | ||||
| ForwModule(df, idn) | ||||
| 	register struct def *df; | ||||
| 	struct node *idn; | ||||
|  | @ -248,7 +257,7 @@ ForwModule(df, idn) | |||
| 	return vis; | ||||
| } | ||||
| 
 | ||||
| static struct def * | ||||
| STATIC struct def * | ||||
| ForwDef(ids, scope) | ||||
| 	register struct node *ids; | ||||
| 	struct scope *scope; | ||||
|  | @ -351,7 +360,7 @@ EnterFromImportList(Idlist, Fromid, local) | |||
| 	register struct def *df; | ||||
| 	struct scopelist *vis = enclosing(CurrVis); | ||||
| 	int forwflag = 0; | ||||
| 	extern struct def *lookfor(), *GetDefinitionModule(); | ||||
| 	extern struct def *GetDefinitionModule(); | ||||
| 
 | ||||
| 	if (local) { | ||||
| 		df = lookfor(Fromid, vis, 0); | ||||
|  | @ -412,7 +421,7 @@ EnterImportList(Idlist, local) | |||
| 	register struct node *idlist = Idlist; | ||||
| 	register struct def *df; | ||||
| 	struct scopelist *vis = enclosing(CurrVis); | ||||
| 	extern struct def *lookfor(), *GetDefinitionModule(); | ||||
| 	extern struct def *GetDefinitionModule(); | ||||
| 
 | ||||
| 	for (; idlist; idlist = idlist->next) { | ||||
| 		if (local) df = ForwDef(idlist, vis->sc_scope); | ||||
|  |  | |||
|  | @ -18,19 +18,17 @@ static char *RcsId = "$Header$"; | |||
| #include	"node.h" | ||||
| #include	"const.h" | ||||
| #include	"type.h" | ||||
| #include	"chk_expr.h" | ||||
| } | ||||
| 
 | ||||
| number(struct node **p;) | ||||
| { | ||||
| 	struct type *tp; | ||||
| } : | ||||
| number(struct node **p;) : | ||||
| [ | ||||
| 	%default | ||||
| 	INTEGER		{ tp = toktype; } | ||||
| 	INTEGER | ||||
| | | ||||
| 	REAL		{ tp = real_type; } | ||||
| 	REAL | ||||
| ]			{ *p = MkLeaf(Value, &dot); | ||||
| 			  (*p)->nd_type = tp; | ||||
| 			  (*p)->nd_type = toktype; | ||||
| 			} | ||||
| ; | ||||
| 
 | ||||
|  |  | |||
|  | @ -16,8 +16,6 @@ static char *RcsId = "$Header$"; | |||
| #include	"LLlex.h" | ||||
| #include	"node.h" | ||||
| 
 | ||||
| extern struct def	*MkDef(); | ||||
| 
 | ||||
| struct def * | ||||
| lookup(id, scope) | ||||
| 	register struct idf *id; | ||||
|  |  | |||
|  | @ -15,7 +15,7 @@ static char *RcsId = "$Header$"; | |||
| #include	"node.h" | ||||
| 
 | ||||
| match_id(id1, id2) | ||||
| 	struct idf *id1, *id2; | ||||
| 	register 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 | ||||
|  | @ -45,7 +45,7 @@ gen_anon_idf() | |||
| } | ||||
| 
 | ||||
| id_not_declared(id) | ||||
| 	struct node *id; | ||||
| 	register struct node *id; | ||||
| { | ||||
| 	/*	The identifier "id" is not declared. If it is not generated,
 | ||||
| 		give an error message | ||||
|  |  | |||
|  | @ -19,6 +19,7 @@ struct node { | |||
| #define Def	9		/* an identified name */ | ||||
| #define Stat	10		/* a statement */ | ||||
| #define Link	11 | ||||
| 				/* do NOT change the order or the numbers!!! */ | ||||
| 	struct type *nd_type;	/* type of this node */ | ||||
| 	struct token nd_token; | ||||
| #define nd_set		nd_token.tk_data.tk_set | ||||
|  |  | |||
|  | @ -64,11 +64,17 @@ FreeNode(nd) | |||
| 	free_node(nd); | ||||
| } | ||||
| 
 | ||||
| NodeCrash(expp) | ||||
| 	struct node *expp; | ||||
| { | ||||
| 	crash("Illegal node %d", expp->nd_class); | ||||
| } | ||||
| 
 | ||||
| #ifdef DEBUG | ||||
| 
 | ||||
| extern char *symbol2str(); | ||||
| 
 | ||||
| static | ||||
| STATIC | ||||
| printnode(nd) | ||||
| 	register struct node *nd; | ||||
| { | ||||
|  |  | |||
|  | @ -42,36 +42,13 @@ static  char *RcsId = "$Header$"; | |||
| ModuleDeclaration | ||||
| { | ||||
| 	struct idf *id; | ||||
| 	register struct def *df; | ||||
| 	extern int proclevel; | ||||
| 	static int modulecount = 0; | ||||
| 	char buf[256]; | ||||
| 	struct def *df; | ||||
| 	struct node *nd; | ||||
| 	struct node *exportlist = 0; | ||||
| 	int qualified; | ||||
| 	extern char *sprint(); | ||||
| } : | ||||
| 	MODULE IDENT	{ | ||||
| 			  id = dot.TOK_IDF; | ||||
| 			  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); | ||||
| 	MODULE IDENT	{ id = dot.TOK_IDF; | ||||
| 			  df = DefineLocalModule(id); | ||||
| 			} | ||||
| 	priority(&(df->mod_priority))? | ||||
| 	';' | ||||
|  | @ -92,7 +69,7 @@ priority(arith *pprio;) | |||
| 	struct node *nd; | ||||
| } : | ||||
| 	'[' ConstExpression(&nd) ']' | ||||
| 			{ if (!(nd->nd_type->tp_fund & T_INTORCARD)) { | ||||
| 			{ if (!(nd->nd_type->tp_fund & T_CARDINAL)) { | ||||
| 				node_error(nd, "Illegal priority"); | ||||
| 			  } | ||||
| 			  *pprio = nd->nd_INT; | ||||
|  | @ -141,13 +118,12 @@ DefinitionModule | |||
| 	int dummy; | ||||
| } : | ||||
| 	DEFINITION | ||||
| 	MODULE IDENT	{  | ||||
| 			  id = dot.TOK_IDF; | ||||
| 	MODULE IDENT	{ id = dot.TOK_IDF; | ||||
| 			  df = define(id, GlobalScope, D_MODULE); | ||||
| 			  if (!SYSTEMModule) open_scope(CLOSEDSCOPE); | ||||
| 			  if (!Defined) Defined = df; | ||||
| 			  df->mod_vis = CurrVis; | ||||
| 			  if (!SYSTEMModule) open_scope(CLOSEDSCOPE); | ||||
| 			  CurrentScope->sc_name = id->id_text; | ||||
| 			  df->mod_vis = CurrVis; | ||||
| 			  df->df_type = standard_type(T_RECORD, 0, (arith) 0); | ||||
| 			  df->df_type->rec_scope = df->mod_vis->sc_scope; | ||||
| 			  DefinitionModule++; | ||||
|  | @ -222,8 +198,7 @@ ProgramModule | |||
| 	struct node *nd; | ||||
| } : | ||||
| 	MODULE | ||||
| 	IDENT	{  | ||||
| 		  id = dot.TOK_IDF; | ||||
| 	IDENT	{ id = dot.TOK_IDF; | ||||
| 		  if (state == IMPLEMENTATION) { | ||||
| 			df = GetDefinitionModule(id); | ||||
| 			CurrVis = df->mod_vis; | ||||
|  | @ -232,11 +207,11 @@ ProgramModule | |||
| 		  } | ||||
| 		  else { | ||||
| 			df = define(id, CurrentScope, D_MODULE); | ||||
| 		  	Defined = df; | ||||
| 			open_scope(CLOSEDSCOPE); | ||||
| 			df->mod_vis = CurrVis; | ||||
| 			CurrentScope->sc_name = id->id_text; | ||||
| 		  } | ||||
| 		  Defined = df; | ||||
| 		  CurrentScope->sc_definedby = df; | ||||
| 		} | ||||
| 	priority(&(df->mod_priority))? | ||||
|  |  | |||
|  | @ -90,7 +90,7 @@ Forward(tk, ptp) | |||
| 	CurrentScope->sc_forw = f; | ||||
| } | ||||
| 
 | ||||
| static | ||||
| STATIC | ||||
| chk_proc(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) | ||||
| 	register struct def **pdf; | ||||
| { | ||||
|  | @ -153,7 +153,7 @@ node_error((*pdf)->for_node, "identifier \"%s\" has not been declared", | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| static | ||||
| STATIC | ||||
| rem_forwards(fo) | ||||
| 	struct forwards *fo; | ||||
| { | ||||
|  | @ -161,7 +161,6 @@ rem_forwards(fo) | |||
| 	*/ | ||||
| 	register struct forwards *f; | ||||
| 	register struct def *df; | ||||
| 	struct def *lookfor(); | ||||
| 
 | ||||
| 	while (f = fo) { | ||||
| 		df = lookfor(&(f->fo_tok), CurrVis, 1); | ||||
|  | @ -181,11 +180,10 @@ Reverse(pdf) | |||
| 	/*	Reverse the order in the list of definitions in a scope.
 | ||||
| 		This is neccesary because this list is built in reverse. | ||||
| 		Also, while we're at it, remove uninteresting definitions | ||||
| 		from this list. The only interesting definitions are: | ||||
| 		D_MODULE, D_PROCEDURE, and D_PROCHEAD. | ||||
| 		from this list. | ||||
| 	*/ | ||||
| 	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; | ||||
| 	df1 = *pdf; | ||||
|  | @ -217,7 +215,6 @@ close_scope(flag) | |||
| 	register struct scope *sc = CurrentScope; | ||||
| 
 | ||||
| 	assert(sc != 0); | ||||
| 	DO_DEBUG(1, debug("Closing a scope")); | ||||
| 
 | ||||
| 	if (flag) { | ||||
| 		if (sc->sc_forw) rem_forwards(sc->sc_forw); | ||||
|  |  | |||
|  | @ -83,13 +83,17 @@ ProcedureCall: | |||
| 
 | ||||
| StatementSequence(register struct node **pnd;) | ||||
| { | ||||
| 	struct node *nd; | ||||
| } : | ||||
| 	statement(pnd) | ||||
| 	[ | ||||
| 		';'	{ *pnd = MkNode(Link, *pnd, NULLNODE, &dot); | ||||
| 			  pnd = &((*pnd)->nd_right); | ||||
| 		';' statement(&nd) | ||||
| 			{ if (nd) { | ||||
| 				*pnd = MkNode(Link, *pnd, nd, &dot); | ||||
| 				(*pnd)->nd_symb = ';'; | ||||
| 			  	pnd = &((*pnd)->nd_right); | ||||
| 			  } | ||||
| 			} | ||||
| 		statement(pnd) | ||||
| 	]* | ||||
| ; | ||||
| 
 | ||||
|  |  | |||
|  | @ -21,9 +21,6 @@ static char *RcsId = "$Header$"; | |||
| #include	"const.h" | ||||
| #include	"scope.h" | ||||
| 
 | ||||
| /*	To be created dynamically in main() from defaults or from command
 | ||||
| 	line parameters. | ||||
| */ | ||||
| int | ||||
| 	word_align = AL_WORD, | ||||
| 	int_align = AL_INT, | ||||
|  | @ -96,38 +93,34 @@ construct_type(fund, tp) | |||
| 
 | ||||
| 	switch (fund)	{ | ||||
| 	case T_PROCEDURE: | ||||
| 		if (tp && !returntype(tp)) { | ||||
| 			error("illegal procedure result type"); | ||||
| 		} | ||||
| 		/* Fall through */ | ||||
| 	case T_POINTER: | ||||
| 	case T_HIDDEN: | ||||
| 		dtp->tp_align = pointer_align; | ||||
| 		dtp->tp_size = pointer_size; | ||||
| 		dtp->next = tp; | ||||
| 		if (fund == T_PROCEDURE && tp) { | ||||
| 			if (! returntype(tp)) { | ||||
| 				error("illegal procedure result type"); | ||||
| 			} | ||||
| 		} | ||||
| 		break; | ||||
| 
 | ||||
| 	case T_SET: | ||||
| 		dtp->tp_align = word_align; | ||||
| 		dtp->next = tp; | ||||
| 		break; | ||||
| 
 | ||||
| 	case T_ARRAY: | ||||
| 		dtp->tp_align = tp->tp_align; | ||||
| 		dtp->next = tp; | ||||
| 		break; | ||||
| 
 | ||||
| 	case T_SUBRANGE: | ||||
| 		dtp->tp_align = tp->tp_align; | ||||
| 		dtp->tp_size = tp->tp_size; | ||||
| 		dtp->next = tp; | ||||
| 		break; | ||||
| 
 | ||||
| 	default: | ||||
| 		crash("funny type constructor"); | ||||
| 	} | ||||
| 
 | ||||
| 	dtp->next = tp; | ||||
| 	return dtp; | ||||
| } | ||||
| 
 | ||||
|  | @ -206,8 +199,11 @@ InitTypes() | |||
| 	address_type = construct_type(T_POINTER, word_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_ub = word_size * 8 - 1; | ||||
| 	bitset_type = set_type(tp); | ||||
|  | @ -229,7 +225,7 @@ chk_basesubrange(tp, base) | |||
| 
 | ||||
| 	if (base->tp_fund == T_SUBRANGE) { | ||||
| 		/* 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) { | ||||
| 			error("Base type has insufficient range"); | ||||
|  | @ -246,7 +242,7 @@ chk_basesubrange(tp, base) | |||
| 		error("Illegal base for a subrange"); | ||||
| 	} | ||||
| 	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"); | ||||
| 	} | ||||
| 	else if (base != tp->next && base != int_type) { | ||||
|  | @ -269,7 +265,7 @@ subr_type(lb, ub) | |||
| 	register struct type *tp = lb->nd_type, *res; | ||||
| 
 | ||||
| 	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; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -306,32 +302,33 @@ subr_type(lb, ub) | |||
| 	return res; | ||||
| } | ||||
| 
 | ||||
| label | ||||
| getrck(tp) | ||||
| genrck(tp) | ||||
| 	register struct type *tp; | ||||
| { | ||||
| 	/*	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->sub_rck == (label) 0) { | ||||
| 			tp->sub_rck = data_label(); | ||||
| 			C_df_dlb(tp->sub_rck); | ||||
| 			C_rom_cst(tp->sub_lb); | ||||
| 			C_rom_cst(tp->sub_ub); | ||||
| 		if (!(ol = tp->sub_rck)) { | ||||
| 			tp->sub_rck = l = data_label(); | ||||
| 		} | ||||
| 		return tp->sub_rck; | ||||
| 	} | ||||
| 	if (tp->enm_rck == (label) 0) { | ||||
| 		tp->enm_rck = data_label(); | ||||
| 		C_df_dlb(tp->enm_rck); | ||||
| 		C_rom_cst((arith) 0); | ||||
| 		C_rom_cst((arith) (tp->enm_ncst - 1)); | ||||
| 	else if (!(ol = tp->enm_rck)) { | ||||
| 		tp->enm_rck = l = data_label(); | ||||
| 	} | ||||
| 	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) | ||||
|  | @ -352,6 +349,7 @@ getbounds(tp, plo, phi) | |||
| 		*phi = tp->enm_ncst - 1; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| struct type * | ||||
| set_type(tp) | ||||
| 	register struct type *tp; | ||||
|  | @ -361,26 +359,20 @@ set_type(tp) | |||
| 	*/ | ||||
| 	arith lb, ub; | ||||
| 
 | ||||
| 	if (tp->tp_fund == T_SUBRANGE) { | ||||
| 		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 { | ||||
| 	if (! bounded(tp)) { | ||||
| 		error("illegal base type for set"); | ||||
| 		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->tp_size = WA(((ub - lb) + 7)/8); | ||||
| 	tp->tp_size = WA(((ub - lb) + 8)/8); | ||||
| 	return tp; | ||||
| } | ||||
| 
 | ||||
|  | @ -412,47 +404,30 @@ ArraySizes(tp) | |||
| 	*/ | ||||
| 	register struct type *index_type = tp->next; | ||||
| 	register struct type *elem_type = tp->arr_elem; | ||||
| 	arith lo, hi; | ||||
| 
 | ||||
| 	tp->arr_elsize = ArrayElSize(elem_type); | ||||
| 	tp->tp_align = elem_type->tp_align; | ||||
| 
 | ||||
| 	/* check index type
 | ||||
| 	*/ | ||||
| 	if (! (index_type->tp_fund & T_INDEX)) { | ||||
| 	if (! bounded(index_type)) { | ||||
| 		error("Illegal index type"); | ||||
| 		tp->tp_size = 0; | ||||
| 		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(); | ||||
| 	C_df_dlb(tp->arr_descr); | ||||
| 
 | ||||
| 	switch(index_type->tp_fund) { | ||||
| 	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(lo); | ||||
| 	C_rom_cst(hi - lo); | ||||
| 	C_rom_cst(tp->arr_elsize); | ||||
| 	tp->tp_size = WA(tp->tp_size); | ||||
| 
 | ||||
| 	/* ??? overflow checking ???
 | ||||
| 	*/ | ||||
| } | ||||
| 
 | ||||
| FreeType(tp) | ||||
|  |  | |||
|  | @ -12,6 +12,7 @@ static char *RcsId = "$Header$"; | |||
| 
 | ||||
| #include	<em_arith.h> | ||||
| #include	<em_label.h> | ||||
| #include	<em_reg.h> | ||||
| #include	<assert.h> | ||||
| 
 | ||||
| #include	"def.h" | ||||
|  | @ -24,6 +25,7 @@ static char *RcsId = "$Header$"; | |||
| #include	"desig.h" | ||||
| #include	"f_info.h" | ||||
| #include	"idf.h" | ||||
| #include	"chk_expr.h" | ||||
| 
 | ||||
| extern arith	NewPtr(); | ||||
| extern arith	NewInt(); | ||||
|  | @ -49,7 +51,7 @@ data_label() | |||
| 	return ++datalabel; | ||||
| } | ||||
| 
 | ||||
| static | ||||
| STATIC | ||||
| DoProfil() | ||||
| { | ||||
| 	static label	filename_label = 0; | ||||
|  | @ -119,16 +121,14 @@ WalkModule(module) | |||
| 		struct node *nd; | ||||
| 
 | ||||
| 		if (state == IMPLEMENTATION) { | ||||
| 			label l1 = data_label(), l2 = text_label(); | ||||
| 			label l1 = data_label(); | ||||
| 			/* we don't actually prevent recursive calls,
 | ||||
| 			   but do nothing if called recursively | ||||
| 			*/ | ||||
| 			C_df_dlb(l1); | ||||
| 			C_bss_cst(word_size, (arith) 0, 1); | ||||
| 			C_loe_dlb(l1, (arith) 0); | ||||
| 			C_zeq(l2); | ||||
| 			C_ret((arith) 0); | ||||
| 			C_df_ilb(l2); | ||||
| 			C_zne((label) 1); | ||||
| 			C_loc((arith) 1); | ||||
| 			C_ste_dlb(l1, (arith) 0); | ||||
| 		} | ||||
|  | @ -159,7 +159,8 @@ WalkProcedure(procedure) | |||
| 	*/ | ||||
| 	struct scopelist *vis = CurrVis; | ||||
| 	register struct scope *sc; | ||||
| 	register struct type *res_type; | ||||
| 	register struct type *tp; | ||||
| 	register struct paramlist *param; | ||||
| 
 | ||||
| 	proclevel++; | ||||
| 	CurrVis = procedure->prc_vis; | ||||
|  | @ -177,19 +178,20 @@ WalkProcedure(procedure) | |||
| 	MkCalls(sc->sc_def); | ||||
| 	return_expr_occurred = 0; | ||||
| 	instructionlabel = 2; | ||||
| 	func_type = res_type = procedure->df_type->next; | ||||
| 	if (! returntype(res_type)) { | ||||
| 	func_type = tp = procedure->df_type->next; | ||||
| 	if (! returntype(tp)) { | ||||
| 		node_error(procedure->prc_body, "illegal result type"); | ||||
| 	} | ||||
| 	WalkNode(procedure->prc_body, (label) 0); | ||||
| 	C_df_ilb((label) 1); | ||||
| 	if (res_type) { | ||||
| 	if (tp) { | ||||
| 		if (! return_expr_occurred) { | ||||
| 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); | ||||
| 	RegisterMessages(sc->sc_def); | ||||
| 	C_end(-sc->sc_off); | ||||
| 	TmpClose(); | ||||
| 	CurrVis = vis; | ||||
|  | @ -257,7 +259,6 @@ WalkStat(nd, lab) | |||
| 	*/ | ||||
| 	register struct node *left = nd->nd_left; | ||||
| 	register struct node *right = nd->nd_right; | ||||
| 	register struct desig *pds = &Desig; | ||||
| 
 | ||||
| 	if (!nd) { | ||||
| 		/* Empty statement
 | ||||
|  | @ -385,9 +386,10 @@ WalkStat(nd, lab) | |||
| 		{ | ||||
| 			struct scopelist link; | ||||
| 			struct withdesig wds; | ||||
| 			struct desig ds; | ||||
| 			arith tmp = 0; | ||||
| 
 | ||||
| 			WalkDesignator(left); | ||||
| 			WalkDesignator(left, &ds); | ||||
| 			if (left->nd_type->tp_fund != T_RECORD) { | ||||
| 				node_error(left, "record variable expected"); | ||||
| 				break; | ||||
|  | @ -396,19 +398,21 @@ WalkStat(nd, lab) | |||
| 			wds.w_next = WithDesigs; | ||||
| 			WithDesigs = &wds; | ||||
| 			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
 | ||||
| 				*/ | ||||
| 				CodeAddress(pds); | ||||
| 				pds->dsg_kind = DSG_FIXED; | ||||
| 				/* Only for the store ... */ | ||||
| 				pds->dsg_offset = tmp = NewPtr(); | ||||
| 				pds->dsg_name = 0; | ||||
| 				CodeStore(pds, pointer_size); | ||||
| 				pds->dsg_kind = DSG_PFIXED; | ||||
| 				CodeAddress(&ds); | ||||
| 				ds.dsg_kind = DSG_FIXED; | ||||
| 				/* Create a designator structure for the
 | ||||
| 				   temporary. | ||||
| 				*/ | ||||
| 				ds.dsg_offset = tmp = NewPtr(); | ||||
| 				ds.dsg_name = 0; | ||||
| 				CodeStore(&ds, pointer_size); | ||||
| 				ds.dsg_kind = DSG_PFIXED; | ||||
| 				/* the record is indirectly available */ | ||||
| 			} | ||||
| 			wds.w_desig = *pds; | ||||
| 			wds.w_desig = ds; | ||||
| 			link.sc_scope = wds.w_scope; | ||||
| 			link.next = CurrVis; | ||||
| 			CurrVis = &link; | ||||
|  | @ -439,7 +443,7 @@ node_error(right, "type incompatibility in RETURN statement"); | |||
| 		break; | ||||
| 
 | ||||
| 	default: | ||||
| 		assert(0); | ||||
| 		crash("(WalkStat)"); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
|  | @ -450,6 +454,7 @@ ExpectBool(nd, true_label, false_label) | |||
| 	/*	"nd" must indicate a boolean expression. Check this and
 | ||||
| 		generate code to evaluate the expression. | ||||
| 	*/ | ||||
| 	struct desig ds; | ||||
| 
 | ||||
| 	if (!chk_expr(nd)) return; | ||||
| 
 | ||||
|  | @ -457,8 +462,8 @@ ExpectBool(nd, true_label, false_label) | |||
| 		node_error(nd, "boolean expression expected"); | ||||
| 	} | ||||
| 
 | ||||
| 	Desig = InitDesig; | ||||
| 	CodeExpr(nd, &Desig,  true_label, false_label); | ||||
| 	ds = InitDesig; | ||||
| 	CodeExpr(nd, &ds,  true_label, false_label); | ||||
| } | ||||
| 
 | ||||
| WalkExpr(nd) | ||||
|  | @ -474,8 +479,9 @@ WalkExpr(nd) | |||
| 	CodePExpr(nd); | ||||
| } | ||||
| 
 | ||||
| WalkDesignator(nd) | ||||
| WalkDesignator(nd, ds) | ||||
| 	struct node *nd; | ||||
| 	struct desig *ds; | ||||
| { | ||||
| 	/*	Check designator and generate code for it
 | ||||
| 	*/ | ||||
|  | @ -484,8 +490,8 @@ WalkDesignator(nd) | |||
| 
 | ||||
| 	if (! chk_designator(nd, DESIGNATOR|VARIABLE, D_DEFINED)) return; | ||||
| 
 | ||||
| 	Desig = InitDesig; | ||||
| 	CodeDesig(nd, &Desig); | ||||
| 	*ds = InitDesig; | ||||
| 	CodeDesig(nd, ds); | ||||
| } | ||||
| 
 | ||||
| DoForInit(nd, left) | ||||
|  | @ -527,13 +533,13 @@ DoAssign(nd, left, right) | |||
| 	register struct node *left, *right; | ||||
| { | ||||
| 	/* May we do it in this order (expression first) ??? */ | ||||
| 	struct desig ds; | ||||
| 	struct desig dsl, dsr; | ||||
| 
 | ||||
| 	if (!chk_expr(right)) return; | ||||
| 	if (! chk_designator(left, DESIGNATOR|VARIABLE, D_DEFINED)) return; | ||||
| 	TryToString(right, left->nd_type); | ||||
| 	Desig = InitDesig; | ||||
| 	CodeExpr(right, &Desig, NO_LABEL, NO_LABEL); | ||||
| 	dsr = InitDesig; | ||||
| 	CodeExpr(right, &dsr, NO_LABEL, NO_LABEL); | ||||
| 
 | ||||
| 	if (! TstAssCompat(left->nd_type, right->nd_type)) { | ||||
| 		node_error(nd, "type incompatibility in assignment"); | ||||
|  | @ -541,17 +547,44 @@ DoAssign(nd, left, right) | |||
| 	} | ||||
| 
 | ||||
| 	if (complex(right->nd_type)) { | ||||
| 		CodeAddress(&Desig); | ||||
| 		CodeAddress(&dsr); | ||||
| 	} | ||||
| 	else { | ||||
| 		CodeValue(&Desig, right->nd_type->tp_size); | ||||
| 		CodeValue(&dsr, right->nd_type->tp_size); | ||||
| 		CheckAssign(left->nd_type, right->nd_type); | ||||
| 	} | ||||
| 	ds = Desig; | ||||
| 	Desig = InitDesig; | ||||
| 	CodeDesig(left, &Desig); | ||||
| 	dsl = InitDesig; | ||||
| 	CodeDesig(left, &dsl); | ||||
| 
 | ||||
| 	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 | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue