From 8275afd2a78ba022ad6a32b762b55aa6b2583eaa Mon Sep 17 00:00:00 2001 From: ghostlyzsh Date: Sat, 3 Aug 2024 10:34:56 -0500 Subject: [PATCH] increment and decrement, desugaring --- kabel/grammar.ebnf | 6 ++-- kabel/src/lexer.rs | 29 ++++++++++----- kabel/src/parser.rs | 87 ++++++++++++++++++++++----------------------- 3 files changed, 67 insertions(+), 55 deletions(-) diff --git a/kabel/grammar.ebnf b/kabel/grammar.ebnf index 6a6e5c436f07620bf8115c9780826050ed823a09..5a096b224a82433f46d0668b33fcc3718e823f0b 100644 --- a/kabel/grammar.ebnf +++ b/kabel/grammar.ebnf @@ -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 } ; diff --git a/kabel/src/lexer.rs b/kabel/src/lexer.rs index 9d5a90d121f6a4ef72977eda2a953fd307acb27b..0a6aca6b1a06246ed8e56aab9315af7f8baee94f 100644 --- a/kabel/src/lexer.rs +++ b/kabel/src/lexer.rs @@ -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, diff --git a/kabel/src/parser.rs b/kabel/src/parser.rs index 025cc23aa69966edbaf28bc9c077ae1a85f5cf8c..8ad8935857452aa5a662f82b94795cbf8dcc878f 100644 --- a/kabel/src/parser.rs +++ b/kabel/src/parser.rs @@ -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 { + 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 { 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,