From cdbafe8d0dfa5976218ee7c324b8300095e27184 Mon Sep 17 00:00:00 2001 From: Brandon Rozek Date: Sat, 29 Sep 2018 12:23:36 -0400 Subject: [PATCH] Made numeric types vector based --- src/operations/node.cpp | 17 +- src/operations/operators.cpp | 346 ++++++++++++++++++++++++++++------ src/parser/lexer.l | 7 +- src/variables/environment.hpp | 8 +- src/variables/value.cpp | 92 +++++++-- src/variables/value.hpp | 36 +++- 6 files changed, 405 insertions(+), 101 deletions(-) diff --git a/src/operations/node.cpp b/src/operations/node.cpp index 04ec804..75f7d1b 100644 --- a/src/operations/node.cpp +++ b/src/operations/node.cpp @@ -90,6 +90,7 @@ Value* eval_expression(Node* node, Environment* env) { // Needed if we are going to take input from the user double temp; + std::vector tempDecs; Variable* var = nullptr; Environment* local_env = nullptr; Node* tempNode = nullptr; @@ -118,7 +119,7 @@ Value* eval_expression(Node* node, Environment* env) { add_variable(local_env, new Variable(tempNode->children[0]->id, // Get the name of the variable needed for the lambda expression eval_expression(node->children[1], env))); - tempVal = eval_expression(tempNode->children[1], local_env); + tempVal = eval_expression(tempNode->children[1], local_env); delete local_env; return tempVal; break; @@ -203,7 +204,8 @@ Value* eval_expression(Node* node, Environment* env) { //---------- case INPUT: // We're only going to support reading in doubles scanf("%lf", &temp); - return make_double(temp); + tempDecs.push_back(temp); + return make_double(tempDecs); break; //---------- case IDENTIFIER: @@ -235,6 +237,7 @@ void eval_statement(Node* node, Environment* env) { } Value* tempVal; + std::vector tempLong; switch(node->type) { case ASSIGN: @@ -250,7 +253,9 @@ void eval_statement(Node* node, Environment* env) { } tempVal = eval_expression(node->children[0], env); if (tempVal->type == BOOLEAN) { - if (get_long(tempVal)) { + tempLong = get_long(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); } else if (node->num_children == 3) { eval_statement(node->children[2], env); @@ -264,9 +269,13 @@ void eval_statement(Node* node, Environment* env) { check_num_nodes(node, 2, "the format of a while statement is: while expression statement(s)"); tempVal = eval_expression(node->children[0], env); if (tempVal->type == BOOLEAN) { - while (get_long(tempVal)) { + tempLong = get_long(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); + if (tempLong.size() > 1) { std::cerr << "Cannot have a vector of booleans for your while expression" << std::endl; break;} } } else { fprintf(stderr, "Error, a non-boolean was in the condition of the while loop.\n"); diff --git a/src/operations/operators.cpp b/src/operations/operators.cpp index 251335f..a26eace 100644 --- a/src/operations/operators.cpp +++ b/src/operations/operators.cpp @@ -1,7 +1,10 @@ #include +#include #include "operators.hpp" #include "../variables/value.hpp" +// TODO: Now replace every single operation with vector equivalent + Value* add(Value* x, Value* y) { if (!x || !y) { std::cerr << "Error, uninitialized values being used in add." << std::endl; } if (x->type == BOOLEAN || y->type == BOOLEAN) { std::cerr << "Error, cannot add a boolean." << std::endl; } @@ -10,18 +13,40 @@ Value* add(Value* x, Value* y) { } Value* ans; + std::vector longResult; + std::vector doubleResult; // Destruct all four cases if (x->type == LONG && y->type == LONG) { - ans = make_long(get_long(x) + get_long(y)); + std::vector x_long = get_long(x); + std::vector y_long = get_long(y); + longResult.reserve(x_long.size()); + std::transform(x_long.begin(), x_long.end(), y_long.begin(), + std::back_inserter(longResult), std::plus()); + ans = make_long(longResult); } else if (x->type == LONG && y->type == DOUBLE) { - ans = make_double(get_long(x) + get_double(y)); + std::vector x_long = get_long(x); + std::vector y_double = get_double(y); + doubleResult.reserve(x_long.size()); + std::transform(x_long.begin(), x_long.end(), y_double.begin(), + std::back_inserter(doubleResult), std::plus<>()); + ans = make_double(doubleResult); } else if (x->type == DOUBLE && y->type == LONG) { - ans = make_double(get_double(x) + get_long(y)); + std::vector x_double = get_double(x); + std::vector y_long = get_long(y); + doubleResult.reserve(x_double.size()); + std::transform(x_double.begin(), x_double.end(), y_long.begin(), + std::back_inserter(doubleResult), std::plus<>()); + ans = make_double(doubleResult); } else if (x->type == STRING && y->type == STRING) { ans = make_string(get_string(x) + get_string(y)); } else { // Both are DOUBLE - ans = make_double(get_double(x) + get_double(y)); + std::vector x_double = get_double(x); + std::vector y_double = get_double(y); + doubleResult.reserve(x_double.size()); + std::transform(x_double.begin(), x_double.end(), y_double.begin(), + std::back_inserter(doubleResult), std::plus()); + ans = make_double(doubleResult); } return ans; @@ -33,16 +58,38 @@ Value* subtract(Value* x, Value* y) { if (x->type == STRING || y->type == STRING) { std::cerr << "Error, cannot subtract a string." << std::endl; } Value* ans; + std::vector longResult; + std::vector doubleResult; // Destruct all four cases if (x->type == LONG && y->type == LONG) { - ans = make_long(get_long(x) - get_long(y)); + std::vector x_long = get_long(x); + std::vector y_long = get_long(y); + longResult.reserve(x_long.size()); + std::transform(x_long.begin(), x_long.end(), y_long.begin(), + std::back_inserter(longResult), std::minus()); + ans = make_long(longResult); } else if (x->type == LONG && y->type == DOUBLE) { - ans = make_double(get_long(x) - get_double(y)); + std::vector x_long = get_long(x); + std::vector y_double = get_double(y); + doubleResult.reserve(x_long.size()); + std::transform(x_long.begin(), x_long.end(), y_double.begin(), + std::back_inserter(doubleResult), std::minus<>()); + ans = make_double(doubleResult); } else if (x->type == DOUBLE && y->type == LONG) { - ans = make_double(get_double(x) - get_long(y)); + std::vector x_double = get_double(x); + std::vector y_long = get_long(y); + doubleResult.reserve(x_double.size()); + std::transform(x_double.begin(), x_double.end(), y_long.begin(), + std::back_inserter(doubleResult), std::minus<>()); + ans = make_double(doubleResult); } else { // Both are DOUBLE - ans = make_double(get_double(x) - get_double(y)); + std::vector x_double = get_double(x); + std::vector y_double = get_double(y); + doubleResult.reserve(x_double.size()); + std::transform(x_double.begin(), x_double.end(), y_double.begin(), + std::back_inserter(doubleResult), std::minus()); + ans = make_double(doubleResult); } return ans; @@ -54,16 +101,38 @@ Value* division(Value* x, Value* y) { if (x->type == STRING || y->type == STRING) { std::cerr << "Error, cannot division a string." << std::endl; } Value* ans; + std::vector longResult; + std::vector doubleResult; // Destruct all four cases if (x->type == LONG && y->type == LONG) { - ans = make_long(get_long(x) / get_long(y)); + std::vector x_long = get_long(x); + std::vector y_long = get_long(y); + longResult.reserve(x_long.size()); + std::transform(x_long.begin(), x_long.end(), y_long.begin(), + std::back_inserter(longResult), std::divides()); + ans = make_long(longResult); } else if (x->type == LONG && y->type == DOUBLE) { - ans = make_double(get_long(x) / get_double(y)); + std::vector x_long = get_long(x); + std::vector y_double = get_double(y); + doubleResult.reserve(x_long.size()); + std::transform(x_long.begin(), x_long.end(), y_double.begin(), + std::back_inserter(doubleResult), std::divides<>()); + ans = make_double(doubleResult); } else if (x->type == DOUBLE && y->type == LONG) { - ans = make_double(get_double(x) / get_long(y)); + std::vector x_double = get_double(x); + std::vector y_long = get_long(y); + doubleResult.reserve(x_double.size()); + std::transform(x_double.begin(), x_double.end(), y_long.begin(), + std::back_inserter(doubleResult), std::divides<>()); + ans = make_double(doubleResult); } else { // Both are DOUBLE - ans = make_double(get_double(x) / get_double(y)); + std::vector x_double = get_double(x); + std::vector y_double = get_double(y); + doubleResult.reserve(x_double.size()); + std::transform(x_double.begin(), x_double.end(), y_double.begin(), + std::back_inserter(doubleResult), std::divides()); + ans = make_double(doubleResult); } return ans; @@ -75,16 +144,38 @@ Value* multiplication(Value* x, Value* y) { if (x->type == STRING || y->type == STRING) { std::cerr << "Error, cannot multiply a string." << std::endl; } Value* ans; + std::vector longResult; + std::vector doubleResult; // Destruct all four cases if (x->type == LONG && y->type == LONG) { - ans = make_long(get_long(x) * get_long(y)); + std::vector x_long = get_long(x); + std::vector y_long = get_long(y); + longResult.reserve(x_long.size()); + std::transform(x_long.begin(), x_long.end(), y_long.begin(), + std::back_inserter(longResult), std::multiplies()); + ans = make_long(longResult); } else if (x->type == LONG && y->type == DOUBLE) { - ans = make_double(get_long(x) * get_double(y)); + std::vector x_long = get_long(x); + std::vector y_double = get_double(y); + doubleResult.reserve(x_long.size()); + std::transform(x_long.begin(), x_long.end(), y_double.begin(), + std::back_inserter(doubleResult), std::multiplies<>()); + ans = make_double(doubleResult); } else if (x->type == DOUBLE && y->type == LONG) { - ans = make_double(get_double(x) * get_long(y)); + std::vector x_double = get_double(x); + std::vector y_long = get_long(y); + doubleResult.reserve(x_double.size()); + std::transform(x_double.begin(), x_double.end(), y_long.begin(), + std::back_inserter(doubleResult), std::multiplies<>()); + ans = make_double(doubleResult); } else { // Both are DOUBLE - ans = make_double(get_double(x) * get_double(y)); + std::vector x_double = get_double(x); + std::vector y_double = get_double(y); + doubleResult.reserve(x_double.size()); + std::transform(x_double.begin(), x_double.end(), y_double.begin(), + std::back_inserter(doubleResult), std::multiplies()); + ans = make_double(doubleResult); } return ans; @@ -98,18 +189,39 @@ Value* less(Value* x, Value* y) { } Value* ans; + std::vector longResult; // Destruct all four cases if (x->type == LONG && y->type == LONG) { - ans = make_boolean(get_long(x) < get_long(y)); + std::vector x_long = get_long(x); + std::vector y_long = get_long(y); + longResult.reserve(x_long.size()); + std::transform(x_long.begin(), x_long.end(), y_long.begin(), + std::back_inserter(longResult), std::less()); + ans = make_booleans(longResult); } else if (x->type == LONG && y->type == DOUBLE) { - ans = make_boolean(get_long(x) < get_double(y)); + std::vector x_long = get_long(x); + std::vector y_double = get_double(y); + longResult.reserve(x_long.size()); + std::transform(x_long.begin(), x_long.end(), y_double.begin(), + std::back_inserter(longResult), std::less<>()); + ans = make_booleans(longResult); } else if (x->type == DOUBLE && y->type == LONG) { - ans = make_boolean(get_double(x) < get_long(y)); + std::vector x_double = get_double(x); + std::vector y_long = get_long(y); + longResult.reserve(x_double.size()); + std::transform(x_double.begin(), x_double.end(), y_long.begin(), + std::back_inserter(longResult), std::less<>()); + ans = make_booleans(longResult); } else if (x->type == STRING && y->type == STRING) { - ans = make_boolean(get_string(x).compare(get_string(y)) < 0); + ans = make_boolean(get_string(x).compare(get_string(y)) < 0); } else { // Both are DOUBLE - ans = make_boolean(get_double(x) < get_double(y)); + std::vector x_double = get_double(x); + std::vector y_double = get_double(y); + longResult.reserve(x_double.size()); + std::transform(x_double.begin(), x_double.end(), y_double.begin(), + std::back_inserter(longResult), std::less()); + ans = make_booleans(longResult); } return ans; @@ -123,18 +235,39 @@ Value* greater(Value* x, Value* y) { } Value* ans; + std::vector longResult; // Destruct all four cases if (x->type == LONG && y->type == LONG) { - ans = make_boolean(get_long(x) > get_long(y)); + std::vector x_long = get_long(x); + std::vector y_long = get_long(y); + longResult.reserve(x_long.size()); + std::transform(x_long.begin(), x_long.end(), y_long.begin(), + std::back_inserter(longResult), std::greater()); + ans = make_booleans(longResult); } else if (x->type == LONG && y->type == DOUBLE) { - ans = make_boolean(get_long(x) > get_double(y)); + std::vector x_long = get_long(x); + std::vector y_double = get_double(y); + longResult.reserve(x_long.size()); + std::transform(x_long.begin(), x_long.end(), y_double.begin(), + std::back_inserter(longResult), std::greater<>()); + ans = make_booleans(longResult); } else if (x->type == DOUBLE && y->type == LONG) { - ans = make_boolean(get_double(x) > get_long(y)); + std::vector x_double = get_double(x); + std::vector y_long = get_long(y); + longResult.reserve(x_double.size()); + std::transform(x_double.begin(), x_double.end(), y_long.begin(), + std::back_inserter(longResult), std::greater<>()); + ans = make_booleans(longResult); } else if (x->type == STRING && y->type == STRING) { - ans = make_boolean(get_string(x).compare(get_string(y)) > 0); + ans = make_boolean(get_string(x).compare(get_string(y)) > 0); } else { // Both are DOUBLE - ans = make_boolean(get_double(x) > get_double(y)); + std::vector x_double = get_double(x); + std::vector y_double = get_double(y); + longResult.reserve(x_double.size()); + std::transform(x_double.begin(), x_double.end(), y_double.begin(), + std::back_inserter(longResult), std::greater()); + ans = make_booleans(longResult); } return ans; @@ -148,18 +281,39 @@ Value* less_equal(Value* x, Value* y) { } Value* ans; + std::vector longResult; // Destruct all four cases if (x->type == LONG && y->type == LONG) { - ans = make_boolean(get_long(x) <= get_long(y)); + std::vector x_long = get_long(x); + std::vector y_long = get_long(y); + longResult.reserve(x_long.size()); + std::transform(x_long.begin(), x_long.end(), y_long.begin(), + std::back_inserter(longResult), std::less_equal()); + ans = make_booleans(longResult); } else if (x->type == LONG && y->type == DOUBLE) { - ans = make_boolean(get_long(x) <= get_double(y)); + std::vector x_long = get_long(x); + std::vector y_double = get_double(y); + longResult.reserve(x_long.size()); + std::transform(x_long.begin(), x_long.end(), y_double.begin(), + std::back_inserter(longResult), std::less_equal<>()); + ans = make_booleans(longResult); } else if (x->type == DOUBLE && y->type == LONG) { - ans = make_boolean(get_double(x) <= get_long(y)); + std::vector x_double = get_double(x); + std::vector y_long = get_long(y); + longResult.reserve(x_double.size()); + std::transform(x_double.begin(), x_double.end(), y_long.begin(), + std::back_inserter(longResult), std::less_equal<>()); + ans = make_booleans(longResult); } else if (x->type == STRING && y->type == STRING) { - ans = make_boolean(get_string(x).compare(get_string(y)) <= 0); + ans = make_boolean(get_string(x).compare(get_string(y)) <= 0); } else { // Both are DOUBLE - ans = make_boolean(get_double(x) <= get_double(y)); + std::vector x_double = get_double(x); + std::vector y_double = get_double(y); + longResult.reserve(x_double.size()); + std::transform(x_double.begin(), x_double.end(), y_double.begin(), + std::back_inserter(longResult), std::less_equal()); + ans = make_booleans(longResult); } return ans; @@ -173,18 +327,39 @@ Value* greater_equal(Value* x, Value* y) { } Value* ans; + std::vector longResult; // Destruct all four cases if (x->type == LONG && y->type == LONG) { - ans = make_boolean(get_long(x) >= get_long(y)); + std::vector x_long = get_long(x); + std::vector y_long = get_long(y); + longResult.reserve(x_long.size()); + std::transform(x_long.begin(), x_long.end(), y_long.begin(), + std::back_inserter(longResult), std::greater_equal()); + ans = make_booleans(longResult); } else if (x->type == LONG && y->type == DOUBLE) { - ans = make_boolean(get_long(x) >= get_double(y)); + std::vector x_long = get_long(x); + std::vector y_double = get_double(y); + longResult.reserve(x_long.size()); + std::transform(x_long.begin(), x_long.end(), y_double.begin(), + std::back_inserter(longResult), std::greater_equal<>()); + ans = make_booleans(longResult); } else if (x->type == DOUBLE && y->type == LONG) { - ans = make_boolean(get_double(x) >= get_long(y)); + std::vector x_double = get_double(x); + std::vector y_long = get_long(y); + longResult.reserve(x_double.size()); + std::transform(x_double.begin(), x_double.end(), y_long.begin(), + std::back_inserter(longResult), std::greater_equal<>()); + ans = make_booleans(longResult); } else if (x->type == STRING && y->type == STRING) { - ans = make_boolean(get_string(x).compare(get_string(y)) >= 0); + ans = make_boolean(get_string(x).compare(get_string(y)) >= 0); } else { // Both are DOUBLE - ans = make_boolean(get_double(x) >= get_double(y)); + std::vector x_double = get_double(x); + std::vector y_double = get_double(y); + longResult.reserve(x_double.size()); + std::transform(x_double.begin(), x_double.end(), y_double.begin(), + std::back_inserter(longResult), std::greater_equal()); + ans = make_booleans(longResult); } return ans; @@ -197,22 +372,39 @@ Value* equals(Value* x, Value* y) { } Value* ans = nullptr; + std::vector longResult; // Destruct all four cases if (x->type == LONG && y->type == LONG) { - ans = make_boolean(get_long(x) == get_long(y)); + std::vector x_long = get_long(x); + std::vector y_long = get_long(y); + longResult.reserve(x_long.size()); + std::transform(x_long.begin(), x_long.end(), y_long.begin(), + std::back_inserter(longResult), std::equal_to()); + ans = make_booleans(longResult); } else if (x->type == LONG && y->type == DOUBLE) { - ans = make_boolean(get_long(x) == get_double(y)); + std::vector x_long = get_long(x); + std::vector y_double = get_double(y); + longResult.reserve(x_long.size()); + std::transform(x_long.begin(), x_long.end(), y_double.begin(), + std::back_inserter(longResult), std::equal_to<>()); + ans = make_booleans(longResult); } else if (x->type == DOUBLE && y->type == LONG) { - ans = make_boolean(get_double(x) == get_long(y)); - } else if (x->type == DOUBLE && y->type == DOUBLE) { - ans = make_boolean(get_double(x) == get_double(y)); - } else if (x->type == BOOLEAN && y->type == BOOLEAN) { - ans = make_boolean(get_long(x) == get_long(y)); + std::vector x_double = get_double(x); + std::vector y_long = get_long(y); + longResult.reserve(x_double.size()); + std::transform(x_double.begin(), x_double.end(), y_long.begin(), + std::back_inserter(longResult), std::equal_to<>()); + ans = make_booleans(longResult); } else if (x->type == STRING && y->type == STRING) { - ans = make_boolean(get_string(x).compare(get_string(y)) == 0); - } else { // Type is a mix between boolean and another type - std::cerr << "Error, cannot compare a boolean with another type." << std::endl; + ans = make_boolean(get_string(x).compare(get_string(y)) == 0); + } else { // Both are DOUBLE + std::vector x_double = get_double(x); + std::vector y_double = get_double(y); + longResult.reserve(x_double.size()); + std::transform(x_double.begin(), x_double.end(), y_double.begin(), + std::back_inserter(longResult), std::equal_to()); + ans = make_booleans(longResult); } return ans; @@ -225,22 +417,39 @@ Value* not_equals(Value* x, Value* y) { } Value* ans= nullptr; + std::vector longResult; // Destruct all four cases if (x->type == LONG && y->type == LONG) { - ans = make_boolean(get_long(x) != get_long(y)); + std::vector x_long = get_long(x); + std::vector y_long = get_long(y); + longResult.reserve(x_long.size()); + std::transform(x_long.begin(), x_long.end(), y_long.begin(), + std::back_inserter(longResult), std::not_equal_to()); + ans = make_booleans(longResult); } else if (x->type == LONG && y->type == DOUBLE) { - ans = make_boolean(get_long(x) != get_double(y)); + std::vector x_long = get_long(x); + std::vector y_double = get_double(y); + longResult.reserve(x_long.size()); + std::transform(x_long.begin(), x_long.end(), y_double.begin(), + std::back_inserter(longResult), std::not_equal_to<>()); + ans = make_booleans(longResult); } else if (x->type == DOUBLE && y->type == LONG) { - ans = make_boolean(get_double(x) != get_long(y)); - } else if (x->type == DOUBLE && y->type == DOUBLE) { - ans = make_boolean(get_double(x) != get_double(y)); - } else if (x->type == BOOLEAN && y->type == BOOLEAN) { - ans = make_boolean(get_long(x) != get_long(y)); + std::vector x_double = get_double(x); + std::vector y_long = get_long(y); + longResult.reserve(x_double.size()); + std::transform(x_double.begin(), x_double.end(), y_long.begin(), + std::back_inserter(longResult), std::not_equal_to<>()); + ans = make_booleans(longResult); } else if (x->type == STRING && y->type == STRING) { - ans = make_boolean(get_string(x).compare(get_string(y)) != 0); - } else { // Type is a mix between boolean and another type - std::cerr << "Error, cannot compare a boolean with another type." << std::endl; + ans = make_boolean(get_string(x).compare(get_string(y)) != 0); + } else { // Both are DOUBLE + std::vector x_double = get_double(x); + std::vector y_double = get_double(y); + longResult.reserve(x_double.size()); + std::transform(x_double.begin(), x_double.end(), y_double.begin(), + std::back_inserter(longResult), std::not_equal_to()); + ans = make_booleans(longResult); } return ans; @@ -249,23 +458,36 @@ Value* not_equals(Value* x, Value* y) { Value* and_value(Value* x, Value* y) { if (!x || !y) { std::cerr << "Error, uninitialized values being used in &&." << std::endl; } if (x->type != BOOLEAN || y->type != BOOLEAN) { std::cerr << "Error, cannot use and AND operation with a non-boolean." << std::endl; } - if (x->type == STRING || y->type == STRING) { std::cerr << "Error, cannot AND a string." << std::endl; } + + std::vector longResult; + std::vector x_long = get_long(x); + std::vector y_long = get_long(y); + std::transform(x_long.begin(), x_long.end(), y_long.begin(), + std::back_inserter(longResult), std::logical_and<>()); - return make_boolean(get_long(x) && get_long(y)); + return make_booleans(longResult); } Value* or_value(Value* x, Value* y) { if (!x || !y) { std::cerr << "Error, uninitialized values being used in ||." << std::endl; } if (x->type != BOOLEAN || y->type != BOOLEAN) { std::cerr << "Error, cannot use and OR operation with a non-boolean." << std::endl; } - if (x->type == STRING || y->type == STRING) { std::cerr << "Error, cannot OR a string." << std::endl; } - return make_boolean(get_long(x) || get_long(y)); + std::vector longResult; + std::vector x_long = get_long(x); + std::vector y_long = get_long(y); + std::transform(x_long.begin(), x_long.end(), y_long.begin(), + std::back_inserter(longResult), std::logical_or<>()); + + return make_booleans(longResult); } Value* not_value(Value* x) { if (!x) { std::cerr << "Error, uninitialized values being used in !." << std::endl; } if (x->type != BOOLEAN) { std::cerr << "Error, cannot NOT a non-boolean." << std::endl; } - if (x->type == STRING) { std::cerr << "Error, cannot negate a string." << std::endl; } - return make_boolean(!get_long(x)); + std::vector longResult; + std::vector x_long = get_long(x); + std::transform(x_long.begin(), x_long.end(), std::back_inserter(longResult), std::logical_not<>()); + + return make_booleans(longResult); } diff --git a/src/parser/lexer.l b/src/parser/lexer.l index e91c68d..a5578fa 100644 --- a/src/parser/lexer.l +++ b/src/parser/lexer.l @@ -1,6 +1,7 @@ %{ #include #include +#include #include "../operations/node.hpp" #include "../variables/value.hpp" #include "parser.tab.h" @@ -21,6 +22,8 @@ DIGIT [0-9] "!" {return NOT;} "(" {return OPENPAREM;} ")" {return ENDPAREM;} +"[" {return OPENVECTOR;} +"]" {return CLOSEVECTOR;} ";" {return SEMICOLON;} %.*\n {} // Comments "<" {return LESS;} @@ -46,8 +49,8 @@ DIGIT [0-9] "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} {yylval.value = new Node(VALUE, make_long(atoi(yytext)), ""); return VALUE;} -{DIGIT}*"."?{DIGIT}+ {yylval.value = new Node(VALUE, make_double(atof(yytext)), ""); 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;} [\n] {linenum++;} [ \t\r]+ {} diff --git a/src/variables/environment.hpp b/src/variables/environment.hpp index fdeba84..ac035a4 100644 --- a/src/variables/environment.hpp +++ b/src/variables/environment.hpp @@ -12,9 +12,11 @@ class Environment { std::vector vars; Environment() { } ~Environment() { - for (uint i = 0; i < size(vars); i++) { - delete vars[i]; - } + // Currently this deletes the values of local environment which messes up + // double(double(5)) + // for (uint i = 0; i < size(vars); i++) { + // delete vars[i]; + // } } }; diff --git a/src/variables/value.cpp b/src/variables/value.cpp index cacf211..a7a521c 100644 --- a/src/variables/value.cpp +++ b/src/variables/value.cpp @@ -3,39 +3,62 @@ #include #include #include +#include #include "../parser/parser.tab.h" -Value* make_long(long num) { - return new Value(LONG, num, 0, nullptr, ""); +Value* make_long(std::vector nums) { + std::vector decs; + return new Value(LONG, nums, decs, nullptr, ""); } -Value* make_double(double dec) { - return new Value(DOUBLE, 0, dec, nullptr, ""); +Value* make_double(std::vector decs) { + std::vector nums; + return new Value(DOUBLE, nums, decs, nullptr, ""); } Value* make_true() { - return new Value(BOOLEAN, 1, 0, nullptr, ""); + std::vector nums = {1}; + std::vector decs; + return new Value(BOOLEAN, nums, decs, nullptr, ""); } Value* make_false() { - return new Value(BOOLEAN, 0, 0, nullptr, ""); + std::vector nums = {0}; + std::vector decs; + return new Value(BOOLEAN, nums, decs, nullptr, ""); } + Value* make_boolean(int x) { - return (x)? make_true() : make_false(); + return (x) ? make_true() : make_false(); +} + +Value* make_booleans(std::vector x) { + std::vector decs; + + std::vector result; + std::transform(x.begin(), x.end(), std::back_inserter(result), + [] (long n) { + return n != 0; + }); + return new Value(BOOLEAN, result, decs, nullptr, ""); } Value* make_expression(Node* expr) { - return new Value(LAMBDA, 0, 0, expr, ""); + std::vector nums; + std::vector decs; + return new Value(LAMBDA, nums, decs, expr, ""); } Value* make_string(std::string str) { - return new Value(STRING, 0, 0, nullptr, str); + std::vector nums; + std::vector decs; + return new Value(STRING, nums, decs, nullptr, str); } void delete_value(Value* val) { free(val); } -long get_long(const Value* val) { - return std::get(val->val); +std::vector get_long(const Value* val) { + return std::get>(val->val); } -double get_double(const Value* val) { - return std::get(val->val); +std::vector get_double(const Value* val) { + return std::get>(val->val); } Node* get_expression(const Value* val) { return std::get(val->val); @@ -44,11 +67,11 @@ std::string get_string(const Value* val) { return std::get(val->val); } -void set_long(Value* val, long num) { +void set_long(Value* val, std::vector num) { val->type = LONG; val->val = num; } -void set_double(Value* val, double dec) { +void set_double(Value* val, std::vector dec) { val->type = DOUBLE; // val->value.dec = dec; val->val = dec; @@ -65,17 +88,46 @@ void set_sring(Value* val, std::string str) { std::string Value::toString() const { std::string result = ""; if (this->type == BOOLEAN) { - if (get_long(this)) { - result += "true"; + std::vector longVec = get_long(this); + if (longVec.size() == 1) { + result += (longVec[0]) ? "true" : "false"; } else { - result += "false"; + result += "["; + for (uint i = 0; i < longVec.size() - 1; i++) { + result += (longVec[i]) ? "true" : "false"; + result += ", "; + } + result += (longVec[longVec.size() - 1]) ? "true" : "false"; + result += "]"; } } else if (this->type == LONG) { - result += get_long(this); + std::vector longVec = get_long(this); + if (longVec.size() == 1) { + result += std::to_string(longVec[0]); + } else { + result += "["; + for (uint i = 0; i < longVec.size() - 1; i++) { + result += std::to_string(longVec[i]); + result += ", "; + } + result += std::to_string(longVec[longVec.size() - 1]); + result += "]"; + } } else if (this->type == STRING) { result += get_string(this); } else if (this->type == DOUBLE) { - result += get_double(this); + std::vector longVec = get_double(this); + if (longVec.size() == 1) { + result += std::to_string(longVec[0]); + } else { + result += "["; + for (uint i = 0; i < longVec.size() - 1; i++) { + result += std::to_string(longVec[i]); + result += ", "; + } + result += std::to_string(longVec[longVec.size() - 1]); + result += "]"; + } } else { // Assume lambda expression result += ""; } diff --git a/src/variables/value.hpp b/src/variables/value.hpp index 063c417..f16d84c 100644 --- a/src/variables/value.hpp +++ b/src/variables/value.hpp @@ -5,6 +5,7 @@ #include #include #include +#include class Node; @@ -13,21 +14,21 @@ enum TypeTag { DOUBLE, LONG, BOOLEAN, STRING, LAMBDA }; class Value { public: enum TypeTag type; - std::variant val; + std::variant, std::vector, Node*, std::string> val; // << Overload friend std::ostream & operator << (std::ostream &out, const Value* val); std::string toString() const; // Constructor - Value(TypeTag t, long n, double d, Node* e, std::string s) { + Value(TypeTag t, std::vector ns, std::vector ds, Node* e, std::string s) { /* set properties */ type = t; if (type == LONG || type == BOOLEAN) { - val = n; + val = ns; } else if (type == DOUBLE){ // Assume DOUBLE - val = d; + val = ds; } else if (type == STRING) { val = s; } else { // Assume lambda expression @@ -35,6 +36,20 @@ class Value { } } + // Copy constructor + Value(const Value &v) { + type = v.type; + val = v.val; + } + + // // Copy when assigned + // Value operator = (const Value &v) { + // std::cout << "COPIED" << std::endl; + // type = v.type; + // val = v.val; + // return *this; + // } + // Destructor ~Value() { std::cout << "VALUE DESTROYED" << std::endl; @@ -42,11 +57,12 @@ class Value { }; // Constructors -Value* make_long(long num); -Value* make_double(double dec); +Value* make_long(std::vector num); +Value* make_double(std::vector dec); Value* make_true(); Value* make_false(); Value* make_boolean(int x); +Value* make_booleans(std::vector x); Value* make_expression(Node* expr); Value* make_string(std::string str); @@ -54,14 +70,14 @@ Value* make_string(std::string str); void delete_value(Value* val); // Getters -long get_long(const Value* val); -double get_double(const Value* val); +std::vector get_long(const Value* val); +std::vector get_double(const Value* val); Node* get_expression(const Value* val); std::string get_string(const Value* val); // Setters -void set_long(Value* val, long num); -void set_double(Value* val, double dec); +void set_long(Value* val, std::vector num); +void set_double(Value* val, std::vector dec); void set_expression(Value* val, Node* node); void set_string(Value* val, std::string str);