mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-20 11:05:54 +00:00
368 lines
8.3 KiB
C++
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
|
|
|