Advertisement
SirBaconBitz

Untitled

May 15th, 2018
146
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.61 KB | None | 0 0
  1. #include "ASTNode.h"
  2.  
  3. #include <utility>
  4. #include <iostream>
  5. #include <chrono>
  6.  
  7. SymbolTable ASTNode::globalTable = SymbolTable();
  8. const std::shared_ptr<Variable> ASTNode::nullVarPtr = std::make_shared<Variable>(null);
  9.  
  10. ASTNode::ASTNode(ASTNodeType type, std::string name): type(type), name(std::move(name)) {}
  11.  
  12. ASTNode::ASTNode(const ASTNode &other) = default;
  13.  
  14. ASTNode::~ASTNode() {
  15.     for (ASTNode* child: children) {
  16.         delete child;
  17.     }
  18.  
  19. }
  20.  
  21. std::shared_ptr<Variable> ASTNode::eval() {
  22.     ASTNodeCleaner cleaner = ASTNodeCleaner(this);
  23.     switch (type) {
  24.         case ROOT:
  25.         case PROG:
  26.         case STMT:
  27.             for (ASTNode* child : children) {
  28.                 if (child->type == RET) {
  29.                     return child->eval();
  30.                 } else {
  31.                     child->eval();
  32.                 }
  33.             }
  34.             break;
  35.         case WHILE:
  36.         {
  37.             ASTNode* condition = children.at(0);
  38.             ASTNode* block = children.at(1);
  39.             // I have no idea why this works without making it a pointer to the std::any value like I do everywhere else.
  40.             // Must just be black magic.
  41.             while (std::any_cast<bool>(condition->eval()->getValue())) {
  42.                 block->eval();
  43.             }
  44.         }
  45.         break;
  46.         case FOR:
  47.         {
  48.            
  49.             ASTNode* init = children.at(0);
  50.             ASTNode* condition = children.at(1);
  51.             ASTNode* iter = children.at(2);
  52.             ASTNode* block = children.at(3);
  53.             init->eval();
  54.             while (true) {
  55.                 if (std::any_cast<bool>(condition->eval()->getValue())) {
  56.                     block->eval();
  57.                     iter->eval();
  58.                 } else break;
  59.             }
  60.         }
  61.         break;
  62.         case IF:
  63.         {
  64.             auto condition = children.front()->eval();
  65.             if (std::any_cast<bool>(condition->getValue())) {
  66.                 if (children.size() > 1) children.at(1)->eval();
  67.                 return std::make_shared<Variable>(boole, true);
  68.             } else {
  69.                 bool metTrueCondition = false;
  70.                 for (int i = 1; i < children.size(); i++) {
  71.                     ASTNode* child = children.at(i);
  72.                     if (child->type == ELIF) {
  73.                         std::shared_ptr<Variable> childCondition = child->eval();
  74.                         if (std::any_cast<bool>(childCondition->getValue())) {
  75.                             metTrueCondition = true;
  76.                             break;
  77.                         }
  78.                     }
  79.                 }
  80.                 if (!metTrueCondition) {
  81.                     for (int i = 2; i < children.size(); i++) {
  82.                         ASTNode* child = children.at(i);
  83.                         if (child->type == STMT) {
  84.                             child->eval();
  85.                             break;
  86.                         }
  87.                     }
  88.                 }
  89.             }
  90.         }
  91.             break;
  92.         case ELIF:
  93.         {
  94.             auto condition = children.front()->eval();
  95.             if (std::any_cast<bool>(condition->getValue())) {
  96.                 if (children.size() > 1) children.at(1)->eval();
  97.                 return std::make_shared<Variable>(boole, true);
  98.             }
  99.         }
  100.             break;
  101.         case CALL:
  102.             if (name == "io.print") {
  103.                 for (ASTNode* child : children) {
  104.                     printf(child->eval()->toString().c_str());
  105.                 }
  106.             } else if (name == "io.println") {
  107.                 for (ASTNode* child : children) {
  108.                     printf(child->eval()->toString().c_str());
  109.                 }
  110.                 printf("\n");
  111.             } else if (name == "sys.clock") {
  112.                 long long ms = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
  113.                 return std::make_shared<Variable>(i64, ms);
  114.                
  115.             }  
  116.             break;
  117.         case LKP:
  118.             if (globalTable.hasSymbol(name)) {
  119.                 return std::any_cast<std::shared_ptr<Variable>>(globalTable.getSymbol(name));
  120.             } else {
  121.                 return std::any_cast<std::shared_ptr<Variable>>(getSymbol(name));
  122.             }
  123.             break;
  124.         case OP:
  125.         {
  126.             auto left = children.at(0)->eval();
  127.             if (name == "+") {
  128.                 auto right = children.at(1)->eval();
  129.                 return std::make_shared<Variable>(left->add(*right));
  130.             } else if (name == "-") {
  131.                 auto right = children.at(1)->eval();
  132.                 return std::make_shared<Variable>(left->sub(*right));
  133.             } else if (name == "*") {
  134.                 auto right = children.at(1)->eval();
  135.                 return std::make_shared<Variable>(left->mul(*right));
  136.             } else if (name == "/") {
  137.                 auto right = children.at(1)->eval();
  138.                 return std::make_shared<Variable>(left->div(*right));
  139.             } else if (name == "%") {
  140.                 auto right = children.at(1)->eval();
  141.                 return std::make_shared<Variable>(left->mod(*right));
  142.             } else if (name == "==") {
  143.                 auto right = children.at(1)->eval();
  144.                 return std::make_shared<Variable>(left->equals(*right));
  145.             } else if (name == "!=") {
  146.                 auto right = children.at(1)->eval();
  147.                 return std::make_shared<Variable>(left->notEquals(*right));
  148.             } else if (name == "=") {
  149.                 auto right = children.at(1)->eval();
  150.                 left->setValue(right->getValue());
  151.             } else if (name == "&&") {
  152.                 auto right = children.at(1)->eval();
  153.                 auto leftBool = std::any_cast<bool>(left->getValue());
  154.                 auto rightBool = std::any_cast<bool>(right->getValue());
  155.                 return std::make_shared<Variable>(boole, leftBool && rightBool);
  156.             } else if (name == "||") {
  157.                 auto right = children.at(1)->eval();
  158.                 auto leftBool = std::any_cast<bool>(left->getValue());
  159.                 auto rightBool = std::any_cast<bool>(right->getValue());
  160.                 return std::make_shared<Variable>(boole, leftBool || rightBool);
  161.             } else if (name == ">") {
  162.                 auto right = children.at(1)->eval();
  163.                 return std::make_shared<Variable>(left->greater(*right));
  164.             } else if (name == "<") {
  165.                 auto right = children.at(1)->eval();
  166.                 return std::make_shared<Variable>(left->less(*right));
  167.             } else if (name == "!") {
  168.                 return std::make_shared<Variable>(boole, !std::any_cast<bool>(left->getValue()));
  169.             }
  170.             break;
  171.         }
  172.         case DECL:
  173.         {
  174.             VariableType type = children.front()->eval()->getType();
  175.             std::shared_ptr<Variable> newVarPtr = std::make_shared<Variable>(type);
  176.             ASTNode* container = getScope();
  177.             container->localTable.addSymbol(name, newVarPtr);
  178.             return newVarPtr;
  179.         }
  180.         case TINF:
  181.             return std::make_shared<Variable>(Variable::resolveTypeString(name));
  182.             break;
  183.         case RET:
  184.             return children.front()->eval();
  185.             break;
  186.     }
  187.     return nullVarPtr;
  188. }
  189.  
  190. void ASTNode::addChild(ASTNode* node) {
  191.     children.push_back(node);
  192.     node->parent = this;
  193. }
  194.  
  195. ASTNode* ASTNode::getParent() {
  196.     return parent;
  197. }
  198.  
  199. std::vector<ASTNode*> ASTNode::getChildren() {
  200.     return children;
  201. }
  202.  
  203. void ASTNode::printRecursive(int depth, std::vector<int> continues) {
  204.     std::string typeName;
  205.     switch (type) {
  206.         case ROOT:
  207.             typeName = "ROOT";
  208.             break;
  209.         case PROG:
  210.             typeName = "PROG";
  211.             break;
  212.         case STMT:
  213.             typeName = "STMT";
  214.             break;
  215.         case FOR:
  216.             typeName = "FOR";
  217.             break;
  218.         case WHILE:
  219.             typeName = "WHILE";
  220.             break;
  221.         case IF:
  222.             typeName = "IF";
  223.             break;
  224.         case ELIF:
  225.             typeName = "ELIF";
  226.             break;
  227.         case CALL:
  228.             typeName = "CALL";
  229.             break;
  230.         case LKP:
  231.             typeName = "LKP";
  232.             break;
  233.         case DECL:
  234.             typeName = "DECL";
  235.             break;
  236.         case TINF:
  237.             typeName = "TINF";
  238.             break;
  239.         case DESTR:
  240.             typeName = "DESTR";
  241.             break;
  242.         case OP:
  243.             typeName = "OP";
  244.             break;
  245.         case RET:
  246.             typeName = "RET";
  247.             break;
  248.     }
  249.     std::cout << name << ", " << typeName << ", " << children.size() << ", " << this << std::endl;
  250.     continues.push_back(depth);
  251.     for (ASTNode* child : children) {
  252.         int startPoint = 0;
  253.         int highest = 0;
  254.         for (int i : continues) if (i > highest) highest = i;
  255.         for (int i = 0; i < depth; i++) {
  256.             if (std::find(continues.begin(), continues.end(), i + 1) != continues.end()) {
  257.                 if (i + 1 != highest) {
  258.                     std::cout << "|    ";
  259.                 } else {
  260.                     std::cout << "|---";
  261.                     if (i + 1 == depth) {
  262.                         std::cout << ">";
  263.                     } else {
  264.                         std::cout << "-";
  265.                     }
  266.                     startPoint = i;
  267.                     break;
  268.                 }
  269.             } else {
  270.                 std::cout << "     ";
  271.             }
  272.         }
  273.         for (int i = startPoint; i < depth - 1; i++) {
  274.             std::cout << "-----";
  275.         }
  276.         if (startPoint + 1 != depth) std::cout << "---->";
  277.         if (child == children.back()) {
  278.             auto iterator = std::find(continues.begin(), continues.end(), depth);
  279.             if (iterator != continues.end()) continues.erase(iterator);
  280.         }
  281.         child->printRecursive(depth + 1, continues);
  282.     }
  283. }
  284.  
  285. std::any ASTNode::getSymbol(std::string name) {
  286.     if (localTable.hasSymbol(name)) {
  287.         return localTable.getSymbol(name);
  288.     } else if (type != ROOT && parent != nullptr) {
  289.         return parent->getSymbol(name);
  290.     } else {
  291.         return nullptr;
  292.     }
  293. }
  294.  
  295. void ASTNode::cleanLocalTable() {
  296.     localTable.deleteSymbols();
  297. }
  298.  
  299. ASTNode *ASTNode::getScope() {
  300.     if (type <= ELIF) {
  301.         return this;
  302.     } else if (type != ROOT) {
  303.         return parent->getScope();
  304.     } else {
  305.         return nullptr;
  306.     }
  307. }
  308.  
  309. ASTNodeCleaner::ASTNodeCleaner(ASTNode *target): target(target) {}
  310.  
  311. ASTNodeCleaner::~ASTNodeCleaner() {
  312.     if (target->type <= ELIF) {
  313.         target->cleanLocalTable();
  314.     }
  315. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement