fortrangoingonforty/fortbite / 871d980

Browse files

resolve segfaults

Authored by espadonne
SHA
871d98008d45b7a07952afd756541c793a9f32f1
Parents
1b5bf50
Tree
98d9cef

1 changed file

StatusFile+-
M src/fortbite_parser_m.f90 108 45
src/fortbite_parser_m.f90modified
@@ -321,51 +321,9 @@ contains
321321
                     call advance(parser)  ! Skip ')'
322322
                     node => create_function_node(func_name)
323323
                 else
324
-                    ! Single argument function - parse one expression  
325
-                    ! Support numbers and negative numbers
326
-                    if (parser%current_token%token_type == TOKEN_NUMBER) then
327
-                        read(parser%current_token%text, *) num_val
328
-                        value = create_scalar(num_val)
329
-                        single_arg => create_literal_node(value)
330
-                        call advance(parser)
331
-                    else if (parser%current_token%token_type == TOKEN_OPERATOR .and. &
332
-                             parser%current_token%text == '-') then
333
-                        ! Handle negative numbers
334
-                        call advance(parser)  ! Skip minus
335
-                        if (parser%current_token%token_type == TOKEN_NUMBER) then
336
-                            read(parser%current_token%text, *) num_val
337
-                            value = create_scalar(-num_val)  ! Make negative
338
-                            single_arg => create_literal_node(value)
339
-                            call advance(parser)
340
-                        else
341
-                            call set_error(parser, 'Expected number after minus sign')
342
-                            return
343
-                        end if
344
-                    else
345
-                        call set_error(parser, 'Function arguments currently support numbers only')
346
-                        return
347
-                    end if
348
-                    
349
-                    if (.not. associated(single_arg)) then
350
-                        call set_error(parser, 'Invalid function argument')
351
-                        return
352
-                    end if
353
-                    
354
-                    if (parser%current_token%token_type == TOKEN_RPAREN) then
355
-                        ! Single argument - create function with one arg
356
-                        call advance(parser)  ! Skip ')'
357
-                        
358
-                        ! Create function node properly
359
-                        allocate(node)
360
-                        node%node_type = AST_FUNCTION_CALL
361
-                        node%function_name = trim(func_name)
362
-                        node%arg_count = 1
363
-                        allocate(node%arguments(1))
364
-                        node%arguments(1)%ptr => single_arg
365
-                    else
366
-                        call set_error(parser, 'Expected closing parenthesis')
367
-                        if (associated(single_arg)) call free_ast(single_arg)
368
-                    end if
324
+                    ! Parse arguments (single or multiple)
325
+                    call parse_function_arguments(parser, func_name, node)
326
+                    if (parser%has_error) return
369327
                 end if
370328
             else
371329
                 ! Variable identifier
@@ -541,4 +499,109 @@ contains
541499
         end if
542500
     end function parse_matrix_literal
543501
     
502
+    !> Parse function arguments (supports single and multiple arguments)
503
+    subroutine parse_function_arguments(parser, func_name, node)
504
+        type(parser_state_t), intent(inout) :: parser
505
+        character(len=*), intent(in) :: func_name
506
+        type(ast_node_t), pointer, intent(out) :: node
507
+        
508
+        type(ast_node_t), pointer :: arg1, arg2, arg3
509
+        integer :: arg_count
510
+        
511
+        arg_count = 0
512
+        nullify(arg1, arg2, arg3)
513
+        
514
+        ! Parse first argument
515
+        call parse_single_argument(parser, arg1)
516
+        if (.not. associated(arg1)) then
517
+            call set_error(parser, 'Invalid function argument')
518
+            return
519
+        end if
520
+        arg_count = 1
521
+        
522
+        ! Check for more arguments
523
+        if (parser%current_token%token_type == TOKEN_COMMA) then
524
+            call advance(parser)  ! Skip comma
525
+            call parse_single_argument(parser, arg2)
526
+            if (.not. associated(arg2)) then
527
+                call set_error(parser, 'Invalid second argument')
528
+                if (associated(arg1)) call free_ast(arg1)
529
+                return
530
+            end if
531
+            arg_count = 2
532
+            
533
+            ! Check for third argument
534
+            if (parser%current_token%token_type == TOKEN_COMMA) then
535
+                call advance(parser)  ! Skip comma
536
+                call parse_single_argument(parser, arg3)
537
+                if (.not. associated(arg3)) then
538
+                    call set_error(parser, 'Invalid third argument')
539
+                    if (associated(arg1)) call free_ast(arg1)
540
+                    if (associated(arg2)) call free_ast(arg2)
541
+                    return
542
+                end if
543
+                arg_count = 3
544
+            end if
545
+        end if
546
+        
547
+        ! Expect closing parenthesis
548
+        if (parser%current_token%token_type /= TOKEN_RPAREN) then
549
+            call set_error(parser, 'Expected closing parenthesis')
550
+            if (associated(arg1)) call free_ast(arg1)
551
+            if (associated(arg2)) call free_ast(arg2)
552
+            if (associated(arg3)) call free_ast(arg3)
553
+            return
554
+        end if
555
+        call advance(parser)  ! Skip ')'
556
+        
557
+        ! Create function node with arguments
558
+        allocate(node)
559
+        node%node_type = AST_FUNCTION_CALL
560
+        node%function_name = trim(func_name)
561
+        node%arg_count = arg_count
562
+        allocate(node%arguments(arg_count))
563
+        
564
+        ! Set arguments
565
+        if (arg_count >= 1) node%arguments(1)%ptr => arg1
566
+        if (arg_count >= 2) node%arguments(2)%ptr => arg2
567
+        if (arg_count >= 3) node%arguments(3)%ptr => arg3
568
+    end subroutine parse_function_arguments
569
+    
570
+    !> Parse a single function argument (number, negative number, or constant)
571
+    subroutine parse_single_argument(parser, arg_node)
572
+        type(parser_state_t), intent(inout) :: parser
573
+        type(ast_node_t), pointer, intent(out) :: arg_node
574
+        
575
+        real(real64) :: num_val
576
+        type(value_t) :: value
577
+        
578
+        if (parser%current_token%token_type == TOKEN_NUMBER) then
579
+            read(parser%current_token%text, *) num_val
580
+            value = create_scalar(num_val)
581
+            arg_node => create_literal_node(value)
582
+            call advance(parser)
583
+        else if (parser%current_token%token_type == TOKEN_OPERATOR .and. &
584
+                 parser%current_token%text == '-') then
585
+            ! Handle negative numbers
586
+            call advance(parser)  ! Skip minus
587
+            if (parser%current_token%token_type == TOKEN_NUMBER) then
588
+                read(parser%current_token%text, *) num_val
589
+                value = create_scalar(-num_val)  ! Make negative
590
+                arg_node => create_literal_node(value)
591
+                call advance(parser)
592
+            else
593
+                call set_error(parser, 'Expected number after minus sign')
594
+                nullify(arg_node)
595
+                return
596
+            end if
597
+        else if (parser%current_token%token_type == TOKEN_IDENTIFIER) then
598
+            ! Handle constants like pi, e
599
+            arg_node => create_identifier_node(parser%current_token%text)
600
+            call advance(parser)
601
+        else
602
+            call set_error(parser, 'Function arguments support numbers and constants')
603
+            nullify(arg_node)
604
+        end if
605
+    end subroutine parse_single_argument
606
+    
544607
 end module fortbite_parser_m