Started using unique_ptr
Nodes and variables now contain unique references to Values
This commit is contained in:
parent
423233bfb1
commit
efc49584ee
7 changed files with 62 additions and 28 deletions
|
@ -215,7 +215,7 @@ Value* eval_expression(Node* node, Environment* env) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
// Change to return copy of value [TODO]
|
// Change to return copy of value [TODO]
|
||||||
return new Value(*get_value(var));
|
return get_value(var);
|
||||||
break;
|
break;
|
||||||
//----------
|
//----------
|
||||||
case VALUE:
|
case VALUE:
|
||||||
|
@ -256,6 +256,7 @@ void eval_statement(Node* node, Environment* env) {
|
||||||
tempVal = eval_expression(node->children[0], env);
|
tempVal = eval_expression(node->children[0], env);
|
||||||
if (tempVal->type == BOOLEAN) {
|
if (tempVal->type == BOOLEAN) {
|
||||||
tempLong = get_long(tempVal);
|
tempLong = get_long(tempVal);
|
||||||
|
delete tempVal;
|
||||||
if (tempLong.size() > 1) { std::cerr << "Cannot have a vector of booleans for your if expression" << std::endl; break;}
|
if (tempLong.size() > 1) { std::cerr << "Cannot have a vector of booleans for your if expression" << std::endl; break;}
|
||||||
if (tempLong[0]) {
|
if (tempLong[0]) {
|
||||||
eval_statement(node->children[1], env);
|
eval_statement(node->children[1], env);
|
||||||
|
@ -272,11 +273,13 @@ void eval_statement(Node* node, Environment* env) {
|
||||||
tempVal = eval_expression(node->children[0], env);
|
tempVal = eval_expression(node->children[0], env);
|
||||||
if (tempVal->type == BOOLEAN) {
|
if (tempVal->type == BOOLEAN) {
|
||||||
tempLong = get_long(tempVal);
|
tempLong = get_long(tempVal);
|
||||||
|
delete tempVal;
|
||||||
if (tempLong.size() > 1) { std::cerr << "Cannot have a vector of booleans for your while expression" << std::endl; break;}
|
if (tempLong.size() > 1) { std::cerr << "Cannot have a vector of booleans for your while expression" << std::endl; break;}
|
||||||
while (tempLong[0]) {
|
while (tempLong[0]) {
|
||||||
eval_statement(node->children[1], env);
|
eval_statement(node->children[1], env);
|
||||||
tempVal = eval_expression(node->children[0], env);
|
tempVal = eval_expression(node->children[0], env);
|
||||||
tempLong = get_long(tempVal);
|
tempLong = get_long(tempVal);
|
||||||
|
delete tempVal;
|
||||||
if (tempLong.size() > 1) { std::cerr << "Cannot have a vector of booleans for your while expression" << std::endl; break;}
|
if (tempLong.size() > 1) { std::cerr << "Cannot have a vector of booleans for your while expression" << std::endl; break;}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -289,6 +292,7 @@ void eval_statement(Node* node, Environment* env) {
|
||||||
check_num_nodes(node, 1, "can only print out one expression at a time.");
|
check_num_nodes(node, 1, "can only print out one expression at a time.");
|
||||||
tempVal = eval_expression(node->children[0], env);
|
tempVal = eval_expression(node->children[0], env);
|
||||||
std::cout << tempVal << std::endl;
|
std::cout << tempVal << std::endl;
|
||||||
|
delete tempVal;
|
||||||
break;
|
break;
|
||||||
//------------
|
//------------
|
||||||
case STATEMENT: // Can have a maximum of two children statement nodes
|
case STATEMENT: // Can have a maximum of two children statement nodes
|
||||||
|
@ -302,6 +306,8 @@ void eval_statement(Node* node, Environment* env) {
|
||||||
//------------
|
//------------
|
||||||
default:
|
default:
|
||||||
printf("Error, %d not a valid statement type.\n", node->type);
|
printf("Error, %d not a valid statement type.\n", node->type);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <memory>
|
||||||
#include "../variables/value.hpp"
|
#include "../variables/value.hpp"
|
||||||
#include "../variables/environment.hpp"
|
#include "../variables/environment.hpp"
|
||||||
|
|
||||||
|
@ -16,7 +17,7 @@ class Environment;
|
||||||
class Node {
|
class Node {
|
||||||
public:
|
public:
|
||||||
int type;
|
int type;
|
||||||
Value* value;
|
std::unique_ptr<Value> value;
|
||||||
|
|
||||||
/* the id of the node (used for identifiers only) */
|
/* the id of the node (used for identifiers only) */
|
||||||
std::string id;
|
std::string id;
|
||||||
|
@ -29,17 +30,13 @@ class Node {
|
||||||
|
|
||||||
std::string toString(void) const;
|
std::string toString(void) const;
|
||||||
|
|
||||||
Node(int t, Value* v, std::string s) {
|
Node(int t, std::unique_ptr<Value> v, std::string s) : value(std::move(v)) {
|
||||||
type = t;
|
type = t;
|
||||||
value = v;
|
|
||||||
id = s;
|
id = s;
|
||||||
num_children = 0;
|
num_children = 0;
|
||||||
for (uint i = 0; i < MAX_CHILDREN; i++) {
|
std::fill(children.begin(), children.end(), nullptr);
|
||||||
children[i] = nullptr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
~Node() {
|
~Node() {
|
||||||
// delete value;
|
|
||||||
for (uint i = 0; i < num_children; i++) {
|
for (uint i = 0; i < num_children; i++) {
|
||||||
delete children[i];
|
delete children[i];
|
||||||
}
|
}
|
||||||
|
@ -47,7 +44,6 @@ class Node {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Abstract Syntax Tree Functions
|
// Abstract Syntax Tree Functions
|
||||||
// struct Node* make_node(int type, struct Value* value, std::string id);
|
|
||||||
void attach_node(Node* parent, Node* child);
|
void attach_node(Node* parent, Node* child);
|
||||||
std::string tree_string(const Node* node, uint tabs);
|
std::string tree_string(const Node* node, uint tabs);
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,9 @@ Value* add(Value* x, Value* y) {
|
||||||
ans = make_double(doubleResult);
|
ans = make_double(doubleResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete x;
|
||||||
|
delete y;
|
||||||
|
|
||||||
return ans;
|
return ans;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,6 +95,9 @@ Value* subtract(Value* x, Value* y) {
|
||||||
ans = make_double(doubleResult);
|
ans = make_double(doubleResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete x;
|
||||||
|
delete y;
|
||||||
|
|
||||||
return ans;
|
return ans;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,6 +141,9 @@ Value* division(Value* x, Value* y) {
|
||||||
ans = make_double(doubleResult);
|
ans = make_double(doubleResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete x;
|
||||||
|
delete y;
|
||||||
|
|
||||||
return ans;
|
return ans;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,6 +187,9 @@ Value* multiplication(Value* x, Value* y) {
|
||||||
ans = make_double(doubleResult);
|
ans = make_double(doubleResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete x;
|
||||||
|
delete y;
|
||||||
|
|
||||||
return ans;
|
return ans;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,6 +236,9 @@ Value* less(Value* x, Value* y) {
|
||||||
ans = make_booleans(longResult);
|
ans = make_booleans(longResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete x;
|
||||||
|
delete y;
|
||||||
|
|
||||||
return ans;
|
return ans;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,6 +285,9 @@ Value* greater(Value* x, Value* y) {
|
||||||
ans = make_booleans(longResult);
|
ans = make_booleans(longResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete x;
|
||||||
|
delete y;
|
||||||
|
|
||||||
return ans;
|
return ans;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -316,6 +334,9 @@ Value* less_equal(Value* x, Value* y) {
|
||||||
ans = make_booleans(longResult);
|
ans = make_booleans(longResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete x;
|
||||||
|
delete y;
|
||||||
|
|
||||||
return ans;
|
return ans;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -362,6 +383,9 @@ Value* greater_equal(Value* x, Value* y) {
|
||||||
ans = make_booleans(longResult);
|
ans = make_booleans(longResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete x;
|
||||||
|
delete y;
|
||||||
|
|
||||||
return ans;
|
return ans;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -407,6 +431,9 @@ Value* equals(Value* x, Value* y) {
|
||||||
ans = make_booleans(longResult);
|
ans = make_booleans(longResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete x;
|
||||||
|
delete y;
|
||||||
|
|
||||||
return ans;
|
return ans;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -452,6 +479,9 @@ Value* not_equals(Value* x, Value* y) {
|
||||||
ans = make_booleans(longResult);
|
ans = make_booleans(longResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete x;
|
||||||
|
delete y;
|
||||||
|
|
||||||
return ans;
|
return ans;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -465,6 +495,9 @@ Value* and_value(Value* x, Value* y) {
|
||||||
std::transform(x_long.begin(), x_long.end(), y_long.begin(),
|
std::transform(x_long.begin(), x_long.end(), y_long.begin(),
|
||||||
std::back_inserter(longResult), std::logical_and<>());
|
std::back_inserter(longResult), std::logical_and<>());
|
||||||
|
|
||||||
|
delete x;
|
||||||
|
delete y;
|
||||||
|
|
||||||
return make_booleans(longResult);
|
return make_booleans(longResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -478,6 +511,9 @@ Value* or_value(Value* x, Value* y) {
|
||||||
std::transform(x_long.begin(), x_long.end(), y_long.begin(),
|
std::transform(x_long.begin(), x_long.end(), y_long.begin(),
|
||||||
std::back_inserter(longResult), std::logical_or<>());
|
std::back_inserter(longResult), std::logical_or<>());
|
||||||
|
|
||||||
|
delete x;
|
||||||
|
delete y;
|
||||||
|
|
||||||
return make_booleans(longResult);
|
return make_booleans(longResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -489,5 +525,7 @@ Value* not_value(Value* x) {
|
||||||
std::vector<long> x_long = get_long(x);
|
std::vector<long> x_long = get_long(x);
|
||||||
std::transform(x_long.begin(), x_long.end(), std::back_inserter(longResult), std::logical_not<>());
|
std::transform(x_long.begin(), x_long.end(), std::back_inserter(longResult), std::logical_not<>());
|
||||||
|
|
||||||
|
delete x;
|
||||||
|
|
||||||
return make_booleans(longResult);
|
return make_booleans(longResult);
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,12 +46,12 @@ DIGIT [0-9]
|
||||||
"input" {return INPUT;}
|
"input" {return INPUT;}
|
||||||
"lambda" {return LAMBDATAG;}
|
"lambda" {return LAMBDATAG;}
|
||||||
":" {return COLON;}
|
":" {return COLON;}
|
||||||
"true" {yylval.value = new Node(VALUE, make_true(), ""); return VALUE;}
|
"true" {yylval.value = new Node(VALUE, std::unique_ptr<Value>(make_true()), ""); return VALUE;}
|
||||||
"false" {yylval.value = new Node(VALUE, make_false(), ""); return VALUE;}
|
"false" {yylval.value = new Node(VALUE, std::unique_ptr<Value>(make_false()), ""); return VALUE;}
|
||||||
\".*\" {yylval.value = new Node(VALUE, make_string(substring(yytext, 1, strlen(yytext) - 1)), ""); return VALUE; }
|
\".*\" {yylval.value = new Node(VALUE, std::unique_ptr<Value>(make_string(substring(yytext, 1, strlen(yytext) - 1))), ""); return VALUE; }
|
||||||
{DIGIT} {std::vector<long> nums; nums.push_back(atoi(yytext)); yylval.value = new Node(VALUE, make_long(nums), ""); return VALUE;}
|
{DIGIT} {std::vector<long> nums; nums.push_back(atoi(yytext)); yylval.value = new Node(VALUE, std::unique_ptr<Value>(make_long(nums)), ""); return VALUE;}
|
||||||
{DIGIT}*"."?{DIGIT}+ {std::vector<double> decs; decs.push_back(atof(yytext)); yylval.value = new Node(VALUE, make_double(decs), ""); return VALUE;}
|
{DIGIT}*"."?{DIGIT}+ {std::vector<double> decs; decs.push_back(atof(yytext)); yylval.value = new Node(VALUE, std::unique_ptr<Value>(make_double(decs)), ""); return VALUE;}
|
||||||
[_a-zA-Z][_a-zA-Z0-9]* {yylval.value = new Node(IDENTIFIER, nullptr, strdup(yytext)); return IDENTIFIER;}
|
[_a-zA-Z][_a-zA-Z0-9]* {yylval.value = new Node(IDENTIFIER, std::unique_ptr<Value>(nullptr), yytext); return IDENTIFIER;}
|
||||||
[\n] {linenum++;}
|
[\n] {linenum++;}
|
||||||
[ \t\r]+ {}
|
[ \t\r]+ {}
|
||||||
. {printf("Error: invlaid lexeme '%s'.\n", yytext); return 0;}
|
. {printf("Error: invlaid lexeme '%s'.\n", yytext); return 0;}
|
||||||
|
|
|
@ -21,7 +21,7 @@ void add_variable(Environment* env, Variable* var) {
|
||||||
// If variable exists, replace it
|
// If variable exists, replace it
|
||||||
Variable* temp_var = find_variable(env, var->id);
|
Variable* temp_var = find_variable(env, var->id);
|
||||||
if (temp_var != nullptr) {
|
if (temp_var != nullptr) {
|
||||||
temp_var->value = var->value;
|
temp_var->value = std::unique_ptr<Value>(new Value(*var->value));
|
||||||
free(var);
|
free(var);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,12 +2,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "variable.hpp"
|
#include "variable.hpp"
|
||||||
|
|
||||||
void set_value(Variable* var, Value* value) {
|
|
||||||
if (!var) { std::cerr << "Error: Invalid Variable" << std::endl; return; }
|
|
||||||
var->value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
Value* get_value(const Variable* var) {
|
Value* get_value(const Variable* var) {
|
||||||
if (!var) { std::cerr << "Error: Invalid Variable" << std::endl; return 0; }
|
if (!var) { std::cerr << "Error: Invalid Variable" << std::endl; return 0; }
|
||||||
return var->value;
|
return new Value(*var->value);
|
||||||
}
|
}
|
|
@ -2,6 +2,7 @@
|
||||||
#define VARIABLE_H
|
#define VARIABLE_H
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <memory>
|
||||||
#include "../variables/value.hpp"
|
#include "../variables/value.hpp"
|
||||||
|
|
||||||
class Value;
|
class Value;
|
||||||
|
@ -10,19 +11,17 @@ class Node;
|
||||||
class Variable {
|
class Variable {
|
||||||
public:
|
public:
|
||||||
std::string id;
|
std::string id;
|
||||||
Value* value;
|
std::unique_ptr<Value> value;
|
||||||
|
|
||||||
Variable(std::string s, Value* val) {
|
Variable(std::string s, Value* val) : value(std::move(val)) {
|
||||||
id = s;
|
id = s;
|
||||||
value = val;
|
|
||||||
}
|
}
|
||||||
~Variable() {
|
~Variable() {
|
||||||
delete value;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Variable Functions
|
// Variable Functions
|
||||||
void set_value(Variable* var, Value* value);
|
|
||||||
Value* get_value(const Variable* var);
|
Value* get_value(const Variable* var);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Reference in a new issue