Fossil SCM

Add "foreach" loops to TH1.

drh 2021-01-26 13:50 trunk
Commit 3316b29225dc6048a8accf9a3466f47fbbb8260324edc415faee2469ce697e65
2 files changed +41 +1
--- src/th_lang.c
+++ src/th_lang.c
@@ -162,10 +162,50 @@
162162
return rc;
163163
}
164164
165165
/*
166166
** TH Syntax:
167
+**
168
+** foreach VARLIST LIST SCRIPT
169
+*/
170
+static int foreach_command(
171
+ Th_Interp *interp,
172
+ void *ctx,
173
+ int argc,
174
+ const char **argv,
175
+ int *argl
176
+){
177
+ int rc;
178
+ char **azVar = 0;
179
+ int *anVar;
180
+ int nVar;
181
+ char **azValue = 0;
182
+ int *anValue;
183
+ int nValue;
184
+ int ii, jj;
185
+
186
+ if( argc!=4 ){
187
+ return Th_WrongNumArgs(interp, "foreach varlist list script");
188
+ }
189
+ rc = Th_SplitList(interp, argv[1], argl[1], &azVar, &anVar, &nVar);
190
+ if( rc ) return rc;
191
+ rc = Th_SplitList(interp, argv[2], argl[2], &azValue, &anValue, &nValue);
192
+ for(ii=0; rc==TH_OK && ii<=nValue-nVar; ii+=nVar){
193
+ for(jj=0; jj<nVar; jj++){
194
+ Th_SetVar(interp, azVar[jj], anVar[jj], azValue[ii+jj], anValue[ii+jj]);
195
+ }
196
+ rc = eval_loopbody(interp, argv[3], argl[3]);
197
+ }
198
+ if( rc==TH_BREAK ) rc = TH_OK;
199
+ Th_Free(interp, azVar);
200
+ Th_Free(interp, azValue);
201
+ return rc;
202
+}
203
+
204
+
205
+/*
206
+** TH Syntax:
167207
**
168208
** list ?arg1 ?arg2? ...?
169209
*/
170210
static int list_command(
171211
Th_Interp *interp,
@@ -1286,10 +1326,11 @@
12861326
} aCommand[] = {
12871327
{"array", array_command, 0},
12881328
{"catch", catch_command, 0},
12891329
{"expr", expr_command, 0},
12901330
{"for", for_command, 0},
1331
+ {"foreach", foreach_command, 0},
12911332
{"if", if_command, 0},
12921333
{"info", info_command, 0},
12931334
{"lindex", lindex_command, 0},
12941335
{"list", list_command, 0},
12951336
{"llength", llength_command, 0},
12961337
--- src/th_lang.c
+++ src/th_lang.c
@@ -162,10 +162,50 @@
162 return rc;
163 }
164
165 /*
166 ** TH Syntax:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
167 **
168 ** list ?arg1 ?arg2? ...?
169 */
170 static int list_command(
171 Th_Interp *interp,
@@ -1286,10 +1326,11 @@
1286 } aCommand[] = {
1287 {"array", array_command, 0},
1288 {"catch", catch_command, 0},
1289 {"expr", expr_command, 0},
1290 {"for", for_command, 0},
 
1291 {"if", if_command, 0},
1292 {"info", info_command, 0},
1293 {"lindex", lindex_command, 0},
1294 {"list", list_command, 0},
1295 {"llength", llength_command, 0},
1296
--- src/th_lang.c
+++ src/th_lang.c
@@ -162,10 +162,50 @@
162 return rc;
163 }
164
165 /*
166 ** TH Syntax:
167 **
168 ** foreach VARLIST LIST SCRIPT
169 */
170 static int foreach_command(
171 Th_Interp *interp,
172 void *ctx,
173 int argc,
174 const char **argv,
175 int *argl
176 ){
177 int rc;
178 char **azVar = 0;
179 int *anVar;
180 int nVar;
181 char **azValue = 0;
182 int *anValue;
183 int nValue;
184 int ii, jj;
185
186 if( argc!=4 ){
187 return Th_WrongNumArgs(interp, "foreach varlist list script");
188 }
189 rc = Th_SplitList(interp, argv[1], argl[1], &azVar, &anVar, &nVar);
190 if( rc ) return rc;
191 rc = Th_SplitList(interp, argv[2], argl[2], &azValue, &anValue, &nValue);
192 for(ii=0; rc==TH_OK && ii<=nValue-nVar; ii+=nVar){
193 for(jj=0; jj<nVar; jj++){
194 Th_SetVar(interp, azVar[jj], anVar[jj], azValue[ii+jj], anValue[ii+jj]);
195 }
196 rc = eval_loopbody(interp, argv[3], argl[3]);
197 }
198 if( rc==TH_BREAK ) rc = TH_OK;
199 Th_Free(interp, azVar);
200 Th_Free(interp, azValue);
201 return rc;
202 }
203
204
205 /*
206 ** TH Syntax:
207 **
208 ** list ?arg1 ?arg2? ...?
209 */
210 static int list_command(
211 Th_Interp *interp,
@@ -1286,10 +1326,11 @@
1326 } aCommand[] = {
1327 {"array", array_command, 0},
1328 {"catch", catch_command, 0},
1329 {"expr", expr_command, 0},
1330 {"for", for_command, 0},
1331 {"foreach", foreach_command, 0},
1332 {"if", if_command, 0},
1333 {"info", info_command, 0},
1334 {"lindex", lindex_command, 0},
1335 {"list", list_command, 0},
1336 {"llength", llength_command, 0},
1337
+1
--- www/th1.md
+++ www/th1.md
@@ -123,10 +123,11 @@
123123
* catch SCRIPT ?VARIABLE?
124124
* continue
125125
* error ?STRING?
126126
* expr EXPR
127127
* for INIT-SCRIPT TEST-EXPR NEXT-SCRIPT BODY-SCRIPT
128
+ * foreach VARIABLE-LIST VALUE-LIST BODY-SCRIPT
128129
* if EXPR SCRIPT (elseif EXPR SCRIPT)* ?else SCRIPT?
129130
* info commands
130131
* info exists VARNAME
131132
* info vars
132133
* lindex LIST INDEX
133134
--- www/th1.md
+++ www/th1.md
@@ -123,10 +123,11 @@
123 * catch SCRIPT ?VARIABLE?
124 * continue
125 * error ?STRING?
126 * expr EXPR
127 * for INIT-SCRIPT TEST-EXPR NEXT-SCRIPT BODY-SCRIPT
 
128 * if EXPR SCRIPT (elseif EXPR SCRIPT)* ?else SCRIPT?
129 * info commands
130 * info exists VARNAME
131 * info vars
132 * lindex LIST INDEX
133
--- www/th1.md
+++ www/th1.md
@@ -123,10 +123,11 @@
123 * catch SCRIPT ?VARIABLE?
124 * continue
125 * error ?STRING?
126 * expr EXPR
127 * for INIT-SCRIPT TEST-EXPR NEXT-SCRIPT BODY-SCRIPT
128 * foreach VARIABLE-LIST VALUE-LIST BODY-SCRIPT
129 * if EXPR SCRIPT (elseif EXPR SCRIPT)* ?else SCRIPT?
130 * info commands
131 * info exists VARNAME
132 * info vars
133 * lindex LIST INDEX
134

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button