Browse Source

Add booleans

github-actions
Garrit Franke 3 years ago
parent
commit
8fe1e42c43
  1. 6
      examples/playground.sb
  2. 2
      src/generator/js.rs
  3. 8
      src/parser/node_type.rs
  4. 11
      src/parser/rules.rs
  5. 32
      src/parser/tests.rs

6
examples/playground.sb

@ -1,6 +1,8 @@
fn main() {
let x = 5 * 2
while x > 0 {
let x = true && false
let y = false && true || true
let z = x && true
while true && x {
return x
}
}

2
src/generator/js.rs

@ -82,6 +82,7 @@ fn generate_expression(expr: Expression) -> String {
Expression::Int(val) => val.to_string(),
Expression::Variable(val) | Expression::Str(val) => val,
Expression::Char(_) => todo!(),
Expression::Bool(b) => b.to_string(),
Expression::FunctionCall(name, e) => generate_function_call(name, e),
Expression::Assign(_, _) => todo!(),
Expression::Array(els) => generate_array(els),
@ -157,6 +158,7 @@ fn generate_function_call(func: String, args: Vec<Expression>) -> String {
.map(|arg| match arg {
Expression::Char(c) => c.to_string(),
Expression::Int(i) => i.to_string(),
Expression::Bool(v) => v.to_string(),
Expression::FunctionCall(n, a) => generate_function_call(n, a),
Expression::Str(s) | Expression::Variable(s) => s,
Expression::Assign(_, _) => todo!(),

8
src/parser/node_type.rs

@ -49,6 +49,7 @@ pub enum Expression {
Int(u32),
Str(String),
Char(u8),
Bool(bool),
Array(Vec<Expression>),
FunctionCall(String, Vec<Expression>),
Variable(String),
@ -69,8 +70,13 @@ impl TryFrom<Token> for Expression {
.parse()
.map_err(|_| "Int value could not be parsed")?,
)),
TokenKind::Keyword(Keyword::Boolean) => match token.raw.as_ref() {
"true" => Ok(Expression::Bool(true)),
"false" => Ok(Expression::Bool(false)),
_ => Err("Boolean value could not be parsed".into()),
},
TokenKind::Literal(Value::Str) => Ok(Expression::Str(token.raw)),
_ => panic!("Value could not be parsed"),
_ => Err("Value could not be parsed".into()),
}
}
}

11
src/parser/rules.rs

@ -157,6 +157,15 @@ impl Parser {
fn parse_expression(&mut self) -> Result<Expression, String> {
let token = self.next()?;
match token.kind {
TokenKind::Keyword(Keyword::Boolean) => {
let state = match BinOp::try_from(self.peek()?.kind) {
Ok(_) => self.parse_bin_op(None)?,
Err(_) => {
Expression::Bool(token.raw.parse::<bool>().map_err(|e| e.to_string())?)
}
};
Ok(state)
}
TokenKind::Literal(Value::Int) => {
let state = match BinOp::try_from(self.peek()?.kind) {
Ok(_) => self.parse_bin_op(None)?,
@ -269,7 +278,7 @@ impl Parser {
None => {
let prev = self.prev().ok_or_else(|| "Expected Token")?;
match &prev.kind {
TokenKind::Identifier(_) | TokenKind::Literal(_) => {
TokenKind::Identifier(_) | TokenKind::Literal(_) | TokenKind::Keyword(_) => {
Ok(Expression::try_from(prev)?)
}
_ => Err(self.make_error(TokenKind::Unknown, prev)),

32
src/parser/tests.rs

@ -391,3 +391,35 @@ fn test_basic_while_loop() {
let tree = parse(tokens, Some(raw.to_string()));
assert!(tree.is_ok())
}
#[test]
fn test_while_loop_boolean_expression() {
let raw = "
fn main() {
let x = 5 * 2
while true && x {
return x
}
}
";
let tokens = tokenize(raw);
let tree = parse(tokens, Some(raw.to_string()));
assert!(tree.is_ok())
}
#[test]
fn test_boolean_arithmetic() {
let raw = "
fn main() {
let x = true && false
let y = false && true || true
let z = x && true
while true && x {
return x
}
}
";
let tokens = tokenize(raw);
let tree = parse(tokens, Some(raw.to_string()));
assert!(tree.is_ok())
}

Loading…
Cancel
Save