Browse Source

feat: struct field access in expressions

structs
Garrit Franke 3 years ago
parent
commit
b1f106caf6
  1. 18
      src/parser/rules.rs
  2. 8
      tests/structs.sb

18
src/parser/rules.rs

@ -194,7 +194,9 @@ impl Parser {
let state = Statement::Exp(self.parse_bin_op(Some(expr))?); let state = Statement::Exp(self.parse_bin_op(Some(expr))?);
Ok(state) Ok(state)
} else if self.peek_token(TokenKind::Dot).is_ok() { } else if self.peek_token(TokenKind::Dot).is_ok() {
Ok(Statement::Exp(self.parse_field_access(Expression::Variable(ident))?)) Ok(Statement::Exp(
self.parse_field_access(Expression::Variable(ident))?,
))
} else { } else {
Ok(Statement::Exp(expr)) Ok(Statement::Exp(expr))
} }
@ -305,6 +307,15 @@ impl Parser {
Err(_) => arr, Err(_) => arr,
} }
} }
TokenKind::Dot => {
let lhs = Expression::Variable(val);
let expr = self.parse_field_access(lhs)?;
dbg!(&expr);
match BinOp::try_from(self.peek()?.kind) {
Ok(_) => self.parse_bin_op(Some(expr))?,
Err(_) => expr,
}
}
_ => match BinOp::try_from(self.peek()?.kind) { _ => match BinOp::try_from(self.peek()?.kind) {
Ok(_) => self.parse_bin_op(Some(Expression::Variable(token.raw)))?, Ok(_) => self.parse_bin_op(Some(Expression::Variable(token.raw)))?,
Err(_) => Expression::Variable(val), Err(_) => Expression::Variable(val),
@ -327,10 +338,7 @@ impl Parser {
fn parse_field_access(&mut self, lhs: Expression) -> Result<Expression, String> { fn parse_field_access(&mut self, lhs: Expression) -> Result<Expression, String> {
self.match_token(TokenKind::Dot)?; self.match_token(TokenKind::Dot)?;
let field = self.match_identifier()?; let field = self.match_identifier()?;
match BinOp::try_from(self.peek()?.kind) { Ok(Expression::FieldAccess(Box::new(lhs), field))
Ok(_) => self.parse_bin_op(Some(lhs)),
Err(_) => return Ok(Expression::FieldAccess(Box::new(lhs), field)),
}
} }
/// TODO: Cleanup /// TODO: Cleanup

8
tests/structs.sb

@ -30,10 +30,16 @@ fn test_initialization() {
fn test_simple_field_access() { fn test_simple_field_access() {
let user: User = user_stub() let user: User = user_stub()
user.username = "Foo Bar" user.username = "Foo Bar"
// assert(user.username == "Foo Bar") }
fn test_field_access_in_function_call() {
let user: User = user_stub()
user.username = "Bar"
assert(user.username == "Bar")
} }
fn main() { fn main() {
test_initialization() test_initialization()
test_simple_field_access() test_simple_field_access()
test_field_access_in_function_call()
} }
Loading…
Cancel
Save