@@ -228,4 +228,81 @@ mod lib_tests {
228228 let result = parse_expr ( "parallel 4 do x + 1 end" ) ;
229229 assert ! ( result. is_ok( ) , "Failed to parse parallel end: {:?}" , result. err( ) ) ;
230230 }
231+
232+ #[ test]
233+ fn test_parse_field_access ( ) {
234+ let result = parse_expr ( "record.field" ) ;
235+ assert ! ( result. is_ok( ) , "Failed to parse field access: {:?}" , result. err( ) ) ;
236+ match result. unwrap ( ) {
237+ bet_syntax:: ast:: Expr :: Field ( _, field) => {
238+ assert_eq ! ( field. node. as_str( ) , "field" ) ;
239+ }
240+ other => panic ! ( "Expected Field, got {:?}" , other) ,
241+ }
242+ }
243+
244+ #[ test]
245+ fn test_parse_chained_field_access ( ) {
246+ let result = parse_expr ( "a.b.c" ) ;
247+ assert ! ( result. is_ok( ) , "Failed to parse chained field access: {:?}" , result. err( ) ) ;
248+ // Should parse as (a.b).c
249+ match result. unwrap ( ) {
250+ bet_syntax:: ast:: Expr :: Field ( base, field_c) => {
251+ assert_eq ! ( field_c. node. as_str( ) , "c" ) ;
252+ match & base. node {
253+ bet_syntax:: ast:: Expr :: Field ( _, field_b) => {
254+ assert_eq ! ( field_b. node. as_str( ) , "b" ) ;
255+ }
256+ other => panic ! ( "Expected inner Field, got {:?}" , other) ,
257+ }
258+ }
259+ other => panic ! ( "Expected Field, got {:?}" , other) ,
260+ }
261+ }
262+
263+ #[ test]
264+ fn test_parse_index_access ( ) {
265+ let result = parse_expr ( "arr.[0]" ) ;
266+ assert ! ( result. is_ok( ) , "Failed to parse index access: {:?}" , result. err( ) ) ;
267+ match result. unwrap ( ) {
268+ bet_syntax:: ast:: Expr :: Index ( _, _) => { }
269+ other => panic ! ( "Expected Index, got {:?}" , other) ,
270+ }
271+ }
272+
273+ #[ test]
274+ fn test_parse_field_then_index ( ) {
275+ let result = parse_expr ( "record.items.[0]" ) ;
276+ assert ! ( result. is_ok( ) , "Failed to parse field then index: {:?}" , result. err( ) ) ;
277+ // Should parse as (record.items).[0]
278+ match result. unwrap ( ) {
279+ bet_syntax:: ast:: Expr :: Index ( base, _) => {
280+ match & base. node {
281+ bet_syntax:: ast:: Expr :: Field ( _, field) => {
282+ assert_eq ! ( field. node. as_str( ) , "items" ) ;
283+ }
284+ other => panic ! ( "Expected inner Field, got {:?}" , other) ,
285+ }
286+ }
287+ other => panic ! ( "Expected Index, got {:?}" , other) ,
288+ }
289+ }
290+
291+ #[ test]
292+ fn test_parse_field_access_in_binop ( ) {
293+ // Field access should have higher precedence than binary operators
294+ let result = parse_expr ( "a.x + b.y" ) ;
295+ assert ! ( result. is_ok( ) , "Failed to parse field in binop: {:?}" , result. err( ) ) ;
296+ match result. unwrap ( ) {
297+ bet_syntax:: ast:: Expr :: BinOp ( bet_syntax:: ast:: BinOp :: Add , _, _) => { }
298+ other => panic ! ( "Expected BinOp(Add, ...), got {:?}" , other) ,
299+ }
300+ }
301+
302+ #[ test]
303+ fn test_parse_field_access_in_match ( ) {
304+ // Field access on match scrutinee (keyword form)
305+ let result = parse_expr ( "match x.y a -> 1; b -> 2 end" ) ;
306+ assert ! ( result. is_ok( ) , "Failed to parse field in match: {:?}" , result. err( ) ) ;
307+ }
231308}
0 commit comments