From 5aac662e859d10f42b541405fa0b8d14a1c1e2a8 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sun, 22 Mar 2015 09:28:56 +0800 Subject: Hack in UFCS syntax --- src/ast/expr.cpp | 1 - src/ast/path.cpp | 6 ++++++ src/ast/path.hpp | 5 +++++ src/convert/resolve.cpp | 8 +------- src/parse/expr.cpp | 24 ++++++++++++++++++++++-- 5 files changed, 34 insertions(+), 10 deletions(-) diff --git a/src/ast/expr.cpp b/src/ast/expr.cpp index 3c1d3c66..97d951fc 100644 --- a/src/ast/expr.cpp +++ b/src/ast/expr.cpp @@ -75,7 +75,6 @@ SERIALISE_TYPE(Expr::, "Expr", { else _(ExprNode_Field) else _(ExprNode_Deref) else _(ExprNode_Cast) - else _(ExprNode_CallPath) else _(ExprNode_BinOp) else _(ExprNode_UniOp) else diff --git a/src/ast/path.cpp b/src/ast/path.cpp index 1f07d4b0..fae2642e 100644 --- a/src/ast/path.cpp +++ b/src/ast/path.cpp @@ -48,6 +48,12 @@ SERIALISE_TYPE(PathNode::, "PathNode", { }) // --- AST::Path +AST::Path::Path(TagUfcs, TypeRef type, TypeRef trait): + m_class(UFCS), + m_ufcs({::std::move(type), ::std::move(trait)} ) +{ +} + template typename ::std::vector >::const_iterator find_named(const ::std::vector >& vec, const ::std::string& name) { diff --git a/src/ast/path.hpp b/src/ast/path.hpp index 447ff0a0..4701b03a 100644 --- a/src/ast/path.hpp +++ b/src/ast/path.hpp @@ -80,6 +80,7 @@ private: RELATIVE, ABSOLUTE, LOCAL, + UFCS, }; /// The crate defining the root of this path (used for path resolution) @@ -89,7 +90,9 @@ private: /// - 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 + /// - UFCS is relative to a type Class m_class; + ::std::vector m_ufcs; ::std::vector m_nodes; BindingType m_binding_type = UNBOUND; @@ -114,6 +117,8 @@ public: Path(TagAbsolute): m_class(ABSOLUTE) {} + struct TagUfcs {}; + Path(TagUfcs, TypeRef type, TypeRef trait); struct TagLocal {}; Path(TagLocal, ::std::string name): m_class(LOCAL), diff --git a/src/convert/resolve.cpp b/src/convert/resolve.cpp index 95325da1..e519d485 100644 --- a/src/convert/resolve.cpp +++ b/src/convert/resolve.cpp @@ -435,13 +435,7 @@ void ResolvePaths_HandleModule_Use(const AST::Crate& crate, const AST::Path& mod case AST::Path::ENUM: break; - case AST::Path::ALIAS: - case AST::Path::ENUM_VAR: - case AST::Path::STRUCT: - case AST::Path::STRUCT_METHOD: - case AST::Path::TRAIT: - case AST::Path::FUNCTION: - case AST::Path::STATIC: + default: throw ParseError::Generic("Wildcard imports are only allowed on modules and enums"); } } diff --git a/src/parse/expr.cpp b/src/parse/expr.cpp index d618a9af..222a6a3a 100644 --- a/src/parse/expr.cpp +++ b/src/parse/expr.cpp @@ -903,6 +903,7 @@ ExprNodeP Parse_ExprVal(TokenStream& lex) case TOK_BRACE_OPEN: lex.putback(tok); return Parse_ExprBlockNode(lex); + case TOK_RWORD_LOOP: return NEWNODE( AST::ExprNode_Loop, "", Parse_ExprBlockNode(lex) ); case TOK_RWORD_WHILE: @@ -919,9 +920,28 @@ ExprNodeP Parse_ExprVal(TokenStream& lex) return rv; } - case TOK_RWORD_SUPER: + // UFCS + case TOK_DOUBLE_LT: + lex.putback(tok); + case TOK_LT: { + TypeRef ty = Parse_Type(lex); + TypeRef trait; + if( GET_TOK(tok, lex) == TOK_RWORD_AS ) { + trait = Parse_Type(lex); + } + else + lex.putback(tok); + GET_CHECK_TOK(tok, lex, TOK_GT); + // TODO: Terminating the "path" here is sometimes valid GET_CHECK_TOK(tok, lex, TOK_DOUBLE_COLON); - path = Parse_PathFrom(lex, AST::Path(AST::Path::TagSuper()), PATH_GENERIC_EXPR); + path = Parse_PathFrom(lex, AST::Path(AST::Path::TagUfcs(), ty, trait), PATH_GENERIC_EXPR); + } + if(0) + case TOK_RWORD_SUPER: + { + GET_CHECK_TOK(tok, lex, TOK_DOUBLE_COLON); + path = Parse_PathFrom(lex, AST::Path(AST::Path::TagSuper()), PATH_GENERIC_EXPR); + } if(0) case TOK_IDENT: // Get path -- cgit v1.2.3