diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ast/ast.cpp | 194 | ||||
-rw-r--r-- | src/ast/ast.hpp | 77 | ||||
-rw-r--r-- | src/ast/path.hpp | 73 | ||||
-rw-r--r-- | src/convert/render.cpp | 10 | ||||
-rw-r--r-- | src/convert/resolve.cpp | 59 | ||||
-rw-r--r-- | src/parse/root.cpp | 22 | ||||
-rw-r--r-- | src/types.hpp | 3 |
7 files changed, 371 insertions, 67 deletions
diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index fe6f2add..893810ec 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -25,33 +25,173 @@ const ::std::vector<TypeRef>& PathNode::args() const }
// --- AST::Path
-void Path::resolve(const Crate& crate)
+template<typename T>
+typename ::std::vector<Item<T> >::const_iterator find_named(const ::std::vector<Item<T> >& vec, const ::std::string& name)
+{
+ return ::std::find_if(vec.begin(), vec.end(), [&name](const Item<T>& x) {
+ return x.name == name;
+ });
+}
+
+void Path::resolve()
{
DEBUG("*this = " << *this);
if(m_class != ABSOLUTE)
throw ParseError::BugCheck("Calling Path::resolve on non-absolute path");
+ if(m_crate == nullptr)
+ throw ParseError::BugCheck("Calling Path::resolve on path with no crate");
- const Module* mod = &crate.root_module();
- for(int i = 0; i < m_nodes.size(); i ++ )
+ const Module* mod = &m_crate->root_module();
+ for(unsigned int i = 0; i < m_nodes.size(); i ++ )
{
+ const bool is_last = (i+1 == m_nodes.size());
+ const bool is_sec_last = (i+2 == m_nodes.size());
const PathNode& node = m_nodes[i];
- auto& sms = mod->submods();
+ DEBUG("node = " << node);
- auto it = ::std::find_if(sms.begin(), sms.end(), [&node](const ::std::pair<Module,bool>& x) {
- return x.first.name() == node.name();
- });
- if( it != sms.end() )
- continue;
+ // Sub-modules
+ {
+ auto& sms = mod->submods();
+ auto it = ::std::find_if(sms.begin(), sms.end(), [&node](const ::std::pair<Module,bool>& x) {
+ return x.first.name() == node.name();
+ });
+ if( it != sms.end() )
+ {
+ DEBUG("Sub-module '" << node.name() << "'");
+ if( node.args().size() )
+ throw ParseError::Generic("Generic params applied to module");
+ mod = &it->first;
+ continue;
+ }
+ }
+ // External crates
+ {
+ auto& crates = mod->extern_crates();
+ auto it = find_named(crates, node.name());
+ if( it != crates.end() )
+ {
+ DEBUG("Extern crate '" << node.name() << "'");
+ if( node.args().size() )
+ throw ParseError::Generic("Generic params applied to extern crate");
+ mod = &it->data.root_module();
+ continue;
+ }
+ }
// Start searching for:
// - Re-exports
+ {
+ auto& imp = mod->imports();
+ auto it = find_named(imp, node.name());
+ if( it != imp.end() )
+ {
+ DEBUG("Re-exported path " << it->data);
+ throw ParseError::Todo("Path::resolve() re-export");
+ }
+ }
// - Functions
+ {
+ auto& items = mod->functions();
+ auto it = find_named(items, node.name());
+ if( it != items.end() )
+ {
+ DEBUG("Found function");
+ if( is_last ) {
+ throw ParseError::Todo("Path::resolve() bind to function");
+ }
+ else {
+ throw ParseError::Generic("Import of function, too many extra nodes");
+ }
+ }
+ }
// - Structs
+ {
+ auto& items = mod->structs();
+ auto it = find_named(items, node.name());
+ if( it != items.end() )
+ {
+ DEBUG("Found struct");
+ if( is_last ) {
+ bind_struct(it->data, node.args());
+ return;
+ }
+ else if( is_sec_last ) {
+ throw ParseError::Todo("Path::resolve() struct method");
+ }
+ else {
+ throw ParseError::Generic("Import of struct, too many extra nodes");
+ }
+ }
+ }
// - Enums (and variants)
+ {
+ auto& enums = mod->enums();
+ auto it = find_named(enums, node.name());
+ if( it != enums.end() )
+ {
+ DEBUG("Found enum");
+ if( is_last ) {
+ bind_enum(it->data, node.args());
+ return ;
+ }
+ else if( is_sec_last ) {
+ bind_enum_var(it->data, m_nodes[i+1].name(), node.args());
+ return ;
+ }
+ else {
+ throw ParseError::Generic("Import of enum, too many extra nodes");
+ }
+ }
+ }
+ // - Constants / statics
+ throw ParseError::Generic("Unable to find component '" + node.name() + "'");
+ }
+
+ // We only reach here if the path points to a module
+ bind_module(*mod);
+}
+void Path::bind_module(const Module& mod)
+{
+ m_binding_type = MODULE;
+ m_binding.module_ = &mod;
+}
+void Path::bind_enum(const Enum& ent, const ::std::vector<TypeRef>& args)
+{
+ m_binding_type = ENUM;
+ m_binding.enum_ = &ent;
+ if( args.size() > 0 )
+ {
+ if( args.size() != ent.params().size() )
+ throw ParseError::Generic("Parameter count mismatch");
+ throw ParseError::Todo("Bind enum with params passed");
+ }
+}
+void Path::bind_enum_var(const Enum& ent, const ::std::string& name, const ::std::vector<TypeRef>& args)
+{
+ unsigned int idx = 0;
+ for( idx = 0; idx < ent.variants().size(); idx ++ )
+ {
+ if( ent.variants()[idx].first == name ) {
+ break;
+ }
}
+ if( idx == ent.variants().size() )
+ throw ParseError::Generic("Enum variant not found");
- throw ParseError::Todo("Path::resolve");
+ if( args.size() > 0 )
+ {
+ if( args.size() != ent.params().size() )
+ throw ParseError::Generic("Parameter count mismatch");
+ throw ParseError::Todo("Bind enum variant with params passed");
+ }
+
+ m_binding_type = ENUM_VAR;
+ m_binding.enumvar = {&ent, idx};
+}
+void Path::bind_struct(const Struct& ent, const ::std::vector<TypeRef>& args)
+{
+ throw ParseError::Todo("Path::resolve() bind to struct type");
}
Path& Path::operator+=(const Path& other)
@@ -106,7 +246,7 @@ Path& Path::operator+=(const Path& other) Impl::Impl(TypeRef impl_type, TypeRef trait_type)
{
}
-void Impl::add_function(bool is_public, Function fcn)
+void Impl::add_function(bool is_public, ::std::string name, Function fcn)
{
}
@@ -132,9 +272,29 @@ ExternCrate::ExternCrate(const char *path) ExternCrate ExternCrate_std()
{
ExternCrate crate;
+
Module& std_mod = crate.root_module();
// TODO: Add modules
+ Module option(crate.crate(), "option");
+ option.add_enum(true, "Option", Enum(
+ {
+ TypeParam(false, "T"),
+ },
+ {
+ StructItem("None", TypeRef()),
+ StructItem("Some", TypeRef(TypeRef::TagArg(), "T")),
+ }
+ ));
+ std_mod.add_submod(true, ::std::move(option));
+
+ Module prelude(crate.crate(), "prelude");
+ // Re-exports
+ #define USE(mod, name, ...) do{ Path p({__VA_ARGS__}); p.set_crate(crate.crate()); p.resolve(); mod.add_alias(true, ::std::move(p), name); } while(0)
+ USE(prelude, "Option", PathNode("option", {}), PathNode("Option",{}) );
+ USE(prelude, "Some", PathNode("option", {}), PathNode("Option",{}), PathNode("Some",{}) );
+ USE(prelude, "None", PathNode("option", {}), PathNode("Option",{}), PathNode("None",{}) );
+ std_mod.add_submod(true, prelude);
return crate;
}
@@ -163,16 +323,6 @@ void Module::add_global(bool is_public, bool is_mut, ::std::string name, TypeRef void Module::add_struct(bool is_public, ::std::string name, TypeParams params, ::std::vector<StructItem> items)
{
}
-void Module::add_function(bool is_public, Function func)
-{
- for( const auto fcn_item : m_functions )
- {
- if( fcn_item.first.name() == func.name() ) {
- throw ParseError::Todo("duplicate function definition");
- }
- }
- m_functions.push_back( ::std::make_pair(func, is_public) );
-}
void Module::add_impl(Impl impl)
{
}
@@ -181,7 +331,7 @@ void Module::iterate_functions(fcn_visitor_t *visitor, const Crate& crate) {
for( auto fcn_item : this->m_functions )
{
- visitor(crate, *this, fcn_item.first);
+ visitor(crate, *this, fcn_item.data);
}
}
diff --git a/src/ast/ast.hpp b/src/ast/ast.hpp index 25876310..c02840c6 100644 --- a/src/ast/ast.hpp +++ b/src/ast/ast.hpp @@ -15,6 +15,16 @@ namespace AST { using ::std::unique_ptr;
using ::std::move;
+class TypeParam
+{
+public:
+ TypeParam(bool is_lifetime, ::std::string name);
+ void addLifetimeBound(::std::string name);
+ void addTypeBound(TypeRef type);
+};
+
+typedef ::std::vector<TypeParam> TypeParams;
+
class Crate;
class MetaItem
@@ -128,6 +138,8 @@ public: friend ::std::ostream& operator<<(::std::ostream& os, const Expr& pat);
};
+typedef ::std::pair< ::std::string, TypeRef> StructItem;
+
class Function
{
public:
@@ -141,15 +153,13 @@ public: typedef ::std::vector<StructItem> Arglist;
private:
- ::std::string m_name;
TypeParams m_generic_params;
Class m_fcn_class;
Expr m_code;
TypeRef m_rettype;
Arglist m_args;
public:
- Function(::std::string name, TypeParams params, Class fcn_class, TypeRef ret_type, Arglist args, Expr code):
- m_name(name),
+ Function(TypeParams params, Class fcn_class, TypeRef ret_type, Arglist args, Expr code):
m_generic_params(params),
m_fcn_class(fcn_class),
m_code(code),
@@ -158,8 +168,6 @@ public: {
}
- const ::std::string& name() const { return m_name; }
-
TypeParams& generic_params() { return m_generic_params; }
const TypeParams& generic_params() const { return m_generic_params; }
@@ -173,12 +181,39 @@ public: Arglist& args() { return m_args; }
};
+class Enum
+{
+ ::std::vector<TypeParam> m_params;
+ ::std::vector<StructItem> m_variants;
+public:
+ Enum( ::std::vector<TypeParam> params, ::std::vector<StructItem> variants ):
+ m_params( move(params) ),
+ m_variants( move(variants) )
+ {}
+
+ const ::std::vector<TypeParam> params() const { return m_params; }
+ const ::std::vector<StructItem> variants() const { return m_variants; }
+};
+
+class Struct
+{
+ ::std::vector<TypeParam> m_params;
+ ::std::vector<StructItem> m_fields;
+public:
+ Struct( ::std::vector<TypeParam> params, ::std::vector<StructItem> fields ):
+ m_params( move(params) ),
+ m_fields( move(fields) )
+ {}
+
+ const ::std::vector<StructItem> fields() const { return m_fields; }
+};
+
class Impl
{
public:
Impl(TypeRef impl_type, TypeRef trait_type);
- void add_function(bool is_public, Function fcn);
+ void add_function(bool is_public, ::std::string name, Function fcn);
};
@@ -206,20 +241,25 @@ struct Item /// Representation of a parsed (and being converted) function
class Module
{
- typedef ::std::vector< ::std::pair<Function, bool> > itemlist_fcn_t;
+ typedef ::std::vector< Item<Function> > itemlist_fcn_t;
typedef ::std::vector< ::std::pair<Module, bool> > itemlist_mod_t;
typedef ::std::vector< Item<Path> > itemlist_use_t;
typedef ::std::vector< Item<ExternCrate> > itemlist_ext_t;
+ typedef ::std::vector< Item<Enum> > itemlist_enum_t;
+ typedef ::std::vector< Item<Struct> > itemlist_struct_t;
- const Crate& m_crate;
+ Crate& m_crate;
::std::string m_name;
::std::vector<MetaItem> m_attrs;
itemlist_fcn_t m_functions;
itemlist_mod_t m_submods;
itemlist_use_t m_imports;
itemlist_ext_t m_extern_crates;
+
+ itemlist_enum_t m_enums;
+ itemlist_struct_t m_structs;
public:
- Module(const Crate& crate, ::std::string name):
+ Module(Crate& crate, ::std::string name):
m_crate(crate),
m_name(name)
{
@@ -231,7 +271,15 @@ public: void add_constant(bool is_public, ::std::string name, TypeRef type, Expr val);
void add_global(bool is_public, bool is_mut, ::std::string name, TypeRef type, Expr val);
void add_struct(bool is_public, ::std::string name, TypeParams params, ::std::vector<StructItem> items);
- void add_function(bool is_public, Function func);
+ void add_enum(bool is_public, ::std::string name, Enum inst) {
+ m_enums.push_back( Item<Enum>( move(name), move(inst), is_public ) );
+ }
+ void add_function(bool is_public, ::std::string name, Function func) {
+ m_functions.push_back( Item<Function>( move(name), move(func), is_public ) );
+ }
+ void add_submod(bool is_public, Module mod) {
+ m_submods.push_back( ::std::make_pair( move(mod), is_public ) );
+ }
void add_impl(Impl impl);
void add_attr(MetaItem item) {
@@ -240,6 +288,7 @@ public: void iterate_functions(fcn_visitor_t* visitor, const Crate& crate);
+ Crate& crate() { return m_crate; }
const Crate& crate() const { return m_crate; }
const ::std::string& name() const { return m_name; }
@@ -255,6 +304,8 @@ public: const itemlist_mod_t& submods() const { return m_submods; }
const itemlist_use_t& imports() const { return m_imports; }
const itemlist_ext_t& extern_crates() const { return m_extern_crates; }
+ const itemlist_enum_t& enums() const { return m_enums; }
+ const itemlist_struct_t& structs() const { return m_structs; }
};
class Crate
@@ -279,6 +330,8 @@ class ExternCrate public:
ExternCrate();
ExternCrate(const char *path);
+ Crate& crate() { return m_crate; }
+ const Crate& crate() const { return m_crate; }
Module& root_module() { return m_crate.root_module(); }
const Module& root_module() const { return m_crate.root_module(); }
};
@@ -295,10 +348,10 @@ public: class Flat
{
::std::vector<CStruct> m_structs;
- ::std::vector<Function> m_functions;
+ ::std::vector< ::std::pair< ::std::string,Function> > m_functions;
public:
- const ::std::vector<Function>& functions() const { return m_functions; }
+ const ::std::vector< ::std::pair<::std::string, Function> >& functions() const { return m_functions; }
const ::std::vector<CStruct>& structs() const { return m_structs; }
};
diff --git a/src/ast/path.hpp b/src/ast/path.hpp index 05439e06..f990dedb 100644 --- a/src/ast/path.hpp +++ b/src/ast/path.hpp @@ -6,23 +6,20 @@ #include "../common.hpp" #include <string> #include <stdexcept> +#include <vector> +#include <initializer_list> +#include <cassert> class TypeRef; namespace AST { class Crate; +class Module; +class Enum; +class Struct; +class Function; -class TypeParam -{ -public: - TypeParam(bool is_lifetime, ::std::string name); - void addLifetimeBound(::std::string name); - void addTypeBound(TypeRef type); -}; - -typedef ::std::vector<TypeParam> TypeParams; -typedef ::std::pair< ::std::string, TypeRef> StructItem; class PathNode { @@ -48,31 +45,71 @@ public: class Path { +public: + enum BindingType { + UNBOUND, + MODULE, + ENUM, + ENUM_VAR, + }; +private: enum Class { RELATIVE, ABSOLUTE, LOCAL, }; + + /// The crate defining the root of this path (used for path resolution) + const Crate* m_crate; + + /// Path class (absolute, relative, local) + /// - Absolute is "relative" to the crate root + /// - Relative doesn't have a set crate (and can't be resolved) + /// - Local is a special case to handle possible use of local varaibles Class m_class; ::std::vector<PathNode> m_nodes; + + BindingType m_binding_type = UNBOUND; + union { + const Module* module_; + const Enum* enum_; + struct { + const Enum* enum_; + unsigned int idx; + } enumvar; + } m_binding; public: Path(): + m_crate(nullptr), m_class(RELATIVE) {} struct TagAbsolute {}; Path(TagAbsolute): + m_crate(nullptr), m_class(ABSOLUTE) {} struct TagLocal {}; Path(TagLocal, ::std::string name): + m_crate(nullptr), m_class(LOCAL), m_nodes({PathNode(name, {})}) {} + Path(::std::initializer_list<PathNode> l): + m_crate(nullptr), + m_class(ABSOLUTE), + m_nodes(l) + {} + + void set_crate(const Crate& crate) { + if( !m_crate ) + m_crate = &crate; + } + static Path add_tailing(const Path& a, const Path& b) { Path ret(a); - for(const auto& ent : b.m_nodes) - ret.m_nodes.push_back(ent); + for(unsigned int i = 1; i < b.m_nodes.size(); i ++) + ret.m_nodes.push_back(b.m_nodes[i]); return ret; } Path operator+(PathNode&& pn) const { @@ -94,10 +131,15 @@ public: m_nodes.push_back(node); } - void resolve(const Crate& crate); + void resolve(); bool is_relative() const { return m_class == RELATIVE; } size_t size() const { return m_nodes.size(); } + + bool is_bound() const { return m_binding_type != UNBOUND; } + BindingType binding_type() const { return m_binding_type; } + const Module& bound_module() const { assert(m_binding_type == MODULE); return *m_binding.module_; } + ::std::vector<PathNode>& nodes() { return m_nodes; } const ::std::vector<PathNode>& nodes() const { return m_nodes; } @@ -105,6 +147,11 @@ public: const PathNode& operator[](size_t idx) const { return m_nodes[idx]; } friend ::std::ostream& operator<<(::std::ostream& os, const Path& path); +private: + void bind_module(const Module& mod); + void bind_enum(const Enum& ent, const ::std::vector<TypeRef>& args); + void bind_enum_var(const Enum& ent, const ::std::string& name, const ::std::vector<TypeRef>& args); + void bind_struct(const Struct& ent, const ::std::vector<TypeRef>& args); }; } // namespace AST diff --git a/src/convert/render.cpp b/src/convert/render.cpp index 7f65945a..bcc0ef68 100644 --- a/src/convert/render.cpp +++ b/src/convert/render.cpp @@ -36,12 +36,14 @@ void Render_Crate(::std::ostream& os, const AST::Flat& crate) FOREACH(::std::vector<AST::CStruct>, s, crate.structs())
os << "struct " << s->mangled_name() << ";\n";
- FOREACH(::std::vector<AST::Function>, fcn, crate.functions())
+ for(const auto& item : crate.functions())
{
- Render_Type(os, fcn->rettype(), nullptr);
- os << " " << fcn->name() << "(";
+ const auto& name = item.first;
+ const auto& fcn = item.second;
+ Render_Type(os, fcn.rettype(), nullptr);
+ os << " " << name << "(";
bool is_first = true;
- FOREACH(item_vec_t, f, fcn->args())
+ FOREACH(item_vec_t, f, fcn.args())
{
if( !is_first )
os << ", ";
diff --git a/src/convert/resolve.cpp b/src/convert/resolve.cpp index 6ea3fcc6..7f36c964 100644 --- a/src/convert/resolve.cpp +++ b/src/convert/resolve.cpp @@ -87,6 +87,8 @@ CPathResolver::CPathResolver(const AST::Crate& crate, const AST::Module& mod): void CPathResolver::resolve_path(AST::Path& path, bool allow_variables) const
{
+ DEBUG("path = " << path);
+
// Handle generic components of the path
for( auto& ent : path.nodes() )
{
@@ -100,6 +102,11 @@ void CPathResolver::resolve_path(AST::Path& path, bool allow_variables) const if( !path.is_relative() )
{
// Already absolute, our job is done
+ // - However, if the path isn't bound, bind it
+ if( !path.is_bound() ) {
+ path.set_crate(m_crate);
+ path.resolve();
+ }
}
else
{
@@ -133,11 +140,12 @@ void CPathResolver::resolve_path(AST::Path& path, bool allow_variables) const // Check name down?
// Add current module path
path = m_module_path + path;
+ break;
}
}
for( const auto& item_fcn : m_module.functions() )
{
- if( item_fcn.first.name() == path[0].name() ) {
+ if( item_fcn.name == path[0].name() ) {
path = m_module_path + path;
break;
}
@@ -149,13 +157,18 @@ void CPathResolver::resolve_path(AST::Path& path, bool allow_variables) const if( bind_name == "" ) {
// wildcard import!
// TODO: Import should be tagged with
- throw ParseError::Todo("CPathResolver::resolve_path() - Wildcards");
+ //throw ParseError::Todo("CPathResolver::resolve_path() - Wildcards");
}
else if( bind_name == path[0].name() ) {
path = AST::Path::add_tailing(bind_path, path);
+ break;
}
}
+ DEBUG("path = " << path);
+ path.resolve();
+
+
throw ParseError::Todo("CPathResolver::resolve_path()");
}
}
@@ -250,6 +263,8 @@ void ResolvePaths_HandleFunction(const AST::Crate& crate, const AST::Module& mod void ResolvePaths_HandleModule_Use(const AST::Crate& crate, const AST::Path& modpath, AST::Module& mod)
{
+ DEBUG("modpath = " << modpath);
+ ::std::vector<AST::Path> new_imports;
for( auto& imp : mod.imports() )
{
// TODO: Handle 'super' and 'self' imports
@@ -258,15 +273,49 @@ void ResolvePaths_HandleModule_Use(const AST::Crate& crate, const AST::Path& mod if( imp.name == "" )
{
+ DEBUG("Wildcard of " << imp.data);
if( imp.is_pub ) {
throw ParseError::Generic("Wildcard uses can't be public");
}
// Wildcard import
AST::Path& basepath = imp.data;
- basepath.resolve(crate);
- throw ParseError::Todo("ResolvePaths_HandleModule - wildcard use");
+ basepath.set_crate(crate);
+ basepath.resolve();
+ switch(basepath.binding_type())
+ {
+ case AST::Path::UNBOUND:
+ throw ParseError::BugCheck("path unbound after calling .resolve()");
+ case AST::Path::MODULE:
+ for( auto& submod : basepath.bound_module().submods() )
+ {
+ if( submod.second == true )
+ {
+ new_imports.push_back( basepath + AST::PathNode(submod.first.name(), {}) );
+ }
+ }
+ for(const auto& imp : basepath.bound_module().imports() )
+ {
+ if( imp.is_pub )
+ {
+ if(imp.name == "")
+ throw ParseError::Generic("Wilcard uses can't be public");
+ new_imports.push_back( imp.data );
+ }
+ }
+ //throw ParseError::Todo("ResolvePaths_HandleModule - wildcard use on module");
+ break;
+ }
+ }
+ }
+
+ for( auto& new_imp : new_imports )
+ {
+ if( not new_imp.is_bound() ) {
+ new_imp.set_crate(crate);
+ new_imp.resolve();
}
+ mod.add_alias(false, new_imp, new_imp[new_imp.size()-1].name());
}
for( auto& submod : mod.submods() )
@@ -279,7 +328,7 @@ void ResolvePaths_HandleModule(const AST::Crate& crate, const AST::Path& modpath {
for( auto& fcn : mod.functions() )
{
- ResolvePaths_HandleFunction(crate, mod, fcn.first);
+ ResolvePaths_HandleFunction(crate, mod, fcn.data);
}
for( auto& submod : mod.submods() )
diff --git a/src/parse/root.cpp b/src/parse/root.cpp index 1c2582f7..d3ca5b9b 100644 --- a/src/parse/root.cpp +++ b/src/parse/root.cpp @@ -243,10 +243,6 @@ AST::Function Parse_FunctionDef(TokenStream& lex) Token tok;
- // Name
- GET_CHECK_TOK(tok, lex, TOK_IDENT);
- ::std::string name = tok.str();
-
// Parameters
AST::TypeParams params;
if( GET_TOK(tok, lex) == TOK_LT )
@@ -329,7 +325,7 @@ AST::Function Parse_FunctionDef(TokenStream& lex) AST::Expr code = Parse_ExprBlock(lex);
- return AST::Function(name, params, fcn_class, ret_type, args, code);
+ return AST::Function(params, fcn_class, ret_type, args, code);
}
void Parse_Struct(AST::Module& mod, TokenStream& lex, const bool is_public, const ::std::vector<AST::MetaItem> meta_items)
@@ -469,9 +465,11 @@ AST::Impl Parse_Impl(TokenStream& lex) }
switch(tok.type())
{
- case TOK_RWORD_FN:
- impl.add_function(is_public, Parse_FunctionDef(lex));
- break;
+ case TOK_RWORD_FN: {
+ GET_CHECK_TOK(tok, lex, TOK_IDENT);
+ ::std::string name = tok.str();
+ impl.add_function(is_public, name, Parse_FunctionDef(lex));
+ break; }
default:
throw ParseError::Unexpected(tok);
@@ -655,9 +653,11 @@ void Parse_ModRoot(Preproc& lex, AST::Module& mod, const ::std::string& path) mod.add_global(is_public, is_mut, name, type, val);
break; }
- case TOK_RWORD_FN:
- mod.add_function(is_public, Parse_FunctionDef(lex));
- break;
+ case TOK_RWORD_FN: {
+ GET_CHECK_TOK(tok, lex, TOK_IDENT);
+ ::std::string name = tok.str();
+ mod.add_function(is_public, name, Parse_FunctionDef(lex));
+ break; }
case TOK_RWORD_STRUCT:
Parse_Struct(mod, lex, is_public, meta_items);
break;
diff --git a/src/types.hpp b/src/types.hpp index f6a58d2a..4a596522 100644 --- a/src/types.hpp +++ b/src/types.hpp @@ -30,6 +30,9 @@ public: struct TagUnsizedArray {};
TypeRef(TagUnsizedArray _, TypeRef inner_type) {}
+ struct TagArg {};
+ TypeRef(TagArg, ::std::string name) {}
+
struct TagPath {};
TypeRef(TagPath, AST::Path path) {}
|