From 801bce6026e86d32b6971463a3aefd38eb3b2f27 Mon Sep 17 00:00:00 2001 From: "John Hodge (sonata)" Date: Thu, 15 Jan 2015 00:07:26 +0800 Subject: Type aliases added (AST only, no parse yet), need to handle lookups --- src/ast/ast.cpp | 31 ++++++++++++++++++++++++++++++- src/ast/ast.hpp | 24 ++++++++++++++++++++++++ src/ast/path.cpp | 15 +++++++++++++++ src/ast/path.hpp | 8 +++++++- src/types.hpp | 6 ++++++ 5 files changed, 82 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index 48cbdb9d..0c33dcb9 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -103,7 +103,8 @@ ExternCrate ExternCrate_std() Module& std_mod = crate.root_module(); - // TODO: Add modules + // === Add modules === + // - option Module option(crate.crate(), "option"); option.add_enum(true, "Option", Enum( { @@ -115,6 +116,29 @@ ExternCrate ExternCrate_std() } )); std_mod.add_submod(true, ::std::move(option)); + // - io + Module io(crate.crate(), "io"); + io.add_typealias(true, "IoResult", TypeAlias( + { TypeParam(false, "T") }, + TypeRef( Path("std", { + PathNode("result",{}), + PathNode("Result", {TypeRef("T"),TypeRef(Path("std", {PathNode("io"), PathNode("IoError")}))}) + }) ) + )); + std_mod.add_submod(true, ::std::move(io)); + // - result + Module result(crate.crate(), "result"); + result.add_enum(true, "Result", Enum( + { + TypeParam(false, "R"), + TypeParam(false, "E"), + }, + { + StructItem("Ok", TypeRef(TypeRef::TagArg(), "R")), + StructItem("Err", TypeRef(TypeRef::TagArg(), "E")), + } + )); + std_mod.add_submod(true, ::std::move(result)); Module prelude(crate.crate(), "prelude"); // Re-exports @@ -151,6 +175,11 @@ void Module::iterate_functions(fcn_visitor_t *visitor, const Crate& crate) } } +SERIALISE_TYPE(TypeAlias::, "AST_TypeAlias", { + s << m_params; + s << m_type; +}) + ::Serialiser& operator<<(::Serialiser& s, Static::Class fc) { switch(fc) diff --git a/src/ast/ast.hpp b/src/ast/ast.hpp index fe07ae7d..77eb4fe3 100644 --- a/src/ast/ast.hpp +++ b/src/ast/ast.hpp @@ -78,6 +78,23 @@ public: SERIALISABLE_PROTOTYPES(); }; +class TypeAlias: + public Serialisable +{ + TypeParams m_params; + TypeRef m_type; +public: + TypeAlias(TypeParams params, TypeRef type): + m_params( move(params) ), + m_type( move(type) ) + {} + + const TypeParams& params() const { return m_params; } + const TypeRef& type() const { return m_type; } + + SERIALISABLE_PROTOTYPES(); +}; + class Static: public Serialisable { @@ -256,8 +273,10 @@ class Module: itemlist_fcn_t m_functions; itemlist_mod_t m_submods; itemlist_use_t m_imports; + ::std::vector > m_type_aliases; itemlist_ext_t m_extern_crates; + itemlist_static_t m_statics; itemlist_enum_t m_enums; itemlist_struct_t m_structs; @@ -272,6 +291,9 @@ public: void add_alias(bool is_public, Path path, ::std::string name) { m_imports.push_back( Item( move(name), move(path), is_public) ); } + void add_typealias(bool is_public, ::std::string name, TypeAlias alias) { + m_type_aliases.push_back( Item( move(name), move(alias), is_public ) ); + } void add_constant(bool is_public, ::std::string name, TypeRef type, Expr val) { m_statics.push_back( Item( move(name), Static(Static::CONST, move(type), move(val)), is_public) ); } @@ -309,6 +331,7 @@ public: itemlist_fcn_t& functions() { return m_functions; } itemlist_mod_t& submods() { return m_submods; } itemlist_use_t& imports() { return m_imports; } + ::std::vector >& type_aliases() { return m_type_aliases; } itemlist_ext_t& extern_crates() { return m_extern_crates; } ::std::vector& impls() { return m_impls; } @@ -316,6 +339,7 @@ public: const itemlist_fcn_t& functions() const { return m_functions; } const itemlist_mod_t& submods() const { return m_submods; } const itemlist_use_t& imports() const { return m_imports; } + const ::std::vector >& type_aliases() const { return m_type_aliases; } const itemlist_ext_t& extern_crates() const { return m_extern_crates; } const itemlist_static_t& statics() const { return m_statics; } const itemlist_enum_t& enums () const { return m_enums; } diff --git a/src/ast/path.cpp b/src/ast/path.cpp index 0bce09c1..e6700696 100644 --- a/src/ast/path.cpp +++ b/src/ast/path.cpp @@ -92,6 +92,21 @@ void Path::resolve(const Crate& root_crate) throw ParseError::Todo("Path::resolve() re-export"); } } + // Type Aliases + { + auto& items = mod->type_aliases(); + auto it = find_named(items, node.name()); + if( it != items.end() ) + { + DEBUG("Type alias <"<data.params()<<"> " << it->data.type()); + if( node.args().size() != it->data.params().size() ) + throw ParseError::Generic("Param count mismatch when referencing type alias"); + // Make a copy of the path, replace params with it, then replace *this? + // - Maybe leave that up to other code? + throw ParseError::Todo("Path::resolve() type alias"); + } + } + // - Functions { auto& items = mod->functions(); diff --git a/src/ast/path.hpp b/src/ast/path.hpp index f39e133d..c6baf607 100644 --- a/src/ast/path.hpp +++ b/src/ast/path.hpp @@ -29,7 +29,7 @@ class PathNode: ::std::string m_name; ::std::vector m_params; public: - PathNode(::std::string name, ::std::vector args); + PathNode(::std::string name, ::std::vector args = {}); const ::std::string& name() const; ::std::vector& args() { return m_params; } const ::std::vector& args() const; @@ -109,6 +109,11 @@ public: m_class(ABSOLUTE), m_nodes(l) {} + Path(::std::string crate, ::std::vector nodes): + m_crate( ::std::move(crate) ), + m_class(ABSOLUTE), + m_nodes( ::std::move(nodes) ) + {} void set_crate(::std::string crate) { if( m_crate == "" ) { @@ -119,6 +124,7 @@ public: static Path add_tailing(const Path& a, const Path& b) { Path ret(a); + ret[ret.size()-1].args() = b[0].args(); for(unsigned int i = 1; i < b.m_nodes.size(); i ++) ret.m_nodes.push_back(b.m_nodes[i]); return ret; diff --git a/src/types.hpp b/src/types.hpp index 512519f8..4ef24685 100644 --- a/src/types.hpp +++ b/src/types.hpp @@ -84,12 +84,18 @@ public: m_class(GENERIC), m_path({AST::PathNode(name, {})}) {} + TypeRef(::std::string name): + TypeRef(TagArg(), ::std::move(name)) + {} struct TagPath {}; TypeRef(TagPath, AST::Path path): m_class(PATH), m_path( ::std::move(path) ) {} + TypeRef(AST::Path path): + TypeRef(TagPath(), ::std::move(path)) + {} bool is_path() const { return m_class == PATH; } AST::Path& path() { assert(is_path()); return m_path; } -- cgit v1.2.3