Fortran · 2342 bytes Raw Blame History
1 module eval_builtin
2 use shell_types
3 use grammar_parser, only: parse_command_line
4 use command_tree, only: command_node_t
5 use ast_executor, only: execute_ast
6 use aliases, only: expand_alias, is_alias, get_alias
7 implicit none
8
9 contains
10
11 subroutine execute_eval(cmd, shell)
12 type(command_t), intent(in) :: cmd
13 type(shell_state_t), intent(inout) :: shell
14 integer :: i, exit_code
15 character(len=4096) :: eval_command
16 type(command_node_t), pointer :: ast_root
17
18 ! If no arguments, just return success
19 if (cmd%num_tokens < 2) then
20 shell%last_exit_status = 0
21 return
22 end if
23
24 ! Concatenate all arguments into a single command string
25 eval_command = trim(cmd%tokens(2))
26 do i = 3, cmd%num_tokens
27 eval_command = trim(eval_command) // ' ' // trim(cmd%tokens(i))
28 end do
29
30 ! Expand aliases in the eval command
31 ! eval should always expand aliases (like interactive mode)
32 call expand_eval_aliases(shell, eval_command)
33
34 ! Parse and execute the eval command using AST parser
35 ast_root => parse_command_line(trim(eval_command))
36 if (associated(ast_root)) then
37 exit_code = execute_ast(ast_root, shell)
38 shell%last_exit_status = exit_code
39 else if (len_trim(eval_command) == 0) then
40 ! Empty command is a no-op, not an error
41 shell%last_exit_status = 0
42 else
43 ! Parse error - set failure status
44 shell%last_exit_status = 1
45 end if
46 end subroutine execute_eval
47
48 subroutine expand_eval_aliases(shell, command)
49 type(shell_state_t), intent(in) :: shell
50 character(len=*), intent(inout) :: command
51 character(len=256) :: first_word
52 character(len=:), allocatable :: alias_value
53 integer :: space_pos
54
55 ! Extract first word
56 space_pos = index(trim(command), ' ')
57 if (space_pos > 0) then
58 first_word = command(:space_pos-1)
59 else
60 first_word = trim(command)
61 end if
62
63 ! Check if it's an alias (only expand in interactive mode per POSIX)
64 if (shell%is_interactive .and. is_alias(shell, trim(first_word))) then
65 alias_value = get_alias(shell, trim(first_word))
66 if (space_pos > 0) then
67 command = trim(alias_value) // command(space_pos:)
68 else
69 command = trim(alias_value)
70 end if
71 end if
72 end subroutine expand_eval_aliases
73
74 end module eval_builtin