//------------------------------------------------------------------------------ /* Copyright (c) 2011-2013, OpenCoin, Inc. */ //============================================================================== #ifndef OPERATION_H #define OPERATION_H namespace Script { // Contracts are non typed have variable data types class Operation { public: // returns false if there was an error virtual bool work (Interpreter* interpreter) = 0; virtual int getFee (); virtual ~Operation () { ; } }; // this is just an Int in the code class IntOp : public Operation { public: bool work (Interpreter* interpreter) { Data::pointer data = interpreter->getIntData (); if (data->isInt32 ()) { interpreter->pushStack ( data ); return (true); } return (false); } }; class FloatOp : public Operation { public: bool work (Interpreter* interpreter) { Data::pointer data = interpreter->getFloatData (); if (data->isFloat ()) { interpreter->pushStack ( data ); return (true); } return (false); } }; class Uint160Op : public Operation { public: bool work (Interpreter* interpreter) { Data::pointer data = interpreter->getUint160Data (); if (data->isUint160 ()) { interpreter->pushStack ( data ); return (true); } return (false); } }; class AddOp : public Operation { public: bool work (Interpreter* interpreter) { Data::pointer data1 = interpreter->popStack (); Data::pointer data2 = interpreter->popStack (); if ( (data1->isInt32 () || data1->isFloat ()) && (data2->isInt32 () || data2->isFloat ()) ) { if (data1->isFloat () || data2->isFloat ()) interpreter->pushStack (Data::pointer (new FloatData (data1->getFloat () + data2->getFloat ()))); else interpreter->pushStack (Data::pointer (new IntData (data1->getInt () + data2->getInt ()))); return (true); } else { return (false); } } }; class SubOp : public Operation { public: bool work (Interpreter* interpreter) { Data::pointer data1 = interpreter->popStack (); Data::pointer data2 = interpreter->popStack (); if ( (data1->isInt32 () || data1->isFloat ()) && (data2->isInt32 () || data2->isFloat ()) ) { if (data1->isFloat () || data2->isFloat ()) interpreter->pushStack (Data::pointer (new FloatData (data1->getFloat () - data2->getFloat ()))); else interpreter->pushStack (Data::pointer (new IntData (data1->getInt () - data2->getInt ()))); return (true); } else { return (false); } } }; class MulOp : public Operation { public: bool work (Interpreter* interpreter) { Data::pointer data1 = interpreter->popStack (); Data::pointer data2 = interpreter->popStack (); if ( (data1->isInt32 () || data1->isFloat ()) && (data2->isInt32 () || data2->isFloat ()) ) { if (data1->isFloat () || data2->isFloat ()) interpreter->pushStack (Data::pointer (new FloatData (data1->getFloat ()*data2->getFloat ()))); else interpreter->pushStack (Data::pointer (new IntData (data1->getInt ()*data2->getInt ()))); return (true); } else { return (false); } } }; class DivOp : public Operation { public: bool work (Interpreter* interpreter) { Data::pointer data1 = interpreter->popStack (); Data::pointer data2 = interpreter->popStack (); if ( (data1->isInt32 () || data1->isFloat ()) && (data2->isInt32 () || data2->isFloat ()) ) { if (data1->isFloat () || data2->isFloat ()) interpreter->pushStack (Data::pointer (new FloatData (data1->getFloat () / data2->getFloat ()))); else interpreter->pushStack (Data::pointer (new IntData (data1->getInt () / data2->getInt ()))); return (true); } else { return (false); } } }; class GtrOp : public Operation { public: bool work (Interpreter* interpreter) { Data::pointer data1 = interpreter->popStack (); Data::pointer data2 = interpreter->popStack (); if ( (data1->isInt32 () || data1->isFloat ()) && (data2->isInt32 () || data2->isFloat ()) ) { interpreter->pushStack (Data::pointer (new BoolData (data1->getFloat () > data2->getFloat ()))); return (true); } else { return (false); } } }; class LessOp : public Operation { public: bool work (Interpreter* interpreter) { Data::pointer data1 = interpreter->popStack (); Data::pointer data2 = interpreter->popStack (); if ( (data1->isInt32 () || data1->isFloat ()) && (data2->isInt32 () || data2->isFloat ()) ) { interpreter->pushStack (Data::pointer (new FloatData (data1->getFloat () < data2->getFloat ()))); return (true); } else { return (false); } } }; class ModOp : public Operation { public: bool work (Interpreter* interpreter) { Data::pointer data1 = interpreter->popStack (); Data::pointer data2 = interpreter->popStack (); if ( data1->isInt32 () && data2->isInt32 () ) { interpreter->pushStack (Data::pointer (new IntData (data1->getInt () % data2->getInt ()))); return (true); } else { return (false); } } }; class StartBlockOp : public Operation { public: bool work (Interpreter* interpreter) { Data::pointer offset = interpreter->getIntData (); return (interpreter->startBlock (offset->getInt ())); } }; class EndBlockOp : public Operation { public: bool work (Interpreter* interpreter) { return (interpreter->endBlock ()); } }; class StopOp : public Operation { public: bool work (Interpreter* interpreter) { interpreter->stop (); return (true); } }; class AcceptDataOp : public Operation { public: bool work (Interpreter* interpreter) { Data::pointer data = interpreter->popStack (); if (data->isInt32 ()) { interpreter->pushStack ( interpreter->getAcceptData (data->getInt ()) ); return (true); } return (false); } }; class JumpIfOp : public Operation { public: bool work (Interpreter* interpreter) { Data::pointer offset = interpreter->getIntData (); Data::pointer cond = interpreter->popStack (); if (cond->isBool () && offset->isInt32 ()) { if (cond->isTrue ()) { return (interpreter->jumpTo (offset->getInt ())); } return (true); } return (false); } }; class JumpOp : public Operation { public: bool work (Interpreter* interpreter) { Data::pointer offset = interpreter->getIntData (); if (offset->isInt32 ()) { return (interpreter->jumpTo (offset->getInt ())); } return (false); } }; class SendXRPOp : public Operation { public: bool work (Interpreter* interpreter) { Data::pointer sourceID = interpreter->popStack (); Data::pointer destID = interpreter->popStack (); Data::pointer amount = interpreter->popStack (); if (sourceID->isUint160 () && destID->isUint160 () && amount->isInt32 () && interpreter->canSign (sourceID->getUint160 ())) { // make sure: // source is either, this contract, issuer, or acceptor // TODO do the send //interpreter->pushStack( send result); return (true); } return (false); } }; class GetDataOp : public Operation { public: bool work (Interpreter* interpreter) { Data::pointer index = interpreter->popStack (); if (index->isInt32 ()) { interpreter->pushStack ( interpreter->getContractData (index->getInt ())); return (true); } return (false); } }; } #endif // vim:ts=4