From efc49584ee3e647507eb593fb4d670addd814024 Mon Sep 17 00:00:00 2001 From: Brandon Rozek Date: Mon, 1 Oct 2018 00:08:24 -0400 Subject: [PATCH] Started using unique_ptr Nodes and variables now contain unique references to Values --- src/operations/node.cpp | 10 +++++++-- src/operations/node.hpp | 12 ++++------- src/operations/operators.cpp | 38 +++++++++++++++++++++++++++++++++++ src/parser/lexer.l | 12 +++++------ src/variables/environment.cpp | 2 +- src/variables/variable.cpp | 7 +------ src/variables/variable.hpp | 9 ++++----- 7 files changed, 62 insertions(+), 28 deletions(-) diff --git a/src/operations/node.cpp b/src/operations/node.cpp index 426da01..edd66db 100644 --- a/src/operations/node.cpp +++ b/src/operations/node.cpp @@ -215,7 +215,7 @@ Value* eval_expression(Node* node, Environment* env) { return 0; } // Change to return copy of value [TODO] - return new Value(*get_value(var)); + return get_value(var); break; //---------- case VALUE: @@ -256,6 +256,7 @@ void eval_statement(Node* node, Environment* env) { tempVal = eval_expression(node->children[0], env); if (tempVal->type == BOOLEAN) { 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[0]) { eval_statement(node->children[1], env); @@ -272,11 +273,13 @@ void eval_statement(Node* node, Environment* env) { tempVal = eval_expression(node->children[0], env); if (tempVal->type == BOOLEAN) { 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;} while (tempLong[0]) { eval_statement(node->children[1], env); tempVal = eval_expression(node->children[0], env); 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;} } } 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."); tempVal = eval_expression(node->children[0], env); std::cout << tempVal << std::endl; + delete tempVal; break; //------------ case STATEMENT: // Can have a maximum of two children statement nodes @@ -302,6 +306,8 @@ void eval_statement(Node* node, Environment* env) { //------------ default: printf("Error, %d not a valid statement type.\n", node->type); - return; + } + + return; } diff --git a/src/operations/node.hpp b/src/operations/node.hpp index 1773c9b..6da0660 100644 --- a/src/operations/node.hpp +++ b/src/operations/node.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #include "../variables/value.hpp" #include "../variables/environment.hpp" @@ -16,7 +17,7 @@ class Environment; class Node { public: int type; - Value* value; + std::unique_ptr value; /* the id of the node (used for identifiers only) */ std::string id; @@ -29,17 +30,13 @@ class Node { std::string toString(void) const; - Node(int t, Value* v, std::string s) { + Node(int t, std::unique_ptr v, std::string s) : value(std::move(v)) { type = t; - value = v; id = s; num_children = 0; - for (uint i = 0; i < MAX_CHILDREN; i++) { - children[i] = nullptr; - } + std::fill(children.begin(), children.end(), nullptr); } ~Node() { - // delete value; for (uint i = 0; i < num_children; i++) { delete children[i]; } @@ -47,7 +44,6 @@ class Node { }; // Abstract Syntax Tree Functions -// struct Node* make_node(int type, struct Value* value, std::string id); void attach_node(Node* parent, Node* child); std::string tree_string(const Node* node, uint tabs); diff --git a/src/operations/operators.cpp b/src/operations/operators.cpp index a26eace..59337d8 100644 --- a/src/operations/operators.cpp +++ b/src/operations/operators.cpp @@ -49,6 +49,9 @@ Value* add(Value* x, Value* y) { ans = make_double(doubleResult); } + delete x; + delete y; + return ans; } @@ -92,6 +95,9 @@ Value* subtract(Value* x, Value* y) { ans = make_double(doubleResult); } + delete x; + delete y; + return ans; } @@ -135,6 +141,9 @@ Value* division(Value* x, Value* y) { ans = make_double(doubleResult); } + delete x; + delete y; + return ans; } @@ -178,6 +187,9 @@ Value* multiplication(Value* x, Value* y) { ans = make_double(doubleResult); } + delete x; + delete y; + return ans; } @@ -224,6 +236,9 @@ Value* less(Value* x, Value* y) { ans = make_booleans(longResult); } + delete x; + delete y; + return ans; } @@ -270,6 +285,9 @@ Value* greater(Value* x, Value* y) { ans = make_booleans(longResult); } + delete x; + delete y; + return ans; } @@ -316,6 +334,9 @@ Value* less_equal(Value* x, Value* y) { ans = make_booleans(longResult); } + delete x; + delete y; + return ans; } @@ -362,6 +383,9 @@ Value* greater_equal(Value* x, Value* y) { ans = make_booleans(longResult); } + delete x; + delete y; + return ans; } @@ -407,6 +431,9 @@ Value* equals(Value* x, Value* y) { ans = make_booleans(longResult); } + delete x; + delete y; + return ans; } @@ -452,6 +479,9 @@ Value* not_equals(Value* x, Value* y) { ans = make_booleans(longResult); } + delete x; + delete y; + 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::back_inserter(longResult), std::logical_and<>()); + delete x; + delete y; + 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::back_inserter(longResult), std::logical_or<>()); + delete x; + delete y; + return make_booleans(longResult); } @@ -489,5 +525,7 @@ Value* not_value(Value* x) { std::vector x_long = get_long(x); std::transform(x_long.begin(), x_long.end(), std::back_inserter(longResult), std::logical_not<>()); + delete x; + return make_booleans(longResult); } diff --git a/src/parser/lexer.l b/src/parser/lexer.l index a5578fa..ef87709 100644 --- a/src/parser/lexer.l +++ b/src/parser/lexer.l @@ -46,12 +46,12 @@ DIGIT [0-9] "input" {return INPUT;} "lambda" {return LAMBDATAG;} ":" {return COLON;} -"true" {yylval.value = new Node(VALUE, make_true(), ""); return VALUE;} -"false" {yylval.value = new Node(VALUE, make_false(), ""); return VALUE;} -\".*\" {yylval.value = new Node(VALUE, make_string(substring(yytext, 1, strlen(yytext) - 1)), ""); return VALUE; } -{DIGIT} {std::vector nums; nums.push_back(atoi(yytext)); yylval.value = new Node(VALUE, make_long(nums), ""); return VALUE;} -{DIGIT}*"."?{DIGIT}+ {std::vector decs; decs.push_back(atof(yytext)); yylval.value = new Node(VALUE, make_double(decs), ""); return VALUE;} -[_a-zA-Z][_a-zA-Z0-9]* {yylval.value = new Node(IDENTIFIER, nullptr, strdup(yytext)); return IDENTIFIER;} +"true" {yylval.value = new Node(VALUE, std::unique_ptr(make_true()), ""); return VALUE;} +"false" {yylval.value = new Node(VALUE, std::unique_ptr(make_false()), ""); return VALUE;} +\".*\" {yylval.value = new Node(VALUE, std::unique_ptr(make_string(substring(yytext, 1, strlen(yytext) - 1))), ""); return VALUE; } +{DIGIT} {std::vector nums; nums.push_back(atoi(yytext)); yylval.value = new Node(VALUE, std::unique_ptr(make_long(nums)), ""); return VALUE;} +{DIGIT}*"."?{DIGIT}+ {std::vector decs; decs.push_back(atof(yytext)); yylval.value = new Node(VALUE, std::unique_ptr(make_double(decs)), ""); return VALUE;} +[_a-zA-Z][_a-zA-Z0-9]* {yylval.value = new Node(IDENTIFIER, std::unique_ptr(nullptr), yytext); return IDENTIFIER;} [\n] {linenum++;} [ \t\r]+ {} . {printf("Error: invlaid lexeme '%s'.\n", yytext); return 0;} diff --git a/src/variables/environment.cpp b/src/variables/environment.cpp index 6f6c8c6..ac9fd7b 100644 --- a/src/variables/environment.cpp +++ b/src/variables/environment.cpp @@ -21,7 +21,7 @@ void add_variable(Environment* env, Variable* var) { // If variable exists, replace it Variable* temp_var = find_variable(env, var->id); if (temp_var != nullptr) { - temp_var->value = var->value; + temp_var->value = std::unique_ptr(new Value(*var->value)); free(var); return; } diff --git a/src/variables/variable.cpp b/src/variables/variable.cpp index d8afe10..0e8bd77 100644 --- a/src/variables/variable.cpp +++ b/src/variables/variable.cpp @@ -2,12 +2,7 @@ #include #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) { if (!var) { std::cerr << "Error: Invalid Variable" << std::endl; return 0; } - return var->value; + return new Value(*var->value); } \ No newline at end of file diff --git a/src/variables/variable.hpp b/src/variables/variable.hpp index fc19077..1b35c24 100644 --- a/src/variables/variable.hpp +++ b/src/variables/variable.hpp @@ -2,6 +2,7 @@ #define VARIABLE_H #include +#include #include "../variables/value.hpp" class Value; @@ -10,19 +11,17 @@ class Node; class Variable { public: std::string id; - Value* value; + std::unique_ptr value; - Variable(std::string s, Value* val) { + Variable(std::string s, Value* val) : value(std::move(val)) { id = s; - value = val; } ~Variable() { - delete value; + } }; // Variable Functions -void set_value(Variable* var, Value* value); Value* get_value(const Variable* var); #endif