newer version
This commit is contained in:
		
							parent
							
								
									3de71150a6
								
							
						
					
					
						commit
						629b8fdb88
					
				
					 17 changed files with 543 additions and 170 deletions
				
			
		| 
						 | 
					@ -223,6 +223,7 @@ again:
 | 
				
			||||||
		register char *np = &buf[1];
 | 
							register char *np = &buf[1];
 | 
				
			||||||
					/* allow a '-' to be added	*/
 | 
										/* allow a '-' to be added	*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							buf[0] = '-';
 | 
				
			||||||
		*np++ = ch;
 | 
							*np++ = ch;
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
		LoadChar(ch);
 | 
							LoadChar(ch);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -18,7 +18,7 @@ LOBJ =	tokenfile.o program.o declar.o expression.o statement.o
 | 
				
			||||||
COBJ =	LLlex.o LLmessage.o char.o error.o main.o \
 | 
					COBJ =	LLlex.o LLmessage.o char.o error.o main.o \
 | 
				
			||||||
	symbol2str.o tokenname.o idf.o input.o type.o def.o \
 | 
						symbol2str.o tokenname.o idf.o input.o type.o def.o \
 | 
				
			||||||
	scope.o misc.o enter.o defmodule.o typequiv.o node.o \
 | 
						scope.o misc.o enter.o defmodule.o typequiv.o node.o \
 | 
				
			||||||
	cstoper.o
 | 
						cstoper.o chk_expr.o
 | 
				
			||||||
OBJ =	$(COBJ) $(LOBJ) Lpars.o
 | 
					OBJ =	$(COBJ) $(LOBJ) Lpars.o
 | 
				
			||||||
GENFILES=	tokenfile.c \
 | 
					GENFILES=	tokenfile.c \
 | 
				
			||||||
	program.c declar.c expression.c statement.c \
 | 
						program.c declar.c expression.c statement.c \
 | 
				
			||||||
| 
						 | 
					@ -39,6 +39,9 @@ main:	$(OBJ) Makefile
 | 
				
			||||||
clean:
 | 
					clean:
 | 
				
			||||||
	rm -f $(OBJ) $(GENFILES) LLfiles 
 | 
						rm -f $(OBJ) $(GENFILES) LLfiles 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					lint:	LLfiles lintlist
 | 
				
			||||||
 | 
						lint $(INCLUDES) `cat lintlist`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
tokenfile.g:	tokenname.c make.tokfile
 | 
					tokenfile.g:	tokenname.c make.tokfile
 | 
				
			||||||
	make.tokfile <tokenname.c >tokenfile.g
 | 
						make.tokfile <tokenname.c >tokenfile.g
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -74,23 +77,24 @@ LLlex.o: LLlex.h Lpars.h class.h f_info.h idf.h input.h
 | 
				
			||||||
LLmessage.o: LLlex.h Lpars.h idf.h
 | 
					LLmessage.o: LLlex.h Lpars.h idf.h
 | 
				
			||||||
char.o: class.h
 | 
					char.o: class.h
 | 
				
			||||||
error.o: LLlex.h f_info.h input.h main.h node.h
 | 
					error.o: LLlex.h f_info.h input.h main.h node.h
 | 
				
			||||||
main.o: LLlex.h Lpars.h debug.h def.h f_info.h idf.h input.h main.h scope.h standards.h type.h
 | 
					main.o: LLlex.h Lpars.h debug.h def.h f_info.h idf.h input.h scope.h standards.h tokenname.h type.h
 | 
				
			||||||
symbol2str.o: Lpars.h
 | 
					symbol2str.o: Lpars.h
 | 
				
			||||||
tokenname.o: Lpars.h idf.h tokenname.h
 | 
					tokenname.o: Lpars.h idf.h tokenname.h
 | 
				
			||||||
idf.o: idf.h
 | 
					idf.o: idf.h
 | 
				
			||||||
input.o: f_info.h input.h
 | 
					input.o: f_info.h input.h
 | 
				
			||||||
type.o: LLlex.h Lpars.h def.h def_sizes.h idf.h node.h type.h
 | 
					type.o: LLlex.h Lpars.h def.h def_sizes.h idf.h node.h type.h
 | 
				
			||||||
def.o: LLlex.h Lpars.h debug.h def.h idf.h main.h node.h scope.h type.h
 | 
					def.o: LLlex.h Lpars.h debug.h def.h idf.h main.h node.h scope.h type.h
 | 
				
			||||||
scope.o: LLlex.h debug.h def.h idf.h main.h scope.h type.h
 | 
					scope.o: LLlex.h debug.h def.h idf.h node.h scope.h type.h
 | 
				
			||||||
misc.o: LLlex.h f_info.h idf.h misc.h
 | 
					misc.o: LLlex.h f_info.h idf.h misc.h node.h
 | 
				
			||||||
enter.o: LLlex.h def.h idf.h node.h scope.h type.h
 | 
					enter.o: LLlex.h def.h idf.h node.h scope.h type.h
 | 
				
			||||||
defmodule.o: LLlex.h def.h f_info.h idf.h input.h scope.h
 | 
					defmodule.o: LLlex.h debug.h def.h f_info.h idf.h input.h scope.h
 | 
				
			||||||
typequiv.o: Lpars.h def.h type.h
 | 
					typequiv.o: Lpars.h def.h type.h
 | 
				
			||||||
node.o: LLlex.h debug.h def.h main.h node.h type.h
 | 
					node.o: LLlex.h debug.h def.h node.h type.h
 | 
				
			||||||
cstoper.o: Lpars.h def_sizes.h idf.h node.h type.h
 | 
					cstoper.o: LLlex.h Lpars.h def_sizes.h idf.h node.h type.h
 | 
				
			||||||
 | 
					chk_expr.o: LLlex.h Lpars.h def.h idf.h node.h scope.h type.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 def.h idf.h misc.h node.h scope.h type.h
 | 
					declar.o: LLlex.h Lpars.h def.h idf.h misc.h node.h scope.h type.h
 | 
				
			||||||
expression.o: LLlex.h Lpars.h debug.h def.h idf.h main.h node.h scope.h
 | 
					expression.o: LLlex.h Lpars.h const.h debug.h def.h idf.h node.h scope.h type.h
 | 
				
			||||||
statement.o: LLlex.h Lpars.h node.h
 | 
					statement.o: LLlex.h Lpars.h node.h
 | 
				
			||||||
Lpars.o: Lpars.h
 | 
					Lpars.o: Lpars.h
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										379
									
								
								lang/m2/comp/chk_expr.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										379
									
								
								lang/m2/comp/chk_expr.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,379 @@
 | 
				
			||||||
 | 
					/* E X P R E S S I O N   C H E C K I N G */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static char *RcsId = "$Header$";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*	Check expressions, and try to evaluate them as far as possible.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					#include	<em_arith.h>
 | 
				
			||||||
 | 
					#include	<em_label.h>
 | 
				
			||||||
 | 
					#include	<assert.h>
 | 
				
			||||||
 | 
					#include	"idf.h"
 | 
				
			||||||
 | 
					#include	"type.h"
 | 
				
			||||||
 | 
					#include	"def.h"
 | 
				
			||||||
 | 
					#include	"LLlex.h"
 | 
				
			||||||
 | 
					#include	"node.h"
 | 
				
			||||||
 | 
					#include	"Lpars.h"
 | 
				
			||||||
 | 
					#include	"scope.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					chk_expr(expp, const)
 | 
				
			||||||
 | 
						register struct node *expp;
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/*	Check the expression indicated by expp for semantic errors,
 | 
				
			||||||
 | 
							identify identifiers used in it, replace constants by
 | 
				
			||||||
 | 
							their value.
 | 
				
			||||||
 | 
						*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch(expp->nd_class) {
 | 
				
			||||||
 | 
						case Oper:
 | 
				
			||||||
 | 
							return	chk_expr(expp->nd_left, const) &&
 | 
				
			||||||
 | 
								chk_expr(expp->nd_right, const) &&
 | 
				
			||||||
 | 
								chk_oper(expp, const);
 | 
				
			||||||
 | 
						case Uoper:
 | 
				
			||||||
 | 
							return	chk_expr(expp->nd_right, const) &&
 | 
				
			||||||
 | 
								chk_uoper(expp, const);
 | 
				
			||||||
 | 
						case Value:
 | 
				
			||||||
 | 
							switch(expp->nd_symb) {
 | 
				
			||||||
 | 
							case REAL:
 | 
				
			||||||
 | 
							case STRING:
 | 
				
			||||||
 | 
							case INTEGER:
 | 
				
			||||||
 | 
								return 1;
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								assert(0);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case Xset:
 | 
				
			||||||
 | 
							return chk_set(expp, const);
 | 
				
			||||||
 | 
						case Name:
 | 
				
			||||||
 | 
							return chk_name(expp, const);
 | 
				
			||||||
 | 
						case Call:
 | 
				
			||||||
 | 
							return chk_call(expp, const);
 | 
				
			||||||
 | 
						case Link:
 | 
				
			||||||
 | 
							return chk_name(expp, const);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						/*NOTREACHED*/
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					chk_set(expp, const)
 | 
				
			||||||
 | 
						register struct node *expp;
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/* ??? */
 | 
				
			||||||
 | 
						return 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					chk_call(expp, const)
 | 
				
			||||||
 | 
						register struct node *expp;
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/* ??? */
 | 
				
			||||||
 | 
						return 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct def *
 | 
				
			||||||
 | 
					findname(expp)
 | 
				
			||||||
 | 
						register struct node *expp;
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/*	Find the name indicated by "expp", starting from the current
 | 
				
			||||||
 | 
							scope.
 | 
				
			||||||
 | 
						*/
 | 
				
			||||||
 | 
						register struct def *df;
 | 
				
			||||||
 | 
						struct def *lookfor();
 | 
				
			||||||
 | 
						register struct node *nd;
 | 
				
			||||||
 | 
						int scope;
 | 
				
			||||||
 | 
						int module;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (expp->nd_class == Name) {
 | 
				
			||||||
 | 
							return lookfor(expp, CurrentScope, 1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						assert(expp->nd_class == Link && expp->nd_symb == '.');
 | 
				
			||||||
 | 
						assert(expp->nd_left->nd_class == Name);
 | 
				
			||||||
 | 
						df = lookfor(expp->nd_left, CurrentScope, 1);
 | 
				
			||||||
 | 
						if (df->df_kind == D_ERROR) return df;
 | 
				
			||||||
 | 
						nd = expp;
 | 
				
			||||||
 | 
						while (nd->nd_class == Link) {
 | 
				
			||||||
 | 
							struct node *nd1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (!(scope = has_selectors(df))) {
 | 
				
			||||||
 | 
								node_error(nd, "identifier \"%s\" has no selectors",
 | 
				
			||||||
 | 
										df->df_idf->id_text);
 | 
				
			||||||
 | 
								return ill_df;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							nd = nd->nd_right;
 | 
				
			||||||
 | 
							if (nd->nd_class == Name) nd1 = nd;
 | 
				
			||||||
 | 
							else nd1 = nd->nd_left;
 | 
				
			||||||
 | 
							module = (df->df_kind == D_MODULE);
 | 
				
			||||||
 | 
							df = lookup(nd1->nd_IDF, scope);
 | 
				
			||||||
 | 
							if (!df) {
 | 
				
			||||||
 | 
								id_not_declared(nd1);
 | 
				
			||||||
 | 
								return ill_df;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (module && !(df->df_flags&(D_EXPORTED|D_QEXPORTED))) {
 | 
				
			||||||
 | 
					node_error(nd1, "identifier \"%s\" not exprted from qualifying module",
 | 
				
			||||||
 | 
					df->df_idf->id_text);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return df;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					chk_name(expp, const)
 | 
				
			||||||
 | 
						register struct node *expp;
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						register struct def *df;
 | 
				
			||||||
 | 
						int retval = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						df = findname(expp);
 | 
				
			||||||
 | 
						if (df->df_kind == D_ERROR) {
 | 
				
			||||||
 | 
							retval = 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						expp->nd_type = df->df_type;
 | 
				
			||||||
 | 
						if (df->df_kind == D_ENUM || df->df_kind == D_CONST) {
 | 
				
			||||||
 | 
							if (expp->nd_left) FreeNode(expp->nd_left);
 | 
				
			||||||
 | 
							if (expp->nd_right) FreeNode(expp->nd_right);
 | 
				
			||||||
 | 
							if (df->df_kind == D_ENUM) {
 | 
				
			||||||
 | 
								expp->nd_left = expp->nd_right = 0;
 | 
				
			||||||
 | 
								expp->nd_class = Value;
 | 
				
			||||||
 | 
								expp->nd_INT = df->enm_val;
 | 
				
			||||||
 | 
								expp->nd_symb = INTEGER;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else if (df->df_kind == D_CONST) {
 | 
				
			||||||
 | 
								*expp = *(df->con_const);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else if (const) {
 | 
				
			||||||
 | 
							node_error(expp, "constant expected");
 | 
				
			||||||
 | 
							retval = 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return retval;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					chk_oper(expp, const)
 | 
				
			||||||
 | 
						register struct node *expp;
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/*	Check a binary operation. If "const" is set, also check
 | 
				
			||||||
 | 
							that it is constant.
 | 
				
			||||||
 | 
							The code is ugly !
 | 
				
			||||||
 | 
						*/
 | 
				
			||||||
 | 
						register struct type *tpl = expp->nd_left->nd_type;
 | 
				
			||||||
 | 
						register struct type *tpr = expp->nd_right->nd_type;
 | 
				
			||||||
 | 
						char *symbol2str();
 | 
				
			||||||
 | 
						int errval = 1;
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						if (tpl == intorcard_type) {
 | 
				
			||||||
 | 
							if (tpr == int_type || tpr == card_type) {
 | 
				
			||||||
 | 
								expp->nd_left->nd_type = tpl = tpr;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (tpr == intorcard_type) {
 | 
				
			||||||
 | 
							if (tpl == int_type || tpl == card_type) {
 | 
				
			||||||
 | 
								expp->nd_right->nd_type = tpr = tpl;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (expp->nd_symb == IN) {
 | 
				
			||||||
 | 
							/* Handle this one specially */
 | 
				
			||||||
 | 
							expp->nd_type == bool_type;
 | 
				
			||||||
 | 
							if (tpr->tp_fund != SET) {
 | 
				
			||||||
 | 
					node_error(expp, "RHS of IN operator not a SET type");
 | 
				
			||||||
 | 
								return 0;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (!TstCompat(tpl, tpr->next)) {
 | 
				
			||||||
 | 
					node_error(expp, "IN operator: type of LHS not compatible with element type of RHS");
 | 
				
			||||||
 | 
								return 0;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return 1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (tpl->tp_fund == SUBRANGE) tpl = tpl->next;
 | 
				
			||||||
 | 
						expp->nd_type = tpl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!TstCompat(tpl, tpr)) {
 | 
				
			||||||
 | 
					node_error(expp, "Incompatible types for operator \"%s\"", symbol2str(expp->nd_symb));
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						switch(expp->nd_symb) {
 | 
				
			||||||
 | 
						case '+':
 | 
				
			||||||
 | 
						case '-':
 | 
				
			||||||
 | 
						case '*':
 | 
				
			||||||
 | 
							switch(tpl->tp_fund) {
 | 
				
			||||||
 | 
							case INTEGER:
 | 
				
			||||||
 | 
							case INTORCARD:
 | 
				
			||||||
 | 
							case CARDINAL:
 | 
				
			||||||
 | 
							case LONGINT:
 | 
				
			||||||
 | 
							case SET:
 | 
				
			||||||
 | 
								if (expp->nd_left->nd_class == Value &&
 | 
				
			||||||
 | 
								    expp->nd_right->nd_class == Value) {
 | 
				
			||||||
 | 
									cstbin(expp);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return 1;
 | 
				
			||||||
 | 
							case REAL:
 | 
				
			||||||
 | 
							case LONGREAL:
 | 
				
			||||||
 | 
								if (const) {
 | 
				
			||||||
 | 
									errval = 2;
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return 1;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case '/':
 | 
				
			||||||
 | 
							switch(tpl->tp_fund) {
 | 
				
			||||||
 | 
							case SET:
 | 
				
			||||||
 | 
								if (expp->nd_left->nd_class == Value &&
 | 
				
			||||||
 | 
								    expp->nd_right->nd_class == Value) {
 | 
				
			||||||
 | 
									cstbin(expp);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return 1;
 | 
				
			||||||
 | 
							case REAL:
 | 
				
			||||||
 | 
							case LONGREAL:
 | 
				
			||||||
 | 
								if (const) {
 | 
				
			||||||
 | 
									errval = 2;
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return 1;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case DIV:
 | 
				
			||||||
 | 
						case MOD:
 | 
				
			||||||
 | 
							switch(tpl->tp_fund) {
 | 
				
			||||||
 | 
							case INTEGER:
 | 
				
			||||||
 | 
							case INTORCARD:
 | 
				
			||||||
 | 
							case CARDINAL:
 | 
				
			||||||
 | 
							case LONGINT:
 | 
				
			||||||
 | 
								if (expp->nd_left->nd_class == Value &&
 | 
				
			||||||
 | 
								    expp->nd_right->nd_class == Value) {
 | 
				
			||||||
 | 
									cstbin(expp);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return 1;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case OR:
 | 
				
			||||||
 | 
						case AND:
 | 
				
			||||||
 | 
							if (tpl == bool_type) {
 | 
				
			||||||
 | 
								if (expp->nd_left->nd_class == Value &&
 | 
				
			||||||
 | 
								    expp->nd_right->nd_class == Value) {
 | 
				
			||||||
 | 
									cstbin(expp);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return 1;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							errval = 3;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case '=':
 | 
				
			||||||
 | 
						case '#':
 | 
				
			||||||
 | 
						case GREATEREQUAL:
 | 
				
			||||||
 | 
						case LESSEQUAL:
 | 
				
			||||||
 | 
						case '<':
 | 
				
			||||||
 | 
						case '>':
 | 
				
			||||||
 | 
							switch(tpl->tp_fund) {
 | 
				
			||||||
 | 
							case SET:
 | 
				
			||||||
 | 
								if (expp->nd_symb == '<' || expp->nd_symb == '>') {
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							case INTEGER:
 | 
				
			||||||
 | 
							case INTORCARD:
 | 
				
			||||||
 | 
							case LONGINT:
 | 
				
			||||||
 | 
							case CARDINAL:
 | 
				
			||||||
 | 
							case ENUMERATION:	/* includes boolean */
 | 
				
			||||||
 | 
							case CHAR:
 | 
				
			||||||
 | 
								if (expp->nd_left->nd_class == Value &&
 | 
				
			||||||
 | 
								    expp->nd_right->nd_class == Value) {
 | 
				
			||||||
 | 
									cstbin(expp);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return 1;
 | 
				
			||||||
 | 
							case POINTER:
 | 
				
			||||||
 | 
								if (!(expp->nd_symb == '=' || expp->nd_symb == '#')) {
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								/* Fall through */
 | 
				
			||||||
 | 
							case REAL:
 | 
				
			||||||
 | 
							case LONGREAL:
 | 
				
			||||||
 | 
								if (const) {
 | 
				
			||||||
 | 
									errval = 2;
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return 1;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							assert(0);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						switch(errval) {
 | 
				
			||||||
 | 
						case 1:
 | 
				
			||||||
 | 
							node_error(expp,"Operator \"%s\": illegal operand type(s)", symbol2str(expp->nd_symb));
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case 2:
 | 
				
			||||||
 | 
							node_error(expp, "Expression not constant");
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case 3:
 | 
				
			||||||
 | 
							node_error(expp, "BOOLEAN type(s) expected");
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					chk_uoper(expp, const)
 | 
				
			||||||
 | 
						register struct node *expp;
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/*	Check an unary operation. If "const" is set, also check that
 | 
				
			||||||
 | 
							it can be evaluated compile-time.
 | 
				
			||||||
 | 
						*/
 | 
				
			||||||
 | 
						register struct type *tpr = expp->nd_right->nd_type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (tpr->tp_fund == SUBRANGE) tpr = tpr->next;
 | 
				
			||||||
 | 
						expp->nd_type = tpr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch(expp->nd_symb) {
 | 
				
			||||||
 | 
						case '+':
 | 
				
			||||||
 | 
							switch(tpr->tp_fund) {
 | 
				
			||||||
 | 
							case INTEGER:
 | 
				
			||||||
 | 
							case LONGINT:
 | 
				
			||||||
 | 
							case REAL:
 | 
				
			||||||
 | 
							case LONGREAL:
 | 
				
			||||||
 | 
							case CARDINAL:
 | 
				
			||||||
 | 
							case INTORCARD:
 | 
				
			||||||
 | 
								expp->nd_token = expp->nd_right->nd_token;
 | 
				
			||||||
 | 
								FreeNode(expp->nd_right);
 | 
				
			||||||
 | 
								expp->nd_right = 0;
 | 
				
			||||||
 | 
								return 1;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case '-':
 | 
				
			||||||
 | 
							switch(tpr->tp_fund) {
 | 
				
			||||||
 | 
							case INTEGER:
 | 
				
			||||||
 | 
							case LONGINT:
 | 
				
			||||||
 | 
							case INTORCARD:
 | 
				
			||||||
 | 
								if (expp->nd_right->nd_class == Value) {
 | 
				
			||||||
 | 
									cstunary(expp);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return 1;
 | 
				
			||||||
 | 
							case REAL:
 | 
				
			||||||
 | 
							case LONGREAL:
 | 
				
			||||||
 | 
								if (expp->nd_right->nd_class == Value) {
 | 
				
			||||||
 | 
									expp->nd_token = expp->nd_right->nd_token;
 | 
				
			||||||
 | 
									if (*(expp->nd_REL) == '-') {
 | 
				
			||||||
 | 
										expp->nd_REL++;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									else	expp->nd_REL--;
 | 
				
			||||||
 | 
									FreeNode(expp->nd_right);
 | 
				
			||||||
 | 
									expp->nd_right = 0;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return 1;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case NOT:
 | 
				
			||||||
 | 
							if (tpr == bool_type) {
 | 
				
			||||||
 | 
								if (expp->nd_right->nd_class == Value) {
 | 
				
			||||||
 | 
									cstunary(expp);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return 1;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							assert(0);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						node_error(expp, "Illegal operand for unary operator \"%s\"",
 | 
				
			||||||
 | 
								symbol2str(expp->nd_symb));
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -19,17 +19,17 @@ arith max_int;		/* maximum integer on target machine	*/
 | 
				
			||||||
arith max_unsigned;	/* maximum unsigned on target machine	*/
 | 
					arith max_unsigned;	/* maximum unsigned on target machine	*/
 | 
				
			||||||
arith max_longint;	/* maximum longint on target machine	*/
 | 
					arith max_longint;	/* maximum longint on target machine	*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cstunary(expp, oper)
 | 
					cstunary(expp)
 | 
				
			||||||
	register struct node *expp;
 | 
						register struct node *expp;
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/*	The unary operation oper is performed on the constant
 | 
						/*	The unary operation in "expp" is performed on the constant
 | 
				
			||||||
		expression expp, and the result restored in expp.
 | 
							expression below it, and the result restored in expp.
 | 
				
			||||||
	*/
 | 
						*/
 | 
				
			||||||
	arith o1 = expp->nd_INT;
 | 
						arith o1 = expp->nd_right->nd_INT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch(oper) {
 | 
						switch(expp->nd_symb) {
 | 
				
			||||||
	case '+':
 | 
						case '+':
 | 
				
			||||||
		return;
 | 
							break;
 | 
				
			||||||
	case '-':
 | 
						case '-':
 | 
				
			||||||
		o1 = -o1;
 | 
							o1 = -o1;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
| 
						 | 
					@ -39,40 +39,37 @@ cstunary(expp, oper)
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		assert(0);
 | 
							assert(0);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						expp->nd_class = Value;
 | 
				
			||||||
 | 
						expp->nd_token = expp->nd_right->nd_token;
 | 
				
			||||||
	expp->nd_INT = o1;
 | 
						expp->nd_INT = o1;
 | 
				
			||||||
	cut_size(expp);
 | 
						cut_size(expp);
 | 
				
			||||||
 | 
						FreeNode(expp->nd_right);
 | 
				
			||||||
 | 
						expp->nd_right = 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cstbin(expp, oper, expr)
 | 
					cstbin(expp)
 | 
				
			||||||
	register struct node *expp, *expr;
 | 
						register struct node *expp;
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/*	The binary operation oper is performed on the constant
 | 
						/*	The binary operation in "expp" is performed on the constant
 | 
				
			||||||
		expressions expp and expr, and the result restored in
 | 
							expressions below it, and the result restored in
 | 
				
			||||||
		expp.
 | 
							expp.
 | 
				
			||||||
	*/
 | 
						*/
 | 
				
			||||||
	arith o1 = expp->nd_INT;
 | 
						arith o1 = expp->nd_left->nd_INT;
 | 
				
			||||||
	arith o2 = expr->nd_INT;
 | 
						arith o2 = expp->nd_right->nd_INT;
 | 
				
			||||||
	int uns = expp->nd_type != int_type;
 | 
						int uns = expp->nd_type != int_type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	assert(expp->nd_class == Value && expr->nd_class == Value);
 | 
						assert(expp->nd_class == Oper);
 | 
				
			||||||
	switch (oper)	{
 | 
						if (expp->nd_right->nd_type->tp_fund == SET) {
 | 
				
			||||||
	case IN:
 | 
							cstset(expp);
 | 
				
			||||||
		/* ??? */
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
	case '*':
 | 
					 | 
				
			||||||
		if (expp->nd_type->tp_fund == SET) {
 | 
					 | 
				
			||||||
			/* ??? */
 | 
					 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						switch (expp->nd_symb)	{
 | 
				
			||||||
 | 
						case '*':
 | 
				
			||||||
		o1 *= o2;
 | 
							o1 *= o2;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case '/':
 | 
					 | 
				
			||||||
		assert(expp->nd_type->tp_fund == SET);
 | 
					 | 
				
			||||||
		/* ??? */
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
	case DIV:
 | 
						case DIV:
 | 
				
			||||||
		if (o2 == 0)	{
 | 
							if (o2 == 0)	{
 | 
				
			||||||
			node_error(expr, "division by 0");
 | 
								node_error(expp, "division by 0");
 | 
				
			||||||
			return;
 | 
								return;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (uns)	{
 | 
							if (uns)	{
 | 
				
			||||||
| 
						 | 
					@ -109,7 +106,7 @@ cstbin(expp, oper, expr)
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case MOD:
 | 
						case MOD:
 | 
				
			||||||
		if (o2 == 0)	{
 | 
							if (o2 == 0)	{
 | 
				
			||||||
			node_error(expr, "modulo by 0");
 | 
								node_error(expp, "modulo by 0");
 | 
				
			||||||
			return;
 | 
								return;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (uns)	{
 | 
							if (uns)	{
 | 
				
			||||||
| 
						 | 
					@ -137,17 +134,9 @@ cstbin(expp, oper, expr)
 | 
				
			||||||
			o1 %= o2;
 | 
								o1 %= o2;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case '+':
 | 
						case '+':
 | 
				
			||||||
		if (expp->nd_type->tp_fund == SET) {
 | 
					 | 
				
			||||||
			/* ??? */
 | 
					 | 
				
			||||||
			return;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		o1 += o2;
 | 
							o1 += o2;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case '-':
 | 
						case '-':
 | 
				
			||||||
		if (expp->nd_type->tp_fund == SET) {
 | 
					 | 
				
			||||||
			/* ??? */
 | 
					 | 
				
			||||||
			return;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		o1 -= o2;
 | 
							o1 -= o2;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case '<':
 | 
						case '<':
 | 
				
			||||||
| 
						 | 
					@ -171,10 +160,6 @@ cstbin(expp, oper, expr)
 | 
				
			||||||
			o1 = o1 > o2;
 | 
								o1 = o1 > o2;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case LESSEQUAL:
 | 
						case LESSEQUAL:
 | 
				
			||||||
		if (expp->nd_type->tp_fund == SET) {
 | 
					 | 
				
			||||||
			/* ??? */
 | 
					 | 
				
			||||||
			return;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if (uns)	{
 | 
							if (uns)	{
 | 
				
			||||||
			o1 = (o1 & mach_long_sign ?
 | 
								o1 = (o1 & mach_long_sign ?
 | 
				
			||||||
				(o2 & mach_long_sign ? o1 <= o2 : 0) :
 | 
									(o2 & mach_long_sign ? o1 <= o2 : 0) :
 | 
				
			||||||
| 
						 | 
					@ -185,10 +170,6 @@ cstbin(expp, oper, expr)
 | 
				
			||||||
			o1 = o1 <= o2;
 | 
								o1 = o1 <= o2;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case GREATEREQUAL:
 | 
						case GREATEREQUAL:
 | 
				
			||||||
		if (expp->nd_type->tp_fund == SET) {
 | 
					 | 
				
			||||||
			/* ??? */
 | 
					 | 
				
			||||||
			return;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if (uns)	{
 | 
							if (uns)	{
 | 
				
			||||||
			o1 = (o1 & mach_long_sign ?
 | 
								o1 = (o1 & mach_long_sign ?
 | 
				
			||||||
				(o2 & mach_long_sign ? o1 >= o2 : 1) :
 | 
									(o2 & mach_long_sign ? o1 >= o2 : 1) :
 | 
				
			||||||
| 
						 | 
					@ -199,17 +180,9 @@ cstbin(expp, oper, expr)
 | 
				
			||||||
			o1 = o1 >= o2;
 | 
								o1 = o1 >= o2;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case '=':
 | 
						case '=':
 | 
				
			||||||
		if (expp->nd_type->tp_fund == SET) {
 | 
					 | 
				
			||||||
			/* ??? */
 | 
					 | 
				
			||||||
			return;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		o1 = o1 == o2;
 | 
							o1 = o1 == o2;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case '#':
 | 
						case '#':
 | 
				
			||||||
		if (expp->nd_type->tp_fund == SET) {
 | 
					 | 
				
			||||||
			/* ??? */
 | 
					 | 
				
			||||||
			return;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		o1 = o1 != o2;
 | 
							o1 = o1 != o2;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case AND:
 | 
						case AND:
 | 
				
			||||||
| 
						 | 
					@ -221,8 +194,33 @@ cstbin(expp, oper, expr)
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		assert(0);
 | 
							assert(0);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						expp->nd_class = Value;
 | 
				
			||||||
 | 
						expp->nd_token = expp->nd_right->nd_token;
 | 
				
			||||||
	expp->nd_INT = o1;
 | 
						expp->nd_INT = o1;
 | 
				
			||||||
	cut_size(expp);
 | 
						cut_size(expp);
 | 
				
			||||||
 | 
						FreeNode(expp->nd_left);
 | 
				
			||||||
 | 
						FreeNode(expp->nd_right);
 | 
				
			||||||
 | 
						expp->nd_left = expp->nd_right = 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cstset(expp)
 | 
				
			||||||
 | 
						register struct node *expp;
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						switch(expp->nd_symb) {
 | 
				
			||||||
 | 
						case IN:
 | 
				
			||||||
 | 
						case '+':
 | 
				
			||||||
 | 
						case '-':
 | 
				
			||||||
 | 
						case '*':
 | 
				
			||||||
 | 
						case '/':
 | 
				
			||||||
 | 
						case GREATEREQUAL:
 | 
				
			||||||
 | 
						case LESSEQUAL:
 | 
				
			||||||
 | 
						case '=':
 | 
				
			||||||
 | 
						case '#':
 | 
				
			||||||
 | 
							/* ??? */
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							assert(0);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cut_size(expr)
 | 
					cut_size(expr)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,6 +5,7 @@ static char *RcsId = "$Header$";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include	<em_arith.h>
 | 
					#include	<em_arith.h>
 | 
				
			||||||
#include	<em_label.h>
 | 
					#include	<em_label.h>
 | 
				
			||||||
 | 
					#include	<alloc.h>
 | 
				
			||||||
#include	<assert.h>
 | 
					#include	<assert.h>
 | 
				
			||||||
#include	"idf.h"
 | 
					#include	"idf.h"
 | 
				
			||||||
#include	"LLlex.h"
 | 
					#include	"LLlex.h"
 | 
				
			||||||
| 
						 | 
					@ -122,7 +123,7 @@ FPSection(int doparams; struct paramlist **ppr;)
 | 
				
			||||||
		  if (doparams) {
 | 
							  if (doparams) {
 | 
				
			||||||
			EnterIdList(FPList, D_VARIABLE, VARp, tp, CurrentScope);
 | 
								EnterIdList(FPList, D_VARIABLE, VARp, tp, CurrentScope);
 | 
				
			||||||
		  }
 | 
							  }
 | 
				
			||||||
		  *ppr = ParamList(FPList, tp);
 | 
							  *ppr = ParamList(FPList, tp, VARp);
 | 
				
			||||||
		  FreeNode(FPList);
 | 
							  FreeNode(FPList);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
;
 | 
					;
 | 
				
			||||||
| 
						 | 
					@ -181,18 +182,18 @@ type(struct type **ptp;):
 | 
				
			||||||
SimpleType(struct type **ptp;)
 | 
					SimpleType(struct type **ptp;)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct def *df;
 | 
						struct def *df;
 | 
				
			||||||
	struct type *tp;
 | 
					 | 
				
			||||||
} :
 | 
					} :
 | 
				
			||||||
	qualident(D_TYPE | D_HTYPE, &df, "type", (struct node **) 0)
 | 
						qualident(D_TYPE | D_HTYPE, &df, "type", (struct node **) 0)
 | 
				
			||||||
	[
 | 
						[
 | 
				
			||||||
		/* nothing */
 | 
							/* nothing */
 | 
				
			||||||
 | 
								{ *ptp = df->df_type; }
 | 
				
			||||||
	|
 | 
						|
 | 
				
			||||||
		SubrangeType(ptp)
 | 
							SubrangeType(ptp)
 | 
				
			||||||
		/* The subrange type is given a base type by the
 | 
							/* The subrange type is given a base type by the
 | 
				
			||||||
		   qualident (this is new modula-2).
 | 
							   qualident (this is new modula-2).
 | 
				
			||||||
		*/
 | 
							*/
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
			  chk_basesubrange(*ptp, tp);
 | 
								  chk_basesubrange(*ptp, df->df_type);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
	]
 | 
						]
 | 
				
			||||||
|
 | 
					|
 | 
				
			||||||
| 
						 | 
					@ -250,7 +251,7 @@ SubrangeType(struct type **ptp;)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
			  /* For the time being: */
 | 
								  /* For the time being: */
 | 
				
			||||||
			  tp = int_type;
 | 
								  tp = int_type;
 | 
				
			||||||
			  tp = construct_type(SUBRANGE, tp, (arith) 0);
 | 
								  tp = construct_type(SUBRANGE, tp);
 | 
				
			||||||
			  *ptp = tp;
 | 
								  *ptp = tp;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
;
 | 
					;
 | 
				
			||||||
| 
						 | 
					@ -352,7 +353,7 @@ SetType(struct type **ptp;)
 | 
				
			||||||
} :
 | 
					} :
 | 
				
			||||||
	SET OF SimpleType(&tp)
 | 
						SET OF SimpleType(&tp)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
			  *ptp = construct_type(SET, tp, (arith) 0 /* ???? */);
 | 
								  *ptp = construct_type(SET, tp);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
;
 | 
					;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -365,6 +366,7 @@ PointerType(struct type **ptp;)
 | 
				
			||||||
	struct type *tp;
 | 
						struct type *tp;
 | 
				
			||||||
	struct def *df;
 | 
						struct def *df;
 | 
				
			||||||
	struct def *lookfor();
 | 
						struct def *lookfor();
 | 
				
			||||||
 | 
						struct node *nd;
 | 
				
			||||||
} :
 | 
					} :
 | 
				
			||||||
	POINTER TO
 | 
						POINTER TO
 | 
				
			||||||
	[ %if ( (df = lookup(dot.TOK_IDF, CurrentScope->sc_scope)))
 | 
						[ %if ( (df = lookup(dot.TOK_IDF, CurrentScope->sc_scope)))
 | 
				
			||||||
| 
						 | 
					@ -380,7 +382,8 @@ PointerType(struct type **ptp;)
 | 
				
			||||||
				  }
 | 
									  }
 | 
				
			||||||
				  else	tp = df->df_type;
 | 
									  else	tp = df->df_type;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
	| %if (df = lookfor(dot.TOK_IDF, CurrentScope, 0),
 | 
						| %if ( nd = new_node(), nd->nd_token = dot,
 | 
				
			||||||
 | 
							df = lookfor(nd, CurrentScope, 0), free_node(nd),
 | 
				
			||||||
	        df->df_kind == D_MODULE)
 | 
						        df->df_kind == D_MODULE)
 | 
				
			||||||
		type(&tp)
 | 
							type(&tp)
 | 
				
			||||||
	|
 | 
						|
 | 
				
			||||||
| 
						 | 
					@ -449,7 +452,7 @@ ConstantDeclaration
 | 
				
			||||||
}:
 | 
					}:
 | 
				
			||||||
	IDENT			{ id = dot.TOK_IDF; }
 | 
						IDENT			{ id = dot.TOK_IDF; }
 | 
				
			||||||
	'=' ConstExpression(&nd){ df = define(id, CurrentScope, D_CONST);
 | 
						'=' ConstExpression(&nd){ df = define(id, CurrentScope, D_CONST);
 | 
				
			||||||
				  /* ???? */
 | 
									  df->con_const = nd;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
;
 | 
					;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,8 +15,8 @@ struct variable {
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct constant {
 | 
					struct constant {
 | 
				
			||||||
	arith co_const;		/* result of a constant expression */
 | 
						struct node *co_const;	/* result of a constant expression */
 | 
				
			||||||
#define con_const	df_value.df_variable.con_const
 | 
					#define con_const	df_value.df_constant.co_const
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct enumval {
 | 
					struct enumval {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,11 +6,11 @@ static char *RcsId = "$Header$";
 | 
				
			||||||
#include	<em_arith.h>
 | 
					#include	<em_arith.h>
 | 
				
			||||||
#include	<em_label.h>
 | 
					#include	<em_label.h>
 | 
				
			||||||
#include	<assert.h>
 | 
					#include	<assert.h>
 | 
				
			||||||
 | 
					#include	"main.h"
 | 
				
			||||||
#include	"Lpars.h"
 | 
					#include	"Lpars.h"
 | 
				
			||||||
#include	"def.h"
 | 
					#include	"def.h"
 | 
				
			||||||
#include	"type.h"
 | 
					#include	"type.h"
 | 
				
			||||||
#include	"idf.h"
 | 
					#include	"idf.h"
 | 
				
			||||||
#include	"main.h"
 | 
					 | 
				
			||||||
#include	"scope.h"
 | 
					#include	"scope.h"
 | 
				
			||||||
#include	"LLlex.h"
 | 
					#include	"LLlex.h"
 | 
				
			||||||
#include	"node.h"
 | 
					#include	"node.h"
 | 
				
			||||||
| 
						 | 
					@ -26,13 +26,12 @@ struct def *ill_df = &illegal_def;
 | 
				
			||||||
struct def *
 | 
					struct def *
 | 
				
			||||||
define(id, scope, kind)
 | 
					define(id, scope, kind)
 | 
				
			||||||
	register struct idf *id;
 | 
						register struct idf *id;
 | 
				
			||||||
	struct scope *scope;
 | 
						register struct scope *scope;
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/*	Declare an identifier in a scope, but first check if it
 | 
						/*	Declare an identifier in a scope, but first check if it
 | 
				
			||||||
		already has been defined. If so, error message.
 | 
							already has been defined. If so, error message.
 | 
				
			||||||
	*/
 | 
						*/
 | 
				
			||||||
	register struct def *df;
 | 
						register struct def *df;
 | 
				
			||||||
	register struct scope *sc;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	DO_DEBUG(5, debug("Defining identifier \"%s\" in scope %d", id->id_text, scope->sc_scope));
 | 
						DO_DEBUG(5, debug("Defining identifier \"%s\" in scope %d", id->id_text, scope->sc_scope));
 | 
				
			||||||
	df = lookup(id, scope->sc_scope);
 | 
						df = lookup(id, scope->sc_scope);
 | 
				
			||||||
| 
						 | 
					@ -157,7 +156,6 @@ Import(ids, idn, local)
 | 
				
			||||||
		identifiers defined in this module.
 | 
							identifiers defined in this module.
 | 
				
			||||||
	*/
 | 
						*/
 | 
				
			||||||
	register struct def *df;
 | 
						register struct def *df;
 | 
				
			||||||
	register struct idf *id = 0;
 | 
					 | 
				
			||||||
	int scope;
 | 
						int scope;
 | 
				
			||||||
	int kind;
 | 
						int kind;
 | 
				
			||||||
	int imp_kind;
 | 
						int imp_kind;
 | 
				
			||||||
| 
						 | 
					@ -165,19 +163,18 @@ Import(ids, idn, local)
 | 
				
			||||||
#define FROM_ENCLOSING	1
 | 
					#define FROM_ENCLOSING	1
 | 
				
			||||||
	struct def *lookfor(), *GetDefinitionModule();
 | 
						struct def *lookfor(), *GetDefinitionModule();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (idn) id = idn->nd_IDF;
 | 
					 | 
				
			||||||
	kind = D_IMPORT;
 | 
						kind = D_IMPORT;
 | 
				
			||||||
	scope = enclosing(CurrentScope)->sc_scope;
 | 
						scope = enclosing(CurrentScope)->sc_scope;
 | 
				
			||||||
	if (!id) imp_kind = FROM_ENCLOSING;
 | 
						if (!idn) imp_kind = FROM_ENCLOSING;
 | 
				
			||||||
	else {
 | 
						else {
 | 
				
			||||||
		imp_kind = FROM_MODULE;
 | 
							imp_kind = FROM_MODULE;
 | 
				
			||||||
		if (local) df = lookfor(id, enclosing(CurrentScope), 1);
 | 
							if (local) df = lookfor(idn, enclosing(CurrentScope), 1);
 | 
				
			||||||
		else df = GetDefinitionModule(id);
 | 
							else df = GetDefinitionModule(idn->nd_IDF);
 | 
				
			||||||
		if (df->df_kind != D_MODULE) {
 | 
							if (df->df_kind != D_MODULE) {
 | 
				
			||||||
			/* enter all "ids" with type D_ERROR */
 | 
								/* enter all "ids" with type D_ERROR */
 | 
				
			||||||
			kind = D_ERROR;
 | 
								kind = D_ERROR;
 | 
				
			||||||
			if (df->df_kind != D_ERROR) {
 | 
								if (df->df_kind != D_ERROR) {
 | 
				
			||||||
node_error(idn, "identifier \"%s\" does not represent a module", id->id_text);
 | 
					node_error(idn, "identifier \"%s\" does not represent a module", idn->nd_IDF->id_text);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		else	scope = df->mod_scope;
 | 
							else	scope = df->mod_scope;
 | 
				
			||||||
| 
						 | 
					@ -197,14 +194,14 @@ ids->nd_IDF->id_text);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		else {
 | 
							else {
 | 
				
			||||||
			if (local) {
 | 
								if (local) {
 | 
				
			||||||
				df = lookfor(ids->nd_IDF,
 | 
									df = lookfor(ids, enclosing(CurrentScope), 0);
 | 
				
			||||||
					     enclosing(CurrentScope), 0);
 | 
					 | 
				
			||||||
			} else df = GetDefinitionModule(ids->nd_IDF);
 | 
								} else df = GetDefinitionModule(ids->nd_IDF);
 | 
				
			||||||
			if (df->df_kind == D_ERROR) {
 | 
								if (df->df_kind == D_ERROR) {
 | 
				
			||||||
node_error(ids, "identifier \"%s\" not visible in enclosing scope",
 | 
					node_error(ids, "identifier \"%s\" not visible in enclosing scope",
 | 
				
			||||||
ids->nd_IDF->id_text);
 | 
					ids->nd_IDF->id_text);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							DO_DEBUG(2, debug("importing \"%s\", kind %d", ids->nd_IDF->id_text, df->df_kind));
 | 
				
			||||||
		define(ids->nd_IDF, CurrentScope, kind)->imp_def = df;
 | 
							define(ids->nd_IDF, CurrentScope, kind)->imp_def = df;
 | 
				
			||||||
		if (df->df_kind == D_TYPE &&
 | 
							if (df->df_kind == D_TYPE &&
 | 
				
			||||||
		    df->df_type->tp_fund == ENUMERATION) {
 | 
							    df->df_type->tp_fund == ENUMERATION) {
 | 
				
			||||||
| 
						 | 
					@ -218,12 +215,14 @@ ids->nd_IDF->id_text);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
exprt_literals(df, toscope)
 | 
					exprt_literals(df, toscope)
 | 
				
			||||||
	register struct def *df;
 | 
						register struct def *df;
 | 
				
			||||||
	register struct scope *toscope;
 | 
						struct scope *toscope;
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/*	A list of enumeration literals is exported. This is implemented
 | 
						/*	A list of enumeration literals is exported. This is implemented
 | 
				
			||||||
		as an import from the scope "toscope".
 | 
							as an import from the scope "toscope".
 | 
				
			||||||
	*/
 | 
						*/
 | 
				
			||||||
 | 
						DO_DEBUG(2, debug("enumeration import:"));
 | 
				
			||||||
	while (df) {
 | 
						while (df) {
 | 
				
			||||||
 | 
							DO_DEBUG(2, debug(df->df_idf->id_text));
 | 
				
			||||||
		define(df->df_idf, toscope, D_IMPORT)->imp_def = df;
 | 
							define(df->df_idf, toscope, D_IMPORT)->imp_def = df;
 | 
				
			||||||
		df = df->enm_next;
 | 
							df = df->enm_next;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,6 +11,11 @@ static char *RcsId = "$Header$";
 | 
				
			||||||
#include	"def.h"
 | 
					#include	"def.h"
 | 
				
			||||||
#include	"LLlex.h"
 | 
					#include	"LLlex.h"
 | 
				
			||||||
#include	"f_info.h"
 | 
					#include	"f_info.h"
 | 
				
			||||||
 | 
					#include	"debug.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef DEBUG
 | 
				
			||||||
 | 
					long	sys_filesize();
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GetFile(name)
 | 
					GetFile(name)
 | 
				
			||||||
	char *name;
 | 
						char *name;
 | 
				
			||||||
| 
						 | 
					@ -30,6 +35,7 @@ GetFile(name)
 | 
				
			||||||
		fatal("Could'nt find a DEFINITION MODULE for \"%s\"", name);
 | 
							fatal("Could'nt find a DEFINITION MODULE for \"%s\"", name);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	LineNumber = 1;
 | 
						LineNumber = 1;
 | 
				
			||||||
 | 
						DO_DEBUG(1, debug("File %s : %ld characters", FileName, sys_filesize(FileName)));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct def *
 | 
					struct def *
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -74,7 +74,7 @@ EnterIdList(idlist, kind, flags, type, scope)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct def *
 | 
					struct def *
 | 
				
			||||||
lookfor(id, scope, give_error)
 | 
					lookfor(id, scope, give_error)
 | 
				
			||||||
	struct idf *id;
 | 
						struct node *id;
 | 
				
			||||||
	struct scope *scope;
 | 
						struct scope *scope;
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/*	Look for an identifier in the visibility range started by
 | 
						/*	Look for an identifier in the visibility range started by
 | 
				
			||||||
| 
						 | 
					@ -86,10 +86,10 @@ lookfor(id, scope, give_error)
 | 
				
			||||||
	register struct scope *sc = scope;
 | 
						register struct scope *sc = scope;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	while (sc) {
 | 
						while (sc) {
 | 
				
			||||||
		df = lookup(id, sc->sc_scope);
 | 
							df = lookup(id->nd_IDF, sc->sc_scope);
 | 
				
			||||||
		if (df) return df;
 | 
							if (df) return df;
 | 
				
			||||||
		sc = nextvisible(sc);
 | 
							sc = nextvisible(sc);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (give_error) id_not_declared(id);
 | 
						if (give_error) id_not_declared(id);
 | 
				
			||||||
	return define(id, scope, D_ERROR);
 | 
						return define(id->nd_IDF, scope, D_ERROR);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,7 +6,6 @@ static char *RcsId = "$Header$";
 | 
				
			||||||
#include	<alloc.h>
 | 
					#include	<alloc.h>
 | 
				
			||||||
#include	<em_arith.h>
 | 
					#include	<em_arith.h>
 | 
				
			||||||
#include	<em_label.h>
 | 
					#include	<em_label.h>
 | 
				
			||||||
#include	"main.h"
 | 
					 | 
				
			||||||
#include	"LLlex.h"
 | 
					#include	"LLlex.h"
 | 
				
			||||||
#include	"idf.h"
 | 
					#include	"idf.h"
 | 
				
			||||||
#include	"def.h"
 | 
					#include	"def.h"
 | 
				
			||||||
| 
						 | 
					@ -34,53 +33,30 @@ number(struct node **p;)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
qualident(int types; struct def **pdf; char *str; struct node **p;)
 | 
					qualident(int types; struct def **pdf; char *str; struct node **p;)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int scope;
 | 
					 | 
				
			||||||
	int  module;
 | 
					 | 
				
			||||||
	register struct def *df;
 | 
						register struct def *df;
 | 
				
			||||||
	struct def *lookfor();
 | 
					 | 
				
			||||||
	register struct node **pnd;
 | 
						register struct node **pnd;
 | 
				
			||||||
	struct node *nd;
 | 
						struct node *nd;
 | 
				
			||||||
 | 
						struct def *findname();
 | 
				
			||||||
} :
 | 
					} :
 | 
				
			||||||
	IDENT		{ if (types) {
 | 
						IDENT		{ nd = MkNode(Name, NULLNODE, NULLNODE, &dot);
 | 
				
			||||||
				df = lookfor(dot.TOK_IDF, CurrentScope, 1);
 | 
					 | 
				
			||||||
				*pdf = df;
 | 
					 | 
				
			||||||
				if (df->df_kind == D_ERROR) types = 0;
 | 
					 | 
				
			||||||
			  }
 | 
					 | 
				
			||||||
			  nd = MkNode(Value, NULLNODE, NULLNODE, &dot);
 | 
					 | 
				
			||||||
			  pnd = &nd;
 | 
								  pnd = &nd;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
	[
 | 
						[
 | 
				
			||||||
			{ if (types &&!(scope = has_selectors(df))) {
 | 
					 | 
				
			||||||
				types = 0;
 | 
					 | 
				
			||||||
				*pdf = ill_df;
 | 
					 | 
				
			||||||
			  }
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		/* selector */
 | 
							/* selector */
 | 
				
			||||||
		'.'	{ *pnd = MkNode(Link,*pnd,NULLNODE,&dot);
 | 
							'.'	{ *pnd = MkNode(Link,*pnd,NULLNODE,&dot);
 | 
				
			||||||
			  pnd = &(*pnd)->nd_right;
 | 
								  pnd = &(*pnd)->nd_right;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		IDENT
 | 
							IDENT
 | 
				
			||||||
			{ *pnd = MkNode(Value,NULLNODE,NULLNODE,&dot);
 | 
								{ *pnd = MkNode(Name,NULLNODE,NULLNODE,&dot); }
 | 
				
			||||||
			  if (types) {
 | 
					 | 
				
			||||||
				module = (df->df_kind == D_MODULE);
 | 
					 | 
				
			||||||
				df = lookup(dot.TOK_IDF, scope);
 | 
					 | 
				
			||||||
				if (!df) {
 | 
					 | 
				
			||||||
					types = 0;
 | 
					 | 
				
			||||||
					df = ill_df;
 | 
					 | 
				
			||||||
					id_not_declared(dot.TOK_IDF);
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				else
 | 
					 | 
				
			||||||
				if (module &&
 | 
					 | 
				
			||||||
				    !(df->df_flags&(D_EXPORTED|D_QEXPORTED))) {
 | 
					 | 
				
			||||||
					error("identifier \"%s\" not exported from qualifying module", dot.TOK_IDF->id_text);
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			  }
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
	]*
 | 
						]*
 | 
				
			||||||
			{ if (types && !(types & df->df_kind)) {
 | 
								{ if (types) {
 | 
				
			||||||
 | 
									*pdf = df = findname(nd);
 | 
				
			||||||
 | 
								  	if (df->df_kind != D_ERROR &&
 | 
				
			||||||
 | 
									    !(types & df->df_kind)) {
 | 
				
			||||||
					error("identifier \"%s\" is not a %s",
 | 
										error("identifier \"%s\" is not a %s",
 | 
				
			||||||
					df->df_idf->id_text, str);
 | 
										df->df_idf->id_text, str);
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
								  }
 | 
				
			||||||
			  if (!p) FreeNode(nd);
 | 
								  if (!p) FreeNode(nd);
 | 
				
			||||||
			  else *p = nd;
 | 
								  else *p = nd;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
| 
						 | 
					@ -114,6 +90,7 @@ ConstExpression(struct node **pnd;):
 | 
				
			||||||
		{ DO_DEBUG(3,
 | 
							{ DO_DEBUG(3,
 | 
				
			||||||
		     ( debug("Constant expression:"),
 | 
							     ( debug("Constant expression:"),
 | 
				
			||||||
		       PrNode(*pnd)));
 | 
							       PrNode(*pnd)));
 | 
				
			||||||
 | 
							  (void) chk_expr(*pnd, 1);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
;
 | 
					;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -209,7 +186,7 @@ factor(struct node **p;)
 | 
				
			||||||
	'(' expression(p) ')'
 | 
						'(' expression(p) ')'
 | 
				
			||||||
|
 | 
					|
 | 
				
			||||||
	NOT		{ *p = MkNode(Uoper, NULLNODE, NULLNODE, &dot); }
 | 
						NOT		{ *p = MkNode(Uoper, NULLNODE, NULLNODE, &dot); }
 | 
				
			||||||
	factor(&((*p)->nd_left))
 | 
						factor(&((*p)->nd_right))
 | 
				
			||||||
;
 | 
					;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bare_set(struct node **pnd;)
 | 
					bare_set(struct node **pnd;)
 | 
				
			||||||
| 
						 | 
					@ -218,7 +195,7 @@ bare_set(struct node **pnd;)
 | 
				
			||||||
} :
 | 
					} :
 | 
				
			||||||
	'{'		{
 | 
						'{'		{
 | 
				
			||||||
			  dot.tk_symb = SET;
 | 
								  dot.tk_symb = SET;
 | 
				
			||||||
			  *pnd = nd = MkNode(Link, NULLNODE, NULLNODE, &dot);
 | 
								  *pnd = nd = MkNode(Xset, NULLNODE, NULLNODE, &dot);
 | 
				
			||||||
			  nd->nd_type = bitset_type;
 | 
								  nd->nd_type = bitset_type;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
	[
 | 
						[
 | 
				
			||||||
| 
						 | 
					@ -261,9 +238,9 @@ designator_tail(struct node **pnd;):
 | 
				
			||||||
	visible_designator_tail(pnd)
 | 
						visible_designator_tail(pnd)
 | 
				
			||||||
	[
 | 
						[
 | 
				
			||||||
		/* selector */
 | 
							/* selector */
 | 
				
			||||||
		'.'	{ *pnd = MkNode(Oper, *pnd, NULLNODE, &dot); }
 | 
							'.'	{ *pnd = MkNode(Link, *pnd, NULLNODE, &dot); }
 | 
				
			||||||
		IDENT	{ (*pnd)->nd_right =
 | 
							IDENT	{ (*pnd)->nd_right =
 | 
				
			||||||
				MkNode(Value, NULLNODE, NULLNODE, &dot);
 | 
									MkNode(Name, NULLNODE, NULLNODE, &dot);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
	|
 | 
						|
 | 
				
			||||||
		visible_designator_tail(pnd)
 | 
							visible_designator_tail(pnd)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,12 +10,12 @@ static char *RcsId = "$Header$";
 | 
				
			||||||
#include	"idf.h"
 | 
					#include	"idf.h"
 | 
				
			||||||
#include	"LLlex.h"
 | 
					#include	"LLlex.h"
 | 
				
			||||||
#include	"Lpars.h"
 | 
					#include	"Lpars.h"
 | 
				
			||||||
#include	"main.h"
 | 
					 | 
				
			||||||
#include	"debug.h"
 | 
					#include	"debug.h"
 | 
				
			||||||
#include	"type.h"
 | 
					#include	"type.h"
 | 
				
			||||||
#include	"def.h"
 | 
					#include	"def.h"
 | 
				
			||||||
#include	"scope.h"
 | 
					#include	"scope.h"
 | 
				
			||||||
#include	"standards.h"
 | 
					#include	"standards.h"
 | 
				
			||||||
 | 
					#include	"tokenname.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
char	options[128];
 | 
					char	options[128];
 | 
				
			||||||
int	DefinitionModule; 
 | 
					int	DefinitionModule; 
 | 
				
			||||||
| 
						 | 
					@ -126,7 +126,6 @@ Option(str)
 | 
				
			||||||
add_standards()
 | 
					add_standards()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	register struct def *df;
 | 
						register struct def *df;
 | 
				
			||||||
	register struct type *tp;
 | 
					 | 
				
			||||||
	struct def *Enter();
 | 
						struct def *Enter();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	(void) Enter("ABS", D_STDFUNC, NULLTYPE, S_ABS);
 | 
						(void) Enter("ABS", D_STDFUNC, NULLTYPE, S_ABS);
 | 
				
			||||||
| 
						 | 
					@ -161,11 +160,11 @@ add_standards()
 | 
				
			||||||
		     0);
 | 
							     0);
 | 
				
			||||||
	df = Enter("BITSET", D_TYPE, bitset_type, 0);
 | 
						df = Enter("BITSET", D_TYPE, bitset_type, 0);
 | 
				
			||||||
	df = Enter("FALSE", D_ENUM, bool_type, 0);
 | 
						df = Enter("FALSE", D_ENUM, bool_type, 0);
 | 
				
			||||||
	df->df_value.df_enum.en_val = 0;
 | 
						df->enm_val = 0;
 | 
				
			||||||
	df->df_value.df_enum.en_next = Enter("TRUE", D_ENUM, bool_type, 0);
 | 
						df->enm_next = Enter("TRUE", D_ENUM, bool_type, 0);
 | 
				
			||||||
	df = df->df_value.df_enum.en_next;
 | 
						df = df->enm_next;
 | 
				
			||||||
	df->df_value.df_enum.en_val = 1;
 | 
						df->enm_val = 1;
 | 
				
			||||||
	df->df_value.df_enum.en_next = 0;
 | 
						df->enm_next = 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
init_DEFPATH()
 | 
					init_DEFPATH()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,6 +8,7 @@ static char *RcsId = "$Header$";
 | 
				
			||||||
#include	"misc.h"
 | 
					#include	"misc.h"
 | 
				
			||||||
#include	"LLlex.h"
 | 
					#include	"LLlex.h"
 | 
				
			||||||
#include	"idf.h"
 | 
					#include	"idf.h"
 | 
				
			||||||
 | 
					#include	"node.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
match_id(id1, id2)
 | 
					match_id(id1, id2)
 | 
				
			||||||
	struct idf *id1, *id2;
 | 
						struct idf *id1, *id2;
 | 
				
			||||||
| 
						 | 
					@ -40,12 +41,13 @@ gen_anon_idf()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
id_not_declared(id)
 | 
					id_not_declared(id)
 | 
				
			||||||
	struct idf *id;
 | 
						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
 | 
				
			||||||
	*/
 | 
						*/
 | 
				
			||||||
	if (!is_anon_idf(id)) {
 | 
						if (!is_anon_idf(id->nd_IDF)) {
 | 
				
			||||||
		error("identifier \"%s\" not declared", id->id_text);
 | 
							node_error(id,
 | 
				
			||||||
 | 
								"identifier \"%s\" not declared", id->nd_IDF->id_text);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,18 +7,28 @@ struct node {
 | 
				
			||||||
#define nd_left	next
 | 
					#define nd_left	next
 | 
				
			||||||
	struct node *nd_right;
 | 
						struct node *nd_right;
 | 
				
			||||||
	int nd_class;		/* kind of node */
 | 
						int nd_class;		/* kind of node */
 | 
				
			||||||
#define Value	1		/* idf or constant */
 | 
					#define Value	1		/* constant */
 | 
				
			||||||
#define Oper	2		/* binary operator */
 | 
					#define Oper	2		/* binary operator */
 | 
				
			||||||
#define Uoper	3		/* unary operator */
 | 
					#define Uoper	3		/* unary operator */
 | 
				
			||||||
#define Call	4		/* cast or procedure - or function call */
 | 
					#define Call	4		/* cast or procedure - or function call */
 | 
				
			||||||
#define Link	5
 | 
					#define Name	5		/* a qualident */
 | 
				
			||||||
 | 
					#define Set	6		/* a set constant */
 | 
				
			||||||
 | 
					#define Xset	7		/* a set */
 | 
				
			||||||
 | 
					#define Def	8		/* an identified name */
 | 
				
			||||||
 | 
					#define Link	11
 | 
				
			||||||
	struct type *nd_type;	/* type of this node */
 | 
						struct type *nd_type;	/* type of this node */
 | 
				
			||||||
	union {
 | 
						union {
 | 
				
			||||||
		struct token ndu_token;
 | 
							struct token ndu_token;	/* (Value, Oper, Uoper, Call, Name,
 | 
				
			||||||
		char *ndu_set;	/* Pointer to a set constant */
 | 
										    Link)
 | 
				
			||||||
 | 
										*/
 | 
				
			||||||
 | 
							arith *ndu_set;		/* pointer to a set constant (Set) */
 | 
				
			||||||
 | 
							struct def *ndu_def;	/* pointer to definition structure for
 | 
				
			||||||
 | 
										   identified name (Def)
 | 
				
			||||||
 | 
										*/
 | 
				
			||||||
	} nd_val;
 | 
						} nd_val;
 | 
				
			||||||
#define nd_token	nd_val.ndu_token
 | 
					#define nd_token	nd_val.ndu_token
 | 
				
			||||||
#define nd_set		nd_val.ndu_set
 | 
					#define nd_set		nd_val.ndu_set
 | 
				
			||||||
 | 
					#define nd_def		nd_val.ndu_def
 | 
				
			||||||
#define nd_symb		nd_token.tk_symb
 | 
					#define nd_symb		nd_token.tk_symb
 | 
				
			||||||
#define nd_lineno	nd_token.tk_lineno
 | 
					#define nd_lineno	nd_token.tk_lineno
 | 
				
			||||||
#define nd_filename	nd_token.tk_filename
 | 
					#define nd_filename	nd_token.tk_filename
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,7 +6,6 @@ static char *RcsId = "$Header$";
 | 
				
			||||||
#include	<em_arith.h>
 | 
					#include	<em_arith.h>
 | 
				
			||||||
#include	<alloc.h>
 | 
					#include	<alloc.h>
 | 
				
			||||||
#include	<system.h>
 | 
					#include	<system.h>
 | 
				
			||||||
#include	"main.h"
 | 
					 | 
				
			||||||
#include	"def.h"
 | 
					#include	"def.h"
 | 
				
			||||||
#include	"type.h"
 | 
					#include	"type.h"
 | 
				
			||||||
#include	"LLlex.h"
 | 
					#include	"LLlex.h"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,8 +6,8 @@ static  char *RcsId = "$Header$";
 | 
				
			||||||
#include	<alloc.h>
 | 
					#include	<alloc.h>
 | 
				
			||||||
#include	<em_arith.h>
 | 
					#include	<em_arith.h>
 | 
				
			||||||
#include	<em_label.h>
 | 
					#include	<em_label.h>
 | 
				
			||||||
#include	"idf.h"
 | 
					 | 
				
			||||||
#include	"main.h"
 | 
					#include	"main.h"
 | 
				
			||||||
 | 
					#include	"idf.h"
 | 
				
			||||||
#include	"LLlex.h"
 | 
					#include	"LLlex.h"
 | 
				
			||||||
#include	"scope.h"
 | 
					#include	"scope.h"
 | 
				
			||||||
#include	"def.h"
 | 
					#include	"def.h"
 | 
				
			||||||
| 
						 | 
					@ -148,13 +148,12 @@ DefinitionModule
 | 
				
			||||||
definition
 | 
					definition
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct def *df;
 | 
						struct def *df;
 | 
				
			||||||
	struct type *tp;
 | 
					 | 
				
			||||||
} :
 | 
					} :
 | 
				
			||||||
	CONST [ ConstantDeclaration ';' ]*
 | 
						CONST [ ConstantDeclaration ';' ]*
 | 
				
			||||||
|
 | 
					|
 | 
				
			||||||
	TYPE
 | 
						TYPE
 | 
				
			||||||
	[ IDENT 	{ df = define(dot.TOK_IDF, CurrentScope, D_TYPE); }
 | 
						[ IDENT 	{ df = define(dot.TOK_IDF, CurrentScope, D_TYPE); }
 | 
				
			||||||
	  [ '=' type(&tp)
 | 
						  [ '=' type(&(df->df_type))
 | 
				
			||||||
	  | /* empty */
 | 
						  | /* empty */
 | 
				
			||||||
	    /*
 | 
						    /*
 | 
				
			||||||
	       Here, the exported type has a hidden implementation.
 | 
						       Here, the exported type has a hidden implementation.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,7 +11,7 @@ static char *RcsId = "$Header$";
 | 
				
			||||||
#include	"scope.h"
 | 
					#include	"scope.h"
 | 
				
			||||||
#include	"type.h"
 | 
					#include	"type.h"
 | 
				
			||||||
#include	"def.h"
 | 
					#include	"def.h"
 | 
				
			||||||
#include	"main.h"
 | 
					#include	"node.h"
 | 
				
			||||||
#include	"debug.h"
 | 
					#include	"debug.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int maxscope;		/* maximum assigned scope number */
 | 
					static int maxscope;		/* maximum assigned scope number */
 | 
				
			||||||
| 
						 | 
					@ -34,7 +34,8 @@ open_scope(scopetype, scope)
 | 
				
			||||||
	register struct scope *sc1;
 | 
						register struct scope *sc1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sc->sc_scope = scope == 0 ? ++maxscope : scope;
 | 
						sc->sc_scope = scope == 0 ? ++maxscope : scope;
 | 
				
			||||||
	sc->sc_forw = 0; sc->sc_def = 0;
 | 
						sc->sc_forw = 0;
 | 
				
			||||||
 | 
						sc->sc_def = 0;
 | 
				
			||||||
	assert(scopetype == OPENSCOPE || scopetype == CLOSEDSCOPE);
 | 
						assert(scopetype == OPENSCOPE || scopetype == CLOSEDSCOPE);
 | 
				
			||||||
	DO_DEBUG(1, debug("Opening a %s scope",
 | 
						DO_DEBUG(1, debug("Opening a %s scope",
 | 
				
			||||||
			scopetype == OPENSCOPE ? "open" : "closed"));
 | 
								scopetype == OPENSCOPE ? "open" : "closed"));
 | 
				
			||||||
| 
						 | 
					@ -42,32 +43,14 @@ open_scope(scopetype, scope)
 | 
				
			||||||
	if (scopetype == CLOSEDSCOPE) {
 | 
						if (scopetype == CLOSEDSCOPE) {
 | 
				
			||||||
		sc1 = new_scope();
 | 
							sc1 = new_scope();
 | 
				
			||||||
		sc1->sc_scope = 0;		/* Pervasive scope nr */
 | 
							sc1->sc_scope = 0;		/* Pervasive scope nr */
 | 
				
			||||||
		sc1->sc_forw = 0; sc1->sc_def = 0;
 | 
							sc1->sc_forw = 0;
 | 
				
			||||||
 | 
							sc1->sc_def = 0;
 | 
				
			||||||
		sc1->next = CurrentScope;
 | 
							sc1->next = CurrentScope;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	sc->next = sc1;
 | 
						sc->next = sc1;
 | 
				
			||||||
	CurrentScope = sc;
 | 
						CurrentScope = sc;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static rem_forwards();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
close_scope()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	register struct scope *sc = CurrentScope;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	assert(sc != 0);
 | 
					 | 
				
			||||||
	DO_DEBUG(1, debug("Closing a scope"));
 | 
					 | 
				
			||||||
	if (sc->sc_forw) rem_forwards(sc->sc_forw);
 | 
					 | 
				
			||||||
	if (sc->next && (sc->next->sc_scope == 0)) {
 | 
					 | 
				
			||||||
		struct scope *sc1 = sc;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		sc = sc->next;
 | 
					 | 
				
			||||||
		free_scope(sc1);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	CurrentScope = sc->next;
 | 
					 | 
				
			||||||
	free_scope(sc);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
init_scope()
 | 
					init_scope()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	register struct scope *sc = new_scope();
 | 
						register struct scope *sc = new_scope();
 | 
				
			||||||
| 
						 | 
					@ -86,7 +69,7 @@ uniq_scope()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct forwards {
 | 
					struct forwards {
 | 
				
			||||||
	struct forwards *next;
 | 
						struct forwards *next;
 | 
				
			||||||
	struct token fo_tok;
 | 
						struct node fo_tok;
 | 
				
			||||||
	struct type **fo_ptyp;
 | 
						struct type **fo_ptyp;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -103,12 +86,29 @@ Forward(tk, ptp)
 | 
				
			||||||
	*/
 | 
						*/
 | 
				
			||||||
	register struct forwards *f = new_forwards();
 | 
						register struct forwards *f = new_forwards();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	f->fo_tok = *tk;
 | 
						f->fo_tok.nd_token = *tk;
 | 
				
			||||||
	f->fo_ptyp = ptp;
 | 
						f->fo_ptyp = ptp;
 | 
				
			||||||
	f->next = CurrentScope->sc_forw;
 | 
						f->next = CurrentScope->sc_forw;
 | 
				
			||||||
	CurrentScope->sc_forw = f;
 | 
						CurrentScope->sc_forw = f;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					close_scope()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						register struct scope *sc = CurrentScope;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						assert(sc != 0);
 | 
				
			||||||
 | 
						DO_DEBUG(1, debug("Closing a scope"));
 | 
				
			||||||
 | 
						if (sc->sc_forw) rem_forwards(sc->sc_forw);
 | 
				
			||||||
 | 
						if (sc->next && (sc->next->sc_scope == 0)) {
 | 
				
			||||||
 | 
							struct scope *sc1 = sc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							sc = sc->next;
 | 
				
			||||||
 | 
							free_scope(sc1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						CurrentScope = sc->next;
 | 
				
			||||||
 | 
						free_scope(sc);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static
 | 
					static
 | 
				
			||||||
rem_forwards(fo)
 | 
					rem_forwards(fo)
 | 
				
			||||||
	struct forwards *fo;
 | 
						struct forwards *fo;
 | 
				
			||||||
| 
						 | 
					@ -116,21 +116,17 @@ rem_forwards(fo)
 | 
				
			||||||
	/*	When closing a scope, all forward references must be resolved
 | 
						/*	When closing a scope, all forward references must be resolved
 | 
				
			||||||
	*/
 | 
						*/
 | 
				
			||||||
	register struct forwards *f;
 | 
						register struct forwards *f;
 | 
				
			||||||
	struct token savetok;
 | 
					 | 
				
			||||||
	register struct def *df;
 | 
						register struct def *df;
 | 
				
			||||||
	struct def *lookfor();
 | 
						struct def *lookfor();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	savetok = dot;
 | 
					 | 
				
			||||||
	while (f = fo) {
 | 
						while (f = fo) {
 | 
				
			||||||
		dot = f->fo_tok;
 | 
							df = lookfor(&(f->fo_tok), CurrentScope, 1);
 | 
				
			||||||
		df = lookfor(dot.TOK_IDF, CurrentScope, 1);
 | 
					 | 
				
			||||||
		if (!(df->df_kind & (D_TYPE | D_HTYPE | D_ERROR))) {
 | 
							if (!(df->df_kind & (D_TYPE | D_HTYPE | D_ERROR))) {
 | 
				
			||||||
			error("identifier \"%s\" not a type",
 | 
								node_error(&(f->fo_tok), "identifier \"%s\" not a type",
 | 
				
			||||||
			      df->df_idf->id_text);
 | 
								      df->df_idf->id_text);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		*(f->fo_ptyp) = df->df_type;
 | 
							*(f->fo_ptyp) = df->df_type;
 | 
				
			||||||
		fo = f->next;
 | 
							fo = f->next;
 | 
				
			||||||
		free_forwards(f);
 | 
							free_forwards(f);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	dot = savetok;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -79,5 +79,6 @@ TstCompat(tp1, tp2)
 | 
				
			||||||
		  || tp1 == intorcard_type
 | 
							  || tp1 == intorcard_type
 | 
				
			||||||
		  || tp1->tp_fund == POINTER
 | 
							  || tp1->tp_fund == POINTER
 | 
				
			||||||
		  )
 | 
							  )
 | 
				
			||||||
		);
 | 
							)
 | 
				
			||||||
 | 
						;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue