#include "rplcore/rplcore.hpp"
#include "rplexpr/rplexpr.hpp"
-RplASList RplASList::m_instance;
-RplASMap RplASMap::m_instance;
-RplASFloat RplASFloat::m_instance;
-RplASInteger RplASInteger::m_instance;
-RplASString RplASString::m_instance;
-RplASBoolean RplASBoolean::m_instance;
-RplASVoid RplASVoid::m_instance;
-RplASFormula RplASFormula::m_instance;
+RplASList* RplASList::m_instance = NULL;
+RplASMap* RplASMap::m_instance = NULL;
+RplASFloat* RplASFloat::m_instance = NULL;
+RplASInteger* RplASInteger::m_instance = NULL;
+RplASString* RplASString::m_instance = NULL;
+RplASBoolean* RplASBoolean::m_instance = NULL;
+RplASVoid* RplASVoid::m_instance = NULL;
+RplASFormula* RplASFormula::m_instance = NULL;
/** @class RplSymbolSpace rplastree.hpp "rplexpr/rplastree.hpp"
*
m_body(NULL)
{
if (type == SST_GLOBAL){
- m_classes[RplASInteger::m_instance.name()] = &RplASInteger::m_instance;
- m_classes[RplASBoolean::m_instance.name()] = &RplASBoolean::m_instance;
- m_classes[RplASFloat::m_instance.name()] = &RplASFloat::m_instance;
- m_classes[RplASString::m_instance.name()] = &RplASString::m_instance;
- m_classes[RplASList::m_instance.name()] = &RplASList::m_instance;
- m_classes[RplASMap::m_instance.name()] = &RplASMap::m_instance;
- m_classes[RplASVoid::m_instance.name()] = &RplASVoid::m_instance;
- m_classes[RplASFormula::m_instance.name()] = &RplASFormula::m_instance;
+ m_classes[RplASInteger::m_instance->name()] = RplASInteger::m_instance;
+ m_classes[RplASBoolean::m_instance->name()] = RplASBoolean::m_instance;
+ m_classes[RplASFloat::m_instance->name()] = RplASFloat::m_instance;
+ m_classes[RplASString::m_instance->name()] = RplASString::m_instance;
+ m_classes[RplASList::m_instance->name()] = RplASList::m_instance;
+ m_classes[RplASMap::m_instance->name()] = RplASMap::m_instance;
+ m_classes[RplASVoid::m_instance->name()] = RplASVoid::m_instance;
+ m_classes[RplASFormula::m_instance->name()] = RplASFormula::m_instance;
}
}
/**
* @brief Constructor.
*/
-RplASBoolean::RplASBoolean() :
- RplASClass("Bool")
+RplASBoolean::RplASBoolean(RplASTree& tree) :
+ RplASClass("Bool", tree)
{
}
/**
/**
* @brief Constructor.
*/
-RplASFloat::RplASFloat() :
- RplASClass("Float")
+RplASFloat::RplASFloat(RplASTree& tree) :
+ RplASClass("Float", tree)
{
}
-RplASFloat::RplASFloat(const QString& name) :
- RplASClass(name)
+RplASFloat::RplASFloat(const QString& name, RplASTree& tree) :
+ RplASClass(name, tree)
{
- m_superClass = &RplASFloat::m_instance;
+ m_superClass = RplASFloat::m_instance;
}
/**
* @brief Creates a value object (used in RplASVariant).
/**
* @brief Constructor.
*/
-RplASInteger::RplASInteger() :
- RplASFloat("Int")
+RplASInteger::RplASInteger(RplASTree& tree) :
+ RplASFloat("Int", tree)
{
}
/**
* @brief Constructor.
*/
-RplASString::RplASString() :
- RplASClass("Str")
+RplASString::RplASString(RplASTree& tree) :
+ RplASClass("Str", tree)
{
}
/**
/**
* @brief Constructor.
*/
-RplASList::RplASList() :
- RplASClass("List")
+RplASList::RplASList(RplASTree& tree) :
+ RplASClass("List", tree)
{
}
/**
* @brief Constructor.
*/
-RplASMap::RplASMap() :
- RplASClass("Map")
+RplASMap::RplASMap(RplASTree& tree) :
+ RplASClass("Map", tree)
{
}
/**
*
* @brief Implements a data type representing a none type.
*/
-RplASVoid::RplASVoid() :
- RplASClass("Void")
+RplASVoid::RplASVoid(RplASTree& tree) :
+ RplASClass("Void", tree)
{
}
* @brief Implements a data type representing a calculated value.
*/
-RplASFormula::RplASFormula() :
- RplASClass("Formula")
+RplASFormula::RplASFormula(RplASTree& tree) :
+ RplASClass("Formula", tree)
{
}
rc.sprintf("<formula %d>", expr->id());
return rc;
}
+
+/** @class RplASUserClass rplastree.hpp "rplexpr/rplastree.hpp"
+ *
+ * @brief Implements a data type representing a user defined class.
+ */
+
+
+/**
+ * @brief Constructor.
+ *
+ * @param name name of the user defined class
+ */
+RplASUserClass::RplASUserClass(const QString& name, RplASTree& tree) :
+ RplASClass(name, tree)
+{
+}
+
+/**
+ * @brief Creates an instance of a user defined class.
+ *
+ * @param source the type (user defined class) of the result
+ * @return an instance of an user defined class
+ */
+void*RplASUserClass::newValueInstance(void* source) const
+{
+ RplASUserClass* clazz = static_cast<RplASUserClass*>(source);
+ RplASUserObject* rc = new RplASUserObject(clazz);
+ return static_cast<void*>(rc);
+}
+
+void RplASUserClass::destroyValueInstance(void* object) const
+{
+ RplASUserObject* obj = static_cast<RplASUserObject*>(object);
+ delete obj;
+}
+
+/**
+ * @brief Returns the bool value of the object.
+ *
+ * @param object object to test
+ * @return true: object != NULL<br>
+ * false: object == NULL
+ */
+bool RplASUserClass::boolValueOf(void* object) const
+{
+ return object != NULL;
+}
+
+/**
+ * @brief Returns a string representation an instance of a user defined class.
+ *
+ * @param object object to convert
+ * @param maxLength maximum length of the string
+ * @return
+ */
+QString RplASUserClass::toString(void* object, int maxLength) const
+{
+ return m_name;
+}
+
+
+/** @class RplASUserObject rplastree.hpp "rplexpr/rplastree.hpp"
+ *
+ * @brief Implements an instance of an user defined class.
+ */
+RplASUserObject::RplASUserObject(RplASUserClass* clazz) :
+ m_class(clazz),
+ m_fields(NULL)
+{
+}
+
+/**
+ * @brief Destructor.
+ */
+RplASUserObject::~RplASUserObject()
+{
+ delete[] m_fields;
+ m_fields = NULL;
+}
class RplASBoolean : public RplASClass {
public:
- RplASBoolean();
+ RplASBoolean(RplASTree& tree);
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;
+ static RplASBoolean* m_instance;
};
class RplASFloat : public RplASClass {
public:
- RplASFloat();
- RplASFloat(const QString& name);
+ RplASFloat(RplASTree& tree);
+ RplASFloat(const QString& name, RplASTree& tree);
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;
+ static RplASFloat* m_instance;
};
class RplASInteger : public RplASFloat {
public:
- RplASInteger();
+ RplASInteger(RplASTree& tree);
public:
virtual bool boolValueOf(void* object) const;
virtual QString toString(void *object, int maxLength = 80) const;
public:
- static RplASInteger m_instance;
+ static RplASInteger* m_instance;
};
class RplASString : public RplASClass {
public:
- RplASString();
+ RplASString(RplASTree& tree);
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;
+ static RplASString* m_instance;
};
class RplASList : public RplASClass {
public:
- RplASList();
+ RplASList(RplASTree& tree);
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;
+ static RplASList* m_instance;
};
class RplASMap : public RplASClass {
public:
- RplASMap();
+ RplASMap(RplASTree& tree);
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;
+ static RplASMap* m_instance;
};
class RplASVoid : public RplASClass {
public:
- RplASVoid();
+ RplASVoid(RplASTree& tree);
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 RplASVoid m_instance;
+ static RplASVoid* m_instance;
};
class RplASFormula : public RplASClass {
public:
- RplASFormula();
+ RplASFormula(RplASTree& tree);
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 RplASFormula m_instance;
+ static RplASFormula* m_instance;
};
+class RplASUserClass : public RplASClass {
+public:
+ RplASUserClass(const QString& name, RplASTree& tree);
+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;
+};
+
+class RplASUserObject {
+public:
+ RplASUserObject(RplASUserClass* clazz);
+ ~RplASUserObject();
+public:
+ void callMember();
+private:
+ RplASUserClass* m_class;
+ RplASVariant* m_fields;
+};
#endif // RPLASCLASSES_HPP
{
const RplASClass* clazz;
const QString* rc = static_cast<const QString*>(asObject(&clazz));
- if (clazz != &RplASString::m_instance){
+ if (clazz != RplASString::m_instance){
const QString& name = clazz->name();
throw RplException("RplASVariant::asString: not a string: %s",
name.toUtf8().constData());
destroyValue();
m_variantType = VT_FLOAT;
m_value.m_float = number;
- m_class = &RplASFloat::m_instance;
+ m_class = RplASFloat::m_instance;
}
/**
destroyValue();
m_variantType = VT_INTEGER;
m_value.m_int = integer;
- m_class = &RplASInteger::m_instance;
+ m_class = RplASInteger::m_instance;
}
/**
destroyValue();
m_variantType = VT_BOOL;
m_value.m_bool = value;
- m_class = &RplASBoolean::m_instance;
+ m_class = RplASBoolean::m_instance;
}
/**
void RplASVariant::setString(const QString& string)
{
// deletion in RplASVariant::destroyValue():
- setObject(new QString(string), &RplASString::m_instance);
+ setObject(new QString(string), RplASString::m_instance);
}
/**
RplASNode1(AST_LIST_CONSTANT),
RplASCalculable()
{
- m_value.setObject(RplASList::m_instance.newValueInstance(),
- &RplASList::m_instance);
+ m_value.setObject(RplASList::m_instance->newValueInstance(),
+ RplASList::m_instance);
}
/**
* @brief Returns the list.
RplASCalculable(),
m_value()
{
- m_value.setObject(new RplASMapOfVariants, &RplASMap::m_instance);
+ m_value.setObject(new RplASMapOfVariants, RplASMap::m_instance);
}
/**
/**
* @brief Constructor.
*/
-RplASClass::RplASClass(const QString& name) :
+RplASClass::RplASClass(const QString& name, RplASTree& tree) :
m_name(name),
- m_methods(),
- m_superClass(NULL)
+ m_symbols(NULL),
+ m_superClass(NULL),
+ m_tree(tree)
{
}
fprintf(fp, "%sclass %s super: %s\n", tabs, m_name.toUtf8().constData(),
m_superClass == NULL
? "<none>" : m_superClass->name().toUtf8().constData());
- QList<QString> sorted;
- sorted.reserve(m_methods.size());
- MethodMap::iterator it;
- for (it = m_methods.begin(); it != m_methods.end(); it++){
- sorted.append(it.key());
- }
- qSort(sorted.begin(), sorted.end(), qLess<QString>());
- QList<QString>::iterator it2;
- for (it2 = sorted.begin(); it2 != sorted.end(); it2++){
- RplASMethod* current = m_methods[*it2];
- current->dump(fp, indent + 1);
- }
+ m_symbols->dump(fp, indent);
+}
+
+/**
+ * @brief Sets the symbol space from the current in the tree.
+ */
+void RplASClass::setSymbols()
+{
+ m_symbols = m_tree.currentSpace();
}
/** @class RplASTree rplastree.hpp "rplexpr/rplastree.hpp"
public:
typedef QMap<QString, RplASMethod*> MethodMap;
public:
- RplASClass(const QString& name);
+ RplASClass(const QString& name, RplASTree& m_tree);
virtual ~RplASClass();
public:
/**
public:
const QString& name() const;
virtual void dump(FILE* fp, int indent);
+ void setSymbols();
protected:
QString m_name;
- MethodMap m_methods;
+ RplSymbolSpace* m_symbols;
const RplASClass* m_superClass;
+ RplASTree& m_tree;
};
#include "rplexpr/rplasclasses.hpp"
L_PARSE_METH_NO_END = 2045,
L_PARSE_METH_NO_END2,
L_PARSE_VAR_DEF_ALREADY_DEFINED,
- L_PARSE_VAR_DEF_ALREADY_DEFINED2
+ L_PARSE_VAR_DEF_ALREADY_DEFINED2,
+ L_PARSE_CLASS_NO_NAME,
+ L_PARSE_CLASS_LOWERCASE = 2050
+
};
/** @class RplMFParser rpllexer.hpp "rplexpr/rplmfparser.hpp"
parent->setChild(expr);
// freed in the destructor of varList (~RplASVariant()):
variant = new RplASVariant();
- variant->setObject(expr, &RplASFormula::m_instance);
+ variant->setObject(expr, RplASFormula::m_instance);
}
return variant;
}
/**
* @brief Parses a class definition.
- * @return the node in an abstract syntax tree
+ *
+ * @pre "class" is read
+ * @post token behind "endc" is read
*/
void RplMFParser::parseClass()
{
- //RplASItem* clazz = NULL;
- QString name = "";
+ const RplSourcePosition* startPos = m_lexer.currentPosition();
+ RplToken* token = m_lexer.nextNonSpaceToken();
+ if (! token->isTokenType(TOKEN_ID))
+ syntaxError(L_PARSE_CLASS_NO_NAME, "class name expected");
+ if (! token->isCapitalizedId())
+ syntaxError(L_PARSE_CLASS_LOWERCASE, "class name must start with an uppercase character");
+ QString name = token->toString();
+ RplASUserClass* clazz = new RplASUserClass(name, m_tree);
+ RplSymbolSpace* parent = m_tree.currentSpace();
+ parent->addClass(clazz);
+ m_tree.startClassOrMethod(name, RplSymbolSpace::SST_CLASS);
+ clazz->setSymbols();
m_tree.finishClassOrMethod(name);
}