From 86938c184b32ce004d5247ad80f924f0ae7a3c86 Mon Sep 17 00:00:00 2001 From: "John Hodge (sonata)" Date: Sun, 11 Jan 2015 15:00:32 +0800 Subject: Add hacky text output of AST --- src/ast/ast.cpp | 71 +++++++++++++++++++++++++++++++++- src/ast/ast.hpp | 64 ++++++++++++++++++++++--------- src/ast/path.hpp | 13 +++++-- src/include/serialise.hpp | 59 ++++++++++++++++++++++++++++ src/include/serialiser_texttree.hpp | 34 +++++++++++++++++ src/main.cpp | 5 +++ src/serialise.cpp | 76 +++++++++++++++++++++++++++++++++++++ src/types.hpp | 8 +++- 8 files changed, 308 insertions(+), 22 deletions(-) create mode 100644 src/include/serialise.hpp create mode 100644 src/include/serialiser_texttree.hpp create mode 100644 src/serialise.cpp (limited to 'src') diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index 893810ec..51d476f8 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -23,6 +23,10 @@ const ::std::vector& PathNode::args() const { return m_params; } +SERIALISE_TYPE(PathNode::, "PathNode", { + s << m_name; + s << m_params; +}) // --- AST::Path template @@ -216,7 +220,26 @@ Path& Path::operator+=(const Path& other) } return os; } +::Serialiser& operator<<(Serialiser& s, Path::Class pc) +{ + switch(pc) + { + case Path::RELATIVE: s << "RELATIVE"; break; + case Path::ABSOLUTE: s << "ABSOLUTE"; break; + case Path::LOCAL: s << "LOCAL"; break; + } + return s; +} +SERIALISE_TYPE(Path::, "AST_Path", { + s << m_class; + s << m_nodes; +}) +SERIALISE_TYPE(MetaItem::, "AST_MetaItem", { + s << m_name; + s << m_str_val; + s << m_items; +}) ::std::ostream& operator<<(::std::ostream& os, const Pattern& pat) { @@ -259,6 +282,10 @@ void Crate::iterate_functions(fcn_visitor_t* visitor) { m_root_module.iterate_functions(visitor, *this); } +SERIALISE_TYPE(Crate::, "AST_Crate", { + s << m_load_std; + s << m_root_module; +}) ExternCrate::ExternCrate() { @@ -268,6 +295,8 @@ ExternCrate::ExternCrate(const char *path) { throw ParseError::Todo("Load extern crate from a file"); } +SERIALISE_TYPE(ExternCrate::, "AST_ExternCrate", { +}) ExternCrate ExternCrate_std() { @@ -299,6 +328,15 @@ ExternCrate ExternCrate_std() return crate; } +SERIALISE_TYPE(Module::, "AST_Module", { + s << m_name; + s << m_attrs; + s << m_extern_crates; + s << m_submods; + s << m_enums; + s << m_structs; + s << m_functions; +}) void Module::add_ext_crate(::std::string ext_name, ::std::string int_name) { DEBUG("add_ext_crate(\"" << ext_name << "\" as " << int_name << ")"); @@ -326,7 +364,6 @@ void Module::add_struct(bool is_public, ::std::string name, TypeParams params, : void Module::add_impl(Impl impl) { } - void Module::iterate_functions(fcn_visitor_t *visitor, const Crate& crate) { for( auto fcn_item : this->m_functions ) @@ -335,6 +372,35 @@ void Module::iterate_functions(fcn_visitor_t *visitor, const Crate& crate) } } +::Serialiser& operator<<(::Serialiser& s, Function::Class fc) +{ + switch(fc) + { + case Function::CLASS_UNBOUND: s << "UNBOUND"; break; + case Function::CLASS_REFMETHOD: s << "REFMETHOD"; break; + case Function::CLASS_MUTMETHOD: s << "MUTMETHOD"; break; + case Function::CLASS_VALMETHOD: s << "VALMETHOD"; break; + } + return s; +} +SERIALISE_TYPE(Function::, "AST_Function", { + s << m_fcn_class; + s << m_generic_params; + s << m_rettype; + s << m_args; + //s << m_code; +}) + +SERIALISE_TYPE(Enum::, "AST_Enum", { + s << m_params; + s << m_variants; +}) + +SERIALISE_TYPE(Struct::, "AST_Struct", { + s << m_params; + s << m_fields; +}) + void Expr::visit_nodes(NodeVisitor& v) { m_node->visit(v); @@ -421,5 +487,8 @@ void TypeParam::addTypeBound(TypeRef type) { } +SERIALISE_TYPE(TypeParam::, "AST_TypeParam", { + // TODO: TypeParam +}) } diff --git a/src/ast/ast.hpp b/src/ast/ast.hpp index c02840c6..510560fe 100644 --- a/src/ast/ast.hpp +++ b/src/ast/ast.hpp @@ -9,25 +9,30 @@ #include "../parse/tokentree.hpp" #include "../types.hpp" +#include namespace AST { using ::std::unique_ptr; using ::std::move; -class TypeParam +class TypeParam: + public Serialisable { public: TypeParam(bool is_lifetime, ::std::string name); void addLifetimeBound(::std::string name); void addTypeBound(TypeRef type); + + SERIALISABLE_PROTOTYPES(); }; typedef ::std::vector TypeParams; class Crate; -class MetaItem +class MetaItem: + public Serialisable { ::std::string m_name; ::std::vector m_items; @@ -44,6 +49,8 @@ public: } const ::std::string& name() const { return m_name; } + + SERIALISABLE_PROTOTYPES(); }; class ExprNode; @@ -140,7 +147,8 @@ public: typedef ::std::pair< ::std::string, TypeRef> StructItem; -class Function +class Function: + public Serialisable { public: enum Class @@ -153,15 +161,15 @@ public: typedef ::std::vector Arglist; private: - TypeParams m_generic_params; Class m_fcn_class; + TypeParams m_generic_params; Expr m_code; TypeRef m_rettype; Arglist m_args; public: Function(TypeParams params, Class fcn_class, TypeRef ret_type, Arglist args, Expr code): - m_generic_params(params), m_fcn_class(fcn_class), + m_generic_params(params), m_code(code), m_rettype(ret_type), m_args(args) @@ -169,19 +177,20 @@ public: } TypeParams& generic_params() { return m_generic_params; } - const TypeParams& generic_params() const { return m_generic_params; } - Expr& code() { return m_code; } - const Expr& code() const { return m_code; } - - const TypeRef& rettype() const { return m_rettype; } TypeRef& rettype() { return m_rettype; } + Arglist& args() { return m_args; } + const TypeParams& generic_params() const { return m_generic_params; } + const Expr& code() const { return m_code; } + const TypeRef& rettype() const { return m_rettype; } const Arglist& args() const { return m_args; } - Arglist& args() { return m_args; } + + SERIALISABLE_PROTOTYPES(); }; -class Enum +class Enum: + public Serialisable { ::std::vector m_params; ::std::vector m_variants; @@ -193,9 +202,12 @@ public: const ::std::vector params() const { return m_params; } const ::std::vector variants() const { return m_variants; } + + SERIALISABLE_PROTOTYPES(); }; -class Struct +class Struct: + public Serialisable { ::std::vector m_params; ::std::vector m_fields; @@ -206,6 +218,8 @@ public: {} const ::std::vector fields() const { return m_fields; } + + SERIALISABLE_PROTOTYPES(); }; class Impl @@ -224,7 +238,8 @@ class Module; typedef void fcn_visitor_t(const AST::Crate& crate, const AST::Module& mod, Function& fcn); template -struct Item +struct Item: + public Serialisable { ::std::string name; T data; @@ -236,10 +251,17 @@ struct Item is_pub( is_pub ) { } + + SERIALISE_TYPE(, "Item", { + s << is_pub; + s << name; + s << data; + }) }; /// Representation of a parsed (and being converted) function -class Module +class Module: + public Serialisable { typedef ::std::vector< Item > itemlist_fcn_t; typedef ::std::vector< ::std::pair > itemlist_mod_t; @@ -306,9 +328,12 @@ public: const itemlist_ext_t& extern_crates() const { return m_extern_crates; } const itemlist_enum_t& enums() const { return m_enums; } const itemlist_struct_t& structs() const { return m_structs; } + + SERIALISABLE_PROTOTYPES(); }; -class Crate +class Crate: + public Serialisable { public: Module m_root_module; @@ -320,11 +345,14 @@ public: const Module& root_module() const { return m_root_module; } void iterate_functions( fcn_visitor_t* visitor ); + + SERIALISABLE_PROTOTYPES(); }; /// Representation of an imported crate /// - Functions are stored as resolved+typechecked ASTs -class ExternCrate +class ExternCrate: + public Serialisable { Crate m_crate; public: @@ -334,6 +362,8 @@ public: const Crate& crate() const { return m_crate; } Module& root_module() { return m_crate.root_module(); } const Module& root_module() const { return m_crate.root_module(); } + + SERIALISABLE_PROTOTYPES(); }; class CStruct diff --git a/src/ast/path.hpp b/src/ast/path.hpp index f990dedb..b518fc8f 100644 --- a/src/ast/path.hpp +++ b/src/ast/path.hpp @@ -9,6 +9,7 @@ #include #include #include +#include class TypeRef; @@ -21,7 +22,8 @@ class Struct; class Function; -class PathNode +class PathNode: + public ::Serialisable { ::std::string m_name; ::std::vector m_params; @@ -41,9 +43,12 @@ public: } return os; } + + SERIALISABLE_PROTOTYPES(); }; -class Path +class Path: + public ::Serialisable { public: enum BindingType { @@ -145,8 +150,10 @@ public: PathNode& operator[](size_t idx) { return m_nodes[idx]; } const PathNode& operator[](size_t idx) const { return m_nodes[idx]; } - + + SERIALISABLE_PROTOTYPES(); friend ::std::ostream& operator<<(::std::ostream& os, const Path& path); + friend ::Serialiser& operator<<(Serialiser& s, Path::Class pc); private: void bind_module(const Module& mod); void bind_enum(const Enum& ent, const ::std::vector& args); diff --git a/src/include/serialise.hpp b/src/include/serialise.hpp new file mode 100644 index 00000000..f4b86133 --- /dev/null +++ b/src/include/serialise.hpp @@ -0,0 +1,59 @@ +/* + */ +#ifndef _SERIALSE_HPP_INCLUDED_ +#define _SERIALSE_HPP_INCLUDED_ + +#include +#include + +class Serialiser; + +#define SERIALISABLE_PROTOTYPES()\ + virtual const char* serialise_tag() const override; \ + virtual void serialise(::Serialiser& s) const override +#define SERIALISE_TYPE(method_prefix, tag_str, body) \ + const char* method_prefix serialise_tag() const { return tag_str; } \ + void method_prefix serialise(::Serialiser& s) const { body } + +class Serialisable +{ +public: + virtual const char* serialise_tag() const = 0; + virtual void serialise(Serialiser& s) const = 0; +}; + +class Serialiser +{ +protected: + virtual void start_object(const char *tag) = 0; + virtual void end_object(const char *tag) = 0; + virtual void start_array(unsigned int size) = 0; + virtual void end_array() = 0; +public: + virtual Serialiser& operator<<(bool val) = 0; + virtual Serialiser& operator<<(unsigned int val) = 0; + virtual Serialiser& operator<<(const ::std::string& s) = 0; + Serialiser& operator<<(const Serialisable& subobj); + + template + Serialiser& operator<<(const ::std::vector& v) + { + start_array(v.size()); + for(const auto& ent : v) + *this << ent; + end_array(); + return *this; + } + template + Serialiser& operator<<(const ::std::pair& v) + { + start_array(2); + *this << v.first; + *this << v.second; + end_array(); + return *this; + } +}; + +#endif + diff --git a/src/include/serialiser_texttree.hpp b/src/include/serialiser_texttree.hpp new file mode 100644 index 00000000..ad88e155 --- /dev/null +++ b/src/include/serialiser_texttree.hpp @@ -0,0 +1,34 @@ +/* + */ + +#ifndef _SERIALISER_TEXTTREE_HPP_INCLUDED_ +#define _SERIALISER_TEXTTREE_HPP_INCLUDED_ + +#include +#include "serialise.hpp" + +class Serialiser_TextTree: + public Serialiser +{ + ::std::ostream& m_os; + int m_indent_level; +public: + Serialiser_TextTree(::std::ostream& os); + + virtual Serialiser& operator<<(bool val) override; + virtual Serialiser& operator<<(unsigned int val) override; + virtual Serialiser& operator<<(const ::std::string& s) override; + +protected: + virtual void start_object(const char *tag) override; + virtual void end_object(const char* tag) override; + virtual void start_array(unsigned int size) override; + virtual void end_array() override; +private: + void indent(); + void unindent(); + void print_indent(); +}; + +#endif + diff --git a/src/main.cpp b/src/main.cpp index 4f92e593..19841c12 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3,6 +3,7 @@ #include "parse/lex.hpp" #include "parse/parseerror.hpp" #include "ast/ast.hpp" +#include extern AST::Crate Parse_Crate(::std::string mainfile); extern void ResolvePaths(AST::Crate& crate); @@ -15,6 +16,10 @@ int main(int argc, char *argv[]) { AST::Crate crate = Parse_Crate("samples/1.rs"); + Serialiser_TextTree s_tt(::std::cout); + Serialiser& s = s_tt; + s << crate; + // Resolve names to be absolute names (include references to the relevant struct/global/function) ResolvePaths(crate); diff --git a/src/serialise.cpp b/src/serialise.cpp new file mode 100644 index 00000000..e4825327 --- /dev/null +++ b/src/serialise.cpp @@ -0,0 +1,76 @@ +/* + */ +#include +#include + +Serialiser& Serialiser::operator<<(const Serialisable& subobj) +{ + start_object(subobj.serialise_tag()); + subobj.serialise(*this); + end_object(subobj.serialise_tag()); + return *this; +} + + +Serialiser_TextTree::Serialiser_TextTree(::std::ostream& os): + m_os(os) +{ +} + +void Serialiser_TextTree::start_object(const char *tag) { + print_indent(); + m_os << tag << "{\n"; + indent(); +} +void Serialiser_TextTree::end_object(const char *_tag) { + unindent(); + print_indent(); + m_os << "}\n"; +} +void Serialiser_TextTree::start_array(unsigned int size) { + print_indent(); + if( size == 0 ) + m_os << "["; + else + m_os << "[\n"; + indent(); +} +void Serialiser_TextTree::end_array() { + unindent(); + print_indent(); + m_os << "]\n"; +} +Serialiser& Serialiser_TextTree::operator<<(bool val) +{ + print_indent(); + m_os << (val ? "true" : "false") << "\n"; + return *this; +} +Serialiser& Serialiser_TextTree::operator<<(unsigned int val) +{ + print_indent(); + m_os << val << "\n"; + return *this; +} + +Serialiser& Serialiser_TextTree::operator<<(const ::std::string& s) +{ + print_indent(); + m_os << "\"" << s << "\"\n"; + return *this; +} +void Serialiser_TextTree::indent() +{ + m_indent_level ++; +} +void Serialiser_TextTree::unindent() +{ + m_indent_level --; +} +void Serialiser_TextTree::print_indent() +{ + for(int i = 0; i < m_indent_level; i ++) + m_os << " "; +} + + diff --git a/src/types.hpp b/src/types.hpp index 4a596522..2e6a1fa1 100644 --- a/src/types.hpp +++ b/src/types.hpp @@ -4,12 +4,14 @@ #include "common.hpp" #include "coretypes.hpp" #include "ast/path.hpp" +#include namespace AST { class Expr; } -class TypeRef +class TypeRef: + public Serialisable { public: TypeRef() {} @@ -40,6 +42,10 @@ public: os << "TypeRef(TODO)"; return os; } + + SERIALISE_TYPE(, "TypeRef", { + // TODO: Typeref serialise + }) }; #endif // TYPES_HPP_INCLUDED -- cgit v1.2.3