Browse Source

feat: struct field assignments

structs
Garrit Franke 3 years ago
parent
commit
e3c8f7124b
  1. 29
      src/parser/rules.rs
  2. 4
      tests/structs.sb

29
src/parser/rules.rs

@ -167,12 +167,18 @@ impl Parser {
TokenKind::Keyword(Keyword::For) => self.parse_for_loop(), TokenKind::Keyword(Keyword::For) => self.parse_for_loop(),
TokenKind::Identifier(_) => { TokenKind::Identifier(_) => {
let ident = self.match_identifier()?; let ident = self.match_identifier()?;
let expr = if self.peek_token(TokenKind::Dot).is_ok() {
self.parse_field_access(Expression::Variable(ident.clone()))?
} else {
Expression::Variable(ident.clone())
};
// TODO: Use match statement
if self.peek_token(TokenKind::BraceOpen).is_ok() { if self.peek_token(TokenKind::BraceOpen).is_ok() {
let state = self.parse_function_call(Some(ident))?; let state = self.parse_function_call(Some(ident))?;
Ok(Statement::Exp(state)) Ok(Statement::Exp(state))
} else if self.peek_token(TokenKind::Assign).is_ok() { } else if self.peek_token(TokenKind::Assign).is_ok() {
let state = self.parse_assignent(Some(Expression::Variable(ident)))?; let state = self.parse_assignent(Some(expr))?;
Ok(state) Ok(state)
} else if self.peek_token(TokenKind::SquareBraceOpen).is_ok() { } else if self.peek_token(TokenKind::SquareBraceOpen).is_ok() {
let expr = self.parse_array_access(Some(ident))?; let expr = self.parse_array_access(Some(ident))?;
@ -187,9 +193,10 @@ impl Parser {
let expr = Expression::Variable(ident); let expr = Expression::Variable(ident);
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() {
Ok(Statement::Exp(self.parse_field_access(Expression::Variable(ident))?))
} else { } else {
let state = Statement::Exp(Expression::Variable(ident)); Ok(Statement::Exp(expr))
Ok(state)
} }
} }
TokenKind::Literal(_) => Ok(Statement::Exp(self.parse_expression()?)), TokenKind::Literal(_) => Ok(Statement::Exp(self.parse_expression()?)),
@ -311,17 +318,21 @@ impl Parser {
}; };
if self.peek_token(TokenKind::Dot).is_ok() { if self.peek_token(TokenKind::Dot).is_ok() {
self.match_token(TokenKind::Dot)?; self.parse_field_access(expr)
let field = self.match_identifier()?;
match BinOp::try_from(self.peek()?.kind) {
Ok(_) => self.parse_bin_op(Some(expr)),
Err(_) => return Ok(Expression::FieldAccess(Box::new(expr), field)),
}
} else { } else {
Ok(expr) Ok(expr)
} }
} }
fn parse_field_access(&mut self, lhs: Expression) -> Result<Expression, String> {
self.match_token(TokenKind::Dot)?;
let field = self.match_identifier()?;
match BinOp::try_from(self.peek()?.kind) {
Ok(_) => self.parse_bin_op(Some(lhs)),
Err(_) => return Ok(Expression::FieldAccess(Box::new(lhs), field)),
}
}
/// TODO: Cleanup /// TODO: Cleanup
fn parse_struct_initialization(&mut self) -> Result<Expression, String> { fn parse_struct_initialization(&mut self) -> Result<Expression, String> {
let name = self.match_identifier()?; let name = self.match_identifier()?;

4
tests/structs.sb

@ -29,8 +29,8 @@ 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") // assert(user.username == "Foo Bar")
} }
fn main() { fn main() {

Loading…
Cancel
Save