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

View file

@ -24,7 +24,11 @@ class Node {
/* at most three children nodes */
uint num_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) {
type = t;
value = v;
@ -45,7 +49,7 @@ class Node {
// Abstract Syntax Tree Functions
// struct Node* make_node(int type, struct Value* value, std::string id);
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
void eval_statement(Node* node, Environment* env);

View file

@ -31,26 +31,21 @@ void delete_value(Value* val) {
free(val);
}
long get_long(Value* val) {
// return val->value.num;
long get_long(const Value* val) {
return std::get<long>(val->val);
}
double get_double(Value* val) {
// return val->value.dec;
double get_double(const Value* val) {
return std::get<double>(val->val);
}
Node* get_expression(Value* val) {
// return val->value.expr;
Node* get_expression(const Value* val) {
return std::get<Node*>(val->val);
}
std::string get_string(Value* val) {
// return val->value.str;
std::string get_string(const Value* val) {
return std::get<std::string>(val->val);
}
void set_long(Value* val, long num) {
val->type = LONG;
// val->value.num = num;
val->val = num;
}
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) {
val->type = LAMBDA;
// val->value.expr = expr;
val->val = expr;
}
void set_sring(Value* val, std::string str) {
val->type = STRING;
// val->value.str = str;
val->val = str;
}
void print_value(Value* val) {
if (val->type == BOOLEAN) {
if (get_long(val)) {
std::cout << "true";
std::string Value::toString() const {
std::string result = "";
if (this->type == BOOLEAN) {
if (get_long(this)) {
result += "true";
} else {
std::cout << "false";
result += "false";
}
} else if (val->type == LONG) {
std::cout << get_long(val);
} else if (val->type == STRING) {
std::cout << get_string(val);
} else if (val->type == DOUBLE) {
std::cout << get_double(val);
} else if (this->type == LONG) {
result += get_long(this);
} else if (this->type == STRING) {
result += get_string(this);
} else if (this->type == DOUBLE) {
result += get_double(this);
} 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;
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) {
/* set properties */
type = t;
@ -30,35 +35,34 @@ class Value {
}
}
// Destructor
~Value() {
std::cout << "VALUE DESTROYED" << std::endl;
}
};
// Constructors
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);
struct Value* make_string(std::string str);
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);
Value* make_string(std::string str);
// Destructor
void delete_value(struct Value* val);
void delete_value(Value* val);
// Getters
long get_long(struct Value* val);
double get_double(struct Value* val);
struct Node* get_expression(struct Value* val);
std::string get_string(struct Value* val);
long get_long(const Value* val);
double get_double(const Value* val);
Node* get_expression(const Value* val);
std::string get_string(const Value* val);
// Setters
void set_long(struct Value* val, long num);
void set_double(struct Value* val, double dec);
void set_expression(struct Value* val, struct Node* node);
void set_string(struct Value* val, std::string str);
void print_value(struct Value* val);
void set_long(Value* val, long num);
void set_double(Value* val, double dec);
void set_expression(Value* val, Node* node);
void set_string(Value* val, std::string str);
#endif