If you make them a 2-of-3-to-redeem, is that the same as an (a and b) OR c transaction?
If I recall correctly, the impediment to implementing (a AND b) OR c transactions is that it should be spendable if you have c, even if you have lost all knowledge of a and/or b. So the knowledge of c has to make the knowledge of a and b redundant. In standard OP_EVAL solutions, all the information identifying a,b and c have to be contained in the transaction. If a or b are changed or forgotten then recreating the hash of the script is impossible and hence the transaction will fail.
So when redeeming an (a and b) transaction, the scriptPubKey is the standard DUP HASH160 <scriptHash> EQUALVERIFY EVAL.
The client start off the scriptSig with 0 <sig a> <sig b> and then complete it with a stored serialized script "[2 <pub a> <pub b> 2 OP_CHECKMULTISIG]" which hashes to scriptHash.
To get the (a and b) or c functionality, we keep the same scriptPubKey and when redeeming using both a and b keys, the client fills it in the normal way with 0 <sig a> <sig b>. However the stored script is "[2 <pub a> <pub b> 2 CHECKMULTISIG]<sig c>[<id> DROP <pub c> CHECKSIGVERIFY EVAL]" so in this case it's two chunks of serialized script on both sides of a signature. The scriptHash in this case is the hash of "[<id> DROP <pub c> CHECKSIGVERIFY EVAL]" and <sig c> is calculated so that CHECKSIGVERIFY will succeed when called on "0 <sig a> <sig b> [2 <pub a> <pub b> 2 OP_CHECKMULTISIG] <sig c> <pub c>"
So the total script executed in normal circumstances is
0 <sig a> <sig b> [2 <pub a> <pub b> 2 CHECKMULTISIG]<sig c>[<id> DROP <pub c> CHECKSIGVERIFY EVAL] DUP HASH160 <scriptHash> EQUALVERIFY EVAL
If all trace of keys a and b have been forgotten then the transaction is redeemed in a different way by using the knowledge of the private key for key c to generate a new signature <sig c'> such that CHECKSIGVERIFY succeeds when called on "[TRUE]<sig c'> <pub c>"
So the total script executed in the event that keys a and b are lost is
[TRUE]<sig c'> [<id> DROP <pub c> CHECKSIGVERIFY EVAL] DUP HASH160 <scriptHash> EQUALVERIFY EVAL
It's unfortunate that the private key for c needs to be kept around to create the sandwiched signature <sig c> which is different for different pubkeys a or b but I doubt there is a way round that without considerably increasing the complexity of the transaction (or scripting language). Fortunately, if a range of pubkeys <pub a> and <pub b> are known in advance, the signatures <sig c> for each pair can be generated at the time and stored in the wallet. The private key for c can then be erased from the computer and kept in a safe.
The DROPed parameter <id> is intended to be an easily bruteforced number which serves to make <scriptHash> different for different <pub a> or <pub b> otherwise a transaction requiring <a and b> or c would have the same address as <p and q> or c. If the wallet is lost then the stored scripts which tie the <id> to the <pub a> <pub b> pairs are lost. To redeem the transactions using the secret key for <pub c> in the safe, the value of <id> must be searched until the hash of "[<id> DROP <pub c> CHEKCSIGVERIFY EVAL]" matches the address of the transaction to be redeemed.
So, indeed, recursive EVALs have their uses.