return false;
}
+/**
+ * @brief Returns a string representation of an instance.
+ *
+ * @param object the object to convert
+ * @return a string describing the <code>object</code>
+ */
+QString RplASBoolean::toString(void* object, int maxLength) const
+{
+ return ((RplASVariant*) object)->asBool() ? "True" : "False";
+}
+
/** @class RplASNumber rplastree.hpp "rplexpr/rplastree.hpp"
*
* @brief Implements the class of a Boolean.
return false;
}
+/**
+ * @brief Returns a string representation of an instance.
+ *
+ * @param object the object to convert
+ * @return a string describing the <code>object</code>
+ */
+QString RplASFloat::toString(void* object, int maxLength) const
+{
+ QString rc;
+ rc.sprintf("%f", ((RplASVariant *) object)->asFloat());
+ return rc;
+}
+
/** @class RplASInteger rplastree.hpp "rplexpr/rplastree.hpp"
*
* @brief Implements the class of a Boolean.
return false;
}
+/**
+ * @brief Returns a string representation of an instance.
+ *
+ * @param object the object to convert
+ * @return a string describing the <code>object</code>
+ */
+QString RplASInteger::toString(void* object, int maxLength) const
+{
+ QString rc;
+ rc.sprintf("%.*d", maxLength, ((RplASVariant *) object)->asInt());
+ return rc;
+}
/** @class RplASString rplastree.hpp "rplexpr/rplastree.hpp"
return rc;
}
+/**
+ * @brief Returns a string representation of an instance.
+ *
+ * @param object the object to convert
+ * @return a string describing the <code>object</code>
+ */
+QString RplASString::toString(void* object, int maxLength) const
+{
+ QString rc;
+ QString* string = reinterpret_cast<QString*> (object);
+ int length = string->size();
+ if (length + 2 > maxLength)
+ length = maxLength - 2;
+ rc.reserve(length);
+ rc += "'";
+ if (string->size() < maxLength - 2) {
+ rc += *string;
+ } else {
+ rc += string->mid(0, maxLength - 2 - 3);
+ rc += "...";
+ }
+ rc += "'";
+ return rc;
+}
/** @class RplASList rplastree.hpp "rplexpr/rplastree.hpp"
*
return rc;
}
+/**
+ * @brief Returns a string representation of an instance.
+ *
+ * @param object the object to convert
+ * @return a string describing the <code>object</code>
+ */
+QString RplASList::toString(void* object, int maxLength) const
+{
+ QString rc;
+ rc.reserve(maxLength);
+ rc += "[";
+ ListValueType* list = reinterpret_cast<ListValueType*>(object);
+ ListValueType::iterator it;
+ bool first = true;
+ for(it = list->begin(); it != list->end(); it++){
+ if (first)
+ first = false;
+ else
+ rc += ",";
+ QString part = (*it)->toString(maxLength - rc.size() - 5);
+ if (maxLength - rc.size() - 5 - part.size() <= 0){
+ rc += "...";
+ break;
+ } else {
+ rc += part;
+ }
+
+ }
+ rc += "]";
+ return rc;
+}
+
/** @class RplASMap rplastree.hpp "rplexpr/rplastree.hpp"
*
* @brief Implements the class of a map.
return rc;
}
+/**
+ * @brief Returns a string representation of an instance.
+ *
+ * @param object the object to convert
+ * @return a string describing the <code>object</code>
+ */
+QString RplASMap::toString(void* object, int maxLength) const
+{
+ QString rc;
+ rc.reserve(maxLength);
+ rc += "[";
+ MapValueType* map = reinterpret_cast<MapValueType*>(object);
+ MapValueType::iterator it;
+ bool first = true;
+ for(it = map->begin(); it != map->end(); it++){
+ if (first)
+ first = false;
+ else
+ rc += ",";
+ if (maxLength - rc.size() - 5 - 2 - it.key().size() <= 0){
+ rc += "...";
+ break;
+ } else {
+ rc += "'";
+ rc += it.key();
+ rc += "':";
+ }
+ QString part = it.value()->toString(maxLength - rc.size() - 5);
+ if (maxLength - rc.size() - 5 - part.size() <= 0){
+ rc += "...";
+ break;
+ } else {
+ rc += part;
+ }
+
+ }
+ rc += "}";
+ return rc;
+}
+
void* newValueInstance(void* source = NULL) const;
void destroyValueInstance(void* object) const;
virtual bool boolValueOf(void* object) const;
+ virtual QString toString(void *object, int maxLength = 80) const;
public:
static RplASBoolean m_instance;
};
void* newValueInstance(void* source = NULL) const;
void destroyValueInstance(void* object) const;
virtual bool boolValueOf(void* object) const;
+ virtual QString toString(void *object, int maxLength = 80) const;
public:
static RplASFloat m_instance;
};
RplASInteger();
public:
virtual bool boolValueOf(void* object) const;
+ virtual QString toString(void *object, int maxLength = 80) const;
public:
static RplASInteger m_instance;
};
void* newValueInstance(void* source = NULL) const;
void destroyValueInstance(void* object) const;
virtual bool boolValueOf(void* object) const;
+ virtual QString toString(void *object, int maxLength = 80) const;
public:
static RplASString m_instance;
};
void* newValueInstance(void* source = NULL) const;
void destroyValueInstance(void* object) const;
virtual bool boolValueOf(void* object) const;
+ virtual QString toString(void *object, int maxLength = 80) const;
public:
static RplASList m_instance;
};
void* newValueInstance(void* source = NULL) const;
void destroyValueInstance(void* object) const;
virtual bool boolValueOf(void* object) const;
+ virtual QString toString(void *object, int maxLength = 80) const;
public:
static RplASMap m_instance;
};
#include "rplcore/rplcore.hpp"
#include "rplexpr/rplexpr.hpp"
+unsigned int RplASItem::m_nextId = 1;
+
/** @class RplASException rplastree.hpp "rplexpr/rplastree.hpp"
*
* @brief Implements a specific exception for the Abstract Syntax Tree.
*/
RplASVariant::RplASVariant() :
m_dataType(DT_UNDEF),
+ m_flags(VF_UNDEF),
// m_value(),
m_class(NULL)
{
*/
RplASVariant::RplASVariant(const RplASVariant& source):
m_dataType(source.m_dataType),
+ m_flags(source.m_flags),
// m_value
m_class(source.m_class)
{
{
destroyValue();
m_dataType = source.m_dataType;
+ m_flags = source.m_flags;
m_class = source.m_class;
copyValue(source);
return *this;
case DT_UNDEF:
break;
default:
- m_class->destroyValueInstance(m_value.m_object);
+ if ((m_flags & VF_IS_COPY) == 0)
+ m_class->destroyValueInstance(m_value.m_object);
m_value.m_object = NULL;
break;
}
setObject(new QString(string), &RplASString::m_instance);
}
+/**
+ * @brief Builds a string.
+ *
+ * @return the value as string
+ */
+QString RplASVariant::toString(int maxLength) const
+{
+ QString rc;
+ switch(m_dataType)
+ {
+ case DT_BOOL:
+ rc = m_value.m_bool ? "True" : "False";
+ break;
+ case DT_FLOAT:
+ rc.sprintf("%f", m_value.m_float);
+ break;
+ case DT_INTEGER:
+ rc.sprintf("%d", m_value.m_float);
+ break;
+ case DT_OBJECT:
+ m_class->toString(m_value.m_object, maxLength);
+ break;
+ default:
+ case DT_UNDEF:
+ rc = "None";
+ break;
+ }
+ return rc;
+}
+
/**
* @brief Make the instance to an object.
*
* @param type the type of the instance
*/
RplASItem::RplASItem(RplASItemType type) :
+ m_id(m_nextId++),
m_type(type),
+ m_flags(0),
m_position(NULL)
{
/**
* @brief Constructor.
*/
-RplASUnary::RplASUnaryOp(int op) :
+RplASUnaryOp::RplASUnaryOp(int op, RplASItemType type) :
+ RplASNode1(type),
m_operator(op)
{
}
*
* @return the operator
*/
-int RplASUnary::getOperator() const
+int RplASUnaryOp::getOperator() const
{
return m_operator;
}
return m_currentSpace;
}
+/**
+ * @brief Returns the method.
+ *
+ * @return the method
+ */
+RplASMethod* RplAsMethodCall::method() const
+{
+ return m_method;
+}
+
+/**
+ * @brief Sets the method.
+ * @param method method to set
+ */
+void RplAsMethodCall::setMethod(RplASMethod* method)
+{
+ m_method = method;
+}
+
+/**
+ * @brief Returns the argument list.
+ *
+ * @return the first element of an argument list
+ */
+RplArgument* RplAsMethodCall::arg1() const
+{
+ return m_arg1;
+}
+
+/**
+ * @brief Sets the argument list.
+ *
+ * @param arg1 NULL or the first element of the argument list
+ */
+void RplAsMethodCall::setArg1(RplArgument* arg1)
+{
+ m_arg1 = arg1;
+}
+
AST_NAMED_VALUE,
AST_METHOD,
AST_INTRINSIC_METHOD,
+ AST_PRE_UNARY_OP,
+ AST_POST_UNARY_OP,
+ AST_BINARY_OP,
AST_METHOD_CALL,
AST_WHILE,
AST_IF,
DT_BOOL,
DT_OBJECT
};
+ enum VariantFlags {
+ VF_UNDEF,
+ /// if DT_OBJECT: object is a copy, don't free at method end
+ VF_IS_COPY = 1 << 1,
+ /// debugger: action if changed
+ VF_WATCH_POINT = 1 << 2
+ };
+
friend class RplASCondition;
public:
RplASVariant();
void setBool(bool value);
void setObject(void* object, const RplASClass* clazz);
void setString(const QString& string);
+ QString toString(int maxLength = 80) const;
+ QString repr() const;
protected:
void copyValue(const RplASVariant& source);
void destroyValue();
private:
- DataType m_dataType;
+ DataType m_dataType:8;
+ /// bitmap of VF_... flags:
+ int m_flags:8;
union {
qreal m_float;
int m_int;
class RplASTree;
class RplASItem
{
+public:
+ enum NodeFlags {
+ NF_UNDEF,
+ /// Debugger: this node is a breakpoint
+ NF_BREAKPOINT = 1 << 1,
+ /// the tree under this node is complete checked for data type correctness
+ NF_TYPECHECK_COMPLETE = 1 << 2
+ };
+
public:
friend class RplASTree;
RplASItem(RplASItemType type);
const RplSourcePosition* position() const;
void setPosition(const RplSourcePosition* position);
protected:
- RplASItemType m_type;
+ unsigned int m_id:16;
+ RplASItemType m_type:8;
+ int m_flags:5;
+ int m_dataType: 3;
const RplSourcePosition* m_position;
+private:
+ static unsigned int m_nextId;
};
class RplASCalculable
RplASItem* m_child4;
};
-class RplASUnary : public RplASNode1
+class RplASUnaryOp : public RplASNode1
{
public:
- RplASUnaryOp(int op);
+ RplASUnaryOp(int op, RplASItemType type);
public:
int getOperator() const;
public:
RplAsMethodCall();
virtual ~RplAsMethodCall();
+public:
+ RplASMethod* method() const;
+ void setMethod(RplASMethod* method);
+
+ RplArgument* arg1() const;
+ void setArg1(RplArgument* arg1);
+
private:
RplASMethod* m_method;
RplArgument* m_arg1;
* true: otherwise
*/
virtual bool boolValueOf(void* object) const = 0;
+ /**
+ * @brief Returns a string representation of an instance.
+ *
+ * @param object the object to convert
+ * @return a string describing the <code>object</code>
+ */
+ virtual QString toString(void *object, int maxLength = 80) const = 0;
public:
const QString& name() const;
protected:
m_hasMoreInput(false),
m_stringFeatures(stringFeatures),
m_storageFlags(storageFlags)
+ // m_prioOfOp
{
+ memset(m_prioOfOp, 0, sizeof m_prioOfOp);
m_currentPosition->setSourceUnit(source->currentReader()
->currentSourceUnit());
memset(m_charInfo, 0, sizeof m_charInfo);
*
* @return the source of the instance
*/
-RplSource*RplLexer::source()
+RplSource* RplLexer::source()
{
return m_source;
}
+/**
+ * @brief Returns the priority of a given operator.
+ *
+ * @param op the operator
+ * @return the priority of the op
+ */
+int RplLexer::prioOfOp(int op){
+ int prio = m_prioOfOp[op];
+}
+
bool m_hasMoreInput;
int m_stringFeatures;
int m_storageFlags;
+ char m_prioOfOp[128];
};
item = var;
m_lexer->undoLastToken();
} else {
- if (token->id() == m_tokenParenthesis){
+ if (token->id() == O_LPARENTH){
RplASItem* args = parseArguments();
- RplAsMethodCall =
- } else if (token->id() == m_tokenDecrement){
+ RplAsMethodCall node = new RplAsMethodCall();
+ node.setArg1(args);
+ } else if (token->id() == O_INC || token->id() == O_DEC){
RplASNamedValue* var = new RplASNamedValue(name);
item = var;
-
}
}
break;
RplSourcePosition* start = m_lexer->currentSourcePosition();
RplASItem* top = NULL;
RplASItem* item;
+ int lastPrio = -1;
bool again = true;
do {
item = parseOperand(level);
token = m_lexer->nextNonSpaceToken();
switch(token->tokenType()){
case TOKEN_OPERATOR:
+ {
+ RplASBinaryOp* op = new RplASBinaryOp();
+ op->setOp(token->id());
+ int prio = m_lexer->prioOfOp(token->id());
+ op->setChild(item);
+ op->setPosition(m_lexer->currentPosition());
+ op->setChild2(parseOperand(level));
+ if
break;
+ }
case TOKEN_STRING:
case TOKEN_NUMBER:
case TOKEN_REAL:
O_XOR, O_BIT_OR, O_BIT_AND, O_LSHIFT, O_RSHIFT, O_RSHIFT2,
O_LT, O_GT, O_LE, O_GE, O_EQ, O_NE,
O_PLUS, O_MINUS, O_DIV, O_MOD, O_TIMES, O_POWER, O_INC, O_DEC,
- O_DOT
+ O_DOT, O_LPARENTH, O_RPARENT, O_LBRACKET, O_RBRACKET
};
#define MF_OPERATORS ";; ; , : ?" \
" ^ | & << >> >>>" \
" < > <= >= == !=" \
" + - / % * ** ++ --" \
- " ."
+ " . ( ) [ ]"
public:
RplMFParser(RplSource& source, RplASTree& ast);
public: