*! version 1.0.2 September 17, 2007 @ 17:22:22 *! splits up a statement based on sets and rewrites it as a command Stata can understand program define _set2logic, rclass version 9.2 /* 1.0.2 - bugfix to glaring error in compound ranges */ /* 1.0.1 - syntax fixed to allow any name */ /* 1.0.0 - does not understand grouping, since these are supposed to be relatively simple statements */ /* syntax: */ /* use . for infinity (ugly) */ /* peel off name to be used */ tokenize `"`*'"' local theName `1' mac shift tokenize `"`*'"', parse("&|") if `"`2'"' == "" { /* have a single expression or a not */ tokenize `"`*'"', parse("~!") local cnt 1 while `"``cnt''"' == "~" | `"``cnt''"'== "!" { local nots "`nots'``cnt''" local cnt = `cnt' + 1 } local item `"``cnt''"' /* to make life easier */ /* first try to use first item as numlist */ capture _stata2logic, values(`item') if !_rc { local chunk "inlist(`theName',`r(theList)')" } else { tokenize `"`item'"', parse("{}") if `"`1'"'=="{" { if `"`3'"'!="}" { ERROR `"`item'"' } local chunk "inlist(`theName',`2')" } else { tokenize `"`item'"', parse("([,])") if `"`3'"'=="," & (`"`1'"'=="(" | `"`1'"'=="[") & (`"`5'"'==")" | `"`5'"'=="]") { local chunk "inrange(`theName',`2',`4')" if "`1'"=="(" & "`2'"!="-." { local chunk "`chunk' & `theName'!=`2'" local parenflag "true" } if "`5'"==")" & "`4'"!="." { local chunk "`chunk' & `theName'!=`4'" local parenflag "true" } } else { ERROR `item' } } } if "`parenflag'"!="" { local chunk "(`chunk')" } if "`nots'"!="" { local chunk (`nots' `chunk') } return local logic `chunk' } /* end test for single expression */ else { _set2logic `theName' `1' local left `r(logic)' local conj `2' macro shift 2 _set2logic `theName' `*' return local logic "`left' `conj' `r(logic)'" } end program define ERROR display as error `"found bad token: `*'"' exit 119 // odd error number better for testing end