Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
No results found
Show changes
Commits on Source (5)
Showing
with 721 additions and 60 deletions
...@@ -138,10 +138,7 @@ Game* Compiler::createGame(SyntaxTree* input_game) ...@@ -138,10 +138,7 @@ Game* Compiler::createGame(SyntaxTree* input_game)
SyntaxTree* state_st = get_STATE_from_GAME(input_game); SyntaxTree* state_st = get_STATE_from_GAME(input_game);
DataSet* state = createDataSet(get_DATA_SET_from_STATE(state_st)); DataSet* state = createDataSet(get_DATA_SET_from_STATE(state_st));
InstructionBlock* IB = createInstructionBlock(get_INSTRUCTION_BLOCK_from_STATE(state_st), state, NULL); InstructionBlock* IB = createInstructionBlock(get_INSTRUCTION_BLOCK_from_STATE(state_st), state, NULL, VAR_TYPE::VOID);
void* ptr = state->getValuePtr("a");
*(int*)ptr = 7;
IB->RunBlock(); IB->RunBlock();
state->print(); state->print();
...@@ -189,52 +186,39 @@ DataSet* Compiler::createDataSet(SyntaxTree* input_data_set) ...@@ -189,52 +186,39 @@ DataSet* Compiler::createDataSet(SyntaxTree* input_data_set)
return data_set; return data_set;
} }
InstructionBlock* Compiler::createInstructionBlock(SyntaxTree* input_instruction_block, DataSet* state, DataSet* move) InstructionBlock* Compiler::createInstructionBlock(SyntaxTree* input_instruction_block, DataSet* state, DataSet* move, VAR_TYPE return_type)
{ {
SyntaxTree* local_data = getElement(input_instruction_block, Type::instruction_block, Type::data_set); SyntaxTree* local_data = getElement(input_instruction_block, Type::instruction_block, Type::data_set);
SyntaxTree* instruction_list = extract(input_instruction_block, 1, "INSTRUCTION_LIST from INSTRUCTION_BLOCK"); // REFACTOR SyntaxTree* instruction_list = extract(input_instruction_block, 1, "INSTRUCTION_LIST from INSTRUCTION_BLOCK"); // REFACTOR
//getElement(input_instruction_block, Type::instruction_block, Type::instruction_list);
// Create local DataSet // Create local DataSet
DataSet* local = createDataSet(local_data); DataSet* local = createDataSet(local_data);
InstructionBlock* instruction_block = new InstructionBlock(NULL, return_type);
// Create Instruction graph // Create Instruction graph
Instruction* entry = NULL; std::list<Instruction*> last_instructions;
Instruction* previous_instr = NULL; Instruction* entry = createInstructionGraph(instruction_list, local, state, move, instruction_block->getReturnVariable(), last_instructions);
while (instruction_list->type == Type::instruction_list)
{
SyntaxTree* instruction_st = getElement(instruction_list, Type::instruction_list, Type::instruction);
instruction_list = extract(instruction_list, 1, "INSTRUCTION_LIST from INSTRUCTION_LIST"); // REFACTOR
//getElement(instruction_list, Type::instruction_list, Type::instruction_list);
Instruction* next_instr = createInstruction(instruction_st, local, state, move);
if (entry == NULL) instruction_block->setEntryPoint(entry);
{
entry = next_instr; return instruction_block;
previous_instr = next_instr;
}
else
{
previous_instr->setNext(next_instr);
previous_instr = next_instr;
}
}
return new InstructionBlock(entry);
} }
Instruction* Compiler::createInstruction(SyntaxTree* input_instruction, DataSet* local, DataSet* state, DataSet* move) Instruction* Compiler::createInstruction(SyntaxTree* input_instruction, DataSet* local, DataSet* state, DataSet* move, Variable* return_var, std::list<Instruction*>& last_instructions)
{ {
SyntaxTree* typed_instruction = getSingleElement(input_instruction, Type::instruction); SyntaxTree* typed_instruction = getSingleElement(input_instruction, Type::instruction);
switch (typed_instruction->type) switch (typed_instruction->type)
{ {
case Type::assign_instr: return createAssignInstruction(typed_instruction, local, state, move); case Type::assign_instr: {
case Type::return_instr: break; Instruction* instr = createAssignInstruction(typed_instruction, local, state, move);
last_instructions.push_back(instr);
return instr;
}
case Type::return_instr: return createReturnInstruction(typed_instruction, local, state, move, return_var);
case Type::if_instr: return createIfInstruction(typed_instruction, local, state, move, return_var, last_instructions);
case Type::while_instr: return createWhileInstruction(typed_instruction, local, state, move, return_var, last_instructions);
default: break; default: break;
} }
...@@ -264,9 +248,10 @@ Instruction* Compiler::createAssignInstruction(SyntaxTree* input_instruction, Da ...@@ -264,9 +248,10 @@ Instruction* Compiler::createAssignInstruction(SyntaxTree* input_instruction, Da
ExpressionInt* expr = createIntExpression(expression_st, local, state, move); ExpressionInt* expr = createIntExpression(expression_st, local, state, move);
return new InstructionAssignInt(to, expr); return new InstructionAssignInt(to, expr);
} }
case VAR_TYPE::BOOL: { case VAR_TYPE::BOOL:
std::cout << "Warnig: Bool value type not implemented\n"; {
return NULL; ExpressionBool* expr = createBoolExpression(expression_st, local, state, move);
return new InstructionAssignBool(to, expr);
} }
default: { default: {
std::cout << "Warnig: Unknown value type\n"; std::cout << "Warnig: Unknown value type\n";
...@@ -277,6 +262,117 @@ Instruction* Compiler::createAssignInstruction(SyntaxTree* input_instruction, Da ...@@ -277,6 +262,117 @@ Instruction* Compiler::createAssignInstruction(SyntaxTree* input_instruction, Da
return nullptr; return nullptr;
} }
Instruction* Compiler::createReturnInstruction(SyntaxTree* input_instruction, DataSet* local, DataSet* state, DataSet* move, Variable* return_var)
{
bool returns_value = input_instruction->children_num == 1;
SyntaxTree* expression_st = NULL;
if(returns_value)
expression_st = extract(input_instruction, 0, "EXPR from RETURN_INSTR"); // REFACTOR
switch (return_var->getType())
{
case VAR_TYPE::VOID: {
if (returns_value)
{
std::cout << "Warnig: Wrong return type, should be VOID\n";
return NULL;
}
return new InstructionReturnVoid();
}
case VAR_TYPE::INT: {
if (!returns_value)
{
std::cout << "Warnig: No return value, should be VOID\n";
return NULL;
}
ExpressionInt* expr = createIntExpression(expression_st, local, state, move);
return new InstructionReturnInt(expr, return_var);
}
case VAR_TYPE::BOOL: {
if (!returns_value)
{
std::cout << "Warnig: No return value, should be VOID\n";
return NULL;
}
ExpressionBool* expr = createBoolExpression(expression_st, local, state, move);
return new InstructionReturnBool(expr, return_var);
}
default: break;
}
return nullptr;
}
Instruction* Compiler::createIfInstruction(SyntaxTree* input_instruction, DataSet* local, DataSet* state, DataSet* move, Variable* return_var, std::list<Instruction*>& last_instructions)
{
SyntaxTree* condition_st = extract(input_instruction, 0, "EXPR from IF_INSTR"); // REFACTOR
SyntaxTree* instruction_list_st = extract(input_instruction, 1, "INSTRUCTION_LIST from IF_INSTR"); // REFACTOR
ExpressionBool* condition = createBoolExpression(condition_st, local, state, move);
Instruction* first = createInstructionGraph(instruction_list_st, local, state, move, return_var, last_instructions);
InstructionConditionalJump* instr = new InstructionConditionalJump(condition, first);
last_instructions.push_back(instr);
return instr;
}
Instruction* Compiler::createWhileInstruction(SyntaxTree* input_instruction, DataSet* local, DataSet* state, DataSet* move, Variable* return_var, std::list<Instruction*>& last_instructions)
{
SyntaxTree* condition_st = extract(input_instruction, 0, "EXPR from WHILE_INSTR"); // REFACTOR
SyntaxTree* instruction_list_st = extract(input_instruction, 1, "INSTRUCTION_LIST from WHILE_INSTR"); // REFACTOR
ExpressionBool* condition = createBoolExpression(condition_st, local, state, move);
Instruction* first = createInstructionGraph(instruction_list_st, local, state, move, return_var, last_instructions);
InstructionConditionalJump* while_instr = new InstructionConditionalJump(condition, first);
for (Instruction* instr : last_instructions)
instr->setNext(while_instr);
last_instructions.clear();
last_instructions.push_back(while_instr);
return while_instr;
}
Instruction* Compiler::createInstructionGraph(SyntaxTree* input_instruction_list, DataSet* local, DataSet* state, DataSet* move, Variable* return_variable, std::list<Instruction*>& predecessors)
{
Instruction* entry = NULL;
//Instruction* previous_instr = NULL;
std::list<Instruction*> last_instructions;
while (input_instruction_list->type == Type::instruction_list)
{
SyntaxTree* instruction_st = getElement(input_instruction_list, Type::instruction_list, Type::instruction);
input_instruction_list = extract(input_instruction_list, 1, "INSTRUCTION_LIST from INSTRUCTION_LIST"); // REFACTOR
last_instructions.clear();
Instruction* next_instr = createInstruction(instruction_st, local, state, move, return_variable, last_instructions);
if (entry == NULL)
{
entry = next_instr;
//previous_instr = next_instr;
predecessors = last_instructions;
}
else
{
//previous_instr->setNext(next_instr);
//previous_instr = next_instr;
for (Instruction* instr : predecessors)
instr->setNext(next_instr);
predecessors.clear();
predecessors = last_instructions;
}
}
return entry;
}
ExpressionInt* Compiler::createIntExpression(SyntaxTree* input_expression, DataSet* local, DataSet* state, DataSet* move) ExpressionInt* Compiler::createIntExpression(SyntaxTree* input_expression, DataSet* local, DataSet* state, DataSet* move)
{ {
switch (input_expression->type) switch (input_expression->type)
...@@ -286,22 +382,11 @@ ExpressionInt* Compiler::createIntExpression(SyntaxTree* input_expression, DataS ...@@ -286,22 +382,11 @@ ExpressionInt* Compiler::createIntExpression(SyntaxTree* input_expression, DataS
SyntaxTree* next_expr = extract(input_expression, 0, "EXPR from EXPR"); // REFACTOR SyntaxTree* next_expr = extract(input_expression, 0, "EXPR from EXPR"); // REFACTOR
return createIntExpression(next_expr, local, state, move); return createIntExpression(next_expr, local, state, move);
} }
case Type::expr_ref: // REFACTOR case Type::expr_ref:
{ {
SyntaxTree* variable_reference_st = extract(input_expression, 0, "VARIABLE_REFERENCE from EXPR"); // REFACTOR SyntaxTree* variable_reference_st = extract(input_expression, 0, "VARIABLE_REFERENCE from EXPR"); // REFACTOR
SyntaxTree* scope_st = extract(variable_reference_st, 0, "SCOPE from VARIABLE_REFERENCE"); // REFACTOR void* from = getIdentifierReference(variable_reference_st, VAR_TYPE::INT, local, state, move);
SyntaxTree* identifier_st = extract(variable_reference_st, 1, "IDENTIFIER from VARIABLE_REFERENCE"); // REFACTOR if (!from) return NULL;
DataSet* data_set_from = getScope(scope_st->type, local, state, move);
if (!data_set_from) return NULL;
void* from = data_set_from->getValuePtr(identifier_st->text);
VAR_TYPE type_from = data_set_from->getValueType(identifier_st->text);
if (!from) std::cout << "Warnig: Not found identifier \"" << identifier_st->text << "\" in scope: " << getTypeName(scope_st->type) << '\n';
if (type_from != VAR_TYPE::INT) {
std::cout << "Warnig: Incorrect variable type, should be INT\n";
return NULL;
}
return new ExpressionInt_Id((int*)from); return new ExpressionInt_Id((int*)from);
} }
...@@ -311,6 +396,12 @@ ExpressionInt* Compiler::createIntExpression(SyntaxTree* input_expression, DataS ...@@ -311,6 +396,12 @@ ExpressionInt* Compiler::createIntExpression(SyntaxTree* input_expression, DataS
std::string string_val = extract(var_def, 0, "type from VAR_DECLARATION")->text; std::string string_val = extract(var_def, 0, "type from VAR_DECLARATION")->text;
return new ExpressionInt_Value(stoi(string_val)); return new ExpressionInt_Value(stoi(string_val));
} }
case Type::expr_neg:
{
SyntaxTree* arg_st = extract(input_expression, 0, "EXPR A from EXPR");
ExpressionInt* arg = createIntExpression(arg_st, local, state, move);
return new ExpressionInt_Neg(arg);
}
case Type::expr_add: case Type::expr_add:
case Type::expr_sub: case Type::expr_sub:
case Type::expr_mul: case Type::expr_mul:
...@@ -338,6 +429,98 @@ ExpressionInt* Compiler::createIntExpression(SyntaxTree* input_expression, DataS ...@@ -338,6 +429,98 @@ ExpressionInt* Compiler::createIntExpression(SyntaxTree* input_expression, DataS
return nullptr; return nullptr;
} }
ExpressionBool* Compiler::createBoolExpression(SyntaxTree* input_expression, DataSet* local, DataSet* state, DataSet* move)
{
switch (input_expression->type)
{
case Type::expr:
{
SyntaxTree* next_expr = extract(input_expression, 0, "EXPR from EXPR"); // REFACTOR
return createBoolExpression(next_expr, local, state, move);
}
case Type::expr_ref:
{
SyntaxTree* variable_reference_st = extract(input_expression, 0, "VARIABLE_REFERENCE from EXPR"); // REFACTOR
void* from = getIdentifierReference(variable_reference_st, VAR_TYPE::BOOL, local, state, move);
if (!from) return NULL;
return new ExpressionBool_Id((bool*)from);
}
case Type::expr_literal:
{
SyntaxTree* var_def = getElement(input_expression, Type::expr_literal, Type::var_definition);
std::string string_val = extract(var_def, 0, "type from VAR_DECLARATION")->text;
return new ExpressionBool_Value(string_val == "true");
}
case Type::expr_not:
{
SyntaxTree* arg_st = extract(input_expression, 0, "EXPR from EXPR");
ExpressionBool* arg = createBoolExpression(arg_st, local, state, move);
return new ExpressionBool_Not(arg);
}
case Type::expr_and:
case Type::expr_or:
{
SyntaxTree* arg_a_st = extract(input_expression, 0, "EXPR A from EXPR");
SyntaxTree* arg_b_st = extract(input_expression, 1, "EXPR B from EXPR");
ExpressionBool* a = createBoolExpression(arg_a_st, local, state, move);
ExpressionBool* b = createBoolExpression(arg_b_st, local, state, move);
switch (input_expression->type)
{
case Type::expr_and: return new ExpressionBool_And(a, b);
case Type::expr_or: return new ExpressionBool_Or(a, b);
}
}
case Type::expr_equal:
case Type::expr_not_equal:
case Type::expr_greater_equal:
case Type::expr_less_equal:
case Type::expr_greater:
case Type::expr_less:
{
SyntaxTree* arg_a_st = extract(input_expression, 0, "EXPR A from EXPR");
SyntaxTree* arg_b_st = extract(input_expression, 1, "EXPR B from EXPR");
ExpressionInt* a = createIntExpression(arg_a_st, local, state, move);
ExpressionInt* b = createIntExpression(arg_b_st, local, state, move);
switch (input_expression->type)
{
case Type::expr_equal: return new ExpressionBool_Equal(a, b);
case Type::expr_not_equal: return new ExpressionBool_NotEqual(a, b);
case Type::expr_greater_equal: return new ExpressionBool_GreaterEqual(a, b);
case Type::expr_less_equal: return new ExpressionBool_LessEqual(a, b);
case Type::expr_greater: return new ExpressionBool_Greater(a, b);
case Type::expr_less: return new ExpressionBool_Less(a, b);
}
}
default: break;
}
return nullptr;
}
void* Compiler::getIdentifierReference(SyntaxTree* var_reference, VAR_TYPE required_type, DataSet* local, DataSet* state, DataSet* move)
{
SyntaxTree* scope_st = extract(var_reference, 0, "SCOPE from VARIABLE_REFERENCE"); // REFACTOR
SyntaxTree* identifier_st = extract(var_reference, 1, "IDENTIFIER from VARIABLE_REFERENCE"); // REFACTOR
DataSet* data_set_from = getScope(scope_st->type, local, state, move);
if (!data_set_from) return NULL;
void* from = data_set_from->getValuePtr(identifier_st->text);
VAR_TYPE type_from = data_set_from->getValueType(identifier_st->text);
if (!from) std::cout << "Warnig: Not found identifier \"" << identifier_st->text << "\" in scope: " << getTypeName(scope_st->type) << '\n';
if (type_from != required_type) {
std::cout << "Warnig: Incorrect variable type, should be " << VarTypeToString(required_type) << "\n";
return NULL;
}
return from;
}
DataSet* Compiler::getScope(Type type, DataSet* local, DataSet* state, DataSet* move) DataSet* Compiler::getScope(Type type, DataSet* local, DataSet* state, DataSet* move)
{ {
switch (type) switch (type)
......
...@@ -83,10 +83,19 @@ private: ...@@ -83,10 +83,19 @@ private:
// Instructions // // Instructions //
InstructionBlock* createInstructionBlock(SyntaxTree* input_instruction_block, DataSet* state, DataSet* move); InstructionBlock* createInstructionBlock(SyntaxTree* input_instruction_block, DataSet* state, DataSet* move, VAR_TYPE return_type);
Instruction* createInstruction(SyntaxTree* input_instruction, DataSet* local, DataSet* state, DataSet* move);
Instruction* createInstruction(SyntaxTree* input_instruction, DataSet* local, DataSet* state, DataSet* move, Variable* return_var, std::list<Instruction*>& last_instructions);
Instruction* createAssignInstruction(SyntaxTree* input_instruction, DataSet* local, DataSet* state, DataSet* move); Instruction* createAssignInstruction(SyntaxTree* input_instruction, DataSet* local, DataSet* state, DataSet* move);
Instruction* createReturnInstruction(SyntaxTree* input_instruction, DataSet* local, DataSet* state, DataSet* move, Variable* return_var);
Instruction* createIfInstruction(SyntaxTree* input_instruction, DataSet* local, DataSet* state, DataSet* move, Variable* return_var, std::list<Instruction*>& last_instructions);
Instruction* createWhileInstruction(SyntaxTree* input_instruction, DataSet* local, DataSet* state, DataSet* move, Variable* return_var, std::list<Instruction*>& last_instructions);
Instruction* createInstructionGraph(SyntaxTree* input_instruction_list, DataSet* local, DataSet* state, DataSet* move, Variable* return_variable, std::list<Instruction*>& predecessors);
ExpressionInt* createIntExpression(SyntaxTree* input_expression, DataSet* local, DataSet* state, DataSet* move); ExpressionInt* createIntExpression(SyntaxTree* input_expression, DataSet* local, DataSet* state, DataSet* move);
ExpressionBool* createBoolExpression(SyntaxTree* input_expression, DataSet* local, DataSet* state, DataSet* move);
void* getIdentifierReference(SyntaxTree* var_reference, VAR_TYPE required_type, DataSet* local, DataSet* state, DataSet* move);
DataSet* getScope(Type type, DataSet* local, DataSet* state, DataSet* move); DataSet* getScope(Type type, DataSet* local, DataSet* state, DataSet* move);
public: public:
......
...@@ -69,3 +69,63 @@ void DataSet::print() ...@@ -69,3 +69,63 @@ void DataSet::print()
std::cout << VarTypeToString(var.type) << ' ' << name << ' ' << getStringValue(getValuePtr(name), var.type) << '\n'; std::cout << VarTypeToString(var.type) << ' ' << name << ' ' << getStringValue(getValuePtr(name), var.type) << '\n';
} }
} }
Variable::Variable(VAR_TYPE type)
: type(type)
{
switch (type)
{
case VAR_TYPE::INT: value_ptr = malloc(sizeof(int)); break;
case VAR_TYPE::BOOL: value_ptr = malloc(sizeof(bool)); break;
default: value_ptr = NULL;
}
}
bool Variable::setValueInt(int value)
{
if (type != VAR_TYPE::INT)
return false;
*(int*)value_ptr = value;
return true;
}
bool Variable::setValueBool(bool value)
{
if (type != VAR_TYPE::BOOL)
return false;
*(bool*)value_ptr = value;
return true;
}
void* Variable::getValue()
{
return value_ptr;
}
int Variable::getValueInt()
{
if (type != VAR_TYPE::INT)
{
std::cout << "Warnig: Wrong type requested. Current type: " << VarTypeToString(type) << " \tRequested: INT\n";
return 0;
}
return *(int*)value_ptr;
}
bool Variable::getValueBool()
{
if (type != VAR_TYPE::BOOL)
{
std::cout << "Warnig: Wrong type requested. Current type: " << VarTypeToString(type) << " \tRequested: BOOL\n";
return 0;
}
return *(bool*)value_ptr;
}
VAR_TYPE Variable::getType()
{
return type;
}
...@@ -51,3 +51,21 @@ public: ...@@ -51,3 +51,21 @@ public:
}; };
class Variable
{
private:
void* value_ptr;
VAR_TYPE type;
public:
Variable(VAR_TYPE type);
bool setValueInt(int value);
bool setValueBool(bool value);
void* getValue();
int getValueInt();
bool getValueBool();
VAR_TYPE getType();
};
...@@ -15,6 +15,7 @@ std::string VarTypeToString(VAR_TYPE type) ...@@ -15,6 +15,7 @@ std::string VarTypeToString(VAR_TYPE type)
{ {
case VAR_TYPE::INT: return "INT"; case VAR_TYPE::INT: return "INT";
case VAR_TYPE::BOOL: return "BOOL"; case VAR_TYPE::BOOL: return "BOOL";
case VAR_TYPE::VOID: return "VOID";
default: return "UNKNOWN"; default: return "UNKNOWN";
} }
} }
......
...@@ -7,6 +7,7 @@ enum class VAR_TYPE ...@@ -7,6 +7,7 @@ enum class VAR_TYPE
{ {
INT, INT,
BOOL, BOOL,
VOID,
UNKNOWN UNKNOWN
......
#include "ExpressionBool.h"
// Constructors
ExpressionBool_Id::ExpressionBool_Id(bool* ptr)
{
value_ptr = ptr;
}
ExpressionBool_Value::ExpressionBool_Value(bool val)
{
value = val;
}
ExpressionBool_Not::ExpressionBool_Not(ExpressionBool* expr)
{
this->expr = expr;
}
bool ExpressionBool_Not::evaluate()
{
return !expr->evaluate();
}
ExpressionBool_TwoBoolArgumentsOperation::ExpressionBool_TwoBoolArgumentsOperation(ExpressionBool* a, ExpressionBool* b)
{
expr_a = a;
expr_b = b;
}
ExpressionBool_TwoIntArgumentsOperation::ExpressionBool_TwoIntArgumentsOperation(ExpressionInt* a, ExpressionInt* b)
{
expr_a = a;
expr_b = b;
}
//Evaluators
bool ExpressionBool::evaluate()
{
return false;
}
bool ExpressionBool_Id::evaluate()
{
return *value_ptr;
}
bool ExpressionBool_Value::evaluate()
{
return value;
}
bool ExpressionBool_And::evaluate()
{
return expr_a->evaluate() && expr_b->evaluate();
}
bool ExpressionBool_Or::evaluate()
{
return expr_a->evaluate() || expr_b->evaluate();
}
bool ExpressionBool_Equal::evaluate()
{
return expr_a->evaluate() == expr_b->evaluate();
}
bool ExpressionBool_NotEqual::evaluate()
{
return expr_a->evaluate() != expr_b->evaluate();
}
bool ExpressionBool_GreaterEqual::evaluate()
{
return expr_a->evaluate() >= expr_b->evaluate();
}
bool ExpressionBool_LessEqual::evaluate()
{
return expr_a->evaluate() <= expr_b->evaluate();
}
bool ExpressionBool_Greater::evaluate()
{
return expr_a->evaluate() > expr_b->evaluate();
}
bool ExpressionBool_Less::evaluate()
{
return expr_a->evaluate() < expr_b->evaluate();
}
#pragma once
#include "ExpressionInt.h"
class ExpressionBool
{
public:
virtual bool evaluate();
};
// Subclasses for Bool Expression
// Expression represents a refference
// to DataSet by identifier
class ExpressionBool_Id : public ExpressionBool
{
private:
bool* value_ptr;
public:
ExpressionBool_Id(bool* ptr);
bool evaluate() override;
};
// Expression represents a
// constant value
class ExpressionBool_Value : public ExpressionBool
{
private:
bool value;
public:
ExpressionBool_Value(bool val);
bool evaluate() override;
};
// Expression represents negation
// of BOOL expression
class ExpressionBool_Not : public ExpressionBool
{
private:
ExpressionBool* expr;
public:
ExpressionBool_Not(ExpressionBool* expr);
bool evaluate() override;
};
// Class agregates two Bool argument operations
class ExpressionBool_TwoBoolArgumentsOperation : public ExpressionBool
{
protected:
ExpressionBool* expr_a;
ExpressionBool* expr_b;
public:
ExpressionBool_TwoBoolArgumentsOperation(ExpressionBool* a, ExpressionBool* b);
};
class ExpressionBool_And : public ExpressionBool_TwoBoolArgumentsOperation
{
public:
ExpressionBool_And(ExpressionBool* a, ExpressionBool* b) : ExpressionBool_TwoBoolArgumentsOperation(a, b) {}
bool evaluate() override;
};
class ExpressionBool_Or : public ExpressionBool_TwoBoolArgumentsOperation
{
public:
ExpressionBool_Or(ExpressionBool* a, ExpressionBool* b) : ExpressionBool_TwoBoolArgumentsOperation(a, b) {}
bool evaluate() override;
};
// Class agregates two Int argument operations
class ExpressionBool_TwoIntArgumentsOperation : public ExpressionBool
{
protected:
ExpressionInt* expr_a;
ExpressionInt* expr_b;
public:
ExpressionBool_TwoIntArgumentsOperation(ExpressionInt* a, ExpressionInt* b);
};
class ExpressionBool_Equal : public ExpressionBool_TwoIntArgumentsOperation
{
public:
ExpressionBool_Equal(ExpressionInt* a, ExpressionInt* b) : ExpressionBool_TwoIntArgumentsOperation(a, b) {}
bool evaluate() override;
};
class ExpressionBool_NotEqual : public ExpressionBool_TwoIntArgumentsOperation
{
public:
ExpressionBool_NotEqual(ExpressionInt* a, ExpressionInt* b) : ExpressionBool_TwoIntArgumentsOperation(a, b) {}
bool evaluate() override;
};
class ExpressionBool_GreaterEqual : public ExpressionBool_TwoIntArgumentsOperation
{
public:
ExpressionBool_GreaterEqual(ExpressionInt* a, ExpressionInt* b) : ExpressionBool_TwoIntArgumentsOperation(a, b) {}
bool evaluate() override;
};
class ExpressionBool_LessEqual : public ExpressionBool_TwoIntArgumentsOperation
{
public:
ExpressionBool_LessEqual(ExpressionInt* a, ExpressionInt* b) : ExpressionBool_TwoIntArgumentsOperation(a, b) {}
bool evaluate() override;
};
class ExpressionBool_Greater : public ExpressionBool_TwoIntArgumentsOperation
{
public:
ExpressionBool_Greater(ExpressionInt* a, ExpressionInt* b) : ExpressionBool_TwoIntArgumentsOperation(a, b) {}
bool evaluate() override;
};
class ExpressionBool_Less : public ExpressionBool_TwoIntArgumentsOperation
{
public:
ExpressionBool_Less(ExpressionInt* a, ExpressionInt* b) : ExpressionBool_TwoIntArgumentsOperation(a, b) {}
bool evaluate() override;
};
...@@ -13,6 +13,16 @@ ExpressionInt_Value::ExpressionInt_Value(int val) ...@@ -13,6 +13,16 @@ ExpressionInt_Value::ExpressionInt_Value(int val)
value = val; value = val;
} }
ExpressionInt_Neg::ExpressionInt_Neg(ExpressionInt* expr)
{
this->expr = expr;
}
int ExpressionInt_Neg::evaluate()
{
return -expr->evaluate();
}
ExpressionInt_TwoArgumentsOperation::ExpressionInt_TwoArgumentsOperation(ExpressionInt* a, ExpressionInt* b) ExpressionInt_TwoArgumentsOperation::ExpressionInt_TwoArgumentsOperation(ExpressionInt* a, ExpressionInt* b)
{ {
expr_a = a; expr_a = a;
......
...@@ -32,6 +32,18 @@ public: ...@@ -32,6 +32,18 @@ public:
int evaluate() override; int evaluate() override;
}; };
// Expression represents negation
// of expression
class ExpressionInt_Neg : public ExpressionInt
{
private:
ExpressionInt* expr;
public:
ExpressionInt_Neg(ExpressionInt* expr);
int evaluate() override;
};
// Class agregates two argument operations // Class agregates two argument operations
class ExpressionInt_TwoArgumentsOperation : public ExpressionInt class ExpressionInt_TwoArgumentsOperation : public ExpressionInt
{ {
......
#include "Instruction.h" #include "Instruction.h"
Instruction::Instruction() Instruction::Instruction()
//:next(NULL) :next(NULL)
{} {}
Instruction::Instruction(Instruction* next) Instruction::Instruction(Instruction* next)
......
...@@ -12,7 +12,7 @@ public: ...@@ -12,7 +12,7 @@ public:
Instruction(); Instruction();
Instruction(Instruction* next); Instruction(Instruction* next);
void setNext(Instruction* next); virtual void setNext(Instruction* next);
virtual Instruction* Run(); virtual Instruction* Run();
......
...@@ -13,3 +13,13 @@ Instruction* InstructionAssignInt::Run() ...@@ -13,3 +13,13 @@ Instruction* InstructionAssignInt::Run()
*(int*)to = expression->evaluate(); *(int*)to = expression->evaluate();
return next; return next;
} }
InstructionAssignBool::InstructionAssignBool(void* to, ExpressionBool* expr)
: InstructionAssign(to), expression(expr)
{}
Instruction* InstructionAssignBool::Run()
{
*(bool*)to = expression->evaluate();
return next;
}
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
#include "Instruction.h" #include "Instruction.h"
#include "Expression/ExpressionInt.h" #include "Expression/ExpressionInt.h"
#include "Expression/ExpressionBool.h"
class InstructionAssign : public Instruction class InstructionAssign : public Instruction
{ {
...@@ -21,3 +22,13 @@ public: ...@@ -21,3 +22,13 @@ public:
InstructionAssignInt(void* to, ExpressionInt* expr); InstructionAssignInt(void* to, ExpressionInt* expr);
Instruction* Run() override; Instruction* Run() override;
}; };
class InstructionAssignBool : public InstructionAssign
{
private:
ExpressionBool* expression;
public:
InstructionAssignBool(void* to, ExpressionBool* expr);
Instruction* Run() override;
};
#include "InstructionConditionalJump.h"
InstructionConditionalJump::InstructionConditionalJump(ExpressionBool* condition, Instruction* if_true)
: condition(condition), if_true(if_true)
{}
Instruction* InstructionConditionalJump::Run()
{
bool result = condition->evaluate();
if (result)
return if_true;
return next;
}
#pragma once
#include "Instruction.h"
#include "Expression/ExpressionBool.h"
class InstructionConditionalJump : public Instruction
{
private:
Instruction* if_true;
ExpressionBool* condition;
public:
InstructionConditionalJump(ExpressionBool* condition, Instruction* if_true);
Instruction* Run() override;
};
#include "InstructionReturn.h"
InstructionReturn::InstructionReturn(Variable* return_var)
: return_pointer(return_var->getValue())
{}
InstructionReturnInt::InstructionReturnInt(ExpressionInt* expr, Variable* return_var)
: InstructionReturn(return_var), expr(expr)
{}
InstructionReturnBool::InstructionReturnBool(ExpressionBool* expr, Variable* return_var)
: InstructionReturn(return_var), expr(expr)
{}
Instruction* InstructionReturnVoid::Run()
{
return NULL;
}
Instruction* InstructionReturnInt::Run()
{
*(int*)return_pointer = expr->evaluate();
return NULL;
}
Instruction* InstructionReturnBool::Run()
{
*(bool*)return_pointer = expr->evaluate();
return NULL;
}
#pragma once
#include "Instruction.h"
#include "Expression/ExpressionInt.h"
#include "Expression/ExpressionBool.h"
#include "../../DataSet/DataSet.h"
class InstructionReturn : public Instruction
{
protected:
void* return_pointer;
public:
InstructionReturn(Variable* return_var);
};
class InstructionReturnVoid: public Instruction
{
public:
Instruction* Run() override;
};
class InstructionReturnInt : public InstructionReturn
{
private:
ExpressionInt* expr;
public:
InstructionReturnInt(ExpressionInt* expr, Variable* return_var);
Instruction* Run() override;
};
class InstructionReturnBool : public InstructionReturn
{
private:
ExpressionBool* expr;
public:
InstructionReturnBool(ExpressionBool* expr, Variable* return_var);
Instruction* Run() override;
};
#include "InstructionBlock.h" #include "InstructionBlock.h"
InstructionBlock::InstructionBlock(Instruction* entry) InstructionBlock::InstructionBlock(Instruction* entry, VAR_TYPE return_type)
: entry_point(entry) : entry_point(entry)//, return_type(return_type)
{} {
return_value = new Variable(return_type);
}
void InstructionBlock::RunBlock() void InstructionBlock::RunBlock()
{ {
...@@ -13,3 +15,13 @@ void InstructionBlock::RunBlock() ...@@ -13,3 +15,13 @@ void InstructionBlock::RunBlock()
// TODO: get return value // TODO: get return value
} }
void InstructionBlock::setEntryPoint(Instruction* entry_point)
{
this->entry_point = entry_point;
}
Variable* InstructionBlock::getReturnVariable()
{
return return_value;
}
...@@ -3,19 +3,27 @@ ...@@ -3,19 +3,27 @@
#include "Instruction/Instruction.h" #include "Instruction/Instruction.h"
#include "Instruction/InstructionAssign.h" #include "Instruction/InstructionAssign.h"
#include "Instruction/InstructionReturn.h"
#include "Instruction/InstructionConditionalJump.h"
#include "../DataSet/DataSet.h" #include "../DataSet/DataSet.h"
class InstructionBlock class InstructionBlock
{ {
private: private:
//DataSet local;
//DataSet state;
Instruction* entry_point; Instruction* entry_point;
//void* return_ptr = NULL;
//VAR_TYPE return_type;
Variable* return_value;
public: public:
InstructionBlock(Instruction* entry); InstructionBlock(Instruction* entry, VAR_TYPE return_type);
void RunBlock(); void RunBlock();
void setEntryPoint(Instruction* entry_point);
Variable* getReturnVariable();
}; };