00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 #ifndef Fennel_JumpInstruction_Included
00027 #define Fennel_JumpInstruction_Included
00028 
00029 #include "fennel/calculator/Instruction.h"
00030 
00031 FENNEL_BEGIN_NAMESPACE
00032 
00033 class FENNEL_CALCULATOR_EXPORT JumpInstruction
00034     : public Instruction
00035 {
00036 public:
00037     explicit
00038     JumpInstruction(TProgramCounter pc) : mJumpTo(pc), mOp() {}
00039 
00040     explicit
00041     JumpInstruction(
00042         TProgramCounter pc,
00043         RegisterRef<bool>* op)
00044         : mJumpTo(pc), mOp(op)
00045     {}
00046 
00047     virtual
00048     ~JumpInstruction() {}
00049 
00050 protected:
00051     TProgramCounter mJumpTo;
00052     RegisterRef<bool>* mOp;     
00053 
00054     virtual void describeHelper(
00055         string &out,
00056         bool values,
00057         const char* longName,
00058         const char* shortName) const;
00059 };
00060 
00061 class FENNEL_CALCULATOR_EXPORT Jump
00062     : public JumpInstruction
00063 {
00064 public:
00065     explicit
00066     Jump(TProgramCounter pc)
00067         : JumpInstruction(pc)
00068     {}
00069 
00070     virtual
00071     ~Jump() {}
00072 
00073     virtual void exec(TProgramCounter& pc) const {
00074         pc = mJumpTo;
00075     }
00076 
00077     static const char * longName();
00078     static const char * shortName();
00079     static int numArgs();
00080     void describe(string& out, bool values) const;
00081 
00082     static InstructionSignature
00083     signature(StandardTypeDescriptorOrdinal type) {
00084         vector<StandardTypeDescriptorOrdinal> v(numArgs(), type);
00085         return InstructionSignature(shortName(), 0, v);
00086     }
00087 
00088     static Instruction*
00089     create(InstructionSignature const & sig)
00090     {
00091         assert(sig.size() == numArgs());
00092         return new Jump(sig.getPc());
00093     }
00094 };
00095 
00096 class FENNEL_CALCULATOR_EXPORT JumpTrue
00097     : public JumpInstruction
00098 {
00099 public:
00100     explicit
00101     JumpTrue(TProgramCounter pc, RegisterRef<bool>* op)
00102         : JumpInstruction (pc, op)
00103     {}
00104 
00105     virtual
00106     ~JumpTrue() {}
00107 
00108     virtual void exec(TProgramCounter& pc) const {
00109         if (!mOp->isNull() && mOp->value() == true) {
00110             pc = mJumpTo;
00111         } else {
00112             pc++;
00113         }
00114     }
00115 
00116     static const char * longName();
00117     static const char * shortName();
00118     static int numArgs();
00119     void describe(string& out, bool values) const;
00120 
00121     static InstructionSignature
00122     signature(StandardTypeDescriptorOrdinal type) {
00123         vector<StandardTypeDescriptorOrdinal> v(numArgs(), type);
00124         return InstructionSignature(shortName(), 0, v);
00125     }
00126 
00127     static Instruction*
00128     create(InstructionSignature const & sig)
00129     {
00130         assert(sig.size() == numArgs());
00131         return new JumpTrue(
00132             sig.getPc(),
00133             static_cast<RegisterRef<bool>*> (sig[0]));
00134     }
00135 };
00136 
00137 class FENNEL_CALCULATOR_EXPORT JumpFalse
00138     : public JumpInstruction
00139 {
00140 public:
00141     explicit
00142     JumpFalse(TProgramCounter pc, RegisterRef<bool>* op)
00143         : JumpInstruction (pc, op)
00144     {}
00145 
00146     virtual
00147     ~JumpFalse() {}
00148 
00149     virtual void exec(TProgramCounter& pc) const {
00150         if (!mOp->isNull() && mOp->value() == false) {
00151             pc = mJumpTo;
00152         } else {
00153             pc++;
00154         }
00155     }
00156 
00157     static const char * longName();
00158     static const char * shortName();
00159     static int numArgs();
00160     void describe(string& out, bool values) const;
00161 
00162     static InstructionSignature
00163     signature(StandardTypeDescriptorOrdinal type) {
00164         vector<StandardTypeDescriptorOrdinal> v(numArgs(), type);
00165         return InstructionSignature(shortName(), 0, v);
00166     }
00167 
00168     static Instruction*
00169     create(InstructionSignature const & sig)
00170     {
00171         assert(sig.size() == numArgs());
00172         return new JumpFalse(
00173             sig.getPc(),
00174             static_cast<RegisterRef<bool>*> (sig[0]));
00175     }
00176 
00177 };
00178 
00179 class FENNEL_CALCULATOR_EXPORT JumpNull
00180     : public JumpInstruction
00181 {
00182 public:
00183     explicit
00184     JumpNull(TProgramCounter pc, RegisterRef<bool>* op)
00185         : JumpInstruction (pc, op)
00186     {}
00187 
00188     virtual
00189     ~JumpNull() {}
00190 
00191     virtual void exec(TProgramCounter& pc) const {
00192         if (mOp->isNull()) {
00193             pc = mJumpTo;
00194         } else {
00195             pc++;
00196         }
00197     }
00198 
00199     static const char * longName();
00200     static const char * shortName();
00201     static int numArgs();
00202     void describe(string& out, bool values) const;
00203 
00204     static InstructionSignature
00205     signature(StandardTypeDescriptorOrdinal type) {
00206         vector<StandardTypeDescriptorOrdinal> v(numArgs(), type);
00207         return InstructionSignature(shortName(), 0, v);
00208     }
00209 
00210     static Instruction*
00211     create(InstructionSignature const & sig)
00212     {
00213         assert(sig.size() == numArgs());
00214         return new JumpNull(
00215             sig.getPc(),
00216             static_cast<RegisterRef<bool>*> (sig[0]));
00217     }
00218 
00219 };
00220 
00221 class FENNEL_CALCULATOR_EXPORT JumpNotNull
00222     : public JumpInstruction
00223 {
00224 public:
00225     explicit
00226     JumpNotNull(TProgramCounter pc, RegisterRef<bool>* op)
00227         : JumpInstruction (pc, op)
00228     {}
00229 
00230     virtual
00231     ~JumpNotNull() {}
00232 
00233     virtual void exec(TProgramCounter& pc) const {
00234         if (!mOp->isNull()) {
00235             pc = mJumpTo;
00236         } else {
00237             pc++;
00238         }
00239     }
00240 
00241     static const char * longName();
00242     static const char * shortName();
00243     static int numArgs();
00244     void describe(string& out, bool values) const;
00245 
00246     static InstructionSignature
00247     signature(StandardTypeDescriptorOrdinal type) {
00248         vector<StandardTypeDescriptorOrdinal> v(numArgs(), type);
00249         return InstructionSignature(shortName(), 0, v);
00250     }
00251 
00252     static Instruction*
00253     create(InstructionSignature const & sig)
00254     {
00255         assert(sig.size() == numArgs());
00256         return new JumpNotNull(
00257             sig.getPc(),
00258             static_cast<RegisterRef<bool>*> (sig[0]));
00259     }
00260 
00261 };
00262 
00263 class FENNEL_CALCULATOR_EXPORT JumpInstructionRegister
00264     : InstructionRegister
00265 {
00266     
00267     template < class INSTCLASS2 >
00268     static void
00269     registerTypes(vector<StandardTypeDescriptorOrdinal> const &t) {
00270 
00271         for (uint i = 0; i < t.size(); i++) {
00272             StandardTypeDescriptorOrdinal type = t[i];
00273             InstructionSignature sig = INSTCLASS2::signature(type);
00274             switch (type) {
00275 #define Fennel_InstructionRegisterSwitch_Bool 1
00276 #include "fennel/calculator/InstructionRegisterSwitch.h"
00277             default:
00278                 throw std::logic_error("Default InstructionRegister");
00279             }
00280         }
00281     }
00282 
00283 public:
00284     static void
00285     registerInstructions() {
00286         vector<StandardTypeDescriptorOrdinal> t;
00287         t.push_back(STANDARD_TYPE_BOOL);
00288 
00289         
00290         
00291         
00292         
00293         
00294         registerTypes<fennel::Jump>(t);
00295         registerTypes<fennel::JumpTrue>(t);
00296         registerTypes<fennel::JumpFalse>(t);
00297         registerTypes<fennel::JumpNull>(t);
00298         registerTypes<fennel::JumpNotNull>(t);
00299     }
00300 };
00301 
00302 
00303 FENNEL_END_NAMESPACE
00304 
00305 #endif
00306 
00307 
00308