summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ast/ast.cpp158
-rw-r--r--src/ast/ast.hpp27
-rw-r--r--src/ast/expr.cpp124
-rw-r--r--src/ast/expr.hpp49
-rw-r--r--src/ast/path.cpp15
-rw-r--r--src/ast/path.hpp2
-rw-r--r--src/ast/pattern.hpp5
-rw-r--r--src/coretypes.hpp7
-rw-r--r--src/include/serialise.hpp122
-rw-r--r--src/include/serialiser_texttree.hpp33
-rw-r--r--src/main.cpp2
-rw-r--r--src/serialise.cpp186
-rw-r--r--src/types.cpp90
-rw-r--r--src/types.hpp3
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();
};