Functions work if given right arguments ^^.

functions
Justyna Ilczuk 2012-12-31 17:10:37 +01:00
parent e01bc95615
commit 6296524bec
37 changed files with 208 additions and 197 deletions

View File

@ -14,8 +14,7 @@ class ASTExpression : public ASTNode {
public:
virtual SenchaObject evaluate() = 0;
virtual void execute() = 0;
virtual void execute_quietly() = 0;
virtual SenchaObject execute() = 0;
ASTExpression();
virtual ~ASTExpression();
};

View File

@ -31,7 +31,7 @@ public:
virtual void accept(Visitor * visitor){ visitor->visit(this); };
virtual SenchaObject evaluate() = 0;
virtual void execute() = 0;
virtual SenchaObject execute() = 0;
virtual ~ASTNode();
};

View File

@ -12,7 +12,7 @@
class ASTStatement : public ASTNode {
public:
ASTStatement();
virtual void execute() = 0;
virtual SenchaObject execute() = 0;
virtual SenchaObject evaluate() { return SenchaObject(); }
virtual ~ASTStatement();
};

View File

@ -9,36 +9,24 @@
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();
auto context = context_manager->get_top();
context->add(name, right_value);
if(name != "")
{
context->set(name, right_value);
}
return children[0]->execute();
}
void Assignment::execute_quietly()
SenchaObject 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 != "")
{
context->set(left_value.name, right_value);
}
return evaluate();
}
Assignment::Assignment(ContextManager * context, std::string name, ASTExpression * left, ASTExpression * right)
Assignment::Assignment(ContextManager * context_manager, std::string name, ASTExpression * left, ASTExpression * right)
{
this->context = context;
this->context_manager = context_manager;
this->name_of_context = "global";
this->type = "Assignment";
this->children.push_back(left);
this->children.push_back(right);

View File

@ -22,13 +22,12 @@
*/
class Assignment : public ASTExpression {
public:
ContextManager * context;
ContextManager * context_manager;
std::string name;
std::string name_of_context;
SenchaObject evaluate();
void execute();
void execute_quietly();
SenchaObject execute();
Assignment(ContextManager * context, std::string name, ASTExpression * left, ASTExpression * right);
virtual ~Assignment();
};

View File

@ -7,15 +7,12 @@
#include "BasicExpression.h"
void BasicExpression::execute()
SenchaObject BasicExpression::execute()
{
std::cout << evaluate().repr() << std::endl;
SenchaObject result = evaluate() ;
return result;
}
void BasicExpression::execute_quietly()
{
evaluate();
}
SenchaObject BasicExpression::evaluate()
{

View File

@ -21,8 +21,8 @@ class BasicExpression : public ASTExpression {
public:
virtual SenchaObject evaluate();
virtual void execute();
virtual void execute_quietly();
virtual SenchaObject execute();
std::string get_operator() { return oper; }
virtual void accept(Visitor * visitor);

View File

@ -25,10 +25,12 @@ void BasicStatement::add_expression(ASTExpression * expr)
}
void BasicStatement::execute()
SenchaObject BasicStatement::execute()
{
for(auto child: children)
child->execute() ;
for(auto it = children.begin(); it!=children.end() -1; it++)
(*it)->execute();
return children[children.size() -1]->evaluate();
}
SenchaObject BasicStatement::evaluate()

View File

@ -21,7 +21,7 @@ public:
BasicStatement();
void add_expression(ASTExpression * expr);
virtual SenchaObject evaluate();
virtual void execute();
virtual SenchaObject execute();
virtual void accept(Visitor * vistitor);
virtual ~BasicStatement();
};

View File

@ -27,15 +27,12 @@ SenchaObject ConstantExpression::evaluate()
return value;
}
void ConstantExpression::execute()
SenchaObject ConstantExpression::execute()
{
std::cout << evaluate().repr() << std::endl;
SenchaObject result = evaluate();
return result;
}
void ConstantExpression::execute_quietly()
{
evaluate();
}
void ConstantExpression::accept(Visitor * visitor)
{

View File

@ -9,14 +9,14 @@
#define CONSTANTEXPRESSION_H_
#include "ASTExpression.h"
#include <iostream>
#include "../Elements/SenchaFunction.h"
/**
* ConstantExpression class is used to store complex expression, which are actually
* SenchaObjects. Constant Expressions are made in parser when it encounter some of primitives
* like string literal or numbers, they also can be made on already made SenchaObject.
* ConstantExpression is a part of AST, so it must have parent. It's a node in which it is build.
* It implements four virtual functions: debug, evaluate, execute_quietly.
* It implements four virtual functions: debug, evaluate.
* It stores the value of expression.
*/
class ConstantExpression : public ASTExpression {
@ -66,10 +66,8 @@ public:
virtual SenchaObject evaluate();
/**Prints representation of value */
virtual void execute() ;
virtual SenchaObject execute() ;
/**Does nothing */
virtual void execute_quietly() ;
};
#endif /* CONSTANTEXPRESSION_H_ */

View File

@ -27,13 +27,16 @@ void DeclarationStatement::add_right_value(ASTExpression * right)
children[0] = right;
}
DeclarationStatement::DeclarationStatement(ContextManager * context)
//def print_d() { print("dupa"); }
DeclarationStatement::DeclarationStatement(ContextManager * context_manager)
{
this->context = context;
this->context_manager = context_manager;
this->name_of_context = "global";//context_manager->create_new_context()->name;
is_function = false;
body = NULL;
right_value = SenchaObject();
children.push_back(new ConstantExpression(this));
children.push_back(new ConstantExpression(SenchaObject()));
this->type = "DeclarationStatement";
}
@ -48,17 +51,19 @@ void DeclarationStatement::add_argument(std::string name)
arguments.push_back(name);
}
void DeclarationStatement::execute()
SenchaObject DeclarationStatement::execute()
{
if(is_function)
{
//TODO implement
//do function registering stuff
SenchaFunction * sf = new SenchaFunction(name, arguments, body);
context_manager->context("global")->register_function(name, sf);
return SenchaObject();
}
else
{
auto context = context_manager->get_top();
context->add(name, right_value);
children[0]->execute();
return children[0]->execute();
}
}

View File

@ -21,7 +21,8 @@
class DeclarationStatement: public ASTStatement {
public:
std::string name;
ContextManager * context;
ContextManager * context_manager;
std::string name_of_context;
SenchaObject right_value;
ASTStatement * body;
std::vector<std::string> arguments;
@ -35,7 +36,7 @@ public:
void add_argument(std::string name);
void add_body(ASTStatement * statement);
virtual void execute();
virtual SenchaObject execute();
virtual ~DeclarationStatement();
};

View File

@ -33,16 +33,17 @@ void IfNode::add_condition(ASTExpression * expression)
children.push_back(expression);
}
void IfNode::execute()
SenchaObject IfNode::execute()
{
if(evaluate_condition())
{
children[1]->execute();
return children[1]->execute();
}
else if(is_else)
{
children[2]->execute();
return children[2]->execute();
}
return SenchaObject();
}

View File

@ -25,7 +25,7 @@ public:
void add_body(ASTStatement * statement);
void add_else_block(ASTStatement * statement);
bool is_else;
virtual void execute();
virtual SenchaObject execute();
bool evaluate_condition();
ASTNode * condition() { return children[0]; }
ASTNode * then_block() { return children[1]; }

View File

@ -23,10 +23,7 @@ public:
virtual SenchaObject evaluate() ;
void execute() { std::cout << debug(); }
void execute_quietly() { //do nothing
}
SenchaObject execute() { std::cout << debug(); return SenchaObject();}
std::string debug() { return "Incorrect Expression:\n" + error_message; }
IncorrectExpression( std::string error_message);

View File

@ -7,8 +7,8 @@
#include "PostfixExpression.h"
PostfixExpression::PostfixExpression(std::string name, ContextManager * context):
name(name), context(context), native(false)
PostfixExpression::PostfixExpression(std::string name, ContextManager * context_manager):
name(name), context_manager(context_manager), native(false)
{
type= "PostfixExpression";
}
@ -30,11 +30,11 @@ void PostfixExpression::add_argument(ASTExpression * expression)
SenchaObject PostfixExpression::evaluate()
{
return context->execute_native_function(name, arguments);
return context_manager->execute_function(name, arguments);
}
void PostfixExpression::execute() {
context->execute_native_function(name, arguments);
SenchaObject PostfixExpression::execute() {
return context_manager->execute_function(name, arguments);
}

View File

@ -18,14 +18,14 @@
class PostfixExpression : public ASTExpression {
public:
std::string name;
ContextManager * context;
ContextManager * context_manager;
bool native;
std::vector<ASTExpression *> arguments;
void add_argument(ASTExpression * expression);
virtual SenchaObject evaluate();
virtual void execute();
virtual void execute_quietly(){ execute();};
virtual SenchaObject execute();
PostfixExpression( std::string name, ContextManager * context);
virtual ~PostfixExpression();

View File

@ -20,10 +20,11 @@ ProgramNode::~ProgramNode() {
}
}
void ProgramNode::execute() {
for (std::vector<ASTNode *>::iterator it = children.begin(); it!=children.end(); ++it) {
SenchaObject ProgramNode::execute() {
for (std::vector<ASTNode *>::iterator it = children.begin(); it!= children.end()-1; ++it) {
(*it)->execute();
}
return children[children.size() -1]->execute();
}
void ProgramNode::accept(Visitor * visitor)
@ -31,9 +32,9 @@ void ProgramNode::accept(Visitor * visitor)
visitor->visit(this);
}
void ProgramNode::execute_last()
SenchaObject ProgramNode::execute_last()
{
children[children.size() - 1]->execute();
return children[children.size() - 1]->execute();
}
SenchaObject ProgramNode::evaluate_last()

View File

@ -19,8 +19,8 @@ public:
ProgramNode();
void add_statement(ASTStatement * statement);
virtual ~ProgramNode();
virtual void execute();
virtual void execute_last();
virtual SenchaObject execute();
virtual SenchaObject execute_last();
virtual SenchaObject evaluate() { return evaluate_last(); }
SenchaObject evaluate_last();
virtual void accept(Visitor * visitor);

View File

@ -19,22 +19,20 @@ RepeatStatement::~RepeatStatement()
delete body;
}
void RepeatStatement::execute()
{
execute_quietly();
}
void RepeatStatement::add_body(ASTStatement * statement)
{
body = statement;
}
void RepeatStatement::execute_quietly()
SenchaObject RepeatStatement::execute()
{
for(int i = 0; i < how_many_times; i++)
{
body->execute();
if(i == how_many_times - 1) return body->execute();
else body->execute();
}
return SenchaObject();
}

View File

@ -22,8 +22,7 @@ public:
int how_many_times;
ASTStatement * body;
void add_iteration_number(SenchaObject so);
virtual void execute();
virtual void execute_quietly();
virtual SenchaObject execute();
void add_body(ASTStatement * statement);
virtual ~RepeatStatement();
};

View File

@ -7,9 +7,10 @@
#include "VariableExpression.h"
VariableExpression::VariableExpression(std::string name, ContextManager * context) {
VariableExpression::VariableExpression(std::string name, ContextManager * context_manager) {
this->name = name;
this->context = context;
this->name_of_context = "global";
this->context_manager = context_manager;
this->type = "VariableExpression";
}
@ -19,17 +20,15 @@ VariableExpression::~VariableExpression() {
SenchaObject VariableExpression::evaluate()
{
auto context = context_manager->get_top();
SenchaObject result = context->get(name);
result.name = name;
return result;
}
void VariableExpression::execute()
SenchaObject VariableExpression::execute()
{
std::cout << evaluate().repr() << std::endl;
SenchaObject result = evaluate();
return result;
}
void VariableExpression::execute_quietly()
{
evaluate();
}

View File

@ -21,11 +21,10 @@ public:
VariableExpression();
VariableExpression(std::string name, ContextManager * context);
ContextManager * context;
ContextManager * context_manager;
std::string name;
void execute();
void execute_quietly();
std::string name_of_context;
SenchaObject execute();
SenchaObject evaluate();
virtual ~VariableExpression();
};

View File

@ -24,12 +24,13 @@ WhileNode::~WhileNode() {
}
void WhileNode::execute()
SenchaObject WhileNode::execute()
{
while(evaluate_condition())
{
body->execute();
}
return SenchaObject();
}
bool WhileNode::evaluate_condition()

View File

@ -20,7 +20,7 @@ public:
WhileNode(ASTExpression * condition, ASTStatement * body);
virtual ~WhileNode();
ASTStatement * body;
virtual void execute();
virtual SenchaObject execute();
bool evaluate_condition();
};

View File

@ -164,7 +164,6 @@ void ASTInspector::visit(WhileNode * while_node)
void ASTInspector::visit(ProgramNode * program)
{
this->occurences["ProgramNode"]++;
std::cout << "Visiting ProgramNode" << std::endl;
depth_level++;
std::string visit_notes = "";
visit_notes += "ProgramNode:\n";
@ -203,11 +202,23 @@ void ASTInspector::visit(DeclarationStatement * declaration_statement)
depth_level++;
std::string visit_notes = "";
visit_notes += "DeclarationStatement:\n";
visit_notes += "It declares: " + declaration_statement->name + "to be:\n";
visit_notes += declaration_statement->right_value.repr();
if(!declaration_statement->is_function )
{
visit_notes += declaration_statement->right_value.repr();
write_report(visit_notes);
}
else
{
visit_notes += "function";
write_report(visit_notes);
declaration_statement->body->accept(this);
}
write_report(visit_notes);
write_report("End of DeclarationStatement\n");
depth_level--;
}

View File

@ -47,9 +47,6 @@ private:
};
#endif /* ASTINSPECTOR_H_ */

View File

@ -23,56 +23,31 @@ void Context::register_function(std::string name, PointerToNativeFunction f)
registered_functions[name] = f;
}
SenchaObject Context::execute_native_function(std::string name, std::vector<ASTExpression *> arguments)
void Context::register_function(std::string name, SenchaFunction * f)
{
SenchaObject result;
if(registered_functions.count(name) == 1)
result = registered_functions[name](arguments);
return result;
registered_sfunctions[name] = f;
}
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);
object_store[name] = 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]);
if(object_store.count(name) != 0)
return object_store[name];
else return SenchaObject();
}
std::string Context::debug() {
std::string debug_note = "";
for( auto iter = this->interpreter_context.begin(); iter != this->interpreter_context.end(); iter++)
for( auto iter = this->object_store.begin(); iter != this->object_store.end(); iter++)
{
debug_note += "Context: " + to_string((*iter).second) + ": " + (*iter).first + " " + object_store[(*iter).second].repr() + "\n";
debug_note += "Context: " + (*iter).second.repr() + ": " + (*iter).first + " " + "\n";
}
return debug_note;

View File

@ -7,7 +7,15 @@
#ifndef CONTEXT_H_
#define CONTEXT_H_
#include <map>
#include <string>
#include "Utils/to_string.h"
#include "Elements/SenchaObject.h"
#include "Elements/SenchaFunction.h"
#include "AST/ASTExpression.h"
class Context {
public:
@ -15,24 +23,19 @@ public:
unsigned int index;
std::string name;
std::map<ObjectIndex, SenchaObject> object_store;
ObjectIndex add_to_store(SenchaObject & object);
SenchaObject get_from_store(ObjectIndex index);
std::map<std::string, SenchaObject> object_store;
unsigned int add_to_store(SenchaObject & object);
SenchaObject get_from_store(unsigned int index);
typedef SenchaObject (*PointerToNativeFunction)(std::vector<ASTExpression *>);
std::map<std::string, PointerToNativeFunction> registered_functions;
std::map<std::string, SenchaFunction *> registered_sfunctions;
void register_function(std::string name, PointerToNativeFunction f);
void register_function(std::string name, SenchaFunction * f);
SenchaObject execute_native_function(std::string name, std::vector<ASTExpression *> arguments);
//Overload it to use contexts
typedef std::map<std::string, ObjectIndex> ExecutionContext;
ExecutionContext interpreter_context;
std::string debug() ;
void add(std::string name, SenchaObject object);
void set(std::string name, SenchaObject object);

View File

@ -9,6 +9,7 @@
ContextManager::ContextManager() {
contexts["global"] = new Context("global");
stack.push(contexts["global"]);
index = 0;
}
@ -20,12 +21,46 @@ Context * ContextManager::create_new_context()
Context * context = new Context("Zdzislaw" + to_string(index));
index++;
contexts[context->name] = context;
stack.push(context);
return context;
}
SenchaObject ContextManager::execute_function(std::string name, std::vector<ASTExpression *> arguments)
{
SenchaObject result;
if(contexts["global"]->registered_functions.count(name) == 1)
{
result = contexts["global"]->registered_functions[name](arguments);
}
else if(contexts["global"]->registered_sfunctions.count(name) == 1)
{
SenchaFunction * function = contexts["global"]->registered_sfunctions[name];
std::string name_of_context = create_new_context()->name;
for(unsigned int i = 0; i < function->names_of_arguments.size(); i++)
get_top()->add(function->names_of_arguments[i], arguments[i]->evaluate());
result = (*function)();
pop_context();
destroy_context(name_of_context);
}
return result;
}
Context * ContextManager::get_context(std::string name)
{
return contexts[name];
}
Context * ContextManager::get_top()
{
return stack.top();
}
void ContextManager::pop_context()
{
stack.pop();
}
Context * ContextManager::context(std::string name)
@ -39,7 +74,7 @@ void ContextManager::destroy_context(std::string name)
auto iter = contexts.find(name);
if(iter != contexts.end())
{
delete (*iter);
delete ((*iter).second);
contexts.erase(iter);
}
}

View File

@ -5,30 +5,33 @@
* Author: attero
*/
#ifndef CONTEXT_H_
#define CONTEXT_H_
#ifndef CONTEXT_MANAGER_H_
#define CONTEXT_MANAGER_H_
#include <map>
#include <vector>
#include <string>
#include <iostream>
#include "Elements/SenchaObject.h"
#include "AST/ASTExpression.h"
#include <stack>
#include "Context.h"
#include "Utils/to_string.h"
typedef unsigned long ObjectIndex;
typedef unsigned long FunctionIndex;
class ContextManager {
public:
ContextManager();
std::stack<Context *> stack;
std::map<std::string, Context *> contexts;
Context * create_new_context();
void destroy_context(std::string name);
Context * get_context(std::string name);
Context * context(std::string name);
Context * get_top();
SenchaObject execute_function(std::string name, std::vector<ASTExpression *> arguments);
void pop_context();
unsigned int index;
virtual ~ContextManager();
};
#endif /* CONTEXT_H_ */
#endif /* CONTEXT_MANAGER_H_ */

View File

@ -7,8 +7,8 @@
#include "SenchaFunction.h"
SenchaFunction::SenchaFunction(std::string name, std::vector<std::string> names_of_arguments, ASTNode * body, ContextManager * context)
: name(name), names_of_arguments(names_of_arguments), body(body), context(context)
SenchaFunction::SenchaFunction(std::string name, std::vector<std::string> names_of_arguments, ASTNode * body)
: name(name), names_of_arguments(names_of_arguments), body(body)
{
}
@ -17,3 +17,7 @@ SenchaFunction::~SenchaFunction() {
}
SenchaObject SenchaFunction::operator()()
{
return body->execute();
}

View File

@ -13,7 +13,6 @@
#include "SenchaObject.h"
#include "Element.h"
#include "../Utils/to_string.h"
#include "../ContextManager.h"
#include "../AST/ASTNode.h"
@ -22,10 +21,12 @@ class SenchaFunction : public Element
public:
std::string name;
std::vector<std::string> names_of_arguments;
ASTNode * body;
ContextManager * context;
SenchaFunction(std::string name, std::vector<std::string> names_of_arguments, ASTNode * body, ContextManager * context);
ASTNode * body;
SenchaFunction(std::string name, std::vector<std::string> names_of_arguments, ASTNode * body);
SenchaObject operator()();
virtual ~SenchaFunction();
};

View File

@ -2,7 +2,7 @@
Parser::Parser(ContextManager * context)
{
this->context = context;
this->context_manager = context;
error_message = "***ERRORS DURING PARSING***\n";
position_in_stream = 0;
in_statement = false;
@ -109,7 +109,8 @@ bool Parser::is_type()
bool Parser::is_function_name()
{
if(context->registered_functions.count(tok_value) == 1)
if(context_manager->context("global")->registered_functions.count(tok_value) == 1 ||
context_manager->context("global")->registered_sfunctions.count(tok_value))
{
read_next();
return true;
@ -127,7 +128,7 @@ ASTStatement * Parser::statement()
}
else if(is_type())
{
DeclarationStatement * declaration = new DeclarationStatement(context);
DeclarationStatement * declaration = new DeclarationStatement(context_manager);
std::string identifier = tok_value;
read_next();
declaration->add_name(identifier);
@ -228,7 +229,7 @@ ASTExpression * Parser::prim_expr()
else if(current_token.get_type() == t_symbol)
{
string name = current_token.value;
VariableExpression * ve = new VariableExpression(name, context);
VariableExpression * ve = new VariableExpression(name, context_manager);
read_next();
return ve;
}
@ -252,7 +253,7 @@ ASTExpression * Parser::postfix_expr()
string name = tok_value;
if(is_function_name())
{
PostfixExpression * function_call = new PostfixExpression(name, context);
PostfixExpression * function_call = new PostfixExpression(name, context_manager);
if(accept("("))
{
if(!accept(")"))
@ -340,7 +341,7 @@ ASTExpression * Parser::expr()
if(accept("="))
{
ASTExpression * right = expr();
Assignment * assignment = new Assignment( context, name, left, right);
Assignment * assignment = new Assignment( context_manager, name, left, right);
return assignment;
}
else return left;

View File

@ -13,8 +13,8 @@ using namespace std;
class Parser
{
public:
Parser(ContextManager * context);
ContextManager * context;
Parser(ContextManager * context_manager);
ContextManager * context_manager;
virtual ~Parser();
void interpret();

View File

@ -155,15 +155,15 @@ void interactive()
{
Lexer lexer;
ContextManager context;
context.register_function("print", print);
context.register_function("sin", s_sin);
context.register_function("cos", s_cos);
context.register_function("tan", s_tan);
context.register_function("sleep", sleep);
context.register_function("len", len);
ContextManager context_manager;
context_manager.context("global")->register_function("print", print);
context_manager.context("global")->register_function("sin", s_sin);
context_manager.context("global")->register_function("cos", s_cos);
context_manager.context("global")->register_function("tan", s_tan);
context_manager.context("global")->register_function("sleep", sleep);
context_manager.context("global")->register_function("len", len);
Parser parser(&context);
Parser parser(&context_manager);
ASTInspector inspector;
vector<Token> tokens;
@ -186,7 +186,7 @@ void interactive()
parser.interpret();
parser.program->execute_last();
inspector.visit(parser.program);
cout << inspector.get_report();
//cout << inspector.get_report();
inspector.forget_everything();
}
}
@ -210,15 +210,15 @@ int main(int argc, char *argv[])
else {
auto name = argument1;
Lexer lexer;
ContextManager context;
context.register_function("print", print);
context.register_function("sin", s_sin);
context.register_function("cos", s_cos);
context.register_function("tan", s_tan);
context.register_function("sleep", sleep);
context.register_function("len", len);
ContextManager context_manager;
context_manager.context("global")->register_function("print", print);
context_manager.context("global")->register_function("sin", s_sin);
context_manager.context("global")->register_function("cos", s_cos);
context_manager.context("global")->register_function("tan", s_tan);
context_manager.context("global")->register_function("sleep", sleep);
context_manager.context("global")->register_function("len", len);
Parser parser(&context);
Parser parser(&context_manager);
vector<Token> tokens;
string line;