Archived
1
0
Fork 0

struct->classes

Environment now has destructor
This commit is contained in:
Brandon Rozek 2018-09-28 21:54:24 -04:00
parent 7733f5b3c2
commit 8dd2e789c0
13 changed files with 167 additions and 150 deletions

View file

@ -4,8 +4,10 @@
#define STATEMENT 200 #define STATEMENT 200
#define CALLFUNC 201 #define CALLFUNC 201
class Node;
// Share the line number between files // Share the line number between files
extern int linenum; extern int linenum;
extern struct Node* result; extern Node* result;
#endif #endif

View file

@ -6,7 +6,7 @@
void interpret_file(char* fileName); void interpret_file(char* fileName);
/* the result variable */ /* the result variable */
struct Node* result; Node* result;
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
if (argc == 1) { if (argc == 1) {
@ -35,10 +35,8 @@ void interpret_file(char* fileName) {
// Interpret the AST // Interpret the AST
// print_tree(result, 0); // For debugging // print_tree(result, 0); // For debugging
struct Environment* env = new Environment(); Environment* env = new Environment();
eval_statement(result, env); eval_statement(result, env);
delete_environment(env); delete env;
// delete env;
delete result; delete result;
} }

View file

@ -8,20 +8,20 @@
#include "../variables/variable.hpp" #include "../variables/variable.hpp"
/* attach an existing node onto a parent */ /* attach an existing node onto a parent */
void attach_node(struct Node* parent, struct Node* child) { void attach_node(Node* parent, Node* child) {
/* connect it */ /* connect it */
parent->children[parent->num_children] = child; parent->children[parent->num_children] = child;
parent->num_children++; parent->num_children++;
if (parent->num_children > MAX_CHILDREN) { std::cerr << "Error, max children attached to a node" << std::endl; } if (parent->num_children > MAX_CHILDREN) { std::cerr << "Error, max children attached to a node" << std::endl; }
} }
void check_num_nodes(struct Node* node, uint num_children, std::string error) { void check_num_nodes(Node* node, uint num_children, std::string error) {
if (node && node->num_children != num_children) { if (node && node->num_children != num_children) {
std::cerr << "Error, " << error << std::endl; std::cerr << "Error, " << error << std::endl;
} }
} }
void print_tree(struct Node* node, uint tabs) { void print_tree(Node* node, uint tabs) {
uint i; uint i;
/* base case */ /* base case */
if(!node) { if(!node) {
@ -74,7 +74,7 @@ void print_tree(struct Node* node, uint tabs) {
} }
struct Value* eval_expression(struct Node* node, struct Environment* env) { Value* eval_expression(Node* node, Environment* env) {
/* base case */ /* base case */
if(!node) { if(!node) {
fprintf(stderr, "Error: No tree structure to evaluate\n"); fprintf(stderr, "Error: No tree structure to evaluate\n");
@ -83,14 +83,14 @@ struct Value* eval_expression(struct Node* node, struct 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;
struct Variable* var = nullptr; Variable* var = nullptr;
struct Environment* local_env = nullptr; Environment* local_env = nullptr;
struct Node* tempNode = nullptr; Node* tempNode = nullptr;
struct Value* tempVal = nullptr; Value* tempVal = nullptr;
// Evaluate subexpressions if existent and node is not a lambda expression // Evaluate subexpressions if existent and node is not a lambda expression
struct Value* val1 = nullptr; Value* val1 = nullptr;
struct Value* val2 = nullptr; Value* val2 = nullptr;
// struct Value* val3 = nullptr; // struct Value* val3 = nullptr;
if (node->num_children > 0 && node->type != LAMBDATAG) { if (node->num_children > 0 && node->type != LAMBDATAG) {
val1 = eval_expression(node->children[0], env); val1 = eval_expression(node->children[0], env);
@ -112,8 +112,7 @@ struct Value* eval_expression(struct Node* node, struct Environment* env) {
new Variable(tempNode->children[0]->id, // Get the name of the variable needed for the lambda expression new Variable(tempNode->children[0]->id, // Get the name of the variable needed for the lambda expression
eval_expression(node->children[1], env))); eval_expression(node->children[1], env)));
tempVal = eval_expression(tempNode->children[1], local_env); tempVal = eval_expression(tempNode->children[1], local_env);
delete_environment(local_env); delete local_env;
// delete local_env;
return tempVal; return tempVal;
break; break;
case PLUS: case PLUS:
@ -222,14 +221,14 @@ struct Value* eval_expression(struct Node* node, struct Environment* env) {
} }
void eval_statement(struct Node* node, struct Environment* env) { void eval_statement(Node* node, Environment* env) {
/* base case */ /* base case */
if(!node) { if(!node) {
fprintf(stderr, "Error: No tree structure to evaluate\n"); fprintf(stderr, "Error: No tree structure to evaluate\n");
return; return;
} }
struct Value* tempVal; Value* tempVal;
switch(node->type) { switch(node->type) {
case ASSIGN: case ASSIGN:

View file

@ -3,33 +3,38 @@
#include <string> #include <string>
#include <array> #include <array>
#include <iostream>
#include "../variables/value.hpp" #include "../variables/value.hpp"
#include "../variables/environment.hpp" #include "../variables/environment.hpp"
#define MAX_CHILDREN 3 #define MAX_CHILDREN 3
class Value;
class Environment;
/* a tree node definition */ /* a tree node definition */
struct Node { class Node {
public:
int type; int type;
struct Value* value; Value* value;
/* the id of the node (used for identifiers only) */ /* the id of the node (used for identifiers only) */
std::string id; std::string id;
/* at most three children nodes */ /* at most three children nodes */
uint num_children; uint num_children;
std::array<struct Node*, MAX_CHILDREN> children; std::array<Node*, MAX_CHILDREN> children;
Node(int t, struct Value* v, std::string s) { Node(int t, Value* v, std::string s) {
type = t; type = t;
value = v; value = v;
id = s; id = s;
num_children = 0;
for (uint i = 0; i < MAX_CHILDREN; i++) { for (uint i = 0; i < MAX_CHILDREN; i++) {
children[i] = nullptr; children[i] = nullptr;
} }
} }
~Node() { ~Node() {
if (value) { delete value; }
// delete value; // delete value;
for (uint i = 0; i < num_children; i++) { for (uint i = 0; i < num_children; i++) {
delete children[i]; delete children[i];
@ -39,11 +44,11 @@ struct Node {
// Abstract Syntax Tree Functions // Abstract Syntax Tree Functions
// struct Node* make_node(int type, struct Value* value, std::string id); // struct Node* make_node(int type, struct Value* value, std::string id);
void attach_node(struct Node* parent, struct Node* child); void attach_node(Node* parent, Node* child);
void print_tree(struct Node* node, int tabs); void print_tree(Node* node, int tabs);
// Interpreting AST // Interpreting AST
void eval_statement(struct Node* node, struct Environment* env); void eval_statement(Node* node, Environment* env);
struct Value* eval_expression(struct Node* node, struct Environment* env); Value* eval_expression(Node* node, Environment* env);
#endif #endif

View file

@ -2,14 +2,14 @@
#include "operators.hpp" #include "operators.hpp"
#include "../variables/value.hpp" #include "../variables/value.hpp"
struct Value* add(struct Value* x, struct 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; }
if ((x->type == STRING || y->type == STRING) && (x->type != STRING || y->type != STRING)) { if ((x->type == STRING || y->type == STRING) && (x->type != STRING || y->type != STRING)) {
std::cerr << "Error, cannot add a string with another data type." << std::endl; std::cerr << "Error, cannot add a string with another data type." << std::endl;
} }
struct Value* ans; Value* ans;
// Destruct all four cases // Destruct all four cases
if (x->type == LONG && y->type == LONG) { if (x->type == LONG && y->type == LONG) {
@ -27,12 +27,12 @@ struct Value* add(struct Value* x, struct Value* y) {
return ans; return ans;
} }
struct Value* subtract(struct Value* x, struct Value* y) { Value* subtract(Value* x, Value* y) {
if (!x || !y) { std::cerr << "Error, uninitialized values being used in subtract." << std::endl; } if (!x || !y) { std::cerr << "Error, uninitialized values being used in subtract." << std::endl; }
if (x->type == BOOLEAN || y->type == BOOLEAN) { std::cerr << "Error, cannot subtract a boolean." << std::endl; } if (x->type == BOOLEAN || y->type == BOOLEAN) { std::cerr << "Error, cannot subtract a boolean." << std::endl; }
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; }
struct Value* ans; Value* ans;
// Destruct all four cases // Destruct all four cases
if (x->type == LONG && y->type == LONG) { if (x->type == LONG && y->type == LONG) {
@ -48,12 +48,12 @@ struct Value* subtract(struct Value* x, struct Value* y) {
return ans; return ans;
} }
struct Value* division(struct Value* x, struct Value* y) { Value* division(Value* x, Value* y) {
if (!x || !y) { std::cerr << "Error, uninitialized values being used in divide." << std::endl; } if (!x || !y) { std::cerr << "Error, uninitialized values being used in divide." << std::endl; }
if (x->type == BOOLEAN || y->type == BOOLEAN) { std::cerr << "Error, cannot divide a boolean." << std::endl; } if (x->type == BOOLEAN || y->type == BOOLEAN) { std::cerr << "Error, cannot divide a boolean." << std::endl; }
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; }
struct Value* ans; Value* ans;
// Destruct all four cases // Destruct all four cases
if (x->type == LONG && y->type == LONG) { if (x->type == LONG && y->type == LONG) {
@ -69,12 +69,12 @@ struct Value* division(struct Value* x, struct Value* y) {
return ans; return ans;
} }
struct Value* multiplication(struct Value* x, struct Value* y) { Value* multiplication(Value* x, Value* y) {
if (!x || !y) { std::cerr << "Error, uninitialized values being used in multiply." << std::endl; } if (!x || !y) { std::cerr << "Error, uninitialized values being used in multiply." << std::endl; }
if (x->type == BOOLEAN || y->type == BOOLEAN) { std::cerr << "Error, cannot multiply a boolean." << std::endl; } if (x->type == BOOLEAN || y->type == BOOLEAN) { std::cerr << "Error, cannot multiply a boolean." << std::endl; }
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; }
struct Value* ans; Value* ans;
// Destruct all four cases // Destruct all four cases
if (x->type == LONG && y->type == LONG) { if (x->type == LONG && y->type == LONG) {
@ -90,14 +90,14 @@ struct Value* multiplication(struct Value* x, struct Value* y) {
return ans; return ans;
} }
struct Value* less(struct Value* x, struct Value* y) { Value* less(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 numerically compare a boolean." << std::endl; } if (x->type == BOOLEAN || y->type == BOOLEAN) { std::cerr << "Error, cannot numerically compare a boolean." << std::endl; }
if ((x->type == STRING || y->type == STRING) && (x->type != STRING || y->type != STRING)) { if ((x->type == STRING || y->type == STRING) && (x->type != STRING || y->type != STRING)) {
std::cerr << "Error, cannot compare a string with another data type." << std::endl; std::cerr << "Error, cannot compare a string with another data type." << std::endl;
} }
struct Value* ans; Value* ans;
// Destruct all four cases // Destruct all four cases
if (x->type == LONG && y->type == LONG) { if (x->type == LONG && y->type == LONG) {
@ -115,14 +115,14 @@ struct Value* less(struct Value* x, struct Value* y) {
return ans; return ans;
} }
struct Value* greater(struct Value* x, struct Value* y) { Value* greater(Value* x, Value* y) {
if (!x || !y) { std::cerr << "Error, uninitialized values being used in greater." << std::endl; } if (!x || !y) { std::cerr << "Error, uninitialized values being used in greater." << std::endl; }
if (x->type == BOOLEAN || y->type == BOOLEAN) { std::cerr << "Error, cannot numerically compare a boolean." << std::endl; } if (x->type == BOOLEAN || y->type == BOOLEAN) { std::cerr << "Error, cannot numerically compare a boolean." << std::endl; }
if ((x->type == STRING || y->type == STRING) && (x->type != STRING || y->type != STRING)) { if ((x->type == STRING || y->type == STRING) && (x->type != STRING || y->type != STRING)) {
std::cerr << "Error, cannot compare a string with another data type." << std::endl; std::cerr << "Error, cannot compare a string with another data type." << std::endl;
} }
struct Value* ans; Value* ans;
// Destruct all four cases // Destruct all four cases
if (x->type == LONG && y->type == LONG) { if (x->type == LONG && y->type == LONG) {
@ -140,14 +140,14 @@ struct Value* greater(struct Value* x, struct Value* y) {
return ans; return ans;
} }
struct Value* less_equal(struct Value* x, struct Value* y) { Value* less_equal(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 numerically compare a boolean." << std::endl; } if (x->type == BOOLEAN || y->type == BOOLEAN) { std::cerr << "Error, cannot numerically compare a boolean." << std::endl; }
if ((x->type == STRING || y->type == STRING) && (x->type != STRING || y->type != STRING)) { if ((x->type == STRING || y->type == STRING) && (x->type != STRING || y->type != STRING)) {
std::cerr << "Error, cannot compare a string with another data type." << std::endl; std::cerr << "Error, cannot compare a string with another data type." << std::endl;
} }
struct Value* ans; Value* ans;
// Destruct all four cases // Destruct all four cases
if (x->type == LONG && y->type == LONG) { if (x->type == LONG && y->type == LONG) {
@ -165,14 +165,14 @@ struct Value* less_equal(struct Value* x, struct Value* y) {
return ans; return ans;
} }
struct Value* greater_equal(struct Value* x, struct Value* y) { Value* greater_equal(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 numerically compare a boolean." << std::endl; } if (x->type == BOOLEAN || y->type == BOOLEAN) { std::cerr << "Error, cannot numerically compare a boolean." << std::endl; }
if ((x->type == STRING || y->type == STRING) && (x->type != STRING || y->type != STRING)) { if ((x->type == STRING || y->type == STRING) && (x->type != STRING || y->type != STRING)) {
std::cerr << "Error, cannot compare a string with another data type." << std::endl; std::cerr << "Error, cannot compare a string with another data type." << std::endl;
} }
struct Value* ans; Value* ans;
// Destruct all four cases // Destruct all four cases
if (x->type == LONG && y->type == LONG) { if (x->type == LONG && y->type == LONG) {
@ -190,13 +190,13 @@ struct Value* greater_equal(struct Value* x, struct Value* y) {
return ans; return ans;
} }
struct Value* equals(struct Value* x, struct Value* y) { Value* equals(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 == STRING || y->type == STRING) && (x->type != STRING || y->type != STRING)) { if ((x->type == STRING || y->type == STRING) && (x->type != STRING || y->type != STRING)) {
std::cerr << "Error, cannot compare a string with another data type." << std::endl; std::cerr << "Error, cannot compare a string with another data type." << std::endl;
} }
struct Value* ans = nullptr; Value* ans = nullptr;
// Destruct all four cases // Destruct all four cases
if (x->type == LONG && y->type == LONG) { if (x->type == LONG && y->type == LONG) {
@ -218,13 +218,13 @@ struct Value* equals(struct Value* x, struct Value* y) {
return ans; return ans;
} }
struct Value* not_equals(struct Value* x, struct Value* y) { Value* not_equals(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 == STRING || y->type == STRING) && (x->type != STRING || y->type != STRING)) { if ((x->type == STRING || y->type == STRING) && (x->type != STRING || y->type != STRING)) {
std::cerr << "Error, cannot compare a string with another data type." << std::endl; std::cerr << "Error, cannot compare a string with another data type." << std::endl;
} }
struct Value* ans= nullptr; Value* ans= nullptr;
// Destruct all four cases // Destruct all four cases
if (x->type == LONG && y->type == LONG) { if (x->type == LONG && y->type == LONG) {
@ -246,7 +246,7 @@ struct Value* not_equals(struct Value* x, struct Value* y) {
return ans; return ans;
} }
struct Value* and_value(struct Value* x, struct 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; } if (x->type == STRING || y->type == STRING) { std::cerr << "Error, cannot AND a string." << std::endl; }
@ -254,7 +254,7 @@ struct Value* and_value(struct Value* x, struct Value* y) {
return make_boolean(get_long(x) && get_long(y)); return make_boolean(get_long(x) && get_long(y));
} }
struct Value* or_value(struct Value* x, struct 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; } if (x->type == STRING || y->type == STRING) { std::cerr << "Error, cannot OR a string." << std::endl; }
@ -262,7 +262,7 @@ struct Value* or_value(struct Value* x, struct Value* y) {
return make_boolean(get_long(x) || get_long(y)); return make_boolean(get_long(x) || get_long(y));
} }
struct Value* not_value(struct 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; } if (x->type == STRING) { std::cerr << "Error, cannot negate a string." << std::endl; }

View file

@ -2,18 +2,18 @@
#define OPERATORS_H #define OPERATORS_H
#include "../variables/value.hpp" #include "../variables/value.hpp"
struct Value* add(struct Value* x, struct Value* y); Value* add(Value* x, Value* y);
struct Value* subtract(struct Value* x, struct Value* y); Value* subtract(Value* x, Value* y);
struct Value* division(struct Value* x, struct Value* y); Value* division(Value* x, Value* y);
struct Value* multiplication(struct Value* x, struct Value* y); Value* multiplication(Value* x, Value* y);
struct Value* less(struct Value* x, struct Value* y); Value* less(Value* x, Value* y);
struct Value* greater(struct Value* x, struct Value* y); Value* greater(Value* x, Value* y);
struct Value* less_equal(struct Value* x, struct Value* y); Value* less_equal(Value* x, Value* y);
struct Value* greater_equal(struct Value* x, struct Value* y); Value* greater_equal(Value* x, Value* y);
struct Value* equals(struct Value* x, struct Value* y); Value* equals(Value* x, Value* y);
struct Value* not_equals(struct Value* x, struct Value* y); Value* not_equals(Value* x, Value* y);
struct Value* and_value(struct Value* x, struct Value* y); Value* and_value(Value* x, Value* y);
struct Value* or_value(struct Value* x, struct Value* y); Value* or_value(Value* x, Value* y);
struct Value* not_value(struct Value* x); Value* not_value(Value* x);
#endif #endif

View file

@ -48,7 +48,7 @@ void start_shell() {
printf("Welcome to SLOTH Version 0.0.1\n"); printf("Welcome to SLOTH Version 0.0.1\n");
printf("Press CTRL+C to Exit\n"); printf("Press CTRL+C to Exit\n");
struct Environment* env = new Environment(); Environment* env = new Environment();
while (1) { while (1) {
// Read line from user and input it into the history // Read line from user and input it into the history
char* input = readline("sloth> "); char* input = readline("sloth> ");
@ -69,7 +69,6 @@ void start_shell() {
eval_statement(result, env); eval_statement(result, env);
} }
delete_environment(env); delete env;
// delete env;
delete result; delete result;
} }

View file

@ -4,7 +4,7 @@
#include "environment.hpp" #include "environment.hpp"
#include "variable.hpp" #include "variable.hpp"
struct Variable* find_variable(struct Environment* env, std::string id) { Variable* find_variable(Environment* env, std::string id) {
auto result = std::find_if(env->vars.begin(), env->vars.end(), auto result = std::find_if(env->vars.begin(), env->vars.end(),
[id](const Variable* element) { [id](const Variable* element) {
return element->id == id; return element->id == id;
@ -17,9 +17,9 @@ struct Variable* find_variable(struct Environment* env, std::string id) {
return nullptr; return nullptr;
} }
void add_variable(struct Environment* env, struct Variable* var) { void add_variable(Environment* env, Variable* var) {
// If variable exists, replace it // If variable exists, replace it
struct Variable* temp_var = find_variable(env, var->id); Variable* temp_var = find_variable(env, var->id);
if (temp_var != nullptr) { if (temp_var != nullptr) {
temp_var->value = var->value; temp_var->value = var->value;
free(var); free(var);
@ -30,9 +30,3 @@ void add_variable(struct Environment* env, struct Variable* var) {
env->vars.push_back(var); env->vars.push_back(var);
} }
void delete_environment(struct Environment* env) {
for (uint i = 0; i < size(env->vars); i++) {
free(env->vars[i]);
}
free(env);
}

View file

@ -5,19 +5,21 @@
#include <string> #include <string>
#include <vector> #include <vector>
struct Environment { class Variable;
std::vector<struct Variable*> vars;
class Environment {
public:
std::vector<Variable*> vars;
Environment() { } Environment() { }
// ~Environment() { ~Environment() {
// for (uint i = 0; i < size(vars); i++) { for (uint i = 0; i < size(vars); i++) {
// delete vars[i]; delete vars[i];
// } }
// } }
}; };
// Variable Lookup Functions // Variable Lookup Functions
void delete_environment(struct Environment* env); Variable* find_variable(Environment* env, std::string id);
struct Variable* find_variable(struct Environment* env, std::string id); void add_variable(Environment* env, Variable* var);
void add_variable(struct Environment* env, struct Variable* var);
#endif #endif

View file

@ -2,65 +2,74 @@
#include "value.hpp" #include "value.hpp"
#include <string> #include <string>
#include <iostream> #include <iostream>
#include <variant>
#include "../parser/parser.tab.h" #include "../parser/parser.tab.h"
struct Value* make_long(long num) { Value* make_long(long num) {
return new Value(LONG, num, 0, nullptr, ""); return new Value(LONG, num, 0, nullptr, "");
} }
struct Value* make_double(double dec) { Value* make_double(double dec) {
return new Value(DOUBLE, 0, dec, nullptr, ""); return new Value(DOUBLE, 0, dec, nullptr, "");
} }
struct Value* make_true() { Value* make_true() {
return new Value(BOOLEAN, 1, 0, nullptr, ""); return new Value(BOOLEAN, 1, 0, nullptr, "");
} }
struct Value* make_false() { Value* make_false() {
return new Value(BOOLEAN, 0, 0, nullptr, ""); return new Value(BOOLEAN, 0, 0, nullptr, "");
} }
struct Value* make_boolean(int x) { Value* make_boolean(int x) {
return (x)? make_true() : make_false(); return (x)? make_true() : make_false();
} }
struct Value* make_expression(struct Node* expr) { Value* make_expression(Node* expr) {
return new Value(LAMBDA, 0, 0, expr, ""); return new Value(LAMBDA, 0, 0, expr, "");
} }
struct Value* make_string(std::string str) { Value* make_string(std::string str) {
return new Value(STRING, 0, 0, nullptr, str); return new Value(STRING, 0, 0, nullptr, str);
} }
void delete_value(struct Value* val) { void delete_value(Value* val) {
free(val); free(val);
} }
long get_long(struct Value* val) { long get_long(Value* val) {
return val->value.num; // return val->value.num;
return std::get<long>(val->val);
} }
double get_double(struct Value* val) { double get_double(Value* val) {
return val->value.dec; // return val->value.dec;
return std::get<double>(val->val);
} }
struct Node* get_expression(struct Value* val) { Node* get_expression(Value* val) {
return val->value.expr; // return val->value.expr;
return std::get<Node*>(val->val);
} }
std::string get_string(struct Value* val) { std::string get_string(Value* val) {
return val->value.str; // return val->value.str;
return std::get<std::string>(val->val);
} }
void set_long(struct Value* val, long num) { void set_long(Value* val, long num) {
val->type = LONG; val->type = LONG;
val->value.num = num; // val->value.num = num;
val->val = num;
} }
void set_double(struct Value* val, double dec) { void set_double(Value* val, double dec) {
val->type = DOUBLE; val->type = DOUBLE;
val->value.dec = dec; // val->value.dec = dec;
val->val = dec;
} }
void set_expression(struct Value* val, struct Node* expr) { void set_expression(Value* val, Node* expr) {
val->type = LAMBDA; val->type = LAMBDA;
val->value.expr = expr; // val->value.expr = expr;
val->val = expr;
} }
void set_sring(struct Value* val, std::string str) { void set_sring(Value* val, std::string str) {
val->type = STRING; val->type = STRING;
val->value.str = str; // val->value.str = str;
val->val = str;
} }
void print_value(struct Value* val) { void print_value(Value* val) {
if (val->type == BOOLEAN) { if (val->type == BOOLEAN) {
if (get_long(val)) { if (get_long(val)) {
std::cout << "true"; std::cout << "true";

View file

@ -1,36 +1,38 @@
#ifndef VALUE_H #ifndef VALUE_H
#define VALUE_H #define VALUE_H
#include "../operations/node.hpp"
#include <iostream>
#include <string> #include <string>
#include <variant>
class Node;
enum TypeTag { DOUBLE, LONG, BOOLEAN, STRING, LAMBDA }; enum TypeTag { DOUBLE, LONG, BOOLEAN, STRING, LAMBDA };
union TypeVal { class Value {
long num; public:
double dec;
struct Node* expr;
std::string str;
TypeVal() { new(&str) std::string(); new(expr) struct Node*; }
~TypeVal() { free(&str); free(expr); }
};
struct Value {
enum TypeTag type; enum TypeTag type;
TypeVal value; std::variant<long, double, Node*, std::string> val;
// Broken implemenation of constructor below
Value(TypeTag t, long n, double d, struct Node* e, std::string s) { Value(TypeTag t, long n, double d, Node* e, std::string s) {
/* set properties */ /* set properties */
type = t; type = t;
if (type == LONG || type == BOOLEAN) { if (type == LONG || type == BOOLEAN) {
value.num = n; val = n;
} else if (type == DOUBLE){ // Assume DOUBLE } else if (type == DOUBLE){ // Assume DOUBLE
value.dec = d; val = d;
} else if (type == STRING) { } else if (type == STRING) {
value.str = s; val = s;
} else { // Assume lambda expression } else { // Assume lambda expression
value.expr = e; val = e;
} }
} }
~Value() {
std::cout << "VALUE DESTROYED" << std::endl;
}
}; };
// Constructors // Constructors

View file

@ -2,12 +2,12 @@
#include <string> #include <string>
#include "variable.hpp" #include "variable.hpp"
void set_value(struct Variable* var, struct Value* value) { void set_value(Variable* var, Value* value) {
if (!var) { std::cerr << "Error: Invalid Variable" << std::endl; return; } if (!var) { std::cerr << "Error: Invalid Variable" << std::endl; return; }
var->value = value; var->value = value;
} }
struct Value* get_value(struct Variable* var) { Value* get_value(Variable* var) {
if (!var) { std::cerr << "Error: Invalid Variable" << std::endl; return 0; } if (!var) { std::cerr << "Error: Invalid Variable" << std::endl; return 0; }
return var->value; return var->value;
} }

View file

@ -2,26 +2,33 @@
#define VARIABLE_H #define VARIABLE_H
#include <string> #include <string>
#include "../operations/node.hpp" #include "../variables/value.hpp"
struct Variable { class Value;
class Node;
class Variable {
public:
std::string id; std::string id;
struct Value* value; Value* value;
Variable(std::string s, struct Value* val) { Variable(std::string s, Value* val) {
id = s; id = s;
value = val; value = val;
} }
~Variable() {
delete value;
}
}; };
// Variable Functions // Variable Functions
void set_value(struct Variable* var, struct Value* value); void set_value(Variable* var, Value* value);
struct Value* get_value(struct Variable* var); Value* get_value(Variable* var);
struct Value* make_long(long num); Value* make_long(long num);
struct Value* make_double(double dec); Value* make_double(double dec);
struct Value* make_true(); Value* make_true();
struct Value* make_false(); Value* make_false();
struct Value* make_boolean(int x); Value* make_boolean(int x);
struct Value* make_expression(struct Node* expr); Value* make_expression(Node* expr);
#endif #endif