finish ast dumper

This commit is contained in:
ValKmjolnir 2023-06-25 22:25:13 +08:00
parent 9f66960244
commit fe40bd7e3f
6 changed files with 262 additions and 155 deletions

View File

@ -2,367 +2,434 @@
#include <iostream>
bool ast_dumper::visit_expr(expr* node) {
std::cout << "expr\n";
std::cout << " -> " << node->get_location().file << ":"
<< node->get_location().begin_line << ":"
<< node->get_location().begin_column << "\n";
node->accept(this);
return true;
}
bool ast_dumper::visit_null_expr(null_expr* node) {
std::cout << "null\n";
std::cout << " -> " << node->get_location().file << ":"
<< node->get_location().begin_line << ":"
<< node->get_location().begin_column << "\n";
dump_indent();
std::cout << "null" << format_location(node->get_location());
return true;
}
bool ast_dumper::visit_nil_expr(nil_expr* node) {
std::cout << "nil\n";
std::cout << " -> " << node->get_location().file << ":"
<< node->get_location().begin_line << ":"
<< node->get_location().begin_column << "\n";
dump_indent();
std::cout << "nil" << format_location(node->get_location());
return true;
}
bool ast_dumper::visit_number_literal(number_literal* node) {
std::cout << "number " << node->get_number() << "\n";
std::cout << " -> " << node->get_location().file << ":"
<< node->get_location().begin_line << ":"
<< node->get_location().begin_column << "\n";
dump_indent();
std::cout << "number " << node->get_number();
std::cout << format_location(node->get_location());
return true;
}
bool ast_dumper::visit_string_literal(string_literal* node) {
std::cout << "string " << node->get_content() << "\n";
std::cout << " -> " << node->get_location().file << ":"
<< node->get_location().begin_line << ":"
<< node->get_location().begin_column << "\n";
dump_indent();
std::cout << "string \"" << rawstr(node->get_content()) << "\"";
std::cout << format_location(node->get_location());
return true;
}
bool ast_dumper::visit_identifier(identifier* node) {
std::cout << "identifier " << node->get_name() << "\n";
std::cout << " -> " << node->get_location().file << ":"
<< node->get_location().begin_line << ":"
<< node->get_location().begin_column << "\n";
dump_indent();
std::cout << "identifier " << node->get_name();
std::cout << format_location(node->get_location());
return true;
}
bool ast_dumper::visit_bool_literal(bool_literal* node) {
std::cout << "bool " << node->get_flag() << "\n";
std::cout << " -> " << node->get_location().file << ":"
<< node->get_location().begin_line << ":"
<< node->get_location().begin_column << "\n";
dump_indent();
std::cout << "bool " << node->get_flag();
std::cout << format_location(node->get_location());
return true;
}
bool ast_dumper::visit_vector_expr(vector_expr* node) {
std::cout << "vector\n";
std::cout << " -> " << node->get_location().file << ":"
<< node->get_location().begin_line << ":"
<< node->get_location().begin_column << "\n";
dump_indent();
std::cout << "vector";
std::cout << format_location(node->get_location());
push_indent();
for(auto i : node->get_elements()) {
if (i==node->get_elements().back()) {
set_last();
}
i->accept(this);
}
pop_indent();
return true;
}
bool ast_dumper::visit_hash_expr(hash_expr* node) {
std::cout << "hash\n";
std::cout << " -> " << node->get_location().file << ":"
<< node->get_location().begin_line << ":"
<< node->get_location().begin_column << "\n";
dump_indent();
std::cout << "hash";
std::cout << format_location(node->get_location());
push_indent();
for(auto i : node->get_members()) {
if (i==node->get_members().back()) {
set_last();
}
i->accept(this);
}
pop_indent();
return true;
}
bool ast_dumper::visit_hash_pair(hash_pair* node) {
std::cout << "pair\n";
std::cout << " -> " << node->get_location().file << ":"
<< node->get_location().begin_line << ":"
<< node->get_location().begin_column << "\n";
dump_indent();
std::cout << "pair " << node->get_name();
std::cout << format_location(node->get_location());
if (node->get_value()) {
push_indent();
set_last();
node->get_value()->accept(this);
pop_indent();
}
return true;
}
bool ast_dumper::visit_function(function* node) {
std::cout << "function\n";
std::cout << " -> " << node->get_location().file << ":"
<< node->get_location().begin_line << ":"
<< node->get_location().begin_column << "\n";
dump_indent();
std::cout << "function";
std::cout << format_location(node->get_location());
push_indent();
for(auto i : node->get_parameter_list()) {
i->accept(this);
}
set_last();
node->get_code_block()->accept(this);
pop_indent();
return true;
}
bool ast_dumper::visit_code_block(code_block* node) {
std::cout << "block\n";
std::cout << " -> " << node->get_location().file << ":"
<< node->get_location().begin_line << ":"
<< node->get_location().begin_column << "\n";
dump_indent();
std::cout << "block";
std::cout << format_location(node->get_location());
push_indent();
for(auto i : node->get_expressions()) {
if (i==node->get_expressions().back()) {
set_last();
}
i->accept(this);
}
pop_indent();
return true;
}
bool ast_dumper::visit_parameter(parameter* node) {
std::cout << "parameter\n";
std::cout << " -> " << node->get_location().file << ":"
<< node->get_location().begin_line << ":"
<< node->get_location().begin_column << "\n";
dump_indent();
std::cout << "parameter";
std::cout << format_location(node->get_location());
push_indent();
if (!node->get_default_value()) {
set_last();
}
node->get_parameter_name()->accept(this);
if (node->get_default_value()) {
set_last();
node->get_default_value()->accept(this);
}
pop_indent();
return true;
}
bool ast_dumper::visit_ternary_operator(ternary_operator* node) {
std::cout << "ternary\n";
std::cout << " -> " << node->get_location().file << ":"
<< node->get_location().begin_line << ":"
<< node->get_location().begin_column << "\n";
dump_indent();
std::cout << "ternary";
std::cout << format_location(node->get_location());
push_indent();
node->get_condition()->accept(this);
node->get_left()->accept(this);
set_last();
node->get_right()->accept(this);
pop_indent();
return true;
}
bool ast_dumper::visit_binary_operator(binary_operator* node) {
std::cout << "binary\n";
std::cout << " -> " << node->get_location().file << ":"
<< node->get_location().begin_line << ":"
<< node->get_location().begin_column << "\n";
dump_indent();
std::cout << "binary";
std::cout << format_location(node->get_location());
push_indent();
node->get_left()->accept(this);
set_last();
node->get_right()->accept(this);
pop_indent();
return true;
}
bool ast_dumper::visit_unary_operator(unary_operator* node) {
std::cout << "unary\n";
std::cout << " -> " << node->get_location().file << ":"
<< node->get_location().begin_line << ":"
<< node->get_location().begin_column << "\n";
dump_indent();
std::cout << "unary";
std::cout << format_location(node->get_location());
push_indent();
set_last();
node->get_value()->accept(this);
pop_indent();
return true;
}
bool ast_dumper::visit_call_expr(call_expr* node) {
std::cout << "call_expr\n";
std::cout << " -> " << node->get_location().file << ":"
<< node->get_location().begin_line << ":"
<< node->get_location().begin_column << "\n";
dump_indent();
std::cout << "call_expr";
std::cout << format_location(node->get_location());
push_indent();
if (!node->get_calls().size()) {
set_last();
}
node->get_first()->accept(this);
for(auto i : node->get_calls()) {
if (i==node->get_calls().back()) {
set_last();
}
i->accept(this);
}
pop_indent();
return true;
}
bool ast_dumper::visit_call_hash(call_hash* node) {
std::cout << "call_hash\n";
std::cout << " -> " << node->get_location().file << ":"
<< node->get_location().begin_line << ":"
<< node->get_location().begin_column << "\n";
dump_indent();
std::cout << "call_hash" << node->get_field();
std::cout << format_location(node->get_location());
return true;
}
bool ast_dumper::visit_call_vector(call_vector* node) {
std::cout << "call_vector\n";
std::cout << " -> " << node->get_location().file << ":"
<< node->get_location().begin_line << ":"
<< node->get_location().begin_column << "\n";
dump_indent();
std::cout << "call_vector";
std::cout << format_location(node->get_location());
push_indent();
for(auto i : node->get_slices()) {
if (i==node->get_slices().back()) {
set_last();
}
i->accept(this);
}
pop_indent();
return true;
}
bool ast_dumper::visit_call_function(call_function* node) {
std::cout << "call_function\n";
std::cout << " -> " << node->get_location().file << ":"
<< node->get_location().begin_line << ":"
<< node->get_location().begin_column << "\n";
dump_indent();
std::cout << "call_function";
std::cout << format_location(node->get_location());
push_indent();
for(auto i : node->get_argument()) {
if (i==node->get_argument().back()) {
set_last();
}
i->accept(this);
}
pop_indent();
return true;
}
bool ast_dumper::visit_slice_vector(slice_vector* node) {
std::cout << "slice\n";
std::cout << " -> " << node->get_location().file << ":"
<< node->get_location().begin_line << ":"
<< node->get_location().begin_column << "\n";
dump_indent();
std::cout << "slice";
std::cout << format_location(node->get_location());
push_indent();
if (!node->get_end()) {
set_last();
}
node->get_begin()->accept(this);
if (node->get_end()) {
set_last();
node->get_end()->accept(this);
}
pop_indent();
return true;
}
bool ast_dumper::visit_definition_expr(definition_expr* node) {
std::cout << "definition\n";
std::cout << " -> " << node->get_location().file << ":"
<< node->get_location().begin_line << ":"
<< node->get_location().begin_column << "\n";
dump_indent();
std::cout << "definition";
std::cout << format_location(node->get_location());
push_indent();
if (node->get_variable_name()) {
node->get_variable_name()->accept(this);
} else {
node->get_variables()->accept(this);
}
set_last();
node->get_value()->accept(this);
pop_indent();
return true;
}
bool ast_dumper::visit_assignment_expr(assignment_expr* node) {
std::cout << "assignment\n";
std::cout << " -> " << node->get_location().file << ":"
<< node->get_location().begin_line << ":"
<< node->get_location().begin_column << "\n";
dump_indent();
std::cout << "assignment";
std::cout << format_location(node->get_location());
push_indent();
node->get_left()->accept(this);
set_last();
node->get_right()->accept(this);
pop_indent();
return true;
}
bool ast_dumper::visit_multi_identifier(multi_identifier* node) {
std::cout << "multi_define\n";
std::cout << " -> " << node->get_location().file << ":"
<< node->get_location().begin_line << ":"
<< node->get_location().begin_column << "\n";
dump_indent();
std::cout << "multi_define";
std::cout << format_location(node->get_location());
push_indent();
for(auto i : node->get_variables()) {
if (i==node->get_variables().back()) {
set_last();
}
i->accept(this);
}
pop_indent();
return true;
}
bool ast_dumper::visit_tuple_expr(tuple_expr* node) {
std::cout << "tuple\n";
std::cout << " -> " << node->get_location().file << ":"
<< node->get_location().begin_line << ":"
<< node->get_location().begin_column << "\n";
dump_indent();
std::cout << "tuple";
std::cout << format_location(node->get_location());
push_indent();
for(auto i : node->get_elements()) {
if (i==node->get_elements().back()) {
set_last();
}
i->accept(this);
}
pop_indent();
return true;
}
bool ast_dumper::visit_multi_assign(multi_assign* node) {
std::cout << "multi_assign\n";
std::cout << " -> " << node->get_location().file << ":"
<< node->get_location().begin_line << ":"
<< node->get_location().begin_column << "\n";
dump_indent();
std::cout << "multi_assign";
std::cout << format_location(node->get_location());
push_indent();
node->get_tuple()->accept(this);
set_last();
node->get_value()->accept(this);
pop_indent();
return true;
}
bool ast_dumper::visit_while_expr(while_expr* node) {
std::cout << "while\n";
std::cout << " -> " << node->get_location().file << ":"
<< node->get_location().begin_line << ":"
<< node->get_location().begin_column << "\n";
dump_indent();
std::cout << "while";
std::cout << format_location(node->get_location());
push_indent();
node->get_condition()->accept(this);
set_last();
node->get_code_block()->accept(this);
pop_indent();
return true;
}
bool ast_dumper::visit_for_expr(for_expr* node) {
std::cout << "for\n";
std::cout << " -> " << node->get_location().file << ":"
<< node->get_location().begin_line << ":"
<< node->get_location().begin_column << "\n";
dump_indent();
std::cout << "for";
std::cout << format_location(node->get_location());
push_indent();
node->get_initial()->accept(this);
node->get_condition()->accept(this);
node->get_step()->accept(this);
set_last();
node->get_code_block()->accept(this);
pop_indent();
return true;
}
bool ast_dumper::visit_iter_expr(iter_expr* node) {
std::cout << "iter\n";
std::cout << " -> " << node->get_location().file << ":"
<< node->get_location().begin_line << ":"
<< node->get_location().begin_column << "\n";
dump_indent();
std::cout << "iter";
std::cout << format_location(node->get_location());
push_indent();
set_last();
if (node->get_name()) {
node->get_name()->accept(this);
} else {
node->get_call()->accept(this);
}
pop_indent();
return true;
}
bool ast_dumper::visit_forei_expr(forei_expr* node) {
std::cout << "forei\n";
std::cout << " -> " << node->get_location().file << ":"
<< node->get_location().begin_line << ":"
<< node->get_location().begin_column << "\n";
dump_indent();
if (node->get_type()==forei_expr::forei_loop_type::foreach) {
std::cout << "foreach";
} else {
std::cout << "forindex";
}
std::cout << format_location(node->get_location());
push_indent();
node->get_iterator()->accept(this);
node->get_value()->accept(this);
set_last();
node->get_code_block()->accept(this);
pop_indent();
return true;
}
bool ast_dumper::visit_condition_expr(condition_expr* node) {
std::cout << "condition\n";
std::cout << " -> " << node->get_location().file << ":"
<< node->get_location().begin_line << ":"
<< node->get_location().begin_column << "\n";
dump_indent();
std::cout << "condition";
std::cout << format_location(node->get_location());
push_indent();
if (!node->get_elsif_stataments().size() &&
!node->get_else_statement()) {
set_last();
}
node->get_if_statement()->accept(this);
for(auto i : node->get_elsif_stataments()) {
if (i==node->get_elsif_stataments().back() &&
!node->get_else_statement()) {
set_last();
}
i->accept(this);
}
if (node->get_else_statement()) {
set_last();
node->get_else_statement()->accept(this);
}
pop_indent();
return true;
}
bool ast_dumper::visit_if_expr(if_expr* node) {
std::cout << "if\n";
std::cout << " -> " << node->get_location().file << ":"
<< node->get_location().begin_line << ":"
<< node->get_location().begin_column << "\n";
dump_indent();
std::cout << "if";
std::cout << format_location(node->get_location());
push_indent();
if (node->get_condition()) {
node->get_condition()->accept(this);
}
set_last();
node->get_code_block()->accept(this);
pop_indent();
return true;
}
bool ast_dumper::visit_continue_expr(continue_expr* node) {
std::cout << "continue\n";
std::cout << " -> " << node->get_location().file << ":"
<< node->get_location().begin_line << ":"
<< node->get_location().begin_column << "\n";
dump_indent();
std::cout << "continue";
std::cout << format_location(node->get_location());
return true;
}
bool ast_dumper::visit_break_expr(break_expr* node) {
std::cout << "break\n";
std::cout << " -> " << node->get_location().file << ":"
<< node->get_location().begin_line << ":"
<< node->get_location().begin_column << "\n";
dump_indent();
std::cout << "break";
std::cout << format_location(node->get_location());
return true;
}
bool ast_dumper::visit_return_expr(return_expr* node) {
std::cout << "return\n";
std::cout << " -> " << node->get_location().file << ":"
<< node->get_location().begin_line << ":"
<< node->get_location().begin_column << "\n";
dump_indent();
std::cout << "return";
std::cout << format_location(node->get_location());
if (node->get_value()) {
push_indent();
set_last();
node->get_value()->accept(this);
pop_indent();
}
return true;
}

View File

@ -2,9 +2,44 @@
#include "ast_visitor.h"
#include <iostream>
#include <cstring>
#include <sstream>
class ast_dumper:public ast_visitor {
private:
std::vector<std::string> indent;
void push_indent() {
if (indent.size()) {
if (indent.back()=="|--") {
indent.back() = "| ";
} else if (indent.back()=="+--") {
indent.back() = " ";
}
// indent.back() = (indent.back()=="|--")? "| ":" ";
}
indent.push_back("|--");
}
void pop_indent() {indent.pop_back();}
void set_last() {indent.back() = "+--";}
void dump_indent() {
if (indent.size() && indent.back()=="| ") {
indent.back() = "|--";
}
for(const auto& i : indent) {
std::cout << i;
}
}
std::string format_location(const span& location) {
std::stringstream ss;
ss << " -> ";
ss << location.file << ":";
ss << location.begin_line << ":" << location.begin_column;
ss << "\n";
return ss.str();
}
public:
bool visit_expr(expr*) override;
bool visit_null_expr(null_expr*) override;
bool visit_nil_expr(nil_expr*) override;
bool visit_number_literal(number_literal*) override;

View File

@ -51,7 +51,7 @@ std::ostream& logo(std::ostream& out) {
<<" \\_\\ \\/ \\__,_|___/\\__,_|_|\n"
<<"ver : "<<__nasver<<" ("<<__DATE__<<" "<<__TIME__<<")\n"
<<"std : c++ "<<__cplusplus<<"\n"
<<"core : "<<std::thread::hardware_concurrency()<<" cores\n"
<<"core : "<<std::thread::hardware_concurrency()<<" core(s)\n"
<<"repo : https://github.com/ValKmjolnir/Nasal-Interpreter\n"
<<"repo : https://gitee.com/valkmjolnir/Nasal-Interpreter\n"
<<"wiki : https://wiki.flightgear.org/Nasal_scripting_language\n"
@ -89,7 +89,7 @@ void execute(
parse.compile(lex).chkerr();
if (cmd&VM_AST) {
auto dumper = new ast_dumper();
dumper->visit_expr(parse.tree());
dumper->visit_code_block(parse.tree());
}
// linker gets parser's ast and load import files to this ast

View File

@ -610,7 +610,7 @@ expr* parse::scalar() {
} else if (lookahead(tok::lbrace)) {
node = hash();
} else if (lookahead(tok::lcurve)) {
const auto& loc=toks[ptr].loc;
const auto& loc = toks[ptr].loc;
match(tok::lcurve);
node = calc();
node->set_begin(loc.begin_line, loc.begin_column);
@ -625,7 +625,7 @@ expr* parse::scalar() {
node = def_node;
} else {
die(thisspan, "expected scalar");
return node;
return null();
}
// check call and avoid ambiguous syntax
if (is_call(toks[ptr].type) && !(lookahead(tok::lcurve) && toks[ptr+1].type==tok::var)) {
@ -839,7 +839,10 @@ expr* parse::loop() {
case tok::rfor: node = for_loop(); break;
case tok::forindex:
case tok::foreach: node = forei_loop(); break;
default: break;
default:
die(thisspan, "unreachable");
node = null();
break;
}
--in_loop;
return node;

View File

@ -11,6 +11,7 @@
#include "nasal_vm.h"
#include "nasal_dbg.h"
#include <thread>
#include <unordered_map>
const u32 VM_AST =0x01;
@ -55,6 +56,7 @@ std::ostream& logo(std::ostream& out) {
<<" \\_\\ \\/ \\__,_|___/\\__,_|_|\n"
<<"ver : "<<__nasver<<" ("<<__DATE__<<" "<<__TIME__<<")\n"
<<"std : c++ "<<__cplusplus<<"\n"
<<"core : "<<std::thread::hardware_concurrency()<<" core(s)\n"
<<"repo : https://github.com/ValKmjolnir/Nasal-Interpreter\n"
<<"repo : https://gitee.com/valkmjolnir/Nasal-Interpreter\n"
<<"wiki : https://wiki.flightgear.org/Nasal_scripting_language\n"
@ -90,15 +92,15 @@ void execute(
// parser gets lexer's token list to compile
parse.compile(lex).chkerr();
if (cmd&VM_AST) {
parse.tree().dump();
}
// linker gets parser's ast and load import files to this ast
ld.link(parse, file, cmd&VM_DETAIL).chkerr();
// optimizer does simple optimization on ast
optimize(parse.tree());
if (cmd&VM_AST) {
parse.tree().dump();
}
// code generator gets parser's ast and import file list to generate code
gen.compile(parse, ld).chkerr();

View File

@ -105,7 +105,7 @@ using usize=std::size_t;
using f64=double;
using std::string;
const u32 STACK_DEPTH=1024;
const u32 STACK_DEPTH=4096;
f64 hex2f(const char* str) {
f64 ret=0;