From 7a507fcb4955715ebccd1eb85cf792a1a7802c61 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Thu, 25 Feb 2016 18:25:04 +0800 Subject: Parse - Rework module parsing to unify root/expr parse --- src/ast/ast.cpp | 6 - src/parse/common.hpp | 2 + src/parse/expr.cpp | 107 +--------- src/parse/root.cpp | 578 +++++++++++++++++++++++++-------------------------- 4 files changed, 292 insertions(+), 401 deletions(-) (limited to 'src') diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index c8ad705f..e552692d 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -603,12 +603,6 @@ void Module::resolve_macro_import(const Crate& crate, const ::std::string& modna throw ::std::runtime_error( FMT("Could not find sub-module '" << modname << "' for macro import") ); } -void Module::add_macro_import(const Crate& crate, ::std::string modname, ::std::string macro_name) -{ - resolve_macro_import(crate, modname, macro_name); - m_macro_imports.insert( ::std::make_pair( move(modname), move(macro_name) ) ); -} - void Module::iterate_functions(fcn_visitor_t *visitor, const Crate& crate) { for( auto& fcn_item : this->m_functions ) diff --git a/src/parse/common.hpp b/src/parse/common.hpp index 0d8ae278..73938aed 100644 --- a/src/parse/common.hpp +++ b/src/parse/common.hpp @@ -51,6 +51,8 @@ extern void Parse_Impl(TokenStream& lex, AST::Module& mod, AST::MetaItems attrs, extern void Parse_MacroRules(TokenStream& lex, AST::Module& mod, AST::MetaItems meta_items); extern void Parse_ExternCrate(TokenStream& lex, AST::Module& mod, AST::MetaItems meta_items); +extern void Parse_Mod_Item(TokenStream& lex, LList& modstack, const ::std::string& file_path, AST::Module& mod, bool is_public, AST::MetaItems meta_items); + extern AST::Function Parse_FunctionDef(TokenStream& lex, ::std::string abi, AST::MetaItems attrs, bool allow_self, bool can_be_prototype); extern AST::Function Parse_FunctionDefWithCode(TokenStream& lex, ::std::string abi, AST::MetaItems attrs, bool allow_self); diff --git a/src/parse/expr.cpp b/src/parse/expr.cpp index 50aaefad..20a7193e 100644 --- a/src/parse/expr.cpp +++ b/src/parse/expr.cpp @@ -76,117 +76,32 @@ ExprNodeP Parse_ExprBlockNode(TokenStream& lex) switch(tok.type()) { case TOK_CATTR_OPEN: + // TODO: Handle `#![` by having a pointer to the parent item (e.g. function)'s attribute list. /*node_attrs.push_back(*/ Parse_MetaItem(lex) /*)*/; GET_CHECK_TOK(tok, lex, TOK_SQUARE_CLOSE); break; // Items: - // - 'use' + case TOK_RWORD_TYPE: case TOK_RWORD_USE: - keep_mod = true; - Parse_Use( - lex, - [&local_mod](AST::Path p, std::string s) { - local_mod->imports().push_back( AST::Item( ::std::move(s), ::std::move(p), false ) ); - } - ); - GET_CHECK_TOK(tok, lex, TOK_SEMICOLON); - break; - // 'extern' blocks case TOK_RWORD_EXTERN: - keep_mod = true; - if( GET_TOK(tok, lex) == TOK_RWORD_CRATE ) { - Parse_ExternCrate(lex, *local_mod, mv$(item_attrs)); - } - else { - lex.putback(tok); - Parse_ExternBlock(lex, ::std::move(item_attrs), local_mod->functions()); - } - break; - // - 'const' case TOK_RWORD_CONST: - keep_mod = true; - { - GET_CHECK_TOK(tok, lex, TOK_IDENT); - ::std::string name = tok.str(); - GET_CHECK_TOK(tok, lex, TOK_COLON); - TypeRef type = Parse_Type(lex); - GET_CHECK_TOK(tok, lex, TOK_EQUAL); - auto val = Parse_Expr1(lex); - GET_CHECK_TOK(tok, lex, TOK_SEMICOLON); - - local_mod->statics().push_back( AST::Item( - ::std::move(name), - AST::Static(mv$(item_attrs), AST::Static::CONST, mv$(type), mv$(val)), - false ) ); - break; - } - // - 'static' case TOK_RWORD_STATIC: - keep_mod = true; - { - bool is_mut = false; - if( GET_TOK(tok, lex) == TOK_RWORD_MUT ) - is_mut = true; - else - lex.putback(tok); - GET_CHECK_TOK(tok, lex, TOK_IDENT); - ::std::string name = tok.str(); - GET_CHECK_TOK(tok, lex, TOK_COLON); - TypeRef type = Parse_Type(lex); - GET_CHECK_TOK(tok, lex, TOK_EQUAL); - auto val = Parse_Expr1(lex); - GET_CHECK_TOK(tok, lex, TOK_SEMICOLON); - - local_mod->add_static(false, mv$(name), - AST::Static(mv$(item_attrs), (is_mut ? AST::Static::MUT : AST::Static::STATIC), mv$(type), mv$(val)) - ); - break; - } - // - 'struct' - case TOK_RWORD_STRUCT: { - keep_mod = true; - GET_CHECK_TOK(tok, lex, TOK_IDENT); - ::std::string name = tok.str(); - local_mod->add_struct(false, mv$(name), Parse_Struct(lex, item_attrs)); - break; } - // - 'enum' - case TOK_RWORD_ENUM: { - keep_mod = true; - GET_CHECK_TOK(tok, lex, TOK_IDENT); - auto name = mv$(tok.str()); - local_mod->add_enum(false, mv$(name), Parse_EnumDef(lex, item_attrs)); - break; } - // - 'trait' - case TOK_RWORD_TRAIT: { - keep_mod = true; - GET_CHECK_TOK(tok, lex, TOK_IDENT); - auto name = tok.str(); - local_mod->add_trait(false, mv$(name), Parse_TraitDef(lex, mv$(item_attrs))); - break; } - // - 'impl' + case TOK_RWORD_STRUCT: + case TOK_RWORD_ENUM: + case TOK_RWORD_TRAIT: case TOK_RWORD_IMPL: - keep_mod = true; - Parse_Impl(lex, *local_mod, mv$(item_attrs), false); - break; - // - 'fn' case TOK_RWORD_FN: + lex.putback(tok); keep_mod = true; - GET_CHECK_TOK(tok, lex, TOK_IDENT); - // - self not allowed, not prototype - local_mod->add_function( - false, tok.str(), Parse_FunctionDefWithCode(lex, "rust", ::std::move(item_attrs), false) - ); + Parse_Mod_Item(lex, modstack, "!", *local_mod, false, mv$(item_attrs)); break; + // 'unsafe' - Check if the next token isn't a `{`, if so it's an item. Otherwise, fall through case TOK_RWORD_UNSAFE: - if( LOOK_AHEAD(lex) == TOK_RWORD_FN ) + if( LOOK_AHEAD(lex) != TOK_BRACE_OPEN ) { - GET_TOK(tok, lex); + lex.putback(tok); keep_mod = true; - GET_CHECK_TOK(tok, lex, TOK_IDENT); - // - self not allowed, not prototype - local_mod->add_function( - false, tok.str(), Parse_FunctionDefWithCode(lex, "rust", ::std::move(item_attrs), false) - ); + Parse_Mod_Item(lex, modstack, "!", *local_mod, false, mv$(item_attrs)); break; } if(0) diff --git a/src/parse/root.cpp b/src/parse/root.cpp index 2ed19aee..ab760a19 100644 --- a/src/parse/root.cpp +++ b/src/parse/root.cpp @@ -16,7 +16,7 @@ #include AST::MetaItem Parse_MetaItem(TokenStream& lex); -void Parse_ModRoot(TokenStream& lex, AST::Crate& crate, AST::Module& mod, LList *prev_modstack, const ::std::string& path); +void Parse_ModRoot(TokenStream& lex, AST::Module& mod, LList *prev_modstack, const ::std::string& path); ::std::vector< ::std::string> Parse_HRB(TokenStream& lex) { @@ -1467,10 +1467,282 @@ void Parse_ExternCrate(TokenStream& lex, AST::Module& mod, AST::MetaItems meta_i //} } -void Parse_ModRoot_Items(TokenStream& lex, AST::Crate& crate, AST::Module& mod, LList& modstack, const ::std::string& path) +void Parse_Mod_Item(TokenStream& lex, LList& modstack, const ::std::string& file_path, AST::Module& mod, bool is_public, AST::MetaItems meta_items) { //TRACE_FUNCTION; - const bool nested_module = (path == "-" || path == "!"); // 'mod name { code }', as opposed to 'mod name;' + const bool nested_module = (file_path == "-" || file_path == "!"); // 'mod name { code }', as opposed to 'mod name;' + Token tok; + + // The actual item! + switch( GET_TOK(tok, lex) ) + { + // `use ...` + case TOK_RWORD_USE: + Parse_Use(lex, [&mod,is_public,&file_path](AST::Path p, std::string s) { + DEBUG(file_path << " - use " << p << " as '" << s << "'"); + mod.add_alias(is_public, mv$(p), s); + }); + GET_CHECK_TOK(tok, lex, TOK_SEMICOLON); + break; + + case TOK_RWORD_EXTERN: + switch( GET_TOK(tok, lex) ) + { + // `extern "" fn ...` + // `extern "" { ...` + case TOK_STRING: { + ::std::string abi = tok.str(); + switch(GET_TOK(tok, lex)) + { + // `extern "" fn ...` + case TOK_RWORD_FN: + GET_CHECK_TOK(tok, lex, TOK_IDENT); + mod.add_function(is_public, tok.str(), Parse_FunctionDefWithCode(lex, abi, ::std::move(meta_items), false)); + break; + // `extern "" { ...` + case TOK_BRACE_OPEN: + Parse_ExternBlock(lex, mod, ::std::move(abi)); + break; + default: + throw ParseError::Unexpected(lex, tok, {TOK_RWORD_FN, TOK_BRACE_OPEN}); + } + break; } + // `extern fn ...` + case TOK_RWORD_FN: + GET_CHECK_TOK(tok, lex, TOK_IDENT); + mod.add_function(is_public, tok.str(), Parse_FunctionDefWithCode(lex, "C", ::std::move(meta_items), false)); + break; + // `extern { ...` + case TOK_BRACE_OPEN: + Parse_ExternBlock(lex, mod, "C"); + break; + // `extern crate "crate-name" as crate_name;` + // `extern crate crate_name;` + case TOK_RWORD_CRATE: + Parse_ExternCrate(lex, mod, mv$(meta_items)); + break; + default: + throw ParseError::Unexpected(lex, tok, {TOK_STRING, TOK_RWORD_FN, TOK_BRACE_OPEN, TOK_RWORD_CRATE}); + } + break; + + // `const NAME` + // `const fn` + case TOK_RWORD_CONST: { + switch( GET_TOK(tok, lex) ) + { + case TOK_IDENT: { + ::std::string name = tok.str(); + + GET_CHECK_TOK(tok, lex, TOK_COLON); + TypeRef type = Parse_Type(lex); + GET_CHECK_TOK(tok, lex, TOK_EQUAL); + AST::Expr val = Parse_Expr(lex, true); + GET_CHECK_TOK(tok, lex, TOK_SEMICOLON); + mod.add_static(is_public, name, AST::Static(::std::move(meta_items), AST::Static::CONST, type, val)); + break; } + case TOK_RWORD_UNSAFE: + GET_CHECK_TOK(tok, lex, TOK_RWORD_FN); + GET_CHECK_TOK(tok, lex, TOK_IDENT); + mod.add_function(is_public, tok.str(), Parse_FunctionDefWithCode(lex, "rust", ::std::move(meta_items), false)); + break; + case TOK_RWORD_FN: { + GET_CHECK_TOK(tok, lex, TOK_IDENT); + // - self not allowed, not prototype + // TODO: Mark as const + mod.add_function(is_public, tok.str(), Parse_FunctionDefWithCode(lex, "rust", ::std::move(meta_items), false)); + break; } + default: + throw ParseError::Unexpected(lex, tok, {TOK_IDENT, TOK_RWORD_FN}); + } + break; } + // `static NAME` + // `static mut NAME` + case TOK_RWORD_STATIC: { + tok = lex.getToken(); + bool is_mut = false; + if(tok.type() == TOK_RWORD_MUT) { + is_mut = true; + tok = lex.getToken(); + } + CHECK_TOK(tok, TOK_IDENT); + ::std::string name = tok.str(); + + GET_CHECK_TOK(tok, lex, TOK_COLON); + TypeRef type = Parse_Type(lex); + + GET_CHECK_TOK(tok, lex, TOK_EQUAL); + + AST::Expr val = Parse_Expr(lex, true); + + GET_CHECK_TOK(tok, lex, TOK_SEMICOLON); + mod.add_static(is_public, name, + AST::Static(::std::move(meta_items), (is_mut ? AST::Static::MUT : AST::Static::STATIC), type, val) + ); + break; } + + // `unsafe fn` + // `unsafe trait` + // `unsafe impl` + case TOK_RWORD_UNSAFE: + meta_items.push_back( AST::MetaItem("#UNSAFE") ); + switch(GET_TOK(tok, lex)) + { + // `unsafe extern fn` + case TOK_RWORD_EXTERN: { + ::std::string abi = "C"; + if(GET_TOK(tok, lex) == TOK_STRING) { + abi = mv$(tok.str()); + } + else { + lex.putback(tok); + } + GET_CHECK_TOK(tok, lex, TOK_RWORD_FN); + GET_CHECK_TOK(tok, lex, TOK_IDENT); + mod.add_function(is_public, tok.str(), Parse_FunctionDefWithCode(lex, abi, ::std::move(meta_items), false)); + break; } + // `unsafe fn` + case TOK_RWORD_FN: + GET_CHECK_TOK(tok, lex, TOK_IDENT); + // - self not allowed, not prototype + // TODO: Mark as unsafe + mod.add_function(is_public, tok.str(), Parse_FunctionDefWithCode(lex, "rust", ::std::move(meta_items), false)); + break; + // `unsafe trait` + case TOK_RWORD_TRAIT: { + GET_CHECK_TOK(tok, lex, TOK_IDENT); + ::std::string name = tok.str(); + // TODO: Mark as unsafe + mod.add_trait(is_public, name, Parse_TraitDef(lex, meta_items)); + break; } + // `unsafe impl` + case TOK_RWORD_IMPL: + Parse_Impl(lex, mod, mv$(meta_items), true); + break; + default: + throw ParseError::Unexpected(lex, tok, {TOK_RWORD_FN, TOK_RWORD_TRAIT, TOK_RWORD_IMPL}); + } + break; + // `fn` + case TOK_RWORD_FN: { + GET_CHECK_TOK(tok, lex, TOK_IDENT); + ::std::string name = tok.str(); + // - self not allowed, not prototype + mod.add_function(is_public, name, Parse_FunctionDefWithCode(lex, "rust", ::std::move(meta_items), false)); + break; } + // `type` + case TOK_RWORD_TYPE: { + GET_CHECK_TOK(tok, lex, TOK_IDENT); + ::std::string name = tok.str(); + mod.add_typealias(is_public, name, Parse_TypeAlias(lex, meta_items)); + break; } + // `struct` + case TOK_RWORD_STRUCT: { + GET_CHECK_TOK(tok, lex, TOK_IDENT); + ::std::string name = tok.str(); + mod.add_struct( is_public, name, Parse_Struct(lex, meta_items) ); + break; } + // `enum` + case TOK_RWORD_ENUM: { + GET_CHECK_TOK(tok, lex, TOK_IDENT); + ::std::string name = tok.str(); + mod.add_enum(is_public, name, Parse_EnumDef(lex, meta_items)); + break; } + // `impl` + case TOK_RWORD_IMPL: + Parse_Impl(lex, mod, mv$(meta_items)); + break; + // `trait` + case TOK_RWORD_TRAIT: { + GET_CHECK_TOK(tok, lex, TOK_IDENT); + ::std::string name = tok.str(); + mod.add_trait(is_public, name, Parse_TraitDef(lex, meta_items)); + break; } + + case TOK_RWORD_MOD: { + GET_CHECK_TOK(tok, lex, TOK_IDENT); + ::std::string name = tok.str(); + + // TODO: Remove this copy, by keeping record of macro_use() + AST::Module submod(meta_items, name); + DEBUG("Sub module '"<string(); + ::std::ifstream ifs_dir (newpath_dir); + if( !ifs_dir.is_open() ) + { + } + else + { + ::std::string newdir( newpath_dir.begin(), newpath_dir.begin() + newpath_dir.find_last_of('/') ); + Lexer sub_lex(newpath_dir); + Parse_ModRoot(sub_lex, submod, &modstack, newdir); + GET_CHECK_TOK(tok, sub_lex, TOK_EOF); + } + } + else + { + ::std::string newpath_dir = file_path + name + "/"; + ::std::string newpath_file = file_path + name + ".rs"; + ::std::ifstream ifs_dir (newpath_dir + "mod.rs"); + ::std::ifstream ifs_file(newpath_file); + if( ifs_dir.is_open() && ifs_file.is_open() ) + { + // Collision + } + else if( ifs_dir.is_open() ) + { + // Load from dir + Lexer sub_lex(newpath_dir + "mod.rs"); + Parse_ModRoot(sub_lex, submod, &modstack, newpath_dir); + GET_CHECK_TOK(tok, sub_lex, TOK_EOF); + } + else if( ifs_file.is_open() ) + { + // Load from file + Lexer sub_lex(newpath_file); + Parse_ModRoot(sub_lex, submod, &modstack, newpath_file); + GET_CHECK_TOK(tok, sub_lex, TOK_EOF); + } + else + { + // Can't find file + throw ParseError::Generic( FMT("Can't find file for " << name << " in '" << file_path << "'") ); + } + } + break; + default: + throw ParseError::Generic("Expected { or ; after module name"); + } + submod.prescan(); + mod.add_submod(is_public, ::std::move(submod)); + Macro_SetModule(modstack); + break; } + + default: + throw ParseError::Unexpected(lex, tok); + } +} + +void Parse_ModRoot_Items(TokenStream& lex, AST::Module& mod, LList& modstack, const ::std::string& path) +{ Token tok; for(;;) @@ -1528,292 +1800,11 @@ void Parse_ModRoot_Items(TokenStream& lex, AST::Crate& crate, AST::Module& mod, lex.putback(tok); } - // The actual item! - switch( GET_TOK(tok, lex) ) - { - // `use ...` - case TOK_RWORD_USE: - Parse_Use(lex, [&mod,is_public,&path](AST::Path p, std::string s) { - DEBUG(path << " - use " << p << " as '" << s << "'"); - mod.add_alias(is_public, mv$(p), s); - }); - GET_CHECK_TOK(tok, lex, TOK_SEMICOLON); - break; - - case TOK_RWORD_EXTERN: - switch( GET_TOK(tok, lex) ) - { - // `extern "" fn ...` - // `extern "" { ...` - case TOK_STRING: { - ::std::string abi = tok.str(); - switch(GET_TOK(tok, lex)) - { - // `extern "" fn ...` - case TOK_RWORD_FN: - GET_CHECK_TOK(tok, lex, TOK_IDENT); - mod.add_function(is_public, tok.str(), Parse_FunctionDefWithCode(lex, abi, ::std::move(meta_items), false)); - break; - // `extern "" { ...` - case TOK_BRACE_OPEN: - Parse_ExternBlock(lex, mod, ::std::move(abi)); - break; - default: - throw ParseError::Unexpected(lex, tok, {TOK_RWORD_FN, TOK_BRACE_OPEN}); - } - break; } - // `extern fn ...` - case TOK_RWORD_FN: - GET_CHECK_TOK(tok, lex, TOK_IDENT); - mod.add_function(is_public, tok.str(), Parse_FunctionDefWithCode(lex, "C", ::std::move(meta_items), false)); - break; - // `extern { ...` - case TOK_BRACE_OPEN: - Parse_ExternBlock(lex, mod, "C"); - break; - // `extern crate "crate-name" as crate_name;` - // `extern crate crate_name;` - case TOK_RWORD_CRATE: - Parse_ExternCrate(lex, mod, mv$(meta_items)); - break; - default: - throw ParseError::Unexpected(lex, tok, {TOK_STRING, TOK_RWORD_FN, TOK_BRACE_OPEN, TOK_RWORD_CRATE}); - } - break; - - // `const NAME` - // `const fn` - case TOK_RWORD_CONST: { - switch( GET_TOK(tok, lex) ) - { - case TOK_IDENT: { - ::std::string name = tok.str(); - - GET_CHECK_TOK(tok, lex, TOK_COLON); - TypeRef type = Parse_Type(lex); - GET_CHECK_TOK(tok, lex, TOK_EQUAL); - AST::Expr val = Parse_Expr(lex, true); - GET_CHECK_TOK(tok, lex, TOK_SEMICOLON); - mod.add_static(is_public, name, AST::Static(::std::move(meta_items), AST::Static::CONST, type, val)); - break; } - case TOK_RWORD_UNSAFE: - GET_CHECK_TOK(tok, lex, TOK_RWORD_FN); - GET_CHECK_TOK(tok, lex, TOK_IDENT); - mod.add_function(is_public, tok.str(), Parse_FunctionDefWithCode(lex, "rust", ::std::move(meta_items), false)); - break; - case TOK_RWORD_FN: { - GET_CHECK_TOK(tok, lex, TOK_IDENT); - // - self not allowed, not prototype - // TODO: Mark as const - mod.add_function(is_public, tok.str(), Parse_FunctionDefWithCode(lex, "rust", ::std::move(meta_items), false)); - break; } - default: - throw ParseError::Unexpected(lex, tok, {TOK_IDENT, TOK_RWORD_FN}); - } - break; } - // `static NAME` - // `static mut NAME` - case TOK_RWORD_STATIC: { - tok = lex.getToken(); - bool is_mut = false; - if(tok.type() == TOK_RWORD_MUT) { - is_mut = true; - tok = lex.getToken(); - } - CHECK_TOK(tok, TOK_IDENT); - ::std::string name = tok.str(); - - GET_CHECK_TOK(tok, lex, TOK_COLON); - TypeRef type = Parse_Type(lex); - - GET_CHECK_TOK(tok, lex, TOK_EQUAL); - - AST::Expr val = Parse_Expr(lex, true); - - GET_CHECK_TOK(tok, lex, TOK_SEMICOLON); - mod.add_static(is_public, name, - AST::Static(::std::move(meta_items), (is_mut ? AST::Static::MUT : AST::Static::STATIC), type, val) - ); - break; } - - // `unsafe fn` - // `unsafe trait` - // `unsafe impl` - case TOK_RWORD_UNSAFE: - meta_items.push_back( AST::MetaItem("#UNSAFE") ); - switch(GET_TOK(tok, lex)) - { - // `unsafe extern fn` - case TOK_RWORD_EXTERN: { - ::std::string abi = "C"; - if(GET_TOK(tok, lex) == TOK_STRING) { - abi = mv$(tok.str()); - } - else { - lex.putback(tok); - } - GET_CHECK_TOK(tok, lex, TOK_RWORD_FN); - GET_CHECK_TOK(tok, lex, TOK_IDENT); - mod.add_function(is_public, tok.str(), Parse_FunctionDefWithCode(lex, abi, ::std::move(meta_items), false)); - break; } - // `unsafe fn` - case TOK_RWORD_FN: - GET_CHECK_TOK(tok, lex, TOK_IDENT); - // - self not allowed, not prototype - // TODO: Mark as unsafe - mod.add_function(is_public, tok.str(), Parse_FunctionDefWithCode(lex, "rust", ::std::move(meta_items), false)); - break; - // `unsafe trait` - case TOK_RWORD_TRAIT: { - GET_CHECK_TOK(tok, lex, TOK_IDENT); - ::std::string name = tok.str(); - // TODO: Mark as unsafe - mod.add_trait(is_public, name, Parse_TraitDef(lex, meta_items)); - break; } - // `unsafe impl` - case TOK_RWORD_IMPL: - Parse_Impl(lex, mod, mv$(meta_items), true); - break; - default: - throw ParseError::Unexpected(lex, tok, {TOK_RWORD_FN, TOK_RWORD_TRAIT, TOK_RWORD_IMPL}); - } - break; - // `fn` - case TOK_RWORD_FN: { - GET_CHECK_TOK(tok, lex, TOK_IDENT); - ::std::string name = tok.str(); - // - self not allowed, not prototype - mod.add_function(is_public, name, Parse_FunctionDefWithCode(lex, "rust", ::std::move(meta_items), false)); - break; } - // `type` - case TOK_RWORD_TYPE: { - GET_CHECK_TOK(tok, lex, TOK_IDENT); - ::std::string name = tok.str(); - mod.add_typealias(is_public, name, Parse_TypeAlias(lex, meta_items)); - break; } - // `struct` - case TOK_RWORD_STRUCT: { - GET_CHECK_TOK(tok, lex, TOK_IDENT); - ::std::string name = tok.str(); - mod.add_struct( is_public, name, Parse_Struct(lex, meta_items) ); - break; } - // `enum` - case TOK_RWORD_ENUM: { - GET_CHECK_TOK(tok, lex, TOK_IDENT); - ::std::string name = tok.str(); - mod.add_enum(is_public, name, Parse_EnumDef(lex, meta_items)); - break; } - // `impl` - case TOK_RWORD_IMPL: - Parse_Impl(lex, mod, mv$(meta_items)); - break; - // `trait` - case TOK_RWORD_TRAIT: { - GET_CHECK_TOK(tok, lex, TOK_IDENT); - ::std::string name = tok.str(); - mod.add_trait(is_public, name, Parse_TraitDef(lex, meta_items)); - break; } - - case TOK_RWORD_MOD: { - GET_CHECK_TOK(tok, lex, TOK_IDENT); - ::std::string name = tok.str(); - - // TODO: Remove this copy, by keeping record of macro_use() - AST::Module submod(meta_items, name); - DEBUG("Sub module '"<string(); - ::std::ifstream ifs_dir (newpath_dir); - if( !ifs_dir.is_open() ) - { - } - else - { - ::std::string newdir( newpath_dir.begin(), newpath_dir.begin() + newpath_dir.find_last_of('/') ); - Lexer sub_lex(newpath_dir); - Parse_ModRoot(sub_lex, crate, submod, &modstack, newdir); - GET_CHECK_TOK(tok, sub_lex, TOK_EOF); - } - } - else - { - ::std::string newpath_dir = path + name + "/"; - ::std::string newpath_file = path + name + ".rs"; - ::std::ifstream ifs_dir (newpath_dir + "mod.rs"); - ::std::ifstream ifs_file(newpath_file); - if( ifs_dir.is_open() && ifs_file.is_open() ) - { - // Collision - } - else if( ifs_dir.is_open() ) - { - // Load from dir - Lexer sub_lex(newpath_dir + "mod.rs"); - Parse_ModRoot(sub_lex, crate, submod, &modstack, newpath_dir); - GET_CHECK_TOK(tok, sub_lex, TOK_EOF); - } - else if( ifs_file.is_open() ) - { - // Load from file - Lexer sub_lex(newpath_file); - Parse_ModRoot(sub_lex, crate, submod, &modstack, newpath_file); - GET_CHECK_TOK(tok, sub_lex, TOK_EOF); - } - else - { - // Can't find file - throw ParseError::Generic( FMT("Can't find file for " << name << " in '" << path << "'") ); - } - } - break; - default: - throw ParseError::Generic("Expected { or ; after module name"); - } - submod.prescan(); - mod.add_submod(is_public, ::std::move(submod)); - Macro_SetModule(modstack); - - // import macros - { - auto at = meta_items.get("macro_use"); - if( at ) - { - if( at->has_sub_items() ) - { - throw ParseError::Todo("selective macro_use"); - } - else - { - mod.add_macro_import(crate, name, ""); - } - } - } - break; } - - default: - throw ParseError::Unexpected(lex, tok); - } + Parse_Mod_Item(lex, modstack, path, mod, is_public, mv$(meta_items)); } } -void Parse_ModRoot(TokenStream& lex, AST::Crate& crate, AST::Module& mod, LList *prev_modstack, const ::std::string& path) +void Parse_ModRoot(TokenStream& lex, AST::Module& mod, LList *prev_modstack, const ::std::string& path) { TRACE_FUNCTION; LList modstack(prev_modstack, &mod); @@ -1821,17 +1812,6 @@ void Parse_ModRoot(TokenStream& lex, AST::Crate& crate, AST::Module& mod, LList< Token tok; - if( crate.m_load_std ) - { - // Import the prelude - AST::Path prelude_path = AST::Path( "std", { AST::PathNode("prelude", {}), AST::PathNode("v1", {}) } ); - Parse_Use_Wildcard( mv$(prelude_path), - [&mod](AST::Path p, std::string s) { - mod.add_alias(false, p, s); - } - ); - } - // Attributes on module/crate (will continue loop) while( GET_TOK(tok, lex) == TOK_CATTR_OPEN ) { @@ -1844,7 +1824,7 @@ void Parse_ModRoot(TokenStream& lex, AST::Crate& crate, AST::Module& mod, LList< // TODO: Iterate attributes, and check for handlers on each - Parse_ModRoot_Items(lex, crate, mod, modstack, path); + Parse_ModRoot_Items(lex, mod, modstack, path); } AST::Crate Parse_Crate(::std::string mainfile) @@ -1884,7 +1864,7 @@ AST::Crate Parse_Crate(::std::string mainfile) } } - Parse_ModRoot(lex, crate, rootmod, NULL, mainpath); + Parse_ModRoot(lex, rootmod, NULL, mainpath); return crate; } -- cgit v1.2.3