Files
rippled/modules/ripple_app/contracts/ripple_Operation.h
2013-07-15 09:37:41 -07:00

368 lines
8.3 KiB
C++

//------------------------------------------------------------------------------
/*
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