[Aldor-l] Generators

Peter Broadbery p_broadbery at hotmail.com
Tue Nov 6 17:52:23 EST 2007



This patch should (emphasis on that word there) implement 'for (x, y) in ...'.

Peter

Index: axl_y.c
===================================================================
--- gf_gener.c	(revision 15)
+++ gf_gener.c	(working copy)
@@ -710,6 +710,10 @@
 			lst = listNConcat(AbSyn)(gen0FindIterVars(abArgv(ab)[i]), lst);
 		break;
 	case AB_Comma:
+		lst = listNil(AbSyn);
+		for (i=0; i < abArgc(ab); i++)
+			lst = listNConcat(AbSyn)(gen0FindIterVars(abArgv(ab)[i]), lst);
+		break;
 	default:
 		msg = "bad iterator passed to gen0FindIterVars";
 		comsgFatal(ab, ALDOR_F_Bug, msg);
Index: abcheck.c
===================================================================
--- abcheck.c	(revision 15)
+++ abcheck.c	(working copy)
@@ -594,8 +594,38 @@
 }
 
 local void
-abCheckFor0(AbSyn var)
+abCheckFor0(AbSyn lhs)
 {
+	AbSyn	*argv	= abArgvAs(AB_Comma, lhs);
+	Length	i, argc	= abArgcAs(AB_Comma, lhs);
+
+	for (i = 0; i < argc; i += 1) {
+		AbSyn	arg = argv[i];
+
+		switch (abTag(arg)) {
+		case AB_Id:
+			break;
+
+		case AB_Apply:
+                  comsgError(arg, ALDOR_E_ChkBadFor);
+                  break;
+                  
+		case AB_Declare:
+			if (abHasTag(lhs, AB_Comma) &&
+			    abHasTag(arg->abDeclare.id, AB_Comma))
+				comsgError(arg, ALDOR_E_ChkBadFor);
+			break;
+
+		default:
+			comsgError(arg, ALDOR_E_ChkBadFor);
+			break;
+		}
+	}
+}
+
+local void
+abCheckFor0_old(AbSyn var)
+{
 	switch (abTag(var)) {
 	case AB_Id:
 		break;
Index: genfoam.c
===================================================================
--- genfoam.c	(revision 15)
+++ genfoam.c	(working copy)
@@ -6234,26 +6234,37 @@
 	call->foamCCall.type = FOAM_NOp;
 	call->foamCCall.op   = foamCopy(stepFun);
 	gen0AddStmt(call, absyn);
+
 	/* Have we finished */	
 	call = foamNewEmpty(FOAM_CCall, 2);
 	call->foamCCall.type = FOAM_Word;
 	call->foamCCall.op   = foamCopy(doneFun);
 	gen0AddStmt(foamNewIf(foamNewCast(FOAM_Bool, call), gen0BreakLabel),
 		    absyn);
+
 	/* Snarf the value...*/
-	id = abDefineeId(absyn);
-        call = foamNewEmpty(FOAM_CCall, 2);
-	call->foamCCall.type = gen0Type(gen0AbContextType(id), NULL);
-	call->foamCCall.op   = foamCopy(valueFun);
-	gen0AddStmt(foamNewSet(genFoamVal(id), call), absyn);
-	
-	if (!abIsNothing(absyn->abFor.test)) {
-		int  l1     = gen0State->labelNo++;
-		Foam test   = genFoamBit(absyn->abFor.test);
-		gen0AddStmt(foamNewIf(test, l1), absyn);
-		gen0AddStmt(foamNewGoto(gen0IterateLabel), absyn);
-		gen0AddStmt(foamNewLabel(l1), absyn);
-	}
+        /*         -- PAB 
+                   id = abDefineeId(absyn);
+                   call = foamNewEmpty(FOAM_CCall, 2);
+                   call->foamCCall.type = gen0Type(gen0AbContextType(id), NULL);
+                   call->foamCCall.op   = foamCopy(valueFun);
+                   gen0AddStmt(foamNewSet(genFoamVal(id), call), absyn);
+	*/
+        if (abTag(absyn->abFor.lhs) == AB_Comma) {
+                call = foamNewEmpty(FOAM_CCall, 2);
+                call->foamCCall.type = FOAM_Rec;
+                call->foamCCall.op   = foamCopy(valueFun);
+                call = gen0CrossToMulti(call, abTUnique(absyn->abFor.lhs));
+                gen0MultiAssign(FOAM_Set, absyn->abFor.lhs, call);
+        }
+        else {
+                id = abDefineeId(absyn);
+                call = foamNewEmpty(FOAM_CCall, 2);
+                call->foamCCall.type = gen0Type(gen0AbContextType(id), NULL);
+                call->foamCCall.op   = foamCopy(valueFun);
+                gen0AddStmt(foamNewSet(genFoamVal(id), call), absyn);
+        }
+
 	return;
 }
 

_________________________________________________________________
100’s of Music vouchers to be won with MSN Music
https://www.musicmashup.co.uk


More information about the Aldor-l mailing list