subroutineevaluaterecursiveprivate
recursive subroutine evaluate(c, id, v)
Evaluate expression id.
Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
| c | type(fypp_t) | inout | the state | |
| id | integer | in | the expression | |
| v | type(value_t) | out | the result |
Calls
- lookup
- fail
- evaluate
- arithmetic
- make_int
- make_bool
- truth_of
- compare
- evaluate_call
- call_method
- subscript
- evaluate_slice
- run_clause
- move_value
- evaluate_fstring
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