add ast dumper

This commit is contained in:
ValKmjolnir 2023-06-25 00:31:11 +08:00
parent 2ce13e2134
commit 9f66960244
10 changed files with 732 additions and 117 deletions

368
ast/ast_dumper.cpp Normal file
View File

@ -0,0 +1,368 @@
#include "ast_dumper.h"
#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";
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";
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";
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";
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";
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";
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";
for(auto i : node->get_elements()) {
i->accept(this);
}
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";
for(auto i : node->get_members()) {
i->accept(this);
}
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";
if (node->get_value()) {
node->get_value()->accept(this);
}
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";
for(auto i : node->get_parameter_list()) {
i->accept(this);
}
node->get_code_block()->accept(this);
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";
for(auto i : node->get_expressions()) {
i->accept(this);
}
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";
node->get_parameter_name()->accept(this);
if (node->get_default_value()) {
node->get_default_value()->accept(this);
}
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";
node->get_condition()->accept(this);
node->get_left()->accept(this);
node->get_right()->accept(this);
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";
node->get_left()->accept(this);
node->get_right()->accept(this);
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";
node->get_value()->accept(this);
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";
node->get_first()->accept(this);
for(auto i : node->get_calls()) {
i->accept(this);
}
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";
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";
for(auto i : node->get_slices()) {
i->accept(this);
}
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";
for(auto i : node->get_argument()) {
i->accept(this);
}
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";
node->get_begin()->accept(this);
if (node->get_end()) {
node->get_end()->accept(this);
}
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";
if (node->get_variable_name()) {
node->get_variable_name()->accept(this);
} else {
node->get_variables()->accept(this);
}
node->get_value()->accept(this);
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";
node->get_left()->accept(this);
node->get_right()->accept(this);
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";
for(auto i : node->get_variables()) {
i->accept(this);
}
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";
for(auto i : node->get_elements()) {
i->accept(this);
}
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";
node->get_tuple()->accept(this);
node->get_value()->accept(this);
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";
node->get_condition()->accept(this);
node->get_code_block()->accept(this);
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";
node->get_initial()->accept(this);
node->get_condition()->accept(this);
node->get_step()->accept(this);
node->get_code_block()->accept(this);
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";
if (node->get_name()) {
node->get_name()->accept(this);
} else {
node->get_call()->accept(this);
}
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";
node->get_iterator()->accept(this);
node->get_value()->accept(this);
node->get_code_block()->accept(this);
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";
node->get_if_statement()->accept(this);
for(auto i : node->get_elsif_stataments()) {
i->accept(this);
}
if (node->get_else_statement()) {
node->get_else_statement()->accept(this);
}
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";
if (node->get_condition()) {
node->get_condition()->accept(this);
}
node->get_code_block()->accept(this);
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";
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";
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";
if (node->get_value()) {
node->get_value()->accept(this);
}
return true;
}

42
ast/ast_dumper.h Normal file
View File

@ -0,0 +1,42 @@
#pragma once
#include "ast_visitor.h"
class ast_dumper:public ast_visitor {
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;
bool visit_string_literal(string_literal*) override;
bool visit_identifier(identifier*) override;
bool visit_bool_literal(bool_literal*) override;
bool visit_vector_expr(vector_expr*) override;
bool visit_hash_expr(hash_expr*) override;
bool visit_hash_pair(hash_pair*) override;
bool visit_function(function*) override;
bool visit_code_block(code_block*) override;
bool visit_parameter(parameter*) override;
bool visit_ternary_operator(ternary_operator*) override;
bool visit_binary_operator(binary_operator*) override;
bool visit_unary_operator(unary_operator*) override;
bool visit_call_expr(call_expr*) override;
bool visit_call_hash(call_hash*) override;
bool visit_call_vector(call_vector*) override;
bool visit_call_function(call_function*) override;
bool visit_slice_vector(slice_vector*) override;
bool visit_definition_expr(definition_expr*) override;
bool visit_assignment_expr(assignment_expr*) override;
bool visit_multi_identifier(multi_identifier*) override;
bool visit_tuple_expr(tuple_expr*) override;
bool visit_multi_assign(multi_assign*) override;
bool visit_while_expr(while_expr*) override;
bool visit_for_expr(for_expr*) override;
bool visit_iter_expr(iter_expr*) override;
bool visit_forei_expr(forei_expr*) override;
bool visit_condition_expr(condition_expr*) override;
bool visit_if_expr(if_expr*) override;
bool visit_continue_expr(continue_expr*) override;
bool visit_break_expr(break_expr*) override;
bool visit_return_expr(return_expr*) override;
};

View File

@ -44,8 +44,183 @@ bool ast_visitor::visit_hash_expr(hash_expr* node) {
} }
bool ast_visitor::visit_hash_pair(hash_pair* node) { bool ast_visitor::visit_hash_pair(hash_pair* node) {
if (node->get_element()) { if (node->get_value()) {
node->get_element()->accept(this); node->get_value()->accept(this);
}
return true;
}
bool ast_visitor::visit_function(function* node) {
for(auto i : node->get_parameter_list()) {
i->accept(this);
}
node->get_code_block()->accept(this);
return true;
}
bool ast_visitor::visit_code_block(code_block* node) {
for(auto i : node->get_expressions()) {
i->accept(this);
}
return true;
}
bool ast_visitor::visit_parameter(parameter* node) {
node->get_parameter_name()->accept(this);
if (node->get_default_value()) {
node->get_default_value()->accept(this);
}
return true;
}
bool ast_visitor::visit_ternary_operator(ternary_operator* node) {
node->get_condition()->accept(this);
node->get_left()->accept(this);
node->get_right()->accept(this);
return true;
}
bool ast_visitor::visit_binary_operator(binary_operator* node) {
node->get_left()->accept(this);
node->get_right()->accept(this);
return true;
}
bool ast_visitor::visit_unary_operator(unary_operator* node) {
node->get_value()->accept(this);
return true;
}
bool ast_visitor::visit_call_expr(call_expr* node) {
node->get_first()->accept(this);
for(auto i : node->get_calls()) {
i->accept(this);
}
return true;
}
bool ast_visitor::visit_call_hash(call_hash* node) {
return true;
}
bool ast_visitor::visit_call_vector(call_vector* node) {
for(auto i : node->get_slices()) {
i->accept(this);
}
return true;
}
bool ast_visitor::visit_call_function(call_function* node) {
for(auto i : node->get_argument()) {
i->accept(this);
}
return true;
}
bool ast_visitor::visit_slice_vector(slice_vector* node) {
node->get_begin()->accept(this);
if (node->get_end()) {
node->get_end()->accept(this);
}
return true;
}
bool ast_visitor::visit_definition_expr(definition_expr* node) {
if (node->get_variable_name()) {
node->get_variable_name()->accept(this);
} else {
node->get_variables()->accept(this);
}
node->get_value()->accept(this);
return true;
}
bool ast_visitor::visit_assignment_expr(assignment_expr* node) {
node->get_left()->accept(this);
node->get_right()->accept(this);
return true;
}
bool ast_visitor::visit_multi_identifier(multi_identifier* node) {
for(auto i : node->get_variables()) {
i->accept(this);
}
return true;
}
bool ast_visitor::visit_tuple_expr(tuple_expr* node) {
for(auto i : node->get_elements()) {
i->accept(this);
}
return true;
}
bool ast_visitor::visit_multi_assign(multi_assign* node) {
node->get_tuple()->accept(this);
node->get_value()->accept(this);
return true;
}
bool ast_visitor::visit_while_expr(while_expr* node) {
node->get_condition()->accept(this);
node->get_code_block()->accept(this);
return true;
}
bool ast_visitor::visit_for_expr(for_expr* node) {
node->get_initial()->accept(this);
node->get_condition()->accept(this);
node->get_step()->accept(this);
node->get_code_block()->accept(this);
return true;
}
bool ast_visitor::visit_iter_expr(iter_expr* node) {
if (node->get_name()) {
node->get_name()->accept(this);
} else {
node->get_call()->accept(this);
}
return true;
}
bool ast_visitor::visit_forei_expr(forei_expr* node) {
node->get_iterator()->accept(this);
node->get_value()->accept(this);
node->get_code_block()->accept(this);
return true;
}
bool ast_visitor::visit_condition_expr(condition_expr* node) {
node->get_if_statement()->accept(this);
for(auto i : node->get_elsif_stataments()) {
i->accept(this);
}
if (node->get_else_statement()) {
node->get_else_statement()->accept(this);
}
return true;
}
bool ast_visitor::visit_if_expr(if_expr* node) {
if (node->get_condition()) {
node->get_condition()->accept(this);
}
node->get_code_block()->accept(this);
return true;
}
bool ast_visitor::visit_continue_expr(continue_expr* node) {
return true;
}
bool ast_visitor::visit_break_expr(break_expr* node) {
return true;
}
bool ast_visitor::visit_return_expr(return_expr* node) {
if (node->get_value()) {
node->get_value()->accept(this);
} }
return true; return true;
} }

View File

@ -14,4 +14,29 @@ public:
virtual bool visit_vector_expr(vector_expr*); virtual bool visit_vector_expr(vector_expr*);
virtual bool visit_hash_expr(hash_expr*); virtual bool visit_hash_expr(hash_expr*);
virtual bool visit_hash_pair(hash_pair*); virtual bool visit_hash_pair(hash_pair*);
virtual bool visit_function(function*);
virtual bool visit_code_block(code_block*);
virtual bool visit_parameter(parameter*);
virtual bool visit_ternary_operator(ternary_operator*);
virtual bool visit_binary_operator(binary_operator*);
virtual bool visit_unary_operator(unary_operator*);
virtual bool visit_call_expr(call_expr*);
virtual bool visit_call_hash(call_hash*);
virtual bool visit_call_vector(call_vector*);
virtual bool visit_call_function(call_function*);
virtual bool visit_slice_vector(slice_vector*);
virtual bool visit_definition_expr(definition_expr*);
virtual bool visit_assignment_expr(assignment_expr*);
virtual bool visit_multi_identifier(multi_identifier*);
virtual bool visit_tuple_expr(tuple_expr*);
virtual bool visit_multi_assign(multi_assign*);
virtual bool visit_while_expr(while_expr*);
virtual bool visit_for_expr(for_expr*);
virtual bool visit_iter_expr(iter_expr*);
virtual bool visit_forei_expr(forei_expr*);
virtual bool visit_condition_expr(condition_expr*);
virtual bool visit_if_expr(if_expr*);
virtual bool visit_continue_expr(continue_expr*);
virtual bool visit_break_expr(break_expr*);
virtual bool visit_return_expr(return_expr*);
}; };

View File

@ -50,8 +50,8 @@ void hash_expr::accept(ast_visitor* visitor) {
} }
hash_pair::~hash_pair() { hash_pair::~hash_pair() {
if (element) { if (value) {
delete element; delete value;
} }
} }
@ -69,7 +69,7 @@ function::~function() {
} }
void function::accept(ast_visitor* visitor) { void function::accept(ast_visitor* visitor) {
// TODO visitor->visit_function(this);
} }
code_block::~code_block() { code_block::~code_block() {
@ -79,7 +79,7 @@ code_block::~code_block() {
} }
void code_block::accept(ast_visitor* visitor) { void code_block::accept(ast_visitor* visitor) {
// TODO visitor->visit_code_block(this);
} }
parameter::~parameter() { parameter::~parameter() {
@ -92,7 +92,7 @@ parameter::~parameter() {
} }
void parameter::accept(ast_visitor* visitor) { void parameter::accept(ast_visitor* visitor) {
// TODO visitor->visit_parameter(this);
} }
ternary_operator::~ternary_operator() { ternary_operator::~ternary_operator() {
@ -108,7 +108,7 @@ ternary_operator::~ternary_operator() {
} }
void ternary_operator::accept(ast_visitor* visitor) { void ternary_operator::accept(ast_visitor* visitor) {
// TODO visitor->visit_ternary_operator(this);
} }
binary_operator::~binary_operator() { binary_operator::~binary_operator() {
@ -121,7 +121,7 @@ binary_operator::~binary_operator() {
} }
void binary_operator::accept(ast_visitor* visitor) { void binary_operator::accept(ast_visitor* visitor) {
// TODO visitor->visit_binary_operator(this);
} }
unary_operator::~unary_operator() { unary_operator::~unary_operator() {
@ -131,7 +131,7 @@ unary_operator::~unary_operator() {
} }
void unary_operator::accept(ast_visitor* visitor) { void unary_operator::accept(ast_visitor* visitor) {
// TODO visitor->visit_unary_operator(this);
} }
call_expr::~call_expr() { call_expr::~call_expr() {
@ -144,11 +144,11 @@ call_expr::~call_expr() {
} }
void call_expr::accept(ast_visitor* visitor) { void call_expr::accept(ast_visitor* visitor) {
// TODO visitor->visit_call_expr(this);
} }
void call_hash::accept(ast_visitor* visitor) { void call_hash::accept(ast_visitor* visitor) {
// TODO visitor->visit_call_hash(this);
} }
call_vector::~call_vector() { call_vector::~call_vector() {
@ -158,7 +158,7 @@ call_vector::~call_vector() {
} }
void call_vector::accept(ast_visitor* visitor) { void call_vector::accept(ast_visitor* visitor) {
// TODO visitor->visit_call_vector(this);
} }
call_function::~call_function() { call_function::~call_function() {
@ -168,7 +168,7 @@ call_function::~call_function() {
} }
void call_function::accept(ast_visitor* visitor) { void call_function::accept(ast_visitor* visitor) {
// TODO visitor->visit_call_function(this);
} }
slice_vector::~slice_vector() { slice_vector::~slice_vector() {
@ -181,7 +181,7 @@ slice_vector::~slice_vector() {
} }
void slice_vector::accept(ast_visitor* visitor) { void slice_vector::accept(ast_visitor* visitor) {
// TODO visitor->visit_slice_vector(this);
} }
definition_expr::~definition_expr() { definition_expr::~definition_expr() {
@ -197,7 +197,7 @@ definition_expr::~definition_expr() {
} }
void definition_expr::accept(ast_visitor* visitor) { void definition_expr::accept(ast_visitor* visitor) {
// TODO visitor->visit_definition_expr(this);
} }
assignment_expr::~assignment_expr() { assignment_expr::~assignment_expr() {
@ -210,20 +210,17 @@ assignment_expr::~assignment_expr() {
} }
void assignment_expr::accept(ast_visitor* visitor) { void assignment_expr::accept(ast_visitor* visitor) {
// TODO visitor->visit_assignment_expr(this);
} }
multi_define::~multi_define() { multi_identifier::~multi_identifier() {
for(auto i : variables) { for(auto i : variables) {
delete i; delete i;
} }
if (value) {
delete value;
}
} }
void multi_define::accept(ast_visitor* visitor) { void multi_identifier::accept(ast_visitor* visitor) {
// TODO visitor->visit_multi_identifier(this);
} }
tuple_expr::~tuple_expr() { tuple_expr::~tuple_expr() {
@ -233,20 +230,20 @@ tuple_expr::~tuple_expr() {
} }
void tuple_expr::accept(ast_visitor* visitor) { void tuple_expr::accept(ast_visitor* visitor) {
// TODO visitor->visit_tuple_expr(this);
} }
multi_assign::~multi_assign() { multi_assign::~multi_assign() {
if (left) { if (tuple) {
delete left; delete tuple;
} }
if (right) { if (value) {
delete right; delete value;
} }
} }
void multi_assign::accept(ast_visitor* visitor) { void multi_assign::accept(ast_visitor* visitor) {
// TODO visitor->visit_multi_assign(this);
} }
while_expr::~while_expr() { while_expr::~while_expr() {
@ -259,7 +256,7 @@ while_expr::~while_expr() {
} }
void while_expr::accept(ast_visitor* visitor) { void while_expr::accept(ast_visitor* visitor) {
// TODO visitor->visit_while_expr(this);
} }
for_expr::~for_expr() { for_expr::~for_expr() {
@ -278,7 +275,7 @@ for_expr::~for_expr() {
} }
void for_expr::accept(ast_visitor* visitor) { void for_expr::accept(ast_visitor* visitor) {
// TODO visitor->visit_for_expr(this);
} }
iter_expr::~iter_expr() { iter_expr::~iter_expr() {
@ -291,7 +288,7 @@ iter_expr::~iter_expr() {
} }
void iter_expr::accept(ast_visitor* visitor) { void iter_expr::accept(ast_visitor* visitor) {
// TODO visitor->visit_iter_expr(this);
} }
forei_expr::~forei_expr() { forei_expr::~forei_expr() {
@ -307,7 +304,7 @@ forei_expr::~forei_expr() {
} }
void forei_expr::accept(ast_visitor* visitor) { void forei_expr::accept(ast_visitor* visitor) {
// TODO visitor->visit_forei_expr(this);
} }
condition_expr::~condition_expr() { condition_expr::~condition_expr() {
@ -323,7 +320,7 @@ condition_expr::~condition_expr() {
} }
void condition_expr::accept(ast_visitor* visitor) { void condition_expr::accept(ast_visitor* visitor) {
// TODO visitor->visit_condition_expr(this);
} }
if_expr::~if_expr() { if_expr::~if_expr() {
@ -336,15 +333,15 @@ if_expr::~if_expr() {
} }
void if_expr::accept(ast_visitor* visitor) { void if_expr::accept(ast_visitor* visitor) {
// TODO visitor->visit_if_expr(this);
} }
void continue_expr::accept(ast_visitor* visitor) { void continue_expr::accept(ast_visitor* visitor) {
// TODO visitor->visit_continue_expr(this);
} }
void break_expr::accept(ast_visitor* visitor) { void break_expr::accept(ast_visitor* visitor) {
// TODO visitor->visit_break_expr(this);
} }
return_expr::~return_expr() { return_expr::~return_expr() {
@ -354,5 +351,5 @@ return_expr::~return_expr() {
} }
void return_expr::accept(ast_visitor* visitor) { void return_expr::accept(ast_visitor* visitor) {
// TODO visitor->visit_return_expr(this);
} }

View File

@ -8,8 +8,7 @@
enum class expr_type:u32 { enum class expr_type:u32 {
ast_null=0, // null node ast_null=0, // null node
ast_expr, // expression node ast_block, // code block
ast_block, // expression block
ast_nil, // nil keyword ast_nil, // nil keyword
ast_num, // number, basic value type ast_num, // number, basic value type
ast_str, // string, basic value type ast_str, // string, basic value type
@ -24,21 +23,7 @@ enum class expr_type:u32 {
ast_callv, // id[index] ast_callv, // id[index]
ast_callf, // id() ast_callf, // id()
ast_subvec, // id[index:index] ast_subvec, // id[index:index]
ast_param, // function parameter ast_param, // function parameter
ast_and, // and keyword
ast_or, // or keyword
ast_equal, // =
ast_addeq, // +=
ast_subeq, // -=
ast_multeq, // *=
ast_diveq, // /=
ast_lnkeq, // ~=
ast_btandeq, // &=
ast_btoreq, // |=
ast_btxoreq, // ^=
ast_ternary, ast_ternary,
ast_binary, ast_binary,
ast_unary, ast_unary,
@ -62,23 +47,18 @@ class ast_visitor;
class hash_pair; class hash_pair;
class parameter; class parameter;
class slice_vector; class slice_vector;
class multi_define; class multi_identifier;
class code_block; class code_block;
class if_expr; class if_expr;
class ast_abstract_node { class ast_abstract_node {
public: protected:
virtual void accept(ast_visitor*) = 0;
};
class expr:public ast_abstract_node {
private:
span nd_loc; span nd_loc;
expr_type nd_type; expr_type nd_type;
public: public:
expr(const span& location, expr_type node_type): ast_abstract_node(const span& location, expr_type node_type):
nd_loc(location), nd_type(node_type) {} nd_loc(location), nd_type(node_type) {}
~expr() = default;
void set_begin(u32 line, u32 column) { void set_begin(u32 line, u32 column) {
nd_loc.begin_line = line; nd_loc.begin_line = line;
nd_loc.begin_column = column; nd_loc.begin_column = column;
@ -89,6 +69,14 @@ public:
nd_loc.end_line = location.end_line; nd_loc.end_line = location.end_line;
nd_loc.end_column = location.end_column; nd_loc.end_column = location.end_column;
} }
virtual void accept(ast_visitor*) = 0;
};
class expr:public ast_abstract_node {
public:
expr(const span& location, expr_type node_type):
ast_abstract_node(location, node_type) {}
~expr() = default;
void accept(ast_visitor*); void accept(ast_visitor*);
}; };
@ -152,6 +140,7 @@ public:
bool_literal(const span& location, const bool bool_flag): bool_literal(const span& location, const bool bool_flag):
expr(location, expr_type::ast_bool), flag(bool_flag) {} expr(location, expr_type::ast_bool), flag(bool_flag) {}
~bool_literal() = default; ~bool_literal() = default;
bool get_flag() const {return flag;}
void accept(ast_visitor*) override; void accept(ast_visitor*) override;
}; };
@ -184,16 +173,17 @@ public:
class hash_pair:public expr { class hash_pair:public expr {
private: private:
std::string name; std::string name;
expr* element; expr* value;
public: public:
hash_pair(const span& location): hash_pair(const span& location):
expr(location, expr_type::ast_pair) {} expr(location, expr_type::ast_pair),
value(nullptr) {}
~hash_pair(); ~hash_pair();
void set_name(const std::string& field_name) {name = field_name;} void set_name(const std::string& field_name) {name = field_name;}
void set_element(expr* node) {element = node;} void set_value(expr* node) {value = node;}
const std::string& get_name() const {return name;} const std::string& get_name() const {return name;}
expr* get_element() {return element;} expr* get_value() {return value;}
void accept(ast_visitor*) override; void accept(ast_visitor*) override;
}; };
@ -248,6 +238,9 @@ public:
void set_parameter_type(param_type pt) {type = pt;} void set_parameter_type(param_type pt) {type = pt;}
void set_parameter_name(identifier* node) {name = node;} void set_parameter_name(identifier* node) {name = node;}
void set_default_value(expr* node) {default_value = node;} void set_default_value(expr* node) {default_value = node;}
param_type get_type() {return type;}
identifier* get_parameter_name() {return name;}
expr* get_default_value() {return default_value;}
void accept(ast_visitor*) override; void accept(ast_visitor*) override;
}; };
@ -265,6 +258,9 @@ public:
void set_condition(expr* node) {condition = node;} void set_condition(expr* node) {condition = node;}
void set_left(expr* node) {left = node;} void set_left(expr* node) {left = node;}
void set_right(expr* node) {right = node;} void set_right(expr* node) {right = node;}
expr* get_condition() {return condition;}
expr* get_left() {return left;}
expr* get_right() {return right;}
void accept(ast_visitor*) override; void accept(ast_visitor*) override;
}; };
@ -302,6 +298,9 @@ public:
void set_type(binary_type operator_type) {type = operator_type;} void set_type(binary_type operator_type) {type = operator_type;}
void set_left(expr* node) {left = node;} void set_left(expr* node) {left = node;}
void set_right(expr* node) {right = node;} void set_right(expr* node) {right = node;}
binary_type get_type() const {return type;}
expr* get_left() {return left;}
expr* get_right() {return right;}
void accept(ast_visitor*) override; void accept(ast_visitor*) override;
}; };
@ -324,6 +323,8 @@ public:
~unary_operator(); ~unary_operator();
void set_type(unary_type operator_type) {type = operator_type;} void set_type(unary_type operator_type) {type = operator_type;}
void set_value(expr* node) {value = node;} void set_value(expr* node) {value = node;}
unary_type get_type() const {return type;}
expr* get_value() {return value;}
void accept(ast_visitor*) override; void accept(ast_visitor*) override;
}; };
@ -339,6 +340,8 @@ public:
~call_expr(); ~call_expr();
void set_first(expr* node) {first = node;} void set_first(expr* node) {first = node;}
void add_call(expr* node) {calls.push_back(node);} void add_call(expr* node) {calls.push_back(node);}
expr* get_first() {return first;}
std::vector<expr*>& get_calls() {return calls;}
void accept(ast_visitor*) override; void accept(ast_visitor*) override;
}; };
@ -351,6 +354,7 @@ public:
expr(location, expr_type::ast_callh), expr(location, expr_type::ast_callh),
field(name) {} field(name) {}
~call_hash() = default; ~call_hash() = default;
const std::string& get_field() const {return field;}
void accept(ast_visitor*) override; void accept(ast_visitor*) override;
}; };
@ -392,13 +396,15 @@ public:
~slice_vector(); ~slice_vector();
void set_begin(expr* node) {begin = node;} void set_begin(expr* node) {begin = node;}
void set_end(expr* node) {end = node;} void set_end(expr* node) {end = node;}
expr* get_begin() {return begin;}
expr* get_end() {return end;}
void accept(ast_visitor*) override; void accept(ast_visitor*) override;
}; };
class definition_expr:public expr { class definition_expr:public expr {
private: private:
identifier* variable_name; identifier* variable_name;
multi_define* variables; multi_identifier* variables;
expr* value; expr* value;
public: public:
@ -407,9 +413,10 @@ public:
variable_name(nullptr), variables(nullptr), value(nullptr) {} variable_name(nullptr), variables(nullptr), value(nullptr) {}
~definition_expr(); ~definition_expr();
void set_identifier(identifier* node) {variable_name = node;} void set_identifier(identifier* node) {variable_name = node;}
void set_multi_define(multi_define* node) {variables = node;} void set_multi_define(multi_identifier* node) {variables = node;}
void set_value(expr* node) {value = node;} void set_value(expr* node) {value = node;}
identifier* get_variable_name() {return variable_name;}
multi_identifier* get_variables() {return variables;}
expr* get_value() {return value;} expr* get_value() {return value;}
void accept(ast_visitor*) override; void accept(ast_visitor*) override;
}; };
@ -441,25 +448,22 @@ public:
void set_type(assign_type operator_type) {type = operator_type;} void set_type(assign_type operator_type) {type = operator_type;}
void set_left(expr* node) {left = node;} void set_left(expr* node) {left = node;}
void set_right(expr* node) {right = node;} void set_right(expr* node) {right = node;}
assign_type get_type() const {return type;} assign_type get_type() const {return type;}
expr* get_left() {return left;} expr* get_left() {return left;}
expr* get_right() {return right;} expr* get_right() {return right;}
void accept(ast_visitor*) override; void accept(ast_visitor*) override;
}; };
class multi_define:public expr { class multi_identifier:public expr {
private: private:
std::vector<expr*> variables; std::vector<expr*> variables;
expr* value;
public: public:
multi_define(const span& location): multi_identifier(const span& location):
expr(location, expr_type::ast_multi_id), expr(location, expr_type::ast_multi_id) {}
value(nullptr) {} ~multi_identifier();
~multi_define();
void add_var(expr* node) {variables.push_back(node);} void add_var(expr* node) {variables.push_back(node);}
void set_value(expr* node) {value = node;} std::vector<expr*>& get_variables() {return variables;}
void accept(ast_visitor*) override; void accept(ast_visitor*) override;
}; };
@ -472,20 +476,24 @@ public:
expr(location, expr_type::ast_tuple) {} expr(location, expr_type::ast_tuple) {}
~tuple_expr(); ~tuple_expr();
void add_element(expr* node) {elements.push_back(node);} void add_element(expr* node) {elements.push_back(node);}
std::vector<expr*>& get_elements() {return elements;}
void accept(ast_visitor*) override; void accept(ast_visitor*) override;
}; };
class multi_assign:public expr { class multi_assign:public expr {
private: private:
tuple_expr* left; tuple_expr* tuple;
expr* right; expr* value;
public: public:
multi_assign(const span& location): multi_assign(const span& location):
expr(location, expr_type::ast_multi_assign) {} expr(location, expr_type::ast_multi_assign),
tuple(nullptr), value(nullptr) {}
~multi_assign(); ~multi_assign();
void set_left(tuple_expr* node) {left = node;} void set_tuple(tuple_expr* node) {tuple = node;}
void set_right(expr* node) {right = node;} void set_value(expr* node) {value = node;}
tuple_expr* get_tuple() {return tuple;}
expr* get_value() {return value;}
void accept(ast_visitor*) override; void accept(ast_visitor*) override;
}; };
@ -570,6 +578,7 @@ public:
void set_iterator(iter_expr* node) {iterator = node;} void set_iterator(iter_expr* node) {iterator = node;}
void set_value(expr* node) {vector_node = node;} void set_value(expr* node) {vector_node = node;}
void set_code_block(code_block* node) {block = node;} void set_code_block(code_block* node) {block = node;}
forei_loop_type get_type() const {return type;}
iter_expr* get_iterator() {return iterator;} iter_expr* get_iterator() {return iterator;}
expr* get_value() {return vector_node;} expr* get_value() {return vector_node;}
code_block* get_code_block() {return block;} code_block* get_code_block() {return block;}

View File

@ -4,6 +4,7 @@
#include "nasal_new_ast.h" #include "nasal_new_ast.h"
#include "nasal_new_parse.h" #include "nasal_new_parse.h"
#include "ast_visitor.h" #include "ast_visitor.h"
#include "ast_dumper.h"
#include <unordered_map> #include <unordered_map>
#include <thread> #include <thread>
@ -86,15 +87,16 @@ void execute(
// parser gets lexer's token list to compile // parser gets lexer's token list to compile
parse.compile(lex).chkerr(); parse.compile(lex).chkerr();
if (cmd&VM_AST) {
auto dumper = new ast_dumper();
dumper->visit_expr(parse.tree());
}
// linker gets parser's ast and load import files to this ast // linker gets parser's ast and load import files to this ast
// ld.link(parse, file, cmd&VM_DETAIL).chkerr(); // ld.link(parse, file, cmd&VM_DETAIL).chkerr();
// optimizer does simple optimization on ast // optimizer does simple optimization on ast
// optimize(parse.tree()); // optimize(parse.tree());
// if (cmd&VM_AST) {
// parse.tree().dump();
// }
// code generator gets parser's ast and import file list to generate code // code generator gets parser's ast and import file list to generate code
// gen.compile(parse, ld).chkerr(); // gen.compile(parse, ld).chkerr();

View File

@ -60,7 +60,7 @@ void parse::die(const span& loc, std::string info) {
err.err("parse", loc, info); err.err("parse", loc, info);
} }
void parse::match(tok type,const char* info) { void parse::match(tok type, const char* info) {
if (!lookahead(type)) { if (!lookahead(type)) {
if (info) { if (info) {
die(thisspan, info); die(thisspan, info);
@ -121,18 +121,10 @@ bool parse::check_func_end(expr* node) {
auto type=node->get_type(); auto type=node->get_type();
if (type==expr_type::ast_func) { if (type==expr_type::ast_func) {
return true; return true;
} else if (type==expr_type::ast_num || } else if (type==expr_type::ast_def) {
type==expr_type::ast_id || return check_func_end(((definition_expr*)node)->get_value());
type==expr_type::ast_str ||
type==expr_type::ast_nil ||
type==expr_type::ast_vec ||
type==expr_type::ast_hash) {
return false;
}
if (type==expr_type::ast_def) {
return check_func_end(((definition_expr*)type)->get_value());
} else if (type==expr_type::ast_assign) { } else if (type==expr_type::ast_assign) {
return check_func_end(((assignment_expr*)type)->get_right()); return check_func_end(((assignment_expr*)node)->get_right());
} }
return false; return false;
} }
@ -270,7 +262,7 @@ hash_pair* parse::pair() {
match(tok::id, "expected hashmap key"); match(tok::id, "expected hashmap key");
} }
match(tok::colon); match(tok::colon);
node->set_element(calc()); node->set_value(calc());
update_location(node); update_location(node);
return node; return node;
} }
@ -408,7 +400,6 @@ expr* parse::calc() {
tmp->set_right(calc()); tmp->set_right(calc());
node = tmp; node = tmp;
} else if (tok::eq<=toks[ptr].type && toks[ptr].type<=tok::lnkeq) { } else if (tok::eq<=toks[ptr].type && toks[ptr].type<=tok::lnkeq) {
// tok::eq~tok::lnkeq is 37 to 42,ast_equal~ast_lnkeq is 21~26
auto tmp = new assignment_expr(toks[ptr].loc); auto tmp = new assignment_expr(toks[ptr].loc);
switch(toks[ptr].type) { switch(toks[ptr].type) {
case tok::eq: tmp->set_type(assignment_expr::assign_type::equal); break; case tok::eq: tmp->set_type(assignment_expr::assign_type::equal); break;
@ -518,7 +509,6 @@ expr* parse::and_expr() {
expr* parse::cmp_expr() { expr* parse::cmp_expr() {
auto node = additive_expr(); auto node = additive_expr();
while(tok::cmpeq<=toks[ptr].type && toks[ptr].type<=tok::geq) { while(tok::cmpeq<=toks[ptr].type && toks[ptr].type<=tok::geq) {
// tok::cmpeq~tok::geq is 43~48,ast_cmpeq~ast_geq is 27~32
auto tmp = new binary_operator(toks[ptr].loc); auto tmp = new binary_operator(toks[ptr].loc);
switch(toks[ptr].type) { switch(toks[ptr].type) {
case tok::cmpeq: tmp->set_type(binary_operator::binary_type::cmpeq); break; case tok::cmpeq: tmp->set_type(binary_operator::binary_type::cmpeq); break;
@ -760,7 +750,7 @@ expr* parse::definition() {
return node; return node;
} }
multi_define* parse::incurve_def() { multi_identifier* parse::incurve_def() {
const auto& loc=toks[ptr].loc; const auto& loc=toks[ptr].loc;
match(tok::lcurve); match(tok::lcurve);
match(tok::var); match(tok::var);
@ -771,7 +761,7 @@ multi_define* parse::incurve_def() {
return node; return node;
} }
multi_define* parse::outcurve_def() { multi_identifier* parse::outcurve_def() {
const auto& loc=toks[ptr].loc; const auto& loc=toks[ptr].loc;
match(tok::lcurve); match(tok::lcurve);
auto node = multi_id(); auto node = multi_id();
@ -781,8 +771,8 @@ multi_define* parse::outcurve_def() {
return node; return node;
} }
multi_define* parse::multi_id() { multi_identifier* parse::multi_id() {
auto node = new multi_define(toks[ptr].loc); auto node = new multi_identifier(toks[ptr].loc);
while(!lookahead(tok::eof)) { while(!lookahead(tok::eof)) {
// only identifier is allowed here // only identifier is allowed here
// but we check it at codegen stage // but we check it at codegen stage
@ -826,16 +816,16 @@ tuple_expr* parse::multi_scalar() {
multi_assign* parse::multi_assignment() { multi_assign* parse::multi_assignment() {
auto node = new multi_assign(toks[ptr].loc); auto node = new multi_assign(toks[ptr].loc);
node->set_left(multi_scalar()); node->set_tuple(multi_scalar());
match(tok::eq); match(tok::eq);
if (lookahead(tok::eof)) { if (lookahead(tok::eof)) {
die(thisspan, "expected value list"); die(thisspan, "expected value list");
return node; return node;
} }
if (lookahead(tok::lcurve)) { if (lookahead(tok::lcurve)) {
node->set_right(check_tuple()?multi_scalar():calc()); node->set_value(check_tuple()?multi_scalar():calc());
} else { } else {
node->set_right(calc()); node->set_value(calc());
} }
update_location(node); update_location(node);
return node; return node;
@ -845,10 +835,10 @@ expr* parse::loop() {
++in_loop; ++in_loop;
expr* node = nullptr; expr* node = nullptr;
switch(toks[ptr].type) { switch(toks[ptr].type) {
case tok::rwhile: node=while_loop(); break; case tok::rwhile: node = while_loop(); break;
case tok::rfor: node=for_loop(); break; case tok::rfor: node = for_loop(); break;
case tok::forindex: case tok::forindex:
case tok::foreach: node=forei_loop(); break; case tok::foreach: node = forei_loop(); break;
default: break; default: break;
} }
--in_loop; --in_loop;
@ -870,6 +860,7 @@ for_expr* parse::for_loop() {
auto node = new for_expr(toks[ptr].loc); auto node = new for_expr(toks[ptr].loc);
match(tok::rfor); match(tok::rfor);
match(tok::lcurve); match(tok::lcurve);
// first expression // first expression
if (lookahead(tok::eof)) { if (lookahead(tok::eof)) {
die(thisspan, "expected definition"); die(thisspan, "expected definition");
@ -884,6 +875,7 @@ for_expr* parse::for_loop() {
node->set_initial(calc()); node->set_initial(calc());
} }
match(tok::semi, "expected ';' in for(;;)"); match(tok::semi, "expected ';' in for(;;)");
// conditional expression // conditional expression
if (lookahead(tok::eof)) { if (lookahead(tok::eof)) {
die(thisspan, "expected conditional expr"); die(thisspan, "expected conditional expr");
@ -894,6 +886,7 @@ for_expr* parse::for_loop() {
node->set_condition(calc()); node->set_condition(calc());
} }
match(tok::semi, "expected ';' in for(;;)"); match(tok::semi, "expected ';' in for(;;)");
//after loop expression //after loop expression
if (lookahead(tok::eof)) { if (lookahead(tok::eof)) {
die(thisspan, "expected calculation"); die(thisspan, "expected calculation");
@ -1009,7 +1002,7 @@ break_expr* parse::break_expression() {
return_expr* parse::return_expression() { return_expr* parse::return_expression() {
auto node = new return_expr(toks[ptr].loc); auto node = new return_expr(toks[ptr].loc);
match(tok::ret); match(tok::ret);
tok type=toks[ptr].type; tok type = toks[ptr].type;
if (type==tok::tknil || type==tok::num || if (type==tok::tknil || type==tok::num ||
type==tok::str || type==tok::id || type==tok::str || type==tok::id ||
type==tok::func || type==tok::sub || type==tok::func || type==tok::sub ||

View File

@ -120,9 +120,9 @@ private:
call_function* callf(); call_function* callf();
slice_vector* subvec(); slice_vector* subvec();
expr* definition(); expr* definition();
multi_define* incurve_def(); multi_identifier* incurve_def();
multi_define* outcurve_def(); multi_identifier* outcurve_def();
multi_define* multi_id(); multi_identifier* multi_id();
tuple_expr* multi_scalar(); tuple_expr* multi_scalar();
multi_assign* multi_assignment(); multi_assign* multi_assignment();
expr* loop(); expr* loop();

View File

@ -80,11 +80,12 @@ NASAL_NEW_AST=\
nasal_new_ast.o\ nasal_new_ast.o\
nasal_new_parse.o\ nasal_new_parse.o\
ast_visitor.o\ ast_visitor.o\
ast_dumper.o\
nasal_new_main.o nasal_new_main.o
# for test # for test
nasal_new: $(NASAL_NEW_AST) nnew: $(NASAL_NEW_AST)
$(CXX) $(NASAL_NEW_AST) -o nasal_new $(CXX) $(NASAL_NEW_AST) -o nnew
@ echo "build done" @ echo "build done"
nasal_new_main.o: ast/nasal_new_main.cpp nasal_new_main.o: ast/nasal_new_main.cpp
@ -108,6 +109,9 @@ nasal_new_parse.o: ast/nasal_new_parse.h ast/nasal_new_parse.cpp ast/nasal_new_a
ast_visitor.o: ast/nasal_new_ast.h ast/ast_visitor.h ast/ast_visitor.cpp ast_visitor.o: ast/nasal_new_ast.h ast/ast_visitor.h ast/ast_visitor.cpp
$(CXX) -std=$(STD) -c -O3 ast/ast_visitor.cpp -fno-exceptions -fPIC -o ast_visitor.o -I . $(CXX) -std=$(STD) -c -O3 ast/ast_visitor.cpp -fno-exceptions -fPIC -o ast_visitor.o -I .
ast_dumper.o: ast/nasal_new_ast.h ast/ast_visitor.h ast/ast_dumper.h ast/ast_dumper.cpp
$(CXX) -std=$(STD) -c -O3 ast/ast_dumper.cpp -fno-exceptions -fPIC -o ast_dumper.o -I .
.PHONY: nasal_new_clean .PHONY: nasal_new_clean
nasal_new_clean: nasal_new_clean:
rm $(NASAL_NEW_AST) rm $(NASAL_NEW_AST)