~starkingdoms/starkingdoms

8275afd2a78ba022ad6a32b762b55aa6b2583eaa — ghostlyzsh 1 year, 4 months ago 71a2bac
increment and decrement, desugaring
3 files changed, 67 insertions(+), 55 deletions(-)

M kabel/grammar.ebnf
M kabel/src/lexer.rs
M kabel/src/parser.rs
M kabel/grammar.ebnf => kabel/grammar.ebnf +4 -2
@@ 41,11 41,11 @@ term = factor { , ( "+" | "-" ) , factor } ;

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

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

subscript = primary , { "[" , expression , "]" , }

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

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



@@ 53,6 53,8 @@ member = identifier , "." ,  { ( identifier | call ) , "." ? } ;

call = ( identifier , "(" , { expression, "," ? } , ")" ) ;

incdec = identifier , [ "++" , "--" ] ;

group = "(" , expression , ")" ;

identifier = alphabetic , { alphabetic | digit } ;

M kabel/src/lexer.rs => kabel/src/lexer.rs +20 -9
@@ 22,15 22,15 @@ impl Lexer {
    pub fn new(input: String) -> Self {
        let mut keywords = HashMap::new();
        keywords.insert("function".to_string(), TokenType::Function);
        keywords.insert("return".to_string(),   TokenType::Return);
        keywords.insert("loop".to_string(),     TokenType::Loop);
        keywords.insert("while".to_string(),    TokenType::While);
        keywords.insert("for".to_string(),      TokenType::For);
        keywords.insert("break".to_string(),    TokenType::Break);
        keywords.insert("return".to_string(), TokenType::Return);
        keywords.insert("loop".to_string(), TokenType::Loop);
        keywords.insert("while".to_string(), TokenType::While);
        keywords.insert("for".to_string(), TokenType::For);
        keywords.insert("break".to_string(), TokenType::Break);
        keywords.insert("continue".to_string(), TokenType::Continue);
        keywords.insert("if".to_string(),       TokenType::If);
        keywords.insert("else".to_string(),     TokenType::Else);
        keywords.insert("var".to_string(),      TokenType::Var);
        keywords.insert("if".to_string(), TokenType::If);
        keywords.insert("else".to_string(), TokenType::Else);
        keywords.insert("var".to_string(), TokenType::Var);
        Self {
            input: input.chars().collect(),
            start: 0,


@@ 53,6 53,10 @@ impl Lexer {
                    self.read_char();
                    self.output.push(token!(self, TokenType::PlusEqual));
                    self.start = self.current;
                } else if self.peek() == '+' {
                    self.read_char();
                    self.output.push(token!(self, TokenType::PlusPlus));
                    self.start = self.current;
                } else {
                    self.output.push(token!(self, TokenType::Plus));
                    self.start = self.current;


@@ 63,6 67,10 @@ impl Lexer {
                    self.read_char();
                    self.output.push(token!(self, TokenType::MinusEqual));
                    self.start = self.current;
                } else if self.peek() == '-' {
                    self.read_char();
                    self.output.push(token!(self, TokenType::MinusMinus));
                    self.start = self.current;
                } else {
                    self.output.push(token!(self, TokenType::Minus));
                    self.start = self.current;


@@ 253,7 261,8 @@ impl Lexer {
                        self.read_char();
                    }
                    if self.keywords.contains_key(&content) {
                        self.output.push(token!(self, self.keywords.get(&content).unwrap().clone()));
                        self.output
                            .push(token!(self, self.keywords.get(&content).unwrap().clone()));
                    } else {
                        self.output.push(token!(self, TokenType::Ident(content)));
                    }


@@ 340,8 349,10 @@ pub enum TokenType {
    Percent,
    PercentEqual,
    Plus,
    PlusPlus,
    PlusEqual,
    Minus,
    MinusMinus,
    MinusEqual,
    LeftParen,
    RightParen,

M kabel/src/parser.rs => kabel/src/parser.rs +43 -44
@@ 366,19 366,8 @@ impl Parser {
            | TokenType::OrEqual = self.peek()?.token_type
            {
                let binop = self.read_token()?;
                let expr = self.assignment()?;
                let expr = self.expression()?;
                if binop.token_type == TokenType::Equal {
                    /*return Ok(AST {
                        ast_type: ASTType::Binary(
                            Box::new(lit!(Ident, name, ident)),
                            BinOp::Asn,
                            Box::new(expr.clone()),
                        ),
                        start: ident.start,
                        end: expr.end,
                        line: ident.line,
                        column: ident.column,
                    });*/
                    return Ok(ast!(
                        ASTType::Binary(
                            Box::new(lit!(Ident, name, ident)),


@@ 391,9 380,9 @@ impl Parser {
                } else if binop.token_type == TokenType::PlusEqual {
                    return Ok(ast!(
                        ASTType::Binary(
                            Box::new(lit!(Ident, name, ident)),
                            BinOp::AddAsn,
                            Box::new(expr.clone())
                            Box::new(lit!(Ident, name.clone(), ident)),
                            BinOp::Asn,
                            Box::new(ast!(ASTType::Binary(Box::new(lit!(Ident, name, ident)), BinOp::Add, Box::new(expr.clone())), expr, expr).clone())
                        ),
                        ident,
                        expr


@@ 401,9 390,9 @@ impl Parser {
                } else if binop.token_type == TokenType::MinusEqual {
                    return Ok(ast!(
                        ASTType::Binary(
                            Box::new(lit!(Ident, name, ident)),
                            BinOp::SubAsn,
                            Box::new(expr.clone())
                            Box::new(lit!(Ident, name.clone(), ident)),
                            BinOp::Asn,
                            Box::new(ast!(ASTType::Binary(Box::new(lit!(Ident, name, ident)), BinOp::Sub, Box::new(expr.clone())), expr, expr).clone())
                        ),
                        ident,
                        expr


@@ 411,9 400,9 @@ impl Parser {
                } else if binop.token_type == TokenType::StarEqual {
                    return Ok(ast!(
                        ASTType::Binary(
                            Box::new(lit!(Ident, name, ident)),
                            BinOp::MulAsn,
                            Box::new(expr.clone())
                            Box::new(lit!(Ident, name.clone(), ident)),
                            BinOp::Asn,
                            Box::new(ast!(ASTType::Binary(Box::new(lit!(Ident, name, ident)), BinOp::Mul, Box::new(expr.clone())), expr, expr).clone())
                        ),
                        ident,
                        expr


@@ 421,9 410,9 @@ impl Parser {
                } else if binop.token_type == TokenType::SlashEqual {
                    return Ok(ast!(
                        ASTType::Binary(
                            Box::new(lit!(Ident, name, ident)),
                            BinOp::DivAsn,
                            Box::new(expr.clone())
                            Box::new(lit!(Ident, name.clone(), ident)),
                            BinOp::Asn,
                            Box::new(ast!(ASTType::Binary(Box::new(lit!(Ident, name.clone(), ident)), BinOp::Div, Box::new(expr.clone())), expr, expr).clone())
                        ),
                        ident,
                        expr


@@ 431,9 420,9 @@ impl Parser {
                } else if binop.token_type == TokenType::PercentEqual {
                    return Ok(ast!(
                        ASTType::Binary(
                            Box::new(lit!(Ident, name, ident)),
                            BinOp::ModAsn,
                            Box::new(expr.clone())
                            Box::new(lit!(Ident, name.clone(), ident)),
                            BinOp::Asn,
                            Box::new(ast!(ASTType::Binary(Box::new(lit!(Ident, name, ident)), BinOp::Mod, Box::new(expr.clone())), expr, expr).clone())
                        ),
                        ident,
                        expr


@@ 441,9 430,9 @@ impl Parser {
                } else if binop.token_type == TokenType::AndEqual {
                    return Ok(ast!(
                        ASTType::Binary(
                            Box::new(lit!(Ident, name, ident)),
                            BinOp::AndAsn,
                            Box::new(expr.clone())
                            Box::new(lit!(Ident, name.clone(), ident)),
                            BinOp::Asn,
                            Box::new(ast!(ASTType::Binary(Box::new(lit!(Ident, name, ident)), BinOp::BitAnd, Box::new(expr.clone())), expr, expr).clone())
                        ),
                        ident,
                        expr


@@ 451,9 440,9 @@ impl Parser {
                } else if binop.token_type == TokenType::CaretEqual {
                    return Ok(ast!(
                        ASTType::Binary(
                            Box::new(lit!(Ident, name, ident)),
                            BinOp::XorAsn,
                            Box::new(expr.clone())
                            Box::new(lit!(Ident, name.clone(), ident)),
                            BinOp::Asn,
                            Box::new(ast!(ASTType::Binary(Box::new(lit!(Ident, name, ident)), BinOp::BitXor, Box::new(expr.clone())), expr, expr).clone())
                        ),
                        ident,
                        expr


@@ 461,9 450,9 @@ impl Parser {
                } else {
                    return Ok(ast!(
                        ASTType::Binary(
                            Box::new(lit!(Ident, name, ident)),
                            BinOp::OrAsn,
                            Box::new(expr.clone())
                            Box::new(lit!(Ident, name.clone(), ident)),
                            BinOp::Asn,
                            Box::new(ast!(ASTType::Binary(Box::new(lit!(Ident, name, ident)), BinOp::BitOr, Box::new(expr.clone())), expr, expr).clone())
                        ),
                        ident,
                        expr


@@ 744,6 733,9 @@ impl Parser {
                    if let TokenType::Period = self.peek()?.token_type {
                        return self.member(token);
                    }
                    if let TokenType::PlusPlus | TokenType::MinusMinus = self.peek()?.token_type {
                        return self.incdec(token);
                    }
                }
                return Ok(lit!(Ident, ident.clone(), token));
            }


@@ 841,6 833,21 @@ impl Parser {
        }
        panic!("Call logic broke");
    }
    pub fn incdec(&mut self, ident: Token) -> Result<AST, KabelError> {
        if let TokenType::Ident(name) = ident.token_type {
            let oper = self.read_token()?;
            if oper.token_type == TokenType::PlusPlus {
                return Ok(ast!(ASTType::Binary(Box::new(lit!(Ident, name.clone(), ident)), BinOp::Asn,
                    Box::new(ast!(ASTType::Binary(Box::new(lit!(Ident, name, ident)), BinOp::Add,
                    Box::new(lit!(Num, 1., oper))), oper, oper))), ident, oper))
            } else {
                return Ok(ast!(ASTType::Binary(Box::new(lit!(Ident, name.clone(), ident)), BinOp::Asn,
                    Box::new(ast!(ASTType::Binary(Box::new(lit!(Ident, name, ident)), BinOp::Sub,
                    Box::new(lit!(Num, 1., oper))), oper, oper))), ident, oper))
            }
        }
        panic!("Inc/dec logic broke");
    }

    pub fn group(&mut self, left_paren: Token) -> Result<AST, KabelError> {
        let expr = self.expression()?;


@@ 965,14 972,6 @@ pub enum BinOp {
    BitXor,
    BitOr,
    Asn,
    AddAsn,
    SubAsn,
    MulAsn,
    DivAsn,
    ModAsn,
    AndAsn,
    XorAsn,
    OrAsn,
    Eq,
    Ne,
    Gr,