Archived
1
0
Fork 0

Made numeric types vector based

This commit is contained in:
Brandon Rozek 2018-09-29 12:23:36 -04:00
parent d486a64052
commit cdbafe8d0d
6 changed files with 405 additions and 101 deletions

View file

@ -90,6 +90,7 @@ Value* eval_expression(Node* node, Environment* env) {
// Needed if we are going to take input from the user // Needed if we are going to take input from the user
double temp; double temp;
std::vector<double> tempDecs;
Variable* var = nullptr; Variable* var = nullptr;
Environment* local_env = nullptr; Environment* local_env = nullptr;
Node* tempNode = nullptr; Node* tempNode = nullptr;
@ -203,7 +204,8 @@ Value* eval_expression(Node* node, Environment* env) {
//---------- //----------
case INPUT: // We're only going to support reading in doubles case INPUT: // We're only going to support reading in doubles
scanf("%lf", &temp); scanf("%lf", &temp);
return make_double(temp); tempDecs.push_back(temp);
return make_double(tempDecs);
break; break;
//---------- //----------
case IDENTIFIER: case IDENTIFIER:
@ -235,6 +237,7 @@ void eval_statement(Node* node, Environment* env) {
} }
Value* tempVal; Value* tempVal;
std::vector<long> tempLong;
switch(node->type) { switch(node->type) {
case ASSIGN: case ASSIGN:
@ -250,7 +253,9 @@ 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) {
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); eval_statement(node->children[1], env);
} else if (node->num_children == 3) { } else if (node->num_children == 3) {
eval_statement(node->children[2], env); 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)"); check_num_nodes(node, 2, "the format of a while statement is: while expression statement(s)");
tempVal = eval_expression(node->children[0], env); tempVal = eval_expression(node->children[0], env);
if (tempVal->type == BOOLEAN) { 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); eval_statement(node->children[1], env);
tempVal = eval_expression(node->children[0], 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 { } else {
fprintf(stderr, "Error, a non-boolean was in the condition of the while loop.\n"); fprintf(stderr, "Error, a non-boolean was in the condition of the while loop.\n");

View file

@ -1,7 +1,10 @@
#include <iostream> #include <iostream>
#include <algorithm>
#include "operators.hpp" #include "operators.hpp"
#include "../variables/value.hpp" #include "../variables/value.hpp"
// TODO: Now replace every single operation with vector equivalent
Value* add(Value* x, Value* y) { Value* add(Value* x, Value* y) {
if (!x || !y) { std::cerr << "Error, uninitialized values being used in add." << std::endl; } 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; } 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; Value* ans;
std::vector<long> longResult;
std::vector<double> doubleResult;
// Destruct all four cases // Destruct all four cases
if (x->type == LONG && y->type == LONG) { if (x->type == LONG && y->type == LONG) {
ans = make_long(get_long(x) + get_long(y)); std::vector<long> x_long = get_long(x);
std::vector<long> 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<long>());
ans = make_long(longResult);
} else if (x->type == LONG && y->type == DOUBLE) { } else if (x->type == LONG && y->type == DOUBLE) {
ans = make_double(get_long(x) + get_double(y)); std::vector<long> x_long = get_long(x);
std::vector<double> 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) { } else if (x->type == DOUBLE && y->type == LONG) {
ans = make_double(get_double(x) + get_long(y)); std::vector<double> x_double = get_double(x);
std::vector<long> 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) { } else if (x->type == STRING && y->type == STRING) {
ans = make_string(get_string(x) + get_string(y)); ans = make_string(get_string(x) + get_string(y));
} else { // Both are DOUBLE } else { // Both are DOUBLE
ans = make_double(get_double(x) + get_double(y)); std::vector<double> x_double = get_double(x);
std::vector<double> 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<double>());
ans = make_double(doubleResult);
} }
return ans; 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; } if (x->type == STRING || y->type == STRING) { std::cerr << "Error, cannot subtract a string." << std::endl; }
Value* ans; Value* ans;
std::vector<long> longResult;
std::vector<double> doubleResult;
// Destruct all four cases // Destruct all four cases
if (x->type == LONG && y->type == LONG) { if (x->type == LONG && y->type == LONG) {
ans = make_long(get_long(x) - get_long(y)); std::vector<long> x_long = get_long(x);
std::vector<long> 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<long>());
ans = make_long(longResult);
} else if (x->type == LONG && y->type == DOUBLE) { } else if (x->type == LONG && y->type == DOUBLE) {
ans = make_double(get_long(x) - get_double(y)); std::vector<long> x_long = get_long(x);
std::vector<double> 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) { } else if (x->type == DOUBLE && y->type == LONG) {
ans = make_double(get_double(x) - get_long(y)); std::vector<double> x_double = get_double(x);
std::vector<long> 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 } else { // Both are DOUBLE
ans = make_double(get_double(x) - get_double(y)); std::vector<double> x_double = get_double(x);
std::vector<double> 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<double>());
ans = make_double(doubleResult);
} }
return ans; 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; } if (x->type == STRING || y->type == STRING) { std::cerr << "Error, cannot division a string." << std::endl; }
Value* ans; Value* ans;
std::vector<long> longResult;
std::vector<double> doubleResult;
// Destruct all four cases // Destruct all four cases
if (x->type == LONG && y->type == LONG) { if (x->type == LONG && y->type == LONG) {
ans = make_long(get_long(x) / get_long(y)); std::vector<long> x_long = get_long(x);
std::vector<long> 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<long>());
ans = make_long(longResult);
} else if (x->type == LONG && y->type == DOUBLE) { } else if (x->type == LONG && y->type == DOUBLE) {
ans = make_double(get_long(x) / get_double(y)); std::vector<long> x_long = get_long(x);
std::vector<double> 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) { } else if (x->type == DOUBLE && y->type == LONG) {
ans = make_double(get_double(x) / get_long(y)); std::vector<double> x_double = get_double(x);
std::vector<long> 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 } else { // Both are DOUBLE
ans = make_double(get_double(x) / get_double(y)); std::vector<double> x_double = get_double(x);
std::vector<double> 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<double>());
ans = make_double(doubleResult);
} }
return ans; 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; } if (x->type == STRING || y->type == STRING) { std::cerr << "Error, cannot multiply a string." << std::endl; }
Value* ans; Value* ans;
std::vector<long> longResult;
std::vector<double> doubleResult;
// Destruct all four cases // Destruct all four cases
if (x->type == LONG && y->type == LONG) { if (x->type == LONG && y->type == LONG) {
ans = make_long(get_long(x) * get_long(y)); std::vector<long> x_long = get_long(x);
std::vector<long> 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<long>());
ans = make_long(longResult);
} else if (x->type == LONG && y->type == DOUBLE) { } else if (x->type == LONG && y->type == DOUBLE) {
ans = make_double(get_long(x) * get_double(y)); std::vector<long> x_long = get_long(x);
std::vector<double> 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) { } else if (x->type == DOUBLE && y->type == LONG) {
ans = make_double(get_double(x) * get_long(y)); std::vector<double> x_double = get_double(x);
std::vector<long> 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 } else { // Both are DOUBLE
ans = make_double(get_double(x) * get_double(y)); std::vector<double> x_double = get_double(x);
std::vector<double> 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<double>());
ans = make_double(doubleResult);
} }
return ans; return ans;
@ -98,18 +189,39 @@ Value* less(Value* x, Value* y) {
} }
Value* ans; Value* ans;
std::vector<long> longResult;
// Destruct all four cases // Destruct all four cases
if (x->type == LONG && y->type == LONG) { if (x->type == LONG && y->type == LONG) {
ans = make_boolean(get_long(x) < get_long(y)); std::vector<long> x_long = get_long(x);
std::vector<long> 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<long>());
ans = make_booleans(longResult);
} else if (x->type == LONG && y->type == DOUBLE) { } else if (x->type == LONG && y->type == DOUBLE) {
ans = make_boolean(get_long(x) < get_double(y)); std::vector<long> x_long = get_long(x);
std::vector<double> 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) { } else if (x->type == DOUBLE && y->type == LONG) {
ans = make_boolean(get_double(x) < get_long(y)); std::vector<double> x_double = get_double(x);
std::vector<long> 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) { } 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 } else { // Both are DOUBLE
ans = make_boolean(get_double(x) < get_double(y)); std::vector<double> x_double = get_double(x);
std::vector<double> 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<double>());
ans = make_booleans(longResult);
} }
return ans; return ans;
@ -123,18 +235,39 @@ Value* greater(Value* x, Value* y) {
} }
Value* ans; Value* ans;
std::vector<long> longResult;
// Destruct all four cases // Destruct all four cases
if (x->type == LONG && y->type == LONG) { if (x->type == LONG && y->type == LONG) {
ans = make_boolean(get_long(x) > get_long(y)); std::vector<long> x_long = get_long(x);
std::vector<long> 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<long>());
ans = make_booleans(longResult);
} else if (x->type == LONG && y->type == DOUBLE) { } else if (x->type == LONG && y->type == DOUBLE) {
ans = make_boolean(get_long(x) > get_double(y)); std::vector<long> x_long = get_long(x);
std::vector<double> 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) { } else if (x->type == DOUBLE && y->type == LONG) {
ans = make_boolean(get_double(x) > get_long(y)); std::vector<double> x_double = get_double(x);
std::vector<long> 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) { } 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 } else { // Both are DOUBLE
ans = make_boolean(get_double(x) > get_double(y)); std::vector<double> x_double = get_double(x);
std::vector<double> 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<double>());
ans = make_booleans(longResult);
} }
return ans; return ans;
@ -148,18 +281,39 @@ Value* less_equal(Value* x, Value* y) {
} }
Value* ans; Value* ans;
std::vector<long> longResult;
// Destruct all four cases // Destruct all four cases
if (x->type == LONG && y->type == LONG) { if (x->type == LONG && y->type == LONG) {
ans = make_boolean(get_long(x) <= get_long(y)); std::vector<long> x_long = get_long(x);
std::vector<long> 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<long>());
ans = make_booleans(longResult);
} else if (x->type == LONG && y->type == DOUBLE) { } else if (x->type == LONG && y->type == DOUBLE) {
ans = make_boolean(get_long(x) <= get_double(y)); std::vector<long> x_long = get_long(x);
std::vector<double> 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) { } else if (x->type == DOUBLE && y->type == LONG) {
ans = make_boolean(get_double(x) <= get_long(y)); std::vector<double> x_double = get_double(x);
std::vector<long> 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) { } 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 } else { // Both are DOUBLE
ans = make_boolean(get_double(x) <= get_double(y)); std::vector<double> x_double = get_double(x);
std::vector<double> 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<double>());
ans = make_booleans(longResult);
} }
return ans; return ans;
@ -173,18 +327,39 @@ Value* greater_equal(Value* x, Value* y) {
} }
Value* ans; Value* ans;
std::vector<long> longResult;
// Destruct all four cases // Destruct all four cases
if (x->type == LONG && y->type == LONG) { if (x->type == LONG && y->type == LONG) {
ans = make_boolean(get_long(x) >= get_long(y)); std::vector<long> x_long = get_long(x);
std::vector<long> 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<long>());
ans = make_booleans(longResult);
} else if (x->type == LONG && y->type == DOUBLE) { } else if (x->type == LONG && y->type == DOUBLE) {
ans = make_boolean(get_long(x) >= get_double(y)); std::vector<long> x_long = get_long(x);
std::vector<double> 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) { } else if (x->type == DOUBLE && y->type == LONG) {
ans = make_boolean(get_double(x) >= get_long(y)); std::vector<double> x_double = get_double(x);
std::vector<long> 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) { } 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 } else { // Both are DOUBLE
ans = make_boolean(get_double(x) >= get_double(y)); std::vector<double> x_double = get_double(x);
std::vector<double> 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<double>());
ans = make_booleans(longResult);
} }
return ans; return ans;
@ -197,22 +372,39 @@ Value* equals(Value* x, Value* y) {
} }
Value* ans = nullptr; Value* ans = nullptr;
std::vector<long> longResult;
// Destruct all four cases // Destruct all four cases
if (x->type == LONG && y->type == LONG) { if (x->type == LONG && y->type == LONG) {
ans = make_boolean(get_long(x) == get_long(y)); std::vector<long> x_long = get_long(x);
std::vector<long> 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<long>());
ans = make_booleans(longResult);
} else if (x->type == LONG && y->type == DOUBLE) { } else if (x->type == LONG && y->type == DOUBLE) {
ans = make_boolean(get_long(x) == get_double(y)); std::vector<long> x_long = get_long(x);
std::vector<double> 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) { } else if (x->type == DOUBLE && y->type == LONG) {
ans = make_boolean(get_double(x) == get_long(y)); std::vector<double> x_double = get_double(x);
} else if (x->type == DOUBLE && y->type == DOUBLE) { std::vector<long> y_long = get_long(y);
ans = make_boolean(get_double(x) == get_double(y)); longResult.reserve(x_double.size());
} else if (x->type == BOOLEAN && y->type == BOOLEAN) { std::transform(x_double.begin(), x_double.end(), y_long.begin(),
ans = make_boolean(get_long(x) == get_long(y)); std::back_inserter(longResult), std::equal_to<>());
ans = make_booleans(longResult);
} else if (x->type == STRING && y->type == STRING) { } 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 { // Type is a mix between boolean and another type } else { // Both are DOUBLE
std::cerr << "Error, cannot compare a boolean with another type." << std::endl; std::vector<double> x_double = get_double(x);
std::vector<double> 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<double>());
ans = make_booleans(longResult);
} }
return ans; return ans;
@ -225,22 +417,39 @@ Value* not_equals(Value* x, Value* y) {
} }
Value* ans= nullptr; Value* ans= nullptr;
std::vector<long> longResult;
// Destruct all four cases // Destruct all four cases
if (x->type == LONG && y->type == LONG) { if (x->type == LONG && y->type == LONG) {
ans = make_boolean(get_long(x) != get_long(y)); std::vector<long> x_long = get_long(x);
std::vector<long> 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<long>());
ans = make_booleans(longResult);
} else if (x->type == LONG && y->type == DOUBLE) { } else if (x->type == LONG && y->type == DOUBLE) {
ans = make_boolean(get_long(x) != get_double(y)); std::vector<long> x_long = get_long(x);
std::vector<double> 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) { } else if (x->type == DOUBLE && y->type == LONG) {
ans = make_boolean(get_double(x) != get_long(y)); std::vector<double> x_double = get_double(x);
} else if (x->type == DOUBLE && y->type == DOUBLE) { std::vector<long> y_long = get_long(y);
ans = make_boolean(get_double(x) != get_double(y)); longResult.reserve(x_double.size());
} else if (x->type == BOOLEAN && y->type == BOOLEAN) { std::transform(x_double.begin(), x_double.end(), y_long.begin(),
ans = make_boolean(get_long(x) != get_long(y)); std::back_inserter(longResult), std::not_equal_to<>());
ans = make_booleans(longResult);
} else if (x->type == STRING && y->type == STRING) { } 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 { // Type is a mix between boolean and another type } else { // Both are DOUBLE
std::cerr << "Error, cannot compare a boolean with another type." << std::endl; std::vector<double> x_double = get_double(x);
std::vector<double> 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<double>());
ans = make_booleans(longResult);
} }
return ans; return ans;
@ -249,23 +458,36 @@ Value* not_equals(Value* x, Value* y) {
Value* and_value(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 || !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 != 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; }
return make_boolean(get_long(x) && get_long(y)); std::vector<long> longResult;
std::vector<long> x_long = get_long(x);
std::vector<long> 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_booleans(longResult);
} }
Value* or_value(Value* x, Value* y) { Value* or_value(Value* x, Value* y) {
if (!x || !y) { std::cerr << "Error, uninitialized values being used in ||." << std::endl; } 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 != 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<long> longResult;
std::vector<long> x_long = get_long(x);
std::vector<long> 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) { Value* not_value(Value* x) {
if (!x) { std::cerr << "Error, uninitialized values being used in !." << std::endl; } 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 != 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<long> longResult;
std::vector<long> x_long = get_long(x);
std::transform(x_long.begin(), x_long.end(), std::back_inserter(longResult), std::logical_not<>());
return make_booleans(longResult);
} }

View file

@ -1,6 +1,7 @@
%{ %{
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <vector>
#include "../operations/node.hpp" #include "../operations/node.hpp"
#include "../variables/value.hpp" #include "../variables/value.hpp"
#include "parser.tab.h" #include "parser.tab.h"
@ -21,6 +22,8 @@ DIGIT [0-9]
"!" {return NOT;} "!" {return NOT;}
"(" {return OPENPAREM;} "(" {return OPENPAREM;}
")" {return ENDPAREM;} ")" {return ENDPAREM;}
"[" {return OPENVECTOR;}
"]" {return CLOSEVECTOR;}
";" {return SEMICOLON;} ";" {return SEMICOLON;}
%.*\n {} // Comments %.*\n {} // Comments
"<" {return LESS;} "<" {return LESS;}
@ -46,8 +49,8 @@ DIGIT [0-9]
"true" {yylval.value = new Node(VALUE, make_true(), ""); return VALUE;} "true" {yylval.value = new Node(VALUE, make_true(), ""); return VALUE;}
"false" {yylval.value = new Node(VALUE, make_false(), ""); 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; } \".*\" {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} {std::vector<long> nums; nums.push_back(atoi(yytext)); yylval.value = new Node(VALUE, make_long(nums), ""); return VALUE;}
{DIGIT}*"."?{DIGIT}+ {yylval.value = new Node(VALUE, make_double(atof(yytext)), ""); return VALUE;} {DIGIT}*"."?{DIGIT}+ {std::vector<double> 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;} [_a-zA-Z][_a-zA-Z0-9]* {yylval.value = new Node(IDENTIFIER, nullptr, strdup(yytext)); return IDENTIFIER;}
[\n] {linenum++;} [\n] {linenum++;}
[ \t\r]+ {} [ \t\r]+ {}

View file

@ -12,9 +12,11 @@ class Environment {
std::vector<Variable*> vars; std::vector<Variable*> vars;
Environment() { } Environment() { }
~Environment() { ~Environment() {
for (uint i = 0; i < size(vars); i++) { // Currently this deletes the values of local environment which messes up
delete vars[i]; // double(double(5))
} // for (uint i = 0; i < size(vars); i++) {
// delete vars[i];
// }
} }
}; };

View file

@ -3,39 +3,62 @@
#include <string> #include <string>
#include <iostream> #include <iostream>
#include <variant> #include <variant>
#include <algorithm>
#include "../parser/parser.tab.h" #include "../parser/parser.tab.h"
Value* make_long(long num) { Value* make_long(std::vector<long> nums) {
return new Value(LONG, num, 0, nullptr, ""); std::vector<double> decs;
return new Value(LONG, nums, decs, nullptr, "");
} }
Value* make_double(double dec) { Value* make_double(std::vector<double> decs) {
return new Value(DOUBLE, 0, dec, nullptr, ""); std::vector<long> nums;
return new Value(DOUBLE, nums, decs, nullptr, "");
} }
Value* make_true() { Value* make_true() {
return new Value(BOOLEAN, 1, 0, nullptr, ""); std::vector<long> nums = {1};
std::vector<double> decs;
return new Value(BOOLEAN, nums, decs, nullptr, "");
} }
Value* make_false() { Value* make_false() {
return new Value(BOOLEAN, 0, 0, nullptr, ""); std::vector<long> nums = {0};
std::vector<double> decs;
return new Value(BOOLEAN, nums, decs, nullptr, "");
} }
Value* make_boolean(int x) { Value* make_boolean(int x) {
return (x)? make_true() : make_false(); return (x) ? make_true() : make_false();
}
Value* make_booleans(std::vector<long> x) {
std::vector<double> decs;
std::vector<long> 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) { Value* make_expression(Node* expr) {
return new Value(LAMBDA, 0, 0, expr, ""); std::vector<long> nums;
std::vector<double> decs;
return new Value(LAMBDA, nums, decs, expr, "");
} }
Value* make_string(std::string str) { Value* make_string(std::string str) {
return new Value(STRING, 0, 0, nullptr, str); std::vector<long> nums;
std::vector<double> decs;
return new Value(STRING, nums, decs, nullptr, str);
} }
void delete_value(Value* val) { void delete_value(Value* val) {
free(val); free(val);
} }
long get_long(const Value* val) { std::vector<long> get_long(const Value* val) {
return std::get<long>(val->val); return std::get<std::vector<long>>(val->val);
} }
double get_double(const Value* val) { std::vector<double> get_double(const Value* val) {
return std::get<double>(val->val); return std::get<std::vector<double>>(val->val);
} }
Node* get_expression(const Value* val) { Node* get_expression(const Value* val) {
return std::get<Node*>(val->val); return std::get<Node*>(val->val);
@ -44,11 +67,11 @@ std::string get_string(const Value* val) {
return std::get<std::string>(val->val); return std::get<std::string>(val->val);
} }
void set_long(Value* val, long num) { void set_long(Value* val, std::vector<long> num) {
val->type = LONG; val->type = LONG;
val->val = num; val->val = num;
} }
void set_double(Value* val, double dec) { void set_double(Value* val, std::vector<double> dec) {
val->type = DOUBLE; val->type = DOUBLE;
// val->value.dec = dec; // val->value.dec = dec;
val->val = dec; val->val = dec;
@ -65,17 +88,46 @@ void set_sring(Value* val, std::string str) {
std::string Value::toString() const { std::string Value::toString() const {
std::string result = ""; std::string result = "";
if (this->type == BOOLEAN) { if (this->type == BOOLEAN) {
if (get_long(this)) { std::vector<long> longVec = get_long(this);
result += "true"; if (longVec.size() == 1) {
result += (longVec[0]) ? "true" : "false";
} else { } 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) { } else if (this->type == LONG) {
result += get_long(this); std::vector<long> 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) { } else if (this->type == STRING) {
result += get_string(this); result += get_string(this);
} else if (this->type == DOUBLE) { } else if (this->type == DOUBLE) {
result += get_double(this); std::vector<double> 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 } else { // Assume lambda expression
result += "<LambdaExpression>"; result += "<LambdaExpression>";
} }

View file

@ -5,6 +5,7 @@
#include <iostream> #include <iostream>
#include <string> #include <string>
#include <variant> #include <variant>
#include <vector>
class Node; class Node;
@ -13,21 +14,21 @@ enum TypeTag { DOUBLE, LONG, BOOLEAN, STRING, LAMBDA };
class Value { class Value {
public: public:
enum TypeTag type; enum TypeTag type;
std::variant<long, double, Node*, std::string> val; std::variant<std::vector<long>, std::vector<double>, Node*, std::string> val;
// << Overload // << Overload
friend std::ostream & operator << (std::ostream &out, const Value* val); friend std::ostream & operator << (std::ostream &out, const Value* val);
std::string toString() const; std::string toString() const;
// Constructor // Constructor
Value(TypeTag t, long n, double d, Node* e, std::string s) { Value(TypeTag t, std::vector<long> ns, std::vector<double> ds, Node* e, std::string s) {
/* set properties */ /* set properties */
type = t; type = t;
if (type == LONG || type == BOOLEAN) { if (type == LONG || type == BOOLEAN) {
val = n; val = ns;
} else if (type == DOUBLE){ // Assume DOUBLE } else if (type == DOUBLE){ // Assume DOUBLE
val = d; val = ds;
} else if (type == STRING) { } else if (type == STRING) {
val = s; val = s;
} else { // Assume lambda expression } 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 // Destructor
~Value() { ~Value() {
std::cout << "VALUE DESTROYED" << std::endl; std::cout << "VALUE DESTROYED" << std::endl;
@ -42,11 +57,12 @@ class Value {
}; };
// Constructors // Constructors
Value* make_long(long num); Value* make_long(std::vector<long> num);
Value* make_double(double dec); Value* make_double(std::vector<double> dec);
Value* make_true(); Value* make_true();
Value* make_false(); Value* make_false();
Value* make_boolean(int x); Value* make_boolean(int x);
Value* make_booleans(std::vector<long> x);
Value* make_expression(Node* expr); Value* make_expression(Node* expr);
Value* make_string(std::string str); Value* make_string(std::string str);
@ -54,14 +70,14 @@ Value* make_string(std::string str);
void delete_value(Value* val); void delete_value(Value* val);
// Getters // Getters
long get_long(const Value* val); std::vector<long> get_long(const Value* val);
double get_double(const Value* val); std::vector<double> get_double(const Value* val);
Node* get_expression(const Value* val); Node* get_expression(const Value* val);
std::string get_string(const Value* val); std::string get_string(const Value* val);
// Setters // Setters
void set_long(Value* val, long num); void set_long(Value* val, std::vector<long> num);
void set_double(Value* val, double dec); void set_double(Value* val, std::vector<double> dec);
void set_expression(Value* val, Node* node); void set_expression(Value* val, Node* node);
void set_string(Value* val, std::string str); void set_string(Value* val, std::string str);