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)]