Przeglądaj źródła

fix: resolve forward references if definition is needed in lookfor()

ceriel 36 lat temu
rodzic
commit
a2464a4fa5
4 zmienionych plików z 58 dodań i 15 usunięć
  1. 32 9
      lang/m2/comp/Makefile
  2. 4 1
      lang/m2/comp/Resolve
  3. 1 0
      lang/m2/comp/def.c
  4. 21 5
      lang/m2/comp/lookup.c

+ 32 - 9
lang/m2/comp/Makefile

@@ -12,13 +12,15 @@ CID =		$(EMHOME)/bin/cid
 CURRDIR =	.
 
 INCLUDES = -I$(MHDIR) -I$(EMHOME)/h -I$(PKGDIR)
+OLIBS = $(LIBDIR)/libem_mes.a $(OBJECTCODE) $(LIBDIR)/libinput.a $(LIBDIR)/libassert.a $(LIBDIR)/liballoc.a $(MALLOC) $(LIBDIR)/libprint.a $(LIBDIR)/libstring.a $(LIBDIR)/libsystem.a
 
 GF =	program.g declar.g expression.g statement.g
 GENGFILES=	tokenfile.g
 GFILES =$(GENGFILES) $(GF)
 LLGENOPTIONS = -v
 PROFILE =
-CFLAGS = $(PROFILE) $(INCLUDES) -O -DSTATIC=
+COPTIONS=
+CFLAGS = $(PROFILE) $(INCLUDES) $(COPTIONS) -O -DSTATIC=
 LINTFLAGS = -DSTATIC= -DNORCSID
 MALLOC = $(LIBDIR)/malloc.o
 LDFLAGS = -i $(PROFILE)
@@ -56,6 +58,18 @@ all:	Cfiles
 	sh -c 'if $(CC) nmclash.c > /dev/null 2>&1 ; then make "EMHOME="$(EMHOME) $(CURRDIR)/main ; else EMHOME=$(EMHOME); export EMHOME; sh Resolve main ; fi'
 	@rm -f nmclash.o a.out
 
+Omain:	Cfiles
+	rm -f *.o
+	sh -c 'if $(CC) nmclash.c > /dev/null 2>&1 ; then make "EMHOME="$(EMHOME) "COPTIONS="-DPEEPHOLE $(CURRDIR)/omain ; else EMHOME=$(EMHOME); export EMHOME; ./Resolve omain ; fi'
+	@rm -f nmclash.o a.out
+	mv *.o PEEPHOLE
+
+CEmain: Cfiles
+	rm -f *.o
+	sh -c 'if $(CC) nmclash.c > /dev/null 2>&1 ; then make "EMHOME="$(EMHOME) "COPTIONS="-DCODE_EXPANDER $(CURRDIR)/cemain ; else EMHOME=$(EMHOME); export EMHOME; ./Resolve cemain ; fi'
+	@rm -f nmclash.o a.out
+	mv *.o CODE_EXPANDER
+
 install:	all
 	cp $(CURRDIR)/main $(EMHOME)/lib/em_m2
 	rm -f $(EMHOME)/man/em_m2.6 $(EMHOME)/man/modula-2.1
@@ -63,8 +77,8 @@ install:	all
 
 cmp:	all
 	-cmp $(CURRDIR)/main $(EMHOME)/lib/em_m2
-	-cmp $(CURRDIR)/em_m2.6 $(EMHOME)/man/em_m2.6 
-	-cmp $(CURRDIR)/modula-2.1 $(EMHOME)/man/modula-2.1 
+	-cmp $(CURRDIR)/em_m2.6 $(EMHOME)/man/em_m2.6
+	-cmp $(CURRDIR)/modula-2.1 $(EMHOME)/man/modula-2.1
 
 opr:
 	make pr | opr
@@ -86,14 +100,14 @@ longnames:	$(SRC) $(HFILES)
 
 # entry points not to be used directly
 
-Cfiles:	hfiles LLfiles $(GENC) $(GENH) Makefile
+Cfiles: hfiles LLfiles $(GENC) $(GENH) Makefile
 	echo $(SRC) $(HFILES) > Cfiles
 
 LLfiles:	$(GFILES)
 	$(LLGEN) $(LLGENOPTIONS) $(GFILES)
 	@touch LLfiles
 
-hfiles:	Parameters make.hfiles
+hfiles: Parameters make.hfiles
 	make.hfiles Parameters
 	touch hfiles
 
@@ -125,10 +139,10 @@ next.c:		$(NEXTFILES) ./make.next
 char.c: char.tab tab
 	tab -fchar.tab >char.c
 
-tab: 
+tab:
 	$(CC) tab.c -o tab
 
-depend:	Cfiles
+depend: Cfiles
 	sed '/^#AUTOAUTO/,$$d' Makefile > Makefile.new
 	echo '#AUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTO' >> Makefile.new
 	$(MKDEP) $(SRC) |\
@@ -149,10 +163,19 @@ Xlint:
 		$(LIBDIR)/llib-lstring.ln \
 		$(LIBDIR)/llib-lsystem.ln
 
-$(CURRDIR)/main:	$(OBJ)
-	$(CC) $(LDFLAGS) $(OBJ) $(LIBDIR)/libem_mes.a $(OBJECTCODE) $(LIBDIR)/libinput.a $(LIBDIR)/libassert.a $(LIBDIR)/liballoc.a $(MALLOC) $(LIBDIR)/libprint.a $(LIBDIR)/libstring.a $(LIBDIR)/libsystem.a -o $(CURRDIR)/main
+$(CURRDIR)/main:	$(OBJ) $(CURRDIR)/Makefile
+	$(CC) $(LDFLAGS) $(OBJ) $(OLIBS) -o $(CURRDIR)/main
 	-size $(CURRDIR)/main
 
+$(CURRDIR)/omain:	$(OBJ) $(CURRDIR)/Makefile
+	$(CC) $(LDFLAGS) $(OBJ) $(OLIBS) -o $(CURRDIR)/omain
+	size $(CURRDIR)/omain
+
+$(CURRDIR)/cemain:      $(OBJ) $(CURRDIR)/Makefile
+	$(CC) $(LDFLAGS) $(OBJ) $(OLIBS) -o $(CURRDIR)/cemain 
+	size $(CURRDIR)/cemain
+
+
 #AUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTO
 LLlex.o: LLlex.h
 LLlex.o: Lpars.h

+ 4 - 1
lang/m2/comp/Resolve

@@ -12,6 +12,9 @@ currdir=`pwd`
 case $1 in
 main)	target=$currdir/$1
 	;;
+omain)	target=$currdir/$1
+	options=-DPEEPHOLE
+	;;
 Xlint)	target=$1
 	;;
 *)	echo "$0: $1: Illegal argument" 1>&2
@@ -51,4 +54,4 @@ $i:	clashes $PW/$i
 	\$(CID) -Fclashes < $PW/$i > $i
 EOF
 done
-make EMHOME=$EMHOME CURRDIR=$currdir $target
+make EMHOME=$EMHOME CURRDIR=$currdir COPTIONS=$options $target

+ 1 - 0
lang/m2/comp/def.c

@@ -111,6 +111,7 @@ define(id, scope, kind)
 	*/
 	register t_def *df;
 
+	DO_DEBUG(options['S'], print("define %s, %x\n", id->id_text, kind));
 	df = lookup(id, scope, D_IMPORT, 0);
 	if (	/* Already in this scope */
 		df

+ 21 - 5
lang/m2/comp/lookup.c

@@ -24,6 +24,9 @@
 #include	"misc.h"
 
 extern int	pass_1;
+#ifdef DEBUG
+extern char	options[];
+#endif
 
 t_def *
 lookup(id, scope, import, flags)
@@ -65,6 +68,7 @@ lookup(id, scope, import, flags)
 			assert(df->imp_def != 0);
 			df = df->imp_def;
 		}
+		DO_DEBUG(options['S'], print("lookup %s, %x\n", id->id_text, df->df_kind));
 	}
 	return df;
 }
@@ -78,24 +82,36 @@ lookfor(id, vis, message, flags)
 		If it is not defined create a dummy definition and,
 		if message is set, give an error message
 	*/
-	register t_scopelist *sc = vis;
+	register t_scopelist *sc;
+	t_scopelist *sc1 = 0;
 	t_def *df;
 
-	while (sc) {
+	for (sc = vis; sc; sc = nextvisible(sc)) {
 		df = lookup(id->nd_IDF, sc->sc_scope, D_IMPORTED, flags);
 		if (df) {
+			if (message && df->df_kind == D_FORWARD) {
+				if (! sc1) sc1 = sc;
+				while (sc && sc->sc_scope != df->df_scope) {
+					sc = enclosing(sc);
+				}
+				if (sc) continue;
+				break;
+			}
 			if (pass_1 && message) {
+				if (sc1) sc = sc1;
 				while (vis->sc_scope->sc_level >
-				       sc->sc_scope->sc_level) {
+				       sc->sc_scope->sc_level ||
+				       (sc1 &&
+					vis->sc_scope->sc_level >=
+					sc->sc_scope->sc_level)) {
 					define( id->nd_IDF,
 						vis->sc_scope,
 						D_INUSE)-> imp_def = df;
-					vis = nextvisible(vis);
+					vis = enclosing(vis);
 				}
 			}
 			return df;
 		}
-		sc = nextvisible(sc);
 	}
 
 	if (message) id_not_declared(id);