You can use for-loops to "chain" declarations and statements,
#mfunc foreach(arr, val)\
for (var val##_arr = arr, val##_len = array_length_1d(val##_arr), val##_ind = 0;\
val##_ind < val##_len; val##_ind++) for (var val = val##_arr[val##_ind];;break)
foreach([1,2,3], v) {
trace(v);
}(note: if you want "break" to work, you'll need a bit of extra logic)
Or write them out like you would in higher-end programming languages [with actual AST processing in macros],
#mfunc foreach(arr, val, block)\
for (var val##_arr = arr, val##_len = array_length_1d(val##_arr), val##_ind = 0;\
val##_ind < val##_len; val##_ind++) { var val = val##_arr[val##_ind]; block; }
foreach([1,2,3], v, {
trace(v);
});