There are quite some problems with your code. I'll go through them one by one.
`y'_`m' evaluates to 2012_1 the first iteration. Since it contains an underscore it cannot be interpreted as numeric. To be interpreted as a string value would require it to be enclosed in "". In the end, Stata tries to interpret it as a variable but 2012_1 is not a valid name (has to start with a letter), hence your error.
You could enclose your value in quotes to create a string variable: "`y'_`m'". This will work for the first iteration, but the second iteration you will get an error, since variable 'date' already exists. After creating a variable, you can only replace it.
Finally, your code says nothing about which value goes to which observation. Even if you would fix the problems already mentioned, your variable will just contain the same values for all observations which is the value of the last iteration in the loop. To replace only one observation you have to specify in i where i is the observation number.
All in all, this would be the amended code:
gen date = "."
local obs = 1
forval y=2012/2013{
forval m=1/2{
display `m'
replace date = "`y'_`m'" in `obs'
local ++obs
}
}
However, I would not recommend creating this type of date variable, as string variables are limited in what you can do with it. Stata's internal date format is the most convenient. If your values 1 and 2 represent half years you could create a half-yearly date variable, see help datetime for information on how to do this. Another option is to create a numeric variable containing the year, and a second numeric variable containing 1 and 2.