diff options
| author | John Hodge <tpg@mutabah.net> | 2015-03-09 22:38:04 +0800 | 
|---|---|---|
| committer | John Hodge <tpg@mutabah.net> | 2015-03-09 22:38:04 +0800 | 
| commit | 65558948954daaa2aec68b76814b043bf829d608 (patch) | |
| tree | 1547e656d41b1b57de7cb1113c0dc9453737c83f | |
| parent | a9512c48f2fe621f771599d029fd12fa534e3497 (diff) | |
| download | mrust-65558948954daaa2aec68b76814b043bf829d608.tar.gz | |
Parse updates
| -rw-r--r-- | Makefile | 9 | ||||
| -rw-r--r-- | samples/log.rs | 5 | ||||
| -rw-r--r-- | src/ast/ast.cpp | 31 | ||||
| -rw-r--r-- | src/ast/ast.hpp | 3 | ||||
| -rw-r--r-- | src/ast/expr.cpp | 52 | ||||
| -rw-r--r-- | src/ast/expr.hpp | 22 | ||||
| -rw-r--r-- | src/ast/pattern.hpp | 2 | ||||
| -rw-r--r-- | src/dump_as_rust.cpp | 24 | ||||
| -rw-r--r-- | src/parse/expr.cpp | 95 | ||||
| -rw-r--r-- | src/parse/lex.hpp | 29 | ||||
| -rw-r--r-- | src/parse/parseerror.cpp | 5 | ||||
| -rw-r--r-- | src/parse/parseerror.hpp | 1 | ||||
| -rw-r--r-- | src/parse/root.cpp | 37 | 
13 files changed, 255 insertions, 60 deletions
| @@ -29,11 +29,14 @@ all: $(BIN)  clean:  	$(RM) -r $(BIN) $(OBJ) -test: $(BIN) samples/1.rs +output/%.ast: samples/%.rs +	@mkdir -p output/ +	$(DBG) $(BIN) $< --emit ast -o $@ 2>&1 | tee $@_dbg.txt ; test $${PIPESTATUS[0]} -eq 0 + +test: $(BIN) samples/1.rs output/std.ast output/log.ast  	mkdir -p output/ -	$(DBG) $(BIN) samples/std.rs --emit ast -o output/std.ast 2>&1 | tee output/ast_dbg.txt ; test $${PIPESTATUS[0]} -eq 0  #	$(DBG) $(BIN) samples/1.rs --crate-path output/std.ast -o output/test.c 2>&1 | tee output/1_dbg.txt -	$(DBG) $(BIN) ../../BinaryView2/src/main.rs --crate-path output/std.ast -o output/test.c 2>&1 | tee output/1_dbg.txt ; test $${PIPESTATUS[0]} -eq 0 +	$(DBG) $(BIN) ../../BinaryView2/src/main.rs --crate-path output/ -o output/test.c 2>&1 | tee output/1_dbg.txt ; test $${PIPESTATUS[0]} -eq 0  $(BIN): $(OBJ)  	@mkdir -p $(dir $@) diff --git a/samples/log.rs b/samples/log.rs new file mode 100644 index 00000000..eb9f544e --- /dev/null +++ b/samples/log.rs @@ -0,0 +1,5 @@ + +macro_rules! error{ +    ($( $v:tt )*) => {}; +} + diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index e6187001..8a903cca 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -48,8 +48,10 @@ SERIALISE_TYPE(MetaItem::, "AST_MetaItem", {      case Pattern::MAYBE_BIND:
          os << "Pattern(TagMaybeBind, '" << pat.m_binding << "')";
          break;
 +    case Pattern::REF:
 +        os << "Pattern(TagReference, '" << pat.m_binding << "' @ " << pat.m_sub_patterns[0] << ")";
 +        break;
      case Pattern::VALUE:
 -        //os << "Pattern(TagValue, " << *pat.m_node << ")";
          os << "Pattern(TagValue, '" << pat.m_binding << "' @ TODO:ExprNode)";
          break;
      case Pattern::TUPLE:
 @@ -64,18 +66,28 @@ SERIALISE_TYPE(MetaItem::, "AST_MetaItem", {  void operator%(Serialiser& s, Pattern::BindType c) {
      switch(c)
      {
 -    case Pattern::ANY:          s << "ANY";         return;
 -    case Pattern::MAYBE_BIND:   s << "MAYBE_BIND";  return;
 -    case Pattern::VALUE:        s << "VALUE";  return;
 -    case Pattern::TUPLE:        s << "TUPLE";  return;
 -    case Pattern::TUPLE_STRUCT: s << "TUPLE_STRUCT";  return;
 +    #define _(v)    case Pattern::v: s << #v; return;
 +    _(ANY)
 +    _(MAYBE_BIND)
 +    _(REF)
 +    _(VALUE)
 +    _(TUPLE)
 +    _(TUPLE_STRUCT)
 +    #undef _
      }
  }
  void operator%(::Deserialiser& s, Pattern::BindType& c) {
      ::std::string   n;
      s.item(n);
 -         if(n == "ANY")         c = Pattern::ANY;
 -    else if(n == "MAYBE_BIND")  c = Pattern::MAYBE_BIND;
 +    if(1)   ;
 +    #define _(v) else if(n == #v) c = Pattern::v;
 +    _(ANY)
 +    _(MAYBE_BIND)
 +    _(REF)
 +    _(VALUE)
 +    _(TUPLE)
 +    _(TUPLE_STRUCT)
 +    #undef _
      else
          throw ::std::runtime_error("");
  }
 @@ -89,6 +101,8 @@ SERIALISE_TYPE_S(Pattern, {  Impl Impl::make_concrete(const ::std::vector<TypeRef>& types) const
  {
      DEBUG("types={" << types << "}");
 +    throw ParseError::Todo("Impl::make_concrete");
 +/*
      INDENT();
      assert(m_params.n_params());
 @@ -120,6 +134,7 @@ Impl Impl::make_concrete(const ::std::vector<TypeRef>& types) const      UNINDENT();
      return ret;
 +*/
  }
  ::rust::option<Impl&> Impl::matches(const TypeRef& trait, const TypeRef& type)
 diff --git a/src/ast/ast.hpp b/src/ast/ast.hpp index 775ed943..c1c9c283 100644 --- a/src/ast/ast.hpp +++ b/src/ast/ast.hpp @@ -268,6 +268,7 @@ public:  private:
      Class   m_fcn_class;
 +    ::std::string   m_lifetime;
      TypeParams  m_params;
      Expr    m_code;
      TypeRef m_rettype;
 @@ -285,6 +286,8 @@ public:      {
      }
 +    void set_self_lifetime(::std::string s) { m_lifetime = s; }
 +    
      const Class fcn_class() const { return m_fcn_class; }
      TypeParams& params() { return m_params; }
 diff --git a/src/ast/expr.cpp b/src/ast/expr.cpp index 3e20655d..9ddd75a9 100644 --- a/src/ast/expr.cpp +++ b/src/ast/expr.cpp @@ -60,6 +60,7 @@ SERIALISE_TYPE(Expr::, "Expr", {      else _(ExprNode_CallObject)      else _(ExprNode_Match)      else _(ExprNode_If) +    else _(ExprNode_IfLet)      else _(ExprNode_Integer)      else _(ExprNode_StructLiteral)      else _(ExprNode_Tuple) @@ -178,6 +179,14 @@ NODE(ExprNode_If, {  },{      os << "if " << *m_cond << " { " << *m_true << " } else { " << *m_false << " }";  }) +NODE(ExprNode_IfLet, { +    s.item(m_pattern); +    s.item(m_value); +    s.item(m_true); +    s.item(m_false); +},{ +    os << "if let " << m_pattern << " = (" << *m_value << ") { " << *m_true << " } else { " << *m_false << " }"; +})  NODE(ExprNode_Integer, {      s % m_datatype; @@ -247,6 +256,10 @@ void operator%(::Serialiser& s, const ExprNode_BinOp::Type t) {      #define _(v)    case ExprNode_BinOp::v: s << #v; return      _(CMPEQU);      _(CMPNEQU); +    _(CMPLT); +    _(CMPLTE); +    _(CMPGT); +    _(CMPGTE);      _(BOOLAND);      _(BOOLOR);      _(BITAND); @@ -257,18 +270,37 @@ void operator%(::Serialiser& s, const ExprNode_BinOp::Type t) {  	_(MULTIPLY);  	_(DIVIDE);  	_(MODULO); +	_(ADD); +	_(SUB);      #undef _      }  }  void operator%(::Deserialiser& s, ExprNode_BinOp::Type& t) {      ::std::string   n;      s.item(n); -    #define _(v)    if(n == #v) t = ExprNode_BinOp::v -         _(CMPEQU); -    else _(CMPNEQU); +    if(0)   ; +    #define _(v)    else if(n == #v) t = ExprNode_BinOp::v +    _(CMPEQU); +    _(CMPNEQU); +    _(CMPLT); +    _(CMPLTE); +    _(CMPGT); +    _(CMPGTE); +    _(BOOLAND); +    _(BOOLOR); +    _(BITAND); +    _(BITOR); +    _(BITXOR); +    _(SHL); +    _(SHR); +	_(MULTIPLY); +	_(DIVIDE); +	_(MODULO); +	_(ADD); +	_(SUB); +    #undef _      else          throw ::std::runtime_error(""); -    #undef _  }  NODE(ExprNode_BinOp, {      s % m_type; @@ -280,6 +312,10 @@ NODE(ExprNode_BinOp, {      {      case CMPEQU:    os << "=="; break;      case CMPNEQU:   os << "!="; break; +    case CMPLT:     os << "<";  break; +    case CMPLTE:    os << "<="; break; +    case CMPGT:     os << ">";  break; +    case CMPGTE:    os << ">="; break;      case BOOLAND:   os << "&&"; break;      case BOOLOR:    os << "||"; break;      case BITAND:    os << "&"; break; @@ -402,6 +438,14 @@ NV(ExprNode_If,      visit(node.m_false);      UNINDENT();  }) +NV(ExprNode_IfLet, +{ +    INDENT(); +    visit(node.m_value); +    visit(node.m_true); +    visit(node.m_false); +    UNINDENT(); +})  NV(ExprNode_Integer, {})  NV(ExprNode_Float, {}) diff --git a/src/ast/expr.hpp b/src/ast/expr.hpp index 28526377..55da44d6 100644 --- a/src/ast/expr.hpp +++ b/src/ast/expr.hpp @@ -202,6 +202,24 @@ struct ExprNode_If:      }      NODE_METHODS();  }; +struct ExprNode_IfLet: +    public ExprNode +{ +    AST::Pattern    m_pattern; +    unique_ptr<ExprNode>    m_value; +    unique_ptr<ExprNode>    m_true; +    unique_ptr<ExprNode>    m_false; + +    ExprNode_IfLet() {} +    ExprNode_IfLet(AST::Pattern pattern, unique_ptr<ExprNode>&& cond, unique_ptr<ExprNode>&& true_code, unique_ptr<ExprNode>&& false_code): +        m_pattern( ::std::move(pattern) ), +        m_value( ::std::move(cond) ), +        m_true( ::std::move(true_code) ), +        m_false( ::std::move(false_code) ) +    { +    } +    NODE_METHODS(); +};  // Literal integer  struct ExprNode_Integer:      public ExprNode @@ -363,6 +381,8 @@ struct ExprNode_BinOp:  		MULTIPLY,  		DIVIDE,  		MODULO, +		ADD, +		SUB,      };      Type    m_type; @@ -425,6 +445,7 @@ public:      NT(ExprNode_CallObject);      NT(ExprNode_Match);      NT(ExprNode_If); +    NT(ExprNode_IfLet);      NT(ExprNode_Integer);      NT(ExprNode_Float); @@ -461,6 +482,7 @@ public:      NT(ExprNode_CallObject);      NT(ExprNode_Match);      NT(ExprNode_If); +    NT(ExprNode_IfLet);      NT(ExprNode_Integer);      NT(ExprNode_Float); diff --git a/src/ast/pattern.hpp b/src/ast/pattern.hpp index 78b224d0..5b03a8a2 100644 --- a/src/ast/pattern.hpp +++ b/src/ast/pattern.hpp @@ -32,7 +32,7 @@ private:      unique_ptr<ExprNode>    m_node;      ::std::vector<Pattern>  m_sub_patterns;  public: -    Pattern(Pattern&& o): +    Pattern(Pattern&& o) noexcept:          m_class(o.m_class),          m_binding( move(o.m_binding) ),          m_path( move(o.m_path) ), diff --git a/src/dump_as_rust.cpp b/src/dump_as_rust.cpp index e5d225bd..c9a64371 100644 --- a/src/dump_as_rust.cpp +++ b/src/dump_as_rust.cpp @@ -155,6 +155,21 @@ public:          m_expr_root = false;          m_os << "if ";          AST::NodeVisitor::visit(n.m_cond); +         +        visit_if_common(expr_root, n.m_true, n.m_false); +    } +    virtual void visit(AST::ExprNode_IfLet& n) override { +        bool expr_root = m_expr_root; +        m_expr_root = false; +        m_os << "if let "; +        print_pattern(n.m_pattern); +        m_os << " = "; +        AST::NodeVisitor::visit(n.m_value); +         +        visit_if_common(expr_root, n.m_true, n.m_false); +    } +    void visit_if_common(bool expr_root, const ::std::unique_ptr<AST::ExprNode>& tv, const ::std::unique_ptr<AST::ExprNode>& fv) +    {          if( expr_root )          {              m_os << "\n"; @@ -164,15 +179,16 @@ public:          {              m_os << " ";          } -        AST::NodeVisitor::visit(n.m_true); -        if(n.m_false.get()) + +        AST::NodeVisitor::visit(tv); +        if(fv.get())          {              if( expr_root )              {                  m_os << "\n";                  m_os << indent() << "else";                  // handle chained if statements nicely -                if( IS(*n.m_false, AST::ExprNode_If) ) { +                if( IS(*fv, AST::ExprNode_If) || IS(*fv, AST::ExprNode_IfLet) ) {                      m_expr_root = true;                      m_os << " ";                  } @@ -183,7 +199,7 @@ public:              {                  m_os << " else ";              } -            AST::NodeVisitor::visit(n.m_false); +            AST::NodeVisitor::visit(fv);          }      }      virtual void visit(AST::ExprNode_Integer& n) override { diff --git a/src/parse/expr.cpp b/src/parse/expr.cpp index 2ae94794..7fb41b0f 100644 --- a/src/parse/expr.cpp +++ b/src/parse/expr.cpp @@ -16,6 +16,7 @@ ExprNodeP Parse_ExprBlockNode(TokenStream& lex);  ExprNodeP Parse_Stmt(TokenStream& lex, bool& opt_semicolon);
  ExprNodeP Parse_Expr0(TokenStream& lex);
  ExprNodeP Parse_ExprBlocks(TokenStream& lex);
 +ExprNodeP Parse_IfStmt(TokenStream& lex);
  ExprNodeP Parse_Expr1(TokenStream& lex);
  AST::Expr Parse_Expr(TokenStream& lex, bool const_only)
 @@ -175,7 +176,9 @@ AST::Pattern Parse_PatternReal_Path(TokenStream& lex, AST::Path path)      Token tok;
      ::std::vector<AST::Pattern> child_pats;
      do {
 -        child_pats.push_back( Parse_Pattern(lex) );
 +        AST::Pattern pat = Parse_Pattern(lex);
 +        DEBUG("pat = " << pat);
 +        child_pats.push_back( ::std::move(pat) );
      } while( GET_TOK(tok, lex) == TOK_COMMA );
      CHECK_TOK(tok, TOK_PAREN_CLOSE);
      return child_pats;
 @@ -251,6 +254,9 @@ ExprNodeP Parse_Stmt(TokenStream& lex, bool& opt_semicolon)          throw ParseError::Todo("for");
      case TOK_RWORD_WHILE:
          throw ParseError::Todo("while");
 +    case TOK_RWORD_IF:
 +        opt_semicolon = true;
 +        return Parse_IfStmt(lex);
      default:
          lex.putback(tok);
          return Parse_Expr0(lex);
 @@ -299,11 +305,17 @@ ExprNodeP Parse_Expr0(TokenStream& lex)  ExprNodeP Parse_IfStmt(TokenStream& lex)
  {
      TRACE_FUNCTION;
 +    SET_PARSE_FLAG(lex, disallow_struct_literal);
      Token   tok;
      ExprNodeP cond;
 +    AST::Pattern    pat;
 +    bool if_let = false;
      if( GET_TOK(tok, lex) == TOK_RWORD_LET ) {
 -        throw ParseError::Todo("if let");
 +        if_let = true;
 +        pat = Parse_Pattern(lex);
 +        GET_CHECK_TOK(tok, lex, TOK_EQUAL);
 +        cond = Parse_Expr0(lex);
      }
      else {
          lex.putback(tok);
 @@ -332,7 +344,10 @@ ExprNodeP Parse_IfStmt(TokenStream& lex)          lex.putback(tok);
      }
 -    return NEWNODE( AST::ExprNode_If, ::std::move(cond), ::std::move(code), ::std::move(altcode) );
 +    if( if_let )
 +        return NEWNODE( AST::ExprNode_IfLet, ::std::move(pat), ::std::move(cond), ::std::move(code), ::std::move(altcode) );
 +    else
 +        return NEWNODE( AST::ExprNode_If, ::std::move(cond), ::std::move(code), ::std::move(altcode) );
  }
  ExprNodeP Parse_Expr_Match(TokenStream& lex)
 @@ -479,9 +494,11 @@ LEFTASSOC(Parse_Expr8, Parse_Expr9,  // 9: Add / Subtract
  LEFTASSOC(Parse_Expr9, Parse_Expr10,
      case TOK_PLUS:
 -        throw ParseError::Todo("expr - add");
 +        rv = NEWNODE( AST::ExprNode_BinOp, AST::ExprNode_BinOp::ADD, ::std::move(rv), next(lex));
 +        break;
      case TOK_DASH:
 -        throw ParseError::Todo("expr - sub");
 +        rv = NEWNODE( AST::ExprNode_BinOp, AST::ExprNode_BinOp::SUB, ::std::move(rv), next(lex));
 +        break;
  )
  // 10: Cast
  LEFTASSOC(Parse_Expr10, Parse_Expr11,
 @@ -563,6 +580,37 @@ ExprNodeP Parse_ExprFC(TokenStream& lex)      }
  }
 +ExprNodeP Parse_ExprVal_StructLiteral(TokenStream& lex, AST::Path path)
 +{
 +    TRACE_FUNCTION;
 +    Token   tok;
 +
 +    // Braced structure literal
 +    // - A series of 0 or more pairs of <ident>: <expr>,
 +    // - '..' <expr>
 +    ::std::vector< ::std::pair< ::std::string, ::std::unique_ptr<AST::ExprNode>> >  items;
 +    while( GET_TOK(tok, lex) == TOK_IDENT )
 +    {
 +        ::std::string   name = tok.str();
 +        GET_CHECK_TOK(tok, lex, TOK_COLON);
 +        ExprNodeP   val = Parse_Expr0(lex);
 +        items.push_back( ::std::make_pair(::std::move(name), ::std::move(val)) );
 +        if( GET_TOK(tok,lex) == TOK_BRACE_CLOSE )
 +            break;
 +        CHECK_TOK(tok, TOK_COMMA);
 +    }
 +    ExprNodeP    base_val;
 +    if( tok.type() == TOK_DOUBLE_DOT )
 +    {
 +        // default
 +        base_val = Parse_Expr0(lex);
 +        GET_TOK(tok, lex);
 +    }
 +    CHECK_TOK(tok, TOK_BRACE_CLOSE);
 +    
 +    return NEWNODE( AST::ExprNode_StructLiteral, path, ::std::move(base_val), ::std::move(items) );
 +}
 +
  ExprNodeP Parse_ExprVal(TokenStream& lex)
  {
      TRACE_FUNCTION;
 @@ -580,37 +628,13 @@ ExprNodeP Parse_ExprVal(TokenStream& lex)          path = Parse_Path(lex, true, PATH_GENERIC_EXPR);
          switch( GET_TOK(tok, lex) )
          {
 -        case TOK_BRACE_OPEN: {
 -            // Braced structure literal
 -            // - A series of 0 or more pairs of <ident>: <expr>,
 -            // - '..' <expr>
 -            ::std::vector< ::std::pair< ::std::string, ::std::unique_ptr<AST::ExprNode>> >  items;
 -            while( GET_TOK(tok, lex) == TOK_IDENT )
 -            {
 -                ::std::string   name = tok.str();
 -                GET_CHECK_TOK(tok, lex, TOK_COLON);
 -                ExprNodeP   val = Parse_Expr0(lex);
 -                items.push_back( ::std::make_pair(::std::move(name), ::std::move(val)) );
 -                if( GET_TOK(tok,lex) == TOK_BRACE_CLOSE )
 -                    break;
 -                CHECK_TOK(tok, TOK_COMMA);
 -            }
 -            ExprNodeP    base_val;
 -            if( tok.type() == TOK_DOUBLE_DOT )
 -            {
 -                // default
 -                base_val = Parse_Expr0(lex);
 -                GET_TOK(tok, lex);
 -            }
 -            CHECK_TOK(tok, TOK_BRACE_CLOSE);
 -            return NEWNODE( AST::ExprNode_StructLiteral, path, ::std::move(base_val), ::std::move(items) );
 -            }
 -        case TOK_PAREN_OPEN: {
 -            lex.putback(tok);
 +        case TOK_PAREN_OPEN:
              // Function call
 -            ::std::vector<ExprNodeP> args = Parse_ParenList(lex);
 -            return NEWNODE( AST::ExprNode_CallPath, ::std::move(path), ::std::move(args) );
 -            }
 +            lex.putback(tok);
 +            return NEWNODE( AST::ExprNode_CallPath, ::std::move(path), Parse_ParenList(lex) );
 +        case TOK_BRACE_OPEN:
 +            if( !CHECK_PARSE_FLAG(lex, disallow_struct_literal) )
 +                return Parse_ExprVal_StructLiteral(lex, ::std::move(path));
          default:
              // Value
              lex.putback(tok);
 @@ -634,6 +658,7 @@ ExprNodeP Parse_ExprVal(TokenStream& lex)          }
          else
          {
 +            CLEAR_PARSE_FLAG(lex, disallow_struct_literal);
              lex.putback(tok);
              ExprNodeP rv = Parse_Expr0(lex);
 diff --git a/src/parse/lex.hpp b/src/parse/lex.hpp index d28b0afd..41bac795 100644 --- a/src/parse/lex.hpp +++ b/src/parse/lex.hpp @@ -56,20 +56,49 @@ struct Position  };  extern ::std::ostream& operator<<(::std::ostream& os, const Position& p); +/// State the parser needs to pass down via a second channel. +struct ParseState +{ +    bool disallow_struct_literal = false; +}; +  class TokenStream  {      bool    m_cache_valid;      Token   m_cache; +    ParseState  m_parse_state;  public:      TokenStream();      virtual ~TokenStream();      Token   getToken();      void    putback(Token tok);      virtual Position getPosition() const = 0; +     +    ParseState& parse_state() { return m_parse_state; } +      protected:      virtual Token   realGetToken() = 0;  }; +class SavedParseState +{ +    TokenStream&    m_lex; +    ParseState  m_state; +public: +    SavedParseState(TokenStream& lex, ParseState state): +        m_lex(lex), +        m_state(state) +    {} +    ~SavedParseState() +    { +        m_lex.parse_state() = m_state; +    } +}; + +#define SET_PARSE_FLAG(lex, flag)    SavedParseState(lex, lex.parse_state()); lex.parse_state().flag = true +#define CLEAR_PARSE_FLAG(lex, flag)    SavedParseState(lex, lex.parse_state()); lex.parse_state().flag = false +#define CHECK_PARSE_FLAG(lex, flag) (lex.parse_state().flag == true) +  class Lexer  {      ::std::ifstream m_istream; diff --git a/src/parse/parseerror.cpp b/src/parse/parseerror.cpp index ed7a845c..b0674c07 100644 --- a/src/parse/parseerror.cpp +++ b/src/parse/parseerror.cpp @@ -24,6 +24,11 @@ ParseError::Todo::Todo(::std::string message):  {
      ::std::cout << "Todo(" << message << ")" << ::std::endl;
  }
 +ParseError::Todo::Todo(const TokenStream& lex, ::std::string message):
 +    m_message(message)
 +{
 +    ::std::cout << lex.getPosition() << ": Todo(" << message << ")" << ::std::endl;
 +}
  ParseError::Todo::~Todo() throw()
  {
  }
 diff --git a/src/parse/parseerror.hpp b/src/parse/parseerror.hpp index 33c02a92..5868f629 100644 --- a/src/parse/parseerror.hpp +++ b/src/parse/parseerror.hpp @@ -37,6 +37,7 @@ class Todo:      ::std::string   m_message;
  public:
      Todo(::std::string message);
 +    Todo(const TokenStream& lex, ::std::string message);
      virtual ~Todo() throw ();
  };
 diff --git a/src/parse/root.cpp b/src/parse/root.cpp index f5f48132..e3d0ac0a 100644 --- a/src/parse/root.cpp +++ b/src/parse/root.cpp @@ -12,12 +12,23 @@ extern AST::Pattern Parse_Pattern(TokenStream& lex);  ::std::vector<TypeRef> Parse_Path_GenericList(TokenStream& lex)
  {
      TRACE_FUNCTION;
 +    Token   tok;
      ::std::vector<TypeRef>  types;
 -    Token   tok;
 +    ::std::vector< ::std::string>   lifetimes;
      do {
 -        types.push_back( Parse_Type(lex) );
 +        switch(GET_TOK(tok, lex))
 +        {
 +        case TOK_LIFETIME:
 +            lifetimes.push_back( tok.str() );
 +            break;
 +        default:
 +            lex.putback(tok);
 +            types.push_back( Parse_Type(lex) );
 +            break;
 +        }
      } while( GET_TOK(tok, lex) == TOK_COMMA );
 +
      // HACK: Split >> into >
      if(tok.type() == TOK_DOUBLE_GT) {
          lex.putback(Token(TOK_GT));
 @@ -25,6 +36,8 @@ extern AST::Pattern Parse_Pattern(TokenStream& lex);      else {
          CHECK_TOK(tok, TOK_GT);
      }
 +    
 +    
      return types;
  }
 @@ -293,14 +306,18 @@ AST::Function Parse_FunctionDef(TokenStream& lex, bool allow_no_code=false)      }
      AST::Function::Class    fcn_class = AST::Function::CLASS_UNBOUND;
 +    AST::Function::Arglist  args;
 +
      GET_CHECK_TOK(tok, lex, TOK_PAREN_OPEN);
      GET_TOK(tok, lex);
      if( tok.type() == TOK_AMP )
      {
          // By-reference method
 +        ::std::string   lifetime;
          if( GET_TOK(tok, lex) == TOK_LIFETIME )
          {
 -            throw ParseError::Todo("Lifetimes on self in methods");
 +            lifetime = tok.str();
 +            GET_TOK(tok, lex);
          }
          if( tok.type() == TOK_RWORD_MUT )
          {
 @@ -312,6 +329,8 @@ AST::Function Parse_FunctionDef(TokenStream& lex, bool allow_no_code=false)              CHECK_TOK(tok, TOK_RWORD_SELF);
              fcn_class = AST::Function::CLASS_REFMETHOD;
          }
 +        DEBUG("TODO: UFCS / self lifetimes");
 +        //args.push_back( ::std::make_pair( AST::Pattern(), TypeRef(TypeRef::TagReference(), lifetime, (fcn_class == AST::Function::CLASS_MUTMETHOD), ) ) );
          GET_TOK(tok, lex);
      }
      else if( tok.type() == TOK_RWORD_SELF )
 @@ -325,10 +344,17 @@ AST::Function Parse_FunctionDef(TokenStream& lex, bool allow_no_code=false)          // Unbound method
      }
 -    AST::Function::Arglist  args;
      if( tok.type() != TOK_PAREN_CLOSE )
      {
 -        lex.putback(tok);
 +        // Comma after self
 +        if( fcn_class != AST::Function::CLASS_UNBOUND )
 +        {
 +            CHECK_TOK(tok, TOK_COMMA);
 +        }
 +        else {
 +            lex.putback(tok);
 +        }
 +        
          // Argument list
          do {
              AST::Pattern pat = Parse_Pattern(lex);
 @@ -992,6 +1018,7 @@ void Parse_ModRoot(Preproc& lex, AST::Crate& crate, AST::Module& mod, LList<AST:                  {
                      throw ParseError::Unexpected(lex, tok);
                  }
 +                crate.load_extern_crate(path);
                  mod.add_ext_crate(path, name);
                  GET_CHECK_TOK(tok, lex, TOK_SEMICOLON);
                  break; }
 | 
