~starkingdoms/starkingdoms

d4a3468798c6b762747794875f371a7c02545db3 — ghostlyzsh 1 year, 4 months ago c4a401a
return, break, continue
2 files changed, 83 insertions(+), 9 deletions(-)

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

statement = function | loop | while | if | expression_statement ;
statement = function | return | loop | while | if | expression_statement ;

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

loop = "loop" , block ;

while = "while" , "(" , expression , ")" , block ;
break = "break" , ";" ;
continue = "continue" , ";" ;

if = "if" , "(" , expression , ")" , block [ , "else" , ( if | block ) ] ;


M kabel/src/parser.rs => kabel/src/parser.rs +79 -7
@@ 49,8 49,11 @@ impl Parser {
        match self.peek()?.token_type {
            TokenType::Ident(ident) => match ident.as_str() {
                "function" => self.function_statement(),
                "return" => self.return_statement(),
                "loop" => self.loop_statement(),
                "while" => self.while_statement(),
                "break" => self.break_statement(),
                "continue" => self.continue_statement(),
                "if" => self.if_statement(),
                _ => self.expression_statement(),
            },


@@ 100,6 103,37 @@ impl Parser {
        }
    }

    pub fn return_statement(&mut self) -> Result<AST, KabelError> {
        let return_ident = self.read_token()?;
        if let TokenType::Semicolon = self.peek()?.token_type {
            let semicolon = self.read_token()?;
            return Ok(AST {
                ast_type: ASTType::Return(None),
                start: return_ident.start,
                end: semicolon.end,
                line: return_ident.line,
                column: return_ident.column,
            });
        }
        let expression = self.expression()?;
        let semicolon = self.read_token()?;
        if let TokenType::Semicolon = semicolon.token_type {
            Ok(AST {
                ast_type: ASTType::Return(Some(Box::new(expression))),
                start: return_ident.start,
                end: semicolon.end,
                line: return_ident.line,
                column: return_ident.column,
            })
        } else {
            return Err(unexpected_token!(
                self,
                "Expected ; found {}",
                semicolon
            ));
        }
    }

    pub fn loop_statement(&mut self) -> Result<AST, KabelError> {
        let loop_ident = self.read_token()?;
        let block = self.block()?;


@@ 135,6 169,38 @@ impl Parser {
        }
    }

    pub fn break_statement(&mut self) -> Result<AST, KabelError> {
        let break_ident = self.read_token()?;
        let semicolon = self.read_token()?;
        if let TokenType::Semicolon = semicolon.token_type {
            Ok(AST {
                ast_type: ASTType::Break,
                start: break_ident.start,
                end: semicolon.end,
                line: break_ident.line, 
                column: break_ident.column,
            })
        } else {
            Err(unexpected_token!(self, "Expected ; found {}", semicolon))
        }
    }

    pub fn continue_statement(&mut self) -> Result<AST, KabelError> {
        let continue_ident = self.read_token()?;
        let semicolon = self.read_token()?;
        if let TokenType::Semicolon = semicolon.token_type {
            Ok(AST {
                ast_type: ASTType::Continue,
                start: continue_ident.start,
                end: semicolon.end,
                line: continue_ident.line, 
                column: continue_ident.column,
            })
        } else {
            Err(unexpected_token!(self, "Expected ; found {}", semicolon))
        }
    }

    pub fn if_statement(&mut self) -> Result<AST, KabelError> {
        let if_ident = self.read_token()?;
        let left_paren = self.read_token()?;


@@ 756,16 822,22 @@ pub struct AST {
pub enum ASTType {
    Program(Vec<AST>),

    Function(Box<AST>, Vec<AST>, Box<AST>), // name, args, block
    Loop(Box<AST>),                         // block
    While(Box<AST>, Box<AST>),              // condition, block
    If(Box<AST>, Box<AST>, Option<Box<AST>>), // condition, block, else/else if
    Block(Vec<AST>),                        // statements

    Decl(Box<AST>, Box<AST>), // identifier, expression
    // statements
    Function(Box<AST>, Vec<AST>, Box<AST>),     // name, args, block
    Return(Option<Box<AST>>),                   // expression
    Loop(Box<AST>),                             // block
    While(Box<AST>, Box<AST>),                  // condition, block
    Break,
    Continue,
    If(Box<AST>, Box<AST>, Option<Box<AST>>),   // condition, block, else/else if
    Block(Vec<AST>),                            // statements

    // expressions
    Decl(Box<AST>, Box<AST>),                   // identifier, expression
    Binary(Box<AST>, BinOp, Box<AST>),
    Unary(UnOp, Box<AST>),

    // primary
    Group(Box<AST>),
    Lit(Lit),
    Call(Box<AST>, Vec<AST>),