~starkingdoms/starkingdoms

e291ccb936429d3fc3b021ce56c4f9b8b72e75d2 — ghostlyzsh 1 year, 4 months ago ea219ec
logical or and logical and
3 files changed, 64 insertions(+), 2 deletions(-)

M kabel/grammar.ebnf
M kabel/src/lexer.rs
M kabel/src/parser.rs
M kabel/grammar.ebnf => kabel/grammar.ebnf +1 -1
@@ 14,11 14,11 @@ declaration = "var" , identifier , "=" , expression ;

assignment = { identifier , "=" , } logical_or ;

(* implemented *)
logical_or = logical_and { , "||" , logical_and } ;

logical_and = equality { , "&&" , equality } ;

(* implemented *)
equality = comparison { , ( "==" | "!=" ) , comparison } ;

comparison = term { , ( ">" | "<" | ">=" | "<=" ) , term } ;

M kabel/src/lexer.rs => kabel/src/lexer.rs +24 -0
@@ 59,6 59,26 @@ impl Lexer {
                self.output.push(token!(self, TokenType::RightParen));
                self.start = self.current;
            }
            b'|' => {
                if self.peek() == b'|' {
                    self.read_char();
                    self.output.push(token!(self, TokenType::OrOr));
                    self.start = self.current;
                } else {
                    self.output.push(token!(self, TokenType::Or));
                    self.start = self.current;
                }
            }
            b'&' => {
                if self.peek() == b'&' {
                    self.read_char();
                    self.output.push(token!(self, TokenType::AndAnd));
                    self.start = self.current;
                } else {
                    self.output.push(token!(self, TokenType::And));
                    self.start = self.current;
                }
            }
            b'=' => {
                if self.peek() == b'=' {
                    self.read_char();


@@ 214,6 234,10 @@ pub enum TokenType {
    GreaterEqual,
    Less,
    LessEqual,
    And,
    AndAnd,
    Or,
    OrOr,

    Ident(String),
    Str(String),

M kabel/src/parser.rs => kabel/src/parser.rs +39 -1
@@ 45,10 45,46 @@ impl Parser {
    }

    pub fn expression(&mut self) -> Result<AST, KabelError> {
        let equality = self.equality()?;
        let equality = self.logical_or()?;
        Ok(equality)
    }

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

        while self.current < self.input.len()
            && self.peek()?.token_type == TokenType::OrOr {
            self.read_token()?;
            let right = self.logical_and()?;
            left = AST {
                ast_type: ASTType::Binary(Box::new(left.clone()), BinOp::Or, Box::new(right.clone())),
                start: left.start,
                end: right.end,
                line: left.line,
                column: left.column,
            };
        }

        Ok(left)
    }
    pub fn logical_and(&mut self) -> Result<AST, KabelError> {
        let mut left = self.equality()?;

        while self.current < self.input.len()
            && self.peek()?.token_type == TokenType::AndAnd {
            self.read_token()?;
            let right = self.equality()?;
            left = AST {
                ast_type: ASTType::Binary(Box::new(left.clone()), BinOp::And, Box::new(right.clone())),
                start: left.start,
                end: right.end,
                line: left.line,
                column: left.column,
            };
        }

        Ok(left)
    }
    pub fn equality(&mut self) -> Result<AST, KabelError> {
        let mut left = self.comparison()?;



@@ 400,6 436,8 @@ pub enum BinOp {
    Ge,
    Ls,
    Le,
    Or,
    And,
}

#[derive(Debug, Clone, Copy)]