fn parse_mixfix_elements(&mut self) -> PResult<(bool, Vec<MixfixParam>)> {
        let mut mode_given = false;
        let mut elements = Vec::new();

        loop {
            match *self.lookahead()? {
                Token::Id(ref s) => {
                    self.eat();
                    let e = MixfixParam::Name(Part::Id(Interned::new(s)));
                    elements.push(e);
                },
                Token::Op(ref s) => {
                    self.eat();
                    let e = MixfixParam::Name(Part::Op(Interned::new(s)));
                    elements.push(e);
                },
                Token::Bang => {
                    self.eat();
                    let e = MixfixParam::Name(Part::Op(Interned::new("!")));
                    elements.push(e);
                },
                Token::Question => {
                    self.eat();
                    let e = MixfixParam::Name(Part::Op(Interned::new("?")));
                    elements.push(e);
                },
                Token::Lp => {
                    let p = located!(self, {
                        self.eat();
                        match *self.lookahead()? {
                            Token::Lp => {
                                self.eat();
                                match *self.lookahead()? {
                                    Token::Bang => {
                                        mode_given = true;
                                        self.eat();
                                        let e = self.parse_tuple()?;
                                        consume!(self, Token::Rp)?;
                                        consume!(self, Token::Rp)?;
                                        Param {
                                            attr: ParamAttr {
                                                assoc: Assoc::Assoc,
                                                by_name: CallingConv::ByValue,
                                                mode: CallingMode::Output,
                                            },
                                            pat: Box::new(e),
                                        }
                                    },
                                    Token::Question => {
                                        mode_given = true;
                                        self.eat();
                                        let e = self.parse_tuple()?;
                                        consume!(self, Token::Rp)?;
                                        consume!(self, Token::Rp)?;
                                        Param {
                                            attr: ParamAttr {
                                                assoc: Assoc::Assoc,
                                                by_name: CallingConv::ByValue,
                                                mode: CallingMode::Input,
                                            },
                                            pat: Box::new(e),
                                        }
                                    },
                                    _ => {
                                        if mode_given {
                                            return self.error_here("Invalid function header. Either all attributes, or none, must have a mode.")
                                        }
                                        let e = self.parse_tuple()?;
                                        consume!(self, Token::Rp)?;
                                        consume!(self, Token::Rp)?;
                                        Param {
                                            attr: ParamAttr {
                                                assoc: Assoc::Assoc,
                                                by_name: CallingConv::ByValue,
                                                mode: CallingMode::Input,
                                            },
                                            pat: Box::new(e),
                                        }
                                    },
                                }
                            },
                            Token::Bang => {
                                mode_given = true;
                                self.eat();
                                let e = self.parse_tuple()?;
                                consume!(self, Token::Rp)?;
                                Param {
                                    attr: ParamAttr {
                                        assoc: Assoc::NonAssoc,
                                        by_name: CallingConv::ByValue,
                                        mode: CallingMode::Output,
                                    },
                                    pat: Box::new(e),
                                }
                            },
                            Token::Question => {
                                mode_given = true;
                                self.eat();
                                let e = self.parse_tuple()?;
                                consume!(self, Token::Rp)?;
                                Param {
                                    attr: ParamAttr {
                                        assoc: Assoc::NonAssoc,
                                        by_name: CallingConv::ByValue,
                                        mode: CallingMode::Input,
                                    },
                                    pat: Box::new(e),
                                }
                            },
                            _ => {
                                if mode_given {
                                    return self.error_here("Invalid function header. Either all attributes, or none, must have a mode.")
                                }
                                let e = self.parse_tuple()?;
                                consume!(self, Token::Rp)?;
                                Param {
                                    attr: ParamAttr {
                                        assoc: Assoc::NonAssoc,
                                        by_name: CallingConv::ByValue,
                                        mode: CallingMode::Input,
                                    },
                                    pat: Box::new(e),
                                }
                            },
                        }
                    });
                    elements.push(MixfixParam::Param(p));
                },
                Token::Lc => {
                    let p = located!(self, {
                        self.eat();
                        match *self.lookahead()? {
                            Token::Lc => {
                                self.eat();
                                match *self.lookahead()? {
                                    Token::Bang => {
                                        mode_given = true;
                                        self.eat();
                                        let e = self.parse_tuple()?;
                                        consume!(self, Token::Rc)?;
                                        consume!(self, Token::Rc)?;
                                        Param {
                                            attr: ParamAttr {
                                                assoc: Assoc::Assoc,
                                                by_name: CallingConv::ByName,
                                                mode: CallingMode::Output,
                                            },
                                            pat: Box::new(e),
                                        }
                                    },
                                    Token::Question => {
                                        mode_given = true;
                                        self.eat();
                                        let e = self.parse_tuple()?;
                                        consume!(self, Token::Rc)?;
                                        consume!(self, Token::Rc)?;
                                        Param {
                                            attr: ParamAttr {
                                                assoc: Assoc::Assoc,
                                                by_name: CallingConv::ByName,
                                                mode: CallingMode::Input,
                                            },
                                            pat: Box::new(e),
                                        }
                                    },
                                    _ => {
                                        if mode_given {
                                            return self.error_here("Invalid function header. Either all attributes, or none, must have a mode.")
                                        }
                                        let e = self.parse_tuple()?;
                                        consume!(self, Token::Rc)?;
                                        consume!(self, Token::Rc)?;
                                        Param {
                                            attr: ParamAttr {
                                                assoc: Assoc::Assoc,
                                                by_name: CallingConv::ByName,
                                                mode: CallingMode::Input,
                                            },
                                            pat: Box::new(e),
                                        }
                                    },
                                }
                            },
                            Token::Bang => {
                                mode_given = true;
                                self.eat();
                                let e = self.parse_tuple()?;
                                consume!(self, Token::Rc)?;
                                Param {
                                    attr: ParamAttr {
                                        assoc: Assoc::NonAssoc,
                                        by_name: CallingConv::ByName,
                                        mode: CallingMode::Output,
                                    },
                                    pat: Box::new(e),
                                }
                            },
                            Token::Question => {
                                mode_given = true;
                                self.eat();
                                let e = self.parse_tuple()?;
                                consume!(self, Token::Rc)?;
                                Param {
                                    attr: ParamAttr {
                                        assoc: Assoc::NonAssoc,
                                        by_name: CallingConv::ByName,
                                        mode: CallingMode::Input,
                                    },
                                    pat: Box::new(e),
                                }
                            },
                            _ => {
                                if mode_given {
                                    return self.error_here("Invalid function header. Either all attributes, or none, must have a mode.")
                                }
                                let e = self.parse_tuple()?;
                                consume!(self, Token::Rc)?;
                                Param {
                                    attr: ParamAttr {
                                        assoc: Assoc::NonAssoc,
                                        by_name: CallingConv::ByName,
                                        mode: CallingMode::Input,
                                    },
                                    pat: Box::new(e),
                                }
                            },
                        }
                    });
                    elements.push(MixfixParam::Param(p));
                },
                _ => {
                    break;
                },
            }
        }

        Ok((mode_given, elements))
    }
// returns the vec of mixfix elements plus a bool indicating if any element specified a mode
// (in which case the return must also specify a mode)
returns the vec of mixfix elements plus a bool indicating if any element specified a mode
(in which case the return must also specify a mode)
returns the vec of mixfix elements plus a bool indicating if any element specified a mode ( in which case the return must also specify a mode )
fn parse_mixfix_elements(&mut self) -> PResult<(bool, Vec<MixfixParam>)> {
        let mut mode_given = false;
        let mut elements = Vec::new();
        loop {
            match *self.lookahead()? {
                Token::Id(ref s) => {
                    self.eat();
                    let e = MixfixParam::Name(Part::Id(Interned::new(s)));
                    elements.push(e);
                },
                Token::Op(ref s) => {
                    self.eat();
                    let e = MixfixParam::Name(Part::Op(Interned::new(s)));
                    elements.push(e);
                },
                Token::Bang => {
                    self.eat();
                    let e = MixfixParam::Name(Part::Op(Interned::new("!")));
                    elements.push(e);
                },
                Token::Question => {
                    self.eat();
                    let e = MixfixParam::Name(Part::Op(Interned::new("?")));
                    elements.push(e);
                },
                Token::Lp => {
                    let p = located!(self, {
                        self.eat();
                        match *self.lookahead()? {
                            Token::Lp => {
                                self.eat();
                                match *self.lookahead()? {
                                    Token::Bang => {
                                        mode_given = true;
                                        self.eat();
                                        let e = self.parse_tuple()?;
                                        consume!(self, Token::Rp)?;
                                        consume!(self, Token::Rp)?;
                                        Param {
                                            attr: ParamAttr {
                                                assoc: Assoc::Assoc,
                                                by_name: CallingConv::ByValue,
                                                mode: CallingMode::Output,
                                            },
                                            pat: Box::new(e),
                                        }
                                    },
                                    Token::Question => {
                                        mode_given = true;
                                        self.eat();
                                        let e = self.parse_tuple()?;
                                        consume!(self, Token::Rp)?;
                                        consume!(self, Token::Rp)?;
                                        Param {
                                            attr: ParamAttr {
                                                assoc: Assoc::Assoc,
                                                by_name: CallingConv::ByValue,
                                                mode: CallingMode::Input,
                                            },
                                            pat: Box::new(e),
                                        }
                                    },
                                    _ => {
                                        if mode_given {
                                            return self.error_here("Invalid function header. Either all attributes, or none, must have a mode.")
                                        }
                                        let e = self.parse_tuple()?;
                                        consume!(self, Token::Rp)?;
                                        consume!(self, Token::Rp)?;
                                        Param {
                                            attr: ParamAttr {
                                                assoc: Assoc::Assoc,
                                                by_name: CallingConv::ByValue,
                                                mode: CallingMode::Input,
                                            },
                                            pat: Box::new(e),
                                        }
                                    },
                                }
                            },
                            Token::Bang => {
                                mode_given = true;
                                self.eat();
                                let e = self.parse_tuple()?;
                                consume!(self, Token::Rp)?;
                                Param {
                                    attr: ParamAttr {
                                        assoc: Assoc::NonAssoc,
                                        by_name: CallingConv::ByValue,
                                        mode: CallingMode::Output,
                                    },
                                    pat: Box::new(e),
                                }
                            },
                            Token::Question => {
                                mode_given = true;
                                self.eat();
                                let e = self.parse_tuple()?;
                                consume!(self, Token::Rp)?;
                                Param {
                                    attr: ParamAttr {
                                        assoc: Assoc::NonAssoc,
                                        by_name: CallingConv::ByValue,
                                        mode: CallingMode::Input,
                                    },
                                    pat: Box::new(e),
                                }
                            },
                            _ => {
                                if mode_given {
                                    return self.error_here("Invalid function header. Either all attributes, or none, must have a mode.")
                                }
                                let e = self.parse_tuple()?;
                                consume!(self, Token::Rp)?;
                                Param {
                                    attr: ParamAttr {
                                        assoc: Assoc::NonAssoc,
                                        by_name: CallingConv::ByValue,
                                        mode: CallingMode::Input,
                                    },
                                    pat: Box::new(e),
                                }
                            },
                        }
                    });
                    elements.push(MixfixParam::Param(p));
                },
                Token::Lc => {
                    let p = located!(self, {
                        self.eat();
                        match *self.lookahead()? {
                            Token::Lc => {
                                self.eat();
                                match *self.lookahead()? {
                                    Token::Bang => {
                                        mode_given = true;
                                        self.eat();
                                        let e = self.parse_tuple()?;
                                        consume!(self, Token::Rc)?;
                                        consume!(self, Token::Rc)?;
                                        Param {
                                            attr: ParamAttr {
                                                assoc: Assoc::Assoc,
                                                by_name: CallingConv::ByName,
                                                mode: CallingMode::Output,
                                            },
                                            pat: Box::new(e),
                                        }
                                    },
                                    Token::Question => {
                                        mode_given = true;
                                        self.eat();
                                        let e = self.parse_tuple()?;
                                        consume!(self, Token::Rc)?;
                                        consume!(self, Token::Rc)?;
                                        Param {
                                            attr: ParamAttr {
                                                assoc: Assoc::Assoc,
                                                by_name: CallingConv::ByName,
                                                mode: CallingMode::Input,
                                            },
                                            pat: Box::new(e),
                                        }
                                    },
                                    _ => {
                                        if mode_given {
                                            return self.error_here("Invalid function header. Either all attributes, or none, must have a mode.")
                                        }
                                        let e = self.parse_tuple()?;
                                        consume!(self, Token::Rc)?;
                                        consume!(self, Token::Rc)?;
                                        Param {
                                            attr: ParamAttr {
                                                assoc: Assoc::Assoc,
                                                by_name: CallingConv::ByName,
                                                mode: CallingMode::Input,
                                            },
                                            pat: Box::new(e),
                                        }
                                    },
                                }
                            },
                            Token::Bang => {
                                mode_given = true;
                                self.eat();
                                let e = self.parse_tuple()?;
                                consume!(self, Token::Rc)?;
                                Param {
                                    attr: ParamAttr {
                                        assoc: Assoc::NonAssoc,
                                        by_name: CallingConv::ByName,
                                        mode: CallingMode::Output,
                                    },
                                    pat: Box::new(e),
                                }
                            },
                            Token::Question => {
                                mode_given = true;
                                self.eat();
                                let e = self.parse_tuple()?;
                                consume!(self, Token::Rc)?;
                                Param {
                                    attr: ParamAttr {
                                        assoc: Assoc::NonAssoc,
                                        by_name: CallingConv::ByName,
                                        mode: CallingMode::Input,
                                    },
                                    pat: Box::new(e),
                                }
                            },
                            _ => {
                                if mode_given {
                                    return self.error_here("Invalid function header. Either all attributes, or none, must have a mode.")
                                }
                                let e = self.parse_tuple()?;
                                consume!(self, Token::Rc)?;
                                Param {
                                    attr: ParamAttr {
                                        assoc: Assoc::NonAssoc,
                                        by_name: CallingConv::ByName,
                                        mode: CallingMode::Input,
                                    },
                                    pat: Box::new(e),
                                }
                            },
                        }
                    });
                    elements.push(MixfixParam::Param(p));
                },
                _ => {
                    break;
                },
            }
        }
        Ok((mode_given, elements))
    }
fn parse_mixfix_elements ( & mut self ) -> PResult < ( bool , Vec < MixfixParam > ) > { let mut mode_given = false ; let mut elements = Vec :: new ( ) ; loop { match * self . lookahead ( ) ? { Token :: Id ( ref s ) => { self . eat ( ) ; let e = MixfixParam :: Name ( Part :: Id ( Interned :: new ( s ) ) ) ; elements . push ( e ) ; } , Token :: Op ( ref s ) => { self . eat ( ) ; let e = MixfixParam :: Name ( Part :: Op ( Interned :: new ( s ) ) ) ; elements . push ( e ) ; } , Token :: Bang => { self . eat ( ) ; let e = MixfixParam :: Name ( Part :: Op ( Interned :: new ( " " ) ) ) ; elements . push ( e ) ; } , Token :: Question => { self . eat ( ) ; let e = MixfixParam :: Name ( Part :: Op ( Interned :: new ( " " ) ) ) ; elements . push ( e ) ; } , Token :: Lp => { let p = located ! ( self { self eat ( ) match self lookahead ( ) { Token Lp { self eat ( ) match self lookahead ( ) { Token Bang { mode_given true self eat ( ) let e self parse_tuple ( ) consume ( self Token Rp ) consume ( self Token Rp ) Param { attr ParamAttr { assoc Assoc Assoc by_name CallingConv ByValue mode CallingMode Output } pat Box new ( e ) } } Token Question { mode_given true self eat ( ) let e self parse_tuple ( ) consume ( self Token Rp ) consume ( self Token Rp ) Param { attr ParamAttr { assoc Assoc Assoc by_name CallingConv ByValue mode CallingMode Input } pat Box new ( e ) } } { if mode_given { return self error_here ( " " ) } let e self parse_tuple ( ) consume ( self Token Rp ) consume ( self Token Rp ) Param { attr ParamAttr { assoc Assoc Assoc by_name CallingConv ByValue mode CallingMode Input } pat Box new ( e ) } } } } Token Bang { mode_given true self eat ( ) let e self parse_tuple ( ) consume ( self Token Rp ) Param { attr ParamAttr { assoc Assoc NonAssoc by_name CallingConv ByValue mode CallingMode Output } pat Box new ( e ) } } Token Question { mode_given true self eat ( ) let e self parse_tuple ( ) consume ( self Token Rp ) Param { attr ParamAttr { assoc Assoc NonAssoc by_name CallingConv ByValue mode CallingMode Input } pat Box new ( e ) } } { if mode_given { return self error_here ( " " ) } let e self parse_tuple ( ) consume ( self Token Rp ) Param { attr ParamAttr { assoc Assoc NonAssoc by_name CallingConv ByValue mode CallingMode Input } pat Box new ( e ) } } } } ) ; elements . push ( MixfixParam :: Param ( p ) ) ; } , Token :: Lc => { let p = located ! ( self { self eat ( ) match self lookahead ( ) { Token Lc { self eat ( ) match self lookahead ( ) { Token Bang { mode_given true self eat ( ) let e self parse_tuple ( ) consume ( self Token Rc ) consume ( self Token Rc ) Param { attr ParamAttr { assoc Assoc Assoc by_name CallingConv ByName mode CallingMode Output } pat Box new ( e ) } } Token Question { mode_given true self eat ( ) let e self parse_tuple ( ) consume ( self Token Rc ) consume ( self Token Rc ) Param { attr ParamAttr { assoc Assoc Assoc by_name CallingConv ByName mode CallingMode Input } pat Box new ( e ) } } { if mode_given { return self error_here ( " " ) } let e self parse_tuple ( ) consume ( self Token Rc ) consume ( self Token Rc ) Param { attr ParamAttr { assoc Assoc Assoc by_name CallingConv ByName mode CallingMode Input } pat Box new ( e ) } } } } Token Bang { mode_given true self eat ( ) let e self parse_tuple ( ) consume ( self Token Rc ) Param { attr ParamAttr { assoc Assoc NonAssoc by_name CallingConv ByName mode CallingMode Output } pat Box new ( e ) } } Token Question { mode_given true self eat ( ) let e self parse_tuple ( ) consume ( self Token Rc ) Param { attr ParamAttr { assoc Assoc NonAssoc by_name CallingConv ByName mode CallingMode Input } pat Box new ( e ) } } { if mode_given { return self error_here ( " " ) } let e self parse_tuple ( ) consume ( self Token Rc ) Param { attr ParamAttr { assoc Assoc NonAssoc by_name CallingConv ByName mode CallingMode Input } pat Box new ( e ) } } } } ) ; elements . push ( MixfixParam :: Param ( p ) ) ; } , _ => { break ; } , } } Ok ( ( mode_given , elements ) ) }
returns the vec of mixfix elements plus a bool indicating if any element specified a mode
(in which case the return must also specify a mode)
returns the vec of mixfix elements plus a bool indicating if any element specified a mode ( in which case the return must also specify a mode )
&mut self
&mut self