diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/hir/dump.cpp | 624 | ||||
-rw-r--r-- | src/hir/from_ast.cpp | 2 | ||||
-rw-r--r-- | src/hir/main_bindings.hpp | 18 | ||||
-rw-r--r-- | src/include/main_bindings.hpp | 3 | ||||
-rw-r--r-- | src/main.cpp | 16 |
5 files changed, 654 insertions, 9 deletions
diff --git a/src/hir/dump.cpp b/src/hir/dump.cpp new file mode 100644 index 00000000..f5788ca3 --- /dev/null +++ b/src/hir/dump.cpp @@ -0,0 +1,624 @@ +/* + * MRustC - Rust Compiler + * - By John Hodge (Mutabah/thePowersGang) + * + * hir/dump.cpp + * - Dump the HIR module tree as pseudo-rust + */ +#include "main_bindings.hpp" +#include "visitor.hpp" +#include "expr.hpp" + +#define NODE_IS(valptr, tysuf) ( dynamic_cast<const ::HIR::ExprNode##tysuf*>(&*valptr) != nullptr ) + +namespace { + + class TreeVisitor: + public ::HIR::Visitor, + public ::HIR::ExprVisitor + { + ::std::ostream& m_os; + unsigned int m_indent_level; + + public: + TreeVisitor(::std::ostream& os): + m_os(os), + m_indent_level(0) + { + } + + void visit_module(::HIR::ItemPath p, ::HIR::Module& mod) override + { + m_os << indent() << "mod " << p.get_name() << " {\n"; + inc_indent(); + + // TODO: Print publicitiy. + ::HIR::Visitor::visit_module(p, mod); + + dec_indent(); + m_os << indent() << "}\n"; + } + + void visit_type_impl(::HIR::TypeImpl& impl) override + { + m_os << indent() << "impl" << impl.m_params.fmt_args() << " " << impl.m_type << "\n"; + if( ! impl.m_params.m_bounds.empty() ) + { + m_os << indent() << " " << impl.m_params.fmt_bounds() << "\n"; + } + m_os << indent() << "{\n"; + inc_indent(); + ::HIR::Visitor::visit_type_impl(impl); + dec_indent(); + m_os << indent() << "}\n"; + } + virtual void visit_trait_impl(const ::HIR::SimplePath& trait_path, ::HIR::TraitImpl& impl) override + { + m_os << indent() << "impl" << impl.m_params.fmt_args() << " " << trait_path << impl.m_trait_args << " for " << impl.m_type << "\n"; + if( ! impl.m_params.m_bounds.empty() ) + { + m_os << indent() << " " << impl.m_params.fmt_bounds() << "\n"; + } + m_os << indent() << "{\n"; + inc_indent(); + ::HIR::Visitor::visit_trait_impl(trait_path, impl); + dec_indent(); + m_os << indent() << "}\n"; + } + void visit_marker_impl(const ::HIR::SimplePath& trait_path, ::HIR::MarkerImpl& impl) override + { + m_os << indent() << "impl" << impl.m_params.fmt_args() << " " << (impl.is_positive ? "" : "!") << trait_path << impl.m_trait_args << " for " << impl.m_type << "\n"; + if( ! impl.m_params.m_bounds.empty() ) + { + m_os << indent() << " " << impl.m_params.fmt_bounds() << "\n"; + } + m_os << indent() << "{ }\n"; + } + + // - Type Items + void visit_type_alias(::HIR::ItemPath p, ::HIR::TypeAlias& item) override + { + m_os << indent() << "type " << p.get_name() << item.m_params.fmt_args() << " = " << item.m_type << item.m_params.fmt_bounds() << "\n"; + } + void visit_trait(::HIR::ItemPath p, ::HIR::Trait& item) override + { + m_os << indent() << "trait " << p.get_name() << item.m_params.fmt_args() << "\n"; + if( ! item.m_params.m_bounds.empty() ) + { + m_os << indent() << " " << item.m_params.fmt_bounds() << "\n"; + } + m_os << indent() << "{\n"; + inc_indent(); + ::HIR::Visitor::visit_trait(p, item); + dec_indent(); + m_os << indent() << "}\n"; + } + void visit_struct(::HIR::ItemPath p, ::HIR::Struct& item) override + { + m_os << indent() << "struct " << p.get_name() << item.m_params.fmt_args(); + TU_MATCHA( (item.m_data), (flds), + (Unit, + if( item.m_params.m_bounds.empty() ) + { + m_os << ";\n"; + } + else + { + m_os << "\n"; + m_os << indent() << " " << item.m_params.fmt_bounds() << "\n"; + m_os << indent() << " ;\n"; + } + ), + (Tuple, + m_os << "("; + for(const auto& fld : flds) + { + m_os << (fld.is_public ? "pub " : "") << fld.ent << ", "; + } + if( item.m_params.m_bounds.empty() ) + { + m_os << ");\n"; + } + else + { + m_os << ")\n"; + m_os << indent() << " " << item.m_params.fmt_bounds() << "\n"; + m_os << indent() << " ;\n"; + } + ), + (Named, + m_os << "\n"; + if( ! item.m_params.m_bounds.empty() ) + { + m_os << indent() << " " << item.m_params.fmt_bounds() << "\n"; + } + m_os << indent() << "{\n"; + inc_indent(); + for(const auto& fld : flds) + { + m_os << indent() << (fld.second.is_public ? "pub " : "") << fld.first << ": " << fld.second.ent << ",\n"; + } + dec_indent(); + m_os << indent() << "}\n"; + ) + ) + } + void visit_enum(::HIR::ItemPath p, ::HIR::Enum& item) override + { + m_os << indent() << "enum " << p.get_name() << item.m_params.fmt_args() << "\n"; + if( ! item.m_params.m_bounds.empty() ) + { + m_os << indent() << " " << item.m_params.fmt_bounds() << "\n"; + } + m_os << indent() << "{\n"; + inc_indent(); + for(const auto& var : item.m_variants) + { + m_os << indent() << var.first; + TU_MATCHA( (var.second), (e), + (Unit, + ), + (Value, + m_os << " = ?";// << + ), + (Tuple, + m_os << "("; + for(const auto& fld : e) + m_os << fld.ent << ", "; + m_os << ")"; + ), + (Struct, + m_os << "{\n"; + inc_indent(); + for(const auto& fld : e) + { + m_os << indent() << fld.first << ": " << fld.second.ent << ",\n"; + } + m_os << indent() << "}"; + dec_indent(); + ) + ) + m_os << ",\n"; + } + dec_indent(); + m_os << indent() << "}\n"; + } + + // - Value Items + void visit_function(::HIR::ItemPath p, ::HIR::Function& item) override + { + m_os << indent(); + if( item.m_const ) + m_os << "const "; + if( item.m_unsafe ) + m_os << "unsafe "; + if( item.m_abi != "rust" ) + m_os << "extern \"" << item.m_abi << "\" "; + m_os << "fn " << p.get_name() << item.m_params.fmt_args() << "("; + for(const auto& arg : item.m_args) + { + m_os << arg.first << ": " << arg.second << ", "; + } + m_os << ") -> " << item.m_return << "\n"; + if( ! item.m_params.m_bounds.empty() ) + { + m_os << indent() << " " << item.m_params.fmt_bounds() << "\n"; + } + + if( item.m_code ) + { + m_os << indent(); + item.m_code->visit( *this ); + m_os << "\n"; + } + else + { + m_os << indent() << " ;\n"; + } + } + void visit_static(::HIR::ItemPath p, ::HIR::Static& item) override + { + if( item.m_value ) + { + m_os << indent() << "static " << p.get_name() << ": " << item.m_type << " = " << item.m_value_res << ";\n"; + } + else + { + m_os << indent() << "extern static " << p.get_name() << ": " << item.m_type << ";\n"; + } + } + void visit_constant(::HIR::ItemPath p, ::HIR::Constant& item) override + { + m_os << indent() << "const " << p.get_name() << ": " << item.m_type << " = " << item.m_value_res << ";\n"; + } + + // - Misc + #if 0 + virtual void visit_params(::HIR::GenericParams& params); + virtual void visit_pattern(::HIR::Pattern& pat); + virtual void visit_pattern_val(::HIR::Pattern::Value& val); + virtual void visit_type(::HIR::TypeRef& tr); + + enum class PathContext { + TYPE, + TRAIT, + + VALUE, + }; + virtual void visit_trait_path(::HIR::TraitPath& p); + virtual void visit_path(::HIR::Path& p, PathContext ); + virtual void visit_path_params(::HIR::PathParams& p); + virtual void visit_generic_path(::HIR::GenericPath& p, PathContext ); + + virtual void visit_expr(::HIR::ExprPtr& exp); + #endif + + void visit(::HIR::ExprNode_Block& node) override + { + if( node.m_nodes.size() == 0 ) { + m_os << "{ }"; + } + //else if( node.m_nodes.size() == 1) { + // m_os << "{ "; + // this->visit_node_ptr(node.m_nodes.front()); + // m_os << " }"; + //} + else { + m_os << "{\n"; + inc_indent(); + for(auto& sn : node.m_nodes) { + m_os << indent(); + this->visit_node_ptr(sn); + if( &sn != &node.m_nodes.back() ) { + m_os << ";\n"; + } + else { + m_os << "\n"; + } + } + dec_indent(); + m_os << indent() << "}"; + } + } + + void visit(::HIR::ExprNode_Return& node) override + { + m_os << "return"; + if( node.m_value ) { + m_os << " "; + this->visit_node_ptr(node.m_value); + } + } + void visit(::HIR::ExprNode_Let& node) override + { + m_os << "let " << node.m_pattern << ": " << node.m_type; + if( node.m_value ) { + m_os << " = "; + this->visit_node_ptr(node.m_value); + } + m_os << ";"; + } + void visit(::HIR::ExprNode_Loop& node) override + { + if( node.m_label != "" ) { + m_os << "'" << node.m_label << ": "; + } + m_os << "loop "; + this->visit_node_ptr(node.m_code); + } + void visit(::HIR::ExprNode_LoopControl& node) override + { + m_os << (node.m_continue ? "continue" : "break"); + if( node.m_label != "" ) { + m_os << " '" << node.m_label; + } + } + void visit(::HIR::ExprNode_Match& node) override + { + m_os << "match "; + this->visit_node_ptr(node.m_value); + m_os << " {\n"; + for(/*const*/ auto& arm : node.m_arms) + { + m_os << indent(); + m_os << arm.m_patterns.front(); + for(unsigned int i = 1; i < arm.m_patterns.size(); i ++ ) { + m_os << " | " << arm.m_patterns[i]; + } + + if( arm.m_cond ) { + m_os << " if "; + this->visit_node_ptr(arm.m_cond); + } + m_os << " => "; + inc_indent(); + this->visit_node_ptr(arm.m_code); + dec_indent(); + m_os << ",\n"; + } + m_os << indent() << "}"; + } + void visit(::HIR::ExprNode_If& node) override + { + m_os << "if "; + this->visit_node_ptr(node.m_cond); + m_os << " "; + if( NODE_IS(node.m_true, _Block) ) { + this->visit_node_ptr(node.m_true); + } + else { + m_os << "{"; + this->visit_node_ptr(node.m_true); + m_os << "}"; + } + if( node.m_false ) + { + m_os << " else "; + if( NODE_IS(node.m_false, _Block) ) { + this->visit_node_ptr(node.m_false); + } + else { + m_os << "{ "; + this->visit_node_ptr(node.m_false); + m_os << " }"; + } + } + } + void visit(::HIR::ExprNode_Assign& node) override + { + this->visit_node_ptr(node.m_slot); + m_os << " = "; + this->visit_node_ptr(node.m_value); + } + void visit(::HIR::ExprNode_BinOp& node) override + { + m_os << "("; + this->visit_node_ptr(node.m_right); + m_os << ")"; + m_os << " " << ::HIR::ExprNode_BinOp::opname(node.m_op) << " "; + m_os << "("; + this->visit_node_ptr(node.m_left); + m_os << ")"; + } + void visit(::HIR::ExprNode_UniOp& node) override + { + switch(node.m_op) + { + case ::HIR::ExprNode_UniOp::Op::Invert: m_os << "!"; break; + case ::HIR::ExprNode_UniOp::Op::Negate: m_os << "-"; break; + } + m_os << "("; + this->visit_node_ptr(node.m_value); + m_os << ")"; + } + void visit(::HIR::ExprNode_Borrow& node) override + { + m_os << "&"; + switch(node.m_type) + { + case ::HIR::BorrowType::Shared: break; + case ::HIR::BorrowType::Unique: m_os << "mut "; break; + case ::HIR::BorrowType::Owned : m_os << "move "; break; + } + // TODO: Avoid parens + m_os << "("; + this->visit_node_ptr(node.m_value); + m_os << ")"; + } + void visit(::HIR::ExprNode_Cast& node) override + { + this->visit_node_ptr(node.m_value); + m_os << " as " << node.m_res_type; + } + void visit(::HIR::ExprNode_Unsize& node) override + { + this->visit_node_ptr(node.m_value); + m_os << " : " << node.m_res_type; + } + void visit(::HIR::ExprNode_Index& node) override + { + // TODO: Avoid parens + m_os << "("; + this->visit_node_ptr(node.m_value); + m_os << ")"; + m_os << "["; + this->visit_node_ptr(node.m_index); + m_os << "]"; + } + void visit(::HIR::ExprNode_Deref& node) override + { + m_os << "*"; + // TODO: Avoid parens + m_os << "("; + this->visit_node_ptr(node.m_value); + m_os << ")"; + } + void visit(::HIR::ExprNode_TupleVariant& node) override + { + m_os << node.m_path; + m_os << "("; + for(/*const*/ auto& arg : node.m_args) { + this->visit_node_ptr(arg); + m_os << ", "; + } + m_os << ")"; + } + void visit(::HIR::ExprNode_CallPath& node) override + { + m_os << node.m_path; + m_os << "("; + for(/*const*/ auto& arg : node.m_args) { + this->visit_node_ptr(arg); + m_os << ", "; + } + m_os << ")"; + } + void visit(::HIR::ExprNode_CallValue& node) override + { + // TODO: Avoid brackets if not needed + m_os << "("; + this->visit_node_ptr(node.m_value); + m_os << ")"; + m_os << "("; + for(/*const*/ auto& arg : node.m_args) { + this->visit_node_ptr(arg); + m_os << ", "; + } + m_os << ")"; + } + void visit(::HIR::ExprNode_CallMethod& node) override + { + // TODO: Avoid brackets if not needed + m_os << "("; + this->visit_node_ptr(node.m_value); + m_os << ")"; + m_os << "." << node.m_method << node.m_params << "("; + for(/*const*/ auto& arg : node.m_args) { + this->visit_node_ptr(arg); + m_os << ", "; + } + m_os << ")"; + } + void visit(::HIR::ExprNode_Field& node) override + { + // TODO: Avoid brackets if not needed + m_os << "("; + this->visit_node_ptr(node.m_value); + m_os << ")"; + m_os << "." << node.m_field; + } + void visit(::HIR::ExprNode_Literal& node) override + { + TU_MATCHA( (node.m_data), (e), + (Integer, + switch(e.m_type) + { + case ::HIR::CoreType::U8: m_os << e.m_value << "_u8" ; break; + case ::HIR::CoreType::U16: m_os << e.m_value << "_u16"; break; + case ::HIR::CoreType::U32: m_os << e.m_value << "_u32"; break; + case ::HIR::CoreType::U64: m_os << e.m_value << "_u64"; break; + case ::HIR::CoreType::Usize:m_os << e.m_value << "_usize"; break; + case ::HIR::CoreType::I8: m_os << static_cast<int64_t>(e.m_value) << "_i8"; break; + case ::HIR::CoreType::I16: m_os << static_cast<int64_t>(e.m_value) << "_i16"; break; + case ::HIR::CoreType::I32: m_os << static_cast<int64_t>(e.m_value) << "_i32"; break; + case ::HIR::CoreType::I64: m_os << static_cast<int64_t>(e.m_value) << "_i64"; break; + case ::HIR::CoreType::Isize:m_os << static_cast<int64_t>(e.m_value) << "_isize";break; + default: m_os << e.m_value << "_unk"; break; + } + ), + (Float, + switch(e.m_type) + { + case ::HIR::CoreType::F32: m_os << e.m_value << "_f32"; break; + case ::HIR::CoreType::F64: m_os << e.m_value << "_f64"; break; + default: m_os << e.m_value << "_unk"; break; + } + ), + (Boolean, + m_os << (e ? "true" : "false"); + ), + (String, + // TODO: Escape + m_os << "\"" << e << "\""; + ), + (ByteString, + // TODO: Escape + m_os << "b\"" << e << "\""; + ) + ) + } + void visit(::HIR::ExprNode_UnitVariant& node) override + { + m_os << node.m_path; + } + void visit(::HIR::ExprNode_PathValue& node) override + { + m_os << node.m_path; + } + void visit(::HIR::ExprNode_Variable& node) override + { + m_os << node.m_name << "#" << node.m_slot; + } + void visit(::HIR::ExprNode_StructLiteral& node) override + { + m_os << node.m_path << " {\n"; + inc_indent(); + for(/*const*/ auto& val : node.m_values) { + m_os << indent() << val.first << ": "; + this->visit_node_ptr( val.second ); + m_os << ",\n"; + } + if( node.m_base_value ) { + m_os << indent() << ".. "; + this->visit_node_ptr( node.m_base_value ); + m_os << "\n"; + } + m_os << indent() << "}"; + dec_indent(); + } + void visit(::HIR::ExprNode_Tuple& node) override + { + m_os << "("; + for( /*const*/ auto& val : node.m_vals ) + { + this->visit_node_ptr(val); + m_os << ", "; + } + m_os << ")"; + } + void visit(::HIR::ExprNode_ArrayList& node) override + { + m_os << "["; + for( /*const*/ auto& val : node.m_vals ) + { + this->visit_node_ptr(val); + m_os << ", "; + } + m_os << "]"; + } + void visit(::HIR::ExprNode_ArraySized& node) override + { + m_os << "["; + this->visit_node_ptr(node.m_val); + m_os << "; " << node.m_size_val; + m_os << "]"; + } + void visit(::HIR::ExprNode_Closure& node) override + { + if( node.m_code ) { + if(node.m_is_move) + m_os << " move"; + m_os << "|"; + for(const auto& arg : node.m_args) + m_os << arg.first << ": " << arg.second << ", "; + m_os << "| -> " << node.m_return << " "; + this->visit_node_ptr( node.m_code ); + } + else { + m_os << node.m_obj_path << "( "; + for(const auto& cap : node.m_var_captures) + m_os << "_#" << cap << ", "; + m_os << ")"; + } + } + + private: + RepeatLitStr indent() const { + return RepeatLitStr { " ", static_cast<int>(m_indent_level) }; + } + void inc_indent() { + m_indent_level ++; + } + void dec_indent() { + m_indent_level --; + } + }; +} + +void HIR_Dump(::std::ostream& sink, const ::HIR::Crate& crate) +{ + TreeVisitor tv { sink }; + + tv.visit_crate( const_cast< ::HIR::Crate&>(crate) ); +} + diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp index f001b081..4fe9759c 100644 --- a/src/hir/from_ast.cpp +++ b/src/hir/from_ast.cpp @@ -1,7 +1,7 @@ #include "common.hpp" #include "hir.hpp" -#include <main_bindings.hpp> +#include "main_bindings.hpp" #include <ast/ast.hpp> #include <ast/crate.hpp> #include "from_ast.hpp" diff --git a/src/hir/main_bindings.hpp b/src/hir/main_bindings.hpp new file mode 100644 index 00000000..6dd6fcc8 --- /dev/null +++ b/src/hir/main_bindings.hpp @@ -0,0 +1,18 @@ +/* + * MRustC - Rust Compiler + * - By John Hodge (Mutabah/thePowersGang) + * + * hir/main_bindings.hpp + * - Functions in hir/ used by main + */ +#pragma once + +#include "crate_ptr.hpp" +#include <iostream> + +namespace AST { + class Crate; +} + +extern void HIR_Dump(::std::ostream& sink, const ::HIR::Crate& crate); +extern ::HIR::CratePtr LowerHIR_FromAST(::AST::Crate crate); diff --git a/src/include/main_bindings.hpp b/src/include/main_bindings.hpp index 63169b61..c01ff86d 100644 --- a/src/include/main_bindings.hpp +++ b/src/include/main_bindings.hpp @@ -5,7 +5,6 @@ #include <string> #include <memory> -#include <hir/crate_ptr.hpp> namespace AST { class Crate; @@ -21,8 +20,6 @@ extern void Expand(::AST::Crate& crate); /// Process #[] decorators extern void Process_Decorators(AST::Crate& crate); -extern ::HIR::CratePtr LowerHIR_FromAST(::AST::Crate crate); - /// Convert the AST to a flat tree extern AST::Flat Convert_Flatten(const AST::Crate& crate); diff --git a/src/main.cpp b/src/main.cpp index 36e1b191..33d81473 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -17,6 +17,7 @@ #include <cstring>
#include <main_bindings.hpp>
#include "resolve/main_bindings.hpp"
+#include "hir/main_bindings.hpp"
#include "hir_conv/main_bindings.hpp"
#include "hir_typeck/main_bindings.hpp"
#include "hir_expand/main_bindings.hpp"
@@ -219,6 +220,11 @@ int main(int argc, char *argv[]) Typecheck_Expressions_Validate(*hir_crate);
});
+ CompilePhaseV("Dump HIR", [&]() {
+ ::std::ofstream os (FMT(params.outfile << "_3_hir.rs"));
+ HIR_Dump( os, *hir_crate );
+ });
+
if( params.last_stage == ProgramParams::STAGE_TYPECK ) {
return 0;
}
@@ -228,12 +234,12 @@ int main(int argc, char *argv[]) HIR_GenerateMIR(*hir_crate);
});
- // Flatten modules into "mangled" set
- //g_cur_phase = "Flatten";
- //AST::Flat flat_crate = Convert_Flatten(crate);
+ // Validate the MIR
+ // TODO: ^
+
+ // Generate code for non-generic public items (if requested)
- // Convert structures to C structures / tagged enums
- //Convert_Render(flat_crate, stdout);
+ // Save HIR tree (if requested)
}
catch(unsigned int) {}
//catch(const CompileError::Base& e)
|