From 69b1d50f361629e59d81bcbf7daad4ee748ee6bc Mon Sep 17 00:00:00 2001 From: hama Date: Thu, 26 Jun 2014 00:22:34 +0200 Subject: [PATCH] dayly work --- rplexpr/rplasclasses.cpp | 132 +++++++++++++++++++++++++++++++++++++++ rplexpr/rplasclasses.hpp | 6 ++ rplexpr/rplastree.cpp | 84 ++++++++++++++++++++++++- rplexpr/rplastree.hpp | 51 +++++++++++++-- rplexpr/rpllexer.cpp | 14 ++++- rplexpr/rpllexer.hpp | 1 + rplexpr/rplmfparser.cpp | 18 ++++-- rplexpr/rplmfparser.hpp | 4 +- 8 files changed, 296 insertions(+), 14 deletions(-) diff --git a/rplexpr/rplasclasses.cpp b/rplexpr/rplasclasses.cpp index 4887b5a..ab2ffa1 100644 --- a/rplexpr/rplasclasses.cpp +++ b/rplexpr/rplasclasses.cpp @@ -142,6 +142,17 @@ bool RplASBoolean::boolValueOf(void* object) const return false; } +/** + * @brief Returns a string representation of an instance. + * + * @param object the object to convert + * @return a string describing the object + */ +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. @@ -198,6 +209,19 @@ bool RplASFloat::boolValueOf(void* object) const return false; } +/** + * @brief Returns a string representation of an instance. + * + * @param object the object to convert + * @return a string describing the object + */ +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. @@ -225,6 +249,18 @@ bool RplASInteger::boolValueOf(void* object) const return false; } +/** + * @brief Returns a string representation of an instance. + * + * @param object the object to convert + * @return a string describing the object + */ +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" @@ -285,6 +321,30 @@ bool RplASString::boolValueOf(void* object) const return rc; } +/** + * @brief Returns a string representation of an instance. + * + * @param object the object to convert + * @return a string describing the object + */ +QString RplASString::toString(void* object, int maxLength) const +{ + QString rc; + QString* string = reinterpret_cast (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" * @@ -354,6 +414,38 @@ bool RplASList::boolValueOf(void* object) const return rc; } +/** + * @brief Returns a string representation of an instance. + * + * @param object the object to convert + * @return a string describing the object + */ +QString RplASList::toString(void* object, int maxLength) const +{ + QString rc; + rc.reserve(maxLength); + rc += "["; + ListValueType* list = reinterpret_cast(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. @@ -422,3 +514,43 @@ bool RplASMap::boolValueOf(void* object) const return rc; } +/** + * @brief Returns a string representation of an instance. + * + * @param object the object to convert + * @return a string describing the object + */ +QString RplASMap::toString(void* object, int maxLength) const +{ + QString rc; + rc.reserve(maxLength); + rc += "["; + MapValueType* map = reinterpret_cast(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; +} + diff --git a/rplexpr/rplasclasses.hpp b/rplexpr/rplasclasses.hpp index b79a51b..e4d3885 100644 --- a/rplexpr/rplasclasses.hpp +++ b/rplexpr/rplasclasses.hpp @@ -64,6 +64,7 @@ public: 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; }; @@ -76,6 +77,7 @@ public: 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; }; @@ -85,6 +87,7 @@ public: RplASInteger(); public: virtual bool boolValueOf(void* object) const; + virtual QString toString(void *object, int maxLength = 80) const; public: static RplASInteger m_instance; }; @@ -96,6 +99,7 @@ public: 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; }; @@ -109,6 +113,7 @@ public: 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; }; @@ -122,6 +127,7 @@ public: 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; }; diff --git a/rplexpr/rplastree.cpp b/rplexpr/rplastree.cpp index 3519946..0280713 100644 --- a/rplexpr/rplastree.cpp +++ b/rplexpr/rplastree.cpp @@ -9,6 +9,8 @@ #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. @@ -47,6 +49,7 @@ RplASException::RplASException(const RplSourcePosition* position, */ RplASVariant::RplASVariant() : m_dataType(DT_UNDEF), + m_flags(VF_UNDEF), // m_value(), m_class(NULL) { @@ -66,6 +69,7 @@ RplASVariant::~RplASVariant() */ RplASVariant::RplASVariant(const RplASVariant& source): m_dataType(source.m_dataType), + m_flags(source.m_flags), // m_value m_class(source.m_class) { @@ -82,6 +86,7 @@ RplASVariant&RplASVariant::operator=(const RplASVariant& source) { destroyValue(); m_dataType = source.m_dataType; + m_flags = source.m_flags; m_class = source.m_class; copyValue(source); return *this; @@ -124,7 +129,8 @@ void RplASVariant::destroyValue() 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; } @@ -260,6 +266,36 @@ void RplASVariant::setString(const QString& string) 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. * @@ -286,7 +322,9 @@ void RplASVariant::setObject(void* object, const RplASClass* clazz) * @param type the type of the instance */ RplASItem::RplASItem(RplASItemType type) : + m_id(m_nextId++), m_type(type), + m_flags(0), m_position(NULL) { @@ -527,7 +565,8 @@ RplASNode4::~RplASNode4() /** * @brief Constructor. */ -RplASUnary::RplASUnaryOp(int op) : +RplASUnaryOp::RplASUnaryOp(int op, RplASItemType type) : + RplASNode1(type), m_operator(op) { } @@ -537,7 +576,7 @@ RplASUnary::RplASUnaryOp(int op) : * * @return the operator */ -int RplASUnary::getOperator() const +int RplASUnaryOp::getOperator() const { return m_operator; } @@ -846,3 +885,42 @@ RplSymbolSpace* RplASTree::currentSpace() const 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; +} + diff --git a/rplexpr/rplastree.hpp b/rplexpr/rplastree.hpp index 012197c..76ef53b 100644 --- a/rplexpr/rplastree.hpp +++ b/rplexpr/rplastree.hpp @@ -16,6 +16,9 @@ enum RplASItemType { 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, @@ -46,6 +49,14 @@ public: 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(); @@ -62,11 +73,15 @@ public: 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; @@ -79,6 +94,15 @@ private: 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); @@ -87,8 +111,13 @@ public: 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 @@ -172,10 +201,10 @@ protected: RplASItem* m_child4; }; -class RplASUnary : public RplASNode1 +class RplASUnaryOp : public RplASNode1 { public: - RplASUnaryOp(int op); + RplASUnaryOp(int op, RplASItemType type); public: int getOperator() const; @@ -239,6 +268,13 @@ class RplAsMethodCall : public RplASNode2, public RplASStatement 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; @@ -295,6 +331,13 @@ public: * 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 object + */ + virtual QString toString(void *object, int maxLength = 80) const = 0; public: const QString& name() const; protected: diff --git a/rplexpr/rpllexer.cpp b/rplexpr/rpllexer.cpp index a2d7e29..c2fc2c1 100644 --- a/rplexpr/rpllexer.cpp +++ b/rplexpr/rpllexer.cpp @@ -302,7 +302,9 @@ RplLexer::RplLexer(RplSource* source, 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); @@ -877,9 +879,19 @@ void RplLexer::startUnit(const QString& unit) * * @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]; +} + diff --git a/rplexpr/rpllexer.hpp b/rplexpr/rpllexer.hpp index e9ff9d7..06b8bf5 100644 --- a/rplexpr/rpllexer.hpp +++ b/rplexpr/rpllexer.hpp @@ -213,6 +213,7 @@ protected: bool m_hasMoreInput; int m_stringFeatures; int m_storageFlags; + char m_prioOfOp[128]; }; diff --git a/rplexpr/rplmfparser.cpp b/rplexpr/rplmfparser.cpp index 57d3898..769ea8b 100644 --- a/rplexpr/rplmfparser.cpp +++ b/rplexpr/rplmfparser.cpp @@ -125,13 +125,13 @@ RplASItem* RplMFParser::parseOperand(int level) 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; @@ -158,13 +158,23 @@ RplASItem* RplMFParser::parseTerm(int depth){ 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: diff --git a/rplexpr/rplmfparser.hpp b/rplexpr/rplmfparser.hpp index 73bc712..b4093d3 100644 --- a/rplexpr/rplmfparser.hpp +++ b/rplexpr/rplmfparser.hpp @@ -29,7 +29,7 @@ public: 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 ";; ; , : ?" \ @@ -37,7 +37,7 @@ public: " ^ | & << >> >>>" \ " < > <= >= == !=" \ " + - / % * ** ++ --" \ - " ." + " . ( ) [ ]" public: RplMFParser(RplSource& source, RplASTree& ast); public: -- 2.39.5