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) {
if (node->get_element()) {
node->get_element()->accept(this);
if (node->get_value()) {
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;
}

View File

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

View File

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

View File

@ -4,6 +4,7 @@
#include "nasal_new_ast.h"
#include "nasal_new_parse.h"
#include "ast_visitor.h"
#include "ast_dumper.h"
#include <unordered_map>
#include <thread>
@ -86,15 +87,16 @@ void execute(
// parser gets lexer's token list to compile
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
// 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

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

View File

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

View File

@ -80,11 +80,12 @@ NASAL_NEW_AST=\
nasal_new_ast.o\
nasal_new_parse.o\
ast_visitor.o\
ast_dumper.o\
nasal_new_main.o
# for test
nasal_new: $(NASAL_NEW_AST)
$(CXX) $(NASAL_NEW_AST) -o nasal_new
nnew: $(NASAL_NEW_AST)
$(CXX) $(NASAL_NEW_AST) -o nnew
@ echo "build done"
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
$(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
nasal_new_clean:
rm $(NASAL_NEW_AST)