Archived
1
0
Fork 0

Made toString functions and overloaded the stream operator

This commit is contained in:
Brandon Rozek 2018-09-28 22:49:26 -04:00
parent 8dd2e789c0
commit d740cc17af
4 changed files with 94 additions and 79 deletions

View file

@ -21,47 +21,53 @@ void check_num_nodes(Node* node, uint num_children, std::string error) {
} }
} }
void print_tree(Node* node, uint tabs) { std::ostream & operator << (std::ostream &out, const Node* n) {
out << n->toString();
return out;
}
std::string Node::toString() const {
return tree_string(this, 0);
}
std::string tree_string(const Node* node, uint tabs) {
std::string result = "";
uint i; uint i;
/* base case */ /* base case */
if(!node) { if(!node) {
std::cerr << "NO TREE STRUCTURE" << std::endl; result += "NO TREE STRUCTURE\n";
return; return result;
} }
/* print leading tabs */ /* print leading tabs */
for(i = 0; i < tabs; i++) { for(i = 0; i < tabs; i++) {
std::cout << " "; result += " ";
} }
switch(node->type) { switch(node->type) {
case IDENTIFIER: std::cout << "IDENTIFIER: " << node->id << std::endl; break; case IDENTIFIER: result += "IDENTIFIER: " + node->id + "\n"; break;
case PLUS: std::cout << "PLUS:" << std::endl; break; case PLUS: result += "PLUS:\n"; break;
case MINUS: std::cout << "MINUS:" << std::endl; break; case MINUS: result += "MINUS:\n"; break;
case DIVIDE: std::cout << "DIVIDE:" << std::endl; break; case DIVIDE: result += "DIVIDE:\n"; break;
case TIMES: std::cout << "TIMES:" << std::endl; break; case TIMES: result += "TIMES:\n"; break;
case LESS: std::cout << "LESS THAN:" << std::endl; break; case LESS: result += "LESS THAN:\n"; break;
case GREATER: std::cout << "GREATER:" << std::endl; break; case GREATER: result += "GREATER:\n"; break;
case LESSEQ: std::cout << "LESS EQUAL:" << std::endl; break; case LESSEQ: result += "LESS EQUAL:\n"; break;
case GREATEREQ: std::cout << "GREATER EQUAL:" << std::endl; break; case GREATEREQ: result += "GREATER EQUAL:\n"; break;
case EQUALS: std::cout << "EQUAL:" << std::endl; break; case EQUALS: result += "EQUAL:\n"; break;
case NEQUALS: std::cout << "NOT EQUAL:" << std::endl; break; case NEQUALS: result += "NOT EQUAL:\n"; break;
case AND: std::cout << "AND:" << std::endl; break; case AND: result += "AND:\n"; break;
case OR: std::cout << "OR:" << std::endl; break; case OR: result += "OR:\n"; break;
case NOT: std::cout << "NOT:" << std::endl; break; case NOT: result += "NOT:\n"; break;
case ASSIGN: std::cout << "ASSIGN:" << std::endl; break; case ASSIGN: result += "ASSIGN:\n"; break;
case IF: std::cout << "IF:" << std::endl; break; case IF: result += "IF:\n"; break;
case WHILE: std::cout << "WHILE:" << std::endl; break; case WHILE: result += "WHILE:\n"; break;
case PRINT: std::cout << "PRINT:" << std::endl; break; case PRINT: result += "PRINT:\n"; break;
case INPUT: std::cout << "INPUT:" << std::endl; break; case INPUT: result += "INPUT:\n"; break;
case LAMBDATAG: std::cout << "LAMBDA:" << std::endl; break; case LAMBDATAG: result += "LAMBDA:\n"; break;
case CALLFUNC: std::cout << "FUNCCALL:" << std::endl; break; case CALLFUNC: result += "FUNCCALL:\n"; break;
case STATEMENT: std::cout << "STATEMENT:" << std::endl; break; case STATEMENT: result += "STATEMENT:\n"; break;
case VALUE: case VALUE: result += "VALUE: " + node->value->toString() + "\n"; break;
std::cout << "VALUE: ";
print_value(node->value);
std::cout << std::endl;
break;
default: default:
std::cerr << "Error, " << node->type << " is not a valid node type." << std::endl; std::cerr << "Error, " << node->type << " is not a valid node type." << std::endl;
exit(1); exit(1);
@ -69,10 +75,11 @@ void print_tree(Node* node, uint tabs) {
/* print all children nodes underneath */ /* print all children nodes underneath */
for(i = 0; i < node->num_children; i++) { for(i = 0; i < node->num_children; i++) {
print_tree(node->children[i], tabs + 1); result += tree_string(node->children[i], tabs + 1);
} }
}
return result;
}
Value* eval_expression(Node* node, Environment* env) { Value* eval_expression(Node* node, Environment* env) {
/* base case */ /* base case */
@ -195,7 +202,6 @@ Value* eval_expression(Node* node, Environment* env) {
break; break;
//---------- //----------
case INPUT: // We're only going to support reading in doubles case INPUT: // We're only going to support reading in doubles
// Look into deleting possible values...?
scanf("%lf", &temp); scanf("%lf", &temp);
return make_double(temp); return make_double(temp);
break; break;
@ -271,8 +277,7 @@ void eval_statement(Node* node, Environment* env) {
case PRINT: case PRINT:
check_num_nodes(node, 1, "can only print out one expression at a time."); check_num_nodes(node, 1, "can only print out one expression at a time.");
tempVal = eval_expression(node->children[0], env); tempVal = eval_expression(node->children[0], env);
print_value(tempVal); std::cout << tempVal << std::endl;
printf("\n");
break; break;
//------------ //------------
case STATEMENT: // Can have a maximum of two children statement nodes case STATEMENT: // Can have a maximum of two children statement nodes

View file

@ -24,7 +24,11 @@ class Node {
/* at most three children nodes */ /* at most three children nodes */
uint num_children; uint num_children;
std::array<Node*, MAX_CHILDREN> children; std::array<Node*, MAX_CHILDREN> children;
friend std::ostream & operator << (std::ostream &out, const Node* n);
std::string toString(void) const;
Node(int t, Value* v, std::string s) { Node(int t, Value* v, std::string s) {
type = t; type = t;
value = v; value = v;
@ -45,7 +49,7 @@ class 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(Node* parent, Node* child); void attach_node(Node* parent, Node* child);
void print_tree(Node* node, int tabs); std::string tree_string(const Node* node, uint tabs);
// Interpreting AST // Interpreting AST
void eval_statement(Node* node, Environment* env); void eval_statement(Node* node, Environment* env);

View file

@ -31,26 +31,21 @@ void delete_value(Value* val) {
free(val); free(val);
} }
long get_long(Value* val) { long get_long(const Value* val) {
// return val->value.num;
return std::get<long>(val->val); return std::get<long>(val->val);
} }
double get_double(Value* val) { double get_double(const Value* val) {
// return val->value.dec;
return std::get<double>(val->val); return std::get<double>(val->val);
} }
Node* get_expression(Value* val) { Node* get_expression(const Value* val) {
// return val->value.expr;
return std::get<Node*>(val->val); return std::get<Node*>(val->val);
} }
std::string get_string(Value* val) { std::string get_string(const Value* val) {
// return val->value.str;
return std::get<std::string>(val->val); return std::get<std::string>(val->val);
} }
void set_long(Value* val, long num) { void set_long(Value* val, long num) {
val->type = LONG; val->type = LONG;
// val->value.num = num;
val->val = num; val->val = num;
} }
void set_double(Value* val, double dec) { void set_double(Value* val, double dec) {
@ -60,29 +55,36 @@ void set_double(Value* val, double dec) {
} }
void set_expression(Value* val, Node* expr) { void set_expression(Value* val, Node* expr) {
val->type = LAMBDA; val->type = LAMBDA;
// val->value.expr = expr;
val->val = expr; val->val = expr;
} }
void set_sring(Value* val, std::string str) { void set_sring(Value* val, std::string str) {
val->type = STRING; val->type = STRING;
// val->value.str = str;
val->val = str; val->val = str;
} }
void print_value(Value* val) { std::string Value::toString() const {
if (val->type == BOOLEAN) { std::string result = "";
if (get_long(val)) { if (this->type == BOOLEAN) {
std::cout << "true"; if (get_long(this)) {
result += "true";
} else { } else {
std::cout << "false"; result += "false";
} }
} else if (val->type == LONG) { } else if (this->type == LONG) {
std::cout << get_long(val); result += get_long(this);
} else if (val->type == STRING) { } else if (this->type == STRING) {
std::cout << get_string(val); result += get_string(this);
} else if (val->type == DOUBLE) { } else if (this->type == DOUBLE) {
std::cout << get_double(val); result += get_double(this);
} else { // Assume lambda expression } else { // Assume lambda expression
std::cout << "<LambdaExpression>"; result += "<LambdaExpression>";
} }
return result;
} }
std::ostream & operator << (std::ostream &out, const Value* val) {
out << val->toString();
return out;
}

View file

@ -15,6 +15,11 @@ class Value {
enum TypeTag type; enum TypeTag type;
std::variant<long, double, Node*, std::string> val; std::variant<long, 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, long n, double d, Node* e, std::string s) {
/* set properties */ /* set properties */
type = t; type = t;
@ -30,35 +35,34 @@ class Value {
} }
} }
// Destructor
~Value() { ~Value() {
std::cout << "VALUE DESTROYED" << std::endl; std::cout << "VALUE DESTROYED" << std::endl;
} }
}; };
// Constructors // Constructors
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);
struct Value* make_string(std::string str); Value* make_string(std::string str);
// Destructor // Destructor
void delete_value(struct Value* val); void delete_value(Value* val);
// Getters // Getters
long get_long(struct Value* val); long get_long(const Value* val);
double get_double(struct Value* val); double get_double(const Value* val);
struct Node* get_expression(struct Value* val); Node* get_expression(const Value* val);
std::string get_string(struct Value* val); std::string get_string(const Value* val);
// Setters // Setters
void set_long(struct Value* val, long num); void set_long(Value* val, long num);
void set_double(struct Value* val, double dec); void set_double(Value* val, double dec);
void set_expression(struct Value* val, struct Node* node); void set_expression(Value* val, Node* node);
void set_string(struct Value* val, std::string str); void set_string(Value* val, std::string str);
void print_value(struct Value* val);
#endif #endif