~starkingdoms/starkingdoms

bc4391c57c6bf4ebe8f2a0101f99617264b39e4d — ghostlyzsh 1 year, 4 months ago d593bc7
while and loop statements
2 files changed, 79 insertions(+), 12 deletions(-)

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

statement = if | while | ( expression , ";" ) ;
statement = function | loop | while | if | expression_statement ;

function = "function" , identifier , "(" , { identifier , "," , } ")" , block

(* implemented *)
loop = "loop" , block ;

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

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

block = "{" , { statement } , "}" ;

expression_statement = expression , ";" ;

expression = assignment | declaration ;

declaration = "var" , identifier , "=" , expression ;

M kabel/src/parser.rs => kabel/src/parser.rs +75 -10
@@ 47,13 47,66 @@ impl Parser {

    pub fn statement(&mut self) -> Result<AST, KabelError> {
        match self.peek()?.token_type {
            TokenType::Ident(ident) => {
                match ident.as_str() {
                    "if" => self.if_statement(),
                    _ => self.expression_statement()
                }
            TokenType::Ident(ident) => match ident.as_str() {
                "loop" => self.loop_statement(),
                "while" => self.while_statement(),
                "if" => self.if_statement(),
                _ => self.expression_statement(),
            },
            _ => self.expression_statement(),
        }
    }

    pub fn loop_statement(&mut self) -> Result<AST, KabelError> {
        let loop_ident = self.read_token()?;
        let block = self.block()?;
        Ok(AST {
            ast_type: ASTType::Loop(Box::new(block.clone())),
            start: loop_ident.start,
            end: block.end,
            line: loop_ident.line,
            column: loop_ident.column,
        })
    }

    pub fn while_statement(&mut self) -> Result<AST, KabelError> {
        let while_ident = self.read_token()?;
        let left_paren = self.read_token()?;
        if let TokenType::LeftParen = left_paren.token_type {
            let condition = 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::While(Box::new(condition), Box::new(block.clone())),
                    start: while_ident.start,
                    end: block.end,
                    line: while_ident.line,
                    column: while_ident.column,
                });
            } else {
                return Err(KabelError::new(
                    ErrorKind::UnexpectedToken,
                    format!(
                        "Expected ) found {}",
                        self.text[right_paren.start..right_paren.end].to_string()
                    ),
                    right_paren.line,
                    right_paren.column,
                    self.text[right_paren.line_start..right_paren.end].to_string(),
                ));
            }
            _ => self.expression_statement()
        } else {
            return Err(KabelError::new(
                ErrorKind::UnexpectedToken,
                format!(
                    "Expected ( found {}",
                    self.text[left_paren.start..left_paren.end].to_string()
                ),
                left_paren.line,
                left_paren.column,
                self.text[left_paren.line_start..left_paren.end].to_string(),
            ));
        }
    }



@@ 72,7 125,11 @@ impl Parser {
                            if let TokenType::LeftBrace = self.peek()?.token_type {
                                let else_block = self.block()?;
                                return Ok(AST {
                                    ast_type: ASTType::If(Box::new(condition), Box::new(block.clone()), Some(Box::new(else_block.clone()))),
                                    ast_type: ASTType::If(
                                        Box::new(condition),
                                        Box::new(block.clone()),
                                        Some(Box::new(else_block.clone())),
                                    ),
                                    start: if_ident.start,
                                    end: else_block.end,
                                    line: if_ident.line,


@@ 84,7 141,11 @@ impl Parser {
                                if content == "if" {
                                    let else_if = self.if_statement()?;
                                    return Ok(AST {
                                        ast_type: ASTType::If(Box::new(condition), Box::new(block.clone()), Some(Box::new(else_if.clone()))),
                                        ast_type: ASTType::If(
                                            Box::new(condition),
                                            Box::new(block.clone()),
                                            Some(Box::new(else_if.clone())),
                                        ),
                                        start: if_ident.start,
                                        end: else_if.end,
                                        line: if_ident.line,


@@ 95,11 156,13 @@ impl Parser {
                                        ErrorKind::UnexpectedToken,
                                        format!(
                                            "Expected if found {}",
                                            self.text[else_if_ident.start..else_if_ident.end].to_string()
                                            self.text[else_if_ident.start..else_if_ident.end]
                                                .to_string()
                                        ),
                                        else_if_ident.line,
                                        else_if_ident.column,
                                        self.text[else_if_ident.line_start..else_if_ident.end].to_string(),
                                        self.text[else_if_ident.line_start..else_if_ident.end]
                                            .to_string(),
                                    ));
                                }
                            }


@@ 752,6 815,8 @@ pub struct AST {
pub enum ASTType {
    Program(Vec<AST>),

    Loop(Box<AST>),
    While(Box<AST>, Box<AST>),
    If(Box<AST>, Box<AST>, Option<Box<AST>>),
    Block(Vec<AST>),