subroutinecall_macrorecursiveprivate
recursive subroutine call_macro(c, which, positional, keywords, by_keyword, v)
Call macro which.
Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
| c | type(fypp_t) | inout | the state | |
| which | integer | in | the macro | |
| positional | type(value_t) | in | dimension(:) | the positional arguments |
| keywords | integer | in | dimension(:) | the keywords |
| by_keyword | type(value_t) | in | dimension(:) | the arguments given by keyword |
| v | type(value_t) | out | the result |
Calls
Source
Show the code
recursive subroutine call_macro(c, which, positional, keywords, by_keyword, v)
type(fypp_t), intent(inout) :: c !! the state
integer, intent(in) :: which !! the macro
type(value_t), intent(in) :: positional(:) !! the positional arguments
integer, intent(in) :: keywords(:) !! the keywords
type(value_t), intent(in) :: by_keyword(:) !! the arguments given by keyword
type(value_t), intent(out) :: v !! the result
type(buffer_t) :: out
character(len=:), allocatable :: text
integer :: k, j, saved, node, n
logical :: given
if (size(positional) > size(c%macros(which)%params)) then
call fail(c, 'a macro is called with too many arguments')
return
end if
do k = 1, size(keywords)
if (.not. any(c%macros(which)%params == keywords(k))) then
call fail(c, 'a macro is called with the unknown keyword '//c%names(keywords(k))%s)
return
end if
end do
call open_scope(c, 0)
if (allocated(c%error)) return
do k = 1, size(c%macros(which)%captured)
call define(c, c%macros(which)%captured(k), c%macros(which)%values(k))
end do
n = size(c%macros(which)%params)
do k = 1, n
given = k <= size(positional)
if (given) then
call define(c, c%macros(which)%params(k), positional(k))
cycle
end if
do j = 1, size(keywords)
if (keywords(j) == c%macros(which)%params(k)) then
call define(c, keywords(j), by_keyword(j))
given = .true.
end if
end do
if (given) cycle
if (c%macros(which)%has_default(k)) then
call define(c, c%macros(which)%params(k), c%macros(which)%defaults(k))
else
call fail(c, 'a macro is called without the argument '//c%names(c%macros(which)%params(k))%s)
end if
end do
saved = c%first_bound
c%first_bound = c%num_bound + 1
node = c%macros(which)%node
call render_body(c, c%nodes(node)%block%bodies(1), out, .false.)
c%first_bound = saved
call close_scope(c)
call take(out, text)
n = len(text)
if (n > 0) then
if (text(n:n) == NL) n = n - 1
end if
call make_string(text(:n), v)
end subroutine call_macro