summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge (sonata) <tpg@mutabah.net>2015-01-11 15:00:32 +0800
committerJohn Hodge (sonata) <tpg@mutabah.net>2015-01-11 15:00:32 +0800
commit86938c184b32ce004d5247ad80f924f0ae7a3c86 (patch)
tree66dfdee288a8f3806dd869a9bccb910b8c854ab6
parentd9cba0738c5fe7928ea345f510f505fe777fd8ea (diff)
downloadmrust-86938c184b32ce004d5247ad80f924f0ae7a3c86.tar.gz
Add hacky text output of AST
-rw-r--r--Makefile4
-rw-r--r--src/ast/ast.cpp71
-rw-r--r--src/ast/ast.hpp64
-rw-r--r--src/ast/path.hpp13
-rw-r--r--src/include/serialise.hpp59
-rw-r--r--src/include/serialiser_texttree.hpp34
-rw-r--r--src/main.cpp5
-rw-r--r--src/serialise.cpp76
-rw-r--r--src/types.hpp8
9 files changed, 310 insertions, 24 deletions
diff --git a/Makefile b/Makefile
index a5f030bf..5c42b6bb 100644
--- a/Makefile
+++ b/Makefile
@@ -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