Browse Source

feat: assignment operators (#10)

* feat: assignment operators

* docs: use assignment operators

Co-authored-by: Garrit Franke <garrit@slashdev.space>
clippy-fix
Garrit Franke 8 months ago
committed by GitHub
parent
commit
6a6547b9c7
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      docs/concepts/control-flow.md
  2. 4
      examples/bubblesort.sb
  3. 2
      lib/stdio.sb
  4. 4
      src/generator/js.rs
  5. 36
      src/lexer/mod.rs
  6. 8
      src/parser/node_type.rs
  7. 4
      src/parser/rules.rs
  8. 2
      src/parser/tests.rs
  9. 8
      tests/operator_assignments.sb

2
docs/concepts/control-flow.md

@ -113,7 +113,7 @@ fn main() {
while index < 5 {
println("the value is: " + a[index])
index = index + 1
index += 1
}
}
```

4
examples/bubblesort.sb

@ -14,10 +14,10 @@ fn main() {
arr[d+1] = swap
}
d = d + 1
d += 1
}
c = c + 1
c += 1
}
println(arr)

2
lib/stdio.sb

@ -13,7 +13,7 @@ fn println(msg: string) {
fn len(arr: int[]): int {
let c: int = 0
while arr[c] {
c = c + 1
c += 1
}
return c

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)

2
src/parser/tests.rs

@ -463,7 +463,7 @@ fn test_array_access_in_loop() {
while i < 5 {
println(x[i])
i = i + 1
i += 1
}
}
";

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