void printAST(struct ast_node *node){ int i; struct set_iterator si; int value; if(node->leafNumber >= 0){ printf("%d: nullable:[%s] ", node->leafNumber, node->nullable ? "YES" : "NO"); printf("firstpos:[ "); si = setIterator(node->firstpos); while(nextSetItem(&si, &value)){ printf("%d ", value); } printf("] lastpos:[ "); si = setIterator(node->lastpos); while(nextSetItem(&si, &value)){ printf("%d ", value); } printf("] followpos:[ "); si = setIterator(node->followpos); while(nextSetItem(&si, &value)){ printf("%d ", value); } printf("]\n"); } if(node->child0){ printAST(node->child0); } if(node->child1){ printAST(node->child1); } }
// Pretty-prints a lisp AST std::string printAST(Node ast, bool printMetadata) { if (ast.type == TOKEN) return ast.val; std::string o = "("; if (printMetadata) { o += ast.metadata.file + " "; o += unsignedToDecimal(ast.metadata.ln) + " "; o += unsignedToDecimal(ast.metadata.ch) + ": "; } o += ast.val; std::vector<std::string> subs; for (unsigned i = 0; i < ast.args.size(); i++) { subs.push_back(printAST(ast.args[i], printMetadata)); } unsigned k = 0; std::string out = " "; // As many arguments as possible go on the same line as the function, // except when seq is used while (k < subs.size() && o != "(seq") { if (subs[k].find("\n") != std::string::npos || (out + subs[k]).length() >= 80) break; out += subs[k] + " "; k += 1; } // All remaining arguments go on their own lines if (k < subs.size()) { o += out + "\n"; std::vector<std::string> subsSliceK; for (unsigned i = k; i < subs.size(); i++) subsSliceK.push_back(subs[i]); o += indentLines(joinLines(subsSliceK)); o += "\n)"; } else { o += out.substr(0, out.size() - 1) + ")"; } return o; }
/* print tree */ void printAST(ASTTREE tree) { if(tree) { printf("[%p] NodeType=%s, ival=%d, type=", tree, humanReadableState(tree->typeNoeud), tree->ival); if(tree->type == NULL) printf("NULL"); else printf("%s",tree->type); printf(" sval ="); if (tree->sval == NULL) printf("NULL"); else printf("'%s'", tree->sval); printf(", up=%p, down=%p, left=%p, right=%p, numLine =%d\n", tree->up, tree->down, tree->left, tree->right,tree->numLine); printAST(tree->up); printAST(tree->down); printAST(tree->left); printAST(tree->right); } }
void printAST(is_node* node, int tabs) { if(node->type != NoNode) { int i; for(i = 0; i < tabs; i++) printf(" "); if(node->id) printf("%s(%s)\n", types[node->type], node->id); else printf("%s\n", types[node->type]); } if(node->child) printAST(node->child, tabs + 1); if(node->next) printAST(node->next, tabs); }
void ClangInternalState::store() { // Cannot use the stack (private copy ctor) llvm::OwningPtr<llvm::raw_fd_ostream> m_LookupTablesOS; llvm::OwningPtr<llvm::raw_fd_ostream> m_IncludedFilesOS; llvm::OwningPtr<llvm::raw_fd_ostream> m_ASTOS; llvm::OwningPtr<llvm::raw_fd_ostream> m_LLVMModuleOS; llvm::OwningPtr<llvm::raw_fd_ostream> m_MacrosOS; m_LookupTablesOS.reset(createOutputFile("lookup", &m_LookupTablesFile)); m_IncludedFilesOS.reset(createOutputFile("included", &m_IncludedFilesFile)); m_ASTOS.reset(createOutputFile("ast", &m_ASTFile)); m_LLVMModuleOS.reset(createOutputFile("module", &m_LLVMModuleFile)); m_MacrosOS.reset(createOutputFile("macros", &m_MacrosFile)); printLookupTables(*m_LookupTablesOS.get(), m_ASTContext); printIncludedFiles(*m_IncludedFilesOS.get(), m_ASTContext.getSourceManager()); printAST(*m_ASTOS.get(), m_ASTContext); printLLVMModule(*m_LLVMModuleOS.get(), m_Module); printMacroDefinitions(*m_MacrosOS.get(), m_Preprocessor); }
int main(int argc, char* argv[]) { if (argc != 2) { fprintf(stderr, "usage: %s <filename>\n", argv[0]); exit(1); } char pgm[120]; strcpy(pgm, argv[1]); if (strchr(pgm, '.') == NULL) strcat(pgm, ".cm"); source = fopen(pgm, "r"); if (source == NULL) { fprintf(stderr, "File %s not found\n", pgm); exit(1); } listing = stdout; #if NO_PARSE while (getToken() != ENDFILE); #else ASTNode* root = parse(); if (TraceParse) { fprintf(listing,"\nSyntax tree:\n"); printAST(root); } #endif if (!Error) { int fnlen = strcspn(pgm,"."); char* codefile = (char *) calloc(fnlen+1, sizeof(char)); strncpy(codefile,pgm,fnlen); codeGen(root, codefile); } fclose(source); return 0; }
int main(int argv, char** argc) { if (argv == 1) { std::cerr << "Must provide a command and arguments! Try parse, rewrite, compile, assemble\n"; return 0; } std::string flag = ""; std::string command = argc[1]; std::string input; std::string secondInput; if (std::string(argc[1]) == "-s") { flag = command.substr(1); command = argc[2]; input = ""; std::string line; while (std::getline(std::cin, line)) { input += line + "\n"; } secondInput = argv == 3 ? "" : argc[3]; } else { if (argv == 2) { std::cerr << "Not enough arguments for serpent cmdline\n"; throw(0); } input = argc[2]; secondInput = argv == 3 ? "" : argc[3]; } bool haveSec = secondInput.length() > 0; if (command == "parse" || command == "parse_serpent") { std::cout << printAST(parseSerpent(input), haveSec) << "\n"; } else if (command == "rewrite") { std::cout << printAST(rewrite(parseLLL(input, true)), haveSec) << "\n"; } else if (command == "compile_to_lll") { std::cout << printAST(compileToLLL(input), haveSec) << "\n"; } else if (command == "build_fragtree") { std::cout << printAST(buildFragmentTree(parseLLL(input, true))) << "\n"; } else if (command == "compile_lll") { std::cout << binToHex(compileLLL(parseLLL(input, true))) << "\n"; } else if (command == "dereference") { std::cout << printAST(dereference(parseLLL(input, true)), haveSec) <<"\n"; } else if (command == "pretty_assemble") { std::cout << printTokens(prettyAssemble(parseLLL(input, true))) <<"\n"; } else if (command == "pretty_compile_lll") { std::cout << printTokens(prettyCompileLLL(parseLLL(input, true))) << "\n"; } else if (command == "pretty_compile") { std::cout << printTokens(prettyCompile(input)) << "\n"; } else if (command == "assemble") { std::cout << assemble(parseLLL(input, true)) << "\n"; } else if (command == "serialize") { std::cout << binToHex(serialize(tokenize(input, Metadata(), false))) << "\n"; } else if (command == "flatten") { std::cout << printTokens(flatten(parseLLL(input, true))) << "\n"; } else if (command == "deserialize") { std::cout << printTokens(deserialize(hexToBin(input))) << "\n"; } else if (command == "compile") { std::cout << binToHex(compile(input)) << "\n"; } else if (command == "encode_datalist") { std::vector<Node> tokens = tokenize(input); std::vector<std::string> o; for (int i = 0; i < (int)tokens.size(); i++) { o.push_back(tokens[i].val); } std::cout << binToHex(encodeDatalist(o)) << "\n"; } else if (command == "decode_datalist") { std::vector<std::string> o = decodeDatalist(hexToBin(input)); std::vector<Node> tokens; for (int i = 0; i < (int)o.size(); i++) tokens.push_back(token(o[i])); std::cout << printTokens(tokens) << "\n"; } else if (command == "tokenize") { std::cout << printTokens(tokenize(input)); } else if (command == "biject") { if (argv == 3) std::cerr << "Not enough arguments for biject\n"; int pos = decimalToUnsigned(secondInput); std::vector<Node> n = prettyCompile(input); if (pos >= (int)n.size()) std::cerr << "Code position too high\n"; Metadata m = n[pos].metadata; std::cout << "Opcode: " << n[pos].val << ", file: " << m.file << ", line: " << m.ln << ", char: " << m.ch << "\n"; } }
void printAST(AST_node root, int lev) { std::string *space = new std::string(lev, '\t'); if (root != NULL) { switch (root->ast_type) { case TERMINAL: std::cout << *space << "Terminal\t" << root->lex_symbol << "\t"; if (root->lex_symbol == NUM) { std::cout << root->val.value << std::endl; } else { std::cout << *(root->val.ident) << std::endl; } break; case CONSTDECL: std::cout << *space << "ConstDecl" << std::endl; break; case PROGRAM: std::cout << *space << "Program" << std::endl; break; case CONSTDEF: std::cout << *space << "ConstDef" << std::endl; break; case CONST: std::cout << *space << "Const" << std::endl; break; case VAR: std::cout << *space << "VAR" << std::endl; break; case VARDECL: std::cout << *space << "VarDecl" << std::endl; break; case VARDEF: std::cout << *space << "VarDef" << std::endl; break; case PRODECL: std::cout << *space << "Procedure Declaration" << std::endl; break; case PROHEAD: std::cout << *space << "Procedure Head Declaration" << std::endl; break; case FUNDECL: std::cout << *space << "Function Declaration" << std::endl; break; case FUNHEAD: std::cout << *space << "Function Head Declaration" << std::endl; break; case ARGLIST: std::cout << *space << "Arglist" << std::endl; break; case ARGS: std::cout << *space << "Args" << std::endl; break; case EXPRESSION: std::cout << *space << "Expression" << std::endl; break; case CONDITION: std::cout << *space << "Condition" << std::endl; break; case TERM: std::cout << *space << "Term" << std::endl; break; case FACTOR: std::cout << *space << "Factor" << std::endl; break; default: break; } if (root->children->size() == 0) { return; } for (std::vector<AST_node>::iterator i = root->children->begin(); i != root->children->end(); i++) { printAST(*i, lev + 1); } } return; }
int main(int argc, const char* argv[]) { try { TCLAP::CmdLine cmd("Xylene", ' ', "pre-release"); TCLAP::SwitchArg asXML("", "xml", "Read file using the XML parser", cmd); TCLAP::SwitchArg printTokens("", "tokens", "Print token list", cmd); TCLAP::SwitchArg printAST("", "ast", "Print AST (if applicable)", cmd); TCLAP::SwitchArg printIR("", "ir", "Print LLVM IR (if applicable)", cmd); TCLAP::SwitchArg doNotParse("", "no-parse", "Don't parse the token list", cmd); TCLAP::SwitchArg doNotRun("", "no-run", "Don't execute the AST", cmd); std::vector<std::string> runnerValues {"llvm-lli", "llvm-llc"}; TCLAP::ValuesConstraint<std::string> runnerConstraint(runnerValues); TCLAP::ValueArg<std::string> runner("r", "runner", "How to run this code", false, "llvm-lli", &runnerConstraint, cmd, nullptr); TCLAP::ValueArg<std::string> code("e", "eval", "Code to evaluate", false, std::string(), "string", cmd, nullptr); TCLAP::ValueArg<std::string> filePath("f", "file", "Load code from this file", false, std::string(), "path", cmd, nullptr); cmd.parse(argc, argv); if (code.getValue().empty() && filePath.getValue().empty()) { TCLAP::ArgException arg("Must specify either option -e or -f"); cmd.getOutput()->failure(cmd, arg); } std::unique_ptr<AST> ast; if (asXML.getValue()) { if (doNotParse.getValue()) return NORMAL_EXIT; if (filePath.getValue().empty()) { TCLAP::ArgException arg("XML option only works with files"); cmd.getOutput()->failure(cmd, arg); } ast = std::make_unique<AST>(XMLParser().parse(rapidxml::file<>(filePath.getValue().c_str())).getTree()); } else { std::string input; if (!filePath.getValue().empty()) { std::ifstream file(filePath.getValue()); std::stringstream buffer; buffer << file.rdbuf(); input = buffer.str(); } else { input = code.getValue(); } auto lx = Lexer(); lx.tokenize(input, filePath.getValue().empty() ? "<cli-eval>" : filePath.getValue()); if (printTokens.getValue()) for (auto tok : lx.getTokens()) println(tok); if (doNotParse.getValue()) return NORMAL_EXIT; ast = std::make_unique<AST>(TokenParser().parse(lx.getTokens()).getTree()); } if (printAST.getValue()) ast->print(); if (doNotRun.getValue()) return NORMAL_EXIT; CompileVisitor::Link v = CompileVisitor::create("Command Line Module", *ast); v->visit(); if (printIR.getValue()) v->getModule()->dump(); if (runner.getValue() == "llvm-lli") { return Runner(v).run(); } else if (runner.getValue() == "llvm-llc") { println("Not yet implemented!"); // TODO } } catch (const TCLAP::ExitException& arg) { return CLI_ERROR; } catch (const TCLAP::ArgException& arg) { println("TCLAP error", arg.error(), "for", arg.argId()); return TCLAP_ERROR; } catch (const Error& err) { println(err.what()); return USER_PROGRAM_ERROR; } // If we're debugging, crash the program on InternalError #ifndef CRASH_ON_INTERNAL_ERROR catch (const InternalError& err) { println(err.what()); return INTERNAL_ERROR; } #endif return 0; }
int main(int argc, char** argv) { ////////////////Basic Printing///////////////////////// //printf("Submitted by Batch No. 06:\n%30s\t(%s)\n%30s\t(%s)\n\n\n", "Abhinav Bhatia", "2011A7PS371P", "Mukul Bhutani ", "2011A7PS343P"); printf("LEVEL %d: %s", 3, "AST/Symbol Table/Type checking/Symantic Rules modules work\n"); printf("Code generation implemented for most constructs\n\n"); ////////////////Basic Printing End///////////////////// FILE* pSourceFile = NULL; int choice; int isParsed = PARSER_NOT_INVOKED; if (argc > 1) { pSourceFile = fopen(argv[1], "r"); } else if (argc == 1) { printf("\nLess number of arguments ...Two arguments required....\n"); printf("1. Source Code File.\n"); printf("2. File for printing parse tree.\n"); char c; scanf("%c", &c); return 0; } if (pSourceFile == NULL) { printf("\nError: No Input File!\nExiting..........."); char c; scanf("%c", &c); return -1; } FILE* pKeywordsFile = fopen(KEYWORDS_INPUT_FILENAME, "r"); if (!pKeywordsFile) { printf("\nError: keywords file \"%s\" not found.\nExiting..........", KEYWORDS_INPUT_FILENAME); char c; scanf("%c", &c); return -1; } FILE* grammarInputFile = fopen(GRAMMAR_INPUT_FILENAME, "r"); if (!grammarInputFile) { printf("\nError: Grammar file \"%s\" not found.\nExiting..........", GRAMMAR_INPUT_FILENAME); char c; scanf("%c", &c); return -1; } FILE* astRulesFile = fopen(AST_RULES_FILENAME, "r"); if (!astRulesFile) { printf("\nError: AST Rules file \"%s\" not found.\nExiting..........", AST_RULES_FILENAME); char c; scanf("%c", &c); return -1; } Parser parser; Lexer lex = lexer_createNew(pSourceFile, pKeywordsFile); printf("\n\nPlease enter your choice\n"); printf("1. Print list of tokens.\n"); printf("2. Verify syntactic correctness of input source code.\n"); printf("3. Print Abstract Syntax Tree.\n"); printf("4. Print Symbol Table.\n"); printf("5. Verify syntactic and semantic correctness.\n"); printf("6. Produce Assembly Code.\n"); printf("7. Exit.\n"); char flushChar; scanf("%d%c", &choice, &flushChar); switch (choice) { case 1: lexer_runLexicalAnalyses(lex); break; case 2: parser = parser_initialise(grammarInputFile, astRulesFile); isParsed = printOnlyParsetree(&parser, lex, DEFAULT_OUTPUT_PARSE_TREE_FILE, isParsed); break; case 3: parser = parser_initialise(grammarInputFile, astRulesFile); isParsed = parseOnlySourceCode(&parser, lex); if (isParsed == PARSED_SUCCESSFULLY) { Tree ast = createAst(parser); printAST(ast); } break; case 4: parser = parser_initialise(grammarInputFile, astRulesFile); isParsed = parseOnlySourceCode(&parser, lex); if (isParsed == PARSED_SUCCESSFULLY) { Tree ast = createAst(parser); createSymbolTables(ast); turnOnReportingSemanticErrors(FALSE); typeExtractorandChecker(ast); printSymbolTable(); } break; case 5: parser = parser_initialise(grammarInputFile, astRulesFile); isParsed = parseOnlySourceCode(&parser, lex); if (isParsed == PARSED_SUCCESSFULLY) { Tree ast = createAst(parser); createSymbolTables(ast); printf("\n\nRunning semantic analysis...."); turnOnReportingSemanticErrors(TRUE); if (typeExtractorandChecker(ast)) { printf("\n\nCode compiles successfully..........:)"); } } break; case 6: parser = parser_initialise(grammarInputFile, astRulesFile); isParsed = parseOnlySourceCode(&parser, lex); if (isParsed == PARSED_SUCCESSFULLY) { Tree ast = createAst(parser); createSymbolTables(ast); turnOnReportingSemanticErrors(TRUE); if (typeExtractorandChecker(ast)) { printf("\n\nCode compiles successfully..........:)"); printf("\n\nGenerating Code......"); FILE* asmm = fopen(argv[2], "w"); generateCode(ast, asmm); printf("\n\nFinished code generation."); //Call code generation here } } break; case 7: return 0; break; default: printf("Invalid Choice...please enter correct choice (1-7)"); break; } char c; scanf("%c", &c); return 0; }
//TODO: Get rid of this static void printAST(size_t indent, scripting::ASTNode *node) { std::cout << "--------------------------------\n"; for (size_t i = 0; i < indent; ++i) { std::cout << " "; } switch (node->type) { case scripting::ASTNode::Assign: { std::cout << "Assign:\n"; printAST(indent+1, ((scripting::LROpNode *)node)->left); printAST(indent+1, ((scripting::LROpNode *)node)->right); break; } case scripting::ASTNode::Add: { std::cout << "Add:\n"; printAST(indent+1, ((scripting::LROpNode *)node)->left); printAST(indent+1, ((scripting::LROpNode *)node)->right); break; } case scripting::ASTNode::Subtract: { std::cout << "Subtract:\n"; printAST(indent+1, ((scripting::LROpNode *)node)->left); printAST(indent+1, ((scripting::LROpNode *)node)->right); break; } case scripting::ASTNode::Multiply: { std::cout << "Multiply:\n"; printAST(indent+1, ((scripting::LROpNode *)node)->left); printAST(indent+1, ((scripting::LROpNode *)node)->right); break; } case scripting::ASTNode::Divide: { std::cout << "Divide:\n"; printAST(indent+1, ((scripting::LROpNode *)node)->left); printAST(indent+1, ((scripting::LROpNode *)node)->right); break; } case scripting::ASTNode::Modulo: { std::cout << "Modulo:\n"; printAST(indent+1, ((scripting::LROpNode *)node)->left); printAST(indent+1, ((scripting::LROpNode *)node)->right); break; } case scripting::ASTNode::Less: { std::cout << "Less:\n"; printAST(indent+1, ((scripting::LROpNode *)node)->left); printAST(indent+1, ((scripting::LROpNode *)node)->right); break; } case scripting::ASTNode::Greater: { std::cout << "Greater:\n"; printAST(indent+1, ((scripting::LROpNode *)node)->left); printAST(indent+1, ((scripting::LROpNode *)node)->right); break; } case scripting::ASTNode::Equal: { std::cout << "Equal:\n"; printAST(indent+1, ((scripting::LROpNode *)node)->left); printAST(indent+1, ((scripting::LROpNode *)node)->right); break; } case scripting::ASTNode::NotEqual: { std::cout << "NotEqual:\n"; printAST(indent+1, ((scripting::LROpNode *)node)->left); printAST(indent+1, ((scripting::LROpNode *)node)->right); break; } case scripting::ASTNode::LessEqual: { std::cout << "LessEqual:\n"; printAST(indent+1, ((scripting::LROpNode *)node)->left); printAST(indent+1, ((scripting::LROpNode *)node)->right); break; } case scripting::ASTNode::GreaterEqual: { std::cout << "GreaterEqual:\n"; printAST(indent+1, ((scripting::LROpNode *)node)->left); printAST(indent+1, ((scripting::LROpNode *)node)->right); break; } case scripting::ASTNode::BoolAnd: { std::cout << "BoolAnd:\n"; printAST(indent+1, ((scripting::LROpNode *)node)->left); printAST(indent+1, ((scripting::LROpNode *)node)->right); break; } case scripting::ASTNode::BoolOr: { std::cout << "BoolOr:\n"; printAST(indent+1, ((scripting::LROpNode *)node)->left); printAST(indent+1, ((scripting::LROpNode *)node)->right); break; } case scripting::ASTNode::BitAnd: { std::cout << "BitAnd:\n"; printAST(indent+1, ((scripting::LROpNode *)node)->left); printAST(indent+1, ((scripting::LROpNode *)node)->right); break; } case scripting::ASTNode::BitOr: { std::cout << "BitOr:\n"; printAST(indent+1, ((scripting::LROpNode *)node)->left); printAST(indent+1, ((scripting::LROpNode *)node)->right); break; } case scripting::ASTNode::BitXOr: { std::cout << "BitXOr:\n"; printAST(indent+1, ((scripting::LROpNode *)node)->left); printAST(indent+1, ((scripting::LROpNode *)node)->right); break; } case scripting::ASTNode::LeftShift: { std::cout << "LeftShift:\n"; printAST(indent+1, ((scripting::LROpNode *)node)->left); printAST(indent+1, ((scripting::LROpNode *)node)->right); break; } case scripting::ASTNode::RightShift: { std::cout << "RightShift:\n"; printAST(indent+1, ((scripting::LROpNode *)node)->left); printAST(indent+1, ((scripting::LROpNode *)node)->right); break; } case scripting::ASTNode::Comma: { std::cout << "Comma (should not be here):\n"; printAST(indent+1, ((scripting::LROpNode *)node)->left); printAST(indent+1, ((scripting::LROpNode *)node)->right); break; } case scripting::ASTNode::StatementSplit: { std::cout << "StatementSplit (should not be here):\n"; printAST(indent+1, ((scripting::LROpNode *)node)->left); printAST(indent+1, ((scripting::LROpNode *)node)->right); break; } case scripting::ASTNode::GetMember: { std::cout << "GetMember:\n"; printAST(indent+1, ((scripting::LROpNode *)node)->left); printAST(indent+1, ((scripting::LROpNode *)node)->right); break; } case scripting::ASTNode::GetMethod: { std::cout << "GetMethod:\n"; printAST(indent+1, ((scripting::LROpNode *)node)->left); printAST(indent+1, ((scripting::LROpNode *)node)->right); break; } case scripting::ASTNode::Call: { scripting::CallNode *cnode = (scripting::CallNode *)node; std::cout << "Call:\n"; printAST(indent+1, cnode->callable); for (size_t i = 0; i < cnode->args.getCount(); ++i) { printAST(indent+1, cnode->args[i]); } break; } case scripting::ASTNode::BoolNot: { std::cout << "BoolNot:\n"; printAST(indent+1, ((scripting::SingleOperandNode *)node)->operand); break; } case scripting::ASTNode::BitNot: { std::cout << "BitNot:\n"; printAST(indent+1, ((scripting::SingleOperandNode *)node)->operand); break; } case scripting::ASTNode::Class: { std::cout << "Class:\n"; printAST(indent+1, ((scripting::SingleOperandNode *)node)->operand); break; } case scripting::ASTNode::Throw: { std::cout << "Throw:\n"; printAST(indent+1, ((scripting::SingleOperandNode *)node)->operand); break; } case scripting::ASTNode::Return: { std::cout << "Return:\n"; printAST(indent+1, ((scripting::SingleOperandNode *)node)->operand); break; } case scripting::ASTNode::Negate: { std::cout << "Negate:\n"; printAST(indent+1, ((scripting::SingleOperandNode *)node)->operand); break; } case scripting::ASTNode::Function: { std::cout << "Function:\n"; scripting::FunctionNode *fnode = (scripting::FunctionNode *)node; for (size_t i = 0; i < fnode->args.getCount(); ++i) { for (size_t j = 0; j <= indent; ++j) { std::cout << " "; } std::cout << fnode->args[i].getData() << '\n'; } printAST(indent+1, fnode->body); break; } case scripting::ASTNode::TryExcept: { std::cout << "TryExcept:\n"; scripting::TryExceptNode *tenode = (scripting::TryExceptNode *)node; printAST(indent+1, tenode->try_); printAST(indent+1, tenode->except); break; } case scripting::ASTNode::If: { std::cout << "If:\n"; scripting::IfNode *inode = (scripting::IfNode *)node; printAST(indent+1, inode->ifCond); printAST(indent+1, inode->if_); for (size_t i = 0; i < inode->elifs.getCount(); ++i) { printAST(indent+1, inode->elifConds[i]); printAST(indent+1, inode->elifs[i]); } if (inode->else_ != nullptr) { printAST(indent+1, inode->else_); } break; } case scripting::ASTNode::While: { std::cout << "While:\n"; scripting::WhileNode *whileNode = (scripting::WhileNode *)node; printAST(indent+1, whileNode->cond); printAST(indent+1, whileNode->block); break; } case scripting::ASTNode::Identifier: { std::cout << "Identifier:\n"; for (size_t j = 0; j <= indent; ++j) { std::cout << " "; } std::cout << ((scripting::IdentifierNode *)node)->name.getData() << std::endl; break; } case scripting::ASTNode::Integer: { std::cout << "Integer:\n"; for (size_t j = 0; j <= indent; ++j) { std::cout << " "; } std::cout << ((scripting::IntegerNode *)node)->value << std::endl; break; } case scripting::ASTNode::Float: { std::cout << "Float:\n"; for (size_t j = 0; j <= indent; ++j) { std::cout << " "; } std::cout << ((scripting::FloatNode *)node)->value << std::endl; break; } case scripting::ASTNode::String: { std::cout << "String:\n"; for (size_t j = 0; j <= indent; ++j) { std::cout << " "; } std::cout << ((scripting::StringNode *)node)->content.getData() << std::endl; break; } case scripting::ASTNode::Statements: { std::cout << "Statements:\n"; scripting::StatementsNode *snode = (scripting::StatementsNode *)node; for (size_t i = 0; i < snode->statements.getCount(); ++i) { printAST(indent+1, snode->statements[i]); } break; } case scripting::ASTNode::True: { std::cout << "True\n"; break; } case scripting::ASTNode::False: { std::cout << "False\n"; break; } case scripting::ASTNode::Nil: { std::cout << "Nil\n"; break; } } }