diff options
| -rw-r--r-- | src/ast/ast.cpp | 158 | ||||
| -rw-r--r-- | src/ast/ast.hpp | 27 | ||||
| -rw-r--r-- | src/ast/expr.cpp | 124 | ||||
| -rw-r--r-- | src/ast/expr.hpp | 49 | ||||
| -rw-r--r-- | src/ast/path.cpp | 15 | ||||
| -rw-r--r-- | src/ast/path.hpp | 2 | ||||
| -rw-r--r-- | src/ast/pattern.hpp | 5 | ||||
| -rw-r--r-- | src/coretypes.hpp | 7 | ||||
| -rw-r--r-- | src/include/serialise.hpp | 122 | ||||
| -rw-r--r-- | src/include/serialiser_texttree.hpp | 33 | ||||
| -rw-r--r-- | src/main.cpp | 2 | ||||
| -rw-r--r-- | src/serialise.cpp | 186 | ||||
| -rw-r--r-- | src/types.cpp | 90 | ||||
| -rw-r--r-- | 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 <iostream>
  #include "../parse/parseerror.hpp"
  #include <algorithm>
 +#include <serialiser_texttree.hpp>
  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<TypeRef>  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 <typename T>
 @@ -87,6 +95,7 @@ class MetaItem:      ::std::vector<MetaItem> 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<TypeRef>   m_types;
      ItemList<Function>  m_functions;
  public:
 +    Trait() {}
      Trait(TypeParams params):
          m_params(params)
      {
 @@ -213,6 +230,7 @@ class Enum:      ::std::vector<TypeParam>    m_params;
      ::std::vector<StructItem>   m_variants;
  public:
 +    Enum() {}
      Enum( ::std::vector<TypeParam> params, ::std::vector<StructItem> variants ):
          m_params( move(params) ),
          m_variants( move(variants) )
 @@ -230,6 +248,7 @@ class Struct:      ::std::vector<TypeParam>    m_params;
      ::std::vector<StructItem>   m_fields;
  public:
 +    Struct() {}
      Struct( ::std::vector<TypeParam> params, ::std::vector<StructItem> fields ):
          m_params( move(params) ),
          m_fields( move(fields) )
 @@ -250,6 +269,7 @@ class Impl:      ::std::vector<Item<Function> >  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<Impl> 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> 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<ExprNode>(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<ExprNode> from_deserialiser(Deserialiser& d);  };  struct ExprNode_Block: @@ -30,7 +33,7 @@ struct ExprNode_Block:  {      ::std::vector< ::std::unique_ptr<ExprNode> >    m_nodes; -    ExprNode_Block(const ExprNode_Block& x) = delete; +    ExprNode_Block() {}      ExprNode_Block(::std::vector< ::std::unique_ptr<ExprNode> >&& 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<ExprNode> 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<TypeRef>& 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<TypeRef>  m_params;  public: +    PathNode() {}      PathNode(::std::string name, ::std::vector<TypeRef> args = {});      const ::std::string& name() const;      ::std::vector<TypeRef>&   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<TypeRef>& 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<Pattern>& 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 <vector>  #include <string>  #include <map> +#include <memory>  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<typename T> +    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<typename T> @@ -45,6 +57,22 @@ public:          end_array();          return *this;      } +    template<typename T> +    Serialiser& operator<<(const ::std::shared_ptr<T>& v) +    { +        *this << v.get(); +        if(v.get()) +            *this << *v; +        return *this; +    } +    template<typename T> +    Serialiser& operator<<(const ::std::unique_ptr<T>& v) +    { +        *this << v.get(); +        if(v.get()) +            *this << *v; +        return *this; +    }      template<typename T1, typename T2>      Serialiser& operator<<(const ::std::pair<T1,T2>& v)      { @@ -57,13 +85,93 @@ public:      template<typename T1, typename T2>      Serialiser& operator<<(const ::std::map<T1,T2>& 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<typename T> +    void item(::std::vector<T>& 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<typename T> +    void item(::std::shared_ptr<T>& v) +    { +        bool present; +         +        item(present); +         +        if(present) { +            v.reset(new T); +            item(*v); +        } +        else { +            v.reset(); +        } +    } +    template<typename T> +    void item(::std::unique_ptr<T>& v) +    { +        bool present; +         +        item(present); +         +        if(present) { +            v.reset( T::from_deserialiser(*this).release() ); +        } +        else { +            v.reset(); +        } +    } +    template<typename T1, typename T2> +    void item(::std::pair<T1,T2>& v) +    { +        if(2 != start_array()) +            throw ::std::runtime_error("Invalid array size for pair"); +        item(v.first); +        item(v.second); +        end_array(); +    } +    template<typename T1, typename T2> +    void item(::std::map<T1,T2>& v) +    { +        size_t count = start_array(); +        while(count--) { +            ::std::pair<T1,T2>  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 <ostream> +#include <istream>  #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 <iostream>
  #include <string>
  #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 <serialise.hpp>  #include <serialiser_texttree.hpp> +#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 - '"<<s.serialise_tag()<<"'"); +    start_object(s.serialise_tag()); +    s.deserialise(*this); +    end_object(s.serialise_tag()); +} +::std::string Deserialiser::start_object() +{ +    ::std::string s = read_tag(); +    DEBUG("tag = '" << s << "'"); +    start_object(nullptr); +    return s; +} + +// --------------------------------------------------------------------  Serialiser_TextTree::Serialiser_TextTree(::std::ostream& os):      m_os(os), -    m_indent_level(0) +    m_indent_level(0), +    m_array_was_empty(false)  {  }  void Serialiser_TextTree::start_object(const char *tag) {      print_indent(); -    m_os << tag << "{\n"; +    m_os << tag << " {\n";      indent();  }  void Serialiser_TextTree::end_object(const char *_tag) { @@ -30,31 +48,39 @@ void Serialiser_TextTree::end_object(const char *_tag) {  }  void Serialiser_TextTree::start_array(unsigned int size) {      print_indent(); -    if( size == 0 ) -        m_os << "["; -    else -        m_os << "[\n"; -    indent(); +    if( size == 0 ) { +        m_os << "[]\n"; +        m_array_was_empty = true; +    } +    else { +        m_os << "[" << size << "\n"; +        indent(); +    }  }  void Serialiser_TextTree::end_array() { -    unindent(); -    print_indent(); -    m_os << "]\n"; +    if( m_array_was_empty ) { +        m_array_was_empty = false; +    } +    else { +        unindent(); +        print_indent(); +        m_os << "]\n"; +    }  }  Serialiser& Serialiser_TextTree::operator<<(bool val)  {      print_indent(); -    m_os << (val ? "true" : "false") << "\n"; +    m_os << (val ? "T" : "F") << "\n";      return *this;  } -Serialiser& Serialiser_TextTree::operator<<(unsigned int val) +Serialiser& Serialiser_TextTree::operator<<(uint64_t val)  {      print_indent();      m_os << val << "\n";      return *this;  } -Serialiser& Serialiser_TextTree::operator<<(const ::std::string& s) +Serialiser& Serialiser_TextTree::operator<<(const char* s)  {      print_indent();      m_os << "\"" << s << "\"\n"; @@ -74,4 +100,138 @@ void Serialiser_TextTree::print_indent()          m_os << " ";  } +// -------------------------------------------------------------------- +Deserialiser_TextTree::Deserialiser_TextTree(::std::istream& is): +    m_is(is) +{ +} +bool Deserialiser_TextTree::is_ws(char c) +{ +    return c == ' ' || c == '\t' || c == '\n' || c == '\r'; +} +char Deserialiser_TextTree::getc() +{ +    char c; +    m_is.get(c); +    return c; +} +char Deserialiser_TextTree::peekc() +{ +    return m_is.peek(); +} +void Deserialiser_TextTree::eat_ws() +{ +    char c; +    do { +        m_is.get(c); +    } while( is_ws(c) ); +    m_is.putback(c); +} +size_t Deserialiser_TextTree::start_array() +{ +    eat_ws(); +    char c = getc(); +    if( c != '[' ) +        throw ::std::runtime_error("TODO: Less shit exception, start_array"); +     +    eat_ws(); +    if( peekc() == ']' ) { +        DEBUG("len = 0"); +        return 0; +    } +     +    size_t len; +    m_is >> len; +    if( !m_is.good() ) +        throw ::std::runtime_error("TODO: Less shit exception, start_array"); +    DEBUG("len = "<<len); +    return len; +} +void Deserialiser_TextTree::end_array() +{ +    eat_ws(); +    char c = getc(); +    DEBUG("c = '"<<c<<"'"); +    if( c != ']' ) +        throw ::std::runtime_error("TODO: Less shit exception, end_array"); +} +::std::string Deserialiser_TextTree::read_tag() +{ +    ::std::string   tag; +    eat_ws(); +    char c; +    do { +        m_is.get(c); +        tag.push_back(c); +    } while( !is_ws(c) ); +    tag.pop_back(); +    if( tag.size() == 0 ) +        throw ::std::runtime_error("TODO: Less shit exception, read_tag"); +    return tag; +} +void Deserialiser_TextTree::item(bool& b) +{ +    eat_ws(); +    switch( getc() ) +    { +    case 'T': DEBUG("true");   b = true;   break; +    case 'F': DEBUG("false");  b = false;  break; +    default: +        throw ::std::runtime_error("TODO: Less shit exception, item(bool)"); +    } +} +void Deserialiser_TextTree::item(uint64_t& v) +{ +    eat_ws(); +    m_is >> 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 = '"<<c<<"'"); +    if( c != '"' ) +        throw ::std::runtime_error("TODO: Less shit exception, item(::std::string)"); +     +    while(peekc() != '"') +    { +        char c = getc(); +        if( c == '\\' ) +            c = getc(); +        rv.push_back(c); +    } +    getc(); // eat " +     +    DEBUG("rv = '"<<rv<<"'"); +    s = rv; +} + +void Deserialiser_TextTree::start_object(const char *tag) +{ +    eat_ws(); +    if( tag != nullptr ) { +        ::std::string s = read_tag(); +        DEBUG("s == " << s); +        if( s != tag ) +            throw ::std::runtime_error("TODO: Less shit exception, start_object"); +    } +    eat_ws(); +    char c = getc(); +    DEBUG("c = '" << c << "' (tag = " << (tag ? tag : "-NUL-")); +    if( c != '{' ) +        throw ::std::runtime_error("TODO: Less shit exception, start_object"); +} +void Deserialiser_TextTree::end_object(const char *tag) +{ +    eat_ws(); +    char c = getc(); +    DEBUG("c = '"<<c<<"'"); +    if( c != '}' ) { +        throw ::std::runtime_error("TODO: Less shit exception, end_object"); +    } +} diff --git a/src/types.cpp b/src/types.cpp index eece7d5b..7a2b21c6 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -51,11 +51,99 @@ inline ::std::ostream& operator<<(::std::ostream& os, const ::std::vector<T>& 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<TypeRef>& 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(); 
  };
 | 
