struct->classes
Environment now has destructor
This commit is contained in:
parent
7733f5b3c2
commit
8dd2e789c0
13 changed files with 167 additions and 150 deletions
|
@ -4,8 +4,10 @@
|
|||
#define STATEMENT 200
|
||||
#define CALLFUNC 201
|
||||
|
||||
class Node;
|
||||
|
||||
// Share the line number between files
|
||||
extern int linenum;
|
||||
extern struct Node* result;
|
||||
extern Node* result;
|
||||
|
||||
#endif
|
|
@ -6,7 +6,7 @@
|
|||
void interpret_file(char* fileName);
|
||||
|
||||
/* the result variable */
|
||||
struct Node* result;
|
||||
Node* result;
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc == 1) {
|
||||
|
@ -35,10 +35,8 @@ void interpret_file(char* fileName) {
|
|||
|
||||
// Interpret the AST
|
||||
// print_tree(result, 0); // For debugging
|
||||
struct Environment* env = new Environment();
|
||||
Environment* env = new Environment();
|
||||
eval_statement(result, env);
|
||||
delete_environment(env);
|
||||
// delete env;
|
||||
|
||||
delete env;
|
||||
delete result;
|
||||
}
|
|
@ -8,20 +8,20 @@
|
|||
#include "../variables/variable.hpp"
|
||||
|
||||
/* 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 */
|
||||
parent->children[parent->num_children] = child;
|
||||
parent->num_children++;
|
||||
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) {
|
||||
std::cerr << "Error, " << error << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void print_tree(struct Node* node, uint tabs) {
|
||||
void print_tree(Node* node, uint tabs) {
|
||||
uint i;
|
||||
/* base case */
|
||||
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 */
|
||||
if(!node) {
|
||||
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
|
||||
double temp;
|
||||
struct Variable* var = nullptr;
|
||||
struct Environment* local_env = nullptr;
|
||||
struct Node* tempNode = nullptr;
|
||||
struct Value* tempVal = nullptr;
|
||||
Variable* var = nullptr;
|
||||
Environment* local_env = nullptr;
|
||||
Node* tempNode = nullptr;
|
||||
Value* tempVal = nullptr;
|
||||
|
||||
// Evaluate subexpressions if existent and node is not a lambda expression
|
||||
struct Value* val1 = nullptr;
|
||||
struct Value* val2 = nullptr;
|
||||
Value* val1 = nullptr;
|
||||
Value* val2 = nullptr;
|
||||
// struct Value* val3 = nullptr;
|
||||
if (node->num_children > 0 && node->type != LAMBDATAG) {
|
||||
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
|
||||
eval_expression(node->children[1], env)));
|
||||
tempVal = eval_expression(tempNode->children[1], local_env);
|
||||
delete_environment(local_env);
|
||||
// delete local_env;
|
||||
delete local_env;
|
||||
return tempVal;
|
||||
break;
|
||||
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 */
|
||||
if(!node) {
|
||||
fprintf(stderr, "Error: No tree structure to evaluate\n");
|
||||
return;
|
||||
}
|
||||
|
||||
struct Value* tempVal;
|
||||
Value* tempVal;
|
||||
|
||||
switch(node->type) {
|
||||
case ASSIGN:
|
||||
|
|
|
@ -3,33 +3,38 @@
|
|||
|
||||
#include <string>
|
||||
#include <array>
|
||||
#include <iostream>
|
||||
#include "../variables/value.hpp"
|
||||
#include "../variables/environment.hpp"
|
||||
|
||||
#define MAX_CHILDREN 3
|
||||
|
||||
class Value;
|
||||
class Environment;
|
||||
|
||||
/* a tree node definition */
|
||||
struct Node {
|
||||
class Node {
|
||||
public:
|
||||
int type;
|
||||
struct Value* value;
|
||||
Value* value;
|
||||
|
||||
/* the id of the node (used for identifiers only) */
|
||||
std::string id;
|
||||
|
||||
/* at most three children nodes */
|
||||
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;
|
||||
value = v;
|
||||
id = s;
|
||||
num_children = 0;
|
||||
for (uint i = 0; i < MAX_CHILDREN; i++) {
|
||||
children[i] = nullptr;
|
||||
}
|
||||
}
|
||||
~Node() {
|
||||
if (value) { delete value; }
|
||||
// delete value;
|
||||
for (uint i = 0; i < num_children; i++) {
|
||||
delete children[i];
|
||||
|
@ -39,11 +44,11 @@ struct Node {
|
|||
|
||||
// Abstract Syntax Tree Functions
|
||||
// struct Node* make_node(int type, struct Value* value, std::string id);
|
||||
void attach_node(struct Node* parent, struct Node* child);
|
||||
void print_tree(struct Node* node, int tabs);
|
||||
void attach_node(Node* parent, Node* child);
|
||||
void print_tree(Node* node, int tabs);
|
||||
|
||||
// Interpreting AST
|
||||
void eval_statement(struct Node* node, struct Environment* env);
|
||||
struct Value* eval_expression(struct Node* node, struct Environment* env);
|
||||
void eval_statement(Node* node, Environment* env);
|
||||
Value* eval_expression(Node* node, Environment* env);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -2,14 +2,14 @@
|
|||
#include "operators.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->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)) {
|
||||
std::cerr << "Error, cannot add a string with another data type." << std::endl;
|
||||
}
|
||||
|
||||
struct Value* ans;
|
||||
Value* ans;
|
||||
|
||||
// Destruct all four cases
|
||||
if (x->type == LONG && y->type == LONG) {
|
||||
|
@ -27,12 +27,12 @@ struct Value* add(struct Value* x, struct Value* y) {
|
|||
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->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; }
|
||||
|
||||
struct Value* ans;
|
||||
Value* ans;
|
||||
|
||||
// Destruct all four cases
|
||||
if (x->type == LONG && y->type == LONG) {
|
||||
|
@ -48,12 +48,12 @@ struct Value* subtract(struct Value* x, struct Value* y) {
|
|||
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->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; }
|
||||
|
||||
struct Value* ans;
|
||||
Value* ans;
|
||||
|
||||
// Destruct all four cases
|
||||
if (x->type == LONG && y->type == LONG) {
|
||||
|
@ -69,12 +69,12 @@ struct Value* division(struct Value* x, struct Value* y) {
|
|||
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->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; }
|
||||
|
||||
struct Value* ans;
|
||||
Value* ans;
|
||||
|
||||
// Destruct all four cases
|
||||
if (x->type == LONG && y->type == LONG) {
|
||||
|
@ -90,14 +90,14 @@ struct Value* multiplication(struct Value* x, struct Value* y) {
|
|||
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->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)) {
|
||||
std::cerr << "Error, cannot compare a string with another data type." << std::endl;
|
||||
}
|
||||
|
||||
struct Value* ans;
|
||||
Value* ans;
|
||||
|
||||
// Destruct all four cases
|
||||
if (x->type == LONG && y->type == LONG) {
|
||||
|
@ -115,14 +115,14 @@ struct Value* less(struct Value* x, struct Value* y) {
|
|||
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->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)) {
|
||||
std::cerr << "Error, cannot compare a string with another data type." << std::endl;
|
||||
}
|
||||
|
||||
struct Value* ans;
|
||||
Value* ans;
|
||||
|
||||
// Destruct all four cases
|
||||
if (x->type == LONG && y->type == LONG) {
|
||||
|
@ -140,14 +140,14 @@ struct Value* greater(struct Value* x, struct Value* y) {
|
|||
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->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)) {
|
||||
std::cerr << "Error, cannot compare a string with another data type." << std::endl;
|
||||
}
|
||||
|
||||
struct Value* ans;
|
||||
Value* ans;
|
||||
|
||||
// Destruct all four cases
|
||||
if (x->type == LONG && y->type == LONG) {
|
||||
|
@ -165,14 +165,14 @@ struct Value* less_equal(struct Value* x, struct Value* y) {
|
|||
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->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)) {
|
||||
std::cerr << "Error, cannot compare a string with another data type." << std::endl;
|
||||
}
|
||||
|
||||
struct Value* ans;
|
||||
Value* ans;
|
||||
|
||||
// Destruct all four cases
|
||||
if (x->type == LONG && y->type == LONG) {
|
||||
|
@ -190,13 +190,13 @@ struct Value* greater_equal(struct Value* x, struct Value* y) {
|
|||
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->type == STRING || y->type == STRING) && (x->type != STRING || y->type != STRING)) {
|
||||
std::cerr << "Error, cannot compare a string with another data type." << std::endl;
|
||||
}
|
||||
|
||||
struct Value* ans = nullptr;
|
||||
Value* ans = nullptr;
|
||||
|
||||
// Destruct all four cases
|
||||
if (x->type == LONG && y->type == LONG) {
|
||||
|
@ -218,13 +218,13 @@ struct Value* equals(struct Value* x, struct Value* y) {
|
|||
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->type == STRING || y->type == STRING) && (x->type != STRING || y->type != STRING)) {
|
||||
std::cerr << "Error, cannot compare a string with another data type." << std::endl;
|
||||
}
|
||||
|
||||
struct Value* ans= nullptr;
|
||||
Value* ans= nullptr;
|
||||
|
||||
// Destruct all four cases
|
||||
if (x->type == LONG && y->type == LONG) {
|
||||
|
@ -246,7 +246,7 @@ struct Value* not_equals(struct Value* x, struct Value* y) {
|
|||
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->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; }
|
||||
|
@ -254,7 +254,7 @@ struct Value* and_value(struct Value* x, struct Value* 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->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; }
|
||||
|
@ -262,7 +262,7 @@ struct Value* or_value(struct Value* x, struct Value* 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->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; }
|
||||
|
|
|
@ -2,18 +2,18 @@
|
|||
#define OPERATORS_H
|
||||
#include "../variables/value.hpp"
|
||||
|
||||
struct Value* add(struct Value* x, struct Value* y);
|
||||
struct Value* subtract(struct Value* x, struct Value* y);
|
||||
struct Value* division(struct Value* x, struct Value* y);
|
||||
struct Value* multiplication(struct Value* x, struct Value* y);
|
||||
struct Value* less(struct Value* x, struct Value* y);
|
||||
struct Value* greater(struct Value* x, struct Value* y);
|
||||
struct Value* less_equal(struct Value* x, struct Value* y);
|
||||
struct Value* greater_equal(struct Value* x, struct Value* y);
|
||||
struct Value* equals(struct Value* x, struct Value* y);
|
||||
struct Value* not_equals(struct Value* x, struct Value* y);
|
||||
struct Value* and_value(struct Value* x, struct Value* y);
|
||||
struct Value* or_value(struct Value* x, struct Value* y);
|
||||
struct Value* not_value(struct Value* x);
|
||||
Value* add(Value* x, Value* y);
|
||||
Value* subtract(Value* x, Value* y);
|
||||
Value* division(Value* x, Value* y);
|
||||
Value* multiplication(Value* x, Value* y);
|
||||
Value* less(Value* x, Value* y);
|
||||
Value* greater(Value* x, Value* y);
|
||||
Value* less_equal(Value* x, Value* y);
|
||||
Value* greater_equal(Value* x, Value* y);
|
||||
Value* equals(Value* x, Value* y);
|
||||
Value* not_equals(Value* x, Value* y);
|
||||
Value* and_value(Value* x, Value* y);
|
||||
Value* or_value(Value* x, Value* y);
|
||||
Value* not_value(Value* x);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -48,7 +48,7 @@ void start_shell() {
|
|||
printf("Welcome to SLOTH Version 0.0.1\n");
|
||||
printf("Press CTRL+C to Exit\n");
|
||||
|
||||
struct Environment* env = new Environment();
|
||||
Environment* env = new Environment();
|
||||
while (1) {
|
||||
// Read line from user and input it into the history
|
||||
char* input = readline("sloth> ");
|
||||
|
@ -69,7 +69,6 @@ void start_shell() {
|
|||
eval_statement(result, env);
|
||||
}
|
||||
|
||||
delete_environment(env);
|
||||
// delete env;
|
||||
delete env;
|
||||
delete result;
|
||||
}
|
|
@ -4,7 +4,7 @@
|
|||
#include "environment.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(),
|
||||
[id](const Variable* element) {
|
||||
return element->id == id;
|
||||
|
@ -17,9 +17,9 @@ struct Variable* find_variable(struct Environment* env, std::string id) {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
void add_variable(struct Environment* env, struct Variable* var) {
|
||||
void add_variable(Environment* env, Variable* var) {
|
||||
// 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) {
|
||||
temp_var->value = var->value;
|
||||
free(var);
|
||||
|
@ -30,9 +30,3 @@ void add_variable(struct Environment* env, struct Variable* 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);
|
||||
}
|
||||
|
|
|
@ -5,19 +5,21 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
struct Environment {
|
||||
std::vector<struct Variable*> vars;
|
||||
class Variable;
|
||||
|
||||
class Environment {
|
||||
public:
|
||||
std::vector<Variable*> vars;
|
||||
Environment() { }
|
||||
// ~Environment() {
|
||||
// for (uint i = 0; i < size(vars); i++) {
|
||||
// delete vars[i];
|
||||
// }
|
||||
// }
|
||||
~Environment() {
|
||||
for (uint i = 0; i < size(vars); i++) {
|
||||
delete vars[i];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Variable Lookup Functions
|
||||
void delete_environment(struct Environment* env);
|
||||
struct Variable* find_variable(struct Environment* env, std::string id);
|
||||
void add_variable(struct Environment* env, struct Variable* var);
|
||||
Variable* find_variable(Environment* env, std::string id);
|
||||
void add_variable(Environment* env, Variable* var);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -2,65 +2,74 @@
|
|||
#include "value.hpp"
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <variant>
|
||||
#include "../parser/parser.tab.h"
|
||||
|
||||
struct Value* make_long(long num) {
|
||||
Value* make_long(long num) {
|
||||
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, "");
|
||||
}
|
||||
struct Value* make_true() {
|
||||
Value* make_true() {
|
||||
return new Value(BOOLEAN, 1, 0, nullptr, "");
|
||||
}
|
||||
struct Value* make_false() {
|
||||
Value* make_false() {
|
||||
return new Value(BOOLEAN, 0, 0, nullptr, "");
|
||||
}
|
||||
struct Value* make_boolean(int x) {
|
||||
Value* make_boolean(int x) {
|
||||
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, "");
|
||||
}
|
||||
struct Value* make_string(std::string str) {
|
||||
Value* make_string(std::string str) {
|
||||
return new Value(STRING, 0, 0, nullptr, str);
|
||||
}
|
||||
|
||||
void delete_value(struct Value* val) {
|
||||
void delete_value(Value* val) {
|
||||
free(val);
|
||||
}
|
||||
|
||||
long get_long(struct Value* val) {
|
||||
return val->value.num;
|
||||
long get_long(Value* val) {
|
||||
// return val->value.num;
|
||||
return std::get<long>(val->val);
|
||||
}
|
||||
double get_double(struct Value* val) {
|
||||
return val->value.dec;
|
||||
double get_double(Value* val) {
|
||||
// return val->value.dec;
|
||||
return std::get<double>(val->val);
|
||||
}
|
||||
struct Node* get_expression(struct Value* val) {
|
||||
return val->value.expr;
|
||||
Node* get_expression(Value* val) {
|
||||
// return val->value.expr;
|
||||
return std::get<Node*>(val->val);
|
||||
}
|
||||
std::string get_string(struct Value* val) {
|
||||
return val->value.str;
|
||||
std::string get_string(Value* val) {
|
||||
// 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->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->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->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->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 (get_long(val)) {
|
||||
std::cout << "true";
|
||||
|
|
|
@ -1,35 +1,37 @@
|
|||
#ifndef VALUE_H
|
||||
#define VALUE_H
|
||||
|
||||
#include "../operations/node.hpp"
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <variant>
|
||||
|
||||
class Node;
|
||||
|
||||
enum TypeTag { DOUBLE, LONG, BOOLEAN, STRING, LAMBDA };
|
||||
|
||||
union TypeVal {
|
||||
long num;
|
||||
double dec;
|
||||
struct Node* expr;
|
||||
std::string str;
|
||||
TypeVal() { new(&str) std::string(); new(expr) struct Node*; }
|
||||
~TypeVal() { free(&str); free(expr); }
|
||||
};
|
||||
class Value {
|
||||
public:
|
||||
enum TypeTag type;
|
||||
std::variant<long, double, Node*, std::string> val;
|
||||
|
||||
struct Value {
|
||||
enum TypeTag type;
|
||||
TypeVal value;
|
||||
// Broken implemenation of constructor below
|
||||
Value(TypeTag t, long n, double d, struct Node* e, std::string s) {
|
||||
/* set properties */
|
||||
type = t;
|
||||
if (type == LONG || type == BOOLEAN) {
|
||||
value.num = n;
|
||||
} else if (type == DOUBLE){ // Assume DOUBLE
|
||||
value.dec = d;
|
||||
} else if (type == STRING) {
|
||||
value.str = s;
|
||||
} else { // Assume lambda expression
|
||||
value.expr = e;
|
||||
Value(TypeTag t, long n, double d, Node* e, std::string s) {
|
||||
/* set properties */
|
||||
type = t;
|
||||
|
||||
if (type == LONG || type == BOOLEAN) {
|
||||
val = n;
|
||||
} else if (type == DOUBLE){ // Assume DOUBLE
|
||||
val = d;
|
||||
} else if (type == STRING) {
|
||||
val = s;
|
||||
} else { // Assume lambda expression
|
||||
val = e;
|
||||
}
|
||||
}
|
||||
|
||||
~Value() {
|
||||
std::cout << "VALUE DESTROYED" << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -2,12 +2,12 @@
|
|||
#include <string>
|
||||
#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; }
|
||||
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; }
|
||||
return var->value;
|
||||
}
|
|
@ -2,26 +2,33 @@
|
|||
#define VARIABLE_H
|
||||
|
||||
#include <string>
|
||||
#include "../operations/node.hpp"
|
||||
#include "../variables/value.hpp"
|
||||
|
||||
struct Variable {
|
||||
class Value;
|
||||
class Node;
|
||||
|
||||
class Variable {
|
||||
public:
|
||||
std::string id;
|
||||
struct Value* value;
|
||||
Value* value;
|
||||
|
||||
Variable(std::string s, struct Value* val) {
|
||||
Variable(std::string s, Value* val) {
|
||||
id = s;
|
||||
value = val;
|
||||
}
|
||||
~Variable() {
|
||||
delete value;
|
||||
}
|
||||
};
|
||||
|
||||
// Variable Functions
|
||||
void set_value(struct Variable* var, struct Value* value);
|
||||
struct Value* get_value(struct Variable* var);
|
||||
struct Value* make_long(long num);
|
||||
struct Value* make_double(double dec);
|
||||
struct Value* make_true();
|
||||
struct Value* make_false();
|
||||
struct Value* make_boolean(int x);
|
||||
struct Value* make_expression(struct Node* expr);
|
||||
void set_value(Variable* var, Value* value);
|
||||
Value* get_value(Variable* var);
|
||||
Value* make_long(long num);
|
||||
Value* make_double(double dec);
|
||||
Value* make_true();
|
||||
Value* make_false();
|
||||
Value* make_boolean(int x);
|
||||
Value* make_expression(Node* expr);
|
||||
|
||||
#endif
|
||||
|
|
Reference in a new issue