Its a common misunderstanding. There are two parts to the SAS system:
Base SAS - this is the programming language, has all the data types, functions etc. It should be used 99% of the time.
Macro - this is a text find/replace system, which happens before the compilation phase. It is only there to generate text (which may be code).
The two systems are distinct and do not overlap. So when looking at macro code, you just need to see what text it generates:
1)
%let y=1; /* Note its good practice to put let statements outside base code */
data A;
do i = 1 to 5;
y = &y. + i; /* Note its good practice to put a . after all macro variables */
output;
end;
run;
Resolves after the pre-processor to:
data A;
do i = 1 to 5;
y = 1 + i;
output;
end;
run;
Which is valid Base code and will output the rows given in the do loop to a dataset.
2)
%macro test();
%let y=1;
%do j=1 %to 5;
y = &y. + &j.;
%end;
%mend test;
%test;
Resolves after the pre-processor to:
y = 1 + 1;
y = 1 + 2;
y = 1 + 3;
y = 1 + 4;
y = 1 + 5;
Which as you can see, on its own is not valid Base SAS code.
In this example it is clear that using the data step is the way forward, there is nothing to be gained by creating macro code, and you will just end up with a messier less perfomant version. Macro does have a use, but replacing Base SAS is not it. Now to correct your second code:
%macro test();
%let y=1;
%do j=1 %to 5;
y = &y. + &j.;
output;
%end;
%mend test;
data want;
%test;
run;