Re: looping over a range

From: Alexandre Ratchov <alex_at_caoua.org>
Date: Tue, 3 Aug 2021 22:59:49 +0200
On Mon, Aug 02, 2021 at 01:51:10PM +0200, Jeanette C. wrote:
> Hey hey,
> I'd love to loop a variable over a numerical range. the goal is to
> alternately process groups of measures on a track. I naively tried and
> failed with:
> for beat in {1..100{ {
>   g ($beat * 2);
>   sel 2;
>   if (($beat % 2) == 0) {
>     ... # processing here
>   } else {
>     ... # Alternate processing here
>   }
> }
> 
> It failed, because the variable beat was set to 1:100. Short of putting in
> all the numbers I can't see how to achieve this goal. Any ideas, please?
> 

Hi,

Here's diff to make "for" use ranges, could you confirm it works for
you?

diff --git a/node.c b/node.c
index 4eca6af..60c28c8 100644
--- a/node.c
+++ b/node.c
_at_@ -400,11 +400,13 @@ node_exec_for(struct node *o, struct exec *x, struct data **r)
 	unsigned result;
 	struct data *list, *i;
 	struct var *v;
+
 	if (node_exec(o->list, x, &list) == RESULT_ERR) {
 		return RESULT_ERR;
 	}
-	if (list->type != DATA_LIST) {
-		cons_errs(x->procname, "argument to 'for' must be a list");
+	if (list->type != DATA_LIST && list->type != DATA_RANGE) {
+		cons_errs(x->procname,
+		    "argument to 'for' must be a list or range");
 		return RESULT_ERR;
 	}
 	v = exec_varlookup(x, o->data->val.ref);
_at_@ -412,15 +414,36 @@ node_exec_for(struct node *o, struct exec *x, struct data **r)
 		v = var_new(x->locals, o->data->val.ref, data_newnil());
 	}
 	result = RESULT_OK;
-	for (i = list->val.list; i != NULL; i = i->next) {
-		data_assign(v->data, i);
-		result = node_exec(o->list->next, x, r);
-		if (result == RESULT_CONTINUE) {
-			continue;
-		} else if (result == RESULT_BREAK) {
-			break;
-		} else if (result != RESULT_OK) {
-			break;
+	if (list->type == DATA_LIST) {
+		for (i = list->val.list; i != NULL; i = i->next) {
+			data_assign(v->data, i);
+			result = node_exec(o->list->next, x, r);
+			if (result == RESULT_CONTINUE) {
+				continue;
+			} else if (result == RESULT_BREAK) {
+				break;
+			} else if (result != RESULT_OK) {
+				break;
+			}
+		}
+	} else {
+		if (list->val.range.min <= list->val.range.max) {
+			i = data_newlong(list->val.range.min);
+			while (1) {
+				data_assign(v->data, i);
+				result = node_exec(o->list->next, x, r);
+				if (result == RESULT_CONTINUE) {
+					continue;
+				} else if (result == RESULT_BREAK) {
+					break;
+				} else if (result != RESULT_OK) {
+					break;
+				}
+				if (i->val.num == list->val.range.max)
+					break;
+				i->val.num++;
+			}
+			data_delete(i);
 		}
 	}
 	data_delete(list);
Received on Tue Aug 03 2021 - 22:59:49 CEST

This archive was generated by hypermail 2.3.0 : Wed Aug 04 2021 - 01:34:26 CEST