commit
39488ed535
|
@ -1,2 +1,3 @@
|
|||
Sencha-lang/Debug/*
|
||||
Sencha-lang/Release/*
|
||||
*.o
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
<tool id="cdt.managedbuild.tool.gnu.cross.cpp.compiler.495732557" name="Cross G++ Compiler" superClass="cdt.managedbuild.tool.gnu.cross.cpp.compiler">
|
||||
<option id="gnu.cpp.compiler.option.optimization.level.793014755" name="Optimization Level" superClass="gnu.cpp.compiler.option.optimization.level" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/>
|
||||
<option id="gnu.cpp.compiler.option.debugging.level.1513381051" name="Debug Level" superClass="gnu.cpp.compiler.option.debugging.level" value="gnu.cpp.compiler.debugging.level.max" valueType="enumerated"/>
|
||||
<option id="gnu.cpp.compiler.option.other.other.335578218" superClass="gnu.cpp.compiler.option.other.other" value="-c -fmessage-length=0 -std=gnu++0x " valueType="string"/>
|
||||
<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.859439950" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
|
||||
</tool>
|
||||
<tool id="cdt.managedbuild.tool.gnu.cross.c.linker.693029150" name="Cross GCC Linker" superClass="cdt.managedbuild.tool.gnu.cross.c.linker"/>
|
||||
|
|
Binary file not shown.
|
@ -1,19 +0,0 @@
|
|||
/*
|
||||
* AST.cpp
|
||||
*
|
||||
* Created on: Nov 4, 2012
|
||||
* Author: attero
|
||||
*/
|
||||
#include "AST.h"
|
||||
#include "AllTypesOfASTNodes.h"
|
||||
|
||||
AST::AST() {
|
||||
root = new ASTProgram();
|
||||
current_node = root;
|
||||
number_of_nodes = 1;
|
||||
level_of_depth = 0;
|
||||
}
|
||||
|
||||
AST::~AST() {
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
/*
|
||||
* AST.h
|
||||
*
|
||||
* Created on: Nov 4, 2012
|
||||
* Author: attero
|
||||
*/
|
||||
|
||||
#ifndef AST_H_
|
||||
#define AST_H_
|
||||
#include "ASTNode.h"
|
||||
|
||||
class AST {
|
||||
public:
|
||||
AST();
|
||||
ASTNode * root;
|
||||
ASTNode * current_node;
|
||||
int number_of_nodes;
|
||||
int level_of_depth;
|
||||
ASTNode * add_node(ASTNode * node);
|
||||
virtual ~AST();
|
||||
};
|
||||
|
||||
#endif /* AST_H_ */
|
|
@ -14,6 +14,11 @@ AST::AST() {
|
|||
level_of_depth = 0;
|
||||
}
|
||||
|
||||
void AST::delete_all_children()
|
||||
{
|
||||
//TODO perform deleting
|
||||
}
|
||||
|
||||
AST::~AST() {
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ public:
|
|||
ASTNode * current_node;
|
||||
int number_of_nodes;
|
||||
int level_of_depth;
|
||||
void delete_all_children();
|
||||
ASTNode * add_node(ASTNode * node);
|
||||
virtual ~AST();
|
||||
};
|
||||
|
|
|
@ -7,12 +7,13 @@
|
|||
|
||||
#include "ASTExpression.h"
|
||||
|
||||
|
||||
ASTExpression::ASTExpression() {
|
||||
// TODO Auto-generated constructor stub
|
||||
this->parent = parent;
|
||||
|
||||
}
|
||||
|
||||
ASTExpression::~ASTExpression() {
|
||||
// TODO Auto-generated destructor stub
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -7,10 +7,15 @@
|
|||
|
||||
#ifndef ASTEXPRESSION_H_
|
||||
#define ASTEXPRESSION_H_
|
||||
#include <string>
|
||||
#include "ASTNode.h"
|
||||
|
||||
class ASTExpression : public ASTNode {
|
||||
public:
|
||||
|
||||
virtual SenchaObject evaluate() = 0;
|
||||
virtual void execute() = 0;
|
||||
virtual void execute_quietly() = 0;
|
||||
ASTExpression();
|
||||
virtual ~ASTExpression();
|
||||
};
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
#include "ASTNode.h"
|
||||
|
||||
ASTNode::ASTNode() {
|
||||
// TODO Auto-generated constructor stub
|
||||
parent = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
#ifndef ASTNODE_H_
|
||||
#define ASTNODE_H_
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "SenchaObject.h"
|
||||
|
||||
class ASTNode {
|
||||
public:
|
||||
|
@ -17,6 +19,8 @@ public:
|
|||
void add_children(ASTNode *);
|
||||
void remove_most_right_children();
|
||||
void set_parent(ASTNode *);
|
||||
|
||||
virtual std::string debug() = 0;
|
||||
virtual void execute() = 0;
|
||||
virtual ~ASTNode();
|
||||
};
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
/*
|
||||
* ASTProgram.cpp
|
||||
*
|
||||
* Created on: Nov 5, 2012
|
||||
* Author: attero
|
||||
*/
|
||||
|
||||
#include "ASTProgram.h"
|
||||
|
||||
ASTProgram::ASTProgram() {
|
||||
// TODO Auto-generated constructor stub
|
||||
|
||||
}
|
||||
|
||||
ASTProgram::~ASTProgram() {
|
||||
// TODO Auto-generated destructor stub
|
||||
}
|
||||
|
||||
void ASTProgram::execute() {
|
||||
std::cout << "Program started!\n";
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
/*
|
||||
* ASTProgram.h
|
||||
*
|
||||
* Created on: Nov 5, 2012
|
||||
* Author: attero
|
||||
*/
|
||||
|
||||
#ifndef ASTPROGRAM_H_
|
||||
#define ASTPROGRAM_H_
|
||||
#include <iostream>
|
||||
#include "ASTNode.h"
|
||||
#include "ASTStatement.h"
|
||||
|
||||
class ASTProgram : public ASTNode {
|
||||
public:
|
||||
ASTProgram();
|
||||
ASTStatement * add_child(ASTStatement * node);
|
||||
virtual ~ASTProgram();
|
||||
virtual void execute();
|
||||
};
|
||||
|
||||
#endif /* ASTPROGRAM_H_ */
|
|
@ -12,6 +12,7 @@
|
|||
class ASTStatement : public ASTNode {
|
||||
public:
|
||||
ASTStatement();
|
||||
virtual void execute() = 0;
|
||||
virtual ~ASTStatement();
|
||||
};
|
||||
|
||||
|
|
|
@ -12,8 +12,14 @@
|
|||
#include "ProgramNode.h"
|
||||
#include "ASTStatement.h"
|
||||
#include "ASTExpression.h"
|
||||
#include "ASTPrimary.h"
|
||||
|
||||
#include "BasicStatement.h"
|
||||
#include "BasicExpression.h"
|
||||
#include "ConstantExpression.h"
|
||||
#include "PostfixExpression.h"
|
||||
#include "IncorrectExpression.h"
|
||||
#include "Assignment.h"
|
||||
#include "DeclarationStatement.h"
|
||||
//And probably more
|
||||
//TODO actualize it
|
||||
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* Assignment.cpp
|
||||
*
|
||||
* Created on: Dec 7, 2012
|
||||
* Author: attero
|
||||
*/
|
||||
|
||||
#include "Assignment.h"
|
||||
|
||||
SenchaObject Assignment::evaluate()
|
||||
{
|
||||
return static_cast<ASTExpression *>(children[1])->evaluate();
|
||||
}
|
||||
|
||||
void Assignment::execute()
|
||||
{
|
||||
auto left_value = static_cast<ASTExpression *>(children[0])->evaluate();
|
||||
auto right_value = static_cast<ASTExpression *>(children[1])->evaluate();
|
||||
static_cast<ASTExpression *>(children[1])->execute_quietly();
|
||||
if(left_value.name != "")
|
||||
{
|
||||
right_value.name = left_value.name;
|
||||
context->set(left_value.name, right_value);
|
||||
}
|
||||
std::cout << right_value.repr() << std::endl;
|
||||
}
|
||||
|
||||
void Assignment::execute_quietly()
|
||||
{
|
||||
auto left_value = static_cast<ASTExpression *>(children[0])->evaluate();
|
||||
auto right_value = static_cast<ASTExpression *>(children[1])->evaluate();
|
||||
static_cast<ASTExpression *>(children[1])->execute_quietly();
|
||||
if(left_value.name != "")
|
||||
{
|
||||
right_value.name = left_value.name;
|
||||
context->set(left_value.name, right_value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Assignment::add_lvalue(ASTExpression * left)
|
||||
{
|
||||
if(children.size()==0)
|
||||
children.push_back(left);
|
||||
else
|
||||
children[0] = left;
|
||||
}
|
||||
|
||||
void Assignment::add_rvalue(ASTExpression * right)
|
||||
{
|
||||
//TODO should note something if it doesn't look like that. Other possibilities like
|
||||
if(children.size()==1)
|
||||
children.push_back(right);
|
||||
else if(children.size()>1)
|
||||
children[1] = right;
|
||||
|
||||
}
|
||||
|
||||
std::string Assignment::debug()
|
||||
{
|
||||
std::string debug_note = static_cast<ASTExpression *>(children[0])->evaluate().repr();
|
||||
debug_note += " = " + static_cast<ASTExpression *>(children[1])->evaluate().repr() + "\n";
|
||||
return debug_note;
|
||||
}
|
||||
|
||||
Assignment::Assignment(ASTNode * parent, Context * context)
|
||||
{
|
||||
this->parent = parent;
|
||||
this->context = context;
|
||||
}
|
||||
|
||||
|
||||
Assignment::~Assignment() {
|
||||
// TODO Auto-generated destructor stub
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Assignment.h
|
||||
*
|
||||
* Created on: Dec 7, 2012
|
||||
* Author: attero
|
||||
*/
|
||||
|
||||
#ifndef ASSIGNMENT_H_
|
||||
#define ASSIGNMENT_H_
|
||||
#include <string>
|
||||
#include "ASTExpression.h"
|
||||
#include "../Context.h"
|
||||
|
||||
class Assignment : public ASTExpression {
|
||||
public:
|
||||
Context * context;
|
||||
|
||||
SenchaObject evaluate();
|
||||
void execute();
|
||||
void execute_quietly();
|
||||
void add_lvalue(ASTExpression *);
|
||||
void add_rvalue(ASTExpression *);
|
||||
virtual std::string debug() ;
|
||||
Assignment(ASTNode * parent, Context * context);
|
||||
virtual ~Assignment();
|
||||
};
|
||||
|
||||
#endif /* ASSIGNMENT_H_ */
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* BasicExpression.cpp
|
||||
*
|
||||
* Created on: Dec 5, 2012
|
||||
* Author: attero
|
||||
*/
|
||||
|
||||
#include "BasicExpression.h"
|
||||
|
||||
void BasicExpression::set_operator(std::string op)
|
||||
{
|
||||
this->oper = op;
|
||||
}
|
||||
|
||||
void BasicExpression::set_left_operand(ASTNode * left)
|
||||
{
|
||||
if(!this->children_set)
|
||||
{
|
||||
children.push_back(left);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->children[0] = left;
|
||||
}
|
||||
|
||||
if(children.size() == 2)
|
||||
children_set = true;
|
||||
}
|
||||
|
||||
void BasicExpression::set_right_operand(ASTNode * right)
|
||||
{
|
||||
if(!this->children_set)
|
||||
{
|
||||
children.push_back(right);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
this->children[1] = right;
|
||||
}
|
||||
|
||||
if(children.size() == 2)
|
||||
children_set = true;
|
||||
}
|
||||
void BasicExpression::execute()
|
||||
{
|
||||
//children[0]->execute();
|
||||
//children[1]->execute();
|
||||
std::cout << evaluate().repr() << std::endl;
|
||||
}
|
||||
|
||||
void BasicExpression::execute_quietly()
|
||||
{
|
||||
evaluate();
|
||||
}
|
||||
SenchaObject BasicExpression::evaluate()
|
||||
{
|
||||
//TODO refactor it ;)
|
||||
|
||||
SenchaObject left = static_cast<ASTExpression *>(children[0])->evaluate();
|
||||
SenchaObject right = static_cast<ASTExpression *>(children[1])->evaluate();
|
||||
|
||||
|
||||
SenchaObject so;
|
||||
if(oper == "+")
|
||||
{
|
||||
so = SenchaObject(left + right);
|
||||
}
|
||||
else if(oper == "-")
|
||||
{
|
||||
so = SenchaObject(left - right);
|
||||
}
|
||||
else if(oper == "*")
|
||||
{
|
||||
so = SenchaObject(left * right);
|
||||
}
|
||||
else if(oper == "/")
|
||||
{
|
||||
so = SenchaObject(left / right);
|
||||
}
|
||||
else if(oper == "=")
|
||||
{
|
||||
so = SenchaObject(right);
|
||||
}
|
||||
return so;
|
||||
}
|
||||
|
||||
BasicExpression::BasicExpression(ASTNode * parent) {
|
||||
this->parent = parent;
|
||||
children_set = false;
|
||||
}
|
||||
|
||||
BasicExpression::~BasicExpression() {
|
||||
// TODO Auto-generated destructor stub
|
||||
// TODO free children memory
|
||||
}
|
||||
|
||||
|
||||
std::string BasicExpression::debug()
|
||||
{
|
||||
std::string debug_note = "Basic expression:\n";
|
||||
debug_note += "left operand: \n";
|
||||
debug_note += this->children[0]->debug();
|
||||
debug_note += "\nright operand:\n" + this->children[1]->debug();
|
||||
debug_note += "\nOperator: " + this->oper +"\n###\n";
|
||||
return debug_note;
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* BasicExpression.h
|
||||
*
|
||||
* Created on: Dec 5, 2012
|
||||
* Author: attero
|
||||
*/
|
||||
|
||||
#ifndef BASICEXPRESSION_H_
|
||||
#define BASICEXPRESSION_H_
|
||||
#include "ASTExpression.h"
|
||||
#include <iostream>
|
||||
class BasicExpression : public ASTExpression {
|
||||
public:
|
||||
|
||||
std::string oper;
|
||||
|
||||
bool children_set;
|
||||
void set_operator(std::string op);
|
||||
void set_left_operand(ASTNode * left);
|
||||
void set_right_operand(ASTNode * right);
|
||||
virtual SenchaObject evaluate();
|
||||
virtual void execute();
|
||||
virtual void execute_quietly();
|
||||
|
||||
|
||||
std::string debug() ;
|
||||
|
||||
BasicExpression(ASTNode * parent);
|
||||
virtual ~BasicExpression();
|
||||
};
|
||||
|
||||
#endif /* BASICEXPRESSION_H_ */
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* BasicStatement.cpp
|
||||
*
|
||||
* Created on: Dec 5, 2012
|
||||
* Author: attero
|
||||
*/
|
||||
|
||||
#include "BasicStatement.h"
|
||||
|
||||
BasicStatement::BasicStatement(ASTNode * parent) {
|
||||
this->parent = parent;
|
||||
}
|
||||
|
||||
BasicStatement::~BasicStatement() {
|
||||
// TODO Auto-generated destructor stub
|
||||
}
|
||||
|
||||
void BasicStatement::add_expression(ASTExpression * expr)
|
||||
{
|
||||
children.push_back(expr);
|
||||
}
|
||||
|
||||
std::string BasicStatement::debug()
|
||||
{
|
||||
return "Basic statement with expression:\n" + children[0]->debug() + "\n;\n";
|
||||
}
|
||||
|
||||
void BasicStatement::execute()
|
||||
{
|
||||
children[0]->execute() ;
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* BasicStatement.h
|
||||
*
|
||||
* Created on: Dec 5, 2012
|
||||
* Author: attero
|
||||
*/
|
||||
|
||||
#ifndef BASICSTATEMENT_H_
|
||||
#define BASICSTATEMENT_H_
|
||||
#include <iostream>
|
||||
#include "ASTExpression.h"
|
||||
#include "ASTStatement.h"
|
||||
|
||||
class BasicStatement : public ASTStatement {
|
||||
public:
|
||||
BasicStatement(ASTNode * parent);
|
||||
virtual std::string debug();
|
||||
void add_expression(ASTExpression * expr);
|
||||
virtual void execute();
|
||||
virtual ~BasicStatement();
|
||||
};
|
||||
|
||||
#endif /* BASICSTATEMENT_H_ */
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* ConstantExpression.cpp
|
||||
*
|
||||
* Created on: Dec 5, 2012
|
||||
* Author: attero
|
||||
*/
|
||||
|
||||
#include "ConstantExpression.h"
|
||||
|
||||
ConstantExpression::ConstantExpression(ASTNode * parent) {
|
||||
this->parent = parent;
|
||||
value = SenchaObject();
|
||||
}
|
||||
|
||||
ConstantExpression::~ConstantExpression() {
|
||||
// TODO Auto-generated destructor stub
|
||||
}
|
||||
|
||||
ConstantExpression::ConstantExpression(ASTNode * parent, SenchaObject value, std::string name)
|
||||
{
|
||||
this->parent = parent;
|
||||
this->value = value;
|
||||
this->value.name = name;
|
||||
}
|
||||
|
||||
SenchaObject ConstantExpression::evaluate()
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
void ConstantExpression::execute()
|
||||
{
|
||||
std::cout << evaluate().repr() << std::endl;//Do nothing
|
||||
}
|
||||
|
||||
void ConstantExpression::execute_quietly()
|
||||
{
|
||||
evaluate();
|
||||
}
|
||||
|
||||
|
||||
ConstantExpression::ConstantExpression(ASTNode * parent, int number)
|
||||
{
|
||||
this->parent = parent; value = SenchaObject(number);
|
||||
}
|
||||
|
||||
ConstantExpression::ConstantExpression(ASTNode * parent, double number)
|
||||
{
|
||||
this->parent = parent;
|
||||
value = SenchaObject(number);
|
||||
}
|
||||
|
||||
ConstantExpression::ConstantExpression(ASTNode * parent, std::string text)
|
||||
{
|
||||
this->parent = parent; value = SenchaObject(text);
|
||||
}
|
||||
|
||||
std::string ConstantExpression::debug() { return "Constant expression:\n" + value.repr() + "\n"; }
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* ConstantExpression.h
|
||||
*
|
||||
* Created on: Dec 5, 2012
|
||||
* Author: attero
|
||||
*/
|
||||
|
||||
#ifndef CONSTANTEXPRESSION_H_
|
||||
#define CONSTANTEXPRESSION_H_
|
||||
#include "ASTExpression.h"
|
||||
#include <iostream>
|
||||
|
||||
class ConstantExpression : public ASTExpression {
|
||||
public:
|
||||
ConstantExpression(ASTNode * parent);
|
||||
ConstantExpression(ASTNode * parent, int number) ;
|
||||
ConstantExpression(ASTNode * parent, double number) ;
|
||||
ConstantExpression(ASTNode * parent, std::string text);
|
||||
ConstantExpression(ASTNode * parent, SenchaObject value, std::string name);
|
||||
SenchaObject value;
|
||||
|
||||
std::string debug();
|
||||
|
||||
|
||||
virtual ~ConstantExpression();
|
||||
virtual SenchaObject evaluate();
|
||||
|
||||
virtual void execute() ;
|
||||
virtual void execute_quietly() ;
|
||||
};
|
||||
|
||||
#endif /* CONSTANTEXPRESSION_H_ */
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* DeclarationStatement.cpp
|
||||
*
|
||||
* Created on: Dec 9, 2012
|
||||
* Author: attero
|
||||
*/
|
||||
|
||||
#include "DeclarationStatement.h"
|
||||
|
||||
|
||||
|
||||
DeclarationStatement::~DeclarationStatement() {
|
||||
// TODO Auto-generated destructor stub
|
||||
}
|
||||
|
||||
void DeclarationStatement::add_right_value(ASTExpression * right)
|
||||
{
|
||||
right_value = right->evaluate();
|
||||
children[0] = right;
|
||||
}
|
||||
|
||||
DeclarationStatement::DeclarationStatement(ASTNode * parent, Context * context)
|
||||
{
|
||||
this->context = context;
|
||||
is_function = false;
|
||||
body = NULL;
|
||||
right_value = SenchaObject();
|
||||
children.push_back(new ConstantExpression(this));
|
||||
}
|
||||
|
||||
std::string DeclarationStatement::debug()
|
||||
{
|
||||
std::string debug_note = "Declaration";
|
||||
return debug_note;
|
||||
}
|
||||
|
||||
void DeclarationStatement::add_name(std::string name)
|
||||
{
|
||||
this->name = name;
|
||||
}
|
||||
|
||||
|
||||
void DeclarationStatement::add_argument(std::string name)
|
||||
{
|
||||
arguments.push_back(name);
|
||||
}
|
||||
|
||||
void DeclarationStatement::execute()
|
||||
{
|
||||
if(is_function)
|
||||
{
|
||||
//TODO implement
|
||||
//do function registering stuff
|
||||
}
|
||||
else
|
||||
{
|
||||
context->add(name, right_value);
|
||||
children[0]->execute() ;
|
||||
}
|
||||
}
|
||||
|
||||
void DeclarationStatement::add_body(ASTStatement * statement)
|
||||
{
|
||||
is_function = true;
|
||||
body = statement;
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* DeclarationStatement.h
|
||||
*
|
||||
* Created on: Dec 9, 2012
|
||||
* Author: attero
|
||||
*/
|
||||
|
||||
#ifndef DECLARATIONSTATEMENT_H_
|
||||
#define DECLARATIONSTATEMENT_H_
|
||||
|
||||
#include "ASTStatement.h"
|
||||
#include "ASTExpression.h"
|
||||
#include "ConstantExpression.h"
|
||||
#include "../Context.h"
|
||||
|
||||
|
||||
class DeclarationStatement: public ASTStatement {
|
||||
public:
|
||||
std::string name;
|
||||
Context * context;
|
||||
SenchaObject right_value;
|
||||
ASTStatement * body;
|
||||
std::vector<std::string> arguments;
|
||||
bool is_function;
|
||||
|
||||
void add_right_value(ASTExpression * right);
|
||||
DeclarationStatement(ASTNode * parent, Context * context);
|
||||
virtual std::string debug();
|
||||
void add_name(std::string);
|
||||
|
||||
|
||||
void add_argument(std::string name);
|
||||
void add_body(ASTStatement * statement);
|
||||
|
||||
virtual void execute();
|
||||
virtual ~DeclarationStatement();
|
||||
};
|
||||
|
||||
#endif /* DECLARATIONSTATEMENT_H_ */
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* IncorrectExpression.cpp
|
||||
*
|
||||
* Created on: Dec 6, 2012
|
||||
* Author: attero
|
||||
*/
|
||||
|
||||
#include "IncorrectExpression.h"
|
||||
|
||||
IncorrectExpression::IncorrectExpression(ASTNode * parent, std::string error_message)
|
||||
{
|
||||
this->parent = parent;
|
||||
this->error_message = error_message;
|
||||
}
|
||||
|
||||
IncorrectExpression::~IncorrectExpression() {
|
||||
// TODO Auto-generated destructor stub
|
||||
}
|
||||
|
||||
SenchaObject IncorrectExpression::evaluate()
|
||||
{
|
||||
SenchaObject null_object;
|
||||
return null_object;
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* IncorrectExpression.h
|
||||
*
|
||||
* Created on: Dec 6, 2012
|
||||
* Author: attero
|
||||
*/
|
||||
|
||||
#ifndef INCORRECTEXPRESSION_H_
|
||||
#define INCORRECTEXPRESSION_H_
|
||||
|
||||
#include "ASTExpression.h"
|
||||
#include <iostream>
|
||||
|
||||
class IncorrectExpression: public ASTExpression {
|
||||
public:
|
||||
|
||||
std::string error_message;
|
||||
|
||||
virtual SenchaObject evaluate() ;
|
||||
|
||||
void execute() { std::cout << debug(); }
|
||||
void execute_quietly() { //do nothing
|
||||
|
||||
}
|
||||
std::string debug() { return "Incorrect Expression:\n" + error_message; }
|
||||
|
||||
IncorrectExpression(ASTNode * parent, std::string error_message);
|
||||
virtual ~IncorrectExpression();
|
||||
};
|
||||
|
||||
#endif /* INCORRECTEXPRESSION_H_ */
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* LogicalExpression.cpp
|
||||
*
|
||||
* Created on: Dec 8, 2012
|
||||
* Author: attero
|
||||
*/
|
||||
|
||||
#include "LogicalExpression.h"
|
||||
|
||||
LogicalExpression::LogicalExpression() {
|
||||
// TODO Auto-generated constructor stub
|
||||
|
||||
}
|
||||
|
||||
LogicalExpression::~LogicalExpression() {
|
||||
// TODO Auto-generated destructor stub
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* LogicalExpression.h
|
||||
*
|
||||
* Created on: Dec 8, 2012
|
||||
* Author: attero
|
||||
*/
|
||||
|
||||
#ifndef LOGICALEXPRESSION_H_
|
||||
#define LOGICALEXPRESSION_H_
|
||||
|
||||
#include "ASTExpression.h"
|
||||
|
||||
class LogicalExpression: public ASTExpression {
|
||||
public:
|
||||
LogicalExpression();
|
||||
virtual ~LogicalExpression();
|
||||
};
|
||||
|
||||
#endif /* LOGICALEXPRESSION_H_ */
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* PostfixExpression.cpp
|
||||
*
|
||||
* Created on: Dec 5, 2012
|
||||
* Author: attero
|
||||
*/
|
||||
|
||||
#include "PostfixExpression.h"
|
||||
|
||||
PostfixExpression::PostfixExpression(ASTNode * parent) {
|
||||
this->parent = parent;
|
||||
head_set = false;
|
||||
body_set = false;
|
||||
|
||||
}
|
||||
|
||||
PostfixExpression::~PostfixExpression() {
|
||||
// TODO Auto-generated destructor stub
|
||||
}
|
||||
|
||||
|
||||
void PostfixExpression::set_head(ASTExpression * expression)
|
||||
{
|
||||
//How should it look like?
|
||||
head_set = true;
|
||||
}
|
||||
|
||||
void PostfixExpression::add_argument(ASTExpression * expression)
|
||||
{
|
||||
arguments.push_back(expression);
|
||||
}
|
||||
|
||||
|
||||
SenchaObject PostfixExpression::evaluate()
|
||||
{
|
||||
return SenchaObject();
|
||||
}
|
||||
|
||||
void PostfixExpression::execute() { evaluate(); }
|
||||
|
||||
|
||||
|
||||
std::string PostfixExpression::debug()
|
||||
{
|
||||
return "Postfix expression tadadah!";
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* PostfixExpression.h
|
||||
*
|
||||
* Created on: Dec 5, 2012
|
||||
* Author: attero
|
||||
*/
|
||||
|
||||
#ifndef POSTFIXEXPRESSION_H_
|
||||
#define POSTFIXEXPRESSION_H_
|
||||
#include "ASTExpression.h"
|
||||
#include "ASTStatement.h"
|
||||
|
||||
class PostfixExpression : public ASTExpression {
|
||||
public:
|
||||
|
||||
bool body_set;
|
||||
bool head_set;
|
||||
std::vector<ASTExpression *> arguments;
|
||||
void set_head(ASTExpression * expression);
|
||||
void add_argument(ASTExpression * expression);
|
||||
|
||||
virtual SenchaObject evaluate();
|
||||
virtual void execute();
|
||||
virtual void execute_quietly(){//do nothing
|
||||
};
|
||||
|
||||
|
||||
std::string debug() ;
|
||||
|
||||
PostfixExpression(ASTNode * parent);
|
||||
virtual ~PostfixExpression();
|
||||
};
|
||||
|
||||
#endif /* POSTFIXEXPRESSION_H_ */
|
|
@ -17,5 +17,28 @@ ProgramNode::~ProgramNode() {
|
|||
}
|
||||
|
||||
void ProgramNode::execute() {
|
||||
std::cout << "Program started!\n";
|
||||
for (std::vector<ASTNode *>::iterator it = children.begin(); it!=children.end(); ++it) {
|
||||
(*it)->execute();
|
||||
}
|
||||
}
|
||||
|
||||
void ProgramNode::execute_last()
|
||||
{
|
||||
children[children.size() -1]->execute();
|
||||
}
|
||||
|
||||
std::string ProgramNode::debug()
|
||||
{
|
||||
std::string debug_note = "Program started debugging\n";
|
||||
|
||||
for (std::vector<ASTNode *>::iterator it = children.begin(); it!=children.end(); ++it) {
|
||||
debug_note += (*it)->debug() + "\n";
|
||||
}
|
||||
debug_note += "END\n";
|
||||
return debug_note;
|
||||
}
|
||||
void ProgramNode::add_statement(ASTStatement * statement)
|
||||
{
|
||||
children.push_back(statement);
|
||||
}
|
||||
|
||||
|
|
|
@ -14,9 +14,11 @@
|
|||
class ProgramNode : public ASTNode {
|
||||
public:
|
||||
ProgramNode();
|
||||
ASTStatement * add_child(ASTStatement * node);
|
||||
std::string debug();
|
||||
void add_statement(ASTStatement * statement);
|
||||
virtual ~ProgramNode();
|
||||
virtual void execute();
|
||||
virtual void execute_last();
|
||||
};
|
||||
|
||||
#endif /* PROGRAMNODE_H_ */
|
||||
|
|
|
@ -0,0 +1,152 @@
|
|||
/*
|
||||
* SenchaObject.cpp
|
||||
*
|
||||
* Created on: Dec 5, 2012
|
||||
* Author: attero
|
||||
*/
|
||||
|
||||
#include "SenchaObject.h"
|
||||
|
||||
SenchaObject::SenchaObject() {
|
||||
set_null_value();
|
||||
}
|
||||
|
||||
SenchaObject::~SenchaObject() {
|
||||
// TODO Auto-generated destructor stub
|
||||
}
|
||||
|
||||
|
||||
std::string SenchaObject::repr()
|
||||
{
|
||||
std::string representation = "";
|
||||
switch(type){
|
||||
case string_literal:
|
||||
representation = "type: string\n";
|
||||
representation += this->text;
|
||||
break;
|
||||
case integer_number:
|
||||
representation = "type: integer\n";
|
||||
representation += to_string(this->integer);
|
||||
break;
|
||||
case float_number:
|
||||
representation = "type: float\n";
|
||||
representation += to_string(this->number);
|
||||
break;
|
||||
case null:
|
||||
representation = "type: null\n";
|
||||
representation += "null";
|
||||
break;
|
||||
case symbol:
|
||||
representation = "type: symbol\n";
|
||||
representation += this->text;
|
||||
break;
|
||||
case invalid:
|
||||
representation = "type: invalid\n";
|
||||
representation += "some crap";
|
||||
break;
|
||||
}
|
||||
return representation;
|
||||
}
|
||||
|
||||
SenchaObject SenchaObject::operator+(const SenchaObject& right)const
|
||||
{
|
||||
SenchaObject result;
|
||||
if(type == right.type)
|
||||
{
|
||||
switch(type){
|
||||
case string_literal:
|
||||
result.set_new_string(this->text + right.text);
|
||||
break;
|
||||
case integer_number:
|
||||
result.set_value(this->integer + right.integer);
|
||||
break;
|
||||
case float_number:
|
||||
result.set_value(this->number + right.number);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result.type = invalid;
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
SenchaObject SenchaObject::operator-(const SenchaObject& right)const
|
||||
{
|
||||
SenchaObject result;
|
||||
if(type == right.type)
|
||||
{
|
||||
switch(type){
|
||||
case string_literal:
|
||||
result.type = invalid;
|
||||
break;
|
||||
case integer_number:
|
||||
result.set_value(this->integer - right.integer);
|
||||
break;
|
||||
case float_number:
|
||||
result.set_value(this->number - right.number);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result.type = invalid;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
SenchaObject SenchaObject::operator*(const SenchaObject& right)const
|
||||
{
|
||||
SenchaObject result;
|
||||
if(type == right.type)
|
||||
{
|
||||
switch(type){
|
||||
case string_literal:
|
||||
result.type = invalid;
|
||||
break;
|
||||
case integer_number:
|
||||
result.set_value(this->integer * right.integer);
|
||||
break;
|
||||
case float_number:
|
||||
result.set_value(this->number * right.number);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result.type = invalid;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
SenchaObject SenchaObject::operator/(const SenchaObject& right)const
|
||||
{
|
||||
SenchaObject result;
|
||||
if(type == right.type)
|
||||
{
|
||||
switch(type){
|
||||
case string_literal:
|
||||
result.type = invalid;
|
||||
break;
|
||||
case integer_number:
|
||||
result.set_value(this->integer / right.integer);
|
||||
break;
|
||||
case float_number:
|
||||
result.set_value(this->number / right.number);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result.type = invalid;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//TODO change code above to something more generic
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* SenchaObject.h
|
||||
*
|
||||
* Created on: Dec 5, 2012
|
||||
* Author: attero
|
||||
*/
|
||||
|
||||
#ifndef SENCHAOBJECT_H_
|
||||
#define SENCHAOBJECT_H_
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include "to_string.h"
|
||||
class SenchaObject {
|
||||
|
||||
public:
|
||||
typedef enum {
|
||||
string_literal,
|
||||
integer_number,
|
||||
float_number,
|
||||
null,
|
||||
symbol,
|
||||
boolean,
|
||||
invalid
|
||||
} Type;
|
||||
|
||||
Type type;
|
||||
|
||||
virtual std::string repr();
|
||||
|
||||
std::string text;
|
||||
std::string name;
|
||||
bool truthy;
|
||||
int integer;
|
||||
double number;
|
||||
|
||||
void set_value(std::string text)
|
||||
{
|
||||
if(text[0] == '\"' && text[text.size()-1] == '\"')
|
||||
{
|
||||
this->text = text.substr(1, text.size()-2);
|
||||
type = string_literal;
|
||||
}
|
||||
}
|
||||
|
||||
void set_new_string(std::string text)
|
||||
{
|
||||
this->text = text;
|
||||
type = string_literal;
|
||||
}
|
||||
|
||||
void set_null_value()
|
||||
{
|
||||
this->type = null;
|
||||
this->integer = 0;
|
||||
this->number = 0;
|
||||
this->text = "";
|
||||
}
|
||||
|
||||
void set_value(int integer)
|
||||
{
|
||||
this->integer = integer;
|
||||
type = integer_number;
|
||||
}
|
||||
|
||||
void set_value(double number)
|
||||
{
|
||||
this->number = number;
|
||||
type = float_number;
|
||||
}
|
||||
|
||||
void set_value(bool logic)
|
||||
{
|
||||
this->truthy = logic;
|
||||
type = boolean;
|
||||
}
|
||||
|
||||
SenchaObject();
|
||||
SenchaObject(int integer) { set_value(integer); }
|
||||
SenchaObject(bool truthy) {set_value(truthy); }
|
||||
SenchaObject(double number) { set_value(number); }
|
||||
SenchaObject(std::string text) { set_value(text); }
|
||||
|
||||
//TODO overload operators as it should be done
|
||||
|
||||
virtual SenchaObject operator+(const SenchaObject& right)const;
|
||||
virtual SenchaObject operator-(const SenchaObject& right)const;
|
||||
virtual SenchaObject operator*(const SenchaObject& right)const;
|
||||
virtual SenchaObject operator/(const SenchaObject& right)const;
|
||||
|
||||
virtual ~SenchaObject();
|
||||
};
|
||||
|
||||
#endif /* SENCHAOBJECT_H_ */
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* to_string.h
|
||||
*
|
||||
* Created on: Dec 5, 2012
|
||||
* Author: attero
|
||||
*/
|
||||
|
||||
#ifndef TO_STRING_H_
|
||||
#define TO_STRING_H_
|
||||
|
||||
#include <sstream>
|
||||
|
||||
|
||||
|
||||
template <class T>
|
||||
inline std::string to_string (const T& t)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << t;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
|
||||
#endif /* TO_STRING_H_ */
|
|
@ -1,18 +0,0 @@
|
|||
/*
|
||||
* ASTExpression.cpp
|
||||
*
|
||||
* Created on: Nov 4, 2012
|
||||
* Author: attero
|
||||
*/
|
||||
|
||||
#include "ASTExpression.h"
|
||||
|
||||
ASTExpression::ASTExpression() {
|
||||
// TODO Auto-generated constructor stub
|
||||
|
||||
}
|
||||
|
||||
ASTExpression::~ASTExpression() {
|
||||
// TODO Auto-generated destructor stub
|
||||
}
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
/*
|
||||
* ASTExpression.h
|
||||
*
|
||||
* Created on: Nov 4, 2012
|
||||
* Author: attero
|
||||
*/
|
||||
|
||||
#ifndef ASTEXPRESSION_H_
|
||||
#define ASTEXPRESSION_H_
|
||||
#include "ASTNode.h"
|
||||
|
||||
class ASTExpression : public ASTNode {
|
||||
public:
|
||||
ASTExpression();
|
||||
virtual ~ASTExpression();
|
||||
};
|
||||
|
||||
#endif /* ASTEXPRESSION_H_ */
|
|
@ -1,18 +0,0 @@
|
|||
/*
|
||||
* ASTNode.cpp
|
||||
*
|
||||
* Created on: Nov 4, 2012
|
||||
* Author: attero
|
||||
*/
|
||||
|
||||
#include "ASTNode.h"
|
||||
|
||||
ASTNode::ASTNode() {
|
||||
// TODO Auto-generated constructor stub
|
||||
parent = 0;
|
||||
}
|
||||
|
||||
ASTNode::~ASTNode() {
|
||||
// TODO Auto-generated destructor stub
|
||||
}
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
/*
|
||||
* ASTNode.h
|
||||
*
|
||||
* Created on: Nov 4, 2012
|
||||
* Author: attero
|
||||
*/
|
||||
|
||||
#ifndef ASTNODE_H_
|
||||
#define ASTNODE_H_
|
||||
#include <vector>
|
||||
|
||||
class ASTNode {
|
||||
public:
|
||||
ASTNode();
|
||||
ASTNode * parent;
|
||||
std::vector<ASTNode *> children;
|
||||
void add_children(ASTNode *);
|
||||
void remove_most_right_children();
|
||||
void set_parent(ASTNode *);
|
||||
virtual void execute() = 0;
|
||||
virtual ~ASTNode();
|
||||
};
|
||||
|
||||
#endif /* ASTNODE_H_ */
|
|
@ -1,20 +0,0 @@
|
|||
/*
|
||||
* ASTPrimary.cpp
|
||||
*
|
||||
* Created on: Nov 4, 2012
|
||||
* Author: attero
|
||||
*/
|
||||
|
||||
#include "ASTPrimary.h"
|
||||
|
||||
ASTPrimary::ASTPrimary(ASTNode * parent) {
|
||||
// TODO Auto-generated constructor stub
|
||||
value = "";
|
||||
this->parent = parent;
|
||||
}
|
||||
|
||||
ASTPrimary::~ASTPrimary() {
|
||||
// TODO Auto-generated destructor stub
|
||||
}
|
||||
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
/*
|
||||
* ASTPrimary.h
|
||||
*
|
||||
* Created on: Nov 4, 2012
|
||||
* Author: attero
|
||||
*/
|
||||
|
||||
#ifndef ASTPRIMARY_H_
|
||||
#define ASTPRIMARY_H_
|
||||
#include "ASTNode.h"
|
||||
#include <string>
|
||||
|
||||
class ASTPrimary : public ASTNode {
|
||||
public:
|
||||
ASTPrimary(ASTNode * parent);
|
||||
|
||||
virtual ~ASTPrimary();
|
||||
virtual void execute() {};
|
||||
std::string value;
|
||||
|
||||
};
|
||||
|
||||
#endif /* ASTPRIMARY_H_ */
|
|
@ -1,21 +0,0 @@
|
|||
/*
|
||||
* ASTProgram.cpp
|
||||
*
|
||||
* Created on: Nov 5, 2012
|
||||
* Author: attero
|
||||
*/
|
||||
|
||||
#include "ASTProgram.h"
|
||||
|
||||
ASTProgram::ASTProgram() {
|
||||
// TODO Auto-generated constructor stub
|
||||
|
||||
}
|
||||
|
||||
ASTProgram::~ASTProgram() {
|
||||
// TODO Auto-generated destructor stub
|
||||
}
|
||||
|
||||
void ASTProgram::execute() {
|
||||
std::cout << "Program started!\n";
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
/*
|
||||
* ASTProgram.h
|
||||
*
|
||||
* Created on: Nov 5, 2012
|
||||
* Author: attero
|
||||
*/
|
||||
|
||||
#ifndef ASTPROGRAM_H_
|
||||
#define ASTPROGRAM_H_
|
||||
#include <iostream>
|
||||
#include "ASTNode.h"
|
||||
#include "ASTStatement.h"
|
||||
|
||||
class ASTProgram : public ASTNode {
|
||||
public:
|
||||
ASTProgram();
|
||||
ASTStatement * add_child(ASTStatement * node);
|
||||
virtual ~ASTProgram();
|
||||
virtual void execute();
|
||||
};
|
||||
|
||||
#endif /* ASTPROGRAM_H_ */
|
|
@ -1,18 +0,0 @@
|
|||
/*
|
||||
* ASTStatement.cpp
|
||||
*
|
||||
* Created on: Nov 4, 2012
|
||||
* Author: attero
|
||||
*/
|
||||
|
||||
#include "ASTStatement.h"
|
||||
|
||||
ASTStatement::ASTStatement() {
|
||||
// TODO Auto-generated constructor stub
|
||||
|
||||
}
|
||||
|
||||
ASTStatement::~ASTStatement() {
|
||||
// TODO Auto-generated destructor stub
|
||||
}
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
/*
|
||||
* ASTStatement.h
|
||||
*
|
||||
* Created on: Nov 4, 2012
|
||||
* Author: attero
|
||||
*/
|
||||
|
||||
#ifndef ASTSTATEMENT_H_
|
||||
#define ASTSTATEMENT_H_
|
||||
#include "ASTNode.h"
|
||||
|
||||
class ASTStatement : public ASTNode {
|
||||
public:
|
||||
ASTStatement();
|
||||
virtual ~ASTStatement();
|
||||
};
|
||||
|
||||
#endif /* ASTSTATEMENT_H_ */
|
|
@ -1,20 +0,0 @@
|
|||
/*
|
||||
* AllTypesOfASTNodes.h
|
||||
*
|
||||
* Created on: Nov 5, 2012
|
||||
* Author: attero
|
||||
*/
|
||||
|
||||
#ifndef ALLTYPESOFASTNODES_H_
|
||||
#define ALLTYPESOFASTNODES_H_
|
||||
|
||||
#include "ASTNode.h"
|
||||
#include "ASTProgram.h"
|
||||
#include "ASTStatement.h"
|
||||
#include "ASTExpression.h"
|
||||
#include "ASTPrimary.h"
|
||||
|
||||
//And probably more
|
||||
//TODO actualize it
|
||||
|
||||
#endif /* ALLTYPESOFASTNODES_H_ */
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Context.cpp
|
||||
*
|
||||
* Created on: Dec 7, 2012
|
||||
* Author: attero
|
||||
*/
|
||||
|
||||
#include "Context.h"
|
||||
|
||||
Context::Context() {
|
||||
// TODO Auto-generated constructor stub
|
||||
index = 0;
|
||||
}
|
||||
|
||||
Context::~Context() {
|
||||
// TODO Auto-generated destructor stub
|
||||
}
|
||||
|
||||
ObjectIndex Context::add_to_store(SenchaObject & object)
|
||||
{
|
||||
index++;
|
||||
object_store[index] = object;
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
SenchaObject Context::get_from_store(ObjectIndex index)
|
||||
{
|
||||
return object_store[index];
|
||||
}
|
||||
|
||||
void Context::add(std::string name, SenchaObject object)
|
||||
{
|
||||
interpreter_context[name] = add_to_store(object);
|
||||
}
|
||||
|
||||
void Context::set(std::string name, SenchaObject object)
|
||||
{
|
||||
if(interpreter_context[name] != 0)
|
||||
{
|
||||
object_store[interpreter_context[name]] = object;
|
||||
}
|
||||
else
|
||||
{
|
||||
add(name, object);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
SenchaObject Context::get(std::string name)
|
||||
{
|
||||
return get_from_store(interpreter_context[name]);
|
||||
}
|
||||
|
||||
std::string Context::debug() {
|
||||
std::string debug_note = "";
|
||||
|
||||
for( auto iter = this->interpreter_context.begin(); iter != this->interpreter_context.end(); iter++)
|
||||
{
|
||||
debug_note += "Context: " + to_string((*iter).second) + ": " + (*iter).first + " " + object_store[(*iter).second].repr() + "\n";
|
||||
}
|
||||
return debug_note;
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Context.h
|
||||
*
|
||||
* Created on: Dec 7, 2012
|
||||
* Author: attero
|
||||
*/
|
||||
|
||||
#ifndef CONTEXT_H_
|
||||
#define CONTEXT_H_
|
||||
#include <map>
|
||||
#include "AST/SenchaObject.h"
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
typedef unsigned long ObjectIndex;
|
||||
typedef unsigned long FunctionIndex;
|
||||
|
||||
class Context {
|
||||
public:
|
||||
Context();
|
||||
typedef unsigned long ObjectIndex;
|
||||
ObjectIndex index;
|
||||
|
||||
std::map<ObjectIndex, SenchaObject> object_store;
|
||||
ObjectIndex add_to_store(SenchaObject & object);
|
||||
SenchaObject get_from_store(ObjectIndex index);
|
||||
|
||||
//Overload it to use contexts
|
||||
void add(std::string name, SenchaObject object);
|
||||
void set(std::string name, SenchaObject object);
|
||||
SenchaObject get(std::string name);
|
||||
typedef std::map<std::string, ObjectIndex> ExecutionContext;
|
||||
ExecutionContext interpreter_context;
|
||||
|
||||
std::string debug() ;
|
||||
|
||||
|
||||
|
||||
ExecutionContext global_context;
|
||||
std::map<FunctionIndex , ExecutionContext *> function_contexts;
|
||||
virtual ~Context();
|
||||
};
|
||||
|
||||
#endif /* CONTEXT_H_ */
|
|
@ -117,7 +117,7 @@ pair<string, Token> Lexer::parse_token(string line)
|
|||
|
||||
bool Lexer::is_keyword(string value)
|
||||
{
|
||||
for(int i=0; i< keywords.size(); i++)
|
||||
for(unsigned int i=0; i< keywords.size(); i++)
|
||||
{
|
||||
if(value == keywords[i]) return true;
|
||||
}
|
||||
|
@ -127,7 +127,7 @@ bool Lexer::is_keyword(string value)
|
|||
bool Lexer::is_punctuation(char c)
|
||||
{
|
||||
|
||||
for(int i=0; i< punctuation.size(); i++)
|
||||
for(unsigned int i=0; i< punctuation.size(); i++)
|
||||
{
|
||||
if(c == punctuation[i]) return true;
|
||||
}
|
||||
|
@ -136,7 +136,7 @@ bool Lexer::is_punctuation(char c)
|
|||
|
||||
bool Lexer::is_operator(string value)
|
||||
{
|
||||
for(int i=0; i< operators.size(); i++)
|
||||
for(unsigned int i=0; i< operators.size(); i++)
|
||||
{
|
||||
if(value == operators[i]) return true;
|
||||
}
|
||||
|
@ -155,7 +155,7 @@ type_of_token Lexer::guess_type(string value)
|
|||
if(isdigit(value[0]))
|
||||
{
|
||||
bool is_integer = true;
|
||||
for(int i=1; i<value.size(); i++)
|
||||
for(unsigned int i=1; i<value.size(); i++)
|
||||
{
|
||||
if(!isdigit(value[i])) is_integer = false;
|
||||
}
|
||||
|
|
|
@ -1,23 +1,38 @@
|
|||
#include "Parser.h"
|
||||
#include "iostream"
|
||||
|
||||
Parser::Parser()
|
||||
{
|
||||
Parser::Parser(Context * context)
|
||||
{
|
||||
this->context = context;
|
||||
error_message = "***ERRORS DURING PARSING***\n";
|
||||
report_message = "***PARSER REPORT***\n";
|
||||
position_in_stream = 0;
|
||||
in_statement = false;
|
||||
program = static_cast<ProgramNode *>(tree.root);
|
||||
}
|
||||
|
||||
|
||||
Parser::~Parser()
|
||||
{
|
||||
//dtor
|
||||
}
|
||||
|
||||
void Parser::erase_all()
|
||||
{
|
||||
tree.delete_all_children();
|
||||
tree.root = new ProgramNode();
|
||||
error_message = "***ERRORS DURING PARSING***\n";
|
||||
report_message = "***PARSER REPORT***\n";
|
||||
position_in_stream = 0;
|
||||
in_statement = false;
|
||||
program = static_cast<ProgramNode *>(tree.root);
|
||||
|
||||
|
||||
}
|
||||
string Parser::show_tokens()
|
||||
{
|
||||
string tokens = "";
|
||||
for (int i = 0; i < token_stream.size(); i++)
|
||||
for (unsigned int i = 0; i < token_stream.size(); i++)
|
||||
{
|
||||
tokens += token_stream[i].value + " ";
|
||||
}
|
||||
|
@ -26,7 +41,7 @@ string Parser::show_tokens()
|
|||
|
||||
void Parser::add_tokens(vector<Token> tokens)
|
||||
{
|
||||
for (int i = 0; i < tokens.size(); i++)
|
||||
for (unsigned int i = 0; i < tokens.size(); i++)
|
||||
{
|
||||
token_stream.push_back(tokens[i]);
|
||||
}
|
||||
|
@ -63,8 +78,8 @@ void Parser::interpret()
|
|||
{
|
||||
read_next();
|
||||
while(tok_value!= "")
|
||||
{
|
||||
statement();
|
||||
{
|
||||
program->add_statement(statement(program));
|
||||
}
|
||||
|
||||
|
||||
|
@ -100,51 +115,54 @@ bool Parser::expect(string s)
|
|||
}
|
||||
|
||||
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;
|
||||
{
|
||||
|
||||
if(tok_value == "def" || tok_value == "string" || tok_value == "num")
|
||||
{
|
||||
read_next();
|
||||
return true;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
|
||||
void Parser::statement()
|
||||
{
|
||||
ASTStatement * Parser::statement(ASTNode * parent)
|
||||
{
|
||||
BasicStatement * stat = new BasicStatement(parent);
|
||||
|
||||
if(accept("{"))
|
||||
{
|
||||
while(!accept("}"))
|
||||
{
|
||||
statement();
|
||||
stat = static_cast<BasicStatement * >(statement(parent));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
else if(is_type())
|
||||
{
|
||||
|
||||
report("Identifier: " + tok_value + "\n");
|
||||
|
||||
{
|
||||
DeclarationStatement * declaration = new DeclarationStatement(parent, context);
|
||||
std::string identifier = tok_value;
|
||||
report("Identifier: " + identifier + "\n");
|
||||
read_next();
|
||||
|
||||
declaration->add_name(identifier);
|
||||
|
||||
if(accept("="))
|
||||
{
|
||||
report("Identifier: " + tok_value + "\n");
|
||||
read_next();
|
||||
expr();
|
||||
report(" := \n");
|
||||
}
|
||||
ASTExpression * ae = expr(stat);
|
||||
declaration->add_right_value(ae);
|
||||
|
||||
report(" := \n");
|
||||
accept(";");
|
||||
}
|
||||
|
||||
if(accept(";"))
|
||||
{
|
||||
report("Variable definition\n");
|
||||
return;
|
||||
report("Variable declaration\n");
|
||||
}
|
||||
|
||||
if(expect("("))
|
||||
|
@ -155,6 +173,7 @@ void Parser::statement()
|
|||
argc++;
|
||||
is_type();
|
||||
report("function argument: " + tok_value + "\n");
|
||||
declaration->add_argument(tok_value);
|
||||
read_next();
|
||||
if(peek(")"))
|
||||
{
|
||||
|
@ -167,87 +186,109 @@ void Parser::statement()
|
|||
if(!accept(";"))
|
||||
{
|
||||
report("function body:\n");
|
||||
statement();
|
||||
declaration->add_body(statement(stat));
|
||||
report("function definition\n");
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
expect(";");
|
||||
report("function declaration\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
delete stat;
|
||||
return declaration;
|
||||
|
||||
}
|
||||
else if(accept("if"))
|
||||
{
|
||||
//stuff
|
||||
//TODO implement that
|
||||
//TODO implement that
|
||||
return stat;
|
||||
}
|
||||
else if(accept("while"))
|
||||
{
|
||||
//similar stuff
|
||||
//similar stuff
|
||||
return stat;
|
||||
}
|
||||
else if(accept("return"))
|
||||
{
|
||||
|
||||
if(!peek(";"))
|
||||
{
|
||||
expr();
|
||||
stat->add_expression(expr(stat));
|
||||
}
|
||||
expect(";");
|
||||
report("RETURN\n");
|
||||
report("RETURN\n");
|
||||
return stat;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
expr();
|
||||
while(!expect(";") && tok_value != "") read_next();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void Parser::prim_expr()
|
||||
{
|
||||
if(current_token.get_type() == t_integer)
|
||||
{
|
||||
report("Number: " + tok_value + "\n");
|
||||
read_next();
|
||||
}
|
||||
else if(current_token.get_type() == t_symbol)
|
||||
{
|
||||
report("Variable: " + tok_value + "\n");
|
||||
read_next();
|
||||
}
|
||||
else if(current_token.get_type() == t_literal)
|
||||
{
|
||||
report("Character literal: " + tok_value + "\n");
|
||||
read_next();
|
||||
}
|
||||
else if(accept("("))
|
||||
{
|
||||
report("( ");
|
||||
expr();
|
||||
report(" ) ");
|
||||
expect(")");
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
error("ERROR: unexpected primary expression " + tok_value + "\n");
|
||||
read_next();
|
||||
}
|
||||
stat->add_expression(expr(stat));
|
||||
while(!expect(";") && tok_value != "") read_next();
|
||||
return stat;
|
||||
|
||||
}
|
||||
|
||||
return stat;
|
||||
}
|
||||
|
||||
void Parser::postfix_expr()
|
||||
{
|
||||
prim_expr();
|
||||
ASTExpression * Parser::prim_expr(ASTNode * expression)
|
||||
{
|
||||
ConstantExpression * ce;
|
||||
BasicExpression * be;
|
||||
//TODO add reference type to prims, syblol is now just a literal... and floats
|
||||
if(current_token.get_type() == t_integer)
|
||||
{
|
||||
report("Number: " + tok_value + "\n");
|
||||
|
||||
ce = new ConstantExpression(expression, std::atoi(tok_value.c_str()));
|
||||
read_next();
|
||||
}
|
||||
else if(current_token.get_type() == t_literal)
|
||||
{
|
||||
|
||||
report("Character literal: " + tok_value + "\n");
|
||||
ce = new ConstantExpression(expression, tok_value);
|
||||
read_next();
|
||||
}
|
||||
else if(current_token.get_type() == t_symbol)
|
||||
{
|
||||
report("variable: " + tok_value + "\n");
|
||||
SenchaObject variable;
|
||||
//TODO is it right?
|
||||
string name = current_token.value;
|
||||
|
||||
variable = context->get(name);
|
||||
variable.name = name;
|
||||
ce = new ConstantExpression(expression, variable, name);
|
||||
read_next();
|
||||
}
|
||||
else if(accept("("))
|
||||
{
|
||||
report("( ");
|
||||
be = static_cast<BasicExpression *>(expr(expression));
|
||||
report(" ) ");
|
||||
expect(")");
|
||||
return be;
|
||||
}
|
||||
else
|
||||
{
|
||||
string error_message = "ERROR: unexpected primary expression " + tok_value + "\n";
|
||||
error(error_message);
|
||||
read_next();
|
||||
return new IncorrectExpression(expression, error_message);
|
||||
}
|
||||
|
||||
return ce;
|
||||
}
|
||||
|
||||
ASTExpression * Parser::postfix_expr(ASTNode * expression)
|
||||
{
|
||||
//TODO implement postfix expression ASAP
|
||||
BasicExpression * be = new BasicExpression(expression);
|
||||
prim_expr(be);
|
||||
if(accept("["))
|
||||
{
|
||||
expr();
|
||||
expr(be);
|
||||
expect("]");
|
||||
report(" [] ");
|
||||
|
||||
|
@ -256,89 +297,169 @@ void Parser::postfix_expr()
|
|||
{
|
||||
if(!accept(")"))
|
||||
{
|
||||
expr();
|
||||
expr(be);
|
||||
report("function argument\n");
|
||||
while(accept(","))
|
||||
{
|
||||
expr();
|
||||
expr(be);
|
||||
report("function argument\n");
|
||||
}
|
||||
|
||||
expect(")");
|
||||
}
|
||||
report("FUNC_CALL\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//TODO implement postfix_expression
|
||||
return be;
|
||||
}
|
||||
|
||||
void Parser::mul_expr()
|
||||
ASTExpression * Parser::mul_expr(ASTNode * expression)
|
||||
{
|
||||
postfix_expr();
|
||||
while(peek("*") || peek("/"))
|
||||
BasicExpression * be = new BasicExpression(expression);
|
||||
be->set_left_operand(prim_expr(be));
|
||||
if(peek("*") || peek("/"))
|
||||
{
|
||||
if(accept("*"))
|
||||
{
|
||||
postfix_expr();
|
||||
be->set_operator("*");
|
||||
report(" *\n");
|
||||
} else if(accept("/"))
|
||||
{
|
||||
postfix_expr();
|
||||
be->set_operator("/");
|
||||
report(" /\n");
|
||||
}
|
||||
be->set_right_operand(mul_expr(be));
|
||||
}
|
||||
|
||||
if(be->oper == "")
|
||||
{
|
||||
ASTExpression * ae;
|
||||
ae = static_cast<ASTExpression *>(be->children[0]);
|
||||
ae->parent = expression;
|
||||
delete be;
|
||||
return ae;
|
||||
}
|
||||
|
||||
return be;
|
||||
}
|
||||
|
||||
void Parser::add_expr()
|
||||
{
|
||||
mul_expr();
|
||||
while(peek("+") || peek("-"))
|
||||
ASTExpression * Parser::add_expr(ASTNode * expression)
|
||||
{
|
||||
BasicExpression * be = new BasicExpression(expression);
|
||||
be->set_left_operand(mul_expr(be));
|
||||
if(peek("+") || peek("-"))
|
||||
{
|
||||
if(accept("+"))
|
||||
{
|
||||
mul_expr();
|
||||
report(" +\n");
|
||||
} else if(accept("-"))
|
||||
report(" +\n");
|
||||
be->set_operator("+");
|
||||
}
|
||||
else if(accept("-"))
|
||||
{
|
||||
mul_expr();
|
||||
report(" -\n");
|
||||
}
|
||||
}
|
||||
report(" -\n");
|
||||
be->set_operator("-");
|
||||
}
|
||||
be->set_right_operand(add_expr(be));
|
||||
}
|
||||
|
||||
if(be->oper == "")
|
||||
{
|
||||
ASTExpression * ae;
|
||||
ae = static_cast<ASTExpression *>(be->children[0]);
|
||||
ae->parent = expression;
|
||||
delete be;
|
||||
return ae;
|
||||
}
|
||||
|
||||
return be;
|
||||
}
|
||||
|
||||
void Parser::rel_expr()
|
||||
{
|
||||
add_expr();
|
||||
while(peek("<"))
|
||||
ASTExpression * Parser::rel_expr(ASTNode * expression)
|
||||
{
|
||||
BasicExpression * be = new BasicExpression(expression);
|
||||
be->set_left_operand(add_expr(be));
|
||||
if(peek("<") || peek(">"))
|
||||
{
|
||||
accept("<");
|
||||
add_expr();
|
||||
report(" <\n");
|
||||
}
|
||||
if(accept("<"))
|
||||
{
|
||||
be->set_operator("<");
|
||||
report(" <\n");
|
||||
}
|
||||
else if (accept(">"))
|
||||
{
|
||||
be->set_operator(">");
|
||||
report(" >\n");
|
||||
}
|
||||
be->set_right_operand(rel_expr(be));
|
||||
}
|
||||
|
||||
if(be->oper == "")
|
||||
{
|
||||
ASTExpression * ae;
|
||||
ae = static_cast<ASTExpression *>(be->children[0]);
|
||||
ae->parent = expression;
|
||||
delete be;
|
||||
return ae;
|
||||
}
|
||||
|
||||
|
||||
return be;
|
||||
}
|
||||
|
||||
void Parser::eq_expr()
|
||||
{
|
||||
rel_expr();
|
||||
while(peek("==") || peek("!="))
|
||||
ASTExpression * Parser::eq_expr(ASTNode * expression)
|
||||
{
|
||||
BasicExpression * be = new BasicExpression(expression);
|
||||
be->set_left_operand(rel_expr(be));
|
||||
if(peek("==") || peek("!="))
|
||||
{
|
||||
if(accept("=="))
|
||||
{
|
||||
rel_expr();
|
||||
be->set_operator("==");
|
||||
report("==\n");
|
||||
}
|
||||
else if(accept("!="))
|
||||
{
|
||||
rel_expr();
|
||||
be->set_operator("!=");
|
||||
report("!=\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
be->set_right_operand(eq_expr(be));
|
||||
}
|
||||
|
||||
if(be->oper == "")
|
||||
{
|
||||
ASTExpression * ae;
|
||||
ae = static_cast<ASTExpression *>(be->children[0]);
|
||||
ae->parent = expression;
|
||||
delete be;
|
||||
return ae;
|
||||
}
|
||||
|
||||
return be;
|
||||
}
|
||||
|
||||
void Parser::expr()
|
||||
{
|
||||
eq_expr();
|
||||
ASTExpression * Parser::expr(ASTNode * expression)
|
||||
{
|
||||
Assignment * assignment = new Assignment(expression, context);
|
||||
ASTExpression * left = eq_expr(assignment);
|
||||
|
||||
if(accept("="))
|
||||
{
|
||||
expr();
|
||||
report(" :=\n");
|
||||
}
|
||||
{
|
||||
ASTExpression * right = expr(assignment);
|
||||
|
||||
assignment->add_lvalue(left);
|
||||
assignment->add_rvalue(right);
|
||||
|
||||
report(" :=\n");
|
||||
return assignment;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
left->parent = expression;
|
||||
delete assignment;
|
||||
return left;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,22 +1,30 @@
|
|||
#ifndef PARSER_H
|
||||
#define PARSER_H
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <vector>
|
||||
#include <cstdlib>
|
||||
#include "Token.h"
|
||||
#include "../AST/AllTypesOfASTNodes.h"
|
||||
#include "Context.h"
|
||||
#include "AST/AllTypesOfASTNodes.h"
|
||||
#include "AST/AST.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Parser
|
||||
{
|
||||
public:
|
||||
Parser();
|
||||
Parser(Context * context);
|
||||
Context * context;
|
||||
|
||||
virtual ~Parser();
|
||||
void interpret();
|
||||
string report_message;
|
||||
string error_message;
|
||||
void add_tokens(vector<Token> tokens);
|
||||
string show_tokens();
|
||||
AST tree;
|
||||
ProgramNode * program;
|
||||
void erase_all();
|
||||
|
||||
protected:
|
||||
|
||||
|
@ -24,7 +32,7 @@ class Parser
|
|||
Token current_token;
|
||||
string tok_value;
|
||||
vector<Token> token_stream;
|
||||
int position_in_stream;
|
||||
unsigned int position_in_stream;
|
||||
|
||||
bool in_statement;
|
||||
bool read_next();
|
||||
|
@ -35,17 +43,16 @@ class Parser
|
|||
|
||||
void error(string s);
|
||||
void report(string s);
|
||||
|
||||
ASTStatement * statement(ASTNode * node);
|
||||
|
||||
//TODO change functions below to use AST nodes
|
||||
void statement();
|
||||
|
||||
void mul_expr();
|
||||
void add_expr();
|
||||
void prim_expr();
|
||||
void postfix_expr();
|
||||
void rel_expr();
|
||||
void eq_expr();
|
||||
void expr();
|
||||
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);
|
||||
};
|
||||
|
||||
#endif // PARSER_H
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
|
||||
|
||||
TestSuite::TestSuite() {
|
||||
// TODO Auto-generated constructor stub
|
||||
tests_passed = 0;
|
||||
tests_failed = 0;
|
||||
tests = 0;
|
||||
|
|
Binary file not shown.
|
@ -4,18 +4,19 @@
|
|||
#include "Lexer.h"
|
||||
#include "Parser.h"
|
||||
#include "Tests/TestLexer.h"
|
||||
#include "Context.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_line = "dupa";
|
||||
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++)
|
||||
for(unsigned int i=0; i< tokens.size(); i++)
|
||||
{
|
||||
cout << tokens[i].get_value() << " type: " << tokens[i].get_type() << endl;
|
||||
}
|
||||
|
@ -32,12 +33,13 @@ void test_parser()
|
|||
lines.push_back("num pun");
|
||||
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;
|
||||
Context context;
|
||||
vector<Token> tokens;
|
||||
|
||||
for(int i=0; i<lines.size(); i++)
|
||||
for(unsigned int i=0; i<lines.size(); i++)
|
||||
{
|
||||
tokens = lexer.parse_line(lines[i]);
|
||||
Parser parser;
|
||||
Parser parser(&context);
|
||||
parser.add_tokens(tokens);
|
||||
parser.interpret();
|
||||
cout << "<<<Parsing number: " << i << " >>>" << endl;
|
||||
|
@ -52,7 +54,7 @@ void test_parser()
|
|||
int how_depth_change(vector<Token> tokens)
|
||||
{
|
||||
int change = 0;
|
||||
for (int i = 0; i < tokens.size(); i++)
|
||||
for (unsigned int i = 0; i < tokens.size(); i++)
|
||||
{
|
||||
if(tokens[i].value == "{") change++;
|
||||
else if(tokens[i].value == "}") change--;
|
||||
|
@ -73,7 +75,9 @@ string compute_indentation(int depth_level)
|
|||
void interactive()
|
||||
{
|
||||
Lexer lexer;
|
||||
Parser parser;
|
||||
|
||||
Context context;
|
||||
Parser parser(&context);
|
||||
|
||||
vector<Token> tokens;
|
||||
|
||||
|
@ -94,19 +98,22 @@ void interactive()
|
|||
|
||||
if(level_of_depth == 0) {
|
||||
parser.interpret();
|
||||
cout << parser.report_message << endl;
|
||||
cout << parser.error_message << endl;
|
||||
cout << parser.show_tokens() << endl;
|
||||
parser.program->execute_last();
|
||||
|
||||
//cout << parser.report_message << endl;
|
||||
//cout << parser.error_message << endl;
|
||||
//cout << parser.show_tokens() << endl;
|
||||
//cout << "My tree:\n";
|
||||
//cout << parser.program->debug();
|
||||
cout << parser.context->debug();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
cout << "Sencha-lang interpreter, version 0.02" << endl;
|
||||
cout << "Sencha-lang interpreter, version 0.12" << endl;
|
||||
|
||||
TestLexer test_l;
|
||||
//test_l.run_tests();
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue