diff --git a/ast/ast_dumper.cpp b/ast/ast_dumper.cpp new file mode 100644 index 0000000..0aaba4a --- /dev/null +++ b/ast/ast_dumper.cpp @@ -0,0 +1,368 @@ +#include "ast_dumper.h" + +#include + +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; +} \ No newline at end of file diff --git a/ast/ast_dumper.h b/ast/ast_dumper.h new file mode 100644 index 0000000..4599537 --- /dev/null +++ b/ast/ast_dumper.h @@ -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; +}; \ No newline at end of file diff --git a/ast/ast_visitor.cpp b/ast/ast_visitor.cpp index 017a0e7..e641856 100644 --- a/ast/ast_visitor.cpp +++ b/ast/ast_visitor.cpp @@ -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; } \ No newline at end of file diff --git a/ast/ast_visitor.h b/ast/ast_visitor.h index 92d42b2..ff30483 100644 --- a/ast/ast_visitor.h +++ b/ast/ast_visitor.h @@ -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*); }; \ No newline at end of file diff --git a/ast/nasal_new_ast.cpp b/ast/nasal_new_ast.cpp index b487fe4..c6d7c16 100644 --- a/ast/nasal_new_ast.cpp +++ b/ast/nasal_new_ast.cpp @@ -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); } \ No newline at end of file diff --git a/ast/nasal_new_ast.h b/ast/nasal_new_ast.h index 2de3937..58ec85d 100644 --- a/ast/nasal_new_ast.h +++ b/ast/nasal_new_ast.h @@ -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& 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 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& 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& 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;} diff --git a/ast/nasal_new_main.cpp b/ast/nasal_new_main.cpp index 586243f..3f473b8 100644 --- a/ast/nasal_new_main.cpp +++ b/ast/nasal_new_main.cpp @@ -4,6 +4,7 @@ #include "nasal_new_ast.h" #include "nasal_new_parse.h" #include "ast_visitor.h" +#include "ast_dumper.h" #include #include @@ -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(); diff --git a/ast/nasal_new_parse.cpp b/ast/nasal_new_parse.cpp index 71bf125..00e3727 100644 --- a/ast/nasal_new_parse.cpp +++ b/ast/nasal_new_parse.cpp @@ -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 || diff --git a/ast/nasal_new_parse.h b/ast/nasal_new_parse.h index 72abdd1..98b736c 100644 --- a/ast/nasal_new_parse.h +++ b/ast/nasal_new_parse.h @@ -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(); diff --git a/makefile b/makefile index 5dfa980..3cc1563 100644 --- a/makefile +++ b/makefile @@ -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) \ No newline at end of file