~starkingdoms/starkingdoms

45ab0ed8dfd72666c4936a53b981f5f365c0e345 — ghostlyzsh 1 year, 4 months ago 8275afd
ternary operators
3 files changed, 167 insertions(+), 20 deletions(-)

M kabel/grammar.ebnf
M kabel/src/lexer.rs
M kabel/src/parser.rs
M kabel/grammar.ebnf => kabel/grammar.ebnf +3 -1
@@ 23,7 23,9 @@ expression = assignment | declaration ;
declaration = "var" , identifier , "=" , expression ;

assignment = ( identifier , ( "=" | "+=" | "-=" | "*="
    | "/=" | "%=" | "&=" | "^=" | "|=" ) , assignment ) | logical_or;
    | "/=" | "%=" | "&=" | "^=" | "|=" ) , assignment ) | ternary ;

ternary = logical_or [ , "?" , expression , ":" , expression ] ;

logical_or = logical_and { , "||" , logical_and } ;


M kabel/src/lexer.rs => kabel/src/lexer.rs +13 -3
@@ 147,6 147,14 @@ impl Lexer {
                self.output.push(token!(self, TokenType::Semicolon));
                self.start = self.current;
            }
            ':' => {
                self.output.push(token!(self, TokenType::Colon));
                self.start = self.current;
            }
            '?' => {
                self.output.push(token!(self, TokenType::Question));
                self.start = self.current;
            }
            '^' => {
                if self.peek() == '=' {
                    self.read_char();


@@ 360,9 368,6 @@ pub enum TokenType {
    RightBrace,
    LeftSquare,
    RightSquare,
    Period,
    Comma,
    Semicolon,
    Equal,
    EqualEqual,
    Bang,


@@ 379,6 384,11 @@ pub enum TokenType {
    OrOr,
    Caret,
    CaretEqual,
    Period,
    Comma,
    Semicolon,
    Colon,
    Question,

    Ident(String),
    Str(String),

M kabel/src/parser.rs => kabel/src/parser.rs +151 -16
@@ 382,7 382,18 @@ impl Parser {
                        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(expr.clone())), expr, expr).clone())
                            Box::new(
                                ast!(
                                    ASTType::Binary(
                                        Box::new(lit!(Ident, name, ident)),
                                        BinOp::Add,
                                        Box::new(expr.clone())
                                    ),
                                    expr,
                                    expr
                                )
                                .clone()
                            )
                        ),
                        ident,
                        expr


@@ 392,7 403,18 @@ impl Parser {
                        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(expr.clone())), expr, expr).clone())
                            Box::new(
                                ast!(
                                    ASTType::Binary(
                                        Box::new(lit!(Ident, name, ident)),
                                        BinOp::Sub,
                                        Box::new(expr.clone())
                                    ),
                                    expr,
                                    expr
                                )
                                .clone()
                            )
                        ),
                        ident,
                        expr


@@ 402,7 424,18 @@ impl Parser {
                        ASTType::Binary(
                            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())
                            Box::new(
                                ast!(
                                    ASTType::Binary(
                                        Box::new(lit!(Ident, name, ident)),
                                        BinOp::Mul,
                                        Box::new(expr.clone())
                                    ),
                                    expr,
                                    expr
                                )
                                .clone()
                            )
                        ),
                        ident,
                        expr


@@ 412,7 445,18 @@ impl Parser {
                        ASTType::Binary(
                            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())
                            Box::new(
                                ast!(
                                    ASTType::Binary(
                                        Box::new(lit!(Ident, name.clone(), ident)),
                                        BinOp::Div,
                                        Box::new(expr.clone())
                                    ),
                                    expr,
                                    expr
                                )
                                .clone()
                            )
                        ),
                        ident,
                        expr


@@ 422,7 466,18 @@ impl Parser {
                        ASTType::Binary(
                            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())
                            Box::new(
                                ast!(
                                    ASTType::Binary(
                                        Box::new(lit!(Ident, name, ident)),
                                        BinOp::Mod,
                                        Box::new(expr.clone())
                                    ),
                                    expr,
                                    expr
                                )
                                .clone()
                            )
                        ),
                        ident,
                        expr


@@ 432,7 487,18 @@ impl Parser {
                        ASTType::Binary(
                            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())
                            Box::new(
                                ast!(
                                    ASTType::Binary(
                                        Box::new(lit!(Ident, name, ident)),
                                        BinOp::BitAnd,
                                        Box::new(expr.clone())
                                    ),
                                    expr,
                                    expr
                                )
                                .clone()
                            )
                        ),
                        ident,
                        expr


@@ 442,7 508,18 @@ impl Parser {
                        ASTType::Binary(
                            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())
                            Box::new(
                                ast!(
                                    ASTType::Binary(
                                        Box::new(lit!(Ident, name, ident)),
                                        BinOp::BitXor,
                                        Box::new(expr.clone())
                                    ),
                                    expr,
                                    expr
                                )
                                .clone()
                            )
                        ),
                        ident,
                        expr


@@ 452,7 529,18 @@ impl Parser {
                        ASTType::Binary(
                            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())
                            Box::new(
                                ast!(
                                    ASTType::Binary(
                                        Box::new(lit!(Ident, name, ident)),
                                        BinOp::BitOr,
                                        Box::new(expr.clone())
                                    ),
                                    expr,
                                    expr
                                )
                                .clone()
                            )
                        ),
                        ident,
                        expr


@@ 460,10 548,28 @@ impl Parser {
                }
            }
            self.current -= 1;
            return self.logical_or();
            return self.ternary();
        }

        return self.logical_or();
        return self.ternary();
    }

    pub fn ternary(&mut self) -> Result<AST, KabelError> {
        let condition = self.logical_or()?;

        if let TokenType::Question = self.peek()?.token_type {
            self.read_token()?;
            let true_expr = self.expression()?;
            if let TokenType::Colon = self.peek()?.token_type {
                self.read_token()?;
                let false_expr = self.expression()?;
                return Ok(ast!(ASTType::Ternary(Box::new(condition.clone()), Box::new(true_expr), Box::new(false_expr.clone())), condition, false_expr));
            } else {
                return Err(unexpected_token!(self, "Expected : found {}", self.token));
            }
        }

        Ok(condition)
    }

    pub fn logical_or(&mut self) -> Result<AST, KabelError> {


@@ 837,13 943,41 @@ impl Parser {
        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))
                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))
                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");


@@ 942,6 1076,7 @@ pub enum ASTType {

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