Quake does something like this (if I remember right):
void WeaponAnim1= [WeaponAnim2]{self.weaponframe=1;};
void WeaponAnim2= [WeaponAnim3]{self.weaponframe=2;};
void WeaponAnim3= [WeaponAnim4]{self.weaponframe=3;};
void WeaponAnim4= [WeaponAnim5]{self.weaponframe=4;};
void WeaponAnim5= [WeaponAnim6]{self.weaponframe=5;};
void WeaponAnim6= [WeaponAnim7]{self.weaponframe=6;};
void WeaponAnim7= [WeaponAnim8]{self.weaponframe=7;};
void WeaponAnim8= [WeaponAnim9]{self.weaponframe=8;};
void WeaponAnim9= [WeaponAnim10]{self.weaponframe=9;};
void WeaponAnim10= [IdleAnim]{self.weaponframe=10;};
And you'd just call WeaponAnim1 from the weapon firing function.
HOWEVER, you could just write a function that advances the weaponframe by 1 and is called each frame to accomplish the task of animation.
The first method is fine for animations with hardly any frames, but once you start getting weapons with up to 100 frames then you'll want to try the second method.
For UrbanWars, I use two functions. One initializes an animation (sets the start frame, and end frame, and the rate of animation) and another one which advances the current frame until it reaches the end frame.