lunarity-parser 0.2.1

A high performance Solidity language Parser
use toolshed::list::GrowableList;

use ast::*;
use Parser;
use lexer::Token;

impl<'ast> Parser<'ast> {
    pub fn inline_assembly_block<B>(&mut self) -> Option<Node<'ast, B>>
    where
        B: From<InlineAssemblyBlock<'ast>> + Copy,
    {
        let start = self.start_then_advance();
        let items = GrowableList::new();

        while let Some(item) = self.assembly_item() {
            items.push(self.arena, item);
        }

        let end = self.expect_end(Token::BraceClose);

        self.node_at(start, end, InlineAssemblyBlock {
            items: items.as_list()
        })
    }

    fn assembly_item(&mut self) -> Option<AssemblyItemNode<'ast>> {
        match self.lexer.token {
            Token::BraceOpen  => self.inline_assembly_block(),
            Token::Identifier => self.assembly_identifier(),
            _                 => None,
        }
    }

    fn assembly_identifier(&mut self) -> Option<AssemblyItemNode<'ast>> {
        let (start, end) = self.loc();
        let identifier = self.lexer.slice();

        self.lexer.advance();

        if self.allow(Token::AssemblyBind) {
            let id   = self.node_at(start, end, identifier);
            let init = expect!(self, self.functional_assembly_expression());

            return self.node_at(start, init.end, AssemblyAssignment {
                id,
                init,
            });
        }

        self.node_at(start, end, identifier)
    }

    fn functional_assembly_expression(&mut self) -> Option<FunctionalAssemblyExpressionNode<'ast>> {
        let id = self.expect_str_node(Token::Identifier);

        self.expect(Token::ParenOpen);

        let arguments = GrowableList::new();

        while let Some(item) = self.assembly_item() {
            arguments.push(self.arena, item);
        }

        let end = self.expect_end(Token::ParenClose);

        self.node_at(id.start, end, FunctionalAssemblyExpression {
            id,
            arguments: arguments.as_list()
        })
    }
}