Made numeric types vector based
This commit is contained in:
parent
d486a64052
commit
cdbafe8d0d
6 changed files with 405 additions and 101 deletions
|
@ -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<double> 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<long> 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");
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#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<long> longResult;
|
||||
std::vector<double> doubleResult;
|
||||
|
||||
// Destruct all four cases
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
ans = make_string(get_string(x) + get_string(y));
|
||||
} 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;
|
||||
|
@ -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<long> longResult;
|
||||
std::vector<double> doubleResult;
|
||||
|
||||
// Destruct all four cases
|
||||
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) {
|
||||
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) {
|
||||
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
|
||||
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;
|
||||
|
@ -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<long> longResult;
|
||||
std::vector<double> doubleResult;
|
||||
|
||||
// Destruct all four cases
|
||||
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) {
|
||||
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) {
|
||||
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
|
||||
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;
|
||||
|
@ -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<long> longResult;
|
||||
std::vector<double> doubleResult;
|
||||
|
||||
// Destruct all four cases
|
||||
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) {
|
||||
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) {
|
||||
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
|
||||
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;
|
||||
|
@ -98,18 +189,39 @@ Value* less(Value* x, Value* y) {
|
|||
}
|
||||
|
||||
Value* ans;
|
||||
std::vector<long> longResult;
|
||||
|
||||
// Destruct all four cases
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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<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;
|
||||
|
@ -123,18 +235,39 @@ Value* greater(Value* x, Value* y) {
|
|||
}
|
||||
|
||||
Value* ans;
|
||||
std::vector<long> longResult;
|
||||
|
||||
// Destruct all four cases
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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<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;
|
||||
|
@ -148,18 +281,39 @@ Value* less_equal(Value* x, Value* y) {
|
|||
}
|
||||
|
||||
Value* ans;
|
||||
std::vector<long> longResult;
|
||||
|
||||
// Destruct all four cases
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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<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;
|
||||
|
@ -173,18 +327,39 @@ Value* greater_equal(Value* x, Value* y) {
|
|||
}
|
||||
|
||||
Value* ans;
|
||||
std::vector<long> longResult;
|
||||
|
||||
// Destruct all four cases
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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<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;
|
||||
|
@ -197,22 +372,39 @@ Value* equals(Value* x, Value* y) {
|
|||
}
|
||||
|
||||
Value* ans = nullptr;
|
||||
std::vector<long> longResult;
|
||||
|
||||
// Destruct all four cases
|
||||
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) {
|
||||
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) {
|
||||
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<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::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<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;
|
||||
|
@ -225,22 +417,39 @@ Value* not_equals(Value* x, Value* y) {
|
|||
}
|
||||
|
||||
Value* ans= nullptr;
|
||||
std::vector<long> longResult;
|
||||
|
||||
// Destruct all four cases
|
||||
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) {
|
||||
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) {
|
||||
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<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::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<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;
|
||||
|
@ -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<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_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<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) {
|
||||
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<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);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
%{
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <vector>
|
||||
#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<long> nums; nums.push_back(atoi(yytext)); yylval.value = new Node(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;}
|
||||
[_a-zA-Z][_a-zA-Z0-9]* {yylval.value = new Node(IDENTIFIER, nullptr, strdup(yytext)); return IDENTIFIER;}
|
||||
[\n] {linenum++;}
|
||||
[ \t\r]+ {}
|
||||
|
|
|
@ -12,9 +12,11 @@ class Environment {
|
|||
std::vector<Variable*> 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];
|
||||
// }
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -3,39 +3,62 @@
|
|||
#include <string>
|
||||
#include <iostream>
|
||||
#include <variant>
|
||||
#include <algorithm>
|
||||
#include "../parser/parser.tab.h"
|
||||
|
||||
Value* make_long(long num) {
|
||||
return new Value(LONG, num, 0, nullptr, "");
|
||||
Value* make_long(std::vector<long> nums) {
|
||||
std::vector<double> 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<double> decs) {
|
||||
std::vector<long> nums;
|
||||
return new Value(DOUBLE, nums, decs, nullptr, "");
|
||||
}
|
||||
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() {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
free(val);
|
||||
}
|
||||
|
||||
long get_long(const Value* val) {
|
||||
return std::get<long>(val->val);
|
||||
std::vector<long> get_long(const Value* val) {
|
||||
return std::get<std::vector<long>>(val->val);
|
||||
}
|
||||
double get_double(const Value* val) {
|
||||
return std::get<double>(val->val);
|
||||
std::vector<double> get_double(const Value* val) {
|
||||
return std::get<std::vector<double>>(val->val);
|
||||
}
|
||||
Node* get_expression(const Value* 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);
|
||||
}
|
||||
|
||||
void set_long(Value* val, long num) {
|
||||
void set_long(Value* val, std::vector<long> num) {
|
||||
val->type = LONG;
|
||||
val->val = num;
|
||||
}
|
||||
void set_double(Value* val, double dec) {
|
||||
void set_double(Value* val, std::vector<double> 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<long> 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<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) {
|
||||
result += get_string(this);
|
||||
} 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
|
||||
result += "<LambdaExpression>";
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <iostream>
|
||||
#include <string>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
class Node;
|
||||
|
||||
|
@ -13,21 +14,21 @@ enum TypeTag { DOUBLE, LONG, BOOLEAN, STRING, LAMBDA };
|
|||
class Value {
|
||||
public:
|
||||
enum TypeTag type;
|
||||
std::variant<long, double, Node*, std::string> val;
|
||||
std::variant<std::vector<long>, std::vector<double>, 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<long> ns, std::vector<double> 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<long> num);
|
||||
Value* make_double(std::vector<double> dec);
|
||||
Value* make_true();
|
||||
Value* make_false();
|
||||
Value* make_boolean(int x);
|
||||
Value* make_booleans(std::vector<long> 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<long> get_long(const Value* val);
|
||||
std::vector<double> 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<long> num);
|
||||
void set_double(Value* val, std::vector<double> dec);
|
||||
void set_expression(Value* val, Node* node);
|
||||
void set_string(Value* val, std::string str);
|
||||
|
||||
|
|
Reference in a new issue