RplASInteger RplASInteger::m_instance;
RplASString RplASString::m_instance;
RplASBoolean RplASBoolean::m_instance;
+RplASVoid RplASVoid::m_instance;
/** @class RplSymbolSpace rplastree.hpp "rplexpr/rplastree.hpp"
*
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;
}
}
QList<QString>::iterator it2;
for (it2 = sorted.begin(); it2 != sorted.end(); it2++){
RplASClass* clazz = m_classes[*it2];
- clazz->dump(fp, indent + 1);
+ clazz->dump(fp, indent);
}
fprintf(fp, "%s== Variables:\n", tabs);
QList<QString>::iterator it4;
for (it4 = sorted.begin(); it4 != sorted.end(); it4++){
RplVariable* var = m_variables[*it4];
- var->dump(fp, indent + 1);
+ var->dump(fp, indent);
}
fprintf(fp, "%s== Body:%s\n", tabs, m_body == NULL ? " <none>" : "");
if (m_body != NULL)
- m_body->dump(fp, indent + 1);
+ m_body->dump(fp, indent);
}
/**
name1.constData(),
name2.constData(), val.constData());
}
+
+/** @class RplVariable rplastree.hpp "rplexpr/rplastree.hpp"
+ *
+ * @brief Implements a data type representing a none type.
+ */
+RplASVoid::RplASVoid() :
+ RplASClass("Void")
+{
+}
+
+/**
+ * @brief Instantiates a new object.
+ *
+ * In this case we do nothing.
+ *
+ * @param source ignored
+ * @return
+ */
+void*RplASVoid::newValueInstance(void*) const
+{
+ return NULL;
+}
+
+/**
+ * @brief Destroys an object created by newValueInstance.
+ *
+ * In this case we do nothing.
+ *
+ * @param object object to
+ * @return
+ */
+void RplASVoid::destroyValueInstance(void* object) const
+{
+}
+
+/**
+ * @brief Returns the bool value of the given object
+ * @param object ignored
+ * @return false
+ */
+bool RplASVoid::boolValueOf(void*) const
+{
+ return false;
+}
+
+/**
+ * @brief Converts the object into a string.
+ *
+ * @param object ignored
+ * @param maxLength ignored
+ * @return the empty string
+ */
+QString RplASVoid::toString(void*, int) const
+{
+ return QString("");
+}
static RplASMap m_instance;
};
+class RplASVoid : public RplASClass {
+public:
+ RplASVoid();
+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;
+};
#endif // RPLASCLASSES_HPP
{
const RplASClass* clazz;
const QString* rc = static_cast<const QString*>(asObject(&clazz));
- if (clazz->name() != "String"){
+ if (clazz != &RplASString::m_instance){
const QString& name = clazz->name();
- throw RplException("RplASVariant::asString: not an string: %s",
+ throw RplException("RplASVariant::asString: not a string: %s",
name.toUtf8().constData());
}
return rc;
m_successor->dump(fp, indent);
}
+/**
+ * @brief Executes the statement.
+ */
void RplASVarDefinition::execute()
{
//@ToDo
{
}
+/** @class RplASExprStatement rplastree.hpp "rplexpr/rplastree.hpp"
+ *
+ * @brief Implements an statement consisting of an expression
+ */
+
+/**
+ * @brief Constructor.
+ */
+RplASExprStatement::RplASExprStatement() :
+ RplASNode1(AST_EXPR_STATEMENT),
+ RplASStatement()
+{
+}
+
+/**
+ * @brief Executes the statement.
+ */
+void RplASExprStatement::execute()
+{
+
+}
+
+/**
+ * @brief Calculates the value of the expression.
+ *
+ * @param value OUT: the calculated value
+ */
+void RplASExprStatement::calc(RplASVariant& value)
+{
+
+}
+
+/**
+ * @brief Writes the internals into a file.
+ *
+ * @param fp target file
+ * @param indent nesting level
+ */
+
+void RplASExprStatement::dump(FILE* fp, int indent)
+{
+ DEFINE_TABS(indent);
+ fprintf(fp, "%sExpr id: %d succ: %d expr: %d\n", tabs, m_id,
+ m_successor == NULL ? 0 : m_successor->id(),
+ m_child == NULL ? 0 : m_child->id() );
+ if (m_child != NULL)
+ m_child->dump(fp, indent + 1);
+ if (m_successor != NULL)
+ m_successor->dump(fp, indent);
+}
+
/** @class RplASNode1 rplastree.hpp "rplexpr/rplastree.hpp"
*
* @brief Implements a inner node of the abstract syntax tree with one child.
m_child->dump(fp, indent + 1);
}
+/**
+ * @brief Executes the statement.
+ */
void RplASMethodCall::execute()
{
}
* @brief Implements an argument of a method for the Abstract Syntax Tree.
*/
/**
- * @brief RplASArgument::RplASArgument
+ * @brief constructor
*/
RplASArgument::RplASArgument() :
RplASNode2(AST_ARGUMENT),
AST_CONSTANT,
AST_NAMED_VALUE,
AST_VAR_DEFINITION,
+ AST_EXPR_STATEMENT,
AST_METHOD,
AST_ARGUMENT,
AST_INTRINSIC_METHOD,
RplASException();
RplASException(const RplSourcePosition* position, const char* message, ...);
protected:
- void build(const RplSourcePosition* position, const char* format, va_list varList);
+ void build(const RplSourcePosition* position, const char* format,
+ va_list varList);
};
class RplASClass;
void dump(FILE* fp, int indent);
};
+class RplASExprStatement : public RplASNode1, public RplASStatement
+{
+public:
+ RplASExprStatement();
+public:
+ virtual void execute();
+ virtual void calc(RplASVariant& value);
+ void dump(FILE* fp, int indent);
+};
+
class RplASUnaryOp : public RplASNode1
{
public:
? &m_position2 : &m_position1;
} else {
m_currentToken->clear();
- m_currentPosition->setLineNo(m_source->currentReader()
- ->currentSourceUnit()->lineNo());
- m_currentPosition->setColumn(m_currentCol);
- if (! fillInput()){
+ RplReader* reader = m_source->currentReader();
+ if (reader == NULL)
m_currentToken->m_tokenType = TOKEN_END_OF_SOURCE;
- } else {
- QChar cc = m_input.at(0);
- int cc2 = cc.unicode();
- if (cc.isSpace()){
- m_currentToken->m_tokenType = TOKEN_SPACE;
- ix = 1;
- while(ix < m_input.size() && m_input.at(ix).isSpace())
- ix++;
- if (m_storageFlags & STORE_BLANK){
- m_currentToken->m_string.append(m_input.mid(0, ix));
- }
- m_currentCol += ix;
- m_input.remove(0, ix);
- rc = m_currentToken;
- } else if (cc.isDigit()){
- rc = scanNumber();
- } else if ( (cc2 == '"' && (m_stringFeatures & SF_QUOTE) != 0)
- || (cc2 == '\'' && (m_stringFeatures & SF_TICK) != 0)){
- rc = scanString();
+ else {
+ m_currentPosition->setLineNo(reader->currentSourceUnit()->lineNo());
+ m_currentPosition->setColumn(m_currentCol);
+ if (! fillInput()){
+ m_currentToken->m_tokenType = TOKEN_END_OF_SOURCE;
} else {
- if (cc2 >= CHAR_INFO_SIZE)
- throw RplLexException(*m_currentPosition,
- "no lexical symbol can start with this char: %lc",
- cc);
- else
- {
- if (rc == NULL && (m_charInfo[cc2] & CC_FIRST_COMMENT_START)){
- rc = findTokenWithId(TOKEN_COMMENT_START,
- CC_2nd_COMMENT_START, m_commentStarts);
- if (rc != NULL)
- scanComment();
+ QChar cc = m_input.at(0);
+ int cc2 = cc.unicode();
+ if (cc.isSpace()){
+ m_currentToken->m_tokenType = TOKEN_SPACE;
+ ix = 1;
+ while(ix < m_input.size() && m_input.at(ix).isSpace())
+ ix++;
+ if (m_storageFlags & STORE_BLANK){
+ m_currentToken->m_string.append(m_input.mid(0, ix));
}
+ m_currentCol += ix;
+ m_input.remove(0, ix);
+ rc = m_currentToken;
+ } else if (cc.isDigit()){
+ rc = scanNumber();
+ } else if ( (cc2 == '"' && (m_stringFeatures & SF_QUOTE) != 0)
+ || (cc2 == '\'' && (m_stringFeatures & SF_TICK) != 0)){
+ rc = scanString();
+ } else {
+ if (cc2 >= CHAR_INFO_SIZE)
+ throw RplLexException(*m_currentPosition,
+ "no lexical symbol can start with this char: %lc",
+ cc);
+ else
+ {
+ if (rc == NULL && (m_charInfo[cc2] & CC_FIRST_COMMENT_START)){
+ rc = findTokenWithId(TOKEN_COMMENT_START,
+ CC_2nd_COMMENT_START, m_commentStarts);
+ if (rc != NULL)
+ scanComment();
+ }
- if (rc == NULL && (m_charInfo[cc2] & CC_FIRST_OP)){
- if ( (m_charInfo[cc2] & CC_OP_1_ONLY) == 0){
- rc = findTokenWithId(TOKEN_OPERATOR,
- CC_2nd_OP, m_operators);
- } else {
+ if (rc == NULL && (m_charInfo[cc2] & CC_FIRST_OP)){
+ if ( (m_charInfo[cc2] & CC_OP_1_ONLY) == 0){
+ rc = findTokenWithId(TOKEN_OPERATOR,
+ CC_2nd_OP, m_operators);
+ } else {
+ rc = m_currentToken;
+ rc->m_tokenType = TOKEN_OPERATOR;
+ rc->m_value.m_id = findInVector(1, m_operators);
+ m_input.remove(0, 1);
+ m_currentCol += 1;
+ }
+ }
+ if (rc == NULL && (m_charInfo[cc2] & CC_FIRST_KEYWORD)){
+ rc = findTokenWithId(TOKEN_KEYWORD,
+ CC_2nd_KEYWORD, m_keywords);
+ }
+ if (rc == NULL && (m_charInfo[cc2] & CC_FIRST_ID)){
+ int length = 1;
+ while(length < m_input.size()
+ && (cc2 = m_input[length].unicode()) < CHAR_INFO_SIZE
+ && (m_charInfo[cc2] & CC_REST_ID) != 0)
+ length++;
rc = m_currentToken;
- rc->m_tokenType = TOKEN_OPERATOR;
- rc->m_value.m_id = findInVector(1, m_operators);
- m_input.remove(0, 1);
- m_currentCol += 1;
+ rc->m_tokenType = TOKEN_ID;
+ rc->m_string.append(m_input.mid(0, length));
+ m_input.remove(0, length);
+ m_currentCol += length;
}
- }
- if (rc == NULL && (m_charInfo[cc2] & CC_FIRST_KEYWORD)){
- rc = findTokenWithId(TOKEN_KEYWORD,
- CC_2nd_KEYWORD, m_keywords);
- }
- if (rc == NULL && (m_charInfo[cc2] & CC_FIRST_ID)){
- int length = 1;
- while(length < m_input.size()
- && (cc2 = m_input[length].unicode()) < CHAR_INFO_SIZE
- && (m_charInfo[cc2] & CC_REST_ID) != 0)
- length++;
- rc = m_currentToken;
- rc->m_tokenType = TOKEN_ID;
- rc->m_string.append(m_input.mid(0, length));
- m_input.remove(0, length);
- m_currentCol += length;
- }
+ }
}
}
}
return rc;
}
+/**
+ * @brief Parses an expression as a statement.
+ *
+ * @return the abstract syntax tree of the expression statement
+ */
+RplASItem* RplMFParser::parseExprStatement()
+{
+ RplSourcePosition *pos = m_lexer.currentPosition();
+ RplASItem* item = parseExpr();
+ RplASExprStatement* statement = new RplASExprStatement();
+ statement->setPosition(pos);
+ statement->setChild(item);
+ return statement;
+}
+
/**
* @brief Parses the body.
*
case TOKEN_REAL:
case TOKEN_OPERATOR:
m_lexer.undoLastToken();
- item = parseExpr();
+ item = parseExprStatement();
break;
case TOKEN_KEYWORD:
switch (token->id()){
item = parseVarDefinition(K_UNDEF);
} else {
m_lexer.undoLastToken();
- item = parseExpr();
+ item = parseExprStatement();
}
break;
}
K_UNDEF, K_IF, K_THEN, K_ELSE, K_FI, K_WHILE, K_DO, K_OD, K_REPEAT, K_UNTIL,
K_FOR, K_FROM, K_TO, K_STEP, K_CASE, K_OF, K_ESAC, K_LEAVE, K_CONTINUE, K_PASS,
K_CLASS, K_ENDC, K_ENDF, K_FUNCTION, K_GENERATOR, K_IMPORT,
- K_CONST, K_LAZY, K_INT, K_FLOAT, K_BOOL, K_NONE, K_TRUE, K_FALSE
+ K_CONST, K_LAZY, K_NONE, K_TRUE, K_FALSE
};
-#define IS_KEYWORD_BEHIND_EXPR(o) (o==K_THEN||o==K_DO||o==K_FROM||o==K_OF \
- ||o==K_ENDF||o==K_ENDC)
#define MF_KEYWORDS "if then else fi while do od repeat until" \
" for from to step case of esac leave continue pass" \
" class endc endf func generator import" \
- " const lazy None True False"
+ " const lazy none true false"
enum Operator {
O_UNDEF, O_SEMI_SEMICOLON, O_SEMICOLON, O_COMMA, O_COLON,
O_ASSIGN, O_PLUS_ASSIGN, O_MINUS_ASSIGN, O_DIV_ASSIGN, O_TIMES_ASSIGN,
void parseImport();
RplASItem* parseModule(const QString& name);
void parse();
+ RplASItem*parseExprStatement();
protected:
RplASArgument* parseArguments();
RplASItem* parseOperand(int level);
/**
* @brief Destructor.
*/
-RplReader::~RplReader() {
+RplReader::~RplReader()
+{
+ clear();
+}
+
+/**
+ * @brief Frees the resources.
+ */
+void RplReader::clear()
+{
QMap<QString, RplSourceUnit*>::iterator it;
for(it = m_units.begin(); it != m_units.end(); it++) {
RplStringSourceUnit* unit = (RplStringSourceUnit*)(*it);
delete unit;
}
+ m_units.clear();
+ m_currentSourceUnit = NULL;
}
/**
* otherwise: the last entry from the source unit stack
*/
RplSourceUnit* RplSource::popSourceUnit(RplReader* reader) {
+ RplSourceUnit* rc = NULL;
if(m_unitStack.size() > 0)
m_unitStack.pop();
m_currentReader = m_unitStack.size() <= 0
? NULL : m_unitStack.top()->reader();
- RplSourceUnit* rc = NULL;
if(m_currentReader == reader)
rc = m_unitStack.top();
else {
* @brief Destructor.
*/
RplStringReader::~RplStringReader() {
+ clear();
}
/**
*/
bool RplStringReader::nextLine(int maxSize, QString& buffer,
bool& hasMore) {
- m_currentSourceUnit->setLineNo(m_currentSourceUnit->lineNo() + 1);
- bool rc = fillBuffer(maxSize, buffer, hasMore);
+ bool rc = m_currentSourceUnit != NULL;
+ if (rc){
+ m_currentSourceUnit->setLineNo(m_currentSourceUnit->lineNo() + 1);
+ rc = fillBuffer(maxSize, buffer, hasMore);
+ }
return rc;
}
*/
virtual bool fillBuffer(int maxSize, QString& buffer, bool& hasMore) = 0;
public:
+ virtual void clear();
RplSource& source();
RplSourceUnit* currentSourceUnit() const;
bool setCurrentSourceUnit(const QString& currentSourceUnit);
m_tree(),
m_reader(m_source)
{
- m_reader.addSource("<test>", "");
m_source.addReader(&m_reader);
}
protected:
void setSource(const char* content){
m_tree.clear();
m_source.clear();
- m_reader.replaceSource("<test>", content);
+ m_reader.clear();
+ m_reader.addSource("<test>", content);
m_source.addReader(&m_reader);
m_source.addSourceUnit(m_reader.currentSourceUnit());
}