✨ add ast dumper
This commit is contained in:
parent
2ce13e2134
commit
9f66960244
|
@ -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;
|
||||||
|
}
|
|
@ -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;
|
||||||
|
};
|
|
@ -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;
|
||||||
}
|
}
|
|
@ -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*);
|
||||||
};
|
};
|
|
@ -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);
|
||||||
}
|
}
|
|
@ -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;}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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 ||
|
||||||
|
|
|
@ -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();
|
||||||
|
|
8
makefile
8
makefile
|
@ -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)
|
Loading…
Reference in New Issue