Old, outdated part of project has been removed.
I added some comments to BasicExpression I removed "parent" from all ASTClasses. Why? It wasn't useful at all, and it make my design much better and easier to improve later.functions
parent
4bbba3bdc9
commit
77399daf66
|
@ -9,7 +9,6 @@
|
|||
|
||||
|
||||
ASTExpression::ASTExpression() {
|
||||
this->parent = parent;
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
#include "ASTNode.h"
|
||||
|
||||
ASTNode::ASTNode() {
|
||||
parent = 0;
|
||||
|
||||
}
|
||||
|
||||
ASTNode::~ASTNode() {
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
class ASTNode : public Visitable{
|
||||
public:
|
||||
ASTNode();
|
||||
ASTNode * parent;
|
||||
std::vector<ASTNode *> children;
|
||||
|
||||
virtual void accept(Visitor * visitor){ visitor->visit(this); };
|
||||
|
|
|
@ -65,9 +65,8 @@ std::string Assignment::debug()
|
|||
return debug_note;
|
||||
}
|
||||
|
||||
Assignment::Assignment(ASTNode * parent, Context * context)
|
||||
Assignment::Assignment(Context * context)
|
||||
{
|
||||
this->parent = parent;
|
||||
this->context = context;
|
||||
this->type = "Assignment";
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ public:
|
|||
void add_lvalue(ASTExpression *);
|
||||
void add_rvalue(ASTExpression *);
|
||||
virtual std::string debug() ;
|
||||
Assignment(ASTNode * parent, Context * context);
|
||||
Assignment(Context * context);
|
||||
virtual ~Assignment();
|
||||
};
|
||||
|
||||
|
|
|
@ -44,8 +44,6 @@ void BasicExpression::set_right_operand(ASTNode * right)
|
|||
}
|
||||
void BasicExpression::execute()
|
||||
{
|
||||
//children[0]->execute();
|
||||
//children[1]->execute();
|
||||
std::cout << evaluate().repr() << std::endl;
|
||||
}
|
||||
|
||||
|
@ -106,7 +104,6 @@ SenchaObject BasicExpression::evaluate()
|
|||
{
|
||||
so = SenchaObject(left < right);
|
||||
}
|
||||
//TODO actually those should get through parser
|
||||
else if(oper == "&&")
|
||||
{
|
||||
so = SenchaObject(left.is_true() && right.is_true());
|
||||
|
@ -118,8 +115,7 @@ SenchaObject BasicExpression::evaluate()
|
|||
return so;
|
||||
}
|
||||
|
||||
BasicExpression::BasicExpression(ASTNode * parent) : children_set(false){
|
||||
this->parent = parent;
|
||||
BasicExpression::BasicExpression() : children_set(false){
|
||||
this->type= "BasicExpression";
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,14 @@
|
|||
#define BASICEXPRESSION_H_
|
||||
#include "ASTExpression.h"
|
||||
#include <iostream>
|
||||
|
||||
/**
|
||||
* BasicExpression is a very important class in my AST design. It always has
|
||||
* two children, which are actually left and right operands. Basic expression stores
|
||||
* a type of operation it does. It can be "+" or "-" for example.
|
||||
* Type of operator is very important when expression evaluates itself.
|
||||
*
|
||||
*/
|
||||
class BasicExpression : public ASTExpression {
|
||||
public:
|
||||
|
||||
|
@ -21,10 +29,11 @@ public:
|
|||
std::string get_operator() { return oper; }
|
||||
virtual void accept(Visitor * visitor);
|
||||
|
||||
BasicExpression(ASTNode * parent);
|
||||
BasicExpression();
|
||||
virtual ~BasicExpression();
|
||||
|
||||
private:
|
||||
//Do I use it for anything actually?
|
||||
bool children_set;
|
||||
std::string oper;
|
||||
};
|
||||
|
|
|
@ -7,8 +7,7 @@
|
|||
|
||||
#include "BasicStatement.h"
|
||||
|
||||
BasicStatement::BasicStatement(ASTNode * parent) {
|
||||
this->parent = parent;
|
||||
BasicStatement::BasicStatement() {
|
||||
this->type = "BasicStatement";
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
class BasicStatement : public ASTStatement {
|
||||
public:
|
||||
BasicStatement(ASTNode * parent);
|
||||
BasicStatement();
|
||||
void add_expression(ASTExpression * expr);
|
||||
virtual SenchaObject evaluate();
|
||||
virtual void execute();
|
||||
|
|
|
@ -7,9 +7,8 @@
|
|||
|
||||
#include "ConstantExpression.h"
|
||||
|
||||
ConstantExpression::ConstantExpression(ASTNode * parent) //Constructor which sets value to null SenchaObject.
|
||||
ConstantExpression::ConstantExpression() //Constructor which sets value to null SenchaObject.
|
||||
{
|
||||
this->parent = parent;
|
||||
value = SenchaObject();
|
||||
this->type = "ConstantExpression";
|
||||
}
|
||||
|
@ -18,9 +17,8 @@ ConstantExpression::~ConstantExpression() {
|
|||
|
||||
}
|
||||
|
||||
ConstantExpression::ConstantExpression(ASTNode * parent, SenchaObject value) : value(value)
|
||||
ConstantExpression::ConstantExpression(SenchaObject value) : value(value)
|
||||
{
|
||||
this->parent = parent;
|
||||
this->type = "ConstantExpression";
|
||||
}
|
||||
|
||||
|
@ -44,21 +42,21 @@ void ConstantExpression::accept(Visitor * visitor)
|
|||
visitor->visit(this);
|
||||
}
|
||||
|
||||
ConstantExpression::ConstantExpression(ASTNode * parent, int number)
|
||||
ConstantExpression::ConstantExpression( int number)
|
||||
{
|
||||
this->parent = parent; value = SenchaObject(number);
|
||||
value = SenchaObject(number);
|
||||
this->type = "ConstantExpression";
|
||||
}
|
||||
|
||||
ConstantExpression::ConstantExpression(ASTNode * parent, double number)
|
||||
ConstantExpression::ConstantExpression( double number)
|
||||
{
|
||||
this->parent = parent;
|
||||
|
||||
this->type = "ConstantExpression";
|
||||
value = SenchaObject(number);
|
||||
}
|
||||
|
||||
ConstantExpression::ConstantExpression(ASTNode * parent, std::string text)
|
||||
ConstantExpression::ConstantExpression( std::string text)
|
||||
{
|
||||
this->type = "ConstantExpression";
|
||||
this->parent = parent; value = SenchaObject(text);
|
||||
value = SenchaObject(text);
|
||||
}
|
||||
|
|
|
@ -24,40 +24,35 @@ public:
|
|||
|
||||
/**
|
||||
* Constructor which sets value to null SenchaObject.o it
|
||||
* @param parent of the ConstantExpression node
|
||||
* @param number value will be set to SenchaObject representing this number
|
||||
*/
|
||||
ConstantExpression(ASTNode * parent);
|
||||
ConstantExpression();
|
||||
|
||||
|
||||
/**
|
||||
*Constructor which creates SenchaObject(number) and sets value to it
|
||||
* @param parent of the ConstantExpression node
|
||||
* @param number value will be set to SenchaObject representing this number
|
||||
*/
|
||||
ConstantExpression(ASTNode * parent, int number) ;
|
||||
ConstantExpression( int number) ;
|
||||
|
||||
/**
|
||||
* Constructor which creates SenchaObject(number) and sets value to it
|
||||
* @param parent of the ConstantExpression node
|
||||
* @param number value will be set to SenchaObject representing this number
|
||||
*/
|
||||
ConstantExpression(ASTNode * parent, double number) ;
|
||||
ConstantExpression( double number) ;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor which creates SenchaObject(text) and sets value to it
|
||||
* @param parent of the ConstantExpression node
|
||||
* @param text value will be set to SenchaObject representing this text
|
||||
*/
|
||||
ConstantExpression(ASTNode * parent, std::string text);
|
||||
ConstantExpression( std::string text);
|
||||
|
||||
/**
|
||||
* Constructor which sets value to given value
|
||||
* @param parent of the ConstantExpression node
|
||||
* @param value this->value will be set to value
|
||||
*/
|
||||
ConstantExpression(ASTNode * parent, SenchaObject value);
|
||||
ConstantExpression(SenchaObject value);
|
||||
|
||||
/** Here's value of constant expression */
|
||||
SenchaObject value;
|
||||
|
|
|
@ -27,7 +27,7 @@ void DeclarationStatement::add_right_value(ASTExpression * right)
|
|||
children[0] = right;
|
||||
}
|
||||
|
||||
DeclarationStatement::DeclarationStatement(ASTNode * parent, Context * context)
|
||||
DeclarationStatement::DeclarationStatement(Context * context)
|
||||
{
|
||||
this->context = context;
|
||||
is_function = false;
|
||||
|
|
|
@ -24,7 +24,7 @@ public:
|
|||
bool is_function;
|
||||
|
||||
void add_right_value(ASTExpression * right);
|
||||
DeclarationStatement(ASTNode * parent, Context * context);
|
||||
DeclarationStatement(Context * context);
|
||||
void add_name(std::string);
|
||||
|
||||
|
||||
|
|
|
@ -8,8 +8,7 @@
|
|||
#include "IfNode.h"
|
||||
|
||||
|
||||
IfNode::IfNode(ASTNode * parent) {
|
||||
this->parent = parent;
|
||||
IfNode::IfNode() {
|
||||
is_else = false;
|
||||
this->type = "IfNode";
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ public:
|
|||
ASTNode * condition() { return children[0]; }
|
||||
ASTNode * then_block() { return children[1]; }
|
||||
ASTNode * else_block() { return children[2]; }
|
||||
IfNode(ASTNode * parent);
|
||||
IfNode();
|
||||
virtual ~IfNode();
|
||||
};
|
||||
|
||||
|
|
|
@ -7,9 +7,8 @@
|
|||
|
||||
#include "IncorrectExpression.h"
|
||||
|
||||
IncorrectExpression::IncorrectExpression(ASTNode * parent, std::string error_message)
|
||||
IncorrectExpression::IncorrectExpression(std::string error_message)
|
||||
{
|
||||
this->parent = parent;
|
||||
this->error_message = error_message;
|
||||
this->type = "IncorrectExpression";
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ public:
|
|||
}
|
||||
std::string debug() { return "Incorrect Expression:\n" + error_message; }
|
||||
|
||||
IncorrectExpression(ASTNode * parent, std::string error_message);
|
||||
IncorrectExpression( std::string error_message);
|
||||
virtual ~IncorrectExpression();
|
||||
};
|
||||
|
||||
|
|
|
@ -7,8 +7,7 @@
|
|||
|
||||
#include "PostfixExpression.h"
|
||||
|
||||
PostfixExpression::PostfixExpression(ASTNode * parent, Context * context) {
|
||||
this->parent = parent;
|
||||
PostfixExpression::PostfixExpression(Context * context) {
|
||||
this->context = context;
|
||||
name = "";
|
||||
native = false;
|
||||
|
|
|
@ -25,7 +25,7 @@ public:
|
|||
virtual void execute_quietly(){ execute();
|
||||
};
|
||||
|
||||
PostfixExpression(ASTNode * parent, Context * context);
|
||||
PostfixExpression( Context * context);
|
||||
virtual ~PostfixExpression();
|
||||
};
|
||||
|
||||
|
|
|
@ -7,9 +7,8 @@
|
|||
|
||||
#include "RepeatStatement.h"
|
||||
|
||||
RepeatStatement::RepeatStatement(ASTNode * parent)
|
||||
RepeatStatement::RepeatStatement()
|
||||
{
|
||||
this->parent = parent;
|
||||
how_many_times = 0;
|
||||
body = NULL;
|
||||
this->type = "RepeatStatement";
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
class RepeatStatement: public ASTStatement {
|
||||
public:
|
||||
RepeatStatement(ASTNode * parent);
|
||||
RepeatStatement();
|
||||
int how_many_times;
|
||||
ASTStatement * body;
|
||||
void add_iteration_number(SenchaObject so);
|
||||
|
|
|
@ -7,10 +7,8 @@
|
|||
|
||||
#include "VariableExpression.h"
|
||||
|
||||
VariableExpression::VariableExpression(ASTNode * parent, Context * context, std::string name) {
|
||||
|
||||
VariableExpression::VariableExpression(Context * context, std::string name) {
|
||||
this->name = name;
|
||||
this->parent = parent;
|
||||
this->context = context;
|
||||
this->type = "VariableExpression";
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
class VariableExpression: public ASTExpression {
|
||||
public:
|
||||
VariableExpression();
|
||||
VariableExpression(ASTNode * parent, Context * context, std::string name);
|
||||
VariableExpression(Context * context, std::string name);
|
||||
|
||||
Context * context;
|
||||
std::string name;
|
||||
|
|
|
@ -7,9 +7,8 @@
|
|||
|
||||
#include "WhileNode.h"
|
||||
|
||||
WhileNode::WhileNode(ASTNode * parent) {
|
||||
WhileNode::WhileNode() {
|
||||
body = NULL;
|
||||
this->parent = parent;
|
||||
this->type = "WhileNode";
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#include "ASTExpression.h"
|
||||
class WhileNode: public ASTStatement {
|
||||
public:
|
||||
WhileNode(ASTNode * parent);
|
||||
WhileNode();
|
||||
virtual ~WhileNode();
|
||||
ASTStatement * body;
|
||||
void add_condition(ASTExpression * expression);
|
||||
|
|
|
@ -78,7 +78,7 @@ void Parser::interpret()
|
|||
read_next();
|
||||
while(tok_value!= "")
|
||||
{
|
||||
program->add_statement(statement(program));
|
||||
program->add_statement(statement());
|
||||
}
|
||||
|
||||
|
||||
|
@ -142,22 +142,22 @@ bool Parser::is_function_name()
|
|||
|
||||
}
|
||||
|
||||
ASTStatement * Parser::statement(ASTNode * parent)
|
||||
ASTStatement * Parser::statement()
|
||||
{
|
||||
BasicStatement * stat = new BasicStatement(parent);
|
||||
BasicStatement * stat = new BasicStatement();
|
||||
|
||||
if(accept("{"))
|
||||
{
|
||||
while(!accept("}"))
|
||||
{
|
||||
stat->children.push_back( statement(parent));
|
||||
stat->children.push_back( statement());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
else if(is_type())
|
||||
{
|
||||
DeclarationStatement * declaration = new DeclarationStatement(parent, context);
|
||||
DeclarationStatement * declaration = new DeclarationStatement(context);
|
||||
std::string identifier = tok_value;
|
||||
|
||||
read_next();
|
||||
|
@ -166,7 +166,7 @@ ASTStatement * Parser::statement(ASTNode * parent)
|
|||
|
||||
if(accept("="))
|
||||
{
|
||||
ASTExpression * ae = expr(stat);
|
||||
ASTExpression * ae = expr();
|
||||
declaration->add_right_value(ae);
|
||||
accept(";");
|
||||
}
|
||||
|
@ -193,7 +193,7 @@ ASTStatement * Parser::statement(ASTNode * parent)
|
|||
if(!accept(";"))
|
||||
{
|
||||
|
||||
declaration->add_body(statement(stat));
|
||||
declaration->add_body(statement());
|
||||
|
||||
}
|
||||
|
||||
|
@ -205,12 +205,12 @@ ASTStatement * Parser::statement(ASTNode * parent)
|
|||
}
|
||||
else if(accept("if"))
|
||||
{
|
||||
IfNode * ifStatement = new IfNode(parent);
|
||||
ifStatement->add_condition(expr(ifStatement));
|
||||
ifStatement->add_body(statement(parent));
|
||||
IfNode * ifStatement = new IfNode();
|
||||
ifStatement->add_condition(expr());
|
||||
ifStatement->add_body(statement());
|
||||
if(accept("else"))
|
||||
{
|
||||
ifStatement->add_else_block(statement(parent));
|
||||
ifStatement->add_else_block(statement());
|
||||
}
|
||||
|
||||
delete stat;
|
||||
|
@ -218,9 +218,9 @@ ASTStatement * Parser::statement(ASTNode * parent)
|
|||
}
|
||||
else if(accept("repeat"))
|
||||
{
|
||||
RepeatStatement * repeat = new RepeatStatement(parent);
|
||||
repeat->add_iteration_number(expr(repeat)->evaluate());
|
||||
repeat->add_body(statement(repeat));
|
||||
RepeatStatement * repeat = new RepeatStatement();
|
||||
repeat->add_iteration_number(expr()->evaluate());
|
||||
repeat->add_body(statement());
|
||||
|
||||
//similar stuff
|
||||
delete stat;
|
||||
|
@ -228,9 +228,9 @@ ASTStatement * Parser::statement(ASTNode * parent)
|
|||
}
|
||||
else if(accept("while"))
|
||||
{
|
||||
WhileNode * while_node = new WhileNode(parent);
|
||||
while_node->add_condition(expr(while_node));
|
||||
while_node->add_body(statement(while_node));
|
||||
WhileNode * while_node = new WhileNode();
|
||||
while_node->add_condition(expr());
|
||||
while_node->add_body(statement());
|
||||
|
||||
delete stat;
|
||||
return while_node;
|
||||
|
@ -240,7 +240,7 @@ ASTStatement * Parser::statement(ASTNode * parent)
|
|||
|
||||
if(!peek(";"))
|
||||
{
|
||||
stat->add_expression(expr(stat));
|
||||
stat->add_expression(expr());
|
||||
}
|
||||
expect(";");
|
||||
|
||||
|
@ -250,7 +250,7 @@ ASTStatement * Parser::statement(ASTNode * parent)
|
|||
else
|
||||
{
|
||||
|
||||
stat->add_expression(expr(stat));
|
||||
stat->add_expression(expr());
|
||||
while(!expect(";") && tok_value != "") read_next();
|
||||
return stat;
|
||||
|
||||
|
@ -259,27 +259,27 @@ ASTStatement * Parser::statement(ASTNode * parent)
|
|||
return stat;
|
||||
}
|
||||
|
||||
ASTExpression * Parser::prim_expr(ASTNode * expression)
|
||||
ASTExpression * Parser::prim_expr()
|
||||
{
|
||||
|
||||
if(current_token.get_type() == t_integer)
|
||||
{
|
||||
ConstantExpression * ce;
|
||||
ce = new ConstantExpression(expression, std::atoi(tok_value.c_str()));
|
||||
ce = new ConstantExpression(std::atoi(tok_value.c_str()));
|
||||
read_next();
|
||||
return ce;
|
||||
}
|
||||
else if(current_token.get_type() == t_float)
|
||||
{
|
||||
ConstantExpression * ce;
|
||||
ce = new ConstantExpression(expression, std::atof(tok_value.c_str()));
|
||||
ce = new ConstantExpression(std::atof(tok_value.c_str()));
|
||||
read_next();
|
||||
return ce;
|
||||
}
|
||||
else if(current_token.get_type() == t_literal)
|
||||
{
|
||||
ConstantExpression * ce;
|
||||
ce = new ConstantExpression(expression, tok_value);
|
||||
ce = new ConstantExpression(tok_value);
|
||||
read_next();
|
||||
return ce;
|
||||
}
|
||||
|
@ -289,13 +289,13 @@ ASTExpression * Parser::prim_expr(ASTNode * expression)
|
|||
if(tok_value == "true")
|
||||
{
|
||||
|
||||
ce = new ConstantExpression(expression, SenchaObject(true));
|
||||
ce = new ConstantExpression( SenchaObject(true));
|
||||
read_next();
|
||||
}
|
||||
else if (tok_value == "false")
|
||||
{
|
||||
|
||||
ce = new ConstantExpression(expression, SenchaObject(false));
|
||||
ce = new ConstantExpression(SenchaObject(false));
|
||||
read_next();
|
||||
}
|
||||
return ce;
|
||||
|
@ -305,14 +305,14 @@ ASTExpression * Parser::prim_expr(ASTNode * expression)
|
|||
string name = current_token.value;
|
||||
|
||||
VariableExpression * ve;
|
||||
ve = new VariableExpression(expression, context, name);
|
||||
ve = new VariableExpression(context, name);
|
||||
read_next();
|
||||
return ve;
|
||||
}
|
||||
else if(accept("("))
|
||||
{
|
||||
BasicExpression * be;
|
||||
be = static_cast<BasicExpression *>(expr(expression));
|
||||
be = static_cast<BasicExpression *>(expr());
|
||||
|
||||
expect(")");
|
||||
return be;
|
||||
|
@ -322,27 +322,27 @@ ASTExpression * Parser::prim_expr(ASTNode * expression)
|
|||
string error_message = "ERROR: unexpected primary expression " + tok_value + "\n";
|
||||
error(error_message);
|
||||
read_next();
|
||||
return new IncorrectExpression(expression, error_message);
|
||||
return new IncorrectExpression(error_message);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ASTExpression * Parser::postfix_expr(ASTNode * expression)
|
||||
ASTExpression * Parser::postfix_expr()
|
||||
{
|
||||
auto name = tok_value;
|
||||
if(is_function_name())
|
||||
{
|
||||
PostfixExpression * function_call = new PostfixExpression(expression, context);
|
||||
PostfixExpression * function_call = new PostfixExpression( context);
|
||||
function_call->set_name(name);
|
||||
if(accept("("))
|
||||
{
|
||||
if(!accept(")"))
|
||||
{
|
||||
|
||||
function_call->add_argument(expr(function_call));
|
||||
function_call->add_argument(expr());
|
||||
while(accept(","))
|
||||
{
|
||||
function_call->add_argument(expr(function_call));
|
||||
function_call->add_argument(expr());
|
||||
|
||||
}
|
||||
expect(")");
|
||||
|
@ -351,13 +351,13 @@ ASTExpression * Parser::postfix_expr(ASTNode * expression)
|
|||
return function_call;
|
||||
}
|
||||
}
|
||||
return prim_expr(expression);
|
||||
return prim_expr();
|
||||
}
|
||||
|
||||
ASTExpression * Parser::mul_expr(ASTNode * expression)
|
||||
ASTExpression * Parser::mul_expr()
|
||||
{
|
||||
BasicExpression * be = new BasicExpression(expression);
|
||||
be->set_left_operand(postfix_expr(be));
|
||||
BasicExpression * be = new BasicExpression();
|
||||
be->set_left_operand(postfix_expr());
|
||||
if(peek("*") || peek("/"))
|
||||
{
|
||||
if(accept("*"))
|
||||
|
@ -369,13 +369,12 @@ ASTExpression * Parser::mul_expr(ASTNode * expression)
|
|||
be->set_operator("/");
|
||||
|
||||
}
|
||||
be->set_right_operand(mul_expr(be));
|
||||
be->set_right_operand(mul_expr());
|
||||
}
|
||||
else
|
||||
{
|
||||
ASTExpression * ae;
|
||||
ae = static_cast<ASTExpression *>(be->children[0]);
|
||||
ae->parent = expression;
|
||||
delete be;
|
||||
return ae;
|
||||
}
|
||||
|
@ -383,10 +382,10 @@ ASTExpression * Parser::mul_expr(ASTNode * expression)
|
|||
return be;
|
||||
}
|
||||
|
||||
ASTExpression * Parser::add_expr(ASTNode * expression)
|
||||
ASTExpression * Parser::add_expr()
|
||||
{
|
||||
BasicExpression * be = new BasicExpression(expression);
|
||||
be->set_left_operand(mul_expr(be));
|
||||
BasicExpression * be = new BasicExpression();
|
||||
be->set_left_operand(mul_expr());
|
||||
if(peek("+") || peek("-"))
|
||||
{
|
||||
if(accept("+"))
|
||||
|
@ -399,13 +398,12 @@ ASTExpression * Parser::add_expr(ASTNode * expression)
|
|||
|
||||
be->set_operator("-");
|
||||
}
|
||||
be->set_right_operand(add_expr(be));
|
||||
be->set_right_operand(add_expr());
|
||||
}
|
||||
else
|
||||
{
|
||||
ASTExpression * ae;
|
||||
ae = static_cast<ASTExpression *>(be->children[0]);
|
||||
ae->parent = expression;
|
||||
delete be;
|
||||
return ae;
|
||||
}
|
||||
|
@ -413,10 +411,10 @@ ASTExpression * Parser::add_expr(ASTNode * expression)
|
|||
return be;
|
||||
}
|
||||
|
||||
ASTExpression * Parser::rel_expr(ASTNode * expression)
|
||||
ASTExpression * Parser::rel_expr()
|
||||
{
|
||||
BasicExpression * be = new BasicExpression(expression);
|
||||
be->set_left_operand(add_expr(be));
|
||||
BasicExpression * be = new BasicExpression();
|
||||
be->set_left_operand(add_expr());
|
||||
if(peek("<") || peek(">"))
|
||||
{
|
||||
if(accept("<"))
|
||||
|
@ -429,13 +427,12 @@ ASTExpression * Parser::rel_expr(ASTNode * expression)
|
|||
be->set_operator(">");
|
||||
|
||||
}
|
||||
be->set_right_operand(rel_expr(be));
|
||||
be->set_right_operand(rel_expr());
|
||||
}
|
||||
else
|
||||
{
|
||||
ASTExpression * ae;
|
||||
ae = static_cast<ASTExpression *>(be->children[0]);
|
||||
ae->parent = expression;
|
||||
delete be;
|
||||
return ae;
|
||||
}
|
||||
|
@ -444,10 +441,10 @@ ASTExpression * Parser::rel_expr(ASTNode * expression)
|
|||
return be;
|
||||
}
|
||||
|
||||
ASTExpression * Parser::eq_expr(ASTNode * expression)
|
||||
ASTExpression * Parser::eq_expr()
|
||||
{
|
||||
BasicExpression * be = new BasicExpression(expression);
|
||||
be->set_left_operand(rel_expr(be));
|
||||
BasicExpression * be = new BasicExpression();
|
||||
be->set_left_operand(rel_expr());
|
||||
if(peek("==") || peek("!="))
|
||||
{
|
||||
if(accept("=="))
|
||||
|
@ -460,13 +457,12 @@ ASTExpression * Parser::eq_expr(ASTNode * expression)
|
|||
be->set_operator("!=");
|
||||
|
||||
}
|
||||
be->set_right_operand(eq_expr(be));
|
||||
be->set_right_operand(eq_expr());
|
||||
}
|
||||
else
|
||||
{
|
||||
ASTExpression * ae;
|
||||
ae = static_cast<ASTExpression *>(be->children[0]);
|
||||
ae->parent = expression;
|
||||
delete be;
|
||||
return ae;
|
||||
}
|
||||
|
@ -474,10 +470,10 @@ ASTExpression * Parser::eq_expr(ASTNode * expression)
|
|||
return be;
|
||||
}
|
||||
|
||||
ASTExpression * Parser::log_expr(ASTNode * expression)
|
||||
ASTExpression * Parser::log_expr()
|
||||
{
|
||||
BasicExpression * be = new BasicExpression(expression);
|
||||
be->set_left_operand(eq_expr(be));
|
||||
BasicExpression * be = new BasicExpression();
|
||||
be->set_left_operand(eq_expr());
|
||||
if(peek("and") || peek("or"))
|
||||
{
|
||||
if(accept("and"))
|
||||
|
@ -490,13 +486,12 @@ ASTExpression * Parser::log_expr(ASTNode * expression)
|
|||
be->set_operator("||");
|
||||
|
||||
}
|
||||
be->set_right_operand(log_expr(be));
|
||||
be->set_right_operand(log_expr());
|
||||
}
|
||||
else
|
||||
{
|
||||
ASTExpression * ae;
|
||||
ae = static_cast<ASTExpression *>(be->children[0]);
|
||||
ae->parent = expression;
|
||||
delete be;
|
||||
return ae;
|
||||
}
|
||||
|
@ -504,15 +499,15 @@ ASTExpression * Parser::log_expr(ASTNode * expression)
|
|||
return be;
|
||||
}
|
||||
|
||||
ASTExpression * Parser::expr(ASTNode * expression)
|
||||
ASTExpression * Parser::expr()
|
||||
{
|
||||
Assignment * assignment = new Assignment(expression, context);
|
||||
Assignment * assignment = new Assignment( context);
|
||||
auto name = tok_value;
|
||||
ASTExpression * left = log_expr(assignment);
|
||||
ASTExpression * left = log_expr();
|
||||
|
||||
if(accept("="))
|
||||
{
|
||||
ASTExpression * right = expr(assignment);
|
||||
ASTExpression * right = expr();
|
||||
|
||||
assignment->add_lvalue(left);
|
||||
assignment->add_rvalue(right);
|
||||
|
@ -523,7 +518,6 @@ ASTExpression * Parser::expr(ASTNode * expression)
|
|||
|
||||
else
|
||||
{
|
||||
left->parent = expression;
|
||||
delete assignment;
|
||||
return left;
|
||||
}
|
||||
|
|
|
@ -44,16 +44,16 @@ class Parser
|
|||
void error(string s);
|
||||
|
||||
|
||||
ASTStatement * statement(ASTNode * node);
|
||||
ASTStatement * statement();
|
||||
|
||||
ASTExpression * log_expr(ASTNode * node);
|
||||
ASTExpression * mul_expr(ASTNode * node);
|
||||
ASTExpression * add_expr(ASTNode * node);
|
||||
ASTExpression * prim_expr(ASTNode * node);
|
||||
ASTExpression * postfix_expr(ASTNode * node);
|
||||
ASTExpression * rel_expr(ASTNode * node);
|
||||
ASTExpression * eq_expr(ASTNode * node);
|
||||
ASTExpression * expr(ASTNode * node);
|
||||
ASTExpression * log_expr();
|
||||
ASTExpression * mul_expr();
|
||||
ASTExpression * add_expr();
|
||||
ASTExpression * prim_expr();
|
||||
ASTExpression * postfix_expr();
|
||||
ASTExpression * rel_expr();
|
||||
ASTExpression * eq_expr();
|
||||
ASTExpression * expr();
|
||||
};
|
||||
|
||||
#endif // PARSER_H
|
||||
|
|
|
@ -28,12 +28,9 @@ std::string TestASTInspector::test_inspecting_basic_expression()
|
|||
muu_assert("Some of nodes were missed in visit", inspector.how_many_occurences_of("BasicExpression") == 1);
|
||||
muu_assert("Some of nodes were missed in visit", inspector.how_many_occurences_of("ConstantExpression") == 2);
|
||||
|
||||
|
||||
delete be;
|
||||
inspector.forget_everything();
|
||||
return test_report;
|
||||
|
||||
|
||||
}
|
||||
|
||||
std::string TestASTInspector::test_inspecting_simple_AST()
|
||||
|
@ -53,31 +50,29 @@ std::string TestASTInspector::test_inspecting_simple_AST()
|
|||
delete be;
|
||||
inspector.forget_everything();
|
||||
return test_report;
|
||||
|
||||
|
||||
}
|
||||
|
||||
std::string TestASTInspector::all_tests()
|
||||
{
|
||||
std::string test_report = "";
|
||||
|
||||
mu_run_test(test_inspecting_basic_expression);
|
||||
mu_run_test(test_inspecting_simple_AST);
|
||||
return test_report;
|
||||
mu_run_test(test_inspecting_basic_expression);
|
||||
mu_run_test(test_inspecting_simple_AST);
|
||||
return test_report;
|
||||
}
|
||||
|
||||
BasicExpression * TestASTInspector::build_basic_expression(std::string oper, SenchaObject arg1, SenchaObject arg2)
|
||||
{
|
||||
BasicExpression * be = new BasicExpression(NULL);
|
||||
BasicExpression * be = new BasicExpression();
|
||||
be->set_operator(oper);
|
||||
be->set_left_operand(new ConstantExpression(be, arg1));
|
||||
be->set_right_operand(new ConstantExpression(be, arg2));
|
||||
be->set_left_operand(new ConstantExpression( arg1));
|
||||
be->set_right_operand(new ConstantExpression( arg2));
|
||||
return be;
|
||||
}
|
||||
|
||||
BasicExpression * TestASTInspector::build_simple_AST(std::string oper, BasicExpression * left, BasicExpression * right)
|
||||
{
|
||||
BasicExpression * be = new BasicExpression(NULL);
|
||||
BasicExpression * be = new BasicExpression();
|
||||
be->set_operator(oper);
|
||||
be->set_left_operand(left);
|
||||
be->set_right_operand(right);
|
||||
|
|
|
@ -52,7 +52,7 @@ PROJECT_LOGO =
|
|||
# If a relative path is entered, it will be relative to the location
|
||||
# where doxygen was started. If left blank the current directory will be used.
|
||||
|
||||
OUTPUT_DIRECTORY = ../documentation
|
||||
OUTPUT_DIRECTORY = ../../sencha-documentation
|
||||
|
||||
# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
|
||||
# 4096 sub-directories (in 2 levels) under the output directory of each output
|
||||
|
|
|
@ -1,59 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
|
||||
<storageModule moduleId="org.eclipse.cdt.core.settings">
|
||||
<cconfiguration id="org.eclipse.linuxtools.cdt.autotools.core.toolChain.1709733272">
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="org.eclipse.linuxtools.cdt.autotools.core.toolChain.1709733272" moduleId="org.eclipse.cdt.core.settings" name="Build (GNU)">
|
||||
<externalSettings/>
|
||||
<extensions>
|
||||
<extension id="org.eclipse.cdt.core.MachO64" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="org.eclipse.cdt.core.PE" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="org.eclipse.cdt.core.Cygwin_PE" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
</extensions>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<configuration buildProperties="" id="org.eclipse.linuxtools.cdt.autotools.core.toolChain.1709733272" name="Build (GNU)" parent="org.eclipse.cdt.build.core.emptycfg">
|
||||
<folderInfo id="org.eclipse.linuxtools.cdt.autotools.core.toolChain.1709733272.940433689" name="/" resourcePath="">
|
||||
<toolChain id="org.eclipse.linuxtools.cdt.autotools.core.toolChain.1507619182" name="org.eclipse.linuxtools.cdt.autotools.core.toolChain" superClass="org.eclipse.linuxtools.cdt.autotools.core.toolChain">
|
||||
<targetPlatform id="org.eclipse.linuxtools.cdt.autotools.core.toolchain.targetPlatform.594452659" isAbstract="false" name="GNU Autotools Target Platform" superClass="org.eclipse.linuxtools.cdt.autotools.core.toolchain.targetPlatform"/>
|
||||
<builder id="org.eclipse.linuxtools.cdt.autotools.core.toolchain.builder.2141841484" managedBuildOn="false" name="null.Build (GNU)" superClass="org.eclipse.linuxtools.cdt.autotools.core.toolchain.builder"/>
|
||||
<tool id="org.eclipse.linuxtools.cdt.autotools.core.gnu.toolchain.tool.configure.447184730" name="configure" superClass="org.eclipse.linuxtools.cdt.autotools.core.gnu.toolchain.tool.configure">
|
||||
<option id="org.eclipse.linuxtools.cdt.autotools.core.option.configure.name.605453349" superClass="org.eclipse.linuxtools.cdt.autotools.core.option.configure.name" value="org.eclipse.linuxtools.cdt.autotools.core.toolChain.1709733272" valueType="string"/>
|
||||
</tool>
|
||||
<tool id="org.eclipse.linuxtools.cdt.autotools.core.toolchain.tool.autogen.2024332737" name="autogen.sh" superClass="org.eclipse.linuxtools.cdt.autotools.core.toolchain.tool.autogen"/>
|
||||
<tool id="org.eclipse.linuxtools.cdt.autotools.core.toolchain.tool.gcc.890759014" name="GCC C Compiler" superClass="org.eclipse.linuxtools.cdt.autotools.core.toolchain.tool.gcc">
|
||||
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.1879953934" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
|
||||
</tool>
|
||||
<tool id="org.eclipse.linuxtools.cdt.autotools.core.toolchain.tool.gpp.1902945035" name="GCC C++ Compiler" superClass="org.eclipse.linuxtools.cdt.autotools.core.toolchain.tool.gpp">
|
||||
<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1269568410" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
|
||||
</tool>
|
||||
</toolChain>
|
||||
</folderInfo>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||
</cconfiguration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<project id="sencha.null.770789515" name="sencha"/>
|
||||
</storageModule>
|
||||
<storageModule moduleId="scannerConfiguration">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
|
||||
<storageModule moduleId="refreshScope"/>
|
||||
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets">
|
||||
<buildTargets>
|
||||
<target name="sencha" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>sencha</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
</buildTargets>
|
||||
</storageModule>
|
||||
</cproject>
|
|
@ -1,27 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>sencha</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
|
||||
<triggers>clean,full,incremental,</triggers>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
|
||||
<triggers>full,incremental,</triggers>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.cdt.core.cnature</nature>
|
||||
<nature>org.eclipse.cdt.core.ccnature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
189
sencha/Lexer.cpp
189
sencha/Lexer.cpp
|
@ -1,189 +0,0 @@
|
|||
#include "Lexer.h"
|
||||
|
||||
Lexer::Lexer()
|
||||
{
|
||||
string keys[] = {"function", "class", "for", "while", "if", "else"};
|
||||
keywords.assign(keys, keys+6);
|
||||
|
||||
char punct[] = {'.', ',', ';', '{', '}', '[', ']', '(', ')'};
|
||||
punctuation.assign(punct, punct+9);
|
||||
|
||||
string oper[] = {"<", ">", "+", "-", "/", "*", "%", "&", "|", "=", ":", "==", "+=", "-=", "<=", ">=", "!=", "&&", "||"};
|
||||
operators.assign(oper, oper +19);
|
||||
}
|
||||
|
||||
Lexer::~Lexer()
|
||||
{
|
||||
//dtor
|
||||
}
|
||||
|
||||
void Lexer::add_keyword(string word)
|
||||
{
|
||||
if(!is_keyword(word))
|
||||
{
|
||||
keywords.push_back(word);
|
||||
}
|
||||
}
|
||||
void Lexer::add_punctuation_char(char c)
|
||||
{
|
||||
if(!is_punctuation(c))
|
||||
{
|
||||
punctuation.push_back(c);
|
||||
}
|
||||
}
|
||||
|
||||
void Lexer::add_operator(string oper)
|
||||
{
|
||||
if(!is_operator(oper))
|
||||
{
|
||||
operators.push_back(oper);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
vector<Token> Lexer::parse_line(string line)
|
||||
{
|
||||
vector<Token> tokens;
|
||||
while(line != "")
|
||||
{
|
||||
pair<string, Token> result_of_parsing = parse_token(line);
|
||||
line = result_of_parsing.first;
|
||||
Token token = result_of_parsing.second;
|
||||
if(token.get_value() != "")
|
||||
{
|
||||
tokens.push_back(token);
|
||||
}
|
||||
}
|
||||
return tokens;
|
||||
|
||||
}
|
||||
|
||||
pair<string, Token> Lexer::parse_token(string line)
|
||||
{
|
||||
string token_value = "";
|
||||
unsigned int i;
|
||||
bool in_char_literal = false;
|
||||
for(i=0; i< line.size(); i++)
|
||||
{
|
||||
if(token_value == "" && isspace(line[i])) continue;
|
||||
|
||||
if(isalnum(line[i]) || line[i] == '\"' || line[i]== '_')
|
||||
{
|
||||
token_value += line[i];
|
||||
if(line[i] == '\"')
|
||||
{
|
||||
if(in_char_literal)
|
||||
{
|
||||
in_char_literal = false;
|
||||
}
|
||||
else in_char_literal = true;
|
||||
}
|
||||
}
|
||||
else if(ispunct(line[i]))
|
||||
{
|
||||
if(token_value=="")
|
||||
{
|
||||
token_value=line[i];
|
||||
i++;
|
||||
if(i<line.size())
|
||||
{
|
||||
if(line[i] == '=')
|
||||
{
|
||||
token_value+=line[i];
|
||||
i++;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if (in_char_literal && isspace(line[i]))
|
||||
{
|
||||
token_value += line[i];
|
||||
}
|
||||
else break;
|
||||
}
|
||||
|
||||
Token token = Token(guess_type(token_value), token_value);
|
||||
string truncated_line = line.substr(i);
|
||||
|
||||
return pair<string, Token>(truncated_line, token);
|
||||
}
|
||||
|
||||
bool Lexer::is_keyword(string value)
|
||||
{
|
||||
for(int i=0; i< keywords.size(); i++)
|
||||
{
|
||||
if(value == keywords[i]) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Lexer::is_punctuation(char c)
|
||||
{
|
||||
|
||||
for(int i=0; i< punctuation.size(); i++)
|
||||
{
|
||||
if(c == punctuation[i]) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Lexer::is_operator(string value)
|
||||
{
|
||||
for(int i=0; i< operators.size(); i++)
|
||||
{
|
||||
if(value == operators[i]) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
type_of_token Lexer::guess_type(string value) //TODO, hey wouldn't it be nice, to implement it?
|
||||
{
|
||||
/* I can have one of these types:
|
||||
typedef enum { t_invalid_token=0, t_symbol, t_integer, t_literal,
|
||||
t_punctuation, t_keyword } type_of_token;
|
||||
|
||||
*/
|
||||
|
||||
if(value == "") return t_invalid_token;
|
||||
if(isdigit(value[0]))
|
||||
{
|
||||
bool is_integer = true;
|
||||
for(int i=1; i<value.size(); i++)
|
||||
{
|
||||
if(!isdigit(value[i])) is_integer = false;
|
||||
}
|
||||
|
||||
if(is_integer) return t_integer;
|
||||
else return t_invalid_token;
|
||||
}
|
||||
if(isalpha(value[0]))
|
||||
{
|
||||
if(is_keyword(value)) return t_keyword;
|
||||
else return t_symbol;
|
||||
|
||||
}
|
||||
|
||||
if(value[0]=='\"')
|
||||
{
|
||||
if(value[value.size()-1] == '\"') return t_literal;
|
||||
else return t_invalid_token;
|
||||
}
|
||||
|
||||
if(value.size() == 1 )
|
||||
{
|
||||
if(is_punctuation(value[0])) return t_punctuation;
|
||||
else
|
||||
{
|
||||
if(is_operator(value)) return t_operator;
|
||||
}
|
||||
}
|
||||
if(value.size() == 2 && is_operator(value)) return t_operator;
|
||||
|
||||
//If any...
|
||||
return t_invalid_token;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
#ifndef LEXER_H
|
||||
#define LEXER_H
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <cctype>
|
||||
#include <iostream>
|
||||
#include "Token.h"
|
||||
|
||||
using namespace std;
|
||||
class Lexer
|
||||
{
|
||||
public:
|
||||
Lexer();
|
||||
virtual ~Lexer();
|
||||
|
||||
|
||||
|
||||
void add_keyword(string word);
|
||||
void add_punctuation_char(char c);
|
||||
void add_operator(string oper);
|
||||
|
||||
vector<Token> parse_line(string line);
|
||||
pair<string, Token> parse_token(string line);
|
||||
type_of_token guess_type(string value);
|
||||
|
||||
protected:
|
||||
private:
|
||||
|
||||
bool is_keyword(string value);
|
||||
bool is_punctuation(char c);
|
||||
bool is_operator(string value );
|
||||
|
||||
vector<string> keywords;
|
||||
vector<char> punctuation;
|
||||
vector<string> operators;
|
||||
};
|
||||
|
||||
#endif // LEXER_H
|
|
@ -1,12 +0,0 @@
|
|||
#include "Object.h"
|
||||
|
||||
Object::Object()
|
||||
{
|
||||
number_value = 0;
|
||||
//ctor
|
||||
}
|
||||
|
||||
Object::~Object()
|
||||
{
|
||||
//dtor
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
#ifndef OBJECT_H
|
||||
#define OBJECT_H
|
||||
#include <string>
|
||||
//I don't know how should it look like!
|
||||
class Object
|
||||
{
|
||||
public:
|
||||
Object();
|
||||
virtual ~Object();
|
||||
//Representation of the object
|
||||
std::string str();
|
||||
//Type
|
||||
std::string type();
|
||||
//Possible values
|
||||
double number_value;
|
||||
std::string characters;
|
||||
protected:
|
||||
private:
|
||||
};
|
||||
|
||||
#endif // OBJECT_H
|
|
@ -1,295 +0,0 @@
|
|||
#include "Parser.h"
|
||||
#include "iostream"
|
||||
|
||||
Parser::Parser(vector<Token> tokens)
|
||||
{
|
||||
error_message = "***ERRORS DURING PARSING***\n";
|
||||
report_message = "***PARSER REPORT***\n";
|
||||
token_stream = tokens;
|
||||
position_in_stream = 0;
|
||||
read_next();
|
||||
}
|
||||
|
||||
Parser::~Parser()
|
||||
{
|
||||
//dtor
|
||||
}
|
||||
|
||||
void Parser::report(string s)
|
||||
{
|
||||
report_message += s ;
|
||||
}
|
||||
|
||||
void Parser::error(string s)
|
||||
{
|
||||
error_message += s ;
|
||||
}
|
||||
|
||||
bool Parser::read_next()
|
||||
{
|
||||
if(position_in_stream < token_stream.size())
|
||||
{
|
||||
current_token = token_stream[position_in_stream];
|
||||
tok_value = current_token.get_value();
|
||||
position_in_stream++;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
current_token = Token(t_invalid_token, "");
|
||||
tok_value = current_token.get_value();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void Parser::interpret()
|
||||
{
|
||||
while(tok_value!= "")
|
||||
{
|
||||
if(is_type())
|
||||
{
|
||||
report("Identifier: " + tok_value + "\n");
|
||||
read_next();
|
||||
|
||||
if(accept("="))
|
||||
{
|
||||
expr();
|
||||
report(" :=\n");
|
||||
}
|
||||
if(accept(";"))
|
||||
{
|
||||
report("Variable definition\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
expect("(");
|
||||
int argc = 0;
|
||||
while(true)
|
||||
{
|
||||
argc++;
|
||||
is_type();
|
||||
report("function argument: " + tok_value + "\n");
|
||||
read_next();
|
||||
if(peek(")"))
|
||||
{
|
||||
break;
|
||||
}
|
||||
expect(",");
|
||||
}
|
||||
expect(")");
|
||||
|
||||
if(!accept(";"))
|
||||
{
|
||||
report("function body:\n");
|
||||
statement();
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
report("Regular statement:\n");
|
||||
statement();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Parser::peek(string s)
|
||||
{
|
||||
return tok_value == s;
|
||||
}
|
||||
|
||||
bool Parser::accept(string s)
|
||||
{
|
||||
if(peek(s))
|
||||
{
|
||||
read_next();
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
|
||||
bool Parser::expect(string s)
|
||||
{
|
||||
if(!accept(s))
|
||||
{
|
||||
string error_message = "Error: expected ";
|
||||
error_message += s;
|
||||
error_message += " but received: " + tok_value + "\n";
|
||||
|
||||
error(error_message);
|
||||
return false;
|
||||
}
|
||||
else return true;
|
||||
}
|
||||
|
||||
bool Parser::is_type()
|
||||
{
|
||||
if(current_token.get_type() == t_symbol || current_token.get_type() == t_keyword)
|
||||
{
|
||||
if(tok_value == "def" || tok_value == "string" || tok_value == "num")
|
||||
{
|
||||
read_next();
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
|
||||
void Parser::statement()
|
||||
{
|
||||
if(accept("{"))
|
||||
{
|
||||
while(!accept("}"))
|
||||
{
|
||||
statement();
|
||||
}
|
||||
}
|
||||
else if(is_type())
|
||||
{
|
||||
report("Local variable: " + tok_value + "\n");
|
||||
read_next();
|
||||
if(accept("="))
|
||||
{
|
||||
expr();
|
||||
report(" :=\n");
|
||||
}
|
||||
expect(";");
|
||||
}
|
||||
else if(accept("if"))
|
||||
{
|
||||
//stuff
|
||||
//TODO implement that
|
||||
}
|
||||
else if(accept("while"))
|
||||
{
|
||||
//similar stuff
|
||||
}
|
||||
else if(accept("return"))
|
||||
{
|
||||
|
||||
if(!peek(";"))
|
||||
{
|
||||
expr();
|
||||
}
|
||||
expect(";");
|
||||
report("RETURN\n");
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
expr();
|
||||
while(!expect(";")) read_next();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void Parser::prim_expr()
|
||||
{
|
||||
if(current_token.get_type() == t_integer)
|
||||
{
|
||||
report("Number: " + tok_value + "\n");
|
||||
}
|
||||
else if(current_token.get_type() == t_symbol)
|
||||
{
|
||||
report("Variable: " + tok_value + "\n");
|
||||
}
|
||||
else if(current_token.get_type() == t_literal)
|
||||
{
|
||||
report("Character literal: " + tok_value + "\n");
|
||||
}
|
||||
else if(accept("("))
|
||||
{
|
||||
expr();
|
||||
expect(")");
|
||||
}
|
||||
else
|
||||
{
|
||||
error("ERROR: unexpected primary expression" + tok_value + "\n");
|
||||
|
||||
}
|
||||
read_next();
|
||||
}
|
||||
|
||||
void Parser::postfix_expr()
|
||||
{
|
||||
prim_expr();
|
||||
if(accept("["))
|
||||
{
|
||||
expr();
|
||||
expect("]");
|
||||
report(" [] ");
|
||||
|
||||
}
|
||||
else if(accept("("))
|
||||
{
|
||||
if(!accept(")"))
|
||||
{
|
||||
expr();
|
||||
report("function argument\n");
|
||||
while(accept(","))
|
||||
{
|
||||
expr();
|
||||
report("function argument\n");
|
||||
}
|
||||
expect(")");
|
||||
}
|
||||
report("FUNC_CALL\n");
|
||||
}
|
||||
}
|
||||
|
||||
void Parser::add_expr()
|
||||
{
|
||||
postfix_expr();
|
||||
while(peek("+") || peek("-"))
|
||||
{
|
||||
if(accept("+"))
|
||||
{
|
||||
postfix_expr();
|
||||
report(" +\n");
|
||||
} else if(accept("-"))
|
||||
{
|
||||
postfix_expr();
|
||||
report(" -\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Parser::rel_expr()
|
||||
{
|
||||
add_expr();
|
||||
while(peek("<"))
|
||||
{
|
||||
accept("<");
|
||||
add_expr();
|
||||
report(" <\n");
|
||||
}
|
||||
}
|
||||
|
||||
void Parser::eq_expr()
|
||||
{
|
||||
rel_expr();
|
||||
while(peek("==") || peek("!="))
|
||||
{
|
||||
if(accept("=="))
|
||||
{
|
||||
rel_expr();
|
||||
report("==\n");
|
||||
}
|
||||
else if(accept("!="))
|
||||
{
|
||||
rel_expr();
|
||||
report("!=\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Parser::expr()
|
||||
{
|
||||
eq_expr();
|
||||
if(accept("="))
|
||||
{
|
||||
expr();
|
||||
report(" := ");
|
||||
}
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
#ifndef PARSER_H
|
||||
#define PARSER_H
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "Token.h"
|
||||
|
||||
|
||||
using namespace std;
|
||||
class Parser
|
||||
{
|
||||
public:
|
||||
Parser(vector<Token> tokens);
|
||||
virtual ~Parser();
|
||||
void interpret();
|
||||
string report_message;
|
||||
string error_message;
|
||||
|
||||
|
||||
protected:
|
||||
private:
|
||||
Token current_token;
|
||||
string tok_value;
|
||||
vector<Token> token_stream;
|
||||
int position_in_stream;
|
||||
|
||||
bool read_next();
|
||||
bool peek(string s);
|
||||
bool accept(string s);
|
||||
bool expect(string s);
|
||||
bool is_type();
|
||||
|
||||
void error(string s);
|
||||
void report(string s);
|
||||
|
||||
void statement();
|
||||
|
||||
void add_expr();
|
||||
void prim_expr();
|
||||
void postfix_expr();
|
||||
void rel_expr();
|
||||
void eq_expr();
|
||||
void expr();
|
||||
};
|
||||
|
||||
#endif // PARSER_H
|
|
@ -1,2 +0,0 @@
|
|||
#include "Token.h"
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
#ifndef TOKEN_H
|
||||
#define TOKEN_H
|
||||
#include <string>
|
||||
|
||||
|
||||
using namespace std;
|
||||
|
||||
typedef enum { t_invalid_token=0, t_symbol, t_integer, t_literal,
|
||||
t_punctuation, t_keyword, t_operator, t_float } type_of_token; //t_float not implemented
|
||||
//TODO implement t_float in lexer
|
||||
|
||||
|
||||
class Token
|
||||
{
|
||||
public:
|
||||
type_of_token type;
|
||||
string value;
|
||||
Token() : type(t_invalid_token), value("") {};
|
||||
Token(type_of_token type, string value) : type(type), value(value) { };
|
||||
type_of_token get_type() { return type; };
|
||||
string get_value() { return value; };
|
||||
|
||||
};
|
||||
|
||||
#endif // TOKEN_H
|
Binary file not shown.
|
@ -1,14 +0,0 @@
|
|||
#ifndef TOKEN_H
|
||||
#define TOKEN_H
|
||||
|
||||
|
||||
class Token
|
||||
{
|
||||
public:
|
||||
Token();
|
||||
virtual ~Token();
|
||||
protected:
|
||||
private:
|
||||
};
|
||||
|
||||
#endif // TOKEN_H
|
|
@ -1,33 +0,0 @@
|
|||
/*
|
||||
* lexer_tests.cpp
|
||||
*
|
||||
* Created on: Nov 2, 2012
|
||||
* Author: attero
|
||||
*/
|
||||
|
||||
#include <cstdio>
|
||||
#include "minunit.h"
|
||||
|
||||
int tests_run = 0;
|
||||
|
||||
int foo = 7;
|
||||
int bar = 4;
|
||||
|
||||
static char * test_foo() {
|
||||
mu_assert("error, foo != 7", foo == 7);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char * test_bar() {
|
||||
mu_assert("error, bar != 5", bar == 5);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char * all_tests() {
|
||||
mu_run_test(test_foo);
|
||||
mu_run_test(test_bar);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1,58 +0,0 @@
|
|||
#include <iostream>
|
||||
#include <string>
|
||||
#include "Token.h"
|
||||
#include "Lexer.h"
|
||||
#include "Parser.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
void test_lexer()
|
||||
{
|
||||
string test_line = "def i; bulb; i + 3; string banan; banan = \"banan and other stuff\"; string kaboom(num how_many_times) { def z; }";
|
||||
string test_line2 = "def how_many_trees = 1; how_many_trees + 3 == 2; num cut_tree( num how_many) {return how_many -1; != <=}";
|
||||
Lexer lexer;
|
||||
vector<Token> tokens = lexer.parse_line(test_line);
|
||||
|
||||
|
||||
for(int i=0; i< tokens.size(); i++)
|
||||
{
|
||||
cout << tokens[i].get_value() << " type: " << tokens[i].get_type() << endl;
|
||||
}
|
||||
|
||||
|
||||
tokens = lexer.parse_line(test_line2);
|
||||
|
||||
/*for(int i=0; i< tokens.size(); i++)
|
||||
{
|
||||
cout << tokens[i].get_value() << " type: " << tokens[i].get_type() << endl;
|
||||
}*/
|
||||
}
|
||||
|
||||
void test_parser()
|
||||
{
|
||||
vector<string> lines;
|
||||
lines.push_back("def i; bulb; i + 3; string banan = \"kartofel\"; banan = \"banan\"; string kaboom(num how_many_times) { def z; }");
|
||||
lines.push_back("{ i like bananas; string hello = \"hello\"; hello(); }");
|
||||
lines.push_back("def how_many_trees = 1; how_many_trees + 3 == 2; num cut_tree(num how_many) {return how_many -1;}");
|
||||
Lexer lexer;
|
||||
vector<Token> tokens;
|
||||
for(int i=0; i<lines.size(); i++)
|
||||
{
|
||||
tokens = lexer.parse_line(lines[i]);
|
||||
Parser parser = Parser(tokens);
|
||||
parser.interpret();
|
||||
cout << "<<<Parsing number: " << i << " >>>" << endl;
|
||||
cout << "Instructions: " << endl ;
|
||||
cout << lines[i] << endl << endl;
|
||||
cout << parser.report_message;
|
||||
cout << parser.error_message << endl;
|
||||
}
|
||||
|
||||
}
|
||||
int main()
|
||||
{
|
||||
cout << "Hello world!" << endl;
|
||||
//test_parser();
|
||||
//test_lexer();
|
||||
return 0;
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
/*
|
||||
* minunit.h
|
||||
*
|
||||
* Created on: Nov 2, 2012
|
||||
* Author: attero
|
||||
*/
|
||||
|
||||
#ifndef MINUNIT_H_
|
||||
#define MINUNIT_H_
|
||||
|
||||
#define mu_assert(message, test) do { if (!(test)) return message; } while (0)
|
||||
#define mu_run_test(test) do { char *message = test(); tests_run++; \
|
||||
if (message) return message; } while (0)
|
||||
extern int tests_run;
|
||||
|
||||
|
||||
#endif /* MINUNIT_H_ */
|
|
@ -1,54 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
||||
<CodeBlocks_project_file>
|
||||
<FileVersion major="1" minor="6" />
|
||||
<Project>
|
||||
<Option title="sencha" />
|
||||
<Option pch_mode="2" />
|
||||
<Option compiler="gcc" />
|
||||
<Build>
|
||||
<Target title="Debug">
|
||||
<Option output="bin/Debug/sencha" prefix_auto="1" extension_auto="1" />
|
||||
<Option object_output="obj/Debug/" />
|
||||
<Option type="1" />
|
||||
<Option compiler="gcc" />
|
||||
<Compiler>
|
||||
<Add option="-g" />
|
||||
</Compiler>
|
||||
</Target>
|
||||
<Target title="Release">
|
||||
<Option output="bin/Release/sencha" prefix_auto="1" extension_auto="1" />
|
||||
<Option object_output="obj/Release/" />
|
||||
<Option type="1" />
|
||||
<Option compiler="gcc" />
|
||||
<Compiler>
|
||||
<Add option="-O2" />
|
||||
</Compiler>
|
||||
<Linker>
|
||||
<Add option="-s" />
|
||||
</Linker>
|
||||
</Target>
|
||||
</Build>
|
||||
<Compiler>
|
||||
<Add option="-Wall" />
|
||||
<Add option="-fexceptions" />
|
||||
</Compiler>
|
||||
<Unit filename="AppleTree.cpp" />
|
||||
<Unit filename="AppleTree.h" />
|
||||
<Unit filename="Fruit.cpp" />
|
||||
<Unit filename="Fruit.h" />
|
||||
<Unit filename="FruitBasket.cpp" />
|
||||
<Unit filename="FruitBasket.h" />
|
||||
<Unit filename="Lexer.cpp" />
|
||||
<Unit filename="Lexer.h" />
|
||||
<Unit filename="Parser.cpp" />
|
||||
<Unit filename="Parser.h" />
|
||||
<Unit filename="Token.cpp" />
|
||||
<Unit filename="Token.h" />
|
||||
<Unit filename="main.cpp" />
|
||||
<Extensions>
|
||||
<envvars />
|
||||
<code_completion />
|
||||
<debugger />
|
||||
</Extensions>
|
||||
</Project>
|
||||
</CodeBlocks_project_file>
|
|
@ -1,54 +0,0 @@
|
|||
# depslib dependency file v1.0
|
||||
1350761891 source:/home/attero/development/sencha-lang/sencha/Token.cpp
|
||||
"Token.h"
|
||||
|
||||
1351424620 /home/attero/development/sencha-lang/sencha/Token.h
|
||||
<string>
|
||||
|
||||
1351540959 source:/home/attero/development/sencha-lang/sencha/Lexer.cpp
|
||||
"Lexer.h"
|
||||
|
||||
1351539503 /home/attero/development/sencha-lang/sencha/Lexer.h
|
||||
<vector>
|
||||
<string>
|
||||
<utility>
|
||||
<cctype>
|
||||
<iostream>
|
||||
"Token.h"
|
||||
|
||||
1351541355 source:/home/attero/development/sencha-lang/sencha/main.cpp
|
||||
<iostream>
|
||||
<string>
|
||||
"Token.h"
|
||||
"Lexer.h"
|
||||
"Parser.h"
|
||||
|
||||
1351539503 source:/home/attero/development/sencha-lang/sencha/Parser.cpp
|
||||
"Parser.h"
|
||||
"iostream"
|
||||
|
||||
1351543306 /home/attero/development/sencha-lang/sencha/Parser.h
|
||||
<string>
|
||||
<vector>
|
||||
"Token.h"
|
||||
"Fruit.h"
|
||||
"FruitBasket.h"
|
||||
|
||||
1351512311 source:/home/attero/development/sencha-lang/sencha/AppleTree.cpp
|
||||
"AppleTree.h"
|
||||
|
||||
1351512311 /home/attero/development/sencha-lang/sencha/AppleTree.h
|
||||
|
||||
1351543287 /home/attero/development/sencha-lang/sencha/Fruit.h
|
||||
<string>
|
||||
|
||||
1351543266 source:/home/attero/development/sencha-lang/sencha/Fruit.cpp
|
||||
"Fruit.h"
|
||||
|
||||
1351542956 source:/home/attero/development/sencha-lang/sencha/FruitBasket.cpp
|
||||
"FruitBasket.h"
|
||||
|
||||
1351543037 /home/attero/development/sencha-lang/sencha/FruitBasket.h
|
||||
<vector>
|
||||
"Fruit.h"
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
||||
<CodeBlocks_layout_file>
|
||||
<ActiveTarget name="Debug" />
|
||||
<File name="Fruit.h" open="1" top="0" tabpos="10">
|
||||
<Cursor position="199" topLine="0" />
|
||||
</File>
|
||||
<File name="Lexer.cpp" open="1" top="0" tabpos="4">
|
||||
<Cursor position="2314" topLine="88" />
|
||||
</File>
|
||||
<File name="Lexer.h" open="1" top="0" tabpos="5">
|
||||
<Cursor position="525" topLine="11" />
|
||||
</File>
|
||||
<File name="Parser.cpp" open="1" top="1" tabpos="6">
|
||||
<Cursor position="258" topLine="0" />
|
||||
</File>
|
||||
<File name="Parser.h" open="1" top="0" tabpos="7">
|
||||
<Cursor position="136" topLine="0" />
|
||||
</File>
|
||||
<File name="Token.cpp" open="1" top="0" tabpos="3">
|
||||
<Cursor position="22" topLine="0" />
|
||||
</File>
|
||||
<File name="Token.h" open="1" top="0" tabpos="2">
|
||||
<Cursor position="416" topLine="0" />
|
||||
</File>
|
||||
<File name="main.cpp" open="1" top="0" tabpos="1">
|
||||
<Cursor position="1282" topLine="23" />
|
||||
</File>
|
||||
</CodeBlocks_layout_file>
|
Loading…
Reference in New Issue