From ba096985c2d2486592037f03e67c500d74292a83 Mon Sep 17 00:00:00 2001 From: "John Hodge (sonata)" Date: Sat, 17 Jan 2015 10:20:41 +0800 Subject: Adding deserialise, partially working --- src/ast/ast.cpp | 158 ++++++++++++++++++++++++++++-- src/ast/ast.hpp | 27 +++++- src/ast/expr.cpp | 124 +++++++++++++++++++++++- src/ast/expr.hpp | 49 +++++++++- src/ast/path.cpp | 15 +++ src/ast/path.hpp | 2 + src/ast/pattern.hpp | 5 +- src/coretypes.hpp | 7 ++ src/include/serialise.hpp | 122 +++++++++++++++++++++-- src/include/serialiser_texttree.hpp | 33 ++++++- src/main.cpp | 2 + src/serialise.cpp | 186 +++++++++++++++++++++++++++++++++--- src/types.cpp | 90 ++++++++++++++++- src/types.hpp | 3 + 14 files changed, 782 insertions(+), 41 deletions(-) diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index f176122b..cf88ed26 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -5,6 +5,7 @@ #include #include "../parse/parseerror.hpp" #include +#include namespace AST { @@ -14,6 +15,10 @@ SERIALISE_TYPE(MetaItem::, "AST_MetaItem", { s << m_name; s << m_str_val; s << m_items; +},{ + s.item(m_name); + s.item(m_str_val); + s.item(m_items); }) ::std::ostream& operator<<(::std::ostream& os, const Pattern& pat) @@ -39,6 +44,30 @@ SERIALISE_TYPE(MetaItem::, "AST_MetaItem", { } return os; } +void operator%(Serialiser& s, Pattern::BindType c) { + switch(c) + { + case Pattern::ANY: s << "ANY"; return; + case Pattern::MAYBE_BIND: s << "MAYBE_BIND"; return; + case Pattern::VALUE: s << "VALUE"; return; + case Pattern::TUPLE: s << "TUPLE"; return; + case Pattern::TUPLE_STRUCT: s << "TUPLE_STRUCT"; return; + } +} +void operator%(::Deserialiser& s, Pattern::BindType& c) { + ::std::string n; + s.item(n); + if(n == "ANY") c = Pattern::ANY; + else if(n == "MAYBE_BIND") c = Pattern::MAYBE_BIND; + else + throw ::std::runtime_error(""); +} +SERIALISE_TYPE_S(Pattern, { + s % m_class; + s.item(m_binding); + s.item(m_sub_patterns); + s.item(m_path); +}); SERIALISE_TYPE(Impl::, "AST_Impl", { @@ -46,6 +75,11 @@ SERIALISE_TYPE(Impl::, "AST_Impl", { s << m_trait; s << m_type; s << m_functions; +},{ + s.item(m_params); + s.item(m_trait); + s.item(m_type); + s.item(m_functions); }) Crate::Crate(): @@ -70,20 +104,37 @@ const Module& Crate::get_root_module(const ::std::string& name) const { } void Crate::load_extern_crate(::std::string name) { - if( name == "std" ) - { - // HACK! Load std using a hackjob (included within the compiler) - m_extern_crates.insert( make_pair( ::std::move(name), ExternCrate_std() ) ); - } - else + ::std::ifstream is("output/"+name+".ast"); + if( !is.is_open() ) { - throw ParseError::Todo("'extern crate' (not hackjob std)"); + throw ParseError::Generic("Can't open crate '" + name + "'"); } + Deserialiser_TextTree ds(is); + Deserialiser& d = ds; + + ExternCrate ret; + d.item( ret.crate() ); + + m_extern_crates.insert( make_pair(::std::move(name), ::std::move(ret)) ); + + //if( name == "std" ) + //{ + // // HACK! Load std using a hackjob (included within the compiler) + // m_extern_crates.insert( make_pair( ::std::move(name), ExternCrate_std() ) ); + //} + //else + //{ + // throw ParseError::Todo("'extern crate' (not hackjob std)"); + //} } SERIALISE_TYPE(Crate::, "AST_Crate", { s << m_load_std; s << m_extern_crates; s << m_root_module; +},{ + s.item(m_load_std); + s.item(m_extern_crates); + s.item(m_root_module); }) ExternCrate::ExternCrate() @@ -95,6 +146,7 @@ ExternCrate::ExternCrate(const char *path) throw ParseError::Todo("Load extern crate from a file"); } SERIALISE_TYPE(ExternCrate::, "AST_ExternCrate", { +},{ }) ExternCrate ExternCrate_std() @@ -171,11 +223,35 @@ ExternCrate ExternCrate_std() SERIALISE_TYPE(Module::, "AST_Module", { s << m_name; s << m_attrs; + s << m_extern_crates; s << m_submods; + + s << m_imports; + s << m_type_aliases; + s << m_enums; s << m_structs; + s << m_statics; + s << m_functions; + s << m_impls; +},{ + s.item(m_name); + s.item(m_attrs); + + s.item(m_extern_crates); + s.item(m_submods); + + s.item(m_imports); + s.item(m_type_aliases); + + s.item(m_enums); + s.item(m_structs); + s.item(m_statics); + + s.item(m_functions); + s.item(m_impls); }) void Module::add_ext_crate(::std::string ext_name, ::std::string int_name) { @@ -193,6 +269,9 @@ void Module::iterate_functions(fcn_visitor_t *visitor, const Crate& crate) SERIALISE_TYPE(TypeAlias::, "AST_TypeAlias", { s << m_params; s << m_type; +},{ + s.item(m_params); + s.item(m_type); }) ::Serialiser& operator<<(::Serialiser& s, Static::Class fc) @@ -205,10 +284,24 @@ SERIALISE_TYPE(TypeAlias::, "AST_TypeAlias", { } return s; } +void operator>>(::Deserialiser& s, Static::Class& fc) +{ + ::std::string n; + s.item(n); + if(n == "CONST") fc = Static::CONST; + else if(n == "STATIC") fc = Static::STATIC; + else if(n == "MUT") fc = Static::MUT; + else + throw ::std::runtime_error("Deserialise Static::Class"); +} SERIALISE_TYPE(Static::, "AST_Static", { s << m_class; s << m_type; - //s << m_value; + s << m_value; +},{ + s >> m_class; + s.item(m_type); + s.item(m_value); }) ::Serialiser& operator<<(::Serialiser& s, Function::Class fc) @@ -222,28 +315,55 @@ SERIALISE_TYPE(Static::, "AST_Static", { } return s; } +void operator>>(::Deserialiser& s, Function::Class& fc) +{ + ::std::string n; + s.item(n); + if(n == "UNBOUND") fc = Function::CLASS_UNBOUND; + else if(n == "REFMETHOD") fc = Function::CLASS_REFMETHOD; + else if(n == "MUTMETHOD") fc = Function::CLASS_MUTMETHOD; + else if(n == "VALMETHOD") fc = Function::CLASS_VALMETHOD; + else + throw ::std::runtime_error("Deserialise Function::Class"); +} SERIALISE_TYPE(Function::, "AST_Function", { s << m_fcn_class; s << m_generic_params; s << m_rettype; s << m_args; - //s << m_code; + s << m_code; +},{ + s >> m_fcn_class; + s.item(m_generic_params); + s.item(m_rettype); + s.item(m_args); + s.item(m_code); }) SERIALISE_TYPE(Trait::, "AST_Trait", { s << m_params; s << m_types; s << m_functions; +},{ + s.item(m_params); + s.item(m_types); + s.item(m_functions); }) SERIALISE_TYPE(Enum::, "AST_Enum", { s << m_params; s << m_variants; +},{ + s.item(m_params); + s.item(m_variants); }) SERIALISE_TYPE(Struct::, "AST_Struct", { s << m_params; s << m_fields; +},{ + s.item(m_params); + s.item(m_fields); }) void TypeParam::addLifetimeBound(::std::string name) @@ -271,7 +391,25 @@ void TypeParam::addTypeBound(TypeRef type) return os; } SERIALISE_TYPE(TypeParam::, "AST_TypeParam", { - // TODO: TypeParam + const char *classstr = "-"; + switch(m_class) + { + case TypeParam::LIFETIME: classstr = "Lifetime"; break; + case TypeParam::TYPE: classstr = "Type"; break; + } + s << classstr; + s << m_name; + s << m_trait_bounds; +},{ + { + ::std::string n; + s.item(n); + if(n == "Lifetime") m_class = TypeParam::LIFETIME; + else if(n == "Type") m_class = TypeParam::TYPE; + else throw ::std::runtime_error(""); + } + s.item(m_name); + s.item(m_trait_bounds); }) } diff --git a/src/ast/ast.hpp b/src/ast/ast.hpp index f5f9b2fb..31cab495 100644 --- a/src/ast/ast.hpp +++ b/src/ast/ast.hpp @@ -33,6 +33,9 @@ class TypeParam: ::std::string m_name; ::std::vector m_trait_bounds; public: + TypeParam(): + m_class(LIFETIME) + {} TypeParam(bool is_lifetime, ::std::string name): m_class( is_lifetime ? LIFETIME : TYPE ), m_name( ::std::move(name) ) @@ -59,6 +62,9 @@ struct Item: T data; bool is_pub; + Item(): + is_pub(false) + {} Item(::std::string&& name, T&& data, bool is_pub): name( move(name) ), data( move(data) ), @@ -67,9 +73,11 @@ struct Item: } SERIALISE_TYPE(, "Item", { - s << is_pub; - s << name; - s << data; + s << name << data << is_pub; + },{ + s.item(name); + s.item(data); + s.item(is_pub); }) }; template @@ -87,6 +95,7 @@ class MetaItem: ::std::vector m_items; ::std::string m_str_val; public: + MetaItem() {} MetaItem(::std::string name): m_name(name) { @@ -108,6 +117,7 @@ class TypeAlias: TypeParams m_params; TypeRef m_type; public: + TypeAlias() {} TypeAlias(TypeParams params, TypeRef type): m_params( move(params) ), m_type( move(type) ) @@ -134,6 +144,9 @@ private: TypeRef m_type; Expr m_value; public: + Static(): + m_class(CONST) + {} Static(Class s_class, TypeRef type, Expr value): m_class(s_class), m_type( move(type) ), @@ -163,6 +176,9 @@ private: TypeRef m_rettype; Arglist m_args; public: + Function(): + m_fcn_class(CLASS_UNBOUND) + {} Function(TypeParams params, Class fcn_class, TypeRef ret_type, Arglist args, Expr code): m_fcn_class(fcn_class), m_generic_params(params), @@ -192,6 +208,7 @@ class Trait: ItemList m_types; ItemList m_functions; public: + Trait() {} Trait(TypeParams params): m_params(params) { @@ -213,6 +230,7 @@ class Enum: ::std::vector m_params; ::std::vector m_variants; public: + Enum() {} Enum( ::std::vector params, ::std::vector variants ): m_params( move(params) ), m_variants( move(variants) ) @@ -230,6 +248,7 @@ class Struct: ::std::vector m_params; ::std::vector m_fields; public: + Struct() {} Struct( ::std::vector params, ::std::vector fields ): m_params( move(params) ), m_fields( move(fields) ) @@ -250,6 +269,7 @@ class Impl: ::std::vector > m_functions; public: + Impl() {} Impl(TypeParams params, TypeRef impl_type, TypeRef trait_type): m_params( move(params) ), m_trait( move(trait_type) ), @@ -306,6 +326,7 @@ class Module: itemlist_struct_t m_structs; ::std::vector m_impls; public: + Module() {} Module(::std::string name): m_name(name) { diff --git a/src/ast/expr.cpp b/src/ast/expr.cpp index b125eea3..92a189e1 100644 --- a/src/ast/expr.cpp +++ b/src/ast/expr.cpp @@ -13,7 +13,31 @@ void Expr::visit_nodes(NodeVisitor& v) os << "Expr(TODO)"; return os; } - +SERIALISE_TYPE(Expr::, "Expr", { + s.item(m_node); +},{ + bool tmp; + s.item(tmp); + if( tmp ) + m_node = ExprNode::from_deserialiser(s); + else + m_node.reset(); +}); + +::std::unique_ptr ExprNode::from_deserialiser(Deserialiser& d) { + ::std::string tag = d.start_object(); + + DEBUG("tag = " << tag); + ExprNode* ptr = nullptr; + if(tag == "ExprNode_Block") ptr = new ExprNode_Block; + else if(tag == "ExprNode_Macro") ptr = new ExprNode_Macro; + else + throw ::std::runtime_error("Unknown node type " + tag); + + ptr->deserialise(d); + d.end_object(tag.c_str()); + return ::std::unique_ptr(ptr); +} ExprNode::~ExprNode() { } @@ -22,64 +46,162 @@ ExprNode_Block::~ExprNode_Block() { void ExprNode_Block::visit(NodeVisitor& nv) { nv.visit(*this); } +SERIALISE_TYPE_S(ExprNode_Block, { + s.item(m_nodes); +}) + +void ExprNode_Macro::visit(NodeVisitor& nv) { + nv.visit(*this); +} +SERIALISE_TYPE_S(ExprNode_Macro, { + s.item(m_name); + //s.item(m_tokens); +}) void ExprNode_Return::visit(NodeVisitor& nv) { nv.visit(*this); } +SERIALISE_TYPE_S(ExprNode_Return, { + s.item(m_value); +}) void ExprNode_LetBinding::visit(NodeVisitor& nv) { nv.visit(*this); } +SERIALISE_TYPE_S(ExprNode_LetBinding, { + s.item(m_pat); + s.item(m_value); +}) void ExprNode_Assign::visit(NodeVisitor& nv) { nv.visit(*this); } +SERIALISE_TYPE_S(ExprNode_Assign, { + s.item(m_slot); + s.item(m_value); +}) void ExprNode_CallPath::visit(NodeVisitor& nv) { nv.visit(*this); } +SERIALISE_TYPE_S(ExprNode_CallPath, { + s.item(m_path); + s.item(m_args); +}) void ExprNode_CallMethod::visit(NodeVisitor& nv) { nv.visit(*this); } +SERIALISE_TYPE_S(ExprNode_CallMethod, { + s.item(m_val); + s.item(m_method); + s.item(m_args); +}) void ExprNode_CallObject::visit(NodeVisitor& nv) { nv.visit(*this); } +SERIALISE_TYPE_S(ExprNode_CallObject, { + s.item(m_val); + s.item(m_args); +}) void ExprNode_Match::visit(NodeVisitor& nv) { nv.visit(*this); } +SERIALISE_TYPE_S(ExprNode_Match, { + s.item(m_val); + s.item(m_arms); +}) void ExprNode_If::visit(NodeVisitor& nv) { nv.visit(*this); } +SERIALISE_TYPE_S(ExprNode_If, { + s.item(m_cond); + s.item(m_true); + s.item(m_false); +}) void ExprNode_Integer::visit(NodeVisitor& nv) { nv.visit(*this); } +SERIALISE_TYPE_S(ExprNode_Integer, { + s % m_datatype; + s.item(m_value); +}) void ExprNode_StructLiteral::visit(NodeVisitor& nv) { nv.visit(*this); } +SERIALISE_TYPE_S(ExprNode_StructLiteral, { + s.item(m_path); + s.item(m_base_value); + s.item(m_values); +}) void ExprNode_Tuple::visit(NodeVisitor& nv) { nv.visit(*this); } +SERIALISE_TYPE_S(ExprNode_Tuple, { + s.item(m_values); +}) void ExprNode_NamedValue::visit(NodeVisitor& nv) { nv.visit(*this); } +SERIALISE_TYPE_S(ExprNode_NamedValue, { + s.item(m_path); +}) void ExprNode_Field::visit(NodeVisitor& nv) { nv.visit(*this); } +SERIALISE_TYPE_S(ExprNode_Field, { + s.item(m_obj); + s.item(m_name); +}) void ExprNode_Cast::visit(NodeVisitor& nv) { nv.visit(*this); } +SERIALISE_TYPE_S(ExprNode_Cast, { + s.item(m_value); + s.item(m_type); +}) + void ExprNode_BinOp::visit(NodeVisitor& nv) { nv.visit(*this); } +void operator%(::Serialiser& s, const ExprNode_BinOp::Type t) { + switch(t) + { + #define _(v) case ExprNode_BinOp::v: s << #v; return + _(CMPEQU); + _(CMPNEQU); + _(BITAND); + _(BITOR); + _(BITXOR); + _(SHL); + _(SHR); + #undef _ + } +} +void operator%(::Deserialiser& s, ExprNode_BinOp::Type& t) { + ::std::string n; + s.item(n); + #define _(v) if(n == #v) t = ExprNode_BinOp::v + _(CMPEQU); + else _(CMPNEQU); + else + throw ::std::runtime_error(""); + #undef _ +} +SERIALISE_TYPE_S(ExprNode_BinOp, { + s % m_type; + s.item(m_left); + s.item(m_right); +}) + }; diff --git a/src/ast/expr.hpp b/src/ast/expr.hpp index bf238c6f..f6de9b99 100644 --- a/src/ast/expr.hpp +++ b/src/ast/expr.hpp @@ -17,12 +17,15 @@ using ::std::unique_ptr; class NodeVisitor; -class ExprNode +class ExprNode: + public Serialisable { public: virtual ~ExprNode() = 0; virtual void visit(NodeVisitor& nv) = 0; + + static ::std::unique_ptr from_deserialiser(Deserialiser& d); }; struct ExprNode_Block: @@ -30,7 +33,7 @@ struct ExprNode_Block: { ::std::vector< ::std::unique_ptr > m_nodes; - ExprNode_Block(const ExprNode_Block& x) = delete; + ExprNode_Block() {} ExprNode_Block(::std::vector< ::std::unique_ptr >&& nodes): m_nodes( move(nodes) ) { @@ -38,6 +41,8 @@ struct ExprNode_Block: virtual ~ExprNode_Block() override; virtual void visit(NodeVisitor& nv) override; + + SERIALISABLE_PROTOTYPES(); }; struct ExprNode_Macro: @@ -46,12 +51,15 @@ struct ExprNode_Macro: ::std::string m_name; ::TokenTree m_tokens; + ExprNode_Macro() {} ExprNode_Macro(::std::string name, ::TokenTree&& tokens): m_name(name), m_tokens( move(tokens) ) {} virtual void visit(NodeVisitor& nv) override; + + SERIALISABLE_PROTOTYPES(); }; // Return a value @@ -66,6 +74,8 @@ struct ExprNode_Return: } virtual void visit(NodeVisitor& nv) override; + + SERIALISABLE_PROTOTYPES(); }; struct ExprNode_LetBinding: public ExprNode @@ -80,6 +90,8 @@ struct ExprNode_LetBinding: } virtual void visit(NodeVisitor& nv) override; + + SERIALISABLE_PROTOTYPES(); }; struct ExprNode_Assign: public ExprNode @@ -94,6 +106,8 @@ struct ExprNode_Assign: } virtual void visit(NodeVisitor& nv) override; + + SERIALISABLE_PROTOTYPES(); }; struct ExprNode_CallPath: public ExprNode @@ -108,6 +122,8 @@ struct ExprNode_CallPath: } virtual void visit(NodeVisitor& nv) override; + + SERIALISABLE_PROTOTYPES(); }; struct ExprNode_CallMethod: public ExprNode @@ -124,6 +140,8 @@ struct ExprNode_CallMethod: } virtual void visit(NodeVisitor& nv) override; + + SERIALISABLE_PROTOTYPES(); }; // Call an object (Fn/FnMut/FnOnce) struct ExprNode_CallObject: @@ -138,6 +156,8 @@ struct ExprNode_CallObject: { } virtual void visit(NodeVisitor& nv) override; + + SERIALISABLE_PROTOTYPES(); }; struct ExprNode_Match: @@ -153,6 +173,8 @@ struct ExprNode_Match: { } virtual void visit(NodeVisitor& nv) override; + + SERIALISABLE_PROTOTYPES(); }; struct ExprNode_If: @@ -169,6 +191,8 @@ struct ExprNode_If: { } virtual void visit(NodeVisitor& nv) override; + + SERIALISABLE_PROTOTYPES(); }; // Literal integer struct ExprNode_Integer: @@ -184,6 +208,8 @@ struct ExprNode_Integer: } virtual void visit(NodeVisitor& nv) override; + + SERIALISABLE_PROTOTYPES(); }; // Literal structure struct ExprNode_StructLiteral: @@ -201,6 +227,8 @@ struct ExprNode_StructLiteral: {} virtual void visit(NodeVisitor& nv) override; + + SERIALISABLE_PROTOTYPES(); }; // Tuple struct ExprNode_Tuple: @@ -213,6 +241,8 @@ struct ExprNode_Tuple: {} virtual void visit(NodeVisitor& nv) override; + + SERIALISABLE_PROTOTYPES(); }; // Variable / Constant struct ExprNode_NamedValue: @@ -224,6 +254,8 @@ struct ExprNode_NamedValue: { } virtual void visit(NodeVisitor& nv) override; + + SERIALISABLE_PROTOTYPES(); }; // Field dereference struct ExprNode_Field: @@ -238,6 +270,8 @@ struct ExprNode_Field: { } virtual void visit(NodeVisitor& nv) override; + + SERIALISABLE_PROTOTYPES(); }; // Type cast ('as') @@ -253,6 +287,8 @@ struct ExprNode_Cast: { } virtual void visit(NodeVisitor& nv) override; + + SERIALISABLE_PROTOTYPES(); }; // Binary operation @@ -283,6 +319,8 @@ struct ExprNode_BinOp: } virtual void visit(NodeVisitor& nv) override; + + SERIALISABLE_PROTOTYPES(); }; class NodeVisitor @@ -297,6 +335,8 @@ public: for( auto& child : node.m_nodes ) visit(child); } + virtual void visit(ExprNode_Macro& node) { + } virtual void visit(ExprNode_Return& node) { visit(node.m_value); } @@ -361,7 +401,8 @@ public: } }; -class Expr +class Expr: + public Serialisable { ::std::shared_ptr m_node; public: @@ -382,6 +423,8 @@ public: void visit_nodes(NodeVisitor& v); friend ::std::ostream& operator<<(::std::ostream& os, const Expr& pat); + + SERIALISABLE_PROTOTYPES(); }; } diff --git a/src/ast/path.cpp b/src/ast/path.cpp index 636c4166..eab5d745 100644 --- a/src/ast/path.cpp +++ b/src/ast/path.cpp @@ -26,6 +26,9 @@ const ::std::vector& PathNode::args() const SERIALISE_TYPE(PathNode::, "PathNode", { s << m_name; s << m_params; +},{ + s.item(m_name); + s.item(m_params); }) // --- AST::Path @@ -287,9 +290,21 @@ Path& Path::operator+=(const Path& other) } return s; } +void operator>>(Deserialiser& s, Path::Class& pc) +{ + ::std::string n; + s.item(n); + if(n == "RELATIVE") pc = Path::RELATIVE; + else if(n == "ABSOLUTE") pc = Path::ABSOLUTE; + else if(n == "LOCAL") pc = Path::LOCAL; + else throw ::std::runtime_error("Unknown path class : " + n); +} SERIALISE_TYPE(Path::, "AST_Path", { s << m_class; s << m_nodes; +},{ + s >> m_class; + s.item(m_nodes); }) } diff --git a/src/ast/path.hpp b/src/ast/path.hpp index f4818764..6370580f 100644 --- a/src/ast/path.hpp +++ b/src/ast/path.hpp @@ -30,6 +30,7 @@ class PathNode: ::std::string m_name; ::std::vector m_params; public: + PathNode() {} PathNode(::std::string name, ::std::vector args = {}); const ::std::string& name() const; ::std::vector& args() { return m_params; } @@ -171,6 +172,7 @@ public: SERIALISABLE_PROTOTYPES(); friend ::std::ostream& operator<<(::std::ostream& os, const Path& path); friend ::Serialiser& operator<<(Serialiser& s, Path::Class pc); + friend void operator>>(Deserialiser& 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/ast/pattern.hpp b/src/ast/pattern.hpp index 70253c09..70fc77f4 100644 --- a/src/ast/pattern.hpp +++ b/src/ast/pattern.hpp @@ -13,7 +13,8 @@ using ::std::move; class ExprNode; -class Pattern +class Pattern: + public Serialisable { public: enum BindType { @@ -81,6 +82,8 @@ public: const ::std::vector& sub_patterns() const { return m_sub_patterns; } friend ::std::ostream& operator<<(::std::ostream& os, const Pattern& pat); + + SERIALISABLE_PROTOTYPES(); }; }; diff --git a/src/coretypes.hpp b/src/coretypes.hpp index 99d574b3..2982d42f 100644 --- a/src/coretypes.hpp +++ b/src/coretypes.hpp @@ -1,6 +1,9 @@ #ifndef CORETYPES_HPP_INCLUDED #define CORETYPES_HPP_INCLUDED +class Serialiser; +class Deserialiser; + enum eCoreType { CORETYPE_INVAL, @@ -15,4 +18,8 @@ enum eCoreType CORETYPE_F64, }; +extern const char* coretype_name(const eCoreType ct); +extern void operator% (::Serialiser& d, eCoreType ct); +extern void operator% (::Deserialiser& d, eCoreType& ct); + #endif // CORETYPES_HPP_INCLUDED diff --git a/src/include/serialise.hpp b/src/include/serialise.hpp index be5658a8..000f8141 100644 --- a/src/include/serialise.hpp +++ b/src/include/serialise.hpp @@ -6,21 +6,27 @@ #include #include #include +#include class Serialiser; +class Deserialiser; #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) \ + virtual void serialise(::Serialiser& s) const override; \ + virtual void deserialise(::Deserialiser& s) override +#define SERIALISE_TYPE(method_prefix, tag_str, body, des_body) \ const char* method_prefix serialise_tag() const { return tag_str; } \ - void method_prefix serialise(::Serialiser& s) const { body } + void method_prefix serialise(::Serialiser& s) const { body } \ + void method_prefix deserialise(::Deserialiser& s) { des_body } +#define SERIALISE_TYPE_S(class_, body) SERIALISE_TYPE(class_::, #class_, body, body) class Serialisable { public: virtual const char* serialise_tag() const = 0; virtual void serialise(Serialiser& s) const = 0; + virtual void deserialise(Deserialiser& s) = 0; }; class Serialiser @@ -31,9 +37,15 @@ protected: virtual void start_array(unsigned int size) = 0; virtual void end_array() = 0; public: + template + inline void item(T& v) { *this << v; } + virtual Serialiser& operator<<(bool val) = 0; - virtual Serialiser& operator<<(unsigned int val) = 0; - virtual Serialiser& operator<<(const ::std::string& s) = 0; + virtual Serialiser& operator<<(uint64_t val) = 0; + virtual Serialiser& operator<<(const char* s) = 0; + Serialiser& operator<<(const ::std::string& s) { + return *this << s.c_str(); + } Serialiser& operator<<(const Serialisable& subobj); template @@ -45,6 +57,22 @@ public: end_array(); return *this; } + template + Serialiser& operator<<(const ::std::shared_ptr& v) + { + *this << v.get(); + if(v.get()) + *this << *v; + return *this; + } + template + Serialiser& operator<<(const ::std::unique_ptr& v) + { + *this << v.get(); + if(v.get()) + *this << *v; + return *this; + } template Serialiser& operator<<(const ::std::pair& v) { @@ -57,13 +85,93 @@ public: template Serialiser& operator<<(const ::std::map& v) { - start_object("map"); + start_array(v.size()); for(const auto& ent : v) *this << ent; - end_object("map"); + end_array(); return *this; } }; +class Deserialiser +{ +protected: + virtual size_t start_array() = 0; + virtual void end_array() = 0; + + virtual ::std::string read_tag() = 0; +public: + virtual void item(bool& b) = 0; + virtual void item(uint64_t& v) = 0; + virtual void item(::std::string& s) = 0; + + virtual void start_object(const char *tag) = 0; + virtual void end_object(const char *tag) = 0; + ::std::string start_object(); + + void item(Serialisable& v); + + template + void item(::std::vector& v) { + size_t size = start_array(); + v.reserve(size); + for(size_t i = 0; i < size; i ++) { + T item; + this->item(item); + v.emplace_back( ::std::move(item) ); + } + end_array(); + } + template + void item(::std::shared_ptr& v) + { + bool present; + + item(present); + + if(present) { + v.reset(new T); + item(*v); + } + else { + v.reset(); + } + } + template + void item(::std::unique_ptr& v) + { + bool present; + + item(present); + + if(present) { + v.reset( T::from_deserialiser(*this).release() ); + } + else { + v.reset(); + } + } + template + void item(::std::pair& v) + { + if(2 != start_array()) + throw ::std::runtime_error("Invalid array size for pair"); + item(v.first); + item(v.second); + end_array(); + } + template + void item(::std::map& v) + { + size_t count = start_array(); + while(count--) { + ::std::pair e; + item(e); + v.insert( e ); + } + end_array(); + } +}; + #endif diff --git a/src/include/serialiser_texttree.hpp b/src/include/serialiser_texttree.hpp index ad88e155..4e8a9cf8 100644 --- a/src/include/serialiser_texttree.hpp +++ b/src/include/serialiser_texttree.hpp @@ -5,6 +5,7 @@ #define _SERIALISER_TEXTTREE_HPP_INCLUDED_ #include +#include #include "serialise.hpp" class Serialiser_TextTree: @@ -12,12 +13,13 @@ class Serialiser_TextTree: { ::std::ostream& m_os; int m_indent_level; + bool m_array_was_empty; 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; + virtual Serialiser& operator<<(uint64_t val) override; + virtual Serialiser& operator<<(const char* s) override; protected: virtual void start_object(const char *tag) override; @@ -30,5 +32,32 @@ private: void print_indent(); }; + +class Deserialiser_TextTree: + public Deserialiser +{ + ::std::istream& m_is; + + static bool is_ws(char c); + char getc(); + char peekc(); + void eat_ws(); +public: + Deserialiser_TextTree(::std::istream& is); + +protected: + virtual size_t start_array() override; + virtual void end_array() override; + virtual ::std::string read_tag() override; + +public: + virtual void item(bool& b) override; + virtual void item(uint64_t& v) override; + virtual void item(::std::string& s) override; + + virtual void start_object(const char *tag) override; + virtual void end_object(const char *tag) override; +}; + #endif diff --git a/src/main.cpp b/src/main.cpp index 55b6f9d4..9ba04dd7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,3 +1,5 @@ +/* + */ #include #include #include "parse/lex.hpp" diff --git a/src/serialise.cpp b/src/serialise.cpp index 65a2ea78..88b323f9 100644 --- a/src/serialise.cpp +++ b/src/serialise.cpp @@ -2,6 +2,7 @@ */ #include #include +#include "common.hpp" Serialiser& Serialiser::operator<<(const Serialisable& subobj) { @@ -11,16 +12,33 @@ Serialiser& Serialiser::operator<<(const Serialisable& subobj) return *this; } +void Deserialiser::item(Serialisable& s) +{ + DEBUG("Deserialise - '"<> len; + if( !m_is.good() ) + throw ::std::runtime_error("TODO: Less shit exception, start_array"); + DEBUG("len = "<> v; + if( !m_is.good() ) + throw ::std::runtime_error("TODO: Less shit exception, item(uint64_t)"); +} +void Deserialiser_TextTree::item(::std::string& s) +{ + eat_ws(); + + ::std::string rv; + char c = getc(); + DEBUG("c = '"<& v) case TypeRef::PATH: os << "TagPath, " << tr.m_path; break; + case TypeRef::ASSOCIATED: + os << "TagAssoc, <" << tr.m_inner_types[0] << " as " << tr.m_inner_types[1] << ">::" << tr.m_path[0].name(); + break; } os << ")"; return os; } +const char* coretype_name(const eCoreType ct ) { + switch(ct) + { + case CORETYPE_INVAL:return "-"; + case CORETYPE_ANY: return "_"; + case CORETYPE_CHAR: return "char"; + case CORETYPE_UINT: return "usize"; + case CORETYPE_INT: return "isize"; + case CORETYPE_U8: return "u8"; + case CORETYPE_I8: return "i8"; + case CORETYPE_U16: return "u16"; + case CORETYPE_I16: return "i16"; + case CORETYPE_U32: return "u32"; + case CORETYPE_I32: return "i32"; + case CORETYPE_U64: return "u64"; + case CORETYPE_I64: return "i64"; + case CORETYPE_F32: return "f16"; + case CORETYPE_F64: return "f16"; + } + return "NFI"; +} +void operator% (::Serialiser& s, eCoreType ct) { + s << coretype_name(ct); +} +void operator% (::Deserialiser& d, eCoreType& ct) { + ::std::string n; + d.item(n); + /* */if(n == "-") ct = CORETYPE_INVAL; + else if(n == "_") ct = CORETYPE_ANY; + else + throw ::std::runtime_error("Deserialise failure - " + n); +} +const char* TypeRef::class_name(TypeRef::Class c) { + switch(c) + { + #define _(x) case TypeRef::x: return #x; + _(ANY) + _(UNIT) + _(PRIMITIVE) + _(TUPLE) + _(REFERENCE) + _(POINTER) + _(ARRAY) + _(GENERIC) + _(PATH) + _(ASSOCIATED) + #undef _ + } + return "NFI"; +} +void operator>>(::Deserialiser& d, TypeRef::Class& c) { + ::std::string n; + d.item(n); + #define _(x) if(n == #x) c = TypeRef::x; + /**/ _(ANY) + else _(UNIT) + else _(PRIMITIVE) + else _(TUPLE) + else _(REFERENCE) + else _(POINTER) + else _(ARRAY) + else _(GENERIC) + else _(PATH) + else _(ASSOCIATED) + else + throw ::std::runtime_error("Deserialise failure - " + n); + #undef _ +} SERIALISE_TYPE(TypeRef::, "TypeRef", { - // TODO: TypeRef serialise + s << class_name(m_class); + s << coretype_name(m_core_type); + s << m_inner_types; + s << m_is_inner_mutable; + s << m_size_expr; + s << m_path; +},{ + s >> m_class; + s % m_core_type; + s.item( m_inner_types ); + s.item( m_is_inner_mutable ); + bool size_expr_present; + s.item(size_expr_present); + if( size_expr_present ) + m_size_expr = AST::ExprNode::from_deserialiser(s); + else + m_size_expr.reset(); + s.item( m_path ); }) diff --git a/src/types.hpp b/src/types.hpp index 1dfeebac..2d052a06 100644 --- a/src/types.hpp +++ b/src/types.hpp @@ -113,6 +113,9 @@ public: ::std::vector& sub_types() { return m_inner_types; } friend ::std::ostream& operator<<(::std::ostream& os, const TypeRef& tr); + + static const char* class_name(TypeRef::Class c); + friend void operator>>(::Deserialiser& d, TypeRef::Class& c); SERIALISABLE_PROTOTYPES(); }; -- cgit v1.2.3