Browse Source

feat: assignment operators

assignment-operators
Garrit Franke 3 years ago
parent
commit
b96ed77156
  1. 4
      src/generator/js.rs
  2. 36
      src/lexer/mod.rs
  3. 8
      src/parser/node_type.rs
  4. 4
      src/parser/rules.rs
  5. 8
      tests/operator_assignments.sb

4
src/generator/js.rs

@ -242,6 +242,10 @@ fn generate_bin_op(left: Expression, op: BinOp, right: Expression) -> String {
BinOp::NotEqual => "!==",
BinOp::Or => "||",
BinOp::Subtraction => "-",
BinOp::AddAssign => "+=",
BinOp::SubtractAssign => "-=",
BinOp::MultiplyAssign => "*=",
BinOp::DivideAssign => "/=",
};
format!(
"({l} {op} {r})",

36
src/lexer/mod.rs

@ -94,6 +94,14 @@ pub enum TokenKind {
And,
/// "||"
Or,
/// "+="
PlusEqual,
/// "-="
MinusEqual,
/// "*="
StarEqual,
/// "/="
SlashEqual,
/// "("
BraceOpen,
/// ")"
@ -193,15 +201,37 @@ impl Cursor<'_> {
c if is_whitespace(c) => self.whitespace(),
'0'..='9' => self.number(),
'"' | '\'' => self.string(),
'+' => Plus,
'-' => Minus,
'*' => Star,
'+' => match self.first() {
'=' => {
self.bump();
PlusEqual
}
_ => Plus,
},
'-' => match self.first() {
'=' => {
self.bump();
MinusEqual
}
_ => Minus,
},
'*' => match self.first() {
'=' => {
self.bump();
StarEqual
}
_ => Star,
},
'%' => Percent,
'/' => match self.first() {
'/' => {
self.bump();
self.comment()
}
'=' => {
self.bump();
SlashEqual
}
_ => Slash,
},
'=' => match self.first() {

8
src/parser/node_type.rs

@ -146,6 +146,10 @@ pub enum BinOp {
NotEqual,
And,
Or,
AddAssign,
SubtractAssign,
MultiplyAssign,
DivideAssign,
}
impl TryFrom<TokenKind> for BinOp {
@ -165,6 +169,10 @@ impl TryFrom<TokenKind> for BinOp {
TokenKind::NotEqual => Ok(BinOp::NotEqual),
TokenKind::And => Ok(BinOp::And),
TokenKind::Or => Ok(BinOp::Or),
TokenKind::PlusEqual => Ok(BinOp::AddAssign),
TokenKind::MinusEqual => Ok(BinOp::SubtractAssign),
TokenKind::StarEqual => Ok(BinOp::MultiplyAssign),
TokenKind::SlashEqual => Ok(BinOp::DivideAssign),
other => Err(format!("Token {:?} cannot be converted into a BinOp", other).into()),
}
}

4
src/parser/rules.rs

@ -152,6 +152,10 @@ impl Parser {
TokenKind::Assign => self.parse_assignent(Some(expr)),
_ => Ok(Statement::Exp(expr)),
}
} else if let Ok(_) = BinOp::try_from(self.peek()?.kind) {
let expr = Expression::Variable(ident.into());
let state = Statement::Exp(self.parse_bin_op(Some(expr))?);
Ok(state)
} else {
let state = Statement::Exp(Expression::Variable(ident.into()));
Ok(state)

8
tests/operator_assignments.sb

@ -0,0 +1,8 @@
fn main() {
let x = 10
x += 1
x -= 2
x *= 2
x /= 2
println(x)
}
Loading…
Cancel
Save