diff options
author | John Hodge (sonata) <tpg@mutabah.net> | 2015-01-11 15:00:32 +0800 |
---|---|---|
committer | John Hodge (sonata) <tpg@mutabah.net> | 2015-01-11 15:00:32 +0800 |
commit | 86938c184b32ce004d5247ad80f924f0ae7a3c86 (patch) | |
tree | 66dfdee288a8f3806dd869a9bccb910b8c854ab6 | |
parent | d9cba0738c5fe7928ea345f510f505fe777fd8ea (diff) | |
download | mrust-86938c184b32ce004d5247ad80f924f0ae7a3c86.tar.gz |
Add hacky text output of AST
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | src/ast/ast.cpp | 71 | ||||
-rw-r--r-- | src/ast/ast.hpp | 64 | ||||
-rw-r--r-- | src/ast/path.hpp | 13 | ||||
-rw-r--r-- | src/include/serialise.hpp | 59 | ||||
-rw-r--r-- | src/include/serialiser_texttree.hpp | 34 | ||||
-rw-r--r-- | src/main.cpp | 5 | ||||
-rw-r--r-- | src/serialise.cpp | 76 | ||||
-rw-r--r-- | src/types.hpp | 8 |
9 files changed, 310 insertions, 24 deletions
@@ -5,14 +5,14 @@ CXX ?= g++ LINKFLAGS := LIBS := CXXFLAGS := -Wall -std=c++11 -CPPFLAGS := +CPPFLAGS := -I src/include/ OBJDIR = .obj/ BIN := bin/mrustc$(EXESUF) -OBJ := main.o macros.o types.o ast/ast.o +OBJ := main.o macros.o types.o ast/ast.o serialise.o OBJ += parse/parseerror.o parse/lex.o parse/preproc.o parse/root.o parse/expr.o OBJ += convert/flatten.o convert/resolve.o convert/render.o OBJ := $(addprefix $(OBJDIR),$(OBJ)) 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<TypeRef>& PathNode::args() const {
return m_params;
}
+SERIALISE_TYPE(PathNode::, "PathNode", {
+ s << m_name;
+ s << m_params;
+})
// --- AST::Path
template<typename T>
@@ -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 <serialise.hpp>
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<TypeParam> TypeParams;
class Crate;
-class MetaItem
+class MetaItem:
+ public Serialisable
{
::std::string m_name;
::std::vector<MetaItem> 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<StructItem> 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<TypeParam> m_params;
::std::vector<StructItem> m_variants;
@@ -193,9 +202,12 @@ public: const ::std::vector<TypeParam> params() const { return m_params; }
const ::std::vector<StructItem> variants() const { return m_variants; }
+
+ SERIALISABLE_PROTOTYPES();
};
-class Struct
+class Struct:
+ public Serialisable
{
::std::vector<TypeParam> m_params;
::std::vector<StructItem> m_fields;
@@ -206,6 +218,8 @@ public: {}
const ::std::vector<StructItem> 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 <typename T>
-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<Function> > itemlist_fcn_t;
typedef ::std::vector< ::std::pair<Module, bool> > 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 <vector> #include <initializer_list> #include <cassert> +#include <serialise.hpp> class TypeRef; @@ -21,7 +22,8 @@ class Struct; class Function; -class PathNode +class PathNode: + public ::Serialisable { ::std::string m_name; ::std::vector<TypeRef> 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<TypeRef>& 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 <vector> +#include <string> + +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<typename T> + Serialiser& operator<<(const ::std::vector<T>& v) + { + start_array(v.size()); + for(const auto& ent : v) + *this << ent; + end_array(); + return *this; + } + template<typename T1, typename T2> + Serialiser& operator<<(const ::std::pair<T1,T2>& 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 <ostream> +#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 <serialiser_texttree.hpp>
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 <serialise.hpp> +#include <serialiser_texttree.hpp> + +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 <serialise.hpp>
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
|