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); });