~starkingdoms/starkingdoms

db1274d4c9c6a4e78cce2f225e1894a85d76c5ac — ghostlyzsh 1 year, 4 months ago d4a3468
array, subscript
3 files changed, 75 insertions(+), 18 deletions(-)

M kabel/grammar.ebnf
M kabel/src/lexer.rs
M kabel/src/parser.rs
M kabel/grammar.ebnf => kabel/grammar.ebnf +6 -2
@@ 34,9 34,13 @@ term = factor { , ( "+" | "-" ) , factor } ;

factor = unary { , ( "*" | "/" ) , unary } ;

unary = ( ( "!" | "-" ) , unary ) | primary ;
unary = ( ( "!" | "-" ) , unary ) | subscript ;

primary = identifier | member | call | number | string | group ;
subscript = primary , { "[" , expression , "]" , }

primary = identifier | array | member | call | number | string | group ;

array = "[" , { expression , "," ? } , "]" ;

member = identifier , "." ,  { ( identifier | call ) , "." ? } ;


M kabel/src/lexer.rs => kabel/src/lexer.rs +11 -0
@@ 74,6 74,14 @@ impl Lexer {
                self.output.push(token!(self, TokenType::RightBrace));
                self.start = self.current;
            }
            b'[' => {
                self.output.push(token!(self, TokenType::LeftSquare));
                self.start = self.current;
            }
            b']' => {
                self.output.push(token!(self, TokenType::RightSquare));
                self.start = self.current;
            }
            b'.' => {
                self.output.push(token!(self, TokenType::Period));
                self.start = self.current;


@@ 184,6 192,7 @@ impl Lexer {
                        self.read_char();
                    }
                    self.output.push(token!(self, TokenType::Ident(content)));
                    self.start = self.current;
                } else if c.is_ascii_digit() {
                    let mut number = (c as char).to_string();
                    while self.peek().is_ascii_digit() {


@@ 256,6 265,8 @@ pub enum TokenType {
    RightParen,
    LeftBrace,
    RightBrace,
    LeftSquare,
    RightSquare,
    Period,
    Comma,
    Semicolon,

M kabel/src/parser.rs => kabel/src/parser.rs +58 -16
@@ 126,11 126,7 @@ impl Parser {
                column: return_ident.column,
            })
        } else {
            return Err(unexpected_token!(
                self,
                "Expected ; found {}",
                semicolon
            ));
            return Err(unexpected_token!(self, "Expected ; found {}", semicolon));
        }
    }



@@ 177,7 173,7 @@ impl Parser {
                ast_type: ASTType::Break,
                start: break_ident.start,
                end: semicolon.end,
                line: break_ident.line, 
                line: break_ident.line,
                column: break_ident.column,
            })
        } else {


@@ 193,7 189,7 @@ impl Parser {
                ast_type: ASTType::Continue,
                start: continue_ident.start,
                end: semicolon.end,
                line: continue_ident.line, 
                line: continue_ident.line,
                column: continue_ident.column,
            })
        } else {


@@ 625,7 621,30 @@ impl Parser {
            }
        }

        Ok(self.primary()?)
        self.subscript()
    }
    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 {
            self.read_token()?;
            let expr = self.expression()?;
            let right_brace = self.read_token()?;
            if let TokenType::RightSquare = right_brace.token_type {
                primary = AST {
                    ast_type: ASTType::Subscript(Box::new(primary.clone()), Box::new(expr)),
                    start: primary.start,
                    end: right_brace.end,
                    line: primary.line,
                    column: primary.column,
                };
            } else {
                return Err(unexpected_token!(self, "Expected ] found {}", right_brace));
            }
        }

        Ok(primary)
    }
    pub fn primary(&mut self) -> Result<AST, KabelError> {
        let token = self.read_token()?;


@@ 667,7 686,10 @@ impl Parser {
                });
            }
            TokenType::LeftParen => {
                return Ok(self.group(token)?);
                return self.group(token);
            }
            TokenType::LeftSquare => {
                return self.array(token);
            }
            _ => {
                return Err(unexpected_token!(self, "Unexpected token {}", token));


@@ 675,6 697,24 @@ impl Parser {
        }
    }

    pub fn array(&mut self, left_square: Token) -> Result<AST, KabelError> {
        let mut expressions = Vec::new();
        while self.peek()?.token_type != TokenType::RightSquare {
            expressions.push(self.expression()?);
            if let TokenType::Comma = self.peek()?.token_type {
                self.read_token()?;
            }
        }
        let right_square = self.read_token()?;
        Ok(AST {
            ast_type: ASTType::Lit(Lit::Array(expressions)),
            start: left_square.start,
            end: right_square.end,
            line: left_square.line,
            column: left_square.column,
        })
    }

    pub fn member(&mut self, ident: Token) -> Result<AST, KabelError> {
        if let TokenType::Ident(first) = ident.token_type {
            let mut expr: AST = lit!(Ident, first, ident);


@@ 823,17 863,18 @@ pub enum ASTType {
    Program(Vec<AST>),

    // 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
    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
    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
    Decl(Box<AST>, Box<AST>), // identifier, expression
    Subscript(Box<AST>, Box<AST>),
    Binary(Box<AST>, BinOp, Box<AST>),
    Unary(UnOp, Box<AST>),



@@ 849,6 890,7 @@ pub enum Lit {
    Ident(String),
    Num(f32),
    Str(String),
    Array(Vec<AST>),
}

#[derive(Debug, Clone, Copy)]