fdoc

subroutineevaluaterecursiveprivate

recursive subroutine evaluate(c, id, v)

Evaluate expression id.

Arguments

NameTypeIntentAttributesDescription
ctype(fypp_t)inout

the state

idintegerin

the expression

vtype(value_t)out

the result

Calls

Source

Show the code
recursive subroutine evaluate(c, id, v)
    type(fypp_t), intent(inout) :: c    !! the state
    integer, intent(in) :: id           !! the expression
    type(value_t), intent(out) :: v     !! the result
    type(value_t) :: a, b
    type(value_t), allocatable :: shrunk(:)
    logical :: found
    integer :: k, j

    if (allocated(c%error)) return
    select case (c%exprs(id)%kind)
    case (E_CONST)
        v = c%exprs(id)%value
    case (E_NAME)
        call lookup(c, c%exprs(id)%name, v, found)
        if (.not. found) call fail(c, "the name '"//c%names(c%exprs(id)%name)%s//"' is not defined")
    case (E_LIST, E_TUPLE)
        v%kind = merge(V_LIST, V_TUPLE, c%exprs(id)%kind == E_LIST)
        allocate (v%items(size(c%exprs(id)%args)))
        do k = 1, size(v%items)
            call evaluate(c, c%exprs(id)%args(k), v%items(k))
        end do
    case (E_ADD, E_SUB, E_MUL)
        call evaluate(c, c%exprs(id)%a, a)
        call evaluate(c, c%exprs(id)%b, b)
        if (.not. allocated(c%error)) call arithmetic(c, c%exprs(id)%kind, a, b, v)
    case (E_NEG)
        call evaluate(c, c%exprs(id)%a, a)
        call make_int(-a%number, v)
    case (E_NOT)
        call evaluate(c, c%exprs(id)%a, a)
        call make_bool(.not. truth_of(a), v)
    case (E_AND)
        call evaluate(c, c%exprs(id)%a, v)
        if (truth_of(v)) call evaluate(c, c%exprs(id)%b, v)
    case (E_OR)
        call evaluate(c, c%exprs(id)%a, v)
        if (.not. truth_of(v)) call evaluate(c, c%exprs(id)%b, v)
    case (E_IF)
        call evaluate(c, c%exprs(id)%a, a)
        if (truth_of(a)) then
            call evaluate(c, c%exprs(id)%b, v)
        else
            call evaluate(c, c%exprs(id)%c, v)
        end if
    case (E_COMPARE)
        call compare(c, id, v)
    case (E_CALL)
        call evaluate_call(c, id, v)
    case (E_METHOD)
        call call_method(c, id, v)
    case (E_INDEX)
        call evaluate(c, c%exprs(id)%a, a)
        call evaluate(c, c%exprs(id)%b, b)
        if (.not. allocated(c%error)) call subscript(c, a, b%number, v)
    case (E_SLICE)
        call evaluate_slice(c, id, v)
    case (E_COMP)
        v%kind = V_LIST
        allocate (v%items(16))
        k = 0
        call run_clause(c, id, 1, v%items, k)
        allocate (shrunk(k))
        do j = 1, k
            call move_value(v%items(j), shrunk(j))
        end do
        call move_alloc(shrunk, v%items)
    case (E_FSTRING)
        call evaluate_fstring(c, id, v)
    case default
        call fail(c, 'an expression cannot be evaluated')
    end select
end subroutine evaluate

Graphs

Calls

Called by