diff options
Diffstat (limited to 'src/parse')
-rw-r--r-- | src/parse/expr.cpp | 6 | ||||
-rw-r--r-- | src/parse/lex.cpp | 1 | ||||
-rw-r--r-- | src/parse/lex.hpp | 39 | ||||
-rw-r--r-- | src/parse/root.cpp | 141 | ||||
-rw-r--r-- | src/parse/tokentree.hpp | 39 |
5 files changed, 170 insertions, 56 deletions
diff --git a/src/parse/expr.cpp b/src/parse/expr.cpp index c56c529d..fd6f14b8 100644 --- a/src/parse/expr.cpp +++ b/src/parse/expr.cpp @@ -483,10 +483,10 @@ ExprNodeP Parse_ExprVal(TokenStream& lex) ExprNodeP rv = Parse_Expr0(lex);
GET_CHECK_TOK(tok, lex, TOK_PAREN_CLOSE);
return rv; }
- case TOK_MACRO: {
- // Need to create a token tree, pass to the macro, then pass the result of that to Parse_Expr0
+ case TOK_MACRO:
+ //return NEWNODE( AST::ExprNode_Macro, tok.str(), Parse_TT(lex) );
+ {
MacroExpander expanded_macro = Macro_Invoke(tok.str().c_str(), Parse_TT(lex));
-
return Parse_Expr0(expanded_macro);
}
default:
diff --git a/src/parse/lex.cpp b/src/parse/lex.cpp index 79db4603..f893f26c 100644 --- a/src/parse/lex.cpp +++ b/src/parse/lex.cpp @@ -6,6 +6,7 @@ * \brief Low-level lexer
*/
#include "lex.hpp"
+#include "tokentree.hpp"
#include "parseerror.hpp"
#include <cassert>
#include <iostream>
diff --git a/src/parse/lex.hpp b/src/parse/lex.hpp index dbf365a0..6a798909 100644 --- a/src/parse/lex.hpp +++ b/src/parse/lex.hpp @@ -197,43 +197,4 @@ private: class EndOfFile {};
};
-class TokenTree
-{
- Token m_tok;
- ::std::vector<TokenTree> m_subtrees;
-public:
- TokenTree() {}
- TokenTree(Token tok):
- m_tok(tok)
- {
- }
- TokenTree(::std::vector<TokenTree> subtrees):
- m_subtrees(subtrees)
- {
- }
-
- const unsigned int size() const {
- return m_subtrees.size();
- }
- const TokenTree& operator[](unsigned int idx) const {
- return m_subtrees[idx];
- }
- const Token& tok() const {
- return m_tok;
- }
-};
-
-class TTStream:
- public TokenStream
-{
- const TokenTree& m_input_tt;
- ::std::vector< ::std::pair<unsigned int, const TokenTree*> > m_stack;
-public:
- TTStream(const TokenTree& input_tt);
- ~TTStream();
-
-protected:
- virtual Token realGetToken();
-};
-
#endif // LEX_HPP_INCLUDED
diff --git a/src/parse/root.cpp b/src/parse/root.cpp index 4f2a5084..e922b39f 100644 --- a/src/parse/root.cpp +++ b/src/parse/root.cpp @@ -481,11 +481,88 @@ AST::Impl Parse_Impl(TokenStream& lex) return impl;
}
-AST::Module Parse_ModRoot(const ::std::string& path, Preproc& lex)
+void Parse_Use_Wildcard(const AST::Path& base_path, ::std::function<void(AST::Path, ::std::string)> fcn)
+{
+ throw ParseError::Todo("Wildcard imports");
+}
+
+void Parse_Use(Preproc& lex, ::std::function<void(AST::Path, ::std::string)> fcn)
{
Token tok;
+ AST::Path path = AST::Path( AST::Path::TagAbsolute() );
+
+ switch( GET_TOK(tok, lex) )
+ {
+ case TOK_RWORD_SELF:
+ throw ParseError::Todo("Parse_Use - self");
+ break;
+ case TOK_RWORD_SUPER:
+ throw ParseError::Todo("Parse_Use - super");
+ break;
+ case TOK_IDENT:
+ path.append( AST::PathNode(tok.str(), {}) );
+ break;
+ default:
+ throw ParseError::Unexpected(tok);
+ }
+ // TODO: Use from crate root
+ while( GET_TOK(tok, lex) == TOK_DOUBLE_COLON )
+ {
+ if( GET_TOK(tok, lex) == TOK_IDENT )
+ {
+ path.append( AST::PathNode(tok.str(), {}) );
+ }
+ else
+ {
+ switch( tok.type() )
+ {
+ case TOK_BRACE_OPEN:
+ throw ParseError::Todo("Parse_Use - multiples");
+ break;
+ case TOK_STAR:
+ throw ParseError::Todo("Parse_Use - wildcard/glob");
+ break;
+ default:
+ throw ParseError::Unexpected(tok);
+ }
+ GET_TOK(tok, lex);
+ break;
+ }
+ }
+
+ ::std::string name;
+ // TODO: This should only be allowed if the last token was an ident
+ if( tok.type() == TOK_RWORD_AS )
+ {
+ GET_CHECK_TOK(tok, lex, TOK_IDENT);
+ name = tok.str();
+ }
+ else
+ {
+ lex.putback(tok);
+ name = path[path.size()-1].name();
+ }
+
+ fcn(path, name);
+}
- AST::Module mod;
+void Parse_ModRoot(Preproc& lex, AST::Module& mod, const ::std::string& path)
+{
+ const bool nested_module = (path.size() == 0); // 'mod name { code }', as opposed to 'mod name;'
+ Token tok;
+
+ if( mod.crate().m_load_std )
+ {
+ // Import the prelude
+ AST::Path prelude_path = AST::Path(AST::Path::TagAbsolute());
+ prelude_path.append( AST::PathNode("std", {}) );
+ prelude_path.append( AST::PathNode("prelude", {}) );
+ Parse_Use_Wildcard(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 )
@@ -493,26 +570,25 @@ AST::Module Parse_ModRoot(const ::std::string& path, Preproc& lex) AST::MetaItem item = Parse_MetaItem(lex);
GET_CHECK_TOK(tok, lex, TOK_SQUARE_CLOSE);
- throw ParseError::Todo("Parent attrs");
- //mod_attrs.push_back( item );
+ mod.add_attr( item );
}
lex.putback(tok);
- // TODO: Handle known parent attribs if operating on crate root
-
+ // TODO: Iterate attributes, and check for handlers on each
+
for(;;)
{
// Check 1 - End of module (either via a closing brace, or EOF)
switch(GET_TOK(tok, lex))
{
case TOK_BRACE_CLOSE:
- if( path.size() > 0 )
+ if( !nested_module )
throw ParseError::Unexpected(tok);
- return mod;
+ return ;
case TOK_EOF:
- if( path.size() == 0 )
+ if( nested_module )
throw ParseError::Unexpected(tok);
- return mod;
+ return ;
default:
lex.putback(tok);
break;
@@ -542,8 +618,7 @@ AST::Module Parse_ModRoot(const ::std::string& path, Preproc& lex) switch( GET_TOK(tok, lex) )
{
case TOK_RWORD_USE:
- // TODO: Do manual path parsing here, as use has its own special set of quirks
- mod.add_alias( is_public, Parse_Path(lex, true, PATH_GENERIC_NONE) );
+ Parse_Use(lex, [&mod,is_public](AST::Path p, std::string s) { mod.add_alias(is_public, p, s); });
GET_CHECK_TOK(tok, lex, TOK_SEMICOLON);
break;
@@ -604,6 +679,44 @@ AST::Module Parse_ModRoot(const ::std::string& path, Preproc& lex) AST::Crate Parse_Crate(::std::string mainfile)
{
- Preproc lex(mainfile);
- return AST::Crate( Parse_ModRoot(mainfile, lex) );
+ Token tok;
+
+ Preproc lex(mainfile);
+ AST::Crate crate;
+ AST::Module& rootmod = crate.root_module();
+
+ // Attributes on module/crate
+ while( GET_TOK(tok, lex) == TOK_CATTR_OPEN )
+ {
+ AST::MetaItem item = Parse_MetaItem(lex);
+ GET_CHECK_TOK(tok, lex, TOK_SQUARE_CLOSE);
+
+ rootmod.add_attr( item );
+ }
+ lex.putback(tok);
+
+ // Check for crate attributes
+ for( const auto& attr : rootmod.attrs() )
+ {
+ if( attr.name() == "no_std" ) {
+ crate.m_load_std = false;
+ }
+ else {
+ // TODO:
+ }
+ }
+
+ if( crate.m_load_std )
+ {
+ // Load the standard library (add 'extern crate std;')
+ rootmod.add_ext_crate("std", "std");
+ // Prelude imports are handled in Parse_ModRoot
+ }
+
+ // Include the std if the 'no_std' attribute was absent
+ // - First need to load the std macros, then can import the prelude
+
+ Parse_ModRoot(lex, rootmod, mainfile);
+
+ return crate;
}
diff --git a/src/parse/tokentree.hpp b/src/parse/tokentree.hpp index 4105897d..b1b353ea 100644 --- a/src/parse/tokentree.hpp +++ b/src/parse/tokentree.hpp @@ -4,6 +4,45 @@ #include "lex.hpp"
+class TokenTree
+{
+ Token m_tok;
+ ::std::vector<TokenTree> m_subtrees;
+public:
+ TokenTree() {}
+ TokenTree(Token tok):
+ m_tok(tok)
+ {
+ }
+ TokenTree(::std::vector<TokenTree> subtrees):
+ m_subtrees(subtrees)
+ {
+ }
+
+ const unsigned int size() const {
+ return m_subtrees.size();
+ }
+ const TokenTree& operator[](unsigned int idx) const {
+ return m_subtrees[idx];
+ }
+ const Token& tok() const {
+ return m_tok;
+ }
+};
+
+class TTStream:
+ public TokenStream
+{
+ const TokenTree& m_input_tt;
+ ::std::vector< ::std::pair<unsigned int, const TokenTree*> > m_stack;
+public:
+ TTStream(const TokenTree& input_tt);
+ ~TTStream();
+
+protected:
+ virtual Token realGetToken();
+};
+
extern TokenTree Parse_TT(TokenStream& lex);
extern TokenTree Parse_TT_Expr(TokenStream& lex);
extern TokenTree Parse_TT_Stmt(TokenStream& lex);
|