Last active
November 28, 2017 03:42
-
-
Save veryjos/a8050ff80f78f6465c7e37e2a2fb2f10 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Success #stdin #stdout 0s 16072KB | |
76 | |
69 | |
FooBar | |
hey | |
there bud |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <vector> | |
#include <stack> | |
#include <string> | |
/** | |
* Variant type to stick in the stack | |
**/ | |
enum VariantType { | |
VariantType_None, | |
VariantType_Int, | |
VariantType_String | |
}; | |
class Variant { | |
public: | |
Variant(int num) : num(num), type(VariantType_Int) { | |
}; | |
Variant(std::string str) : str(str), type(VariantType_String) { | |
}; | |
VariantType GetType() { | |
return type; | |
}; | |
int AsInt() { | |
return num; | |
}; | |
std::string AsString() { | |
return str; | |
}; | |
private: | |
VariantType type; | |
int num; | |
std::string str; | |
}; | |
/** | |
* Base node type for syntax tree | |
**/ | |
class Node { | |
public: | |
std::vector<Node*> children; | |
virtual void Accept(std::stack<Variant>* stack) { | |
// Visit each child (this will be postorder) | |
for (auto child : children) { | |
child->Accept(stack); | |
} | |
}; | |
}; | |
/** | |
* Node which prints out the top of the stack | |
**/ | |
class PrintNode : public Node { | |
public: | |
virtual void Accept(std::stack<Variant>* stack) override { | |
// If empty do nothing | |
if (children.empty()) | |
return; | |
// Visit lefthand side | |
children[0]->Accept(stack); | |
// Pop the last value off the stack (added by children) | |
// and evaluate them. Push the result on the stack. | |
Variant value = stack->top(); | |
stack->pop(); | |
switch (value.GetType()) { | |
case VariantType_Int: | |
printf("%d\n", value.AsInt()); | |
break; | |
case VariantType_String: | |
printf("%s\n", value.AsString().c_str()); | |
break; | |
}; | |
// Visit the rest of the children | |
for (int i=1;i<children.size();++i) { | |
children[i]->Accept(stack); | |
} | |
}; | |
}; | |
/** | |
* Node for adding two NumberNodes | |
**/ | |
class AddNode : public Node { | |
public: | |
void Accept(std::stack<Variant>* stack) override { | |
// Visit the left node, then the right node | |
children[0]->Accept(stack); | |
children[1]->Accept(stack); | |
// Pop the last two values off the stack (added by children) | |
// and add them. Push the result on the stack | |
Variant rightHandSide = stack->top(); | |
stack->pop(); | |
Variant leftHandSide = stack->top(); | |
stack->pop(); | |
// Add them as ints | |
if (leftHandSide.GetType() == VariantType_Int && | |
rightHandSide.GetType() == VariantType_Int) { | |
// Push the result | |
stack->push(Variant(leftHandSide.AsInt() + rightHandSide.AsInt())); | |
} | |
// Or as strings | |
else | |
if (leftHandSide.GetType() == VariantType_String && | |
rightHandSide.GetType() == VariantType_String) { | |
// Push the result | |
stack->push(Variant(leftHandSide.AsString() + rightHandSide.AsString())); | |
} | |
}; | |
}; | |
/** | |
* Represents a number literal | |
**/ | |
class NumberNode : public Node { | |
public: | |
NumberNode(int num) : value(num) {}; | |
void Accept(std::stack<Variant>* stack) override { | |
stack->push(Variant(value)); | |
}; | |
int value; | |
}; | |
/** | |
* Represents a string literal | |
**/ | |
class StringNode : public Node { | |
public: | |
StringNode(std::string str) : value(str) {}; | |
void Accept(std::stack<Variant>* stack) override { | |
stack->push(Variant(value)); | |
}; | |
std::string value; | |
}; | |
int main() { | |
///////////////////////////////// | |
// / | |
// Add | |
// / \ | |
// 1 Add | |
// / \ | |
// 50 25 | |
///////////////////////////////// | |
{ | |
// Create a print node at root | |
auto printNode = new PrintNode(); | |
// Do some math | |
auto addNodeOuter = new AddNode(); | |
auto addNodeInner = new AddNode(); | |
addNodeOuter->children.push_back(new NumberNode(1)); | |
addNodeInner->children.push_back(new NumberNode(50)); | |
addNodeInner->children.push_back(new NumberNode(25)); | |
addNodeOuter->children.push_back(addNodeInner); // Righthand side is the inner node | |
// We want to print the result of this, so push the outer node | |
printNode->children.push_back(addNodeOuter); | |
// Start visiting the tree from the root print node | |
printNode->Accept(new std::stack<Variant>()); | |
} | |
///////////////////////////////// | |
// / | |
// 69 | |
///////////////////////////////// | |
{ | |
// Create a print node at root | |
auto printNode = new PrintNode(); | |
// Just stick a number there | |
printNode->children.push_back(new NumberNode(69)); | |
// Start visiting the tree from the root print node | |
printNode->Accept(new std::stack<Variant>()); | |
} | |
///////////////////////////////// | |
// / | |
// Add | |
// / \ | |
// "Foo" "Bar" | |
///////////////////////////////// | |
{ | |
// Create a print node at root | |
auto printNode = new PrintNode(); | |
// Just add two string literals | |
auto addNode = new AddNode(); | |
addNode->children.push_back(new StringNode("Foo")); | |
addNode->children.push_back(new StringNode("Bar")); | |
// Add to the print node's children | |
printNode->children.push_back(addNode); | |
// Start visiting the tree from the root print node | |
printNode->Accept(new std::stack<Variant>()); | |
} | |
///////////////////////////////// | |
// / \ | |
// "hey " Print | |
// / | |
// Add | |
// / \ | |
// "there " "bud" | |
///////////////////////////////// | |
{ | |
// Create a print node at root | |
auto printNode = new PrintNode(); | |
printNode->children.push_back(new StringNode("hey ")); | |
// Create a print node for the righthand side | |
auto printNodeRight = new PrintNode(); | |
// Just add two string literals | |
auto addNode = new AddNode(); | |
addNode->children.push_back(new StringNode("there ")); | |
addNode->children.push_back(new StringNode("bud")); | |
// Add to the right print node's children | |
printNodeRight->children.push_back(addNode); | |
// And finally add the right print node to the root print node's right side | |
printNode->children.push_back(printNodeRight); | |
// Start visiting the tree from the root print node | |
printNode->Accept(new std::stack<Variant>()); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment