~starkingdoms/starkingdoms

24160e4edc4a7c5fb01735650a8a1f4363725c18 — ghostlyzsh 1 year, 4 months ago db1274d
for
2 files changed, 56 insertions(+), 3 deletions(-)

M kabel/grammar.ebnf
M kabel/src/parser.rs
M kabel/grammar.ebnf => kabel/grammar.ebnf +3 -1
@@ 1,12 1,14 @@
program = { statement } ;

statement = function | return | loop | while | if | expression_statement ;
statement = function | return | loop | while | for | break | continue
                | if | expression_statement ;

function = "function" , identifier , "(" , { identifier , "," , } ")" , block
return = "return" , expression , ";" ;

loop = "loop" , block ;
while = "while" , "(" , expression , ")" , block ;
for = "for" , "(" , [ expression ] , ";" , [ expression ] , ";" , [ expression ] , ")" , block
break = "break" , ";" ;
continue = "continue" , ";" ;


M kabel/src/parser.rs => kabel/src/parser.rs +53 -2
@@ 52,6 52,7 @@ impl Parser {
                "return" => self.return_statement(),
                "loop" => self.loop_statement(),
                "while" => self.while_statement(),
                "for" => self.for_statement(),
                "break" => self.break_statement(),
                "continue" => self.continue_statement(),
                "if" => self.if_statement(),


@@ 165,6 166,56 @@ impl Parser {
        }
    }

    pub fn for_statement(&mut self) -> Result<AST , KabelError> {
        let for_ident = self.read_token()?;
        let left_paren = self.read_token()?;
        if let TokenType::LeftParen = left_paren.token_type {
            let expression1;
            if let TokenType::Semicolon = self.peek()?.token_type {
                expression1 = None;
            } else {
                expression1 = Some(self.expression()?);
            }
            let semicolon = self.read_token()?;
            if let TokenType::Semicolon = semicolon.token_type {
                let expression2;
                if let TokenType::Semicolon = self.peek()?.token_type {
                    expression2 = None;
                } else {
                    expression2 = Some(self.expression()?);
                }
                let semicolon = self.read_token()?;
                if let TokenType::Semicolon = semicolon.token_type {
                    let expression3;
                    if let TokenType::RightParen = self.peek()?.token_type {
                        expression3 = None;
                    } else {
                        expression3 = Some(self.expression()?);
                    }
                    let right_paren = self.read_token()?;
                    if let TokenType::RightParen = right_paren.token_type {
                        let block = self.block()?;
                        return Ok(AST {
                            ast_type: ASTType::For(Box::new(expression1), Box::new(expression2), Box::new(expression3), Box::new(block.clone())),
                            start: for_ident.start,
                            end: block.end,
                            line: for_ident.line,
                            column: for_ident.column,
                        });
                    } else {
                        return Err(unexpected_token!(self, "Expected ) found {}", right_paren));
                    }
                } else {
                    return Err(unexpected_token!(self, "Expected ; found {}", semicolon));
                }
            } else {
                return Err(unexpected_token!(self, "Expected ; found {}", semicolon));
            }
        } else {
            return Err(unexpected_token!(self, "Expected ( found {}", left_paren));
        }
    }

    pub fn break_statement(&mut self) -> Result<AST, KabelError> {
        let break_ident = self.read_token()?;
        let semicolon = self.read_token()?;


@@ 626,8 677,7 @@ impl Parser {
    pub fn subscript(&mut self) -> Result<AST, KabelError> {
        let mut primary = self.primary()?;

        while self.current < self.input.len() &&
            self.peek()?.token_type == TokenType::LeftSquare {
        while self.current < self.input.len() && self.peek()?.token_type == TokenType::LeftSquare {
            self.read_token()?;
            let expr = self.expression()?;
            let right_brace = self.read_token()?;


@@ 867,6 917,7 @@ pub enum ASTType {
    Return(Option<Box<AST>>),               // expression
    Loop(Box<AST>),                         // block
    While(Box<AST>, Box<AST>),              // condition, block
    For(Box<Option<AST>>, Box<Option<AST>>, Box<Option<AST>>, Box<AST>), // expr1, expr2, expr3, block
    Break,
    Continue,
    If(Box<AST>, Box<AST>, Option<Box<AST>>), // condition, block, else/else if